[SCM] gerbera/upstream: New upstream version 1.0.0

jcowgill at users.alioth.debian.org jcowgill at users.alioth.debian.org
Sat Sep 23 17:41:41 UTC 2017


The following commit has been merged in the upstream branch:
commit 6049a47741ea746bdb2aaeca254426107d67cd67
Author: James Cowgill <jcowgill at debian.org>
Date:   Tue May 30 09:07:17 2017 +0100

    New upstream version 1.0.0

diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..202e2c1
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1 @@
+BasedOnStyle: Webkit
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..563b00f
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,2 @@
+[*.xsd]
+indent_size = 4
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2a8e542
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+mediatomb.spec
+*.swp
+mediatomb-service-optware
+.idea
+cmake-build-debug
+*.orig
+CMakeCache.txt
+CMakeFiles
+cmake_install.cmake
+Makefile
+mediatomb
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..0557d8a
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,52 @@
+# None as otherwise it clobbers our compiler choce
+language: none
+
+# Ubuntu 14.04 Trusty support
+sudo: required
+dist: trusty
+
+before_install:
+  - sudo apt-get update -qq
+  - sudo apt-get install -y uuid-dev libexpat1-dev libsqlite3-dev libmysqlclient-dev libmagic-dev libexif-dev libcurl4-openssl-dev
+  - ./scripts/install-duktape.sh
+  - ./scripts/install-pupnp18.sh
+  - ./scripts/install-taglib111.sh
+
+# Build
+script:
+  - mkdir build
+  - cd build
+  - cmake -DCMAKE_VERBOSE_MAKEFILE=ON .. && make
+
+matrix:
+  include:
+    - env: CXX=g++-4.9 CC=gcc-4.9
+      addons:
+        apt:
+          sources:
+            - ubuntu-toolchain-r-test
+          packages:
+            - g++-4.9
+    - env: CXX=g++-5 CC=gcc-5
+      addons:
+        apt:
+          sources:
+            - ubuntu-toolchain-r-test
+          packages:
+            - g++-5
+    - env: CXX=g++-6 CC=gcc-6
+      addons:
+        apt:
+          sources:
+            - ubuntu-toolchain-r-test
+          packages:
+            - g++-6
+    - env: CXX=clang++-4.0 CC=clang-4.0
+      addons:
+        apt:
+          sources:
+            - ubuntu-toolchain-r-test
+            - llvm-toolchain-trusty-4.0
+          packages:
+            - libc++-dev
+            - clang-4.0
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..66d5727
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,519 @@
+cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
+
+# It is 2017 so lets leverage a modern C++
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
+set(CMAKE_CXX_EXTENSIONS False)
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
+include(CheckFunctionExists)
+
+set(CMAKE_VERBOSE_MAKEFILE off CACHE BOOL "Show verbose build commands")
+set(WITH_MAGIC          1 CACHE BOOL "Use libmagic to identify file mime types")
+set(WITH_MYSQL          1 CACHE BOOL "MySQL is required if sqlite is not available")
+set(WITH_CURL           1 CACHE BOOL "CURL required for YouTube and/or SopCast")
+set(WITH_JS             1 CACHE BOOL "Enable JavaScript for custom import script")
+set(WITH_TAGLIB         1 CACHE BOOL "Use TagLib to extract audio file metadata")
+set(WITH_AVCODEC        0 CACHE BOOL "Enable ffmpeg/libav")
+set(WITH_EXIF           1 CACHE BOOL "Use libexif to extract image metadata")
+set(WITH_LASTFM         0 CACHE BOOL "Enable LastFM")
+set(WITH_LOGGING        1 CACHE BOOL "Enable file logging")
+set(WITH_DEBUG_LOGGING  1 CACHE BOOL "Enables debug logging")
+
+project("gerbera")
+set(gerbera_MAJOR_VERSION     1)
+set(gerbera_MINOR_VERSION     0)
+set(gerbera_PATCH_VERSION     0)
+set(gerbera_RELEASE           "")
+set(gerbera_SUFFIX            "")
+
+set(libgerberaFILES
+        src/action_request.cc
+        src/action_request.h
+        src/atrailers_content_handler.cc
+        src/atrailers_content_handler.h
+        src/atrailers_service.cc
+        src/atrailers_service.h
+        src/autoscan.cc
+        src/autoscan.h
+        src/autoscan_inotify.cc
+        src/autoscan_inotify.h
+        src/buffered_io_handler.cc
+        src/buffered_io_handler.h
+        src/cached_url.cc
+        src/cached_url.h
+        src/cds_objects.cc
+        src/cds_objects.h
+        src/cds_resource.cc
+        src/cds_resource.h
+        src/cds_resource_manager.cc
+        src/cds_resource_manager.h
+        src/common.h
+        src/config_manager.cc
+        src/config_manager.h
+        src/config_options.h
+        src/content_manager.cc
+        src/content_manager.h
+        src/curl_io_handler.cc
+        src/curl_io_handler.h
+        src/destroyer.cc
+        src/destroyer.h
+        src/dictionary.cc
+        src/dictionary.h
+        src/exceptions.cc
+        src/exceptions.h
+        src/executor.h
+        src/fd_io_handler.cc
+        src/fd_io_handler.h
+        src/file_io_handler.cc
+        src/file_io_handler.h
+        src/file_request_handler.cc
+        src/file_request_handler.h
+        src/filesystem.cc
+        src/filesystem.h
+        src/generic_task.cc
+        src/generic_task.h
+        src/io_handler_buffer_helper.cc
+        src/io_handler_buffer_helper.h
+        src/io_handler.cc
+        src/io_handler_chainer.cc
+        src/io_handler_chainer.h
+        src/io_handler.h
+        src/jpeg_resolution.cc
+        src/lastfm_scrobbler.cc
+        src/lastfm_scrobbler.h
+        src/layout/fallback_layout.cc
+        src/layout/fallback_layout.h
+        src/layout/js_layout.cc
+        src/layout/js_layout.h
+        src/layout/layout.h
+        src/logger.cc
+        src/logger.h
+        src/md5/md5.c
+        src/md5/md5.h
+        src/mem_io_handler.cc
+        src/mem_io_handler.h
+        src/memory.cc
+        src/memory.h
+        src/metadata/exiv2_handler.cc
+        src/metadata/exiv2_handler.h
+        src/metadata/ffmpeg_handler.cc
+        src/metadata/ffmpeg_handler.h
+        src/metadata_handler.cc
+        src/metadata_handler.h
+        src/metadata/libexif_handler.cc
+        src/metadata/libexif_handler.h
+        src/metadata/taglib_handler.cc
+        src/metadata/taglib_handler.h
+        src/metadata/fanart_handler.cc
+        src/metadata/fanart_handler.h
+        src/mpegremux_processor.cc
+        src/mpegremux_processor.h
+        src/mt_inotify.cc
+        src/mt_inotify.h
+        src/mxml/attribute.cc
+        src/mxml/attribute.h
+        src/mxml/comment.cc
+        src/mxml/comment.h
+        src/mxml/context.cc
+        src/mxml/context.h
+        src/mxml/document.cc
+        src/mxml/document.h
+        src/mxml/element.cc
+        src/mxml/element.h
+        src/mxml/mxml.h
+        src/mxml/node.cc
+        src/mxml/node.h
+        src/mxml/parseexception.cc
+        src/mxml/parseexception.h
+        src/mxml/parser_expat.cc
+        src/mxml/parser.h
+        src/mxml/xml_text.cc
+        src/mxml/xml_text.h
+        src/mxml/xml_to_json.cc
+        src/mxml/xml_to_json.h
+        src/object_dictionary.h
+        src/online_service.cc
+        src/online_service.h
+        src/online_service_helper.cc
+        src/online_service_helper.h
+        src/play_hook.cc
+        src/play_hook.h
+        src/process.cc
+        src/process_executor.cc
+        src/process_executor.h
+        src/process.h
+        src/process_io_handler.cc
+        src/process_io_handler.h
+        src/reentrant_array.h
+        src/request_handler.cc
+        src/request_handler.h
+        src/rexp.cc
+        src/rexp.h
+        src/scripting/import_script.cc
+        src/scripting/import_script.h
+        src/scripting/js_functions.cc
+        src/scripting/js_functions.h
+        src/scripting/playlist_parser_script.cc
+        src/scripting/playlist_parser_script.h
+        src/scripting/runtime.cc
+        src/scripting/runtime.h
+        src/scripting/script.cc
+        src/scripting/script.h
+        src/server.cc
+        src/serve_request_handler.cc
+        src/serve_request_handler.h
+        src/server.h
+        src/session_manager.cc
+        src/session_manager.h
+        src/singleton.cc
+        src/singleton.h
+        src/sopcast_content_handler.cc
+        src/sopcast_content_handler.h
+        src/sopcast_service.cc
+        src/sopcast_service.h
+        src/storage/cache_object.cc
+        src/storage/cache_object.h
+        src/storage.cc
+        src/storage.h
+        src/storage/mysql/mysql_create_sql.h
+        src/storage/mysql/mysql_storage.cc
+        src/storage/mysql/mysql_storage.h
+        src/storage/sqlite3/sqlite3_create_sql.h
+        src/storage/sqlite3/sqlite3_storage.cc
+        src/storage/sqlite3/sqlite3_storage.h
+        src/storage/sql_storage.cc
+        src/storage/sql_storage.h
+        src/storage/storage_cache.cc
+        src/storage/storage_cache.h
+        src/string_converter.cc
+        src/string_converter.h
+        src/subscription_request.cc
+        src/subscription_request.h
+        src/task_processor.cc
+        src/task_processor.h
+        src/thread_executor.cc
+        src/thread_executor.h
+        src/timer.cc
+        src/timer.h
+        src/tools.cc
+        src/tools.h
+        src/transcoding/transcode_dispatcher.cc
+        src/transcoding/transcode_dispatcher.h
+        src/transcoding/transcode_ext_handler.cc
+        src/transcoding/transcode_ext_handler.h
+        src/transcoding/transcode_handler.h
+        src/transcoding/transcoding.cc
+        src/transcoding/transcoding.h
+        src/transcoding/transcoding_process_executor.cc
+        src/transcoding/transcoding_process_executor.h
+        src/update_manager.cc
+        src/update_manager.h
+        src/upnp_cds_actions.cc
+        src/upnp_cds.cc
+        src/upnp_cds.h
+        src/upnp_cds_subscriptions.cc
+        src/upnp_cm_actions.cc
+        src/upnp_cm.cc
+        src/upnp_cm.h
+        src/upnp_cm_subscriptions.cc
+        src/upnp_mrreg_actions.cc
+        src/upnp_mrreg.cc
+        src/upnp_mrreg.h
+        src/upnp_mrreg_subscriptions.cc
+        src/upnp_xml.cc
+        src/upnp_xml.h
+        src/url.cc
+        src/url.h
+        src/url_request_handler.cc
+        src/url_request_handler.h
+        src/web/action.cc
+        src/web/add.cc
+        src/web/add_object.cc
+        src/web/auth.cc
+        src/web_callbacks.cc
+        src/web_callbacks.h
+        src/web/containers.cc
+        src/web/directories.cc
+        src/web/edit_load.cc
+        src/web/edit_save.cc
+        src/web/files.cc
+        src/web/items.cc
+        src/web/pages.cc
+        src/web/pages.h
+        src/web/remove.cc
+        src/web_request_handler.cc
+        src/web_request_handler.h
+        src/web/tasks.cc
+        src/web/web_autoscan.cc
+        src/web/web_update.cc
+        src/xpath.cc
+        src/xpath.h
+        src/youtube_content_handler.cc
+        src/youtube_content_handler.h
+        src/youtube_service.cc
+        src/youtube_service.h
+        src/youtube_video_url.cc
+        src/youtube_video_url.h
+        src/zmm/array.cc
+        src/zmm/array.h
+        src/zmm/base_array.h
+        src/zmm/base_queue.h
+        src/zmm/base_stack.h
+        src/zmm/exception.cc
+        src/zmm/exception.h
+        src/zmm/object_queue.h
+        src/zmm/object_stack.h
+        src/zmm/stringtokenizer.cc
+        src/zmm/stringtokenizer.h
+        src/zmm/zmmf.h
+        src/zmm/object.cc
+        src/zmm/object.h
+        src/zmm/ref.h
+        src/zmm/stringbuffer.cc
+        src/zmm/stringbuffer.h
+        src/zmm/strings.cc
+        src/zmm/strings.h
+        src/zmm/zmm.h)
+
+add_library(libgerbera OBJECT ${libgerberaFILES})
+
+target_include_directories(libgerbera PRIVATE "${CMAKE_SOURCE_DIR}/src")
+
+add_executable(gerbera src/main.cc $<TARGET_OBJECTS:libgerbera>)
+target_include_directories(gerbera PRIVATE "${CMAKE_SOURCE_DIR}/src")
+
+# Warnings are nice
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
+
+# Add the automatically determined parts of the RPATH which point to
+# dirss outside the build tree to the install RPATH
+set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+
+# Provide __FILENAME__ for debug statements
+include(DefFileName)
+define_file_path_for_sources(libgerbera)
+define_file_path_for_sources(gerbera)
+
+# Use libc++ with clang
+if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
+endif()
+
+# Host OS Check
+if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
+    set(HOST_OS "linux")
+    set(LINUX 1)
+elseif(${CMAKE_SYSTEM_NAME} MATCHES ".*(SunOS|Solaris).*")
+    set(HOST_OS "solaris")
+    set(SOLARIS 1)
+elseif(${CMAKE_SYSTEM_NAME} MATCHES ".*BSD.*")
+    set(HOST_OS "bsd")
+    set(BSD 1)
+elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
+    set(HOST_OS "darwin")
+    set(DARWIN 1)
+endif()
+if(NOT HOST_OS)
+    message(FATAL_ERROR 
+                "gerbera was unable to deterimine the host OS. Please report this. Value of CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
+endif()
+
+if (SOLARIS)
+    add_definitions(-DSOLARIS)
+endif()
+
+add_definitions(-DPACKAGE_NAME="gerbera${gerbera_SUFFIX}")
+add_definitions(-DVERSION="${gerbera_MAJOR_VERSION}.${gerbera_MINOR_VERSION}.${gerbera_PATCH_VERSION}${gerbera_RELEASE}${gerbera_SUFFIX}")
+add_definitions(-DPACKAGE_DATADIR="${CMAKE_INSTALL_PREFIX}/share/gerbera")
+
+add_definitions(-DCOMPILE_INFO="")
+add_definitions(-DEXTERNAL_TRANSCODING -DAUTO_CREATE_DATABASE)
+
+if (WITH_LOGGING OR WITH_DEBUG_LOGGING)
+    add_definitions(-DLOG_ENABLED)
+endif()
+if (WITH_DEBUG_LOGGING)
+    add_definitions(-DTOMBDEBUG)
+endif()
+
+find_package(Threads REQUIRED)
+target_link_libraries (gerbera ${CMAKE_THREAD_LIBS_INIT})
+
+find_package(Iconv REQUIRED)
+include_directories(${ICONV_INCLUDE_DIR})
+target_link_libraries (gerbera ${ICONV_LIBRARIES})
+
+find_package(LibUUID REQUIRED)
+include_directories(${LIBUUID_INCLUDE_DIRS})
+target_link_libraries (gerbera ${LIBUUID_LIBRARIES})
+
+find_package (LibUpnp REQUIRED)
+include_directories(${UPNP_INCLUDE_DIRS})
+target_link_libraries (gerbera ${UPNP_LIBRARIES})
+
+if (UPNP_VERSION_STRING VERSION_LESS "1.8.0")
+    message(FATAL_ERROR "gerbera requires libupnp 1.8.0 or above.")
+endif()
+if (NOT UPNP_HAS_IPV6)
+    message(FATAL_ERROR "gerbera requires libupnp with IPv6 support.")
+endif()
+if (NOT UPNP_HAS_REUSEADDR)
+    message(WARNING "\n !! It is strongly recommended to build libupnp with --enable-reuseaddr !!\nWithout this option Gerbera will be unable to restart with the same port number.")
+endif()
+
+# Debian ships a snapshot from 2010: libupnp4 (1.8.0~svn20100507-1.2)
+# This is missing templated types so we need to ifdef
+if(UPNP_INCLUDE_DIR AND NOT EXISTS "${UPNP_INCLUDE_DIR}/upnp-1.8/TemplateInclude.h")
+    message (WARNING "\n!! You are using a very old 1.8 snapshot. Please upgrade to a newer snapshot from upstream (https://github.com/mrjimenez/pupnp) !!\n")
+    message (STATUS "gerbera: Enabling old libupnp snapshot compat. Web interface will probably not work.")
+    add_definitions(-DUPNP_OLD_SNAPSHOT)
+endif()
+
+find_package (EXPAT REQUIRED)
+include_directories(${EXPAT_INCLUDE_DIRS})
+target_link_libraries (gerbera ${EXPAT_LIBRARIES})
+
+find_package (SQLite3 REQUIRED)
+include_directories(${SQLITE3_INCLUDE_DIRS})
+target_link_libraries (gerbera ${SQLITE3_LIBRARIES})
+add_definitions(-DHAVE_SQLITE3)
+
+check_function_exists(nl_langinfo HAVE_NL_LANGINFO)
+if (HAVE_NL_LANGINFO)
+    add_definitions("-DHAVE_NL_LANGINFO")
+endif()
+
+check_function_exists(setlocale HAVE_SETLOCALE)
+if (HAVE_SETLOCALE)
+    add_definitions("-DHAVE_SETLOCALE")
+endif()
+
+# Link to the socket library if it exists. This is something you need on Solaris/OmniOS/Joyent
+find_library(SOCKET_LIBRARY socket)
+if(SOCKET_LIBRARY)
+    set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${SOCKET_LIBRARY})
+    target_link_libraries(gerbera ${SOCKET_LIBRARY})
+endif()
+
+# Link to libnsl (Network services library) if it exists. This is something you need on Solaris/OmniOS/Joyent
+find_library(NSL_LIBRARY nsl)
+if(NSL_LIBRARY)
+    set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${NSL_LIBRARY})
+    target_link_libraries(gerbera ${NSL_LIBRARY})
+endif()
+
+find_package(INotify)
+IF (INOTIFY_FOUND)
+    include_directories(${INOTIFY_INCLUDE_DIRS})
+    target_link_libraries (gerbera ${INOTIFY_LIBRARY})
+    add_definitions(-DHAVE_INOTIFY)
+endif ()
+
+if(WITH_JS)
+    find_package(Duktape)
+    IF (DUKTAPE_FOUND)
+        include_directories(${DUKTAPE_INCLUDE_DIRS})
+        target_link_libraries (gerbera ${DUKTAPE_LIBRARIES})
+        add_definitions(-DHAVE_JS)
+    endif ()
+endif()
+
+if(WITH_MYSQL)
+    find_package(MySQL REQUIRED)
+    if (MYSQL_FOUND)
+        include_directories(${MYSQL_INCLUDE_DIRS})
+        target_link_libraries (gerbera ${MYSQL_CLIENT_LIBS})
+        add_definitions(-DHAVE_MYSQL)
+    else()
+        message(FATAL_ERROR "MySQL not found")
+    endif ()
+endif()
+
+if(WITH_CURL)
+    find_package (CURL REQUIRED)
+    if (CURL_FOUND)
+        include_directories(${CURL_INCLUDE_DIRS})
+        target_link_libraries (gerbera ${CURL_LIBRARIES})
+
+        add_definitions(-DHAVE_CURL)
+        add_definitions(-DONLINE_SERVICES)
+        add_definitions(-DYOUTUBE)
+    else()
+        message(FATAL_ERROR "cURL not found")
+    endif()
+endif()
+
+if(WITH_TAGLIB)
+    find_package (Taglib)
+    if (TAGLIB_FOUND)
+        include_directories(${TAGLIB_INCLUDE_DIRS})
+        target_link_libraries (gerbera ${TAGLIB_LIBRARIES})
+        add_definitions(-DHAVE_TAGLIB)
+    else()
+        message(FATAL_ERROR "SpiderMonkey (MozJS) not found")
+    endif()
+endif()
+
+if(WITH_MAGIC)
+    find_package (LibMagic)
+    if (MAGIC_FOUND)
+        include_directories(${MAGIC_INCLUDE_DIRS})
+        target_link_libraries (gerbera ${MAGIC_LIBRARIES})
+        add_definitions(-DHAVE_MAGIC)
+    else()
+        message(FATAL_ERROR "Magic not found")
+    endif ()
+endif()
+
+if(WITH_AVCODEC)
+    find_package (FFMPEG)
+    if (FFMPEG_FOUND)
+        include_directories(${FFMPEG_INCLUDE_DIR})
+        target_link_libraries (gerbera ${FFMPEG_LIBRARIES})
+        add_definitions(-DHAVE_FFMPEG)
+        if (HAVE_AVSTREAM_CODECPAR)
+            add_definitions(-DHAVE_AVSTREAM_CODECPAR)
+        endif()
+
+    else()
+        message(FATAL_ERROR "FFMpeg/LibAV not found")
+    endif ()
+endif()
+
+if(WITH_EXIF)
+    find_package (EXIF)
+    if (EXIF_FOUND)
+        include_directories(${EXIF_INCLUDE_DIRS})
+        target_link_libraries (gerbera ${EXIF_LIBRARIES})
+        add_definitions(-DHAVE_LIBEXIF)
+    else()
+        message(FATAL_ERROR "LibExif not found")
+    endif()
+endif()
+
+if(WITH_LASTFM)
+    find_package (LastFMLib)
+    if (LASTFMLIB_FOUND)
+        include_directories(${LASTFMLIB_INCLUDE_DIRS})
+        target_link_libraries (gerbera ${LASTFMLIB_LIBRARIES})
+        add_definitions(-DHAVE_LASTFMLIB)
+    else()
+        message(FATAL_ERROR "LastFMLib not found")
+    endif()
+endif()
+
+# Needs to be towards the end (after CURL, TagLib, etc...)
+find_package (ZLIB REQUIRED)
+include_directories(${ZLIB_INCLUDE_DIRS})
+target_link_libraries (gerbera ${ZLIB_LIBRARIES})
+
+INSTALL(TARGETS gerbera DESTINATION bin)
+INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/scripts/js DESTINATION share/gerbera)
+INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/web DESTINATION share/gerbera)
+INSTALL(FILES
+        ${PROJECT_SOURCE_DIR}/config/mappings.xml
+        ${PROJECT_SOURCE_DIR}/config/mysql.sql
+        ${PROJECT_SOURCE_DIR}/config/sqlite3.sql
+        DESTINATION share/gerbera)
+INSTALL(FILES ${PROJECT_SOURCE_DIR}/doc/gerbera.1 DESTINATION share/man/man1)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..751d37d
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,24 @@
+# Contributing
+
+We welcome pull requests from everyone!
+
+MediaTomb is an old project that we are working on modernising - there are a lot of cobwebs 🕸 .
+
+For new code please use modern C++ (up to 14) constructs where possible, and avoid the `zmm` namespace.
+
+1. Fork this repo.
+
+2. Clone your fork:
+
+    `git clone git at github.com:your-username/mediatomb.git`
+
+2. Make your change.
+
+3. Push to your fork
+
+4. [Submit a pull request](https://github.com/v00d00/mediatomb/compare).
+
+Some things that will increase the chance that your pull request is accepted:
+
+* Stick to [Webkit style](https://webkit.org/code-style-guidelines/).
+* Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
diff --git a/COPYING b/COPYING
deleted file mode 100644
index 78af4cb..0000000
--- a/COPYING
+++ /dev/null
@@ -1,344 +0,0 @@
-Note that the only valid version of the GPL for MediaTomb is this particular 
-version of the license (ie v2, not v2.2 or v3.x or whatever), unless 
-explicitly otherwise stated.
-
-
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/ChangeLog b/ChangeLog
deleted file mode 100644
index 4e7b6ec..0000000
--- a/ChangeLog
+++ /dev/null
@@ -1,333 +0,0 @@
-MediaTomb - UPnP AV Mediaserver.
-v0.12.1 08.04.2010
-        * fixed YouTube service support (got broken after they updated their
-          website)
-        * fixed a problem in soap response http headers (solves "access error" 
-          on Yamaha RX-V2065)
-        * turned out the change log for 0.12.0 was not complete (various 
-          closed bugs were not mentioned)
-        * fixed automatic id3lib detection when taglib is not available
-
-v0.12.0 25.03.2010
-        * added video thumbnail generation using libffmpegthumbnailer
-        * added configure settings which allow to enable sqlite backups by 
-          default
-        * added cross compile defaults for the inotify check to configure
-        * added configure check for broken libmagic on Slackware
-        * added libmp4v2 metadata handler to get tags and cover art from mp4
-          files
-        * got rid of several compiler warnings
-        * added storage cache
-        * added storage insert buffering
-        * fixed mysql "threads didn't exit" issue
-        * implemented YouTube service support which allows to watch YouTube 
-          videos on your UPnP player (in combination with transcoding)
-        * added fixes to allow PCM playback on the PS3 and other devices,
-          thanks to mru for his findings. This allows streaming transcoded
-          OGG and FLAC media to the PS3.
-        * added option to enable tooltips for the web UI, thanks to cweiske
-          for the patch
-        * fixed bug #1986789 - Error when renaming a playlist container
-        * added parameter -D/--debug (enable debug output)
-        * closed feature request #1934646 - added parameter --version 
-          (prints version information
-        * added parameter --compile-info (prints compile information)
-        * fixed problem "Negative duration in .m3u files" (SF forum)
-        * fixed bug #2078017 - Playlist inital import fails in autoscan
-          directories
-        * fixed bug #1890657 - transcoding tmp file using 2 //
-        * fixed bug #1978210 - compile error with newer libcurl
-        * fixed bug #1934649 - typo in --help text
-        * fixed bugs #1986709 and #1996046 - cannot rename item with & in name
-        * fixed bug #2122696 - build error with MySQL 5.1
-        * fixed bug #1973930 - Incorrect UPnP class assigned to Vorbis and
-          Theora items
-		* fixed bug #1934659 - unspecific error message when db is not available
-        * fixed bug #2904448 - memset with number of bytes set to 0 in
-          array.cc
-        * added a "Directories" view in the default layout for Photos and
-          Video, the feature is still somewhat experimental
-        * added a feature that allows to mark played items
-        * improved inotify check which was failing with 2.4 kernels
-        * added support for lastfmlib, thanks to Dirk Vanden Boer vor the
-          patch
-        * increased buffer length for the exif field following the request
-          from one of our users
-        * fixed a problem where the upnp-string-limit function was not
-          correctly truncating UTF-8 strings
-        * fixed a bug where --enable-id3lib did not turn off the automatic
-          enabling of taglib, which then resulted in an error message saying, 
-          that both libraries are enabled
-        * implemented feature request #2833402 - ability to change
-          ffmpegthumbnailer param "image quallity"
-        * fixed bug #2783557 - Mediatomb always flags file as chunked output,
-          thanks to Michael Guntsche
-        * fixed bug #2804342 - wrong namespace in <serviceId>
-        * added a fix for glibc 2.10, thanks to Honoome for the patch
-        * added patches for NetBSD, thanks to Jared D. McNeill
-        * fixed bug #2944701 Adding comment in config as last line yields
-          segfault
-        * fixed bug #2779907 SQLITE3: (1) cannot start a transaction within a
-          transaction
-        * fixed bug #2820213 build broken with libmp4v2-1.9.0
-        * fixed bug #2161155 inotify thread aborts 
-        * fixed bug #2011296 SVN rev 1844 doesn't show more than 10 files on
-          PS3
-        * fixed bug #1988738 web ui docs miss note how to access web ui
-        * fixed bug #1929230 invalid XML in UPNP messages
-        * fixed bug #1865386 autoscan dir already exists error 
-		* implemented feature request #2313953 support for forked libmp4v2
-          project
-        * implemented feature request #1955192 flag/mark watched video files
-        * implemented feature request #1928580 better logging/tracing support
-        * implemented feature request #1754010 m4a metadata extraction
-
-v0.11.0 01.03.2008  External transcoding support
-        * implemented transcoding support that allows to plug in an arbitrary
-          transcoding application
-        * added fourcc detection for AVI files and transcoding options to 
-          limit transcoding to certain fourcc's
-        * added new metadata extractor using ffmpeg, patch submitted by 
-          Ingo Preiml
-        * added vorbis / theora detection for ogg containers, so video files
-          should not end up in audio containers anymore
-        * fixed bug where database-file option was still checked even when
-          MySQL was selected in the configuration
-        * fixed a bug where check of the home directory was enforced even if 
-          the configuration file was specified on command line
-        * UTF-8 fix suggested by piman - taglib should handle UTF-8 correctly, 
-          so we will request an UTF-8 string from taglib and do not do the 
-          conversion ourselves
-        * UTF-8 fix for libextractor, basically same as with TagLib
-        * added default mapping for flv files since they are not correctly
-          recognized by libmagic
-        * fixed a bug where we could get crashed by a missing URL parameter
-          sent to the UI
-        * fixed 64bit related issues in the UPnP SDK
-        * fixed a problem where ID3 tags were not detected with id3lib
-        * fixed off by one errors in StringBuffer class, thanks to stigpo for
-          the patch
-        * fixed bug #1824216 - encoded URLs were not treated properly
-        * made sure that log output is always flushed
-        * made temporary directory configurable
-        * using expat as XML parser
-        * new XML generator - support for comments
-        * changed layout of the storage configuration XML
-        * added migration for old config.xml
-        * speed up sqlite3 by setting synchronous=off by default
-        * adding automatic database backup for sqlite3
-        * adding automatic backup restore on sqlite3 database corruption
-        * fix permission problem - supplementary groups weren't set by
-          initgroups()
-        * fixed js (spidermonkey) related crashes
-        * fix mysql reconnect issue - charset was lost after reconnect
-        * added check to avoid coredump when max number of inotify watches
-          has been reached
-        * made sure that range requests specified as "bytes=0-" do not trigger
-          a 416 response for media where the filesize is unknown
-        * added fix for chunked encoding that was posted on the maemo forums
-        * fixed configure to determine if iconv needs the const char cast or
-          not (fixes OSX compilation problem)
-        * added album art support for the PS3
-        * fixed a bug where path used by add container chain was not converted
-          to UTF-8
-        * added patch for author and director extraction from id3 tags, 
-          submitted by Reinhard Enders
-        * init script for fedora now uses the -e option instead of grepping
-          for the IP (old variant only worked on systems with english
-          language)
-        * updated spec file with changes from Marc Wiriadisastra
-        * we now are also providing the filesize along with the other metadata
-        * added environment variables that can be used for additional server
-          configuration (useful for directory independent NAS setups)
-        * added comments and examples to the config.xml that is generated by
-          the server
-        * added patch from Gabriel Burca to extract keywords from id3 tags
-        * added runtime inotify detection
-        * added a workaround for the Noxon V1 which for some reasons sends 
-          us a double encoded ampersand XML sequences in the URL
-        * implemented feature request #1771561, extension to mimetype mappings
-          can now be case insensitive
-
-v0.10.0	11.07.2007  Playlist and inotify autoscan support.
-        * MySQL database version pumped to 3 (MediaTomb will automatically
-          update the database during the first launch)
-        * Sqlite3 database version pumped to 2 (MediaTomb will automatically
-          update the database during the first launch)
-        * added support for inotify based autoscan
-        * playlist support - parsing playlist via js is now possible
-        * added network interface option
-        * added workaround for a PS3 related problem, where sockets were left
-          open (bug #1732412)
-        * improved iconv handling of illegal characters
-        * added character conversion safeguards to make sure that non UTF-8
-          strings do not make it into the database from js scripts
-        * made character conversion functions available to js
-        * added option to hide PC Directory from UPnP renderers
-        * added album art support, album art is extracted from ID3 tags
-          and offered to UPnP devices
-
-v0.9.1  28.05.2007  Playstation 3 support
-        * added support for Playstation 3
-        * added command line option that allows to tell the server where to
-          put the configuration upon first startup
-        * fixed a fseeko-check related bug in configure
-        * the configure script now honors the LDFLAGS while checking for sqlite3
-        * fixed wrong message printout in configure
-        * PC Directory can now be renamed in the UI
-        * fixed a bug in configure.ac, the --with-extractor-libs= parameter
-          didn't work
-        * fixed a MySQL related bug, if the path or filename contained non-UTF8
-          characters, the inserted strings weren't complete
-        * circumvented a bug/feature of older MySQL versions, that caused the
-          MySQL database creation script to fail
-        * MySQL database version pumped to 2 (MediaTomb will automatically
-          update the database during the first launch)
-
-v0.9.0  25.03.2007  Major rework
-        * the UI was completely rewritten from scratch; it uses AJAX for all
-          requests
-        * integrated libupnp (http://pupnp.sf.net/) into our source tree
-        * added largefile support
-        * code has undergone some performance optimizations
-        * fixed a bug where server did not shutdown while http download
-          was in progress
-        * all sqlite3 queries are now handled by a single, dedicated
-          thread to make MediaTomb work with SQLite3 compiled with
-          "--enable-threadsafe"
-        * fixed a bug where setting -p 0 did not trigger automatic
-          port selection if it had to override the value in config.xml
-        * fixed bug 1425424 - crash on a bad config.xml - we did not handle 
-          the case where the <udn> tag was not present.
-          Thanks to Nektarios K. Papadopoulos <npapadop at users.sourceforge.net>
-          for the report and patch.
-        * added configure option and adapted the code to completely 
-          supress all log output
-        * added configure option and adapted the code to supress
-          debug output
-        * added taglib support, thanks to Benhur Stein <benhur.stein at gmail.com>
-          for the patch. 
-        * bug 1524468 (startup in daemon mode fails) does no longer occur
-          after the integration of libupnp 1.4.x sources
-        * fixed bug 1292295 (string conversion was failing on 64bit platforms)
-        * fixed issue with ContainerUpdateIDs (were not sent out along with
-          accepted subscription)
-        * fixed issue where some directories could not be browsed (filesystem 
-          browser). It turned out that we forgot to convert the filenames
-          to UTF-8, as the result invalid characters made their way into
-          the XML that was feeded to the browser.
-        * improved illegal character conversion handling - in case iconv
-          fails we will pad the rest of the name string with "?" and print
-          out the failed name in the console.
-        * we now try to determine the default import charsets by looking
-          at the system locale.
-        * implemented track number metadata extraction (feature request
-          1430799). track numbers are now extracted via id3lib/taglib and
-          can also be used in the import script. import.js has been adapted
-          to add tracknumbers to song names in the Album container.
-        * added option to supress hidden files when browsing the filesystem
-        * added X_MS_MediaReceiverRegistrar Service to allow future Xbox 360 
-          support
-        * added workarounds to enable Telegent TG100 avi playback
-        * server can now be restarted by sending it a SIGHUP
-        * the current configuration file will never be displayed in the UI and
-          will never be added to the database - we do not want the user to
-          accidentally share it on the network since it may contain
-          security sensitive data
-        * tomb-install is no longer needed, the server will automatically create
-          a default ~/.mediatomb/config.xml file if there is none
-        * the database tables will be created automatically if they don't
-          exist
-        * adapted configure script to correctly set flags for linkers that
-          use the --as-needed option
-        * the "PC Directory" isn't changeable via the UI anymore to ensure a
-          correct view of the "PC Directory"
-        * lookups in the database are now done with hashes, which should make
-          many things faster, especially the adding
-        * changed the database field "location" from varchar(255) to text to
-          allow urls and locations of unlimited size
-        * created a new theme for the UI
-        * added support for "blind" .srt requests - some renderers like the
-          DSM320 will blindly request the url provided via browse, replacing
-          and found file extension with .srt, we will look for the .srt file
-          in the directory where the original media is located, using the
-          same filename, but with the .srt extension
-        * created XML schema for "config.xml" to provide the possiblity of
-          validating the configuration
-        * added fallback if js is not available - there is a builtin feature
-          to create a default virtual layout now; config.xml has got an
-          option to select the virtual-layout type, it can be builting, js or
-          disabled.
-        * added charset option to the import script, it is not possible to
-          specify the script encoding
-        * we now validate filesystem, metadata and scripting charsets upon 
-          startup
-        * added a special option that allows limiting title and description
-          lengths in UPnP browse replies to a specified length; this was
-          necessary to work around a bug in the TG100 that has problems
-          browsing items where title length exceeds 101 characters.
-        * import.js can now specify the upnp class of the last container in the
-          chain
-        * all items within a container which upnp class is set to 
-          object.container.album.musicAlbum will automatically be sorted by 
-          track number.
-        * added option to configure the presentation URL to make it easier
-          for NAS vendors to integrate the server into their web UI
-        * made model number configurable
-
-v0.8.1	07.09.2005
-        * added "serve" directory, any files there can be downloaded 
-          like from a normal webserver
-        * implemented keyword extraction for auxdata from libexif
-        * implemented keyword extraction for auxdata from libextractor
-        * added Exif metadata support for images via libexif.
-        * added resolution attribute to image res tag
-        * added bitrate and duration attribute to mp3 res tag (via id3lib)
-        * added auxdata field for items, auxilary data can be extracted
-          and used by import scripts.
-        * added configuration options to specify which aux fields should 
-          be extracted and filled by the library.
-        * added mysql support
-        * refined configure script, almost all dependencies are now
-          optional.
-        * changed database, (not backward compatible again)
-        * when an item is deleted all referenced items are deleted as well
-        * added option to specify an alternative magic file
-
-v0.8.0  15.06.2005  Scripting/Virtual Server Layout
-        * Server layout can now be defined using java script,
-          default layout script is provided.
-        * Added ID3 tag support.
-        * Fixed various memory leaks.
-        * Files in the Filesystem Browser are now sorted alphabetically.
-        * Added extension to mime-type mappings to the configuration.
-        * Added option to limit import by file extensions.
-        * Added daemon mode as well as setuid/setgid options, init.d
-          script included.
-        * Fixed mime-type recognition when importing media (filemagic output
-          is now parsed using regular expressions)
-        * Introduced new log system.
-        * Adding/Browsing/Removing media in the UI is now handled
-          asynchroniously.
-        * Added a command line option to import media upon server launch.
-        * Added target directory option to tomb-install, cleaned up a few
-          things.
-
-v0.7.1  17.04.2005  D-Link DSM-320 fix
-        * Mappings of mime-types to upnp classes are now configurable.
-          Actually this is how we solved the DSM-320 problem - they
-          crashed if upnp class of items was different than what the
-          DSM expected.
-
-        * tomb-install now creates the database and configuration file
-          from templates (was hardcoded); also sets the name of the server
-          individually for each user (host / username)
-
-        * Improved handling of configuration, if non critical options are
-          missing we are now setting default values.
-
-v0.7    14.04.2005  First release
-        * The changelog does not start at day 0, updates will be made
-          starting from this release.
-        
-          
diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
index 0000000..00a6f37
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,354 @@
+## Gerbera - UPnP AV Mediaserver.
+
+### v1.0.0
+- Rebranded as Gerbera, new Logo!
+- Ported to CMake
+- Removed bundled libupnp - Now requires upstream 1.8 version.
+- Removed bundled libuuid.
+- Enhanced cover art support for MP4, FLAC, Vorbis & WMA files (via TagLib).
+- TagLib handler opens files read only: stops inotify rescanning the dir on access causing "Object not found" see here.
+- Album folders have "creator" metadata (artist).
+- Album folders have artwork: either from external files or the tracks embedded artwork.
+- Per-track external art support: filename-of-track.jp\* (minus the audio file extension).
+- WIP port to "Modern C++" / tidying.
+- Removed libflac use/dep.
+- Remove libmp4v2 use/dep.
+- Remove id3lib use/dep.
+- Removed broken DVD support (dvdnav).
+- IPv6 Support
+- Replaced SpiderMonkey (mozjs) dependency with the duktape engine.
+- Lots of other stuff.
+
+### MediaTomb v0.12.2
+- Added mtime and sizeOnDisk to JS objects
+
+### MediaTomb v0.12.1 08.04.2010
+- fixed YouTube service support (got broken after they updated their
+  website)
+- fixed a problem in soap response http headers (solves "access error" 
+  on Yamaha RX-V2065)
+- turned out the change log for 0.12.0 was not complete (various 
+  closed bugs were not mentioned)
+- fixed automatic id3lib detection when taglib is not available
+
+### MediaTomb v0.12.0 25.03.2010
+- added video thumbnail generation using libffmpegthumbnailer
+- added configure settings which allow to enable sqlite backups by 
+  default
+- added cross compile defaults for the inotify check to configure
+- added configure check for broken libmagic on Slackware
+- added libmp4v2 metadata handler to get tags and cover art from mp4
+  files
+- got rid of several compiler warnings
+- added storage cache
+- added storage insert buffering
+- fixed mysql "threads didn't exit" issue
+- implemented YouTube service support which allows to watch YouTube 
+  videos on your UPnP player (in combination with transcoding)
+- added fixes to allow PCM playback on the PS3 and other devices,
+  thanks to mru for his findings. This allows streaming transcoded
+  OGG and FLAC media to the PS3.
+- added option to enable tooltips for the web UI, thanks to cweiske
+  for the patch
+- fixed bug #1986789 - Error when renaming a playlist container
+- added parameter -D/--debug (enable debug output)
+- closed feature request #1934646 - added parameter --version 
+  (prints version information
+- added parameter --compile-info (prints compile information)
+- fixed problem "Negative duration in .m3u files" (SF forum)
+- fixed bug #2078017 - Playlist inital import fails in autoscan
+  directories
+- fixed bug #1890657 - transcoding tmp file using 2 //
+- fixed bug #1978210 - compile error with newer libcurl
+- fixed bug #1934649 - typo in --help text
+- fixed bugs #1986709 and #1996046 - cannot rename item with & in name
+- fixed bug #2122696 - build error with MySQL 5.1
+- fixed bug #1973930 - Incorrect UPnP class assigned to Vorbis and
+  Theora items
+- fixed bug #1934659 - unspecific error message when db is not available
+- fixed bug #2904448 - memset with number of bytes set to 0 in
+  array.cc
+- added a "Directories" view in the default layout for Photos and
+  Video, the feature is still somewhat experimental
+- added a feature that allows to mark played items
+- improved inotify check which was failing with 2.4 kernels
+- added support for lastfmlib, thanks to Dirk Vanden Boer vor the
+  patch
+- increased buffer length for the exif field following the request
+  from one of our users
+- fixed a problem where the upnp-string-limit function was not
+  correctly truncating UTF-8 strings
+- fixed a bug where --enable-id3lib did not turn off the automatic
+  enabling of taglib, which then resulted in an error message saying, 
+  that both libraries are enabled
+- implemented feature request #2833402 - ability to change
+  ffmpegthumbnailer param "image quallity"
+- fixed bug #2783557 - Mediatomb always flags file as chunked output,
+  thanks to Michael Guntsche
+- fixed bug #2804342 - wrong namespace in <serviceId>
+- added a fix for glibc 2.10, thanks to Honoome for the patch
+- added patches for NetBSD, thanks to Jared D. McNeill
+- fixed bug #2944701 Adding comment in config as last line yields
+  segfault
+- fixed bug #2779907 SQLITE3: (1) cannot start a transaction within a
+  transaction
+- fixed bug #2820213 build broken with libmp4v2-1.9.0
+- fixed bug #2161155 inotify thread aborts 
+- fixed bug #2011296 SVN rev 1844 doesn't show more than 10 files on
+  PS3
+- fixed bug #1988738 web ui docs miss note how to access web ui
+- fixed bug #1929230 invalid XML in UPNP messages
+- fixed bug #1865386 autoscan dir already exists error 
+- implemented feature request #2313953 support for forked libmp4v2
+  project
+- implemented feature request #1955192 flag/mark watched video files
+- implemented feature request #1928580 better logging/tracing support
+- implemented feature request #1754010 m4a metadata extraction
+
+### MediaTomb v0.11.0 01.03.2008  External transcoding support
+- implemented transcoding support that allows to plug in an arbitrary
+  transcoding application
+- added fourcc detection for AVI files and transcoding options to 
+  limit transcoding to certain fourcc's
+- added new metadata extractor using ffmpeg, patch submitted by 
+  Ingo Preiml
+- added vorbis / theora detection for ogg containers, so video files
+  should not end up in audio containers anymore
+- fixed bug where database-file option was still checked even when
+  MySQL was selected in the configuration
+- fixed a bug where check of the home directory was enforced even if 
+  the configuration file was specified on command line
+- UTF-8 fix suggested by piman - taglib should handle UTF-8 correctly, 
+  so we will request an UTF-8 string from taglib and do not do the 
+  conversion ourselves
+- UTF-8 fix for libextractor, basically same as with TagLib
+- added default mapping for flv files since they are not correctly
+  recognized by libmagic
+- fixed a bug where we could get crashed by a missing URL parameter
+  sent to the UI
+- fixed 64bit related issues in the UPnP SDK
+- fixed a problem where ID3 tags were not detected with id3lib
+- fixed off by one errors in StringBuffer class, thanks to stigpo for
+  the patch
+- fixed bug #1824216 - encoded URLs were not treated properly
+- made sure that log output is always flushed
+- made temporary directory configurable
+- using expat as XML parser
+- new XML generator - support for comments
+- changed layout of the storage configuration XML
+- added migration for old config.xml
+- speed up sqlite3 by setting synchronous=off by default
+- adding automatic database backup for sqlite3
+- adding automatic backup restore on sqlite3 database corruption
+- fix permission problem - supplementary groups weren't set by
+  initgroups()
+- fixed js (spidermonkey) related crashes
+- fix mysql reconnect issue - charset was lost after reconnect
+- added check to avoid coredump when max number of inotify watches
+  has been reached
+- made sure that range requests specified as "bytes=0-" do not trigger
+  a 416 response for media where the filesize is unknown
+- added fix for chunked encoding that was posted on the maemo forums
+- fixed configure to determine if iconv needs the const char cast or
+  not (fixes OSX compilation problem)
+- added album art support for the PS3
+- fixed a bug where path used by add container chain was not converted
+  to UTF-8
+- added patch for author and director extraction from id3 tags, 
+  submitted by Reinhard Enders
+- init script for fedora now uses the -e option instead of grepping
+  for the IP (old variant only worked on systems with english
+  language)
+- updated spec file with changes from Marc Wiriadisastra
+- we now are also providing the filesize along with the other metadata
+- added environment variables that can be used for additional server
+  configuration (useful for directory independent NAS setups)
+- added comments and examples to the config.xml that is generated by
+  the server
+- added patch from Gabriel Burca to extract keywords from id3 tags
+- added runtime inotify detection
+- added a workaround for the Noxon V1 which for some reasons sends 
+  us a double encoded ampersand XML sequences in the URL
+- implemented feature request #1771561, extension to mimetype mappings
+  can now be case insensitive
+
+### MediaTomb v0.10.0	11.07.2007  Playlist and inotify autoscan support.
+- MySQL database version pumped to 3 (MediaTomb will automatically
+  update the database during the first launch)
+- Sqlite3 database version pumped to 2 (MediaTomb will automatically
+  update the database during the first launch)
+- added support for inotify based autoscan
+- playlist support - parsing playlist via js is now possible
+- added network interface option
+- added workaround for a PS3 related problem, where sockets were left
+  open (bug #1732412)
+- improved iconv handling of illegal characters
+- added character conversion safeguards to make sure that non UTF-8
+  strings do not make it into the database from js scripts
+- made character conversion functions available to js
+- added option to hide PC Directory from UPnP renderers
+- added album art support, album art is extracted from ID3 tags
+  and offered to UPnP devices
+
+### MediaTomb v0.9.1  28.05.2007  Playstation 3 support
+- added support for Playstation 3
+- added command line option that allows to tell the server where to
+  put the configuration upon first startup
+- fixed a fseeko-check related bug in configure
+- the configure script now honors the LDFLAGS while checking for sqlite3
+- fixed wrong message printout in configure
+- PC Directory can now be renamed in the UI
+- fixed a bug in configure.ac, the --with-extractor-libs= parameter
+  didn't work
+- fixed a MySQL related bug, if the path or filename contained non-UTF8
+  characters, the inserted strings weren't complete
+- circumvented a bug/feature of older MySQL versions, that caused the
+  MySQL database creation script to fail
+- MySQL database version pumped to 2 (MediaTomb will automatically
+  update the database during the first launch)
+
+### MediaTomb v0.9.0  25.03.2007  Major rework
+- the UI was completely rewritten from scratch; it uses AJAX for all
+  requests
+- integrated libupnp (http://pupnp.sf.net/) into our source tree
+- added largefile support
+- code has undergone some performance optimizations
+- fixed a bug where server did not shutdown while http download
+  was in progress
+- all sqlite3 queries are now handled by a single, dedicated
+  thread to make MediaTomb work with SQLite3 compiled with
+  "--enable-threadsafe"
+- fixed a bug where setting -p 0 did not trigger automatic
+  port selection if it had to override the value in config.xml
+- fixed bug 1425424 - crash on a bad config.xml - we did not handle 
+  the case where the <udn> tag was not present.
+  Thanks to Nektarios K. Papadopoulos <npapadop at users.sourceforge.net>
+  for the report and patch.
+- added configure option and adapted the code to completely 
+  supress all log output
+- added configure option and adapted the code to supress
+  debug output
+- added taglib support, thanks to Benhur Stein <benhur.stein at gmail.com>
+  for the patch. 
+- bug 1524468 (startup in daemon mode fails) does no longer occur
+  after the integration of libupnp 1.4.x sources
+- fixed bug 1292295 (string conversion was failing on 64bit platforms)
+- fixed issue with ContainerUpdateIDs (were not sent out along with
+  accepted subscription)
+- fixed issue where some directories could not be browsed (filesystem 
+  browser). It turned out that we forgot to convert the filenames
+  to UTF-8, as the result invalid characters made their way into
+  the XML that was feeded to the browser.
+- improved illegal character conversion handling - in case iconv
+  fails we will pad the rest of the name string with "?" and print
+  out the failed name in the console.
+- we now try to determine the default import charsets by looking
+  at the system locale.
+- implemented track number metadata extraction (feature request
+  1430799). track numbers are now extracted via id3lib/taglib and
+  can also be used in the import script. import.js has been adapted
+  to add tracknumbers to song names in the Album container.
+- added option to supress hidden files when browsing the filesystem
+- added X_MS_MediaReceiverRegistrar Service to allow future Xbox 360 
+  support
+- added workarounds to enable Telegent TG100 avi playback
+- server can now be restarted by sending it a SIGHUP
+- the current configuration file will never be displayed in the UI and
+  will never be added to the database - we do not want the user to
+  accidentally share it on the network since it may contain
+  security sensitive data
+- tomb-install is no longer needed, the server will automatically create
+  a default ~/.mediatomb/config.xml file if there is none
+- the database tables will be created automatically if they don't
+  exist
+- adapted configure script to correctly set flags for linkers that
+  use the --as-needed option
+- the "PC Directory" isn't changeable via the UI anymore to ensure a
+  correct view of the "PC Directory"
+- lookups in the database are now done with hashes, which should make
+  many things faster, especially the adding
+- changed the database field "location" from varchar(255) to text to
+  allow urls and locations of unlimited size
+- created a new theme for the UI
+- added support for "blind" .srt requests - some renderers like the
+  DSM320 will blindly request the url provided via browse, replacing
+  and found file extension with .srt, we will look for the .srt file
+  in the directory where the original media is located, using the
+  same filename, but with the .srt extension
+- created XML schema for "config.xml" to provide the possiblity of
+  validating the configuration
+- added fallback if js is not available - there is a builtin feature
+  to create a default virtual layout now; config.xml has got an
+  option to select the virtual-layout type, it can be builting, js or
+  disabled.
+- added charset option to the import script, it is not possible to
+  specify the script encoding
+- we now validate filesystem, metadata and scripting charsets upon 
+  startup
+- added a special option that allows limiting title and description
+  lengths in UPnP browse replies to a specified length; this was
+  necessary to work around a bug in the TG100 that has problems
+  browsing items where title length exceeds 101 characters.
+- import.js can now specify the upnp class of the last container in the
+  chain
+- all items within a container which upnp class is set to 
+  object.container.album.musicAlbum will automatically be sorted by 
+  track number.
+- added option to configure the presentation URL to make it easier
+  for NAS vendors to integrate the server into their web UI
+- made model number configurable
+
+### MediaTomb v0.8.1	07.09.2005
+- added "serve" directory, any files there can be downloaded 
+  like from a normal webserver
+- implemented keyword extraction for auxdata from libexif
+- implemented keyword extraction for auxdata from libextractor
+- added Exif metadata support for images via libexif.
+- added resolution attribute to image res tag
+- added bitrate and duration attribute to mp3 res tag (via id3lib)
+- added auxdata field for items, auxilary data can be extracted
+  and used by import scripts.
+- added configuration options to specify which aux fields should 
+  be extracted and filled by the library.
+- added mysql support
+- refined configure script, almost all dependencies are now
+  optional.
+- changed database, (not backward compatible again)
+- when an item is deleted all referenced items are deleted as well
+- added option to specify an alternative magic file
+
+### MediaTomb v0.8.0  15.06.2005  Scripting/Virtual Server Layout
+- Server layout can now be defined using java script,
+  default layout script is provided.
+- Added ID3 tag support.
+- Fixed various memory leaks.
+- Files in the Filesystem Browser are now sorted alphabetically.
+- Added extension to mime-type mappings to the configuration.
+- Added option to limit import by file extensions.
+- Added daemon mode as well as setuid/setgid options, init.d
+  script included.
+- Fixed mime-type recognition when importing media (filemagic output
+  is now parsed using regular expressions)
+- Introduced new log system.
+- Adding/Browsing/Removing media in the UI is now handled
+  asynchroniously.
+- Added a command line option to import media upon server launch.
+- Added target directory option to tomb-install, cleaned up a few
+  things.
+
+### MediaTomb v0.7.1  17.04.2005  D-Link DSM-320 fix
+- Mappings of mime-types to upnp classes are now configurable.
+  Actually this is how we solved the DSM-320 problem - they
+  crashed if upnp class of items was different than what the
+  DSM expected.
+
+- tomb-install now creates the database and configuration file
+  from templates (was hardcoded); also sets the name of the server
+  individually for each user (host / username)
+
+- Improved handling of configuration, if non critical options are
+  missing we are now setting default values.
+
+### MediaTomb v0.7    14.04.2005  First release
+- The changelog does not start at day 0, updates will be made
+  starting from this release.
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index 007e939..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,370 +0,0 @@
-Installation Instructions
-*************************
-
-Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
-Inc.
-
-   Copying and distribution of this file, with or without modification,
-are permitted in any medium without royalty provided the copyright
-notice and this notice are preserved.  This file is offered as-is,
-without warranty of any kind.
-
-Basic Installation
-==================
-
-   Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package.  The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package.  Some packages provide this
-`INSTALL' file but do not implement all of the features documented
-below.  The lack of an optional feature in a given package is not
-necessarily a bug.  More recommendations for GNU packages can be found
-in *note Makefile Conventions: (standards)Makefile Conventions.
-
-   The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation.  It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions.  Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
-   It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring.  Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
-
-   If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release.  If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
-   The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'.  You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
-
-   The simplest way to compile this package is:
-
-  1. `cd' to the directory containing the package's source code and type
-     `./configure' to configure the package for your system.
-
-     Running `configure' might take a while.  While running, it prints
-     some messages telling which features it is checking for.
-
-  2. Type `make' to compile the package.
-
-  3. Optionally, type `make check' to run any self-tests that come with
-     the package, generally using the just-built uninstalled binaries.
-
-  4. Type `make install' to install the programs and any data files and
-     documentation.  When installing into a prefix owned by root, it is
-     recommended that the package be configured and built as a regular
-     user, and only the `make install' phase executed with root
-     privileges.
-
-  5. Optionally, type `make installcheck' to repeat any self-tests, but
-     this time using the binaries in their final installed location.
-     This target does not install anything.  Running this target as a
-     regular user, particularly if the prior `make install' required
-     root privileges, verifies that the installation completed
-     correctly.
-
-  6. You can remove the program binaries and object files from the
-     source code directory by typing `make clean'.  To also remove the
-     files that `configure' created (so you can compile the package for
-     a different kind of computer), type `make distclean'.  There is
-     also a `make maintainer-clean' target, but that is intended mainly
-     for the package's developers.  If you use it, you may have to get
-     all sorts of other programs in order to regenerate files that came
-     with the distribution.
-
-  7. Often, you can also type `make uninstall' to remove the installed
-     files again.  In practice, not all packages have tested that
-     uninstallation works correctly, even though it is required by the
-     GNU Coding Standards.
-
-  8. Some packages, particularly those that use Automake, provide `make
-     distcheck', which can by used by developers to test that all other
-     targets like `make install' and `make uninstall' work correctly.
-     This target is generally not run by end users.
-
-Compilers and Options
-=====================
-
-   Some systems require unusual options for compilation or linking that
-the `configure' script does not know about.  Run `./configure --help'
-for details on some of the pertinent environment variables.
-
-   You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment.  Here
-is an example:
-
-     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
-   *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
-   You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory.  To do this, you can use GNU `make'.  `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script.  `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.  This
-is known as a "VPATH" build.
-
-   With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory.  After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
-
-   On MacOS X 10.5 and later systems, you can create libraries and
-executables that work on multiple system types--known as "fat" or
-"universal" binaries--by specifying multiple `-arch' options to the
-compiler but only a single `-arch' option to the preprocessor.  Like
-this:
-
-     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
-                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
-                 CPP="gcc -E" CXXCPP="g++ -E"
-
-   This is not guaranteed to produce working output in all cases, you
-may have to build one architecture at a time and combine the results
-using the `lipo' tool if you have problems.
-
-Installation Names
-==================
-
-   By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc.  You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX', where PREFIX must be an
-absolute file name.
-
-   You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files.  If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
-   In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files.  Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.  In general, the
-default for these options is expressed in terms of `${prefix}', so that
-specifying just `--prefix' will affect all of the other directory
-specifications that were not explicitly provided.
-
-   The most portable way to affect installation locations is to pass the
-correct locations to `configure'; however, many packages provide one or
-both of the following shortcuts of passing variable assignments to the
-`make install' command line to change installation locations without
-having to reconfigure or recompile.
-
-   The first method involves providing an override variable for each
-affected directory.  For example, `make install
-prefix=/alternate/directory' will choose an alternate location for all
-directory configuration variables that were expressed in terms of
-`${prefix}'.  Any directories that were specified during `configure',
-but not in terms of `${prefix}', must each be overridden at install
-time for the entire installation to be relocated.  The approach of
-makefile variable overrides for each directory variable is required by
-the GNU Coding Standards, and ideally causes no recompilation.
-However, some platforms have known limitations with the semantics of
-shared libraries that end up requiring recompilation when using this
-method, particularly noticeable in packages that use GNU Libtool.
-
-   The second method involves providing the `DESTDIR' variable.  For
-example, `make install DESTDIR=/alternate/directory' will prepend
-`/alternate/directory' before all installation names.  The approach of
-`DESTDIR' overrides is not required by the GNU Coding Standards, and
-does not work on platforms that have drive letters.  On the other hand,
-it does better at avoiding recompilation issues, and works well even
-when some directory options were not specified in terms of `${prefix}'
-at `configure' time.
-
-Optional Features
-=================
-
-   If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-   Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System).  The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
-   For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-   Some packages offer the ability to configure how verbose the
-execution of `make' will be.  For these packages, running `./configure
---enable-silent-rules' sets the default to minimal output, which can be
-overridden with `make V=1'; while running `./configure
---disable-silent-rules' sets the default to verbose, which can be
-overridden with `make V=0'.
-
-Particular systems
-==================
-
-   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
-CC is not installed, it is recommended to use the following options in
-order to use an ANSI C compiler:
-
-     ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
-
-and if that doesn't work, install pre-built binaries of GCC for HP-UX.
-
-   HP-UX `make' updates targets which have the same time stamps as
-their prerequisites, which makes it generally unusable when shipped
-generated files such as `configure' are involved.  Use GNU `make'
-instead.
-
-   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
-parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
-a workaround.  If GNU CC is not installed, it is therefore recommended
-to try
-
-     ./configure CC="cc"
-
-and if that doesn't work, try
-
-     ./configure CC="cc -nodtk"
-
-   On Solaris, don't put `/usr/ucb' early in your `PATH'.  This
-directory contains several dysfunctional programs; working variants of
-these programs are available in `/usr/bin'.  So, if you need `/usr/ucb'
-in your `PATH', put it _after_ `/usr/bin'.
-
-   On Haiku, software installed for all users goes in `/boot/common',
-not `/usr/local'.  It is recommended to use the following options:
-
-     ./configure --prefix=/boot/common
-
-Specifying the System Type
-==========================
-
-   There may be some features `configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on.  Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
-`--build=TYPE' option.  TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
-     CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
-     OS
-     KERNEL-OS
-
-   See the file `config.sub' for the possible values of each field.  If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
-   If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
-produce code for.
-
-   If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
-   If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists.  Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
-   Variables not defined in a site shell script can be set in the
-environment passed to `configure'.  However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost.  In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'.  For example:
-
-     ./configure CC=/usr/local2/bin/gcc
-
-causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf limitation.  Until the limitation is lifted, you can use
-this workaround:
-
-     CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-`configure' Invocation
-======================
-
-   `configure' recognizes the following options to control how it
-operates.
-
-`--help'
-`-h'
-     Print a summary of all of the options to `configure', and exit.
-
-`--help=short'
-`--help=recursive'
-     Print a summary of the options unique to this package's
-     `configure', and exit.  The `short' variant lists options used
-     only in the top level, while the `recursive' variant lists options
-     also present in any nested packages.
-
-`--version'
-`-V'
-     Print the version of Autoconf used to generate the `configure'
-     script, and exit.
-
-`--cache-file=FILE'
-     Enable the cache: use and save the results of the tests in FILE,
-     traditionally `config.cache'.  FILE defaults to `/dev/null' to
-     disable caching.
-
-`--config-cache'
-`-C'
-     Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
-     Do not print messages saying which checks are being made.  To
-     suppress all normal output, redirect it to `/dev/null' (any error
-     messages will still be shown).
-
-`--srcdir=DIR'
-     Look for the package's source code in directory DIR.  Usually
-     `configure' can determine that directory automatically.
-
-`--prefix=DIR'
-     Use DIR as the installation prefix.  *note Installation Names::
-     for more details, including other options available for fine-tuning
-     the installation locations.
-
-`--no-create'
-`-n'
-     Run the configure checks, but stop before creating any output
-     files.
-
-`configure' also accepts some other, not widely useful, options.  Run
-`configure --help' for more details.
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..64430ab
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,268 @@
+**Note that the only valid version of the GPL for MediaTomb is this particular 
+version of the license (ie v2, not v2.2 or v3.x or whatever), unless 
+explicitly otherwise stated.**
+
+The GNU General Public License, Version 2, June 1991 (GPLv2)
+============================================================
+
+> Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+> 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+
+Preamble
+--------
+
+The licenses for most software are designed to take away your freedom to share
+and change it. By contrast, the GNU General Public License is intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users. This General Public License applies to most
+of the Free Software Foundation's software and to any other program whose
+authors commit to using it. (Some other Free Software Foundation software is
+covered by the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+When we speak of free software, we are referring to freedom, not price. Our
+General Public Licenses are designed to make sure that you have the freedom to
+distribute copies of free software (and charge for this service if you wish),
+that you receive source code or can get it if you want it, that you can change
+the software or use pieces of it in new free programs; and that you know you can
+do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to deny
+you these rights or to ask you to surrender the rights. These restrictions
+translate to certain responsibilities for you if you distribute copies of the
+software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or for a
+fee, you must give the recipients all the rights that you have. You must make
+sure that they, too, receive or can get the source code. And you must show them
+these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2) offer
+you this license which gives you legal permission to copy, distribute and/or
+modify the software.
+
+Also, for each author's protection and ours, we want to make certain that
+everyone understands that there is no warranty for this free software. If the
+software is modified by someone else and passed on, we want its recipients to
+know that what they have is not the original, so that any problems introduced by
+others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We wish
+to avoid the danger that redistributors of a free program will individually
+obtain patent licenses, in effect making the program proprietary. To prevent
+this, we have made it clear that any patent must be licensed for everyone's free
+use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification
+follow.
+
+
+Terms And Conditions For Copying, Distribution And Modification
+---------------------------------------------------------------
+
+**0.** This License applies to any program or other work which contains a notice
+placed by the copyright holder saying it may be distributed under the terms of
+this General Public License. The "Program", below, refers to any such program or
+work, and a "work based on the Program" means either the Program or any
+derivative work under copyright law: that is to say, a work containing the
+Program or a portion of it, either verbatim or with modifications and/or
+translated into another language. (Hereinafter, translation is included without
+limitation in the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not covered by
+this License; they are outside its scope. The act of running the Program is not
+restricted, and the output from the Program is covered only if its contents
+constitute a work based on the Program (independent of having been made by
+running the Program). Whether that is true depends on what the Program does.
+
+**1.** You may copy and distribute verbatim copies of the Program's source code
+as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this License
+and to the absence of any warranty; and give any other recipients of the Program
+a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you may at
+your option offer warranty protection in exchange for a fee.
+
+**2.** You may modify your copy or copies of the Program or any portion of it,
+thus forming a work based on the Program, and copy and distribute such
+modifications or work under the terms of Section 1 above, provided that you also
+meet all of these conditions:
+
+*   **a)** You must cause the modified files to carry prominent notices stating
+    that you changed the files and the date of any change.
+
+*   **b)** You must cause any work that you distribute or publish, that in whole
+    or in part contains or is derived from the Program or any part thereof, to
+    be licensed as a whole at no charge to all third parties under the terms of
+    this License.
+
+*   **c)** If the modified program normally reads commands interactively when
+    run, you must cause it, when started running for such interactive use in the
+    most ordinary way, to print or display an announcement including an
+    appropriate copyright notice and a notice that there is no warranty (or
+    else, saying that you provide a warranty) and that users may redistribute
+    the program under these conditions, and telling the user how to view a copy
+    of this License. (Exception: if the Program itself is interactive but does
+    not normally print such an announcement, your work based on the Program is
+    not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Program, and can be reasonably
+considered independent and separate works in themselves, then this License, and
+its terms, do not apply to those sections when you distribute them as separate
+works. But when you distribute the same sections as part of a whole which is a
+work based on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the entire whole,
+and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise the
+right to control the distribution of derivative or collective works based on the
+Program.
+
+In addition, mere aggregation of another work not based on the Program with the
+Program (or with a work based on the Program) on a volume of a storage or
+distribution medium does not bring the other work under the scope of this
+License.
+
+**3.** You may copy and distribute the Program (or a work based on it, under
+Section 2) in object code or executable form under the terms of Sections 1 and 2
+above provided that you also do one of the following:
+
+*   **a)** Accompany it with the complete corresponding machine-readable source
+    code, which must be distributed under the terms of Sections 1 and 2 above on
+    a medium customarily used for software interchange; or,
+
+*   **b)** Accompany it with a written offer, valid for at least three years, to
+    give any third party, for a charge no more than your cost of physically
+    performing source distribution, a complete machine-readable copy of the
+    corresponding source code, to be distributed under the terms of Sections 1
+    and 2 above on a medium customarily used for software interchange; or,
+
+*   **c)** Accompany it with the information you received as to the offer to
+    distribute corresponding source code. (This alternative is allowed only for
+    noncommercial distribution and only if you received the program in object
+    code or executable form with such an offer, in accord with Subsection b
+    above.)
+
+The source code for a work means the preferred form of the work for making
+modifications to it. For an executable work, complete source code means all the
+source code for all modules it contains, plus any associated interface
+definition files, plus the scripts used to control compilation and installation
+of the executable. However, as a special exception, the source code distributed
+need not include anything that is normally distributed (in either source or
+binary form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component itself
+accompanies the executable.
+
+If distribution of executable or object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the source code
+from the same place counts as distribution of the source code, even though third
+parties are not compelled to copy the source along with the object code.
+
+**4.** You may not copy, modify, sublicense, or distribute the Program except as
+expressly provided under this License. Any attempt otherwise to copy, modify,
+sublicense or distribute the Program is void, and will automatically terminate
+your rights under this License. However, parties who have received copies, or
+rights, from you under this License will not have their licenses terminated so
+long as such parties remain in full compliance.
+
+**5.** You are not required to accept this License, since you have not signed
+it. However, nothing else grants you permission to modify or distribute the
+Program or its derivative works. These actions are prohibited by law if you do
+not accept this License. Therefore, by modifying or distributing the Program (or
+any work based on the Program), you indicate your acceptance of this License to
+do so, and all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+**6.** Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these terms and
+conditions. You may not impose any further restrictions on the recipients'
+exercise of the rights granted herein. You are not responsible for enforcing
+compliance by third parties to this License.
+
+**7.** If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues), conditions
+are imposed on you (whether by court order, agreement or otherwise) that
+contradict the conditions of this License, they do not excuse you from the
+conditions of this License. If you cannot distribute so as to satisfy
+simultaneously your obligations under this License and any other pertinent
+obligations, then as a consequence you may not distribute the Program at all.
+For example, if a patent license would not permit royalty-free redistribution of
+the Program by all those who receive copies directly or indirectly through you,
+then the only way you could satisfy both it and this License would be to refrain
+entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply and the
+section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or
+other property right claims or to contest validity of any such claims; this
+section has the sole purpose of protecting the integrity of the free software
+distribution system, which is implemented by public license practices. Many
+people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose that
+choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+**8.** If the distribution and/or use of the Program is restricted in certain
+countries either by patents or by copyrighted interfaces, the original copyright
+holder who places the Program under this License may add an explicit
+geographical distribution limitation excluding those countries, so that
+distribution is permitted only in or among countries not thus excluded. In such
+case, this License incorporates the limitation as if written in the body of this
+License.
+
+**9.** The Free Software Foundation may publish revised and/or new versions of
+the General Public License from time to time. Such new versions will be similar
+in spirit to the present version, but may differ in detail to address new
+problems or concerns.
+
+Each version is given a distinguishing version number. If the Program specifies
+a version number of this License which applies to it and "any later version",
+you have the option of following the terms and conditions either of that version
+or of any later version published by the Free Software Foundation. If the
+Program does not specify a version number of this License, you may choose any
+version ever published by the Free Software Foundation.
+
+**10.** If you wish to incorporate parts of the Program into other free programs
+whose distribution conditions are different, write to the author to ask for
+permission. For software which is copyrighted by the Free Software Foundation,
+write to the Free Software Foundation; we sometimes make exceptions for this.
+Our decision will be guided by the two goals of preserving the free status of
+all derivatives of our free software and of promoting the sharing and reuse of
+software generally.
+
+
+No Warranty
+-----------
+
+**11.** BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM
+"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+**12.** IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
+OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
diff --git a/Makefile.am b/Makefile.am
deleted file mode 100644
index 7381051..0000000
--- a/Makefile.am
+++ /dev/null
@@ -1,4 +0,0 @@
-SUBDIRS = tombupnp build scripts web config doc artwork
-
-EXTRA_DIST = mediatomb.spec README.UTF_8
-
diff --git a/NEWS b/NEWS
deleted file mode 100644
index 1d41d4b..0000000
--- a/NEWS
+++ /dev/null
@@ -1,2 +0,0 @@
-Please visit http://mediatomb.cc/news for the latest project news.
-
diff --git a/README b/README
deleted file mode 100644
index 34db00c..0000000
--- a/README
+++ /dev/null
@@ -1,3450 +0,0 @@
-MediaTomb - UPnP MediaServer
-
-   This documentation is valid for MediaTomb version 0.12.1.
-
-   Copyright (c) 2005 Gena Batsyan, Sergey Bostandzhyan
-
-   Copyright (c) 2006-2010, 2013 Gena Batsyan, Sergey Bostandzhyan,
-   Leonhard Wimmer
-
-   THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR
-   OWN RISK!
-     __________________________________________________________
-
-   Table of Contents
-
-   1. Introduction
-
-        1.1. Currently Supported Features
-
-   2. Requirements
-   3. Compiling From Source
-
-        3.1. Standard Method
-        3.2. Configure Options
-
-   4. Initial Installation
-
-        4.1. Network Setup
-        4.2. First Time Launch
-
-   5. Command Line Options
-
-        5.1. IP Address
-        5.2. Interface
-        5.3. Port
-        5.4. Configuration File
-        5.5. Daemon Mode
-        5.6. Home Directory
-        5.7. Config Directory
-        5.8. Write PID File
-        5.9. Run Under Different User Name
-        5.10. Run Under Different Group
-        5.11. Add Content
-        5.12. Log To File
-        5.13. Debug Output
-        5.14. Compile Info
-        5.15. Version Information
-        5.16. Display Command Line Summary
-
-   6. Configuration File
-
-        6.1. Server Settings
-        6.2. Import Settings
-        6.3. Transcoding Settings
-
-   7. Supported Devices
-
-        7.1. MediaRenderers
-        7.2. Network Attached Storage Devices
-
-   8. Running The Server
-   9. Legal
-
-        9.1. Copyright
-        9.2. License
-
-   10. Acknowledgments
-   11. Contributions
-
-1. Introduction
-
-   MediaTomb is an open source (GPL) UPnP MediaServer with a nice
-   web user interface, it allows you to stream your digital media
-   through your home network and listen to/watch it on a variety
-   of UPnP compatible devices.
-
-   MediaTomb implements the UPnP MediaServer V 1.0 specification
-   that can be found on http://www.upnp.org/. The current
-   implementation focuses on parts that are required by the
-   specification, however we look into extending the functionality
-   to cover the optional parts of the spec as well.
-
-   MediaTomb should work with any UPnP compliant MediaRenderer,
-   please tell us if you experience difficulties with particular
-   models, also take a look at the Supported Devices list for more
-   information.
-
-WARNING!
-
-   The server has an integrated file system browser in the UI,
-   that means that anyone who has access to the UI can browse your
-   file system (with user permissions under which the server is
-   running) and also download your data! If you want maximum
-   security - disable the UI completely! Account authentication
-   offers simple protection that might hold back your kids, but it
-   is not secure enough for use in an untrusted environment!
-
-   Note:
-          since the server is meant to be used in a home LAN
-          environment the UI is enabled by default and accounts
-          are deactivated, thus allowing anyone on your network to
-          connect to the user interface.
-
-1.1. Currently Supported Features
-
-     * browse and playback your media via UPnP
-     * metadata extraction from mp3, ogg, flac, jpeg, etc. files.
-     * Exif thumbnail support
-     * user defined server layout based on extracted metadata
-       (scriptable virtual containers)
-     * automatic directory rescans
-     * sophisticated web UI with a tree view of the database and
-       the file system, allowing to add/remove/edit/browse your
-       media
-     * highly flexible media format transcoding via plugins /
-       scripts
-     * allows to watch YouTube(tm) videos on your UPnP player
-       device
-     * supports last fm scrobbing using lastfmlib
-     * on the fly video thumbnail generation with
-       libffmpegthumbnailer
-     * support for external URLs (create links to internet content
-       and serve them via UPnP to your renderer)
-     * support for ContentDirectoryService container updates
-     * Active Items (experimental feature), allows execution of
-       server side scripts upon HTTP GET requests to certain items
-     * highly flexible configuration, allowing you to control the
-       behavior of various features of the server
-     * runs on Linux, FreeBSD, NetBSD, Mac OS X, eCS
-     * runs on x86, Alpha, ARM, MIPS, Sparc, PowerPC
-
-2. Requirements
-
-   Note:
-          remember to install associated development packages,
-          because development headers are needed for compilation!
-
-   Note:
-          libupnp is now a part of MediaTomb and does not have to
-          be installed separately. We base our heavily patched
-          version on libupnp 1.4.1 from http://pupnp.sf.net/
-
-   Note:
-          you need at least one database in order to compile and
-          run MediaTomb - either sqlite or mysql.
-
-   In order to compile MediaTomb you will have to install the
-   following packages.:
-     * sqlite (version > 3.x) http://www.sqlite.org/ REQUIRED (if
-       mysql is not available)
-     * mysql client library (version > 4.0.x) http://mysql.org/
-       REQUIRED (if sqlite is not available)
-     * expat http://expat.sourceforge.net/ REQUIRED
-       Expat is a very good and robust XML parser, since most of
-       UPnP is based on XML this package is a requirement.
-     * zlib http://www.zlib.net/ OPTIONAL, HIGHLY RECOMMENDED
-       Zlib is a compression library that is available on most
-       systems, we need it for the database autocreation
-       functionality. Make sure to install the zlib development
-       package providing zlib.h, if it is not available you will
-       need to create the MediaTomb sqlite3/MySQL database
-       manually.
-     * libmagic OPTIONAL, RECOMMENDED
-       This is the 'file' package, it is used to determine the
-       mime type of the media. If you don't have this you will
-       have to enter file extension to mime type mappings manually
-       in your config file.
-     * js - SpiderMonkey JavaScript Engine
-       http://www.mozilla.org/js/spidermonkey/ OPTIONAL,
-       RECOMMENDED, REQUIRED FOR PLAYLIST SUPPORT
-       This package is necessary to allow the user defined
-       creation of virtual containers. The import.js script
-       defines the layout of your media, the default import script
-       will create a structure sorted by Audio/Photo/Video, it
-       will make use of the gathered metadata (like ID3 tags) to
-       sort your music by Artist/Album/Genre/Year , etc. The
-       import script can be adjusted and modified - it allows you
-       to create the layout that you want.
-     * taglib http://developer.kde.org/~wheeler/taglib.html
-       OPTIONAL, RECOMMENDED
-       This library retrieves metadata from mp3, ogg and flac
-       files. You will need it if you want to have virtual objects
-       for those files (i.e. nice content layout).
-
-        Note:
-                It makes no sense to use taglib and id3lib at the
-                same time, the configure script will first look
-                for TagLib, if TagLib detection fails it will
-                search for id3lib. You can also force the
-                configure script to take the library of your
-                choice, overriding the default setting.
-
-     * id3lib http://id3lib.sourceforge.net/ (at least version
-       3.8.3) OPTIONAL, RECOMMENDED (if TagLib is not available)
-       This library retrieves id3 tags from mp3 files.
-     * libexif http://libexif.sourceforge.net/ OPTIONAL,
-       RECOMMENDED
-       You will need this library if you want to extract metadata
-       from images, this will allow you to have virtual containers
-       for your Photos, sorted by various attributes like Date,
-       etc. It also enables thumbnail support: if EXIF thumbnails
-       are present in your images they will also be offered via
-       UPnP.
-     * curl http://curl.haxx.se/ OPTIONAL, REQUIRED FOR YOUTUBE
-       AND SOPCAST SUPPORT
-       curl is a library that allows to easily fetch content from
-       the web, if you want to compile MediaTomb with YouTube
-       and/or SopCast support then curl is required.
-     * ffmpeg http://ffmpeg.mplayerhq.hu/ OPTIONAL
-       Currently ffmpeg is used to gather additional metadata from
-       audio and video files.
-     * libffmpegthumbnailer
-       http://code.google.com/p/ffmpegthumbnailer/ OPTIONAL
-       ffmpegthumbnailer is used to generate video thumbnails on
-       the fly. If your device (like DSM-510 or PlayStation 3)
-       supports video thumbnails it would be worth to compile
-       MediaTomb with this library.
-
-        Note:
-                ffmpegthumbnailer support is only provided if
-                MediaTomb is compiled with ffmpeg support.
-
-     * lastfmlib http://code.google.com/p/lastfmlib/ OPTIONAL
-       last.fm scrobbing
-
-   In order to use the web UI you will need to have javascript
-   enabled in your web browser.
-
-   The UI has been tested and works with the recent versions of :
-     * Firefox/Mozilla
-     * Opera
-
-   Tested and does not work with the recent versions of:
-     * Konqueror
-     * Safari
-
-   Limited functionality with:
-     * Internet Explorer 6 and 7
-
-3. Compiling From Source
-
-3.1. Standard Method
-
-   If you don't care about the details - make sure you have
-   installed the required packages and the appropriate development
-   headers and simply run
-$ ./configure
-$ make
-$ make install
-
-   This should compile and install MediaTomb, the resulting binary
-   is ready to run.
-
-   Note:
-          if you checked out the sources from SVN the configure
-          script will not be available, you will have to create it
-          with the following command:
-
-autoreconf -i
-
-3.2. Configure Options
-
-   The MediaTomb configure script provides a large variety of
-   options, allowing you to specify the additional libraries that
-   will be used, features that will be compiled or disabled,
-   workarounds for known bugs in some distributions and so on.
-   Some options are straightforward, some require deeper knowledge
-   - make sure you know what you are doing :)
-
-3.2.1. Install Location Of Architecture Independent Files
-
---prefix=PREFIX
-
-   Default:
-          /usr/local/
-
-   Install all architecture independent files - all .js files and
-   .png images for the Web UI, the import.js script, the service
-   description XML files - in the directory of your choice. This
-   is especially useful if you do not want to perform a
-   system-wide installation, but want to install MediaTomb only
-   for your user.
-
-   Important:
-          the prefix path will be compiled into the binary; the
-          binary will still be relocatable, but you move those
-          files you will have to point MediaTomb to the proper
-          location by specifying it in the server configuration
-          file.
-
-3.2.2. Static Build
-
---enable-static
-
-   Default:
-          disabled
-
-   Build a static binary. This may be useful if you plan to
-   install a precompiled MediaTomb binary on a system that does
-   not have all the required libraries and where installation of
-   those libraries is not possible due to reasons beyond your
-   control.
-
-   Note:
-          if you enable this option, make sure that you have all
-          static versions of the appropriate libraries installed
-          on your system. The configure script may not detect that
-          those are missing - in this case you will get linker
-          errors. Some distributions, for example Fedora Core, do
-          not ship static library versions.
-
-3.2.3. Automatically Create Database
-
---enable-db-autocreate
-
-   Default:
-          enabled
-
-   Automatically create the database if it is missing (for example
-   upon a first time launch). Disabling this will make the
-   resulting binary a little smaller, however you will have to
-   take care of the database creation yourself by invoking the
-   appropriate .sql scripts that are provided with the package.
-
-   Note:
-          the server configuration file has to be setup correctly.
-          Either sqlite or MySQL has to be chosen in the storage
-          section, for sqlite the database file has to point to a
-          writable location, for MySQL the user has to be setup
-          with a valid password and permissions and the database
-          "mediatomb" has to exist.
-
-3.2.4. Debug Malloc/Realloc Of Zero bytes
-
---enable-debug-malloc0
-
-   Default:
-          disabled
-
-   This feature is only for debugging purposes, whenever a malloc
-   or realloc with a value of zero bytes is encountered, the
-   server will terminate with abort()
-
-3.2.5. Force Linking With The Pthread Library
-
---enable-pthread-lib
-
-   Default:
-          disabled
-
-   We use the ACX_PTHREAD macro from the autoconf archive to
-   determine the way how to link against the pthread library.
-   Usually it works fine, but it can fail when cross compiling.
-   This configure option tells us to use -lpthread when linking,
-   it seems to be needed when building MediaTomb under Optware.
-   Note, that using --disable-pthread-lib will not prevent
-   automatic checks against the pthread library.
-
-3.2.6. Force Linking With The Iconv Library
-
---enable-iconv-lib
-
-   Default:
-          disabled
-
-   By default we will attempt to use iconv functionality provided
-   with glibc, however under some circumstances it may make sense
-   to link against a separate iconv library. This option will
-   attempt to do that. Note, that using --disable-iconv-lib will
-   not prevent automatic attempts to link ageinst the iconv
-   library in the case where builtin glibc iconv functionality is
-   not available.
-
-3.2.7. Use Atomic Assembler Code For x86 Single CPU systems
-
---enable-atomic-x86-single
-
-   Default:
-          disabled
-
-   Use assembler code suited for single CPU x86 machines. This may
-   improve performance, but your binary will not function properly
-   on SMP systems. If you specify this for a non x86 architecture
-   the binary will not run at all. If you wonder about the purpose
-   of assembler code in a mediaserver application: we need it for
-   atomic operations that are required for reference counting. The
-   pthread library will be used as a fallback for other
-   architectures, but can also be forced by a designated configure
-   option. This however, will have the worst performance.
-
-   By default x86 SMP code will be used on x86 systems - it will
-   reliably work on both SMP and single CPU systems, but will not
-   be as fast as the atomic-x86-single option on uniprocessor
-   machines.
-
-3.2.8. Use Pthread Code For Atomic Operations
-
---enable-atomic-pthread
-
-   Default:
-          auto detect
-
-   This is the default setting for non x86 architectures, we may
-   add assembler optimizations for other architectures as well,
-   but currently only x86 optimizations are available. This option
-   may also be safely used on x86 machines - the drawback is poor
-   performance, compared to assembler optimized code.
-
-3.2.9. Enable SIGHUP Handling
-
---enable-sighup
-
-   This option turns on SIGHUP handling, every time a SIGHUP is
-   caught we will attempt to restart the server and reread the
-   configuration file. By default this feature is enabled for x86
-   platforms, but is disabled for others. We discovered that
-   MediaTomb will not cleanly restart on ARM based systems,
-   investigations revealed that this is somehow related to an
-   unclean libupnp shutdown. This will be fixed in a later
-   release.
-
-   Default:
-          auto detect
-
-3.2.10. X_MS_MediaReceiverRegistrar Support
-
---enable-mrreg-service
-
-   Default:
-          disabled
-
-   This option will enable the compilation and support of the
-   X_MS_MediaReceiverRegistrar UPnP service, this was implemented
-   for future Xbox 360 support. If you have a renderer that
-   requires this service, you can safely enable it. It will always
-   return true to IsValidated and IsAuthorized requests.
-
-   Note:
-          eventhough this service is implemented there is still no
-          Xbox 360 support in MediaTomb, more work needs to be
-          done.
-
-3.2.11. Playstation 3 Support
-
---enable-protocolinfo-extension
-
-   Default:
-          enabled
-
-   This option allows to send additional information in the
-   protocolInfo attribute, this will enable MP3 and MPEG4 playback
-   for the Playstation 3, but may also be useful to some other
-   renderers.
-
-   Note:
-          allthough compiled in, this feature is disabled in
-          configuration by default.
-
-3.2.12. Fseeko Check
-
---disable-fseeko-check
-
-   Default:
-          enabled
-
-   This is a workaround for a bug in some Debian distributions,
-   disable this check if you know that your system has large file
-   support, but configure fails to detect it.
-
-3.2.13. Largefile Support
-
---disable-largefile
-
-   Default:
-          auto
-
-   By default largefile support will be auto detected by
-   configure, however you can disable it if you do not want it or
-   if you experience problems with it on your system.
-
-3.2.14. Redefinition Of Malloc And Realloc
-
---disable-rpl-malloc
-
-   Default:
-          enabled
-
-   Autoconf may redefine malloc and realloc functions to
-   rpl_malloc and rpl_realloc, usually this will happen if the
-   autotools think that you are compiling against a non GNU C
-   library. Since malloc and realloc may behave different on other
-   systems, this gives us the opportunity to write wrapper
-   functions to handle special cases. However, this redefinition
-   may get triggered when cross compiling, even if you are
-   compiling against the GNU C lib. If this is the case, you can
-   use this option to disable the redefinition.
-
-3.2.15. SQLite Support
-
---enable-sqlite3
-
-   Default:
-          enabled
-
-   The SQLite database is very easy in installation and use, you
-   do not have to setup any users, permissions, etc. A database
-   file will be simply created as specified in the MediaTomb
-   configuration. At least SQLite version 3 is required.
-
-3.2.16. MySQL Support
-
---enable-mysql
-
-   Default:
-          enabled
-
-   MySQL is a very powerful database, however it requires some
-   additional setup. You will find information on how to setup
-   MediaTomb with MySQL in the Installation section.
-
-3.2.17. SpiderMonkey LibJS Support
-
---enable-libjs
-
-   Default:
-          enabled
-
-   SpiderMonkey is Mozilla's JavaScript engine, it plays a very
-   important role in MediaTomb. We use it to create a nice virtual
-   container layout based on the metadata that is extracted from
-   your media. We also allow the user to create custom import
-   scripts, so everyone has the possibility to adapt the layout to
-   ones personal needs. Read more about this in the installation
-   section.
-
-   The main problem with this library is, that it is called
-   differently on various distributions and that it is installed
-   in different locations. For example, it is called js on Fedora,
-   but is available under the name of smjs on Debian. If configure
-   fails to find your js headers and libraries you can point it to
-   the desired locations (see options below).
-
-3.2.18. Filemagic Support
-
---enable-libmagic
-
-   Default:
-          enabled
-
-   This library determines the file type and provides us with the
-   appropriate mime type information. It is very important to
-   correctly determine the mime type of your media - this
-   information will be sent to your renderer. Based on the mime
-   type information, the renderer will decide if it can
-   play/display the particular file or not. If auto detection
-   returns strange mime types, you may want to do a check using
-   the 'file' command (the 'file' package must be installed on
-   your system). Assuming that you want to check somefile.avi
-   enter the following in your terminal:
-$ file -i somefile.avi
-
-   This will print the detected mime type, this is exactly the
-   information that we use in MediaTomb. You can override auto
-   detection by defining appropriate file extension to mime type
-   mappings in your configuration file. You can also edit the mime
-   type information of an imported object manually via the web UI.
-
-3.2.19. Id3lib Support
-
---enable-id3lib
-
-   Default:
-          disabled, used if taglib is not available
-
-   This library will parse id3 tags of your MP3 files, the
-   gathered information will be saved in the database and provided
-   via UPnP. Further, the gathered metadata will be used by the
-   import script to create a nice container layout
-   (Audio/Artist/Album, etc.)
-
-3.2.20. Taglib Support
-
---enable-taglib
-
-   Default:
-          enabled, preffered over id3lib
-
-   This library will parse id3 tags of your MP3 files as well as
-   information provided with flac files. It claims to be faster
-   than id3lib, but it also seems to have some drawbacks. We had
-   some cases where it crashed when trying to parse tags of
-   certain MP3 files on embedded systems, we had reports and
-   observed that it had problems parsing the sample rates. We also
-   did some valgrinding and detected memory leaks. Our feeling is,
-   that you will have more stable results with id3lib, however it
-   is up to you to enable or disable this library. By default
-   id3lib will be taken if both libraries are present on the
-   system.
-
-3.2.21. Libexif Support
-
---enable-libexif
-
-   Default:
-          enabled
-
-   The exif library will gather metadata from your photos, it will
-   also find exif thumbnails which are created automatically by
-   most digital camera models. The gathered data will be used by
-   the import script, the thumbnails will be offered as additional
-   resources via UPnP.
-
-3.2.22. Inotify Support
-
---enable-inotify
-
-   Default:
-          auto
-
-   Inotify is a kernel mechanism that allows monitoring of
-   filesystem events. You need this if you want to use the Inotify
-   Autoscan mode, contrary to the Timed mode which recsans given
-   directories in specified intervals, Inotify mode will
-   immedeately propagate changes in monitored directories on the
-   filesystem to the database.
-
-   If you do not specify this option configure will check if
-   inotify works on the build system and compile it in only if the
-   check succeeds. If you specify this option, the functionality
-   will be compiled in even if the build system does not support
-   inotify - the availability of inotify will then be checked at
-   server runtime.
-
-3.2.23. YouTube Service Support
-
---enable-youtube
-
-   Default:
-          enabled
-
-   This option enabled support of the YouTube service, it allows
-   to gather information about content on the YouTube site and
-   offers the content via UPnP, thus enabling you to watch your
-   favorite YouTube videos on your UPnP player device. The feature
-   only makes sense in combination with transcoding, since most
-   devices do not support playback of flv files natively.
-
-3.2.24. External Transcoding
-
---enable-external-transcoding
-
-   Default:
-          enabled
-
-3.2.25. Sqlite Backup Defaults
-
---enable-sqlite-backup-defaults
-
-   Default:
-          disabled
-
-   Enables backup option for sqlite as the default setting, might
-   be useful for NAS builds.
-
-3.2.26. Curl
-
---enable-curl
-
-   Default:
-          enabled if external transcoding or YouTube features are
-          turned on
-
-   It only makes sense to enable the curl library if YouTube and
-   External Transcoding are turned on. YouTube requires curl, but
-   it's optional for External Transcoding.
-
-3.2.27. Ffmpeg Support
-
---enable-ffmpeg
-
-   Default:
-          enabled
-
-   Currently the ffmpeg library is used to extract additional
-   information from audio and video files. It is also capable of
-   reading out the tag information from theora content. It is not
-   yet used for transcoding, so this feature only gathers
-   additional metadata.
-
-3.2.28. Ffmpeg Thumbnailer Support
-
---enable-ffmpegthumbnailer
-
-   Default:
-          enabled
-
-   Compiling with ffmpegthumbnailer support is only possible if
-   you also compile with ffmpeg support. The library allows to
-   generate thumbnails for the videos on the fly.
-
-3.2.29. MediaTomb Debug Output
-
---enable-tombdebug
-
-   Default:
-          disabled
-
-   This option enables debug output, the server will print out a
-   lot of information which is mainly interesting to developers.
-   Use this if you are trying to trace down a bug or a problem,
-   the additional output may give you some clues.
-
-3.2.30. UPnP Library Debug Output
-
---enable-upnpdebug
-
-   Default:
-          disabled
-
-   This option enables debug output of the UPnP SDK. You should
-   not need it under normal circumstances.
-
-3.2.31. Log Output
-
---disable-log
-
-   Default:
-          enabled
-
-   This option allows you to suppress all log output from the
-   server.
-
-3.2.32. Debug Log Output
-
-   Default:
-          enabled
-
-   This option allows you to compile the server with debug
-   messages. If enabled, switching between verbose and normal
-   output during runtime becomes possible.
-
-3.2.33. Package Search Directory
-
---with-search=DIR
-
-   Default:
-          /opt/local/ on Darwin, /usr/local/ on all other systems
-
-   Some systems may have whole sets of packages installed in an
-   alternative location, for example Darwinports on OSX get
-   installed to /opt/local/. This option tells the configure
-   script to additionally search for headers and libraries of
-   various packages in DIR/include and DIR/lib.
-
-3.2.34. Specifying Header And Library Locations Of Various Packages
-
-   You can specify the exact location of particular headers and
-   libraries. Some packages use extra programs that tell us the
-   appropriate flags that are needed for compilation - like
-   mysql_config. You can also specify the exact location of those
-   programs. The parameters are self explanatory, in case of
-   headers and libraries the DIR parameter is the directory where
-   those headers and libraries are located.
---with-sqlite3-h=DIR               search for sqlite3 headers only in DI
-R
---with-sqlite3-libs=DIR            search for sqlite3 libraries only in
-DIR
---with-mysql-cfg=mysql_config      absolute path/name of mysql_config
---with-js-h=DIR                    search for js (spidermonkey) headers
-in DIR
---with-js-libs=DIR                 search for js (spidermonkey) librarie
-s in DIR
---with-libmagic-h=DIR              search for filemagic headers in DIR
---with-libmagic-libs=DIR           search for filemagic headers in DIR
---with-libexif-h=DIR               search for libexif headers in DIR
---with-libexif-libs=DIR            search for libexif libraries in DIR
---with-expat-h=DIR                 search for expat headers in DIR
---with-expat-libs=DIR              search for expat libraries in DIR
---with-taglib-cfg=taglib-config    absolute path/name of taglib-config
---with-id3lib-h=DIR                search for id3lib headers in DIR
---with-id3lib-libs=DIR             search for id3lib libraries in DIR
---with-zlib-h=DIR                  search for zlib headers in DIR
---with-zlib-libs=DIR               search for zlib libraries in DIR
---with-inotify-h=DIR               search for inotify header in DIR
---with-iconv-h=DIR                 search for iconv headers in DIR/sys
---with-iconv-libs=DIR              search for iconv libraries in DIR
---with-avformat-h=DIR              search for avformat headers in DIR
---with-avformat-libs=DIR           search for avformat libraries in DIR
---with-avutil-libs=DIR             search for avutil libraries in DIR
---with-ffmpegthumbnailer-h=DIR     search for ffmpegthumbnailer headers
-in DIR
---with-ffmpegthumbnailer-libs=DIR  search for ffmpegthumbnailer librarie
-s in DIR
---with-curl-cfg=curl-config        absolute path/name of curl-config scr
-ipt
---with-libmp4v2-h=DIR              search for libmp4v2 headers in DIR
---with-libmp4v2-libs=DIR           search for libmp4v2 libraries in DIR
---with-rt-libs=DIR                 search for rt libraries in DIR
---with-pthread-libs=DIR            search for pthread libraries in DIR
---with-lastfmlib-h=DIR             search for lastfmlib headers in DIR
---with-lastfmlib-libs=DIR          search for lastfmlib libraries in DIR
-
-
-3.2.35. The devconf Script
-
-   If you are doing some development work and some debugging, you
-   will probably want to compile with the -g flag and also disable
-   optimization. The devconf script does exactly that. In
-   addition, it accepts command line parameters that are passed to
-   the configure script.
-
-4. Initial Installation
-
-4.1. Network Setup
-
-   Some systems require a special setup on the network interface.
-   If MediaTomb exits with UPnP Error -117, or if it does not
-   respond to M-SEARCH requests from the renderer (i.e. MediaTomb
-   is running, but your renderer device does not show it) you
-   should try the following settings (the lines below assume that
-   MediaTomb is running on a Linux machine, on network interface
-   eth1):
-# route add -net 239.0.0.0 netmask 255.0.0.0 eth1
-# ifconfig eth1 allmulti
-
-   Those settings will be applied automatically by the init.d
-   startup script.
-
-   You should also make sure that your firewall is not blocking
-   port UDP port 1900 (required for SSDP) and UDP/TCP port of
-   MediaTomb. By default MediaTomb will select a free port
-   starting with 49152, however you can specify a port of your
-   choice in the configuration file.
-
-4.2. First Time Launch
-
-   When starting MediaTomb for the first time, a .mediatomb
-   directory will be created in your home. Further, a default
-   server configuration file, called config.xml will be generated
-   in that directory.
-
-4.2.1. Using Sqlite Database
-
-   If you are using sqlite - you are ready to go, the database
-   file will be created automatically and will be located
-   ~/.mediatomb/mediatomb.db If needed you can adjust the database
-   file name and location in the server configuration file.
-
-4.2.2. Using MySQL Database
-
-   If MediaTomb was compiled with support for both databases,
-   sqlite will be chosen as default because the initial database
-   can be created and used without any user interaction. If
-   MediaTomb was compiled only with MySQL support, the appropriate
-   config.xml file will be created in the ~/.mediatomb directory,
-   but the server will then terminate, because user interaction is
-   required.
-
-   MediaTomb has to be able to connect to the MySQL server and at
-   least the (empty) database has to exist. To create the database
-   and provide MediaTomb with the ability to connect to the MySQL
-   server you need to have the appropriate permissions. Note that
-   user names and passwords in MySQL have nothing to do with UNIX
-   accounts, MySQL has it's own user names/passwords. Connect to
-   the MySQL database as "root" or any other user with the
-   appropriate permissions:
-$ mysql [-u <username>] [-p]
-
-   (You'll probably need to use "-u" to specify a different MySQL
-   user and "-p" to specify a password.)
-
-   Create a new database for MediaTomb: (substitute "<database
-   name>" with the name of the database)
-mysql> CREATE DATABASE <database name>;
-
-   (You can also use "mysqladmin" instead.)
-
-   Give MediaTomb the permissions to access the database:
-mysql> GRANT ALL ON <database name>.*
-       TO '<user name>'@'<hostname>'
-       IDENTIFIED BY '<password>';
-
-   If you don't want to set a password, omit "IDENTIFIED BY .."
-   completely. You could also use the MySQL "root" user with
-   MediaTomb directly, but this is not recommended.
-
-   To create a database and a user named "mediatomb" (who is only
-   able to connect via "localhost") without a password (the
-   defaults) use:
-mysql> CREATE DATABASE mediatomb;
-mysql> GRANT ALL ON mediatomb.* TO 'mediatomb'@'localhost';
-
-   If MediaTomb was compiled with database auto creation the
-   tables will be created automatically during the first startup.
-   All table names have a "mt_" prefix, so you can theoretically
-   share the database with a different application. However, this
-   is not recommended.
-
-   If database auto creation wasn't compiled in (configure was run
-   with the "--disable-db-autocreate" or zlib.h was not available)
-   you have to create the tables manually:
-$ mysql [-u <username>] [-p] \
-  <database name> < \
-  <install prefix>/share/mediatomb/mysql.sql
-
-   After creating the database and making the appropriate changes
-   in your MediaTomb config file you are ready to go - launch the
-   server, and everything should work.
-
-5. Command Line Options
-
-   There is a number of options that can be passed via command
-   line upon server start up, for a short summary you can invoke
-   MediaTomb with the following parameter:
-$ mediatomb --help
-
-   Note:
-          the command line options override settings in the
-          configuration file!
-
-5.1. IP Address
-
---ip or -i
-
-   The server will bind to the given IP address, currently we can
-   not bind to multiple interfaces so binding to 0.0.0.0 will not
-   be possible.
-
-5.2. Interface
-
---interface or -e
-
-   Interface to bind to, for example eth0, this can be specified
-   instead of the ip address.
-
-5.3. Port
-
---port or -p
-
-   Specify the server port that will be used for the web user
-   interface, for serving media and for UPnP requests, minimum
-   allowed value is 49152. If this option is omitted a default
-   port will be chosen, however, in this case it is possible that
-   the port will change upon server restart.
-
-5.4. Configuration File
-
- --config or -c
-
-   By default MediaTomb will search for a file named "config.xml"
-   in the ~/.mediatomb directory. This option allows you to
-   specify a config file by the name and location of your choice.
-   The file name must be absolute.
-
-5.5. Daemon Mode
-
---daemon or -d
-
-   Run the server in background, MediaTomb will shutdown on
-   SIGTERM, SIGINT and restart on SIGHUP.
-
-5.6. Home Directory
-
---home or -m
-
-   Specify an alternative home directory. By default MediaTomb
-   will try to retrieve the users home directory from the
-   environment, then it will look for a .mediatomb directory in
-   users home. If .mediatomb was found we will try to find the
-   default configuration file (config.xml), if not found we will
-   create both, the .mediatomb directory and the default config
-   file.
-
-   This option is useful in two cases: when the home directory can
-   not be retrieved from the environment (in this case you could
-   also use -c to point MediaTomb to your configuration file or
-   when you want to create a new configuration in a non standard
-   location (for example, when setting up daemon mode). In the
-   latter case you can combine this parameter with the parameter
-   described in Section 5.7, "Config Directory"
-
-5.7. Config Directory
-
---cfgdir or -f
-
-   The default configuration directory is combined out of the
-   users home and the default that equals to .mediatomb, this
-   option allows you to override the default directory naming.
-   This is useful when you want to setup the server in a
-   nonstandard location, but want that the default configuration
-   to be written by the server.
-
-5.8. Write PID File
-
---pidfile or -P
-
-   Specify a file that will hold the server process ID, the
-   filename must be absolute.
-
-5.9. Run Under Different User Name
-
---user or -u
-
-   Run MediaTomb under the specified user name, this is especially
-   useful in combination with the daemon mode.
-
-5.10. Run Under Different Group
-
---group or -g
-
-   Run MediaTomb under the specified group, this is especially
-   useful in combination with the daemon mode.
-
-5.11. Add Content
-
---add or -a
-
-   Add the specified directory or file name to the database
-   without UI interaction. The path must be absolute, if path is a
-   directory then it will be added recursively. If path is a file,
-   then only the given file will be imported.
-
-5.12. Log To File
-
---logfile or -l
-
-   Do not output log messages to stdout, but redirect everything
-   to a specified file.
-
-5.13. Debug Output
-
---debug or -D
-
-   Enable debug log output.
-
-5.14. Compile Info
-
---compile-info
-
-   Print the configuration summary (used libraries and enabled
-   features) and exit.
-
-5.15. Version Information
-
---version
-
-   Print version information and exit.
-
-5.16. Display Command Line Summary
-
---help or -h
-
-   Print a summary about the available command line options.
-
-6. Configuration File
-
-   MediaTomb is highly configurable and allows the user to set
-   various options and preferences that define the servers
-   behavior. Rather than enforcing certain features upon the user,
-   we prefer to offer a number of choices where possible. The
-   heart of MediaTomb configuration is the config.xml file, which
-   is located in the ~/.mediatomb directory. If the configuration
-   file is not found in the default location and no configuration
-   was specified on the command line, MediaTomb will generate a
-   default config.xml file in the ~/.mediatomb directory. The file
-   is in the XML format and can be edited by a simple text editor,
-   here is the list of all available options:
-     * "Required" means that the server will not start if the tag
-       is missing in the configuration.
-     * "Optional" means that the tag can be left out of the
-       configuration file.
-
-   The root tag of MediaTomb configuration is:
-<config>
-
-6.1. Server Settings
-
-   These settings define the server configuration, this includes
-   UPnP behavior, selection of database, accounts for the UI as
-   well as installation locations of shared data.
-<server>
-
-   Required
-
-   This section defines the server configuration parameters.
-
-   Child tags:
-     *
-<port>0</port>
-
-       Optional
-       Default: 0 (automatic)
-       Specifies the port where the server will be listening for
-       HTTP requests. Note, that because of the implementation in
-       the UPnP SDK only ports above 49152 are supported. The
-       value of zero means, that a port will be automatically
-       selected by the SDK.
-     *
-<ip>192.168.0.23</ip>
-
-       Optional
-       Default: ip of the first available interface.
-       Specifies the IP address to bind to, by default one of the
-       available interfaces will be selected.
-     *
-<interface>eth0</interface>
-
-       Optional
-       Default: first available interface.
-       Specifies the interface to bind to, by default one of the
-       available interfaces will be selected.
-     *
-<name>MediaTomb</name>
-
-       Optional
-       Default: MediaTomb
-       Server friendly name, you will see this on your devices
-       that you use to access the server.
-     *
-<manufacturerURL>http://mediatomb.org/</manufacturerURL>
-
-       Optional
-       Default: http://mediatomb.cc/
-       This tag sets the manufacturer URL of a UPnP device, a
-       custom setting may be necessary to trick some renderers in
-       order to enable special features that otherwise are only
-       active with the vendor implemented server.
-     *
-<modelName>MediaTomb</modelName>
-
-       Optional
-       Default: MediaTomb
-       This tag sets the model name of a UPnP device, a custom
-       setting may be necessary to trick some renderers in order
-       to enable special features that otherwise are only active
-       with the vendor implemented server.
-     *
-<modelNumber>0.9.0</modelNumber>
-
-       Optional
-       Default: MediaTomb version
-       This tag sets the model number of a UPnP device, a custom
-       setting may be necessary to trick some renderers in order
-       to enable special features that otherwise are only active
-       with the vendor implemented server.
-     *
-<serialNumber>1</serialNumber>
-
-       Optional
-       Default: 1
-       This tag sets the serial number of a UPnP device.
-     *
-<presentationURL append-to="ip">80/index.html</presentationURL>
-
-       Optional
-       Default: "/"
-       The presentation URL defines the location of the servers
-       user interface, usually you do not need to change this
-       however, vendors who want to ship our server along with
-       their NAS devices may want to point to the main
-       configuration page of the device.
-       Attributes:
-          +
-append-to=...
-
-            Optional
-            Default: "none"
-            The append-to attribute defines how the text in the
-            presentationURL tag should be treated.
-            The allowed values are:
-append-to="none"
-
-            Use the string exactly as it appears in the
-            presentationURL tag.
-append-to="ip"
-
-            Append the string specified in the presentationURL tag
-            to the ip address of the server, this is useful in a
-            dynamic ip environment where you do not know the ip
-            but want to point the URL to the port of your web
-            server.
-append-to="port"
-
-            Append the string specified in the presentationURL tag
-            to the server ip and port, this may be useful if you
-            want to serve some static pages using the built in web
-            server.
-     *
-<udn/>
-
-       Required
-       Default: automatically generated if the tag is empty
-       Unique Device Name, according to the UPnP spec it must be
-       consistent throughout reboots. You can fill in something
-       yourself, but we suggest that you leave this tag empty - it
-       will be filled out and saved automatically after the first
-       launch of the server.
-     *
-<home>/home/your_user_name/.mediatomb</home>
-
-       Required
-       Default: ~/.mediatomb
-       Server home - the server will search for the data that it
-       needs relative to this directory - basically for the sqlite
-       database file. The mediatomb.html bookmark file will also
-       be generated in that directory.
-     *
-<webroot>/usr/share/mediatomb/web</webroot>
-
-       Required
-       Default: depends on the installation prefix that is passed
-       to the configure script.
-       Root directory for the web server, this is the location
-       where device description documents, UI html and js files,
-       icons, etc. are stored.
-     *
-<servedir>/home/myuser/mystuff</servedir>
-
-       Optional
-       Default: empty (disabled)
-       Files from this directory will be served as from a regular
-       web server. They do not need to be added to the database,
-       but they are also not served via UPnP browse requests.
-       Directory listing is not supported, you have to specify
-       full paths.
-
-        Example:
-                the file something.jar is located in
-                /home/myuser/mystuff/javasubdir/something.jar on
-                your filesystem. Your ip address is 192.168.0.23,
-                the server is running on port 50500. Assuming the
-                above configuration you could download it by
-                entering this link in your web browser:
-                http://192.168.0.23:50500/content/serve/javasubdir
-                /something.jar
-
-     *
-<alive>180</alive>
-
-       Optional
-       Default: 180, this is according to the UPnP specification.
-       Interval for broadcasting SSDP:alive messages
-     *
-<protocolInfo extend="no"/>
-
-       Optional
-       Default: no
-       Adds specific tags to the protocolInfo attribute, this is
-       required to enable MP3 and MPEG4 playback on Playstation 3.
-     *
-<pc-directory upnp-hide="no"/>
-
-       Optional
-       Default: no
-       Enabling this option will make the PC-Directory container
-       invisible for UPnP devices.
-
-        Note:
-                independent of the above setting the container
-                will be always visible in the web UI!
-
-     *
-<tmpdir>/tmp/</tmpdir>
-
-       Optional
-       Default: /tmp/
-       Selects the temporary directory that will be used by the
-       server.
-     *
-<bookmark>mediatomb.html</bookmark>
-
-       Optional
-       Default: mediatomb.html
-       The bookmark file offers an easy way to access the user
-       interface, it is especially helpful when the server is not
-       configured to run on a fixed port. Each time the server is
-       started, the bookmark file will be filled in with a
-       redirect to the servers current IP address and port. To use
-       it, simply bookmark this file in your browser, the default
-       location is ~/.mediatomb/mediatomb.html
-     *
-<custom-http-headers>
-
-       Optional
-       This section holds the user defined HTTP headers that will
-       be added to all HTTP responses that come from the server.
-       Child tags:
-          +
-<add header="..."/>
-<add header="..."/>
-...
-
-            Optional
-            Specify a header to be added to the response. If you
-            have a DSM-320 use <add header="X-User-Agent:
-            redsonic"/> to fix the .AVI playback problem.
-     *
-<upnp-string-limit>
-
-       Optional
-       Default: disabled
-       This will limit title and description length of containers
-       and items in UPnP browse replies, this feature was added a
-       s workaround for the TG100 bug which can only handle titles
-       no longer than 100 characters. A negative value will
-       disable this feature, the minimum allowed value is "4"
-       because three dots will be appended to the string if it has
-       been cut off to indicate that limiting took place.
-
-     *
-<ui enabled="yes" poll-interval="2" poll-when-idle="no"/>
-
-       Optional
-       This section defines various user interface settings.
-       WARNING!
-       The server has an integrated filesystem browser, that means
-       that anyone who has access to the UI can browse your
-       filesystem (with user permissions under which the server is
-       running) and also download your data! If you want maximum
-       security - disable the UI completely! Account
-       authentication offers simple protection that might hold
-       back your kids, but it is not secure enough for use in an
-       untrusted environment!
-
-        Note:
-                since the server is meant to be used in a home LAN
-                environment the UI is enabled by default and
-                accounts are deactivated, thus allowing anyone on
-                your network to connect to the user interface.
-
-       Attributes:
-          +
-enabled=...
-
-            Optional
-            Default: yes
-            Enables ("yes") or disables ("no") the web user
-            interface.
-          +
-show-tooltips=...
-
-            Optional
-            Default: yes
-            This setting specifies if icon tooltips should be
-            shown in the web UI.
-          +
-poll-interval=...
-
-            Optional
-            Default: 2
-            The poll-interval is an integer value which specifies
-            how often the UI will poll for tasks. The interval is
-            specified in seconds, only values greater than zero
-            are allowed.
-          +
-poll-when-idle=...
-
-            Optional
-            Default: no
-            The poll-when-idle attribute influences the behavior
-            of displaying current tasks: - when the user does
-            something in the UI (i.e. clicks around) we always
-            poll for the current task and will display it - if a
-            task is active, we will continue polling in the
-            background and update the current task view
-            accordingly - when there is no active task (i.e. the
-            server is currently idle) we will stop the background
-            polling and only request updates upon user actions,
-            but not when the user is idle (i.e. does not click
-            around in the UI)
-            Setting poll-when-idle to "yes" will do background
-            polling even when there are no current tasks; this may
-            be useful if you defined multiple users and want to
-            see the tasks the other user is queuing on the server
-            while you are actually idle.
-            The tasks that are monitored are:
-               o adding files or directories
-               o removing items or containers
-               o automatic rescans
-       Child tags:
-          +
-<accounts enabled="yes" session-timeout="30"/>
-
-            Optional
-            This section holds various account settings.
-            Attributes:
-               o
-enabled=...
-
-                 Optional
-                 Default: yes
-                 Specifies if accounts are enabled ("yes") or
-                 disabled ("no").
-               o
-session-timeout=...
-
-                 Optional
-                 Default: 30
-                 The session-timeout attribute specifies the
-                 timeout interval in minutes. The server checks
-                 every five minutes for sessions that have timed
-                 out, therefore in the worst case the session
-                 times out after session-timeout + 5 minutes.
-            Accounts can be defined as shown below:
-               o
-<account user="name" password="password"/>
-<account user="name" password="password"/>
-....
-
-                 Optional
-                 There can be multiple users, however this is
-                 mainly a feature for the future. Right now there
-                 are no per-user permissions.
-          +
-<items-per-page default="25">
-
-            Optional
-            Default: 25
-            This sets the default number of items per page that
-            will be shown when browsing the database in the web
-            UI.
-            The values for the items per page drop down menu can
-            be defined in the following manner:
-               o
-<option>10</option>
-<option>25</option>
-<option>50</option>
-<option>100</option>
-
-                 Default: 10, 25, 50, 100
-
-                    Note:
-                            this list must contain the default
-                            value, i.e. if you define a default
-                            value of 25, then one of the <option>
-                            tags must also list this value.
-
-     *
-<storage caching="yes">
-
-       Required
-       Defines the storage section - database selection is done
-       here. Currently sqlite3 and mysql are supported. Each
-       storage driver has it's own configuration parameters.
-          +
-caching="yes"
-
-            Optional
-            Default: yes
-            Enables caching, this feature should improve the
-            overall import speed.
-          +
-<sqlite enabled="yes>
-
-            Required if MySQL is not defined
-            Allowed values are "sqlite3" or "mysql", the available
-            options depend on the selected driver.
-               o
-enabled="yes"
-
-                 Optional
-                 Default: yes
-            Below are the sqlite driver options:
-               o
-<database-file>mediatomb.db</database-file>
-
-                 Optional
-                 Default: mediatomb.db
-                 The database location is relative to the server's
-                 home, if the sqlite database does not exist it
-                 will be created automatically.
-               o
-<synchronous>off</synchronous>
-
-                 Optional
-                 Default: off
-                 Possible values are "off", "normal" and "full".
-                 This option sets the SQLite pragma "synchronous".
-                 This setting will affect the performance of the
-                 database write operations. For more information
-                 about this option see the SQLite documentation:
-                 http://www.sqlite.org/pragma.html#pragma_synchron
-                 ous
-               o
-<on-error>restore</on-error>
-
-                 Optional
-                 Default: restore
-                 Possible values are "restore" and "fail".
-                 This option tells MediaTomb what to do if an
-                 SQLite error occurs (no database or a corrupt
-                 database). If it is set to "restore" it will try
-                 to restore the database from a backup file (if
-                 one exists) or try to recreate a new database
-                 from scratch.
-                 If the option is set to "fail", MediaTomb will
-                 abort on an SQLite error.
-               o
-<backup enabled="no" interval="6000"/>
-
-                 Optional
-                 Backup parameters:
-                    #
-enabled=...
-
-                      Optional
-                      Default: no
-                      Enables or disables database backup.
-                    #
-interval=...
-
-                      Optional
-                      Default: 600
-                      Defines the backup interval in seconds.
-          +
-<mysql enabled="no"/>
-
-            Defines the MySQL storage driver section.
-               o
-enabled=...
-
-                 Optional
-                 Default: yes
-                 Enables or disables the MySQL driver.
-            Below are the child tags for MySQL:
-               o
-<host>localhost</host>
-
-                 Optional
-                 Default: "localhost"
-                 This specifies the host where your MySQL database
-                 is running.
-               o
-<port>0</port>
-
-                 Optional
-                 Default: 0
-                 This specifies the port where your MySQL database
-                 is running.
-               o
-<username>root</username>
-
-                 Optional
-                 Default: "mediatomb"
-                 This option sets the user name that will be used
-                 to connect to the database.
-               o
-<password></password>
-
-                 Optional
-                 Default: no password
-                 Defines the password for the MySQL user. If the
-                 tag doesn't exist MediaTomb will use no password,
-                 if the tag exists, but is empty MediaTomb will
-                 use an empty password. MySQL has a distinction
-                 between no password and an empty password.
-               o
-<database>mediatomb</database>
-
-                 Optional
-                 Default: "mediatomb"
-                 Name of the database that will be used by
-                 MediaTomb.
-
-6.1.1. Extended Runtime Options
-
-<extended-runtime-options>
-
-   These options reside under the server tag and allow to
-   additinally control the so called "runtime options". The
-   difference to the import options is:
-
-   Import options are only triggered when data is being imported
-   into the database, this means that if you want new settings to
-   be applied to already imported data, you will have to reimport
-   it. Runtime options can be switched on and off without the need
-   to reimport any media. Unfortunately you still need to restart
-   the server so that these options take effect, however after
-   that they are immediately active.
-     *
-<ffmpegthumbnailer enabled="no">
-
-       Optional
-       Default: no
-       Ffmpegthumbnailer is a nice, easy to use library that
-       allows to generate thumbnails from video files. Some DLNA
-       compliant devices support video thumbnails, if you think
-       that your device may be one of those you can try enabling
-       this option. It would also make sense to enable the
-       protocolInfo option, since it will add specific DLNA tags
-       to tell your device that a video thumbnail is being offered
-       by the server.
-
-        Note:
-                thumbnails are not cached and not stored anywhere,
-                they will be generated on the fly in memory and
-                released afterwards. If your device supports video
-                thumbnails and requests them from the server in
-                large amounts, the performance when browsing video
-                containers will depend on the speed of your
-                machine. A feature to allow caching of thumbnails
-                is planned for future releases.
-
-       The following options allow to control the
-       ffmpegthumbnailer library (these are basically the same
-       options as the ones offered by the ffmpegthumbnailer
-       command line application). All tags below are optional and
-       have sane default values.
-          +
-<thumbnail-size>128</thumbnail-size>
-
-            Optional
-            Default: 128
-            The thumbnail size should not exceed 160x160 pixels,
-            higher values can be used but will mostprobably not be
-            supported by DLNA devices. The value of zero or less
-            is not allowed.
-          +
-<seek-percentage>5</seek-percentage>
-
-            Optional
-            Default: 5
-            Time to seek to in the movie (percentage), values less
-            than zero are not allowed.
-          +
-<filmstrip-overlay>yes</filmstrip-overlay>
-
-            Optional
-            Default: yes
-            Creates a filmstrip like border around the image, turn
-            this option off if you want pure images.
-          +
-<image-quality>8</image-quality>
-
-            Optional
-            Default: 8
-            Sets the image quality of the generated thumbnails.
-          +
-<workaround-bugs>no</workaround-bugs>
-
-            Optional
-            Default: no
-            Accodring to ffmpegthumbnailer documentation, this
-            option will enable workarounds for bugs in older
-            ffmpeg versions. You can try enabling it if you
-            experience unexpected behaviour, like hangups during
-            thumbnail generation, crashes and alike.
-     *
-<lastfm enabled="no">
-
-       Optional
-       Support for the last.fm service.
-          +
-<username>login</username>
-
-            Required
-            Your last.fm user name.
-          +
-<password>pass</password>
-
-            Required
-            Your last.fm password.
-     *
-<mark-played-items enabled="no" suppress-cds-updates="yes">
-
-       Optional
-       The attributes of the tag have the following meaning:
-          +
-enabled=...
-
-            Optional
-            Default: no
-            Enables or disables the marking of played items, seto
-            to "yes" to enable the feature.
-          +
-suppress-cds-updates=...
-
-            Optional
-            Default: yes
-            This is an advanced feature, leave the default setting
-            if unsure. Usually, when items are modified we send
-            out container updates as specified in the Content
-            Directory Service. This notifies the player that data
-            in a particular container has changed, players that
-            support CDS updates will rebrowse the container and
-            refresh the view. However, in this case we probably do
-            not want it (this actually depends on the particular
-            player implementation). For example, if we update the
-            list of currently playing items, the player could
-            interrupt playback and rebrowse the current container
-            - clearly an unwatned behaviour. Because of this, we
-            provide an option to suppress and not send out
-            container updates - only for the case where the item
-            is marked as "played". In order to see the changes you
-            will have to get out of the current container and
-            enter it again - then the view on your player should
-            get updated.
-
-              Note:
-                      some players (i.e. PS3) cache a lot of data
-                      and do not react to container updates, for
-                      those players it may be necessary to leave
-                      the server view or restart the player in
-                      order to update content (same as when adding
-                      new data).
-
-       The following tag defines how played items should be
-       marked:
-          +
-<string mode="prepend">* </string>
-
-            Optional
-            Default: *
-            Specifies what string should be appended or prepended
-            to the title of the object that will be marked as
-            "played".
-               o
-mode=...
-
-                 Optional
-                 Default: prepend
-                 Specifies how a string should be added to the
-                 object's title, allowed values are "append" and
-                 "prepend".
-          +
-<mark>
-
-            Optional
-            This subsection allows to list which type of content
-            should get marked. We figured, that marking played
-            items is mostly useful for videos, mainly for watching
-            series. It could also be used with audio and image
-            content, but otherwise it's probably useless. Thefore
-            we decided to specify only three supported types that
-            can get marked:
-               o
-<content>audio</content>
-<content>video</content>
-<content>image</content>
-
-                 You can specify any combination of the above tags
-                 to mark the items you want.
-
-6.2. Import Settings
-
-   The import settings define various options on how to aggregate
-   the content.
-<import hidden-files="no">
-
-   Optional
-
-   This tag defines the import section.
-
-   Attributes:
-     *
-hidden-files=...
-
-       Optional
-       Default: no
-       This attribute defines if files starting with a dot will be
-       imported into the database ("yes"). Autoscan can override
-       this attribute on a per directory basis.
-
-   Child tags:
-     *
-<filesystem-charset>ISO-8859-1</filesystem-charset>
-
-       Optional
-       Default: if nl_langinfo() function is present, this setting
-       will be auto detected based on your system locale, else set
-       to ISO-8859-1
-       Defines the charset of the filesystem. For example, if you
-       have file names in Cyrillic KOI8-R encoding, then you
-       should specify that here. The server uses UTF-8 internally,
-       this import parameter will help you to correctly import
-       your data.
-     *
-<metadata-charset>ISO-8859-1</metadata-charset>
-
-       Optional
-       Default: if nl_langinfo() function is present, this setting
-       will be auto detected based on your system locale, else set
-       to ISO-8859-1
-       Same as above, but defines the charset of the metadata
-       (i.e. id3 tags, Exif information, etc.)
-     *
-<scripting script-charset="UTF-8">
-
-       Optional
-       Defines the scripting section.
-          +
-script-charset=...
-
-            Optional
-            Default: UTF-8
-       Below are the available scripting options:
-          +
-<virtual-layout type="builtin">
-
-            Optional
-            Defines options for the virtual container layout; the
-            so called "virtual container layout" is the way how
-            the server organizes the media according to the
-            extracted metadata. For example, it allows sorting
-            audio files by Album, Artist, Year and so on.
-               o
-type=...
-
-                 Optional
-                 Default: builtin
-                 Specifies what will be used to create the virtual
-                 layout, possible values are:
-                    # builtin: a default layout will be created by
-                      the server
-                    # js: a user customizable javascript will be
-                      used (MediaTomb must be compiled with js
-                      support)
-                    # disabled: only PC-Directory structure will
-                      be created, i.e. no virtual layout
-            The virtual layout can be adjusted using an import
-            script which is defined as follows:
-               o
-<import-script>/path/to/my/import-script.js</import-script>
-
-                 Required if virtual layout type is "js"
-                 Default: ${prefix}/share/mediatomb/js/import.js,
-                 where ${prefix} is your installation prefix
-                 directory.
-                 Points to the script invoked upon media import.
-                 For more details read doc/scripting.txt
-               o
-<dvd-script>/path/to/my/import-dvd.js</dvd-script>
-
-                 Optional, only has effect when layout type is
-                 "js" and if MediaTomb was compiled with
-                 libdvdread support.
-                 Default:
-                 ${prefix}/share/mediatomb/js/import-dvd.js, where
-                 ${prefix} is your installation prefix directory.
-                 Points to the script invoked upon import of DVD
-                 iso images. For more details read
-                 doc/scripting.txt
-          +
-<common-script>/path/to/my/common-script.js</common-script>
-
-            Optional
-            Default: ${prefix}/share/mediatomb/js/common.js, where
-            ${prefix} is your installation prefix directory.
-            Points to the so called common script - think of it as
-            a custom library of js helper functions, functions
-            added there can be used in your import and in your
-            playlist scripts. For more details read
-            doc/scripting.txt
-          +
-<playlist-script create-link="yes">/path/to/my/playlist-script.js</playl
-ist-script>
-
-            Optional
-            Default: ${prefix}/share/mediatomb/js/playlists.js,
-            where ${prefix} is your installation prefix directory.
-            Points to the script that is parsing various
-            playlists, by default parsing of pls and m3u playlists
-            is implemented, however the script can be adapted to
-            parse almost any kind of text based playlist. For more
-            details read doc/scripting.txt
-               o
-create-link=...
-
-                 Optional
-                 Default: yes
-                 Links the playlist to the virtual container which
-                 contains the expanded playlist items. This means,
-                 that if the actual playlist file is removed from
-                 the database, the virtual container corresponding
-                 to the playlist will also be removed.
-     *
-<magic-file>/path/to/my/magic-file</magic-file>
-
-       Optional
-       Default: System default
-       Specifies an alternative file for filemagic, containing
-       mime type information.
-     *
-<autoscan use-inotify="auto">
-
-       Optional
-       Specifies a list of default autoscan directories.
-       This section defines persistent autoscan directories. It is
-       also possible to define autoscan directories in the UI, the
-       difference is that autoscan directories that are defined
-       via the config file can not be removed in the UI. Even if
-       the directory gets removed on disk, the server will try to
-       monitor the specified location and will re add the removed
-       directory if it becomes available/gets created again.
-          +
-use-inotify=...
-
-            Optional
-            Default: auto
-            Specifies if the inotify autoscan feature should be
-            enabled. The default value is "auto", which means that
-            availability of inotify support on the system will be
-            detected automatically, it will then be used if
-            available. Setting the option to 'no' will disable
-            inotify even if it is available. Allowed values:
-            "yes", "no", "auto"
-       Child tags:
-          +
-<directory location="/media" mode="timed" interval="3600"
-    level="full" recursive="no" hidden-files="no"/>
-<directory location="/audio" mode="inotify"
-    recursive="yes" hidden-files="no"/>
-...
-
-            Optional
-            Defines an autoscan directory and it's parameters.
-            The attributes specify various autoscan options:
-               o
-location=...
-
-                 Required
-                 Absolute path to the directory that shall be
-                 monitored.
-               o
-mode=...
-
-                 Required
-                 Scan mode, currently "inotify" and "timed" are
-                 supported. Timed mode rescans the given directory
-                 in specified intervals, inotify mode uses the
-                 kernel inotify mechanism to watch for filesystem
-                 events.
-               o
-interval=...
-
-                 Required for "timed" mode
-                 Scan interval in seconds.
-               o
-level=...
-
-                 Required for "timed" mode
-                 Either "full" or "basic". Basic mode will only
-                 check if any files have been added or were
-                 deleted from the monitored directory, full mode
-                 will remember the last modification time and re
-                 add the media that has changed. Full mode might
-                 be useful when you want to monitor changes in the
-                 media, like id3 tags and alike.
-               o
-recursive=...
-
-                 Required
-                 Values of "yes" or "no" are allowed, specifies if
-                 autoscan shall monitor the given directory
-                 including all sub directories.
-               o
-hidden-files=...
-
-                 Optional
-                 Default: value specified in <import
-                 hidden-files=""/>
-                 Allowed values: "yes" or "no", process hidden
-                 files, overrides the hidden-files value in the
-                 <import/> tag.
-     *
-<mappings>
-
-       Optional
-       Defines various mapping options for importing media,
-       currently two subsections are supported.
-       This section defines mime type and upnp:class mappings, it
-       is vital if filemagic is not available - in this case media
-       type auto detection will fail and you will have to set the
-       mime types manually by matching the file extension. It is
-       also helpful if you want to override auto detected mime
-       types or simply skip filemagic processing for known file
-       types.
-          +
-<extension-mimetype ignore-unknown="no" case-sensitive="no">
-
-            Optional
-            This section holds the file name extension to mime
-            type mappings.
-            Attributes:
-               o
-ignore-unknown=...
-
-                 Optional
-                 Default: no
-                 If ignore-unknown is set to "yes", then only the
-                 extensions that are listed in this section are
-                 imported.
-               o
-case-sensitive=...
-
-                 Optional
-                 Default: no
-                 Specifies if extensions listed in this section
-                 are case sensitive, allowed values are "yes" or
-                 "no".
-            Child tags:
-               o
-<map from="mp3" to="audio/mpeg"/>
-
-                 Optional
-                 Specifies a mapping from a certain file name
-                 extension (everything after the last dot ".") to
-                 mime type.
-
-                    Note:
-                            this improves the import speed,
-                            because invoking libmagic to discover
-                            the right mime type of a file is
-                            omitted for files with extensions
-                            listed here.
-
-                    Note:
-                            extension is case sensitive, this will
-                            probably need to be fixed.
-
-          +
-<mimetype-upnpclass>
-
-            Optional
-            This section holds the mime type to upnp:class
-            mappings.
-            Child tags:
-               o
-<map from="audio/*" to="object.item.audioItem.musicTrack"/>
-
-                 Optional
-                 Specifies a mapping from a certain mime type to
-                 upnp:class in the Content Directory. The mime
-                 type can either be entered explicitly
-                 "audio/mpeg" or using a wildcard after the slash
-                 "audio/*". The values of "from" and "to"
-                 attributes are case sensitive.
-          +
-<mimetype-contenttype>
-
-            Optional
-            This section makes sure that the server knows about
-            remapped mimetypes and still extracts the metadata
-            correctly. For example, we know that id3lib can only
-            handle mp3 files, the default mimetype of mp3 content
-            is audio/mpeg. If the user remaps mp3 files to a
-            different mimetype, we must know about it so we can
-            still pass this item to id3lib for metadata
-            extraction.
-
-              Note:
-                      if this section is not present in your
-                      config file, the defaults will be filled in
-                      automatically. However, if you add an empty
-                      tag, without defining the following <treat>
-                      tags, the server will assume that you want
-                      to have an empty list and no files will be
-                      process by the metadata handler.
-
-               o
-<treat mimetype="audio/mpeg" as="mp3"/>
-
-                 Optional
-                 Tells the server what content the specified
-                 mimetype actually is.
-
-                    Note:
-                            it makes no sense to define 'as'
-                            values that are not below, the server
-                            only needs to know the content type of
-                            the ones specified, otherwise it does
-                            not matter.
-
-                 The 'as' attribute can have following values:
-                    #
-mp3
-
-                      Default mimetype: audio/mpeg
-                      The content is an mp3 file and should be
-                      processed by either id3lib or taglib (if
-                      available).
-                    #
-ogg
-
-                      Default mimetype: application/ogg
-                      The content is an ogg file and should be
-                      processed by taglib (if available).
-                    #
-flac
-
-                      Default mimetype: audio/x-flac
-                      The content is a flac file and should be
-                      processed by taglib (if available).
-                    #
-jpg
-
-                      Default mimetype: image/jpeg
-                      The content is a jpeg image and should be
-                      processed by libexif (if available).
-                    #
-playlist
-
-                      Default mimetype: audio/x-mpegurl or
-                      audio/x-scpls
-                      The content is a playlist and should be
-                      processed by the playlist parser script.
-                    #
-pcm
-
-                      Default mimetype: audio/L16 or audio/x-wav
-                      The content is a PCM file.
-                    #
-avi
-
-                      Default mimetype: video/x-msvideo
-                      The content is an AVI container, FourCC
-                      extraction will be attempted.
-     *
-<library-options>
-
-       Optional
-       This section holds options for the various supported import
-       libraries, it is useful in conjunction with virtual
-       container scripting, but also allows to tune some other
-       features as well.
-       Currently the library-options allow additional extraction
-       of the so called auxilary data (explained below) and
-       provide control over the video thumbnail generation.
-       Here is some information on the auxdata: UPnP defines
-       certain tags to pass along metadata of the media (like
-       title, artist, year, etc.), however some media provides
-       more metadata and exceeds the scope of UPnP. This
-       additional metadata can be used to fine tune the server
-       layout, it allows the user to create a more complex
-       container structure using a customized import script. The
-       metadata that can be extracted depends on the library,
-       currently we support libebexif which provides a default set
-       of keys that can be passed in the options below. The data
-       according to those keys will the be extracted from the
-       media and imported into the database along with the item.
-       When processing the item, the import script will have full
-       access to the gathered metadata, thus allowing the user to
-       organize the data with the use of the extracted
-       information. A practical example would be: if have more
-       than one digital camera in your family you could extract
-       the camera model from the Exif tags and sort your photos in
-       a structure of your choice, like:
-       Photos/MyCamera1/All Photos
-       Photos/MyCamera1/Date
-       Photos/MyCamera2/All Photos
-       Photos/MyCamera2/Date
-       etc.
-       Child tags:
-          +
-<libexif>
-
-            Optional
-            Options for the exif library.
-            Child tags:
-               o
-<auxdata>
-
-                 Optional
-                 Currently only adding keywords to auxdata is
-                 supported. For a list of keywords/tags see the
-                 libexif documentation. Auxdata can be read by the
-                 import java script to gain more control over the
-                 media structure.
-                 Child tags:
-                    #
-<add-data tag="keyword1"/>
-<add-data tag="keyword2"/>
-...
-
-                      Optional
-                      If the library was able to extract the data
-                      according to the given keyword, it will be
-                      added to auxdata. You can then use that data
-                      in your import scripts.
-            A sample configuration for the example described above
-            would be:
-<libexif>
-    <auxdata>
-        <add-data tag="EXIF_TAG_MODEL"/>
-    </auxdata>
-</libexif>
-
-          +
-<id3>
-
-            Optional
-            These options apply to id3lib or taglib libraries.
-            Child tags:
-               o
-<auxdata>
-
-                 Optional
-                 Currently only adding keywords to auxdata is
-                 supported. The keywords are those defined in the
-                 id3 specification, we do not perform any extra
-                 checking, so you could try to use any string as a
-                 keyword - if it does not exist in the tag nothing
-                 bad will happen.
-                 Here is a list of possible keywords:
-                 TALB, TBPM, TCOM, TCON, TCOP, TDAT, TDLY, TENC,
-                 TEXT, TFLT, TIME, TIT1, TIT2, TIT3, TKEY, TLAN,
-                 TLEN, TMED, TOAL, TOFN, TOLY, TOPE, TORY, TOWN,
-                 TPE1, TPE2, TPE3, TPE4, TPOS, TPUB, TRCK, TRDA,
-                 TRSN, TRSO, TSIZ, TSRC, TSSE, TYER, TXXX
-                 Child tags:
-                    #
-<add-data tag="TCOM"/>
-<add-data tag="TENC"/>
-...
-
-                      Optional
-                      If the library was able to extract the data
-                      according to the given keyword, it will be
-                      added to auxdata. You can then use that data
-                      in your import scripts.
-            A sample configuration for the example described above
-            would be:
-<id3>
-    <auxdata>
-        <add-data tag="TENC"/>
-    </auxdata>
-</id3>
-
-6.2.1. Online Content Settings
-
-   This section resides under import and defines options for
-   various supported online services.
-<online-content fetch-buffer-size="262144" fetch-buffer-fill-size="0">
-
-   Optional
-
-   This tag defines the online content section.
-
-   Attributes:
-     *
-fetch-buffer-size=...
-
-       Optional
-       Default: 262144
-       Often, online content can be directly accessed by the
-       player - we will just give it the URL. However, sometimes
-       it may be necessary to proxy the content through MediaTomb.
-       This setting defines the buffer size in bytes, that will be
-       used when fetching content from the web. The value must not
-       be less than allowed by the curl library (usually 16384
-       bytes).
-     *
-fetch-buffer-fill-size=...
-
-       Optional
-       Default: 0 (disabled)
-       This setting allows to prebuffer a certain amount of data,
-       given in bytes, before sending it to the player, this
-       should ensure a constant data flow in case of slow
-       connections. Usually this setting is not needed, because
-       most players will anyway have some kind of buffering,
-       however if the connection is particularly slow you may want
-       to try enable this setting.
-
-   Below are the settings for supported services.
-
-6.2.2. YouTube Service
-
-   MediaTomb allows you to watch YouTube videos using your UPnP
-   device, you can specify what content you are interested in, we
-   will import the meta data and present it in the database, so
-   you can browse the content on your player just like you do it
-   with your local data.
-
-   WANING:
-          by using this feature you may be violating the YouTube
-          service terms and conditions:
-          http://www.youtube.com/t/terms
-
-   Note:
-          we do not download/mirror the actual videos, we only get
-          description of the content and present it in the
-          database. The actual video is only streamed when you
-          press play on your device. So, when we use the term
-          "retrieve videos" we actually mean retrieving the video
-          name, description and associated meta data, not the
-          actual flv file.
-
-   Note:
-          so far we have not yet seen many devices that will
-          natively support the .flv format, you will need to setup
-          appropriate transcoding profiles to make use of the
-          YouTube feature.
-
-<YouTube enabled="no" refresh="12600" update-at-start="yes" purge-after=
-"1200000" racy-content="exclude">
-
-   Optional
-
-   Options and setting for YouTube service support, the attributes
-   are:
-     *
-enabled=...
-
-       Optional
-       Default: no
-       Enables or disables the service, allowed values are "yes"
-       or "no".
-     *
-refresh=...
-
-       Optional
-       Default: 28800
-       Refresh interval in seconds, each time the interval elapses
-       we will contact the YouTube server and fetch new meta data,
-       presenting the changes in the database view. This allows
-       you to stay up to date with what is available on YouTube,
-       you probably should not need to update more than once per
-       day, so specify a reasonably high value here. Setting the
-       option to 0 (zero) disables automatic refreshing.
-     *
-purge-after=...
-
-       Optional
-       Default: 0 (disabled)
-       Time amount in seconds when data that has not been updated
-       is considered old and can be purged from the database. This
-       setting helps to prevent an endless filling of the database
-       with YouTube meta data, the idea is the following: each
-       video has a unique ID, during a refresh cycle the video
-       meta data will be imported into the database and a time
-       stamp will be added. Each refresh cycle we may encounter
-       same content (i.e. nothing changed on the YouTube site), we
-       will update the time stamp. However, if a particular video
-       is no longer available on YouTube it will not be refreshed,
-       once the time stamp exceeds the purge-after value we will
-       remove the meta data for this particular video from the
-       database.
-     *
-update-at-start=...
-
-       Optional
-       Default: no
-       This option defines if we will contact the service right
-       after MediaTomb was started (about 10 seconds after start
-       up) or if data should be fetched when the first refresh
-       cycle kicks in. It may be useful if you frequently restart
-       the server and do not want the content to be updated each
-       time. Allowed values are "yes" or "no".
-     *
-format=...
-
-       Optional
-       Default: mp4
-       Selects the format in which the videos should be retrieved
-       from YouTube.
-          +
-mp4
-
-            A while ago YouTube also offers the videos in the mp4
-            format which is playable by most players, it will also
-            allow you to seek/pause.
-          +
-flv
-
-            Flash video, obviously not a good choice if you want
-            to play it on your UPnP device, only useful in
-            combination with a properly set up transcoding
-            profile.
-     *
-hd=...
-
-       Optional
-       Default: no
-       If set to "yes", then a HD video will be retrieved if
-       available.
-     *
-racy-content=...
-
-       Optional
-       Default: exclude
-       Specifies if restricted content should be inclueded in the
-       search results. The option will automatically be used with
-       YouTube requests that support. By default restricted
-       content is not included.
-
-   Below are various options that allow you to define what content
-   you are interested in.
-
-   Note:
-          all tags are optional and can occur more then once.
-
-     *
-<standardfeed feed="top_rated" region-id="ru" time-range="today" start-i
-ndex="1" amount="all"/>
-
-       Optional
-       This tag tells us to retrieve one of the standard video
-       feeds. It can appear more than once with different options
-       (i.e. different feed and region settings).
-          +
-feed=...
-
-            Required
-            Definition of the standard feed that you are
-            interested in, the allowed values are:
-               o
-top_rated
-
-               o
-top_favorites
-
-               o
-most_viewed
-
-               o
-most_recent
-
-               o
-most_discussed
-
-               o
-most_linked
-
-               o
-most_responded
-
-               o
-recently_featured
-
-               o
-watch_on_mobile
-
-          +
-region-id=...
-
-            Optional
-            Allows to get a standard feed for a specific region,
-            the option is ignored for the watch_on_mobile standard
-            feed.
-            Currently, the following region id's are supported:
-               o
-au
-
-                 Australia
-               o
-br
-
-                 Brazil
-               o
-ca
-
-                 Canada
-               o
-fr
-
-                 France
-               o
-de
-
-                 Germany
-               o
-gb
-
-                 Great Britain
-               o
-nl
-
-                 The Netherlands
-               o
-hk
-
-                 Hong Kong
-               o
-ie
-
-                 Ireland
-               o
-it
-
-                 Italy
-               o
-jp
-
-                 Japan
-               o
-mx
-
-                 Mexico
-               o
-nz
-
-                 New Zealand
-               o
-pl
-
-                 Poland
-               o
-ru
-
-                 Russia
-               o
-kr
-
-                 South Korea
-               o
-es
-
-                 Spain
-               o
-tw
-
-                 Taiwan
-               o
-us
-
-                 United States
-          +
-time-range=...
-
-            Optional
-            Allows to specify a certain time range when retrieving
-            the feed content. The time-range option is only
-            supported for the following standard feeds: top_rated,
-            top_favorites, most_viewed, most_discussed,
-            most_linked and most_responded.
-            Following values are supported:
-               o
-all_time
-
-               o
-today
-
-               o
-this_week
-
-               o
-this_month
-
-          +
-start-index=...
-
-            Optional
-            Starting index of the item in the list, useful if you
-            want to skip the first xxx results, must be an integer
-            value >= 1.
-          +
-amount=...
-
-            Amount of items to fetch, can be either an integer
-            value or the keyword "all".
-     *
-<favorites user="mediatomb"/>
-
-       Optional
-       Retrieves all favorites of the given user.
-          +
-user=...
-
-            Required
-            Name of the YouTube user whose favorites should be
-            fetched.
-     *
-<subscriptions user="mediatomb"/>
-
-       Optional
-       Retrieves all subscriptions of the given user.
-          +
-user=...
-
-            Required
-            Name of the YouTube user whose subscriptions should be
-            fetched.
-     *
-<playlists user="mediatomb"/>
-
-       Optional
-       Retrieve all playlists of the given user.
-          +
-user=...
-
-            Required
-            Name of the YouTube user whose playlists should be
-            fetched.
-     *
-<uploads user="mediatomb" start-index="1" amount="all"/>
-
-       Required
-       Retrieves videos that were uploaded by a specified user.
-          +
-user=...
-
-            Required
-            Name of the YouTube user whose playlists should be
-            fetched.
-          +
-start-index=...
-
-            Optional
-            Starting index of the item in the list, useful if you
-            want to skip the first xxx results, must be an integer
-            value >= 1.
-          +
-amount=...
-
-            Amount of items to fetch, can be either an integer
-            value or the keyword "all".
-
-6.3. Transcoding Settings
-
-   The transcoding section allows to define ways on how to
-   transcode content.
-<transcoding enabled="yes" fetch-buffer-size="262144" fetch-buffer-fill-
-size="0">
-
-   Optional
-
-   This tag defines the transcoding section.
-
-   Attributes:
-     *
-enabled=...
-
-       Optional
-       Default: yes
-       This attribute defines if transcoding is enabled as a
-       whole, possible values are "yes" or "no".
-     *
-fetch-buffer-size=...
-
-       Optional
-       Default: 262144
-       In case you have transcoders that can not handle online
-       content directly (see the accept-url parameter below), it
-       is possible to put the transcoder between two FIFOs, in
-       this case MediaTomb will fetch the online content. This
-       setting defines the buffer size in bytes, that will be used
-       when fetching content from the web. The value must not be
-       less than allowed by the curl library (usually 16384
-       bytes).
-     *
-fetch-buffer-fill-size=...
-
-       Optional
-       Default: 0 (disabled)
-       This setting allows to prebuffer a certain amount of data
-       before sending it to the transcoder, this should ensure a
-       constant data flow in case of slow connections. Usually
-       this setting is not needed, because most transcoders will
-       just patiently wait for data and we anyway buffer on the
-       output end. However, we observed that ffmpeg will fail to
-       transcode flv files if it encounters buffer underruns -
-       this setting helps to avoid this situation.
-
-   Child tags:
-     *
-<mimetype-profile-mappings>
-
-       The mime type to profile mappings define which mime type is
-       handled by which profile.
-       Different mime types can map to the same profile in case
-       that the transcoder in use supports various input formats.
-       The same mime type can also map to several profiles, in
-       this case multiple resources in the XML will be generated,
-       allowing the player to decide which one to take.
-       The mappings under mimetype-profile are defined in the
-       following manner:
-          +
-<transcode mimetype="audio/x-flac" using="oggflac-pcm"/>
-
-            Optional
-            In this example we want to transcode our flac audio
-            files (they have the mimetype audio/x-flac) using the
-            "oggflac-pcm" profile which is defined below.
-               o
-mimetype=...
-
-                 Selects the mime type of the source media that
-                 should be transcoded.
-               o
-using=...
-
-                 Selects the transcoding profile that will handle
-                 the mime type above. Information on how to define
-                 transcoding profiles can be found below.
-     *
-<profiles>
-
-       This section defines the various transcoding profiles.
-          +
-<profile name="oggflag-pcm" enabled="yes" type="external">
-
-            Optional
-            Definition of a transcoding profile.
-               o
-name=...
-
-                 Required
-                 Name of the transcoding profile, this is the name
-                 that is specified in the mime type to profile
-                 mappings.
-               o
-enabled=...
-
-                 Required
-                 Enables or disables the profile, allowed values
-                 are "yes" or "no".
-               o
-type=...
-
-                 Required
-                 Defines the profile type, currently only
-                 "external" is supported, this will change in the
-                 future.
-               o
-<mimetype>audio/x-wav</mimetype>
-
-                 Required
-                 Defines the mime type of the transcoding result
-                 (i.e. of the transcoded stream). In the above
-                 example we transcode to PCM.
-               o
-<accept-url>yes</accept-url>
-
-                 Optional
-                 Default: yes
-                 Some transcoders are able to handle non local
-                 content, i.e. instead giving a local file name
-                 you can pass an URL to the transcoder. However,
-                 some transcoders can only deal with local files,
-                 for this case set the value to "no".
-               o
-<first-resource>no</first-resource>
-
-                 Optional
-                 Default: no
-                 It is possible to offer more than one resource in
-                 the browse result, a good player implementation
-                 will go through all resources and pick the one
-                 that it can handle best. Unfortunately most
-                 players only look at the first resource and
-                 ignore the rest. When you add a transcoding
-                 profile for a particular media type it will show
-                 up as an additional resource in the browse
-                 result, using this parameter you can make sure
-                 that the transcoded resource appears first in the
-                 list.
-
-                    Note:
-                            if more than one transcoding profile
-                            is applied on one source media type
-                            (i.e. you transcode an OGG file to MP3
-                            and to PCM), and the first-resource
-                            parameter is specified in both
-                            profiles, then the resource positions
-                            are undefined.
-
-               o
-<hide-original-resource>no</hide-original-resource>
-
-                 Optional
-                 Default: no
-                 This parameter will hide the resource of the
-                 original media when sending the browse result to
-                 the player, this can be useful if your device
-                 gets confused by multiple resources and allows
-                 you to send only the transcoded one.
-               o
-<accept-ogg-theora>no</accept-org-theora>
-
-                 Optional
-                 Default: no
-                 As you may know, OGG is just a container, the
-                 content could be Vorbis or Theora while the mime
-                 type is "application/ogg". For transcoding we
-                 need to identify if we are dealing with audio or
-                 video content, specifying yes in this tag in the
-                 profile will make sure that only OGG files
-                 containing Theora will be processed.
-               o
-<avi-fourcc-list mode="ignore">
-
-                 Optional
-                 Default: disabled
-                 This option allows to specify a particular list
-                 of AVI fourcc strings that can be either set to
-                 be ignored or processed by the profile.
-
-                    Note:
-                            this option has no effect on non AVI
-                            content.
-
-                    #
-mode=...
-
-                      Required
-                      Specifies how the list should be handled by
-                      the transcoding engine, possible values are:
-                         @
-"disabled"
-
-                           The option is completely disabled,
-                           fourcc list is not being processed.
-                         @
-"process"
-
-                           Only the fourcc strings that are listed
-                           will be processed by the transcoding
-                           profile, AVI files with other fourcc
-                           strings will be ignored. Setting this
-                           is useful if you want to transcode only
-                           some specific fourcc's and not
-                           transcode the rest.
-                         @
-"ignore"
-
-                           The fourcc strings listed will not be
-                           transcoded, all other codecs will be
-                           transcoded. Setting this might be
-                           useful if you want to prevent a limited
-                           number of codecs from being transcoded,
-                           but want to apply transcoding on the
-                           rest (i.e. - do not transcode divx and
-                           xvid, but want to transcode mjpg and
-                           whatever else might be in the AVI
-                           container).
-                 The list of fourcc strings is enclosed in the
-                 avi-fourcc-list section:
-                    #
-<fourcc>XVID</fourcc>
-<fourcc>DX50</fourcc>
-
-                      etc...
-               o
-<agent command="ogg123" arguments="-d wav -f %out %in/>
-
-                 Required
-                 Defines the transcoding agent and the parameters,
-                 in the example above we use ogg123 to convert ogg
-                 or flac to wav.
-                    #
-command=...
-
-                      Required
-                      Defines the transcoder binary that will be
-                      executed by MediaTomb upon a transcode
-                      request, the binary must be in $PATH. It is
-                      very important that the transcoder is
-                      capable of writing the output to a FIFO,
-                      some applications, for example ffmpeg, have
-                      problems with that. The command line
-                      arguments are specified separately (see
-                      below).
-                    #
-arguments=...
-
-                      Required
-                      Specifies the command line arguments that
-                      will be given to the transcoder application
-                      upon execution. There are two special
-                      tokens:
-%in
-%out
-
-                      Those tokens get substituted by the input
-                      file name and the output FIFO name before
-                      execution.
-               o
-<buffer size="1048576" chunk-size="131072" fill-size="262144"/>
-
-                 Required
-                 These settings help you to achieve a smooth
-                 playback of transcoded media. The actual values
-                 need to be tuned and depend on the speed of your
-                 system. The general idea is to buffer the data
-                 before sending it out to the player, it is also
-                 possible to delay first playback until the buffer
-                 is filled to a certain amount. The prefill should
-                 give you enough space to overcome some high
-                 bitrate scenes in case your system can not
-                 transcode them in real time.
-                    #
-size=...
-
-                      Required
-                      Size of the buffer in bytes.
-                    #
-chunk-size=...
-
-                      Required
-                      Size of chunks in bytes, that are read by
-                      the buffer from the transcoder. Smaller
-                      chunks will produce a more constant buffer
-                      fill ratio, however too small chunks may
-                      slow things down.
-                    #
-fill-size=...
-
-                      Required
-                      Initial fill size - number of bytes that
-                      have to be in the buffer before the first
-                      read (i.e. before sending the data to the
-                      player for the first time). Set this to 0
-                      (zero) if you want to disable prefilling.
-               o
-<resolution>320x240</resolution>
-
-                 Optional
-                 Default: not specified
-                 Allows you to tell the resolution of the
-                 transcoded media to your player. This may be
-                 helpful if you want to generate thumbnails for
-                 your photos, or if your player has the ability to
-                 pick video streams in a particular resolution. Of
-                 course the setting should match the real
-                 resolution of the transcoded media.
-               o
-<use-chunked-encoding>yes</use-chunked-encoding>
-
-                 Optional
-                 Default: yes
-                 Specifies that the content should be sent out
-                 using chunked HTTP encoding, this is the default
-                 setting for transcoded streams, because the
-                 content length of the data is not known.
-               o
-<sample-frequency>source</sample-frequency>
-
-                 Optional
-                 Default: source
-                 Specifies the sample frequency of the transcoded
-                 media, this information is passed to the player
-                 and is particularly important when streaming PCM
-                 data. Possible values are: source (automatically
-                 set the same frequency as the frequency of the
-                 source content, which is useful if you are not
-                 doing any resampling), off (do not provide this
-                 information to the player), frequency (specify a
-                 fixed value, where frequency is a numeric value >
-                 0)
-               o
-<audio-channels>source</audio-channels>
-
-                 Optional
-                 Default: source
-                 Specifies the number of audio channels in the
-                 transcoded media, this information is passed to
-                 the player and is particularly important when
-                 streaming PCM data. Possible values are: source
-                 (automatically set the same number of audio
-                 channels as in the source content), off (do not
-                 provide this information to the player), number
-                 (specify a fixed value, where number is a numeric
-                 value > 0)
-               o
-<thumbnail>yes</thumbnail>
-
-                 Optional
-                 Default: no
-
-                    Note:
-                            this is an experimental option, the
-                            implementation will be refined in the
-                            future releases.
-
-                 This is a special option which was added for the
-                 PS3 users. If the resolution option (see above)
-                 was set, then, depending on the resolution an
-                 special DLNA tag will be added, marking the
-                 resource as a thumbnail. This is useful if you
-                 have a transcoding script that extracts an image
-                 out of the video and presents it as a thumbnail.
-                 Use the option with caution, no extra checking is
-                 being done if the resulting mimetype represents
-                 an image, also, it is will only work if the
-                 output of the profile is a JPG image.
-
-7. Supported Devices
-
-Attention Hardware Manufacturers:
-
-   If you want to improve compatibility between MediaTomb and your
-   renderer device or if you are interested in a port of MediaTomb
-   for your NAS device please e-mail to: <contact at mediatomb dot
-   cc>
-
-7.1. MediaRenderers
-
-   MediaTomb supports all UPnP compliant MediaRenderers, however
-   there can always be various problems that depend on the
-   particular device implementation. We always try to implement
-   workarounds to compensate for failures and limitations of
-   various renderers.
-
-   This is the list of client devices that MediaTomb has been
-   tested with and that are known to work. Please drop us a mail
-   if you are using MediaTomb with a device that is not in the
-   list, report any success and failure. We will try to fix the
-   issues and will add the device to the list.
-
-7.1.1. Acer
-
-     * AT3705-MGW
-
-7.1.2. Asus
-
-     * O!Play
-
-7.1.3. Conceptronic
-
-     * C54WMP
-
-7.1.4. Currys UK
-
-     * Logik IR100
-
-7.1.5. Denon
-
-     * AVR-3808
-     * AVR-4306
-     * AVR-4308
-     * S-52
-     * ASD-3N
-
-7.1.6. D-Link
-
-     * DSM-320
-     * DSM-320RD
-     * DSM-510
-     * DSM-520
-
-   Some additional settings in MediaTomb configuration are
-   required to enable special features for the DSM renderers. If
-   you have a DSM-320 and are experiencing problems during AVI
-   playback, add the following to the server section of your
-   config.xml:
-<custom-http-headers>
-    <add header="X-User-Agent: redsonic"/>
-</custom-http-headers>
-
-   Further, the DSM-320 behaves differently if it thinks that it
-   is dealing with the D-Link server. Add the following to the
-   server section of your configuration to enable srt subtitle
-   support:
-<manufacturerURL>redsonic.com</manufacturerURL>
-<modelNumber>105</modelNumber>
-
-   It is still being investigated, but we were able to get
-   subtitles working with a U.S. DSM-320 unit running firmware
-   version 1.09
-
-   Also, the DSM-510 (probably also valid for other models) will
-   only play avi files if the mimetype is set to video/avi, you
-   may want to add a mapping for that to the extension-mimetype
-   section in your config.xml:
-<map from="avi" to="video/avi"/>
-
-7.1.7. Freecom
-
-     * MusicPal
-
-7.1.8. Haeger
-
-     * OnAir (also known as BT Internet Radio)
-
-7.1.9. HP
-
-     * MediaSmart TV
-
-   Users reported that after a firmwre upgrade the device stopped
-   working properly. It seems that it does not sue the UPnP Browse
-   action anymore, but now uses the optional Search action which
-   is not implemented in MediaTomb.
-
-7.1.10. Hifidelio
-
-     * Hifidelio Pro-S
-
-7.1.11. I-O Data
-
-     * AVeL LinkPlayer2 AVLP2/DVDLA
-
-7.1.12. JVC
-
-     * DD-3
-     * DD-8
-
-7.1.13. Kathrein
-
-     * UFS922
-
-7.1.14. Kodak
-
-     * EasyShare EX-1011
-
-7.1.15. Linn
-
-     * Sneaky DS
-
-7.1.16. Linksys
-
-     * WMLS11B (Wireless-B Music System)
-     * KiSS 1600
-
-7.1.17. Medion
-
-     * MD 85651
-
-7.1.18. NeoDigits
-
-     * HELIOS X3000
-
-7.1.19. Netgear
-
-     * EVA700
-     * MP101
-
-7.1.20. Nokia
-
-     * N-95
-     * N-800
-
-7.1.21. Odys
-
-     * i-net MusicBox
-
-7.1.22. Philips
-
-     * Streamium SL-300i
-     * Streamium SL-400i
-     * Streamium MX-6000i
-     * Streamium NP1100
-     * Streamium MCi900
-     * WAS7500
-     * WAK3300
-     * WAC3500D
-     * SLA-5500
-     * SLA-5520
-     * 37PFL9603D
-
-7.1.23. Pinnacle
-
-     * ShowCenter 200
-     * SoundBridge
-
-7.1.24. Pioneer
-
-     * BDP-HD50-K
-     * BDP-94HD
-
-7.1.25. Raidsonic
-
-     * IB-MP308HW-B
-
-7.1.26. Revo
-
-     * Pico RadioStation
-
-7.1.27. Roberts
-
-     * WM201 WiFi Radio
-
-   Playing OGG audio files requres a custom mimetype, add the
-   following to the <extension-mimetype> section and reimport your
-   OGGs:
-<map from="ogg" to="audio/ogg"/>
-
-   Also, add this to the <mimetype-contenttype> section:
-<treat mimetype="audio/ogg" as="ogg"/>
-
-7.1.28. Roku
-
-     * SoundBridge M1001
-     * SoundBridge M2000
-
-7.1.29. Sagem
-
-     * My Dual Radio 700
-
-7.1.30. Siemens
-
-     * Gigaset M740AV
-
-7.1.31. SMC
-
-     * EZ Stream SMCWAA-G
-
-7.1.32. Snazio
-
-     * Snazio* Net DVD Cinema HD SZ1350
-
-7.1.33. Sony
-
-     * Playstation 3
-
-   Firmware 1.80 introduces UPnP/DLNA support, add the following
-   to the <server> section of your configuration file to enable
-   MediaTomb PS3 compatibility:
-<protocolInfo extend="yes"/>
-
-7.1.34. Syabas
-
-     * Popcorn Hour A110
-
-7.1.35. T+A
-
-     * T+A Music Player
-
-7.1.36. Tangent
-
-     * Quattro MkII
-
-7.1.37. Telegent
-
-     * TG100
-
-   The TG100 client has a problem browsing containers, where item
-   titles exceed 101 characters. We implemented a server-side
-   workaround which allows you to limit the lengths of all titles
-   and descriptions. Use the following settings in the <server>
-   section of your configuration file:
-<upnp-string-limit>101</upnp-string-limit>
-
-7.1.38. TerraTec
-
-     * NOXON iRadio
-     * NOXON 2 Audio
-
-7.1.39. Western Digital
-
-     * WD TV Live
-
-7.1.40. Vistron
-
-     * MX-200I
-
-7.1.41. Xtreamer
-
-     * Xtreamer
-
-7.1.42. Yamaha
-
-     * RX-V2065
-
-7.1.43. ZyXEL
-
-     * DMA-1000
-     * DMA-2500
-
-   Some users reported problems where the DMA will show an error
-   "Failed to retrieve list" and the DMA disconnecting from the
-   server. Incresing the alive interval seems to solve the problem
-   - add the following option to the <server> section of your
-   configuration file:
-<alive>600</alive>
-
-   Additionally, the DMA expects that avi files are serverd with
-   the mime type of video/avi, so add the following to the
-   <extensoin-mimetype> section in your configuration file:
-<map from="avi" to="video/avi"/>
-
-   Also, add this to the <mimetype-contenttype> section:
-<treat mimetype="video/avi" as="avi"/>
-
-7.2. Network Attached Storage Devices
-
-   We provide a bitbake metadata file for the OpenEmbedded
-   environment, it allows to easily cross compile MediaTomb for
-   various platforms. We have successfully tested MediaTomb on ARM
-   and MIPSel based devices, so it should be possible to install
-   and run the server on various Linux based NAS products that are
-   available on the market.
-
-   So far two devices are shipped with a preinstalled version of
-   MediaTomb, community firmware versions are available for the
-   rest.
-
-7.2.1. Asus
-
-     * WL500g
-
-   Use the statically linked mips32el binary package that is
-   provided on our download site.
-
-7.2.2. Buffalo
-
-     * KuroBox-HG
-     * LinkStation
-
-7.2.3. Excito
-
-     * Bubba Mini Server (preinstalled)
-
-7.2.4. Iomega
-
-     * StorCenter (preinstalled)
-
-7.2.5. Linksys
-
-     * NSLU2
-
-   Available via Optware.
-
-7.2.6. Maxtor
-
-     * MSS-I
-
-   Either use the Optware feeds or the statically linked mips2el
-   binary package that is provided on our download site.
-
-7.2.7. Raidsonic
-
-     * IB-NAS4200-B
-
-   Use the statically linked binary armv4 package that is provided
-   on our download site.
-
-7.2.8. Xtreamer
-
-     * Xtreamer eTRAYz
-
-7.2.9. Western Digital
-
-     * MyBook
-
-8. Running The Server
-
-   When you run MediaTomb for the first time a default
-   configuration will be created in the ~/.mediatomb directory. If
-   you are using the sqlite database no further intervention is
-   necessary, if you are using MySQL you will have to make some
-   adjustments (see Configuration section for more details). To
-   start the server simply run "mediatomb" from the console, to
-   shutdown cleanly press Ctrl-C. At start up MediaTomb will print
-   a link to the web UI.
-
-   Note:
-          Internet Explorer support is limited and not yet
-          finished. It is very difficult to support this browser
-          because of a huge number of bugs in its javascript
-          implementation. If you don't believe us - just visit
-          http://selfhtml.org/ and see how often IE is mentioned
-          in not following the specs or simply not working with
-          certain functions and features. We recommend Firefox.
-
-   If you want to run a second server from the same PC, make sure
-   to use a different configuration file with a different udn and
-   a different database.
-
-   After server launch the bookmark file is created in the
-   ~/.mediatomb directory. You now can manually add the bookmark
-   ~/.mediatomb/mediatomb.html in your browser. This will redirect
-   you to the UI if the server is running.
-
-   Assuming that you enabled the UI, you should now be able to get
-   around quite easily.
-
-   We also support the daemon mode which allows to start the
-   server in background, the --user and --group parameters should
-   be used to run the server under an unprivileged account. A
-   script for starting/stopping the server is provided.
-
-9. Legal
-
-THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR OWN
-RISK!
-
-9.1. Copyright
-
-Copyright (C) 2005
-
-   Gena Batyan <bgeradz at mediatomb dot cc>
-
-   Sergey Bostandzhyan <jin at mediatomb dot cc>
-
-Copyright (C) 2006-2008
-
-   Gena Batyan <bgeradz at mediatomb dot cc>
-
-   Sergey Bostandzhyan <jin at mediatomb dot cc>
-
-   Leonhard Wimmer <leo at mediatomb dot cc>
-
-9.2. License
-
-   MediaTomb is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License
-   version 2 as published by the Free Software Foundation.
-   MediaTomb is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-   GNU General Public License for more details. You should have
-   received a copy of the GNU General Public License version 2
-   along with MediaTomb; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-10. Acknowledgments
-
-   We are using the following code in our tree:
-     * uuid from E2fsprogs 1.35 under GNU GPL, Copyright (C) 1996,
-       1997, 1998 Theodore Ts'o. <tytso at mit dot edu> Some
-       functions from the UPnP SDK were conflicting with libuuid,
-       so we had to take the sources in and do some renaming.
-     * md5 implementation by L. Peter Deutsch <ghost at aladdin
-       dot com>, Copyright (c) 1999 Aladdin Enterprises. All
-       rights reserved. (See source headers for further details)
-     * md5 javascript implementation distributed under BSD
-       License, Copyright (c) Paul Johnston 1999 - 2002.
-       http://pajhome.org.uk/crypt/md5
-     * Prototype JavaScript Framework http://www.prototypejs.org/
-       (c) 2005-2007 Sam Stephenson, MIT-style license.
-     * (heavily modified version of) NanoTree
-       http://nanotree.sourceforge.net/ (c) 2003 (?) Martin
-       Mouritzen <martin at nano dot dk>; LGPL
-     * IE PNG fix from
-       http://webfx.eae.net/dhtml/pngbehavior/pngbehavior.html
-     * tombupnp is based on pupnp (http://pupnp.sf.net) which is
-       based on libupnp (http://upnp.sf.net), originally
-       distributed under the BSD license, Copyright (c) 2000-2003
-       Intel Corporation. Note that all changes to libupnp/pupnp
-       code that were made by the MediaTomb team are covered by
-       the LGPL license.
-     * ACX_PTHREAD autoconf script
-       http://autoconf-archive.cryp.to/acx_pthread.html (c) 2006
-       Steven G. Johnson <stevenj at alum dot mit dot edu>
-     * The the Inotify::nextEvent() function is based on code from
-       the inotify tools package, http://inotify-tools.sf.net/,
-       distributed under GPL v2, (c) Rohan McGovern <rohan at
-       mcgovern dot id dot au>
-
-11. Contributions
-
-     * Initial version of the MediaTomb start up script was
-       contributed by Iain Lea <iain at bricbrac dot de>
-     * TagLib support patch was contributed by Benhur Stein
-       <benhur.stein at gmail dot com>
-     * ffmpeg metadata handler was contributed by Ingo Preiml
-       <ipreiml at edu dot uni-klu dot ac dot at>
-     * ID3 keyword extraction patch was contributed by Gabriel
-       Burca <gburca-mediatomb at ebixio dot com>
-     * tombupnp is kept in sync with the latest pupnp
-       (http://pupnp.sf.net/) patches, see documentation in the
-       tombupnp directory
-     * Photo layout by year/month was contributed by Aleix
-       Conchillo Flaque <aleix at member dot fsf dot org>
-     * lastfmlib patch was contributed by Dirk Vanden Boer <dirk
-       dot vdb at gmail dot com>
-     * NetBSD patches were contributed by Jared D. McNeill
-       <jmcneill at NetBSD dot org>
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..fc6c80d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,151 @@
+<img src="https://github.com/v00d00/gerbera/blob/master/artwork/logo-horiz.png?raw=true" />
+
+# Gerbera - UPnP Media Server
+
+[![Build Status](https://travis-ci.org/v00d00/gerbera.svg?branch=master)](https://travis-ci.org/v00d00/gerbera) [![IRC](https://img.shields.io/badge/chat-on%20freenode-blue.svg)](https://webchat.freenode.net/?channels=#gerbera)
+
+Gerbera is a UPnP media server which allows you to stream your digital media through your home network and consume it on a variety of UPnP compatible devices.
+
+_Gerbera is based on [MediaTomb 12.1](http://mediatomb.cc) which is dead upstream, so this is my attempt to kick it back into life._
+
+**Pull requests are very welcome and reporting issues is encouraged.**
+
+## Features
+
+* Browse and playback your media via UPnP
+* Metadata extraction from mp3, ogg, flac, jpeg, etc. files.
+* Exif thumbnail support
+* User defined server layout based on extracted metadata (scriptable virtual containers)
+* Automatic directory rescans (timed, inotify)
+* Web UI with a tree view of the database and the file system, allowing to add/remove/edit/browse your media
+* Highly flexible media format transcoding via plugins / scripts
+* Allows to watch YouTube(tm) videos on your UPnP player device [Broken]
+* Supports last fm scrobbing using lastfmlib 
+* On the fly video thumbnail generation with libffmpegthumbnailer
+* Support for external URLs (create links to internet content and serve them via UPnP to your renderer)
+* Support for ContentDirectoryService container updates
+* Active Items (experimental feature), allows execution of server side scripts upon HTTP GET requests to certain items
+* Highly flexible configuration, allowing you to control the behavior of various features of the server
+* runs on Linux, FreeBSD, NetBSD, Mac OS X, eCS
+* runs on x86, Alpha, ARM, MIPS, Sparc, PowerPC
+
+## Differences to Mediatomb (So far)
+- Rebranded as Gerbera, new Logo!
+- Actively maintained/developed.
+- Removed bundled `libupnp` - Now requires upstream 1.8 version.
+- Removed bundled `libuuid`.
+- Ported to CMake.
+- Enhanced cover art support for MP4, FLAC, Vorbis & WMA files (via TagLib).
+- TagLib handler opens files read only: stops inotify rescanning the dir on access causing "Object not found" [see here][1].
+- Album folders have "creator" metadata (artist).
+- Album folders have artwork: either from external files or the tracks embedded artwork.
+- Per-track external art support: `filename-of-track.jp\*` (minus the audio file extension).
+- Removed `libflac` use/dep.
+- Remove `libmp4v2` use/dep.
+- Remove `id3lib` use/dep.
+- Removed broken DVD image support (dvdnav).
+- IPv6 Support
+- Replaced SpiderMonkey (mozjs) dependency with embedded [duktape] engine.
+- WIP port to "Modern C++" / tidying.
+- Lots of other stuff.
+
+## Installing
+
+### Ubuntu
+Stephen Czetty maintains a [Ubuntu PPA].
+
+### Gentoo
+The [v00d00 overlay] contains a git live ebuild. It will get added to the main portage tree at some point.
+
+## Building
+
+The project has been ported to [CMake].
+
+### Install prerequisites.
+
+#### On Ubuntu 16.04
+```
+apt-get install uuid-dev libexpat1-dev libsqlite3-dev libmysqlclient-dev \
+libmagic-dev libexif-dev libcurl4-openssl-dev
+# If building with LibAV/FFmpeg (-DWITH_AVCODEC=1)
+apt-get install libavutil-dev libavcodec-dev libavformat-dev libavdevice-dev \
+libavfilter-dev libavresample-dev libswscale-dev libswresample-dev libpostproc-dev
+```
+
+The following packages are too old in 16.04 and must be installed from source:
+`taglib` (1.11.x), and `libupnp` (1.8.x).
+
+`libupnp` must be configured/built with `--enable-ipv6`. See
+`scripts/install-pupnp18.sh` for details.
+
+### Quick start build instructions:
+
+```
+git clone https://github.com/v00d00/gerbera.git
+mkdir build
+cd build
+cmake ../gerbera -DWITH_MAGIC=1 -DWITH_MYSQL=1 -DWITH_CURL=1 -DWITH_JS=1 \
+-DWITH_TAGLIB=1 -DWITH_AVCODEC=1 -DWITH_EXIF=1 -DWITH_LASTFM=1
+make -j4
+sudo make install
+```
+Alternatively, the options can be set using a GUI (make sure to press "c" to configure after toggling settings in the GUI):
+```
+git clone https://github.com/v00d00/gerbera.git
+mkdir build
+cd build
+cmake ../gerbera
+make edit_cache
+# Enable some of the WITH... options
+make -j4
+sudo make install
+```
+
+## Dependencies
+
+| Lib          	| Version 	| Required? 	| Note                 	    |
+|--------------	|---------	|-----------	|-------------------------- |
+| libupnp      	| 1.8     	| Required  	| [pupnp] with IPv6 support |
+| libuuid      	|         	| Required  	|                      	    |
+| expat        	|         	| Required  	|                      	    |
+| sqlite3      	|         	| Required  	|                      	    |
+| duktape      	|         	| Optional  	| Scripting Support    	    |
+| mysql        	|         	| Optional  	| Client Libs          	    |
+| curl         	|         	| Optional  	| Enables web services 	    |
+| [taglib]      | 1.11    	| Optional  	| Audio tag support         |
+| libmagic     	|         	| Optional  	| File type detection  	    |
+| ffmpeg/libav 	|         	| Optional  	| File metadata             |
+| libexif      	|         	| Optional  	| JPEG Exif metadata        |
+| lastfmlib    	|         	| Optional  	| Enables scrobbling   	    |
+|              	|         	|           	|                      	    |
+
+## Branches
+**master**: Where the action happens
+
+**vanilla**: Sourceforge mediatomb with patches to build on more modern systems
+
+**gentoo**: Pretty much as vanilla (shipped as net-misc/mediatomb).
+
+## Licence
+
+    GPLv2
+
+    Copyright (C) 2005
+       Gena Batyan <bgeradz at mediatomb dot cc>
+       Sergey Bostandzhyan <jin at mediatomb dot cc>
+
+    Copyright (C) 2006-2008
+       Gena Batyan <bgeradz at mediatomb dot cc>
+       Sergey Bostandzhyan <jin at mediatomb dot cc>
+       Leonhard Wimmer <leo at mediatomb dot cc>
+
+    Copyright (C) 2016-2017
+        Gerbera Contributors
+
+[1]: https://sourceforge.net/p/mediatomb/discussion/440751/thread/258c3cf7/?limit=250
+[pupnp]: https://github.com/mrjimenez/pupnp.git
+[taglib]: http://taglib.org/
+[CMake]: https://cmake.org/
+[Ubuntu PPA]: https://launchpad.net/~stephenczetty/+archive/ubuntu/mediatomb-v00d00
+[v00d00 overlay]: https://github.com/v00d00/overlay
+[duktape]: http://duktape.org
\ No newline at end of file
diff --git a/README.UTF_8 b/README.old
similarity index 100%
rename from README.UTF_8
rename to README.old
diff --git a/TODO b/TODO
deleted file mode 100644
index b18655e..0000000
--- a/TODO
+++ /dev/null
@@ -1 +0,0 @@
-todo... TODO
diff --git a/acinclude.m4 b/acinclude.m4
deleted file mode 100644
index 3cc5ec3..0000000
--- a/acinclude.m4
+++ /dev/null
@@ -1,868 +0,0 @@
-# ====================================================================
-# ACX_PTHREAD
-# ====================================================================
-#
-# This script has been downloaded from
-# http://autoconf-archive.cryp.to/acx_pthread.html
-#
-# Copyright © 2006 Steven G. Johnson <stevenj at alum.mit.edu>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or (at
-# your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-# USA.
-#
-# As a special exception, the respective Autoconf Macro's copyright
-# owner gives unlimited permission to copy, distribute and modify the
-# configure scripts that are the output of Autoconf when processing the
-# Macro. You need not follow the terms of the GNU General Public
-# License when using or distributing such scripts, even though portions
-# of the text of the Macro appear in them. The GNU General Public
-# License (GPL) does govern all other use of the material that
-# constitutes the Autoconf Macro.
-#
-# This special exception to the GPL applies to versions of the
-# Autoconf Macro released by the Autoconf Macro Archive. When you make
-# and distribute a modified version of the Autoconf Macro, you may
-# extend this special exception to the GPL to apply to your modified
-# version as well.
-
-AC_DEFUN([ACX_PTHREAD], [
-AC_REQUIRE([AC_CANONICAL_HOST])
-AC_LANG_SAVE
-AC_LANG_C
-acx_pthread_ok=no
-
-# We used to check for pthread.h first, but this fails if pthread.h
-# requires special compiler flags (e.g. on True64 or Sequent).
-# It gets checked for in the link test anyway.
-
-# First of all, check if the user has set any of the PTHREAD_LIBS,
-# etcetera environment variables, and if threads linking works using
-# them:
-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
-        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
-        AC_MSG_RESULT($acx_pthread_ok)
-        if test x"$acx_pthread_ok" = xno; then
-                PTHREAD_LIBS=""
-                PTHREAD_CFLAGS=""
-        fi
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-fi
-
-# We must check for the threads library under a number of different
-# names; the ordering is very important because some systems
-# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
-# libraries is broken (non-POSIX).
-
-# Create a list of thread flags to try.  Items starting with a "-" are
-# C compiler flags, and other items are library names, except for "none"
-# which indicates that we try without any flags at all, and "pthread-config"
-# which is a program returning the flags for the Pth emulation library.
-
-acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
-
-# The ordering *is* (sometimes) important.  Some notes on the
-# individual items follow:
-
-# pthreads: AIX (must check this before -lpthread)
-# none: in case threads are in libc; should be tried before -Kthread and
-#       other compiler flags to prevent continual compiler warnings
-# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
-# -pthreads: Solaris/gcc
-# -mthreads: Mingw32/gcc, Lynx/gcc
-# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
-#      doesn't hurt to check since this sometimes defines pthreads too;
-#      also defines -D_REENTRANT)
-#      ... -mt is also the pthreads flag for HP/aCC
-# pthread: Linux, etcetera
-# --thread-safe: KAI C++
-# pthread-config: use pthread-config program (for GNU Pth library)
-
-case "${host_cpu}-${host_os}" in
-        *solaris*)
-
-        # On Solaris (at least, for some versions), libc contains stubbed
-        # (non-functional) versions of the pthreads routines, so link-based
-        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
-        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
-        # a function called by this macro, so we could check for that, but
-        # who knows whether they'll stub that too in a future libc.)  So,
-        # we'll just look for -pthreads and -lpthread first:
-
-        acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
-        ;;
-esac
-
-if test x"$acx_pthread_ok" = xno; then
-for flag in $acx_pthread_flags; do
-
-        case $flag in
-                none)
-                AC_MSG_CHECKING([whether pthreads work without any flags])
-                ;;
-
-                -*)
-                AC_MSG_CHECKING([whether pthreads work with $flag])
-                PTHREAD_CFLAGS="$flag"
-                ;;
-
-                pthread-config)
-                AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
-                if test x"$acx_pthread_config" = xno; then continue; fi
-                PTHREAD_CFLAGS="`pthread-config --cflags`"
-                PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
-                ;;
-
-                *)
-                AC_MSG_CHECKING([for the pthreads library -l$flag])
-                PTHREAD_LIBS="-l$flag"
-                ;;
-        esac
-
-        save_LIBS="$LIBS"
-        save_CFLAGS="$CFLAGS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
-        # Check for various functions.  We must include pthread.h,
-        # since some functions may be macros.  (On the Sequent, we
-        # need a special flag -Kthread to make this header compile.)
-        # We check for pthread_join because it is in -lpthread on IRIX
-        # while pthread_create is in libc.  We check for pthread_attr_init
-        # due to DEC craziness with -lpthreads.  We check for
-        # pthread_cleanup_push because it is one of the few pthread
-        # functions on Solaris that doesn't have a non-functional libc stub.
-        # We try pthread_create on general principles.
-        AC_TRY_LINK([#include <pthread.h>],
-                    [pthread_t th; pthread_join(th, 0);
-                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
-                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
-                    [acx_pthread_ok=yes])
-
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-
-        AC_MSG_RESULT($acx_pthread_ok)
-        if test "x$acx_pthread_ok" = xyes; then
-                break;
-        fi
-
-        PTHREAD_LIBS=""
-        PTHREAD_CFLAGS=""
-done
-fi
-
-# Various other checks:
-if test "x$acx_pthread_ok" = xyes; then
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
-        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
-        AC_MSG_CHECKING([for joinable pthread attribute])
-        attr_name=unknown
-        for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
-            AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
-                        [attr_name=$attr; break])
-        done
-        AC_MSG_RESULT($attr_name)
-        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
-            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
-                               [Define to necessary symbol if this constant
-                                uses a non-standard name on your system.])
-        fi
-
-        AC_MSG_CHECKING([if more special flags are required for pthreads])
-        flag=no
-        case "${host_cpu}-${host_os}" in
-            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
-            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
-        esac
-        AC_MSG_RESULT(${flag})
-        if test "x$flag" != xno; then
-            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
-        fi
-
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-
-        # More AIX lossage: must compile with xlc_r or cc_r
-        if test x"$GCC" != xyes; then
-          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
-        else
-          PTHREAD_CC=$CC
-        fi
-else
-        PTHREAD_CC="$CC"
-fi
-
-AC_SUBST(PTHREAD_LIBS)
-AC_SUBST(PTHREAD_CFLAGS)
-AC_SUBST(PTHREAD_CC)
-
-# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
-if test x"$acx_pthread_ok" = xyes; then
-        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
-        :
-else
-        acx_pthread_ok=no
-        $2
-fi
-AC_LANG_RESTORE
-])dnl ACX_PTHREAD
-
-# sets the search path which is used by MT_HAVE_PACKAGE
-AC_DEFUN([MT_SET_SEARCHPATH],
-[
-    AC_REQUIRE([AC_CANONICAL_HOST])
-
-    MT_SEARCHPATH="/usr/local"
-    case $host in
-        *-*-darwin*)
-            MT_SEARCHPATH="/opt/local"
-        ;;
-    esac
-
-    AC_ARG_WITH(search,
-        AC_HELP_STRING([--with-search=DIR], [additionally search for packages in DIR]),
-        [
-            MT_SEARCHPATH=$withval
-            AC_MSG_NOTICE([Will also search for packages in ${MT_SEARCHPATH}])
-        ]
-    )
-
-    MT_SEARCHPATH_HEADERS="${MT_SEARCHPATH}/include"
-    MT_SEARCHPATH_LIBS="${MT_SEARCHPATH}/lib"
-    MT_SEARCHPATH_PROGS="${MT_SEARCHPATH}/bin"
-    MT_SEARCHPATH_PKGCONFIG="${MT_SEARCHPATH}/lib/pkgconfig"
-
-    AC_SUBST(MT_SEARCHPATH)
-    AC_SUBST(MT_SEARCHPATH_HEADERS)
-    AC_SUBST(MT_SEARCHPATH_LIBS)
-    AC_SUBST(MT_SEARCHPATH_PROGS)
-    AC_SUBST(MT_SEARCHPATH_PKGCONFIG)
-])
-
-
-# $1 with parameter/package name
-# $2 library name
-# $3 function name
-# $4 "pass" if requested option failed
-# $5 other libraries
-# 
-# returns:
-#   mt_$1_library_status
-#   mt_$1_libs
-#   mt_$1_ldflags
-
-AC_DEFUN([MT_CHECK_LIBRARY_INTERNAL],
-[
-    mt_[]translit($1, `/.-', `___')_arg_default=yes
-    mt_[]translit($1, `/.-', `___')_library_status=yes
-
-    LIBS_SAVE=$LIBS
-    LDFLAGS_SAVE=$LDFLAGS
-    CFLAGS_SAVE=$CFLAGS
-    CXXFLAGS_SAVE=$CXXFLAGS
-    CPPFLAGS_SAVE=$CPPFLAGS
-
-    AC_ARG_WITH($1-libs,
-        AC_HELP_STRING([--with-$1-libs=DIR], [search for $1 libraries in DIR]),
-        [
-            mt_[]translit($1, `/.-', `___')_search_libs="$withval"
-            AC_MSG_NOTICE([Will search for $1 libs in $withval])
-        ]
-    )
-
-    if test "$mt_[]translit($1, `/.-', `___')_search_libs" ; then
-        unset ac_cv_lib_[]translit($2, `/.-', `___')_$3
-        LDFLAGS="$LDFLAGS -L$mt_[]translit($1, `/.-', `___')_search_libs"
-        AC_CHECK_LIB($2, $3,
-            [
-                mt_[]translit($1, `/.-', `___')_libs="-l$2 $5"
-                mt_[]translit($1, `/.-', `___')_ldflags="-L$mt_[]translit($1, `/.-', `___')_search_libs"
-            ],
-            [
-                mt_[]translit($1, `/.-', `___')_library_status=missing
-                if test "$4" = "pass"; then
-                    AC_MSG_NOTICE([$1 library not found in requested location $mt_$1_search_libs])
-                else
-                AC_MSG_ERROR([$1 library not found in requested location $mt_$1_search_libs])
-                fi
-            ],
-            [
-                $5
-            ]
-        )
-    else
-        unset ac_cv_lib_[]translit($2, `/.-', `___')_$3
-        AC_CHECK_LIB($2, $3,
-            [
-                mt_[]translit($1, `/.-', `___')_libs="-l$2 $5"
-            ],
-            [
-                LDFLAGS="$LDFLAGS -L$MT_SEARCHPATH_LIBS"
-                unset ac_cv_lib_[]translit($2, `/.-', `___')_$3
-                AC_CHECK_LIB($2, $3,
-                    [
-                        mt_[]translit($1, `/.-', `___')_libs="-l$2 $5"
-                        mt_[]translit($1, `/.-', `___')_ldflags="-L$MT_SEARCHPATH_LIBS" 
-                    ],
-                    [
-                        mt_[]translit($1, `/.-', `___')_library_status=missing
-                    ],
-                    [
-                        $5
-                    ]
-                )
-            ],
-            [
-                $5
-            ]
-        )
-    fi
-
-    if test "x$mt_[]translit($1, `/.-', `___')_library_status" != xyes; then
-        mt_[]translit($1, `/.-', `___')_libs=""
-        mt_[]translit($1, `/.-', `___')_ldflags=""
-    fi
-
-    LIBS=$LIBS_SAVE
-    LDFLAGS=$LDFLAGS_SAVE
-    CFLAGS=$CFLAGS_SAVE
-    CXXFLAGS=$CXXFLAGS_SAVE
-    CPPFLAGS=$CPPFLAGS_SAVE
-])
-
-# $1 with parameter / library name
-# $2 header without .h extension
-# $3 fail / pass
-#
-# returns:
-#   mt_$1_header_status
-#   mt_$1_cxxflags
-
-AC_DEFUN([MT_CHECK_HEADER_INTERNAL],
-[
-    LIBS_SAVE=$LIBS
-    LDFLAGS_SAVE=$LDFLAGS
-    CFLAGS_SAVE=$CFLAGS
-    CXXFLAGS_SAVE=$CXXFLAGS
-    CPPFLAGS_SAVE=$CPPFLAGS
-
-    mt_[]translit($1, `/.-', `___')_header_status=yes
-
-    AC_ARG_WITH($1-h,
-        AC_HELP_STRING([--with-$1-h=DIR], [search for $1 headers in DIR]),
-        [
-            mt_[]translit($1, `/.-', `___')_search_headers="$withval"
-            AC_MSG_NOTICE([Will search for $1 headers in $withval])
-        ]
-    )
-
-    if test "$mt_[]translit($1, `/.-', `___')_search_headers" ; then
-        unset translit(ac_cv_header_$2_h, `/.-', `___')
-        CFLAGS="$CFLAGS -I${mt_[]translit($1, `/.-', `___')_search_headers}"
-        CXXFLAGS="$CXXFLAGS -I${mt_[]translit($1, `/.-', `___')_search_headers}"
-        CPPFLAGS="$CPPFLAGS -I${mt_[]translit($1, `/.-', `___')_search_headers}"
-        AC_CHECK_HEADER($mt_[]translit($1, `/.-', `___')_search_headers/$2.h,
-            [
-                mt_[]translit($1, `/.-', `___')_cxxflags="-I${mt_[]translit($1, `/.-', `___')_search_headers}"
-            ],
-            [
-                mt_[]translit($1, `/.-', `___')_header_status=missing
-                if test "$3" = "pass"; then
-                    AC_MSG_NOTICE([$1 headers not found in requested location $mt_$1_search_headers])
-                else
-                    AC_MSG_ERROR([$1 headers not found in requested location $mt_$1_search_headers])
-                fi
-            ]
-        )
-    else
-        unset translit(ac_cv_header_$2_h, `/.-', `___')
-        AC_CHECK_HEADER($2.h,
-            [],
-            [
-                CFLAGS="$CFLAGS -I$MT_SEARCHPATH_HEADERS"
-                CXXFLAGS="$CXXFLAGS -I$MT_SEARCHPATH_HEADERS"
-                CPPFLAGS="$CPPFLAGS -I$MT_SEARCHPATH_HEADERS"
-                unset translit(ac_cv_header_$2_h, `/.-', `___')
-                AC_CHECK_HEADER($MT_SEARCHPATH_HEADERS/$2.h,
-                    [
-                        mt_[]translit($1, `/.-', `___')_cxxflags="-I${MT_SEARCHPATH_HEADERS}"
-                    ],
-                    [
-                        mt_[]translit($1, `/.-', `___')_header_status=missing
-                    ]
-                )
-            ]
-        )
-    fi
-
-    if test "x$mt_[]translit($1, `/.-', `___')_header_status" != xyes; then
-        mt_[]translit($1, `/.-', `___')_cxxflags=""
-    fi
-
-    LIBS=$LIBS_SAVE
-    LDFLAGS=$LDFLAGS_SAVE
-    CFLAGS=$CFLAGS_SAVE
-    CXXFLAGS=$CXXFLAGS_SAVE
-    CPPFLAGS=$CPPFLAGS_SAVE
-])
-
-
-# $1 package name
-# $2 header name (without .h extension)
-# $3 library name
-# $4 function name
-# $5 "pass" if requested options failed
-# $6 additional LDFLAGS
-#
-# returns:
-#   mt_$1_package_status
-#   $1_CFLAGS
-#   $1_LIBS
-#   $1_LDFLAGS
-   
-AC_DEFUN([MT_CHECK_PACKAGE_INTERNAL],
-[
-    MT_CHECK_HEADER_INTERNAL([$1], [$2], [$5])
-    mt_[]translit($1, `/.-', `___')_package_status=${mt_[]translit($1, `/.-', `___')_header_status}
-  
-    if test "x$mt_[]translit($1, `/.-', `___')_package_status" = xyes; then 
-        MT_CHECK_LIBRARY_INTERNAL([$1], [$3], [$4], [$5], [$6])
-        mt_[]translit($1, `/.-', `___')_package_status=${mt_[]translit($1, `/.-', `___')_library_status}
-    fi
-    
-    if test "x$mt_[]translit($1, `/.-', `___')_package_status" = xyes; then
-        translit($1, `a-z/.-', `A-Z___')_CFLAGS=${mt_[]translit($1, `/.-', `___')_cxxflags}
-        translit($1, `a-z/.-', `A-Z___')_LIBS=${mt_[]translit($1, `/.-', `___')_libs}
-        translit($1, `a-z/.-', `A-Z___')_LDFLAGS=${mt_[]translit($1, `/.-', `___')_ldflags}
-    fi 
-])
-
-# $1 option name
-# $2 enable/disable
-# $3 help text
-# $4 action if enabled
-# $5 action if disabled
-#
-# returns:
-#   $1_OPTION_ENABLED
-#   $1_OPTION_REQUESTED
-
-AC_DEFUN([MT_OPTION],
-[
-
-    translit(mt_$1_option_enabled, `/.-', `___')=
-    translit(mt_$1_option_requested, `/.-', `___')=no
-    if test "x$2" = xdisable; then
-        translit(mt_$1_option_enabled, `/.-', `___')=yes
-    else
-        translit(mt_$1_option_enabled, `/.-', `___')=no
-    fi
-
-    AC_ARG_ENABLE([$1],
-        AC_HELP_STRING([--$2-$1], [$3]),
-        [
-            translit(mt_$1_option_enabled, `/.-', `___')=$enableval
-            translit(mt_$1_option_requested, `/.-', `___')=yes
-        ]
-    )
-
-    translit($1, `a-z/.-', `A-Z___')_OPTION_ENABLED=${translit(mt_$1_option_enabled,`/.-', `___')}
-    translit($1, `a-z/.-', `A-Z___')_OPTION_REQUESTED=${translit(mt_$1_option_requested, `/.-', `___')}
-
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_OPTION_ENABLED)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_OPTION_REQUESTED)
-
-    AS_IF([test "x${translit(mt_$1_option_enabled,`/.-', `___')}" = xyes], [$4], [$5])[]dnl
-])
-
-# $1 package name
-# $2 enable/disable
-# $3 enable/disable help string
-# $4 header name (without .h)
-# $5 library name
-# $6 function name
-# $7 "pass" on requested options
-# $8 additional LDFLAGS
-# returns substed:
-#   $1_STATUS
-#   $1_LDFLAGS
-#   $1_LIBS
-#   $1_CFLAGS
-
-AC_DEFUN([MT_CHECK_OPTIONAL_PACKAGE], 
-[
-    mt_[]translit($1, `/.-', `___')_status=yes
-
-    MT_OPTION([$1], [$2], [$3],[],[])
-
-    if test "x${translit($1, `a-z/.-', `A-Z___')_OPTION_ENABLED}" = xyes; then
-        MT_CHECK_PACKAGE_INTERNAL([$1], [$4], [$5], [$6], [$7], [$8])
-        mt_[]translit($1, `/.-', `___')_status=${mt_[]translit($1, `/.-', `___')_package_status}
-    else
-        mt_[]translit($1, `/.-', `___')_status=disabled
-    fi
-    
-    if ((test "x${translit($1, `a-z/.-', `A-Z___')_OPTION_ENABLED}" = xyes) &&
-        (test "x${translit($1, `a-z/.-', `A-Z___')_OPTION_REQUESTED}" = xyes) &&
-        (test "x$mt_[]translit($1, `/.-', `___')_status" != xyes) && (test "$7" != "pass")); then
-        AC_MSG_ERROR([unable to configure $1 support])
-    fi
-
-    if ((test "x$mt_[]translit($1, `/.-', `___')_status" = xyes) &&
-        (test "x$9" != "xundef")); then
-        AC_DEFINE(translit(HAVE_$1, `a-z/.-', `A-Z___'), [1], [$1 library presence])
-    fi
-    
-    translit($1, `a-z/.-', `A-Z___')_STATUS=${mt_[]translit($1, `/.-', `___')_status}
-
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_LIBS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_LDFLAGS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_CFLAGS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_STATUS)
-])
-
-# $1 package name
-# $2 header name (without .h)
-# $3 library name
-# $4 function name
-# $5 additional ldflags
-#
-# returns substed:
-#   $1_STATUS
-#   $1_LDFLAGS
-#   $1_LIBS
-#   $1_CFLAGS
-
-
-AC_DEFUN([MT_CHECK_REQUIRED_PACKAGE],
-[
-    MT_CHECK_PACKAGE_INTERNAL([$1], [$2], [$3], [$4], [], [$5])
-    if test "x$mt_[]translit($1, `/.-', `___')_package_status" != xyes; then
-        AC_MSG_ERROR([unable to configure required package $1])
-    fi
-
-    AC_DEFINE(translit(HAVE_$1, `a-z/.-', `A-Z___'), [1], [$1 library presence])
-    
-    translit($1, `a-z/.-', `A-Z___')_STATUS=${mt_[]translit($1, `/.-', `___')_package_status}
-
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_CFLAGS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_LIBS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_LDFLAGS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_STATUS)
-])
-
-# $1 with parameter name
-# $2 library name
-# $3 function to check
-AC_DEFUN([MT_CHECK_LIBRARY],
-[
-    MT_CHECK_LIBRARY_INTERNAL([$1], [$2], [$3])
-
-    translit($1, `a-z/.-', `A-Z___')_LIBS=${mt_$1_libs}
-    translit($1, `a-z/.-', `A-Z___')_LDFLAGS=${mt_$1_ldflags}
-    translit($1, `a-z/.-', `A-Z___')_STATUS=${mt_$1_library_status}
-    
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_LIBS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_LDFLAGS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_STATUS)
-])
-
-# $1 with parameter name
-# $2 header to check
-# $3 fail or pass in case a path parameter was specified and the header missing
-#    empty: fail
-AC_DEFUN([MT_CHECK_HEADER],
-[
-    MT_CHECK_HEADER_INTERNAL($1, $2, $3)
-    
-    translit($1, `a-z/.-', `A-Z___')_CFLAGS=${mt_$1_cxxflags}
-    translit($1, `a-z/.-', `A-Z___')_STATUS=${mt_$1_header_status}
-
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_CFLAGS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_STATUS)
-])
-
-# $1 package name
-# $2 config file name
-# $3 headers
-# $4 library name
-# $5 function name
-# $6 optional library command
-#
-#  returns substed:
-#    $mt_$1_package_status
-#    $1_LDFLAGS
-#    $1_LIBS
-#    $1_CFLAGS
-
-AC_DEFUN([MT_CHECK_BINCONFIG_INTERNAL],
-[
-    LIBS_SAVE=$LIBS
-    LDFLAGS_SAVE=$LDFLAGS
-    CFLAGS_SAVE=$CFLAGS
-    CXXFLAGS_SAVE=$CXXFLAGS
-    CPPFLAGS_SAVE=$CPPFLAGS
-
-
-    mt_$1_config=none
-    mt_$1_package_status=yes
-
-    AC_ARG_WITH($1-cfg,
-        AC_HELP_STRING([--with-$1-cfg=$2], [absolute path/name of $2]),
-        [
-            mt_$1_search_config="$withval"
-            AC_MSG_NOTICE([Will search for $1 config in $withval])
-        ]
-    )
-
-    if test -n "$mt_$1_search_config"; then
-        AC_MSG_NOTICE([You specified ${mt_$1_search_config} for $2])
-        if test -f "$mt_$1_search_config"; then
-            mt_$1_config=${mt_$1_search_config}
-        else
-            AC_MSG_ERROR([${mt_$1_search_config} not found])
-        fi
-
-        mt_$1_version=`${mt_$1_config} --version 2>/dev/null`
-        if test -z "$mt_$1_version"; then
-            AC_MSG_ERROR([${mt_$1_search_config} could not be executed or returned invalid values])
-        fi
-    else
-        AC_PATH_PROG(mt_$1_config, $2, none)
-        if test "x$mt_$1_config" = xnone; then
-            unset ac_cv_path_mt_$1_config
-            AC_PATH_PROG(mt_$1_config, $2, none, $MT_SEARCHPATH_PROGS)
-            if test "x$mt_$1_config" = xnone; then
-                mt_$1_package_status=missing
-                AC_MSG_RESULT([$2 not found, please install the $1 devel package])
-            fi
-        fi
-       
-        mt_$1_version=`${mt_$1_config} --version 2>/dev/null`
-        if test -z "$mt_$1_version"; then
-            AC_MSG_NOTICE([${mt_$1_config} could not be executed or returned invalid values])
-            mt_$1_package_status=missing
-        fi
-    fi
-    if test "x$mt_$1_package_status" = xyes; then
-        AC_MSG_CHECKING([$1 cflags])
-        mt_$1_cxxflags=`${mt_$1_config} --cflags`
-        AC_MSG_RESULT([$mt_$1_cxxflags])
-        mt_$1_libs=
-        AC_MSG_CHECKING([$1 libs])
-        if test -z "$6";  then
-            mt_$1_libs=`${mt_$1_config} --libs`
-        else
-            mt_$1_libs=`${mt_$1_config} $6`
-        fi
-        AC_MSG_RESULT([$mt_$1_libs])
-    fi
-
-    if test "x$mt_$1_package_status" = xyes; then
-        CPPFLAGS="$CPPFLAGS $mt_$1_cxxflags"
-        CXXFLAGS="$CXXFLAGS $mt_$1_cxxflags"
-        CFLAGS="$CFLAGS $mt_$1_cxxflags"
-        for mt_u_header in translit($3, `/.-', `___'); do
-            unset ac_cv_header_${mt_u_header}
-        done
-        AC_CHECK_HEADERS($3, [], [mt_$1_package_status=missing])
-    fi
-
-    if test "x$mt_$1_package_status" = xyes; then
-        LIBS="$mt_$1_libs $LIBS"
-        if test -z "$4"; then
-            unset ac_cv_func_$5
-            AC_CHECK_FUNCS($5, [], [mt_$1_package_status=missing])
-        else
-            unset ac_cv_lib_$4_$5
-            AC_CHECK_LIB($4, $5, [], [mt_$1_package_status=missing])
-        fi
-    fi
-
-    if test "x$mt_$1_package_status" = xyes; then
-        translit($1, `a-z/.-', `A-Z___')_CFLAGS=${mt_$1_cxxflags}
-        translit($1, `a-z/.-', `A-Z___')_LIBS=${mt_$1_libs}
-        translit($1, `a-z/.-', `A-Z___')_VERSION=${mt_$1_version}
-    fi 
-
-
-    LIBS=$LIBS_SAVE
-    LDFLAGS=$LDFLAGS_SAVE
-    CFLAGS=$CFLAGS_SAVE
-    CXXFLAGS=$CXXFLAGS_SAVE
-    CPPFLAGS=$CPPFLAGS_SAVE
-])
-
-# $1 package name
-# $2 enable/disable
-# $3 enable/disable help string
-# $4 config file name
-# $5 headers
-# $6 library name
-# $7 function name
-# $8 custom lib parameter
-#
-# returns:
-#   mt_$1_package_status
-#   $1_CFLAGS
-#   $1_LIBS
-#   $1_VERSION
-
-AC_DEFUN([MT_CHECK_OPTIONAL_PACKAGE_CFG],
-[
-    mt_$1_status=yes
-    mt_$1_requested=no
-
-    MT_OPTION([$1], [$2], [$3],[],[])
-
-    if test "x${translit($1, `a-z/.-', `A-Z___')_OPTION_ENABLED}" = xyes; then
-        MT_CHECK_BINCONFIG_INTERNAL($1, $4, $5, $6, $7, $8)
-        mt_$1_status=${mt_$1_package_status}
-    else
-        mt_$1_status=disabled
-    fi
- 
-    if ((test "x${translit($1, `a-z/.-', `A-Z___')_OPTION_ENABLED}" = xyes) &&
-        (test "x${translit($1, `a-z/.-', `A-Z___')_OPTION_REQUESTED}" = xyes) &&
-        (test "x$mt_$1_status" != xyes)); then
-        AC_MSG_ERROR([unable to configure $1 support])
-    fi
-   
-    if test "x$mt_$1_status" = xyes; then
-        AC_DEFINE(translit(HAVE_$1, `a-z/.-', `A-Z___'), [1], [$1 library presence])
-    fi
-
-    translit($1, `a-z/.-', `A-Z___')_STATUS=${mt_$1_status}
-
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_CFLAGS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_LIBS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_VERSION)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_STATUS)
-
-
-#    AS_IF([test x"$mt_$1_status" = xyes], [$8], [$9])[]dnl
-])
-
-# $1 package name
-# $2 config file name
-# $3 headers
-# $4 library name
-# $5 function name
-#
-#  returns substed:
-#    $mt_$1_package_status
-#    $1_LDFLAGS
-#    $1_LIBS
-#    $1_CFLAGS
-
-AC_DEFUN([MT_CHECK_REQUIRED_PACKAGE_CFG],
-[
-    MT_CHECK_BINCONFIG_INTERNAL($1, $2, $3, $4, $5)
-    if test "x$mt_$1_package_status" != xyes; then
-        AC_MSG_ERROR([unable to configure required package $1])
-    fi
-    
-    translit($1, `a-z/.-', `A-Z___')_STATUS=${mt_$1_package_status}
-        
-    AC_DEFINE(translit(HAVE_$1, `a-z/.-', `A-Z___'), [1], [$1 library presence])
-
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_CFLAGS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_LIBS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_VERSION)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_STATUS)
-])
-
-# $1 package name
-# $2 config file name
-# $3 headers
-# $4 library name
-# $5 function name
-#
-#  returns substed:
-#    $mt_$1_package_status
-#    $1_LDFLAGS
-#    $1_LIBS
-#    $1_CFLAGS
-
-
-AC_DEFUN([MT_CHECK_PACKAGE_CFG],
-[
-    mt_$1_status=yes
-
-    if test "x$mt_$1_status" = xyes; then
-        MT_CHECK_BINCONFIG_INTERNAL($1, $2, $3, $4, $5)
-        mt_$1_status=${mt_$1_package_status}
-    fi
-    
-    if test "x$mt_$1_status" = xyes; then
-        AC_DEFINE(translit(HAVE_$1, `a-z/.-', `A-Z___'), [1], [$1 library presence])
-    fi
-
-    translit($1, `a-z/.-', `A-Z___')_STATUS=${mt_$1_status}
-
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_CFLAGS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_LIBS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_VERSION)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_STATUS)
-])
-
-# $1 package name
-# $2 headers
-# $3 library name
-# $4 function name
-# $5 additional LDFLAGS
-#
-#  returns substed:
-#    $mt_$1_package_status
-#    $1_LDFLAGS
-#    $1_LIBS
-#    $1_CFLAGS
-
-
-AC_DEFUN([MT_CHECK_PACKAGE],
-[
-    mt_[]translit($1, `/.-', `___')_status=yes
-
-    if test "x$mt_[]translit($1, `/.-', `___')_status" = xyes; then
-        MT_CHECK_PACKAGE_INTERNAL([$1], [$2], [$3], [$4], [], [$5])
-        mt_[]translit($1, `/.-', `___')_status=${mt_[]translit($1, `/.-', `___')_package_status}
-    fi
-
-    if test "x$mt_[]translit($1, `/.-', `___')_status" = xyes; then
-        AC_DEFINE(translit(HAVE_$1, `a-z/.-', `A-Z___'), [1], [$1 library presence])
-    fi
-
-    translit($1, `a-z/.-', `A-Z___')_STATUS=${mt_[]translit($1, `/.-', `___')_status}
-
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_CFLAGS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_LIBS)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_VERSION)
-    AC_SUBST(translit($1, `a-z/.-', `A-Z___')_STATUS)
-])
-
-
diff --git a/artwork/Makefile.am b/artwork/Makefile.am
deleted file mode 100644
index f972d84..0000000
--- a/artwork/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-EXTRA_DIST=mediatomb.xpm
-
diff --git a/artwork/gerbera.xpm b/artwork/gerbera.xpm
new file mode 100644
index 0000000..ef8675e
--- /dev/null
+++ b/artwork/gerbera.xpm
@@ -0,0 +1,583 @@
+/* XPM */
+static char * logo5_xpm[] = {
+"32 32 548 2",
+"  	c None",
+". 	c #5F2000",
+"+ 	c #411300",
+"@ 	c #692400",
+"# 	c #340F00",
+"$ 	c #ED5E00",
+"% 	c #8D3500",
+"& 	c #CC4F00",
+"* 	c #9C3B00",
+"= 	c #4B1800",
+"- 	c #120300",
+"; 	c #D65400",
+"> 	c #B84800",
+", 	c #8A3600",
+"' 	c #FF6900",
+") 	c #C24E00",
+"! 	c #7B2F00",
+"~ 	c #FC6800",
+"{ 	c #BD4C00",
+"] 	c #4A1700",
+"^ 	c #591D00",
+"/ 	c #BF4900",
+"( 	c #D75500",
+"_ 	c #401400",
+": 	c #D55600",
+"< 	c #FB6800",
+"[ 	c #873600",
+"} 	c #A94600",
+"| 	c #FF6D00",
+"1 	c #D85B00",
+"2 	c #BD4F00",
+"3 	c #CC5500",
+"4 	c #521D00",
+"5 	c #E25900",
+"6 	c #A43E00",
+"7 	c #963800",
+"8 	c #571E00",
+"9 	c #A44000",
+"0 	c #FF6A00",
+"a 	c #C55200",
+"b 	c #FF6E00",
+"c 	c #D95D00",
+"d 	c #000000",
+"e 	c #BC5200",
+"f 	c #FF7100",
+"g 	c #C25400",
+"h 	c #E16300",
+"i 	c #CA5700",
+"j 	c #CB5400",
+"k 	c #9E3E00",
+"l 	c #D95600",
+"m 	c #F26300",
+"n 	c #9B3E00",
+"o 	c #D25800",
+"p 	c #EE6700",
+"q 	c #A74700",
+"r 	c #FF7200",
+"s 	c #FE7200",
+"t 	c #723000",
+"u 	c #C55900",
+"v 	c #FF7500",
+"w 	c #A34900",
+"x 	c #F87200",
+"y 	c #BC5400",
+"z 	c #823600",
+"A 	c #FD6E00",
+"B 	c #782F00",
+"C 	c #3A1100",
+"D 	c #7E2E00",
+"E 	c #9D3E00",
+"F 	c #FF6B00",
+"G 	c #FA6B00",
+"H 	c #A64700",
+"I 	c #D65E00",
+"J 	c #9E4500",
+"K 	c #FF7600",
+"L 	c #BA5600",
+"M 	c #CC5F00",
+"N 	c #FF7900",
+"O 	c #A14A00",
+"P 	c #FF7800",
+"Q 	c #AC4F00",
+"R 	c #D56000",
+"S 	c #EE6900",
+"T 	c #070100",
+"U 	c #742C00",
+"V 	c #E15B00",
+"W 	c #DF5800",
+"X 	c #863100",
+"Y 	c #7D2E00",
+"Z 	c #150400",
+"` 	c #D45B00",
+" .	c #FD7200",
+"..	c #A54A00",
+"+.	c #713100",
+"@.	c #E56C00",
+"#.	c #FF7A00",
+"$.	c #E66F00",
+"%.	c #AD5300",
+"&.	c #FF7D00",
+"*.	c #A54E00",
+"=.	c #FC7B00",
+"-.	c #994600",
+";.	c #FD7600",
+">.	c #C45800",
+",.	c #8F3C00",
+"'.	c #F46800",
+").	c #A74200",
+"!.	c #CB4F00",
+"~.	c #FF6800",
+"{.	c #EB6300",
+"].	c #973F00",
+"^.	c #F26D00",
+"/.	c #FA7600",
+"(.	c #944500",
+"_.	c #B45600",
+":.	c #FF7E00",
+"<.	c #FE7F00",
+"[.	c #9F4E00",
+"}.	c #F77D00",
+"|.	c #9E4E00",
+"1.	c #FF8100",
+"2.	c #D96C00",
+"3.	c #C76000",
+"4.	c #FF7B00",
+"5.	c #FC7800",
+"6.	c #984400",
+"7.	c #FA7000",
+"8.	c #FF7000",
+"9.	c #DD5E00",
+"0.	c #310F00",
+"a.	c #431500",
+"b.	c #D15600",
+"c.	c #ED6800",
+"d.	c #9B4500",
+"e.	c #F97600",
+"f.	c #FF7C00",
+"g.	c #F57900",
+"h.	c #823E00",
+"i.	c #F47C00",
+"j.	c #FF8300",
+"k.	c #A55300",
+"l.	c #EB7A00",
+"m.	c #9D5000",
+"n.	c #FF8500",
+"o.	c #AA5600",
+"p.	c #F17900",
+"q.	c #FF7F00",
+"r.	c #D46700",
+"s.	c #BF5800",
+"t.	c #F66F00",
+"u.	c #6A2B00",
+"v.	c #411600",
+"w.	c #762D00",
+"x.	c #843200",
+"y.	c #511A00",
+"z.	c #622100",
+"A.	c #C24B00",
+"B.	c #BF4C00",
+"C.	c #AB4600",
+"D.	c #9E4300",
+"E.	c #AA4A00",
+"F.	c #AF4F00",
+"G.	c #984700",
+"H.	c #FA7C00",
+"I.	c #DB7100",
+"J.	c #AD5900",
+"K.	c #D36E00",
+"L.	c #854100",
+"M.	c #9C4700",
+"N.	c #7B3600",
+"O.	c #BA6200",
+"P.	c #984E00",
+"Q.	c #FF8400",
+"R.	c #FD8200",
+"S.	c #974900",
+"T.	c #DD6A00",
+"U.	c #AF5000",
+"V.	c #9D4700",
+"W.	c #BF5600",
+"X.	c #E26400",
+"Y.	c #FA6C00",
+"Z.	c #FC6600",
+"`.	c #A43D00",
+" +	c #300C00",
+".+	c #C24C00",
+"++	c #FE6900",
+"@+	c #F16E00",
+"#+	c #C65C00",
+"$+	c #803B00",
+"%+	c #974A00",
+"&+	c #F57F00",
+"*+	c #F38000",
+"=+	c #7C3700",
+"-+	c #C94200",
+";+	c #F65100",
+">+	c #FF5200",
+",+	c #FE5300",
+"'+	c #E24A00",
+")+	c #A03900",
+"!+	c #D06D00",
+"~+	c #C86800",
+"{+	c #5F2D00",
+"]+	c #B25900",
+"^+	c #EC7400",
+"/+	c #FF7700",
+"(+	c #FF7300",
+"_+	c #FF6F00",
+":+	c #E66100",
+"<+	c #8B3600",
+"[+	c #953C00",
+"}+	c #E36200",
+"|+	c #DB6E00",
+"1+	c #954C00",
+"2+	c #934300",
+"3+	c #EA4D00",
+"4+	c #FF4E00",
+"5+	c #FC4800",
+"6+	c #E84100",
+"7+	c #F34400",
+"8+	c #FF4C00",
+"9+	c #FD5100",
+"0+	c #AC3A00",
+"a+	c #8F4A00",
+"b+	c #D76100",
+"c+	c #A04400",
+"d+	c #A14200",
+"e+	c #A34000",
+"f+	c #883300",
+"g+	c #120400",
+"h+	c #934000",
+"i+	c #BC5600",
+"j+	c #BC5800",
+"k+	c #C76100",
+"l+	c #D86D00",
+"m+	c #BB6000",
+"n+	c #CF4400",
+"o+	c #FF4F00",
+"p+	c #E33E01",
+"q+	c #6B1E10",
+"r+	c #161616",
+"s+	c #2C1614",
+"t+	c #B33006",
+"u+	c #FD4900",
+"v+	c #F95100",
+"w+	c #984200",
+"x+	c #F18000",
+"y+	c #E47600",
+"z+	c #C86300",
+"A+	c #A74F00",
+"B+	c #9F4900",
+"C+	c #C85A00",
+"D+	c #F66D00",
+"E+	c #F16000",
+"F+	c #732800",
+"G+	c #933700",
+"H+	c #C04E00",
+"I+	c #D95C00",
+"J+	c #E36400",
+"K+	c #EE6D00",
+"L+	c #F07100",
+"M+	c #E56F00",
+"N+	c #DE6F00",
+"O+	c #CA6800",
+"P+	c #753500",
+"Q+	c #FA5200",
+"R+	c #FC4900",
+"S+	c #681E10",
+"T+	c #1A1A1A",
+"U+	c #181818",
+"V+	c #CC3703",
+"W+	c #BB3D00",
+"X+	c #120500",
+"Y+	c #602C00",
+"Z+	c #A54C00",
+"`+	c #A54900",
+" @	c #A14500",
+".@	c #B14A00",
+"+@	c #A24100",
+"@@	c #4B1900",
+"#@	c #642200",
+"$@	c #E65B00",
+"%@	c #FF8000",
+"&@	c #A44B00",
+"*@	c #F04300",
+"=@	c #151515",
+"-@	c #A62C09",
+";@	c #FF4D00",
+">@	c #C36700",
+",@	c #F88100",
+"'@	c #FC7000",
+")@	c #EC6500",
+"!@	c #D35600",
+"~@	c #A43F00",
+"{@	c #320D00",
+"]@	c #722B00",
+"^@	c #9C4000",
+"/@	c #B54E00",
+"(@	c #C05600",
+"_@	c #CC6200",
+":@	c #BE5E00",
+"<@	c #B25A00",
+"[@	c #733100",
+"}@	c #FD5200",
+"|@	c #F94700",
+"1@	c #4C1A12",
+"2@	c #191919",
+"3@	c #BF3304",
+"4@	c #C34000",
+"5@	c #D36F00",
+"6@	c #FA6700",
+"7@	c #DD5700",
+"8@	c #6B2500",
+"9@	c #080100",
+"0@	c #893500",
+"a@	c #C45200",
+"b@	c #DF6200",
+"c@	c #DA6300",
+"d@	c #D06100",
+"e@	c #CD6300",
+"f@	c #BD5D00",
+"g@	c #A75400",
+"h@	c #703700",
+"i@	c #E04A00",
+"j@	c #C73504",
+"k@	c #2A1716",
+"l@	c #7E220D",
+"m@	c #F54500",
+"n@	c #FE5200",
+"o@	c #9E3B00",
+"p@	c #A75700",
+"q@	c #A15200",
+"r@	c #A14F00",
+"s@	c #A44E00",
+"t@	c #A34600",
+"u@	c #923B00",
+"v@	c #632500",
+"w@	c #1B0500",
+"x@	c #DA5500",
+"y@	c #FF6C00",
+"z@	c #FD6F00",
+"A@	c #DC6300",
+"B@	c #AB4E00",
+"C@	c #9E4A00",
+"D@	c #B95A00",
+"E@	c #D96F00",
+"F@	c #E37700",
+"G@	c #983B00",
+"H@	c #E74000",
+"I@	c #C13404",
+"J@	c #CF3802",
+"K@	c #FA4800",
+"L@	c #FF5000",
+"M@	c #CD4300",
+"N@	c #884700",
+"O@	c #FB8500",
+"P@	c #F97900",
+"Q@	c #DE6800",
+"R@	c #A64A00",
+"S@	c #401700",
+"T@	c #782B00",
+"U@	c #A13F00",
+"V@	c #AA4600",
+"W@	c #994000",
+"X@	c #C25600",
+"Y@	c #F06F00",
+"Z@	c #FF8200",
+"`@	c #FD8400",
+" #	c #A65700",
+".#	c #892D00",
+"+#	c #ED4E00",
+"@#	c #FF5100",
+"##	c #FB5200",
+"$#	c #C74100",
+"%#	c #904A00",
+"&#	c #D57300",
+"*#	c #964D00",
+"=#	c #D06900",
+"-#	c #FC7D00",
+";#	c #FF7400",
+">#	c #EF6900",
+",#	c #AE4700",
+"'#	c #2F0E00",
+")#	c #5F2200",
+"!#	c #CD5400",
+"~#	c #FC6D00",
+"{#	c #F87A00",
+"]#	c #CA6500",
+"^#	c #994C00",
+"/#	c #BE6000",
+"(#	c #924A00",
+"_#	c #864200",
+":#	c #983800",
+"<#	c #A53500",
+"[#	c #A23700",
+"}#	c #732E00",
+"|#	c #C96C00",
+"1#	c #934D00",
+"2#	c #F38100",
+"3#	c #FA8300",
+"4#	c #BB5E00",
+"5#	c #682F00",
+"6#	c #B95600",
+"7#	c #EA6B00",
+"8#	c #DF5900",
+"9#	c #632200",
+"0#	c #6D2600",
+"a#	c #EE5E00",
+"b#	c #D15E00",
+"c#	c #A74C00",
+"d#	c #A04900",
+"e#	c #D46400",
+"f#	c #FA7A00",
+"g#	c #A24F00",
+"h#	c #E27400",
+"i#	c #9A4F00",
+"j#	c #FB8700",
+"k#	c #B56000",
+"l#	c #D87300",
+"m#	c #B15E00",
+"n#	c #E47900",
+"o#	c #DF7500",
+"p#	c #AF5900",
+"q#	c #C05D00",
+"r#	c #904100",
+"s#	c #B35100",
+"t#	c #9E4400",
+"u#	c #A74500",
+"v#	c #C14E00",
+"w#	c #CE5100",
+"x#	c #8A3200",
+"y#	c #893300",
+"z#	c #8B3500",
+"A#	c #642600",
+"B#	c #260A00",
+"C#	c #DD6200",
+"D#	c #BE5900",
+"E#	c #CD6400",
+"F#	c #E57200",
+"G#	c #BA5F00",
+"H#	c #CE6B00",
+"I#	c #D06B00",
+"J#	c #D16C00",
+"K#	c #CA6700",
+"L#	c #E06F00",
+"M#	c #B95500",
+"N#	c #D25E00",
+"O#	c #E96400",
+"P#	c #712B00",
+"Q#	c #B04900",
+"R#	c #B65500",
+"S#	c #C45E00",
+"T#	c #CD6700",
+"U#	c #D06800",
+"V#	c #E17200",
+"W#	c #B95B00",
+"X#	c #DC6C00",
+"Y#	c #612B00",
+"Z#	c #ED7100",
+"`#	c #FD7400",
+" $	c #9D4400",
+".$	c #E76400",
+"+$	c #F36300",
+"@$	c #6F2800",
+"#$	c #672600",
+"$$	c #F56600",
+"%$	c #FE6C00",
+"&$	c #C35300",
+"*$	c #8B3C00",
+"=$	c #FD7500",
+"-$	c #F77800",
+";$	c #BE5C00",
+">$	c #DD6C00",
+",$	c #ED7400",
+"'$	c #FD7900",
+")$	c #944200",
+"!$	c #F46F00",
+"~$	c #F16800",
+"{$	c #732D00",
+"]$	c #A94400",
+"^$	c #D45400",
+"/$	c #AC4100",
+"($	c #B24400",
+"_$	c #F46200",
+":$	c #A04000",
+"<$	c #C65600",
+"[$	c #F56F00",
+"}$	c #853B00",
+"|$	c #AE5100",
+"1$	c #E96E00",
+"2$	c #F07200",
+"3$	c #833A00",
+"4$	c #AC4D00",
+"5$	c #D25C00",
+"6$	c #933E00",
+"7$	c #ED6600",
+"8$	c #C95200",
+"9$	c #571D00",
+"0$	c #E96300",
+"a$	c #B94F00",
+"b$	c #883B00",
+"c$	c #A14800",
+"d$	c #F97200",
+"e$	c #EF6E00",
+"f$	c #070200",
+"g$	c #E86800",
+"h$	c #D45D00",
+"i$	c #C65400",
+"j$	c #ED6400",
+"k$	c #8F3900",
+"l$	c #DD5A00",
+"m$	c #FA6400",
+"n$	c #551C00",
+"o$	c #491900",
+"p$	c #EF6400",
+"q$	c #531E00",
+"r$	c #943E00",
+"s$	c #FE7100",
+"t$	c #9F4400",
+"u$	c #E36500",
+"v$	c #B14B00",
+"w$	c #EA6400",
+"x$	c #983D00",
+"y$	c #FD6800",
+"z$	c #CC5100",
+"A$	c #2F0D00",
+"B$	c #A03C00",
+"C$	c #F66200",
+"D$	c #973D00",
+"E$	c #E66200",
+"F$	c #D75B00",
+"G$	c #4A1A00",
+"H$	c #E96100",
+"I$	c #541D00",
+"J$	c #9C3C00",
+"K$	c #C74D00",
+"L$	c #6A2500",
+"M$	c #8F3800",
+"N$	c #B84A00",
+"O$	c #BC4C00",
+"P$	c #642300",
+"Q$	c #581E00",
+"R$	c #EC5D00",
+"S$	c #632300",
+"T$	c #441600",
+"U$	c #823000",
+"V$	c #702700",
+"W$	c #3F1300",
+"                              .     +                           ",
+"                    @       # $ %   & *                         ",
+"              = -   ; >     , ' ) ! ~ {     ] ^                 ",
+"              / ( _ : < [   } | 1 2 | 3   4 5 6                 ",
+"          7 8 9 0 3 a b c d e f g h f i d j 0 k                 ",
+"          l m n o p q r s t u v w x v y z A | B   C D           ",
+"          E F G H I J v K L M N O N P Q R r S T U V W           ",
+"      X Y Z ` f  ...+. at .#.$.%.&.*.&.=.-.;.K >.,.'.F ).          ",
+"      !.~.{.].^.K /.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.          ",
+"      a.b.| c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.K t.u.d v.w.x.y.  ",
+"  z.A.B.C.D.E.F.G.H.1.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.0 Z.`.  ",
+"   +.+++| f @+#+$+%+&+*+=+-+;+>+,+'+)+!+~+{+]+^+#./+(+_+:+<+    ",
+"      [+}+r K #.&.|+1+2+3+4+5+6+7+8+9+0+a+*+j.q.f./.b+c+d+e+f+  ",
+"        g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+w+x+y+z+A+B+C+D+| ' E+F+",
+"  G+H+I+J+K+L+M+N+O+P+Q+R+S+T+T+T+U+V+o+W+d X+Y+(.Z+`+ @. at +@@@  ",
+"#@$@' | f v N &.%@Q.&@>+*@=@T+T+T+T+-@;@n+>@, at 1.&.N v '@)@!@~@{@",
+"  d ]@^@/@(@M _@:@<@[@}@|@1 at T+T+T+2@3 at 4+4@5 at Q.1.&.N v f | 6 at 7@8@",
+"  9 at 0@a at b@c at d@e at f@g at h@i@;@j at k@T+2 at l@m at n@o at p@q at r@s at Z+`+t at u@v at d   ",
+"w at x@~.y at z@A at B@C at D@E at F@G at v+8+H@I at J@K at L@M at N@O at j.%@P at Q@R at S@        ",
+"  T at U@V at W@X at Y@4.:.Z@`@ #.#+#@#o+L@##$#%#&#*#=#-#4./+;#>#,#'#    ",
+"    )#!#~#r K N {#]#^#/#(#_#:#<#[#}#|#1#2#3#4#5#6#7#r b F 8#9#  ",
+"  0#a#' | S b#c#d#e#f#g#h#i#j#k#l#m#n#o#p#Z@%@q#r#s#t#u#v#w#x#  ",
+"  + y#z#A#d B#C#v P D#E#F#G#n.H#I#J#K#Z@|.L#&.#.M#N#f O#P#      ",
+"            Q#8.r u R#4.S#N+1.T#U#V#W#q.X#Y#Z#/+`# $.$y at +$@$    ",
+"          #$$$%$&$*$=$/+&@-$&.;$>$,$A+4.'$=+)$!$r ~${$]$^$/$    ",
+"          ($_$:$d <$r [$}$P N |$1$2$3$/+K 4$5$6$7$y at 8$          ",
+"          0#9$  d 0$b a$b$;#v c$d$e$f$g$r h$i$j$k$l$m$n$        ",
+"                o$~ p$q$r$f s$t$r u$d v$b w$x$y$z$A$B$9$        ",
+"                0#C$z#  D$| E$} b F$d G$H$6 at I$J$K$              ",
+"                  L$    M$' N$M$0 O$    z#C$P$                  ",
+"                        Q$R$S$T$a#U$      V$                    ",
+"                          W$    #@d                             "};
diff --git a/artwork/logo-horiz.png b/artwork/logo-horiz.png
new file mode 100644
index 0000000..437e697
Binary files /dev/null and b/artwork/logo-horiz.png differ
diff --git a/artwork/logo-horiz.svg b/artwork/logo-horiz.svg
new file mode 100644
index 0000000..20bfc8c
--- /dev/null
+++ b/artwork/logo-horiz.svg
@@ -0,0 +1,589 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="210mm"
+   height="297mm"
+   viewBox="0 0 744.09448819 1052.3622047"
+   id="svg5261"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="logo.svg">
+  <defs
+     id="defs5263">
+    <linearGradient
+       id="linearGradient5811"
+       inkscape:collect="always">
+      <stop
+         id="stop5961"
+         offset="0"
+         style="stop-color:#ff9100;stop-opacity:1" />
+      <stop
+         id="stop5963"
+         offset="1"
+         style="stop-color:#ff6100;stop-opacity:1" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient5965">
+      <stop
+         style="stop-color:#ff2200;stop-opacity:1"
+         offset="0"
+         id="stop5813" />
+      <stop
+         style="stop-color:#ff6100;stop-opacity:1"
+         offset="1"
+         id="stop5815" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5817"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(72.730983,30.304576)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5823"
+       gradientUnits="userSpaceOnUse"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489"
+       gradientTransform="translate(144.28732,-27.921454)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5827"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(226.16517,-133.65624)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5831"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(264.54566,-295.2635)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5835"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(164.81021,-590.83787)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5839"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(78.540594,-731.35679)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5843"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-667.17161,-753.94393)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5849"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-548.08536,-839.48381)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5851"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-350.36,-899.44108)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5855"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-68.200347,-838.82218)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5859"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(122.75649,-671.78705)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5927"
+       gradientUnits="userSpaceOnUse"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489"
+       gradientTransform="translate(-687.55257,-738.68075)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5929"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-715.85668,-683.3006)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5931"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-769.15303,-556.3987)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5933"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-813.33235,-382.14573)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5935"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-806.11258,-114.73025)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5937"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-666.09766,37.925386)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5941"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-272.87703,179.15334)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5943"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-72.555184,131.72193)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5945"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-522.5637,142.46446)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5947"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-745.23013,-26.830662)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5965"
+       id="radialGradient5957"
+       cx="372.01669"
+       cy="376.95248"
+       fx="372.01669"
+       fy="376.95248"
+       r="108.72436"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5975"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-164.65829,-889.33076)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5979"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-178.47647,166.04596)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5983"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-426.06786,171.82418)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5987"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-383.11566,-886.31312)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.76"
+     inkscape:cx="315.78337"
+     inkscape:cy="558.98048"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1139"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     showguides="true"
+     inkscape:guide-bbox="true">
+    <sodipodi:guide
+       position="38.636364,643.75001"
+       orientation="0,1"
+       id="guide4230" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata5266">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <g
+       id="g6136"
+       transform="matrix(0.22318551,0,0,0.22318551,52.730415,324.84311)">
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="191.96478"
+         cx="370.47345"
+         id="path5809"
+         style="opacity:1;fill:url(#linearGradient5817);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(0.9902176,0.13953171,-0.13953171,0.9902176,0,0)"
+         style="opacity:1;fill:url(#linearGradient5823);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5821"
+         cx="442.02979"
+         cy="133.73875"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         transform="matrix(0.75793329,0.65233207,-0.65233207,0.75793329,0,0)"
+         style="opacity:1;fill:url(#linearGradient5831);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5829"
+         cx="562.28809"
+         cy="-133.60329"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         transform="matrix(0.92511973,0.3796755,-0.3796755,0.92511973,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="28.003967"
+         cx="523.90765"
+         id="ellipse5825"
+         style="opacity:1;fill:url(#linearGradient5827);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(-0.99939776,0.03470039,-0.03470039,-0.99939776,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-592.28369"
+         cx="-369.42914"
+         id="ellipse5841"
+         style="opacity:1;fill:url(#linearGradient5843);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(-0.52914026,0.84853438,-0.84853438,-0.52914026,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-727.67047"
+         cx="133.08415"
+         id="ellipse5973"
+         style="opacity:1;fill:url(#linearGradient5975);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5987);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5985"
+         cx="-85.373215"
+         cy="-724.65283"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.82249299,0.56877524,-0.56877524,-0.82249299,0,0)" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5851);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5845"
+         cx="-52.617542"
+         cy="-737.78082"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.75966775,0.6503114,-0.6503114,-0.75966775,0,0)" />
+      <ellipse
+         transform="matrix(-0.94784472,0.31873246,-0.31873246,-0.94784472,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-677.82355"
+         cx="-250.3429"
+         id="ellipse5847"
+         style="opacity:1;fill:url(#linearGradient5849);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(-0.34988944,0.936791,-0.936791,-0.34988944,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-677.16193"
+         cx="229.54213"
+         id="ellipse5853"
+         style="opacity:1;fill:url(#linearGradient5855);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5859);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5857"
+         cx="420.49899"
+         cy="-510.12686"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.14020714,0.99012219,-0.99012219,0.14020714,0,0)" />
+      <ellipse
+         transform="matrix(-0.018687,0.99982538,-0.99982538,-0.018687,0,0)"
+         style="opacity:1;fill:url(#linearGradient5839);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5837"
+         cx="376.28302"
+         cy="-569.69666"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         transform="matrix(0.31816875,0.9480341,-0.9480341,0.31816875,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-429.17767"
+         cx="462.55267"
+         id="ellipse5833"
+         style="opacity:1;fill:url(#linearGradient5835);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="scale(-1,-1)"
+         style="opacity:1;fill:url(#linearGradient5927);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5905"
+         cx="-389.81012"
+         cy="-577.02051"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5979);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5977"
+         cx="119.26597"
+         cy="327.70627"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.85658083,-0.51601286,0.51601286,0.85658083,0,0)" />
+      <ellipse
+         inkscape:transform-center-y="22.223356"
+         inkscape:transform-center-x="46.467017"
+         transform="matrix(0.49952848,-0.86629747,0.86629747,0.49952848,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="333.4845"
+         cx="-128.32542"
+         id="ellipse5981"
+         style="opacity:1;fill:url(#linearGradient5983);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5943);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5921"
+         cx="225.18727"
+         cy="293.38217"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.94784472,-0.31873246,0.31873246,0.94784472,0,0)" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5945);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5923"
+         cx="-224.82121"
+         cy="304.12473"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.34988944,-0.936791,0.936791,0.34988944,0,0)" />
+      <ellipse
+         transform="matrix(-0.14020714,-0.99012219,0.99012219,-0.14020714,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="134.82953"
+         cx="-447.48761"
+         id="ellipse5925"
+         style="opacity:1;fill:url(#linearGradient5947);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="199.58554"
+         cx="-368.35519"
+         id="ellipse5915"
+         style="opacity:1;fill:url(#linearGradient5937);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         transform="matrix(0.018687,-0.99982538,0.99982538,0.018687,0,0)" />
+      <ellipse
+         transform="matrix(0.75966775,-0.6503114,0.6503114,0.75966775,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="340.81357"
+         cx="24.865421"
+         id="ellipse5919"
+         style="opacity:1;fill:url(#linearGradient5941);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5931);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5909"
+         cx="-471.41055"
+         cy="-394.73849"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.92511973,-0.3796755,0.3796755,-0.92511973,0,0)" />
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="-220.48552"
+         cx="-515.5899"
+         id="ellipse5911"
+         style="opacity:1;fill:url(#linearGradient5933);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         transform="matrix(-0.75793329,-0.65233207,0.65233207,-0.75793329,0,0)" />
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="-521.64038"
+         cx="-418.11423"
+         id="ellipse5907"
+         style="opacity:1;fill:url(#linearGradient5929);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         transform="matrix(-0.9902176,-0.13953171,0.13953171,-0.9902176,0,0)" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5935);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5913"
+         cx="-508.37006"
+         cy="46.929958"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.31816875,-0.9480341,0.9480341,-0.31816875,0,0)" />
+      <circle
+         r="102.14286"
+         cy="376.95248"
+         cx="372.01669"
+         id="path5819"
+         style="opacity:1;fill:url(#radialGradient5957);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <circle
+         style="opacity:1;fill:#1a1a1a;fill-opacity:1;stroke:#000000;stroke-width:6.80356836;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="circle5949"
+         cx="372.01669"
+         cy="376.95248"
+         r="52.794647" />
+    </g>
+    <flowRoot
+       xml:space="preserve"
+       id="flowRoot6165"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"><flowRegion
+         id="flowRegion6167"><rect
+           id="rect6169"
+           width="455.5788"
+           height="192.93913"
+           x="260.61935"
+           y="248.28078" /></flowRegion><flowPara
+         id="flowPara6171"
+         style="font-size:180px">Gerbera</flowPara></flowRoot>    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.22259712px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="217.17351"
+       y="433.12665"
+       id="text6173"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan6175"
+         x="217.17351"
+         y="433.12665"
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:89.78077698px;font-family:HammersmithOne;-inkscape-font-specification:HammersmithOne;fill:#000000">gerbera</tspan></text>
+  </g>
+</svg>
diff --git a/artwork/logo-orange.svg b/artwork/logo-orange.svg
new file mode 100644
index 0000000..e60c3bf
--- /dev/null
+++ b/artwork/logo-orange.svg
@@ -0,0 +1,582 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="39.317825mm"
+   height="40.377014mm"
+   viewBox="0 0 139.31513 143.06816"
+   id="svg5261"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="logo-orange.svg">
+  <defs
+     id="defs5263">
+    <linearGradient
+       id="linearGradient5811"
+       inkscape:collect="always">
+      <stop
+         id="stop5961"
+         offset="0"
+         style="stop-color:#ff9100;stop-opacity:1" />
+      <stop
+         id="stop5963"
+         offset="1"
+         style="stop-color:#ff6100;stop-opacity:1" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient5965">
+      <stop
+         style="stop-color:#ff2200;stop-opacity:1"
+         offset="0"
+         id="stop5813" />
+      <stop
+         style="stop-color:#ff6100;stop-opacity:1"
+         offset="1"
+         id="stop5815" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5817"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(72.730983,30.304576)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5823"
+       gradientUnits="userSpaceOnUse"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489"
+       gradientTransform="translate(144.28732,-27.921454)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5827"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(226.16517,-133.65624)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5831"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(264.54566,-295.2635)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5835"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(164.81021,-590.83787)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5839"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(78.540594,-731.35679)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5843"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-667.17161,-753.94393)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5849"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-548.08536,-839.48381)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5851"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-350.36,-899.44108)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5855"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-68.200347,-838.82218)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5859"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(122.75649,-671.78705)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5927"
+       gradientUnits="userSpaceOnUse"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489"
+       gradientTransform="translate(-687.55257,-738.68075)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5929"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-715.85668,-683.3006)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5931"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-769.15303,-556.3987)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5933"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-813.33235,-382.14573)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5935"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-806.11258,-114.73025)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5937"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-666.09766,37.925386)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5941"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-272.87703,179.15334)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5943"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-72.555184,131.72193)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5945"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-522.5637,142.46446)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5947"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-745.23013,-26.830662)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5965"
+       id="radialGradient5957"
+       cx="372.01669"
+       cy="376.95248"
+       fx="372.01669"
+       fy="376.95248"
+       r="108.72436"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5975"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-164.65829,-889.33076)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5979"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-178.47647,166.04596)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5983"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-426.06786,171.82418)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5987"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-383.11566,-886.31312)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.8101934"
+     inkscape:cx="65.508705"
+     inkscape:cy="75.944207"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1171"
+     inkscape:window-x="1920"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0">
+    <sodipodi:guide
+       position="-28.759714,73.803659"
+       orientation="0,1"
+       id="guide4230" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata5266">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-67.396077,-339.34767)">
+    <g
+       id="g6136"
+       transform="matrix(0.22318551,0,0,0.22318551,52.730415,324.84311)">
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="191.96478"
+         cx="370.47345"
+         id="path5809"
+         style="opacity:1;fill:url(#linearGradient5817);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(0.9902176,0.13953171,-0.13953171,0.9902176,0,0)"
+         style="opacity:1;fill:url(#linearGradient5823);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5821"
+         cx="442.02979"
+         cy="133.73875"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         transform="matrix(0.75793329,0.65233207,-0.65233207,0.75793329,0,0)"
+         style="opacity:1;fill:url(#linearGradient5831);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5829"
+         cx="562.28809"
+         cy="-133.60329"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         transform="matrix(0.92511973,0.3796755,-0.3796755,0.92511973,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="28.003967"
+         cx="523.90765"
+         id="ellipse5825"
+         style="opacity:1;fill:url(#linearGradient5827);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(-0.99939776,0.03470039,-0.03470039,-0.99939776,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-592.28369"
+         cx="-369.42914"
+         id="ellipse5841"
+         style="opacity:1;fill:url(#linearGradient5843);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(-0.52914026,0.84853438,-0.84853438,-0.52914026,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-727.67047"
+         cx="133.08415"
+         id="ellipse5973"
+         style="opacity:1;fill:url(#linearGradient5975);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5987);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5985"
+         cx="-85.373215"
+         cy="-724.65283"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.82249299,0.56877524,-0.56877524,-0.82249299,0,0)" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5851);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5845"
+         cx="-52.617542"
+         cy="-737.78082"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.75966775,0.6503114,-0.6503114,-0.75966775,0,0)" />
+      <ellipse
+         transform="matrix(-0.94784472,0.31873246,-0.31873246,-0.94784472,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-677.82355"
+         cx="-250.3429"
+         id="ellipse5847"
+         style="opacity:1;fill:url(#linearGradient5849);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(-0.34988944,0.936791,-0.936791,-0.34988944,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-677.16193"
+         cx="229.54213"
+         id="ellipse5853"
+         style="opacity:1;fill:url(#linearGradient5855);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5859);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5857"
+         cx="420.49899"
+         cy="-510.12686"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.14020714,0.99012219,-0.99012219,0.14020714,0,0)" />
+      <ellipse
+         transform="matrix(-0.018687,0.99982538,-0.99982538,-0.018687,0,0)"
+         style="opacity:1;fill:url(#linearGradient5839);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5837"
+         cx="376.28302"
+         cy="-569.69666"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         transform="matrix(0.31816875,0.9480341,-0.9480341,0.31816875,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-429.17767"
+         cx="462.55267"
+         id="ellipse5833"
+         style="opacity:1;fill:url(#linearGradient5835);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="scale(-1,-1)"
+         style="opacity:1;fill:url(#linearGradient5927);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5905"
+         cx="-389.81012"
+         cy="-577.02051"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5979);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5977"
+         cx="119.26597"
+         cy="327.70627"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.85658083,-0.51601286,0.51601286,0.85658083,0,0)" />
+      <ellipse
+         inkscape:transform-center-y="22.223356"
+         inkscape:transform-center-x="46.467017"
+         transform="matrix(0.49952848,-0.86629747,0.86629747,0.49952848,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="333.4845"
+         cx="-128.32542"
+         id="ellipse5981"
+         style="opacity:1;fill:url(#linearGradient5983);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5943);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5921"
+         cx="225.18727"
+         cy="293.38217"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.94784472,-0.31873246,0.31873246,0.94784472,0,0)" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5945);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5923"
+         cx="-224.82121"
+         cy="304.12473"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.34988944,-0.936791,0.936791,0.34988944,0,0)" />
+      <ellipse
+         transform="matrix(-0.14020714,-0.99012219,0.99012219,-0.14020714,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="134.82953"
+         cx="-447.48761"
+         id="ellipse5925"
+         style="opacity:1;fill:url(#linearGradient5947);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="199.58554"
+         cx="-368.35519"
+         id="ellipse5915"
+         style="opacity:1;fill:url(#linearGradient5937);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         transform="matrix(0.018687,-0.99982538,0.99982538,0.018687,0,0)" />
+      <ellipse
+         transform="matrix(0.75966775,-0.6503114,0.6503114,0.75966775,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="340.81357"
+         cx="24.865421"
+         id="ellipse5919"
+         style="opacity:1;fill:url(#linearGradient5941);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5931);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5909"
+         cx="-471.41055"
+         cy="-394.73849"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.92511973,-0.3796755,0.3796755,-0.92511973,0,0)" />
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="-220.48552"
+         cx="-515.5899"
+         id="ellipse5911"
+         style="opacity:1;fill:url(#linearGradient5933);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         transform="matrix(-0.75793329,-0.65233207,0.65233207,-0.75793329,0,0)" />
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="-521.64038"
+         cx="-418.11423"
+         id="ellipse5907"
+         style="opacity:1;fill:url(#linearGradient5929);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         transform="matrix(-0.9902176,-0.13953171,0.13953171,-0.9902176,0,0)" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5935);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5913"
+         cx="-508.37006"
+         cy="46.929958"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.31816875,-0.9480341,0.9480341,-0.31816875,0,0)" />
+      <circle
+         r="102.14286"
+         cy="376.95248"
+         cx="372.01669"
+         id="path5819"
+         style="opacity:1;fill:url(#radialGradient5957);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <circle
+         style="opacity:1;fill:#1a1a1a;fill-opacity:1;stroke:#000000;stroke-width:6.80356836;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="circle5949"
+         cx="372.01669"
+         cy="376.95248"
+         r="52.794647" />
+    </g>
+    <flowRoot
+       xml:space="preserve"
+       id="flowRoot6165"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"><flowRegion
+         id="flowRegion6167"><rect
+           id="rect6169"
+           width="455.5788"
+           height="192.93913"
+           x="260.61935"
+           y="248.28078" /></flowRegion><flowPara
+         id="flowPara6171"
+         style="font-size:180px">Gerbera</flowPara></flowRoot>  </g>
+</svg>
diff --git a/artwork/logo-vertical.svg b/artwork/logo-vertical.svg
new file mode 100644
index 0000000..cdec309
--- /dev/null
+++ b/artwork/logo-vertical.svg
@@ -0,0 +1,582 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="210mm"
+   height="297mm"
+   viewBox="0 0 744.09448819 1052.3622047"
+   id="svg5261"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="logo.svg">
+  <defs
+     id="defs5263">
+    <linearGradient
+       id="linearGradient5811"
+       inkscape:collect="always">
+      <stop
+         id="stop5961"
+         offset="0"
+         style="stop-color:#ff9100;stop-opacity:1" />
+      <stop
+         id="stop5963"
+         offset="1"
+         style="stop-color:#ff6100;stop-opacity:1" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient5965">
+      <stop
+         style="stop-color:#ff2200;stop-opacity:1"
+         offset="0"
+         id="stop5813" />
+      <stop
+         style="stop-color:#ff6100;stop-opacity:1"
+         offset="1"
+         id="stop5815" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5817"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(72.730983,30.304576)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5823"
+       gradientUnits="userSpaceOnUse"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489"
+       gradientTransform="translate(144.28732,-27.921454)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5827"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(226.16517,-133.65624)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5831"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(264.54566,-295.2635)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5835"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(164.81021,-590.83787)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5839"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(78.540594,-731.35679)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5843"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-667.17161,-753.94393)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5849"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-548.08536,-839.48381)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5851"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-350.36,-899.44108)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5855"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-68.200347,-838.82218)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5859"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(122.75649,-671.78705)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5927"
+       gradientUnits="userSpaceOnUse"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489"
+       gradientTransform="translate(-687.55257,-738.68075)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5929"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-715.85668,-683.3006)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5931"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-769.15303,-556.3987)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5933"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-813.33235,-382.14573)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5935"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-806.11258,-114.73025)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5937"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-666.09766,37.925386)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5941"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-272.87703,179.15334)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5943"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-72.555184,131.72193)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5945"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-522.5637,142.46446)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5947"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-745.23013,-26.830662)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5965"
+       id="radialGradient5957"
+       cx="372.01669"
+       cy="376.95248"
+       fx="372.01669"
+       fy="376.95248"
+       r="108.72436"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5975"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-164.65829,-889.33076)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5979"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-178.47647,166.04596)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5983"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-426.06786,171.82418)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5987"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-383.11566,-886.31312)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.98994949"
+     inkscape:cx="533.93593"
+     inkscape:cy="625.63164"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1139"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5266">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <g
+       id="g6136"
+       transform="matrix(0.69744022,0,0,0.69744022,108.54263,-27.814164)">
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="191.96478"
+         cx="370.47345"
+         id="path5809"
+         style="opacity:1;fill:url(#linearGradient5817);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(0.9902176,0.13953171,-0.13953171,0.9902176,0,0)"
+         style="opacity:1;fill:url(#linearGradient5823);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5821"
+         cx="442.02979"
+         cy="133.73875"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         transform="matrix(0.75793329,0.65233207,-0.65233207,0.75793329,0,0)"
+         style="opacity:1;fill:url(#linearGradient5831);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5829"
+         cx="562.28809"
+         cy="-133.60329"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         transform="matrix(0.92511973,0.3796755,-0.3796755,0.92511973,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="28.003967"
+         cx="523.90765"
+         id="ellipse5825"
+         style="opacity:1;fill:url(#linearGradient5827);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(-0.99939776,0.03470039,-0.03470039,-0.99939776,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-592.28369"
+         cx="-369.42914"
+         id="ellipse5841"
+         style="opacity:1;fill:url(#linearGradient5843);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(-0.52914026,0.84853438,-0.84853438,-0.52914026,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-727.67047"
+         cx="133.08415"
+         id="ellipse5973"
+         style="opacity:1;fill:url(#linearGradient5975);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5987);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5985"
+         cx="-85.373215"
+         cy="-724.65283"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.82249299,0.56877524,-0.56877524,-0.82249299,0,0)" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5851);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5845"
+         cx="-52.617542"
+         cy="-737.78082"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.75966775,0.6503114,-0.6503114,-0.75966775,0,0)" />
+      <ellipse
+         transform="matrix(-0.94784472,0.31873246,-0.31873246,-0.94784472,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-677.82355"
+         cx="-250.3429"
+         id="ellipse5847"
+         style="opacity:1;fill:url(#linearGradient5849);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(-0.34988944,0.936791,-0.936791,-0.34988944,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-677.16193"
+         cx="229.54213"
+         id="ellipse5853"
+         style="opacity:1;fill:url(#linearGradient5855);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5859);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5857"
+         cx="420.49899"
+         cy="-510.12686"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.14020714,0.99012219,-0.99012219,0.14020714,0,0)" />
+      <ellipse
+         transform="matrix(-0.018687,0.99982538,-0.99982538,-0.018687,0,0)"
+         style="opacity:1;fill:url(#linearGradient5839);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5837"
+         cx="376.28302"
+         cy="-569.69666"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         transform="matrix(0.31816875,0.9480341,-0.9480341,0.31816875,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-429.17767"
+         cx="462.55267"
+         id="ellipse5833"
+         style="opacity:1;fill:url(#linearGradient5835);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="scale(-1,-1)"
+         style="opacity:1;fill:url(#linearGradient5927);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5905"
+         cx="-389.81012"
+         cy="-577.02051"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5979);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5977"
+         cx="119.26597"
+         cy="327.70627"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.85658083,-0.51601286,0.51601286,0.85658083,0,0)" />
+      <ellipse
+         inkscape:transform-center-y="22.223356"
+         inkscape:transform-center-x="46.467017"
+         transform="matrix(0.49952848,-0.86629747,0.86629747,0.49952848,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="333.4845"
+         cx="-128.32542"
+         id="ellipse5981"
+         style="opacity:1;fill:url(#linearGradient5983);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5943);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5921"
+         cx="225.18727"
+         cy="293.38217"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.94784472,-0.31873246,0.31873246,0.94784472,0,0)" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5945);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5923"
+         cx="-224.82121"
+         cy="304.12473"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.34988944,-0.936791,0.936791,0.34988944,0,0)" />
+      <ellipse
+         transform="matrix(-0.14020714,-0.99012219,0.99012219,-0.14020714,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="134.82953"
+         cx="-447.48761"
+         id="ellipse5925"
+         style="opacity:1;fill:url(#linearGradient5947);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="199.58554"
+         cx="-368.35519"
+         id="ellipse5915"
+         style="opacity:1;fill:url(#linearGradient5937);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         transform="matrix(0.018687,-0.99982538,0.99982538,0.018687,0,0)" />
+      <ellipse
+         transform="matrix(0.75966775,-0.6503114,0.6503114,0.75966775,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="340.81357"
+         cx="24.865421"
+         id="ellipse5919"
+         style="opacity:1;fill:url(#linearGradient5941);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5931);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5909"
+         cx="-471.41055"
+         cy="-394.73849"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.92511973,-0.3796755,0.3796755,-0.92511973,0,0)" />
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="-220.48552"
+         cx="-515.5899"
+         id="ellipse5911"
+         style="opacity:1;fill:url(#linearGradient5933);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         transform="matrix(-0.75793329,-0.65233207,0.65233207,-0.75793329,0,0)" />
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="-521.64038"
+         cx="-418.11423"
+         id="ellipse5907"
+         style="opacity:1;fill:url(#linearGradient5929);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         transform="matrix(-0.9902176,-0.13953171,0.13953171,-0.9902176,0,0)" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5935);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5913"
+         cx="-508.37006"
+         cy="46.929958"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.31816875,-0.9480341,0.9480341,-0.31816875,0,0)" />
+      <circle
+         r="102.14286"
+         cy="376.95248"
+         cx="372.01669"
+         id="path5819"
+         style="opacity:1;fill:url(#radialGradient5957);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <circle
+         style="opacity:1;fill:#1a1a1a;fill-opacity:1;stroke:#000000;stroke-width:6.80356836;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="circle5949"
+         cx="372.01669"
+         cy="376.95248"
+         r="52.794647" />
+    </g>
+    <flowRoot
+       xml:space="preserve"
+       id="flowRoot6165"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"><flowRegion
+         id="flowRegion6167"><rect
+           id="rect6169"
+           width="455.5788"
+           height="192.93913"
+           x="260.61935"
+           y="248.28078" /></flowRegion><flowPara
+         id="flowPara6171"
+         style="font-size:180px">Gerbera</flowPara></flowRoot>    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15.39684868px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="151.86647"
+       y="576.04797"
+       id="text6173"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan6175"
+         x="151.86647"
+         y="576.04797"
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:123.17478943px;font-family:HammersmithOne;-inkscape-font-specification:HammersmithOne">gerbera</tspan></text>
+  </g>
+</svg>
diff --git a/artwork/logo.png b/artwork/logo.png
new file mode 100644
index 0000000..489d320
Binary files /dev/null and b/artwork/logo.png differ
diff --git a/artwork/logo.svg b/artwork/logo.svg
new file mode 100644
index 0000000..4dd0baf
--- /dev/null
+++ b/artwork/logo.svg
@@ -0,0 +1,582 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="210mm"
+   height="297mm"
+   viewBox="0 0 744.09448819 1052.3622047"
+   id="svg5261"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="logo.svg">
+  <defs
+     id="defs5263">
+    <linearGradient
+       id="linearGradient5811"
+       inkscape:collect="always">
+      <stop
+         id="stop5961"
+         offset="0"
+         style="stop-color:#ff9100;stop-opacity:1" />
+      <stop
+         id="stop5963"
+         offset="1"
+         style="stop-color:#ff6100;stop-opacity:1" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient5965">
+      <stop
+         style="stop-color:#ff2200;stop-opacity:1"
+         offset="0"
+         id="stop5813" />
+      <stop
+         style="stop-color:#ff6100;stop-opacity:1"
+         offset="1"
+         id="stop5815" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5817"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(72.730983,30.304576)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5823"
+       gradientUnits="userSpaceOnUse"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489"
+       gradientTransform="translate(144.28732,-27.921454)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5827"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(226.16517,-133.65624)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5831"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(264.54566,-295.2635)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5835"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(164.81021,-590.83787)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5839"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(78.540594,-731.35679)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5843"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-667.17161,-753.94393)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5849"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-548.08536,-839.48381)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5851"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-350.36,-899.44108)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5855"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-68.200347,-838.82218)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5859"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(122.75649,-671.78705)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5927"
+       gradientUnits="userSpaceOnUse"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489"
+       gradientTransform="translate(-687.55257,-738.68075)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5929"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-715.85668,-683.3006)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5931"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-769.15303,-556.3987)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5933"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-813.33235,-382.14573)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5935"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-806.11258,-114.73025)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5937"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-666.09766,37.925386)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5941"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-272.87703,179.15334)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5943"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-72.555184,131.72193)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5945"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-522.5637,142.46446)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5947"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-745.23013,-26.830662)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5965"
+       id="radialGradient5957"
+       cx="372.01669"
+       cy="376.95248"
+       fx="372.01669"
+       fy="376.95248"
+       r="108.72436"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5975"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-164.65829,-889.33076)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5979"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-178.47647,166.04596)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5983"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-426.06786,171.82418)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5811"
+       id="linearGradient5987"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-383.11566,-886.31312)"
+       x1="303.29388"
+       y1="283.06799"
+       x2="303.29388"
+       y2="42.374489" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.98994949"
+     inkscape:cx="533.93593"
+     inkscape:cy="706.44384"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1139"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5266">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <g
+       id="g6136"
+       transform="matrix(0.21523558,0,0,0.21523558,42.475995,262.1228)">
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="191.96478"
+         cx="370.47345"
+         id="path5809"
+         style="opacity:1;fill:url(#linearGradient5817);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(0.9902176,0.13953171,-0.13953171,0.9902176,0,0)"
+         style="opacity:1;fill:url(#linearGradient5823);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5821"
+         cx="442.02979"
+         cy="133.73875"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         transform="matrix(0.75793329,0.65233207,-0.65233207,0.75793329,0,0)"
+         style="opacity:1;fill:url(#linearGradient5831);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5829"
+         cx="562.28809"
+         cy="-133.60329"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         transform="matrix(0.92511973,0.3796755,-0.3796755,0.92511973,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="28.003967"
+         cx="523.90765"
+         id="ellipse5825"
+         style="opacity:1;fill:url(#linearGradient5827);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(-0.99939776,0.03470039,-0.03470039,-0.99939776,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-592.28369"
+         cx="-369.42914"
+         id="ellipse5841"
+         style="opacity:1;fill:url(#linearGradient5843);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(-0.52914026,0.84853438,-0.84853438,-0.52914026,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-727.67047"
+         cx="133.08415"
+         id="ellipse5973"
+         style="opacity:1;fill:url(#linearGradient5975);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5987);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5985"
+         cx="-85.373215"
+         cy="-724.65283"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.82249299,0.56877524,-0.56877524,-0.82249299,0,0)" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5851);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5845"
+         cx="-52.617542"
+         cy="-737.78082"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.75966775,0.6503114,-0.6503114,-0.75966775,0,0)" />
+      <ellipse
+         transform="matrix(-0.94784472,0.31873246,-0.31873246,-0.94784472,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-677.82355"
+         cx="-250.3429"
+         id="ellipse5847"
+         style="opacity:1;fill:url(#linearGradient5849);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="matrix(-0.34988944,0.936791,-0.936791,-0.34988944,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-677.16193"
+         cx="229.54213"
+         id="ellipse5853"
+         style="opacity:1;fill:url(#linearGradient5855);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5859);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5857"
+         cx="420.49899"
+         cy="-510.12686"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.14020714,0.99012219,-0.99012219,0.14020714,0,0)" />
+      <ellipse
+         transform="matrix(-0.018687,0.99982538,-0.99982538,-0.018687,0,0)"
+         style="opacity:1;fill:url(#linearGradient5839);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5837"
+         cx="376.28302"
+         cy="-569.69666"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         transform="matrix(0.31816875,0.9480341,-0.9480341,0.31816875,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="-429.17767"
+         cx="462.55267"
+         id="ellipse5833"
+         style="opacity:1;fill:url(#linearGradient5835);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         transform="scale(-1,-1)"
+         style="opacity:1;fill:url(#linearGradient5927);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5905"
+         cx="-389.81012"
+         cy="-577.02051"
+         rx="31.501034"
+         ry="120.39446" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5979);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5977"
+         cx="119.26597"
+         cy="327.70627"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.85658083,-0.51601286,0.51601286,0.85658083,0,0)" />
+      <ellipse
+         inkscape:transform-center-y="22.223356"
+         inkscape:transform-center-x="46.467017"
+         transform="matrix(0.49952848,-0.86629747,0.86629747,0.49952848,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="333.4845"
+         cx="-128.32542"
+         id="ellipse5981"
+         style="opacity:1;fill:url(#linearGradient5983);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5943);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5921"
+         cx="225.18727"
+         cy="293.38217"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.94784472,-0.31873246,0.31873246,0.94784472,0,0)" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5945);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5923"
+         cx="-224.82121"
+         cy="304.12473"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(0.34988944,-0.936791,0.936791,0.34988944,0,0)" />
+      <ellipse
+         transform="matrix(-0.14020714,-0.99012219,0.99012219,-0.14020714,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="134.82953"
+         cx="-447.48761"
+         id="ellipse5925"
+         style="opacity:1;fill:url(#linearGradient5947);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="199.58554"
+         cx="-368.35519"
+         id="ellipse5915"
+         style="opacity:1;fill:url(#linearGradient5937);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         transform="matrix(0.018687,-0.99982538,0.99982538,0.018687,0,0)" />
+      <ellipse
+         transform="matrix(0.75966775,-0.6503114,0.6503114,0.75966775,0,0)"
+         ry="120.39446"
+         rx="31.501034"
+         cy="340.81357"
+         cx="24.865421"
+         id="ellipse5919"
+         style="opacity:1;fill:url(#linearGradient5941);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5931);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5909"
+         cx="-471.41055"
+         cy="-394.73849"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.92511973,-0.3796755,0.3796755,-0.92511973,0,0)" />
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="-220.48552"
+         cx="-515.5899"
+         id="ellipse5911"
+         style="opacity:1;fill:url(#linearGradient5933);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         transform="matrix(-0.75793329,-0.65233207,0.65233207,-0.75793329,0,0)" />
+      <ellipse
+         ry="120.39446"
+         rx="31.501034"
+         cy="-521.64038"
+         cx="-418.11423"
+         id="ellipse5907"
+         style="opacity:1;fill:url(#linearGradient5929);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         transform="matrix(-0.9902176,-0.13953171,0.13953171,-0.9902176,0,0)" />
+      <ellipse
+         style="opacity:1;fill:url(#linearGradient5935);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="ellipse5913"
+         cx="-508.37006"
+         cy="46.929958"
+         rx="31.501034"
+         ry="120.39446"
+         transform="matrix(-0.31816875,-0.9480341,0.9480341,-0.31816875,0,0)" />
+      <circle
+         r="102.14286"
+         cy="376.95248"
+         cx="372.01669"
+         id="path5819"
+         style="opacity:1;fill:url(#radialGradient5957);fill-opacity:1;stroke:#000000;stroke-width:13.16300011;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+      <circle
+         style="opacity:1;fill:#1a1a1a;fill-opacity:1;stroke:#000000;stroke-width:6.80356836;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="circle5949"
+         cx="372.01669"
+         cy="376.95248"
+         r="52.794647" />
+    </g>
+    <flowRoot
+       xml:space="preserve"
+       id="flowRoot6165"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"><flowRegion
+         id="flowRegion6167"><rect
+           id="rect6169"
+           width="455.5788"
+           height="192.93913"
+           x="260.61935"
+           y="248.28078" /></flowRegion><flowPara
+         id="flowPara6171"
+         style="font-size:180px">Gerbera</flowPara></flowRoot>    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15.39684868px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="199.60614"
+       y="388.15964"
+       id="text6173"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan6175"
+         x="199.60614"
+         y="388.15964"
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:123.17478943px;font-family:'hammersmith one';-inkscape-font-specification:'hammersmith one'">Gerbera</tspan></text>
+  </g>
+</svg>
diff --git a/artwork/mediatomb.xpm b/artwork/mediatomb.xpm
deleted file mode 100644
index 782e37c..0000000
--- a/artwork/mediatomb.xpm
+++ /dev/null
@@ -1,316 +0,0 @@
-/* XPM */
-static char *dummy[]={
-"32 32 281 2",
-"Qt c None",
-"#p c #565656",
-".A c #656565",
-"cw c #717171",
-".z c #343434",
-"b3 c #555555",
-"b7 c #494949",
-".2 c #4c4c4c",
-".# c #565656",
-"cr c #595959",
-"bQ c #434343",
-"al c #494949",
-".M c #3f3f3f",
-"a7 c #363636",
-".U c #3a3a3a",
-"cv c #3b3b3b",
-"cq c #323232",
-"b8 c #2a2a2a",
-"bW c #282828",
-"cs c #282828",
-".k c #343434",
-"cf c #2a2a2a",
-"a. c #292929",
-"cu c #2d2d2d",
-"ay c #343434",
-"ct c #333333",
-"b4 c #222222",
-"#d c #212121",
-"#H c #2c2c2c",
-"b0 c #222222",
-".j c #262626",
-"aX c #353535",
-".L c #1d1d1d",
-"cg c #232323",
-"bt c #282828",
-"#e c #2b2b2b",
-"aL c #252525",
-"aP c #1f1f1f",
-"bu c #252525",
-"cb c #1d1d1d",
-"bV c #1f1f1f",
-"#G c #1a1a1a",
-".a c #242424",
-"bN c #1c1c1c",
-".y c #1a1a1a",
-".7 c #1b1b1b",
-"ca c #1e1e1e",
-".T c #1c1c1c",
-"cp c #1a1a1a",
-"ak c #181818",
-".B c #222222",
-"bM c #1c1c1c",
-".1 c #1a1a1a",
-"bl c #181818",
-".i c #1b1b1b",
-"#Y c #1d1d1d",
-".8 c #1f1f1f",
-"ch c #181818",
-".l c #1e1e1e",
-"bZ c #181818",
-".b c #1c1c1c",
-"ce c #161616",
-"bm c #181818",
-"b6 c #181818",
-"ax c #151515",
-"b9 c #171717",
-"be c #141414",
-"b2 c #181818",
-"bR c #171717",
-".h c #191919",
-"#q c #1d1d1d",
-".N c #1d1d1d",
-"co c #141414",
-".3 c #1c1c1c",
-".c c #1a1a1a",
-"aK c #151515",
-"#X c #151515",
-"#o c #151515",
-"cc c #151515",
-"a6 c #161616",
-"ci c #141414",
-".V c #1c1c1c",
-"a# c #1a1a1a",
-".K c #171717",
-"bB c #161616",
-".x c #171717",
-"aO c #131313",
-".g c #171717",
-"aW c #121212",
-"bA c #141414",
-"bf c #181818",
-".d c #181818",
-"b5 c #151515",
-"bX c #161616",
-"bP c #141414",
-".f c #1b1b1b",
-"cn c #141414",
-".e c #1c1c1c",
-"b1 c #161616",
-".m c #1c1c1c",
-"c# c #131313",
-".C c #1d1d1d",
-"cj c #151515",
-"am c #1e1e1e",
-"#c c #161616",
-"cd c #141414",
-".S c #171717",
-"#f c #1f1f1f",
-"a8 c #1c1c1c",
-"cm c #161616",
-"#9 c #161616",
-"#I c #202020",
-"bU c #151515",
-"ck c #161616",
-".6 c #181818",
-".0 c #191919",
-"c. c #181818",
-".w c #1c1c1c",
-"bs c #151515",
-"cl c #161616",
-"bY c #171717",
-"bL c #181818",
-"#F c #191919",
-"bk c #1b1b1b",
-"aj c #1c1c1c",
-"bv c #1d1d1d",
-".J c #1e1e1e",
-"aY c #1f1f1f",
-"az c #202020",
-"aw c #212121",
-"aM c #222222",
-"bT c #232323",
-"aJ c #242424",
-".n c #252525",
-".v c #262626",
-"a5 c #272727",
-".R c #282828",
-".9 c #292929",
-"#b c #2a2a2a",
-"a4 c #2b2b2b",
-".Z c #2c2c2c",
-".D c #2d2d2d",
-".u c #2e2e2e",
-".o c #2f2f2f",
-".Q c #303030",
-".Y c #313131",
-".I c #323232",
-".P c #333333",
-".t c #343434",
-".p c #353535",
-".s c #363636",
-".r c #373737",
-".q c #383838",
-".H c #393939",
-".G c #3a3a3a",
-".E c #3b3b3b",
-".F c #3c3c3c",
-".O c #3d3d3d",
-".X c #3e3e3e",
-".W c #3f3f3f",
-".5 c #404040",
-"aI c #414141",
-"#n c #424242",
-"#m c #434343",
-"bC c #444444",
-"#l c #454545",
-".4 c #464646",
-"#Q c #494949",
-"bS c #4a4a4a",
-"#a c #4b4b4b",
-"#k c #4c4c4c",
-"aV c #4d4d4d",
-"#j c #4e4e4e",
-"#Z c #4f4f4f",
-"#J c #505050",
-"bh c #525252",
-"bb c #535353",
-"#w c #545454",
-"a2 c #555555",
-"aT c #565656",
-"ag c #575757",
-"at c #585858",
-"af c #595959",
-"#. c #5a5a5a",
-"as c #5b5b5b",
-"## c #5e5e5e",
-"a9 c #606060",
-"aZ c #616161",
-"#i c #626262",
-"#g c #636363",
-"aB c #646464",
-"#t c #656565",
-"#h c #666666",
-"#P c #676767",
-"#3 c #686868",
-"ao c #696969",
-"bg c #6d6d6d",
-"b# c #6e6e6e",
-"a0 c #6f6f6f",
-"aR c #707070",
-"aD c #717171",
-"bE c #727272",
-"aq c #737373",
-"bj c #767676",
-"bp c #777777",
-"#4 c #787878",
-"bd c #797979",
-"#R c #7a7a7a",
-"#x c #7b7b7b",
-"a1 c #7c7c7c",
-"aS c #7d7d7d",
-"aE c #7e7e7e",
-"bq c #828282",
-"ah c #848484",
-"aH c #868686",
-"aN c #878787",
-"aU c #888888",
-"aF c #898989",
-"au c #8a8a8a",
-"bF c #909090",
-"#E c #919191",
-"ba c #9a9a9a",
-"#8 c #9b9b9b",
-"ar c #9c9c9c",
-"#W c #9f9f9f",
-"ad c #a1a1a1",
-"b. c #a2a2a2",
-"aQ c #a3a3a3",
-"aC c #a4a4a4",
-"bH c #a6a6a6",
-"bK c #a8a8a8",
-"bo c #acacac",
-"bO c #afafaf",
-"#s c #b1b1b1",
-"#N c #b3b3b3",
-"#u c #b6b6b6",
-"ac c #b7b7b7",
-"#5 c #b8b8b8",
-"aa c #bcbcbc",
-"ap c #bfbfbf",
-"bw c #c2c2c2",
-"#6 c #c7c7c7",
-"aA c #c8c8c8",
-"an c #c9c9c9",
-"#v c #cbcbcb",
-"#O c #cecece",
-"#7 c #cfcfcf",
-"#r c #d0d0d0",
-"#K c #d1d1d1",
-"#0 c #d3d3d3",
-"bz c #d5d5d5",
-"bx c #d6d6d6",
-"by c #dcdcdc",
-"#D c #dedede",
-"ab c #e0e0e0",
-"bD c #e1e1e1",
-"#C c #e2e2e2",
-"bn c #e3e3e3",
-"#B c #e5e5e5",
-"#y c #e6e6e6",
-"bJ c #e7e7e7",
-"#A c #e8e8e8",
-"bI c #e9e9e9",
-"#z c #eaeaea",
-"br c #ededed",
-"bi c #efefef",
-"#S c #f1f1f1",
-"bc c #f2f2f2",
-"#V c #f3f3f3",
-"a3 c #f4f4f4",
-"bG c #f5f5f5",
-"ae c #f6f6f6",
-"#1 c #f7f7f7",
-"#U c #f8f8f8",
-"aG c #f9f9f9",
-"av c #fafafa",
-"ai c #fbfbfb",
-"#T c #fcfcfc",
-"#2 c #fdfdfd",
-"#M c #fefefe",
-"#L c #ffffff",
-"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt",
-"QtQtQtQtQtQtQtQtQtQt.#.a.b.c.d.e.f.g.h.i.jQtQtQtQtQtQtQtQtQtQtQt",
-"QtQtQtQtQtQtQtQt.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.zQtQtQtQtQtQtQtQt",
-"QtQtQtQtQtQt.A.B.C.D.E.F.E.E.G.H.q.s.p.t.I.D.J.K.LQtQtQtQtQtQtQt",
-"QtQtQtQtQt.M.N.n.E.O.O.O.O.F.E.G.H.q.s.p.P.I.Q.R.S.TQtQtQtQtQtQt",
-"QtQtQtQt.U.V.u.O.O.W.W.X.X.O.O.F.G.H.q.s.t.P.Y.o.Z.0.1QtQtQtQtQt",
-"QtQtQt.2.3.o.X.F.4.F.W.5.W.W.X.O.E.G.H.r.p.P.I.Q.u.Z.6.7QtQtQtQt",
-"QtQtQt.8.9.X.W.F#.###a.F.W.5.W.X.F.E.H.q.s.t.I.Q.o.D#b#c#dQtQtQt",
-"QtQt#e#f.O.W.5.O#g#h#i###j#k.X.X.O.F.G.H#l#m#n.5.W.O.F.Z#o#pQtQt",
-"QtQt#q.P.X.W.5#j#r#s#h#t#u#v#w.E.O.F.E#x#y#z#A#B#C#D#E.t#F#GQtQt",
-"Qt#H#I.F.X.W#J#K#L#M#N#u#M#L#O#P#Q.G#R#S#L#L#T#U#V#W.P#b.n#XQtQt",
-"Qt#Y.D.F.X#Z#0#1#M#L#2#M#1#L#L#O#3#4#5#6#O#M#T#7#8.p.Z#b.9#9a.Qt",
-"Qta#.q.F.Oaa#Labac#M#L#Ladae#L#L#8afag#wah#Mai#R.u.u.Z#b.RajakQt",
-"alam.G.E.Oan#Labaoap#L#Laq#8#L#Laras#.atau#2av#x.o.D.Z#b.RawaxQt",
-"ayaz.H.G.FaA#LabaBaC#L#LaDaE#L#LarasafataF#TaGaHaI.I.Z#b.RaJaKQt",
-"aLaM.q.H.EaA#Lab#gaC#L#LaDaE#L#Lar#.afagaFai#UaN#j#a.W.Q.9.vaOQt",
-"aPaM.r.q.HaA#Lab#iaQ#L#LaRaS#L#L#8afagaTaUaGaeaNaV#k#m.t#b.naWQt",
-"aXaY.p.r.qaA#LabaZaQ#L#La0a1#L#L#8agaTa2aN#1a3aH#l.sa4.Ra5aJa6Qt",
-"a7a8.t.p.s#6#Laba9b.#L#Lb##x#L#LbaaTa2bbaNa3bcbd.D#b.9a5.vazbeQt",
-"Qtbf.I.t.p#6#Lab##ad#L#Lbgbd#L#Lba#wbbbhahbcbibja4.9.Ra5.nbkblQt",
-"Qtbm.9.I.H#O#Mbn#hbo#L#Lbpah#M#2b.bb#Q.qbqbibr#x#b.Ra5.v.nbsbtQt",
-"Qtbubv.Q#E#1aiaibw#S#2#2bxbyaiaG#zao.Qasbzbr#z#r#ka5.v.naMbAQtQt",
-"QtQtbBa4bC#O#1bDbE#NaGbcaubF#SbGaC.p.u.rbHbIbJbK.Q.v.naJbLbMQtQt",
-"QtQtbN.w.u#maaaZ#ka2bOau#Q.Hahb..p.D.D.Z.saCbK.Y.v.naJawbPbQQtQt",
-"QtQtQtbRaJ.D.s.obS#jbS.q.u.u.o.t.Z.Za4#b.9.P.Y.v.naJbTbUbVQtQtQt",
-"QtQtQtbWbX.va4.oaI.s.D.Z.Z.Z.Za4a4#b.9.R.Ra5.v.naJbTbYbZQtQtQtQt",
-"QtQtQtQtb0b1.n.Z.Z#b#b#b#b#b#b.9.9.R.Ra5.v.n.naJbTbLb2b3QtQtQtQt",
-"QtQtQtQtQtb4b5az.R.R.9.9.R.R.R.Ra5a5.v.v.naJbTawbsb6b7QtQtQtQtQt",
-"QtQtQtQtQtQtb8b9c.bTa5a5a5a5.v.v.v.n.naJaJbTbkc#caQtQtQtQtQtQtQt",
-"QtQtQtQtQtQtQtQtcbccbY.JaJ.n.n.naJaJbTaz#FcdcecfQtQtQtQtQtQtQtQt",
-"QtQtQtQtQtQtQtQtQtQtcgchcicjckclbscmcncocpcqQtQtQtQtQtQtQtQtQtQt",
-"QtQtQtQtQtQtQtQtQtQtQtQtQtcrcsctcucvcwQtQtQtQtQtQtQtQtQtQtQtQtQt"};
diff --git a/artwork/stone.blend b/artwork/stone.blend
deleted file mode 100644
index 687a873..0000000
Binary files a/artwork/stone.blend and /dev/null differ
diff --git a/build/Makefile.am b/build/Makefile.am
deleted file mode 100644
index ead18aa..0000000
--- a/build/Makefile.am
+++ /dev/null
@@ -1,101 +0,0 @@
-EXTRA_DIST = gen_libmediatomb_src.sh
-CLEANFILES  = IUpnpErrFile.txt IUpnpInfoFile.txt
-
-noinst_LIBRARIES = libmediatomb.a
-include $(srcdir)/libmediatomb_src
-
-libmediatomb_a_CXXFLAGS = \
-                     -I$(top_srcdir)/src \
-                     -I$(top_srcdir)/tombupnp/ixml/inc \
-                     -I$(top_srcdir)/tombupnp/threadutil/inc \
-                     -I$(top_srcdir)/tombupnp/upnp/inc \
-                     -I$(top_srcdir) \
-                     $(SQLITE3_CFLAGS) \
-                     $(MYSQL_CFLAGS) \
-                     $(LIBJS_CFLAGS) \
-                     $(TAGLIB_CFLAGS) \
-                     $(LIBEXTRACTOR_CFLAGS) \
-                     $(ICONV_CXXFLAGS) \
-                     $(LIBMAGIC_CFLAGS) \
-                     $(ID3LIB_CFLAGS) \
-                     $(FLAC_CFLAGS) \
-                     $(LIBEXIF_CFLAGS) \
-                     $(ZLIB_CFLAGS) \
-                     $(PTHREAD_CFLAGS) \
-                     $(INOTIFY_CFLAGS) \
-                     $(AVFORMAT_CFLAGS) \
-                     $(AVUTIL_CFLAGS) \
-                     $(FFMPEGTHUMBNAILER_CFLAGS) \
-                     $(CURL_CFLAGS) \
-                     $(EXPAT_CFLAGS) \
-                     $(LIBMP4V2_CFLAGS) \
-                     $(LASTFMLIB_CFLAGS)
-
-bin_PROGRAMS = mediatomb
-mediatomb_SOURCES = $(top_srcdir)/src/main.cc
-mediatomb_CXXFLAGS = -I$(top_srcdir)/src \
-                     -I$(top_srcdir)/tombupnp/ixml/inc \
-                     -I$(top_srcdir)/tombupnp/threadutil/inc \
-                     -I$(top_srcdir)/tombupnp/upnp/inc \
-                     -I$(top_srcdir) \
-                     $(SQLITE3_CFLAGS) \
-                     $(MYSQL_CFLAGS) \
-                     $(LIBJS_CFLAGS) \
-                     $(TAGLIB_CFLAGS) \
-                     $(LIBEXTRACTOR_CFLAGS) \
-                     $(ICONV_CXXFLAGS) \
-                     $(LIBMAGIC_CFLAGS) \
-                     $(ID3LIB_CFLAGS) \
-                     $(FLAC_CFLAGS) \
-                     $(LIBEXIF_CFLAGS) \
-                     $(ZLIB_CFLAGS) \
-                     $(PTHREAD_CFLAGS) \
-                     $(INOTIFY_CFLAGS) \
-                     $(AVFORMAT_CFLAGS) \
-                     $(AVUTIL_CFLAGS) \
-                     $(FFMPEGTHUMBNAILER_CFLAGS) \
-                     $(CURL_CFLAGS) \
-                     $(EXPAT_CFLAGS) \
-                     $(LIBMP4V2_CFLAGS) \
-                     $(LASTFMLIB_CFLAGS)
-
-mediatomb_LDADD = \
-    libmediatomb.a \
-    $(top_srcdir)/tombupnp/build/libtombupnp.a \
-    $(LIBEXIF_LDFLAGS) \
-    $(ZLIB_LDFLAGS) \
-    $(EXPAT_LDFLAGS) \
-    $(RT_LDFLAGS) \
-    $(SQLITE3_LDFLAGS) \
-    $(LIBMP4V2_LDFLAGS) \
-	$(LIBMAGIC_LDFLAGS) \
-    $(PTHREAD_LDFLAGS) \
-    $(LIBEXTRACTOR_LDFLAGS) \
-    $(AVFORMAT_LDFLAGS) \
-    $(AVUTIL_LDFLAGS) \
-    $(FFMPEGTHUMBNAILER_LDFLAGS) \
-    $(LASTFMLIB_LDFLAGS) \
-    $(ICONV_LIBS) \
-    $(SQLITE3_LIBS) \
-    $(MYSQL_LIBS) \
-    $(TAGLIB_LIBS) \
-    $(LIBEXTRACTOR_LIBS) \
-    $(LIBJS_LIBS) \
-	$(LIBMAGIC_LIBS) \
-    $(ID3LIB_LIBS) \
-    $(FLAC_LIBS) \
-    $(LIBEXIF_LIBS) \
-    $(ZLIB_LIBS) \
-    $(RT_LIBS) \
-    $(PTHREAD_CFLAGS) \
-    $(PTHREAD_LIBS) \
-    $(AVFORMAT_LIBS) \
-    $(AVUTIL_LIBS) \
-    $(FFMPEGTHUMBNAILER_LIBS) \
-    $(EXPAT_LIBS) \
-    $(LIBMP4V2_LIBS) \
-    $(NSL_LIBS) \
-    $(LWRES_LIBS) \
-    $(LASTFMLIB_LIBS) \
-    $(CURL_LIBS)
-    
diff --git a/build/dummy.h b/build/dummy.h
deleted file mode 100644
index e69de29..0000000
diff --git a/build/gen_libmediatomb_src.sh b/build/gen_libmediatomb_src.sh
deleted file mode 100755
index f647ac4..0000000
--- a/build/gen_libmediatomb_src.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-echo 'libmediatomb_a_SOURCES = \'
-
-find ../src | egrep '\.(cc?|h)$' | sed 's/$/ \\/' | sort 
-
-echo "dummy.h"
-
diff --git a/build/libmediatomb_src b/build/libmediatomb_src
deleted file mode 100644
index ba000a7..0000000
--- a/build/libmediatomb_src
+++ /dev/null
@@ -1,303 +0,0 @@
-libmediatomb_a_SOURCES = \
-../src/action_request.cc \
-../src/action_request.h \
-../src/atrailers_content_handler.cc \
-../src/atrailers_content_handler.h \
-../src/atrailers_service.cc \
-../src/atrailers_service.h \
-../src/autoscan.cc \
-../src/autoscan.h \
-../src/autoscan_inotify.cc \
-../src/autoscan_inotify.h \
-../src/buffered_io_handler.cc \
-../src/buffered_io_handler.h \
-../src/cached_url.cc \
-../src/cached_url.h \
-../src/cds_objects.cc \
-../src/cds_objects.h \
-../src/cds_resource.cc \
-../src/cds_resource.h \
-../src/cds_resource_manager.cc \
-../src/cds_resource_manager.h \
-../src/common.h \
-../src/config_manager.cc \
-../src/config_manager.h \
-../src/config_options.h \
-../src/content_manager.cc \
-../src/content_manager.h \
-../src/curl_io_handler.cc \
-../src/curl_io_handler.h \
-../src/destroyer.cc \
-../src/destroyer.h \
-../src/dictionary.cc \
-../src/dictionary.h \
-../src/dvd_io_handler.cc \
-../src/dvd_io_handler.h \
-../src/dvdnav_read.cc \
-../src/dvdnav_read.h \
-../src/exceptions.cc \
-../src/exceptions.h \
-../src/executor.h \
-../src/fd_io_handler.cc \
-../src/fd_io_handler.h \
-../src/file_io_handler.cc \
-../src/file_io_handler.h \
-../src/file_request_handler.cc \
-../src/file_request_handler.h \
-../src/filesystem.cc \
-../src/filesystem.h \
-../src/generic_task.cc \
-../src/generic_task.h \
-../src/hash/dbb_hash.h \
-../src/hash/db_hash.h \
-../src/hash/dbo_hash.h \
-../src/hash/dbr_hash.h \
-../src/hash/direct_hash_base.h \
-../src/hash/dsb_hash.h \
-../src/hash/dso_hash.h \
-../src/hash.h \
-../src/inotify-nosys.h \
-../src/io_handler_buffer_helper.cc \
-../src/io_handler_buffer_helper.h \
-../src/io_handler.cc \
-../src/io_handler_chainer.cc \
-../src/io_handler_chainer.h \
-../src/io_handler.h \
-../src/jpeg_resolution.cc \
-../src/lastfm_scrobbler.cc \
-../src/lastfm_scrobbler.h \
-../src/layout/fallback_layout.cc \
-../src/layout/fallback_layout.h \
-../src/layout/js_layout.cc \
-../src/layout/js_layout.h \
-../src/layout/layout.h \
-../src/logger.cc \
-../src/logger.h \
-../src/main.cc \
-../src/md5/md5.c \
-../src/md5/md5.h \
-../src/mem_io_handler.cc \
-../src/mem_io_handler.h \
-../src/memory.cc \
-../src/memory.h \
-../src/metadata/dvd_handler.cc \
-../src/metadata/dvd_handler.h \
-../src/metadata/exiv2_handler.cc \
-../src/metadata/exiv2_handler.h \
-../src/metadata/ffmpeg_handler.cc \
-../src/metadata/ffmpeg_handler.h \
-../src/metadata_handler.cc \
-../src/metadata_handler.h \
-../src/metadata/id3_handler.cc \
-../src/metadata/id3_handler.h \
-../src/metadata/libexif_handler.cc \
-../src/metadata/libexif_handler.h \
-../src/metadata/libmp4v2_handler.cc \
-../src/metadata/libmp4v2_handler.h \
-../src/metadata/taglib_handler.cc \
-../src/metadata/taglib_handler.h \
-../src/metadata/flac_handler.cc \
-../src/metadata/flac_handler.h \
-../src/mpegdemux/buffer.c \
-../src/mpegdemux/buffer.h \
-../src/mpegdemux/mpegdemux.c \
-../src/mpegdemux/mpegdemux.h \
-../src/mpegdemux/mpegdemux_internal.h \
-../src/mpegdemux/mpeg_parse.c \
-../src/mpegdemux/mpeg_parse.h \
-../src/mpegdemux/mpeg_remux.c \
-../src/mpegdemux/mpeg_remux.h \
-../src/mpegremux_processor.cc \
-../src/mpegremux_processor.h \
-../src/mt_inotify.cc \
-../src/mt_inotify.h \
-../src/mxml/attribute.cc \
-../src/mxml/attribute.h \
-../src/mxml/comment.cc \
-../src/mxml/comment.h \
-../src/mxml/context.cc \
-../src/mxml/context.h \
-../src/mxml/document.cc \
-../src/mxml/document.h \
-../src/mxml/element.cc \
-../src/mxml/element.h \
-../src/mxml/mxml.h \
-../src/mxml/node.cc \
-../src/mxml/node.h \
-../src/mxml/parseexception.cc \
-../src/mxml/parseexception.h \
-../src/mxml/parser_expat.cc \
-../src/mxml/parser.h \
-../src/mxml/xml_text.cc \
-../src/mxml/xml_text.h \
-../src/mxml/xml_to_json.cc \
-../src/mxml/xml_to_json.h \
-../src/object_dictionary.h \
-../src/online_service.cc \
-../src/online_service.h \
-../src/online_service_helper.cc \
-../src/online_service_helper.h \
-../src/play_hook.cc \
-../src/play_hook.h \
-../src/process.cc \
-../src/process_executor.cc \
-../src/process_executor.h \
-../src/process.h \
-../src/process_io_handler.cc \
-../src/process_io_handler.h \
-../src/reentrant_array.h \
-../src/request_handler.cc \
-../src/request_handler.h \
-../src/rexp.cc \
-../src/rexp.h \
-../src/scripting/dvd_image_import_script.cc \
-../src/scripting/dvd_image_import_script.h \
-../src/scripting/import_script.cc \
-../src/scripting/import_script.h \
-../src/scripting/js_functions.cc \
-../src/scripting/js_functions.h \
-../src/scripting/playlist_parser_script.cc \
-../src/scripting/playlist_parser_script.h \
-../src/scripting/runtime.cc \
-../src/scripting/runtime.h \
-../src/scripting/script.cc \
-../src/scripting/script.h \
-../src/server.cc \
-../src/serve_request_handler.cc \
-../src/serve_request_handler.h \
-../src/server.h \
-../src/session_manager.cc \
-../src/session_manager.h \
-../src/singleton.cc \
-../src/singleton.h \
-../src/sopcast_content_handler.cc \
-../src/sopcast_content_handler.h \
-../src/sopcast_service.cc \
-../src/sopcast_service.h \
-../src/storage/cache_object.cc \
-../src/storage/cache_object.h \
-../src/storage.cc \
-../src/storage.h \
-../src/storage/mysql/mysql_create_sql.h \
-../src/storage/mysql/mysql_storage.cc \
-../src/storage/mysql/mysql_storage.h \
-../src/storage/sqlite3/sqlite3_create_sql.h \
-../src/storage/sqlite3/sqlite3_storage.cc \
-../src/storage/sqlite3/sqlite3_storage.h \
-../src/storage/sql_storage.cc \
-../src/storage/sql_storage.h \
-../src/storage/storage_cache.cc \
-../src/storage/storage_cache.h \
-../src/string_converter.cc \
-../src/string_converter.h \
-../src/subscription_request.cc \
-../src/subscription_request.h \
-../src/sync.cc \
-../src/sync.h \
-../src/task_processor.cc \
-../src/task_processor.h \
-../src/thread_executor.cc \
-../src/thread_executor.h \
-../src/timer.cc \
-../src/timer.h \
-../src/tools.cc \
-../src/tools.h \
-../src/transcoding/transcode_dispatcher.cc \
-../src/transcoding/transcode_dispatcher.h \
-../src/transcoding/transcode_ext_handler.cc \
-../src/transcoding/transcode_ext_handler.h \
-../src/transcoding/transcode_handler.h \
-../src/transcoding/transcoding.cc \
-../src/transcoding/transcoding.h \
-../src/transcoding/transcoding_process_executor.cc \
-../src/transcoding/transcoding_process_executor.h \
-../src/update_manager.cc \
-../src/update_manager.h \
-../src/upnp_cds_actions.cc \
-../src/upnp_cds.cc \
-../src/upnp_cds.h \
-../src/upnp_cds_subscriptions.cc \
-../src/upnp_cm_actions.cc \
-../src/upnp_cm.cc \
-../src/upnp_cm.h \
-../src/upnp_cm_subscriptions.cc \
-../src/upnp_mrreg_actions.cc \
-../src/upnp_mrreg.cc \
-../src/upnp_mrreg.h \
-../src/upnp_mrreg_subscriptions.cc \
-../src/upnp_xml.cc \
-../src/upnp_xml.h \
-../src/url.cc \
-../src/url.h \
-../src/url_request_handler.cc \
-../src/url_request_handler.h \
-../src/uuid/clear.c \
-../src/uuid/compare.c \
-../src/uuid/copy.c \
-../src/uuid/gen_uuid.c \
-../src/uuid/isnull.c \
-../src/uuid/pack.c \
-../src/uuid/parse.c \
-../src/uuid/unpack.c \
-../src/uuid/unparse.c \
-../src/uuid/uuid.h \
-../src/uuid/uuidP.h \
-../src/uuid/uuid_time.c \
-../src/uuid/uuid_types.h \
-../src/web/action.cc \
-../src/web/add.cc \
-../src/web/add_object.cc \
-../src/web/auth.cc \
-../src/web_callbacks.cc \
-../src/web_callbacks.h \
-../src/web/containers.cc \
-../src/web/directories.cc \
-../src/web/edit_load.cc \
-../src/web/edit_save.cc \
-../src/web/files.cc \
-../src/web/items.cc \
-../src/weborama_content_handler.cc \
-../src/weborama_content_handler.h \
-../src/weborama_service.cc \
-../src/weborama_service.h \
-../src/web/pages.cc \
-../src/web/pages.h \
-../src/web/remove.cc \
-../src/web_request_handler.cc \
-../src/web_request_handler.h \
-../src/web/tasks.cc \
-../src/web/web_autoscan.cc \
-../src/web/web_update.cc \
-../src/xpath.cc \
-../src/xpath.h \
-../src/youtube_content_handler.cc \
-../src/youtube_content_handler.h \
-../src/youtube_service.cc \
-../src/youtube_service.h \
-../src/youtube_video_url.cc \
-../src/youtube_video_url.h \
-../src/zmm/atomic.h \
-../src/zmmf/array.cc \
-../src/zmmf/array.h \
-../src/zmmf/base_array.h \
-../src/zmmf/base_queue.h \
-../src/zmmf/base_stack.h \
-../src/zmmf/exception.cc \
-../src/zmmf/exception.h \
-../src/zmmf/object_queue.h \
-../src/zmmf/object_stack.h \
-../src/zmmf/stringtokenizer.cc \
-../src/zmmf/stringtokenizer.h \
-../src/zmmf/zmmf.h \
-../src/zmm/nil.cc \
-../src/zmm/nil.h \
-../src/zmm/null.h \
-../src/zmm/object.cc \
-../src/zmm/object.h \
-../src/zmm/ref.h \
-../src/zmm/stringbuffer.cc \
-../src/zmm/stringbuffer.h \
-../src/zmm/strings.cc \
-../src/zmm/strings.h \
-../src/zmm/zmm.h \
-dummy.h
diff --git a/cmake/DefFileName.cmake b/cmake/DefFileName.cmake
new file mode 100644
index 0000000..6ed5194
--- /dev/null
+++ b/cmake/DefFileName.cmake
@@ -0,0 +1,28 @@
+# Based on deffilename.cmake from
+# https://github.com/cdesjardins/include
+#
+# Helper function to add preprocesor definition of __FILENAME__
+# to pass the filename without directory path for debugging use.
+#
+# Example:
+#
+#   define_file_path_for_sources(my_target)
+#
+# Will add -D__FILENAME__="filename" for each source file depended on
+# by my_target, where filename is the path relative to CMAKE_SOURCE_DIR.
+#
+function(define_file_path_for_sources targetname)
+    get_target_property(source_files "${targetname}" SOURCES)
+    foreach(sourcefile ${source_files})
+        # Get source file's current list of compile definitions.
+        get_property(defs SOURCE "${sourcefile}"
+            PROPERTY COMPILE_DEFINITIONS)
+        # Add the __FILENAME__=filename compile definition to the list.
+        string(REPLACE "${CMAKE_SOURCE_DIR}" "" NAME "${sourcefile}")
+        list(APPEND defs "__FILENAME__=\"${NAME}\"")
+        # Set the updated compile definitions on the source file.
+        set_property(
+            SOURCE "${sourcefile}"
+            PROPERTY COMPILE_DEFINITIONS ${defs})
+    endforeach()
+endfunction()
\ No newline at end of file
diff --git a/cmake/FindDuktape.cmake b/cmake/FindDuktape.cmake
new file mode 100644
index 0000000..21eab33
--- /dev/null
+++ b/cmake/FindDuktape.cmake
@@ -0,0 +1,33 @@
+# - Try to find duktape
+# Once done this will define
+#
+#  DUKTAPE_FOUND - system has Duktape
+#  DUKTAPE_INCLUDE_DIRS - the Duktape include directory
+#  DUKTAPE_LIBRARIES - Link these to use DUKTAPE
+#  DUKTAPE_DEFINITIONS - Compiler switches required for using Duktape
+#
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_DUK QUIET duktape libduktape)
+
+find_path(DUKTAPE_INCLUDE_DIR duktape.h
+    HINTS ${PC_DUK_INCLUDEDIR} ${PC_DUK_INCLUDE_DIRS}
+    PATH_SUFFIXES duktape)
+
+find_library(DUKTAPE_LIBARY
+    NAMES duktape libduktape
+    HINTS ${PC_DUK_LIBDIR} ${PC_DUK_LIBRARY_DIRS})
+
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Duktape
+        REQUIRED_VARS DUKTAPE_LIBARY DUKTAPE_INCLUDE_DIR)
+
+if (DUKTAPE_FOUND)
+    set (DUKTAPE_LIBRARIES ${DUKTAPE_LIBARY})
+    set (DUKTAPE_INCLUDE_DIRS ${DUKTAPE_INCLUDE_DIR} )
+endif ()
+
+MARK_AS_ADVANCED(
+    DUKTAPE_INCLUDE_DIR
+    DUKTAPE_LIBARY
+)
diff --git a/cmake/FindEXIF.cmake b/cmake/FindEXIF.cmake
new file mode 100644
index 0000000..cfc17e5
--- /dev/null
+++ b/cmake/FindEXIF.cmake
@@ -0,0 +1,112 @@
+# - Find libexif
+# Find the native EXIF includes and library.
+# Once done this will define:
+#
+#  EXIF_ROOT_DIR       - The base directory of EXIF library.
+#  EXIF_INCLUDE_DIRS   - Where to find exif-*.h header files.
+#  EXIF_LIBRARIES      - Libraries to be linked with executable.
+#  EXIF_FOUND          - True if EXIF library is found.
+#
+#  EXIF_VERSION_STRING - The version of EXIF library found (x.y.z)
+#  EXIF_VERSION_MAJOR  - The major version of EXIF library
+#  EXIF_VERSION_MINOR  - The minor version of EXIF library
+#  EXIF_VERSION_PATCH  - The patch version of EXIF library
+#
+# Optional input variables:
+#
+#  EXIF_USE_STATIC_LIB - This can be set to ON to use the static version of
+#      the library. If it does not exist in the system, a warning is printed
+#      and the shared library is used.
+#
+# If libexif is installed in a custom folder (this usually happens on Windows)
+# the environment variable EXIF_ROOT_DIR can be set to the base folder of
+# the library.
+#
+#=============================================================================
+# Copyright (C) 2011 Simone Rossetto <simros85 at gmail.com>
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#=============================================================================
+
+### FIND section ###
+find_path(EXIF_ROOT_DIR
+    NAMES "include/libexif/exif-data.h"
+    PATHS ENV EXIF_ROOT_DIR)
+
+find_path(EXIF_INCLUDE_DIR
+    NAMES "libexif/exif-data.h"
+    HINTS ${EXIF_ROOT_DIR}
+    PATHS ENV EXIF_ROOT_DIR
+    PATH_SUFFIXES "include")
+
+find_library(EXIF_LIBRARY
+    NAMES "exif"
+    HINTS ${EXIF_ROOT_DIR}
+    PATHS ENV EXIF_ROOT_DIR
+    PATH_SUFFIXES "lib")
+
+find_file(_exif_pkg_config_file
+    NAMES "libexif.pc"
+    HINTS ${EXIF_ROOT_DIR}
+    PATHS ENV EXIF_ROOT_DIR
+    PATH_SUFFIXES "lib/pkgconfig" "pkgconfig")
+
+if(EXISTS ${_exif_pkg_config_file})
+    file(STRINGS "${_exif_pkg_config_file}" _exif_version REGEX "^Version: .*$")
+    string(REGEX REPLACE "^.*Version: ([0-9]+).*$" "\\1" EXIF_VERSION_MAJOR "${_exif_version}")
+    string(REGEX REPLACE "^.*Version: [0-9]+\\.([0-9]+).*$" "\\1" EXIF_VERSION_MINOR  "${_exif_version}")
+    string(REGEX REPLACE "^.*Version: [0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" EXIF_VERSION_PATCH "${_exif_version}")
+    set(EXIF_VERSION_STRING "${EXIF_VERSION_MAJOR}.${EXIF_VERSION_MINOR}.${EXIF_VERSION_PATCH}")
+else(EXISTS ${_exif_pkg_config_file})
+    set(EXIF_VERSION_STRING "")
+endif(EXISTS ${_exif_pkg_config_file})
+
+
+### OPTIONS and COMPONENTS section ###
+if(EXIF_USE_STATIC_LIB)
+    set(_exif_shared_lib ${EXIF_LIBRARY})
+    if(WIN32 AND NOT MSVC)
+        string(REPLACE ".dll.a" ".a" _exif_static_lib ${_exif_shared_lib})
+    elseif(APPLE)
+        string(REPLACE ".dylib" ".a" _exif_static_lib ${_exif_shared_lib})
+    elseif(UNIX)
+        string(REPLACE ".so" ".a" _exif_static_lib ${_exif_shared_lib})
+    endif()
+
+    if(EXISTS ${_exif_static_lib})
+        set(EXIF_LIBRARY ${_exif_static_lib})
+    else(EXISTS ${_exif_static_lib})
+        message(WARNING "EXIF static library does not exist, using the shared one.")
+        set(EXIF_LIBRARY ${_exif_shared_lib})
+    endif(EXISTS ${_exif_static_lib})
+endif(EXIF_USE_STATIC_LIB)
+
+mark_as_advanced(
+    EXIF_LIBRARY
+    EXIF_INCLUDE_DIR
+    _exif_pkg_config_file
+    _exif_shared_lib
+    _exif_static_lib)
+
+
+### final check ###
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(EXIF
+    REQUIRED_VARS EXIF_LIBRARY EXIF_INCLUDE_DIR
+    VERSION_VAR EXIF_VERSION_STRING)
+
+if(EXIF_FOUND)
+    set(EXIF_INCLUDE_DIRS ${EXIF_INCLUDE_DIR} "${EXIF_INCLUDE_DIR}/libexif")
+    set(EXIF_LIBRARIES ${EXIF_LIBRARY})
+endif(EXIF_FOUND)
\ No newline at end of file
diff --git a/cmake/FindFFMPEG.cmake b/cmake/FindFFMPEG.cmake
new file mode 100644
index 0000000..caa53f1
--- /dev/null
+++ b/cmake/FindFFMPEG.cmake
@@ -0,0 +1,219 @@
+# Copyright (c) 1993-2015 Ken Martin, Will Schroeder, Bill Lorensen
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# 
+#  * Redistributions of source code must retain the above copyright notice,
+#    this list of conditions and the following disclaimer.
+# 
+#  * Redistributions in binary form must reproduce the above copyright notice,
+#    this list of conditions and the following disclaimer in the documentation
+#    and/or other materials provided with the distribution.
+# 
+#  * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
+#    of any contributors may be used to endorse or promote products derived
+#    from this software without specific prior written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#
+# Find the native FFMPEG includes and library
+#
+# This module defines
+# FFMPEG_INCLUDE_DIR, where to find avcodec.h, avformat.h ...
+# FFMPEG_LIBRARIES, the libraries to link against to use FFMPEG.
+# FFMPEG_FOUND, If false, do not try to use FFMPEG.
+
+# also defined, but not for general use are
+# FFMPEG_avformat_LIBRARY and FFMPEG_avcodec_LIBRARY, where to find the FFMPEG library.
+# This is usefull to do it this way so that we can always add more libraries
+# if needed to FFMPEG_LIBRARIES if ffmpeg ever changes...
+
+include(CheckStructHasMember)
+
+# if ffmpeg headers are all in one directory
+FIND_PATH(FFMPEG_INCLUDE_DIR avformat.h
+        PATHS
+        $ENV{FFMPEG_DIR}/include
+        ~/Library/Frameworks
+        /Library/Frameworks
+        /usr/local/include
+        /usr/include
+        /sw/include # Fink
+        /opt/local/include # DarwinPorts
+        /opt/csw/include # Blastwave
+        /opt/include
+        /usr/freeware/include
+        PATH_SUFFIXES ${CMAKE_LIBRARY_ARCHITECTURE} ffmpeg
+        DOC "Location of FFMPEG Headers"
+        )
+
+# if ffmpeg headers are seperated to each of libavformat, libavcodec etc..
+IF (NOT FFMPEG_INCLUDE_DIR)
+    FIND_PATH(FFMPEG_INCLUDE_DIR libavformat/avformat.h
+            PATHS
+            $ENV{FFMPEG_DIR}/include
+            ~/Library/Frameworks
+            /Library/Frameworks
+            /usr/local/include
+            /usr/include
+            /sw/include # Fink
+            /opt/local/include # DarwinPorts
+            /opt/csw/include # Blastwave
+            /opt/include
+            /usr/freeware/include
+            PATH_SUFFIXES ${CMAKE_LIBRARY_ARCHITECTURE} ffmpeg
+            DOC "Location of FFMPEG Headers"
+            )
+
+ENDIF (NOT FFMPEG_INCLUDE_DIR)
+
+# we want the -I include line to use the parent directory of ffmpeg as
+# ffmpeg uses relative includes such as <ffmpeg/avformat.h> or <libavcodec/avformat.h>
+get_filename_component(FFMPEG_INCLUDE_DIR ${FFMPEG_INCLUDE_DIR} ABSOLUTE)
+
+FIND_LIBRARY(FFMPEG_avformat_LIBRARY avformat
+        /usr/local/lib
+        /usr/lib
+        )
+
+FIND_LIBRARY(FFMPEG_avcodec_LIBRARY avcodec
+        /usr/local/lib
+        /usr/lib
+        )
+
+FIND_LIBRARY(FFMPEG_avutil_LIBRARY avutil
+        /usr/local/lib
+        /usr/lib
+        )
+
+FIND_LIBRARY(FFMPEG_vorbis_LIBRARY vorbis
+        /usr/local/lib
+        /usr/lib
+        )
+
+FIND_LIBRARY(FFMPEG_dc1394_LIBRARY dc1394_control
+        /usr/local/lib
+        /usr/lib
+        )
+
+FIND_LIBRARY(FFMPEG_vorbisenc_LIBRARY vorbisenc
+        /usr/local/lib
+        /usr/lib
+        )
+
+FIND_LIBRARY(FFMPEG_theora_LIBRARY theora
+        /usr/local/lib
+        /usr/lib
+        )
+
+FIND_LIBRARY(FFMPEG_dts_LIBRARY dts
+        /usr/local/lib
+        /usr/lib
+        )
+
+FIND_LIBRARY(FFMPEG_gsm_LIBRARY gsm
+        /usr/local/lib
+        /usr/lib
+        )
+
+FIND_LIBRARY(FFMPEG_swscale_LIBRARY swscale
+        /usr/local/lib
+        /usr/lib
+        )
+
+FIND_LIBRARY(FFMPEG_z_LIBRARY z
+        /usr/local/lib
+        /usr/lib
+        )
+
+FIND_LIBRARY(FFMPEG_bz2_LIBRARY bz2
+        /usr/local/lib
+        /usr/lib
+        )
+
+SET(FFMPEG_LIBRARIES)
+IF (FFMPEG_INCLUDE_DIR)
+    IF (FFMPEG_avformat_LIBRARY)
+        IF (FFMPEG_avcodec_LIBRARY)
+            IF (FFMPEG_avutil_LIBRARY)
+                SET(FFMPEG_FOUND TRUE)
+                SET(FFMPEG_INCLUDE_DIRS ${FFMPEG_INCLUDE_DIR})
+                SET(FFMPEG_BASIC_LIBRARIES
+                        ${FFMPEG_avcodec_LIBRARY}
+                        ${FFMPEG_avformat_LIBRARY}
+                        ${FFMPEG_avutil_LIBRARY}
+                        )
+
+                # swscale is always a part of newer ffmpeg distros
+                IF (FFMPEG_swscale_LIBRARY)
+                    LIST(APPEND FFMPEG_BASIC_LIBRARIES ${FFMPEG_swscale_LIBRARY})
+                ENDIF (FFMPEG_swscale_LIBRARY)
+
+                SET(FFMPEG_LIBRARIES ${FFMPEG_BASIC_LIBRARIES})
+
+                IF (FFMPEG_vorbis_LIBRARY)
+                    LIST(APPEND FFMPEG_LIBRARIES ${FFMPEG_vorbis_LIBRARY})
+                ENDIF (FFMPEG_vorbis_LIBRARY)
+
+                IF (FFMPEG_dc1394_LIBRARY)
+                    LIST(APPEND FFMPEG_LIBRARIES ${FFMPEG_dc1394_LIBRARY})
+                ENDIF (FFMPEG_dc1394_LIBRARY)
+
+                IF (FFMPEG_vorbisenc_LIBRARY)
+                    LIST(APPEND FFMPEG_LIBRARIES ${FFMPEG_vorbisenc_LIBRARY})
+                ENDIF (FFMPEG_vorbisenc_LIBRARY)
+
+                IF (FFMPEG_theora_LIBRARY)
+                    LIST(APPEND FFMPEG_LIBRARIES ${FFMPEG_theora_LIBRARY})
+                ENDIF (FFMPEG_theora_LIBRARY)
+
+                IF (FFMPEG_dts_LIBRARY)
+                    LIST(APPEND FFMPEG_LIBRARIES ${FFMPEG_dts_LIBRARY})
+                ENDIF (FFMPEG_dts_LIBRARY)
+
+                IF (FFMPEG_gsm_LIBRARY)
+                    LIST(APPEND FFMPEG_LIBRARIES ${FFMPEG_gsm_LIBRARY})
+                ENDIF (FFMPEG_gsm_LIBRARY)
+
+                IF (FFMPEG_z_LIBRARY)
+                    LIST(APPEND FFMPEG_LIBRARIES ${FFMPEG_z_LIBRARY})
+                ENDIF (FFMPEG_z_LIBRARY)
+
+                IF (FFMPEG_bz2_LIBRARY)
+                    LIST(APPEND FFMPEG_LIBRARIES ${FFMPEG_bz2_LIBRARY})
+                ENDIF (FFMPEG_bz2_LIBRARY)
+
+                SET(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} CACHE INTERNAL "All presently found FFMPEG libraries.")
+
+                CHECK_STRUCT_HAS_MEMBER("struct AVStream" codecpar libavformat/avformat.h HAVE_AVSTREAM_CODECPAR LANGUAGE C)
+
+            ENDIF (FFMPEG_avutil_LIBRARY)
+        ENDIF (FFMPEG_avcodec_LIBRARY)
+    ENDIF (FFMPEG_avformat_LIBRARY)
+ENDIF (FFMPEG_INCLUDE_DIR)
+
+MARK_AS_ADVANCED(
+        FFMPEG_INCLUDE_DIR
+        FFMPEG_avformat_LIBRARY
+        FFMPEG_avcodec_LIBRARY
+        FFMPEG_avutil_LIBRARY
+        FFMPEG_vorbis_LIBRARY
+        FFMPEG_dc1394_LIBRARY
+        FFMPEG_vorbisenc_LIBRARY
+        FFMPEG_theora_LIBRARY
+        FFMPEG_dts_LIBRARY
+        FFMPEG_gsm_LIBRARY
+        FFMPEG_swscale_LIBRARY
+        FFMPEG_z_LIBRARY
+)
diff --git a/cmake/FindINotify.cmake b/cmake/FindINotify.cmake
new file mode 100644
index 0000000..ca9f388
--- /dev/null
+++ b/cmake/FindINotify.cmake
@@ -0,0 +1,23 @@
+# (c) 2014 Copyright ownCloud, Inc.
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING* file.
+
+# This module defines
+#  INOTIFY_INCLUDE_DIR, where to find inotify.h, etc.
+#  INOTIFY_FOUND, If false, do not try to use inotify.
+# also defined, but not for general use are
+#  INOTIFY_LIBRARY, where to find the inotify library.
+
+find_path(INOTIFY_INCLUDE_DIR sys/inotify.h 
+          HINTS /usr/include/${CMAKE_LIBRARY_ARCHITECTURE})
+mark_as_advanced(INOTIFY_INCLUDE_DIR)
+
+# all listed variables are TRUE
+# handle the QUIETLY and REQUIRED arguments and set INOTIFY_FOUND to TRUE if
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(INOTIFY DEFAULT_MSG INOTIFY_INCLUDE_DIR)
+
+IF(INOTIFY_FOUND)
+  SET(INotify_INCLUDE_DIRS ${INOTIFY_INCLUDE_DIR})
+ENDIF(INOTIFY_FOUND)
+
diff --git a/cmake/FindIconv.cmake b/cmake/FindIconv.cmake
new file mode 100644
index 0000000..896bbfd
--- /dev/null
+++ b/cmake/FindIconv.cmake
@@ -0,0 +1,59 @@
+# From: https://github.com/onyx-intl/cmake_modules/blob/master/FindIconv.cmake
+#
+# - Try to find Iconv
+# Once done this will define 
+# 
+#  ICONV_FOUND - system has Iconv 
+#  ICONV_INCLUDE_DIR - the Iconv include directory 
+#  ICONV_LIBRARIES - Link these to use Iconv 
+#  ICONV_SECOND_ARGUMENT_IS_CONST - the second argument for iconv() is const
+# 
+include(CheckCXXSourceCompiles)
+
+IF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
+  # Already in cache, be silent
+  SET(ICONV_FIND_QUIETLY TRUE)
+ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
+
+FIND_PATH(ICONV_INCLUDE_DIR iconv.h) 
+ 
+FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c)
+ 
+IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 
+   SET(ICONV_FOUND TRUE) 
+ENDIF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 
+
+set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
+set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES})
+IF(ICONV_FOUND)
+  check_cxx_source_compiles("
+  #include <iconv.h>
+  int main(){
+    iconv_t conv = 0;
+    const char* in = 0;
+    size_t ilen = 0;
+    char* out = 0;
+    size_t olen = 0;
+    iconv(conv, &in, &ilen, &out, &olen);
+    return 0;
+  }
+" ICONV_SECOND_ARGUMENT_IS_CONST )
+ENDIF(ICONV_FOUND)
+set(CMAKE_REQUIRED_INCLUDES)
+set(CMAKE_REQUIRED_LIBRARIES)
+
+IF(ICONV_FOUND) 
+  IF(NOT ICONV_FIND_QUIETLY) 
+    MESSAGE(STATUS "Found Iconv: ${ICONV_LIBRARIES}") 
+  ENDIF(NOT ICONV_FIND_QUIETLY) 
+ELSE(ICONV_FOUND) 
+  IF(Iconv_FIND_REQUIRED) 
+    MESSAGE(FATAL_ERROR "Could not find Iconv") 
+  ENDIF(Iconv_FIND_REQUIRED) 
+ENDIF(ICONV_FOUND)
+
+MARK_AS_ADVANCED(
+  ICONV_INCLUDE_DIR
+  ICONV_LIBRARIES
+  ICONV_SECOND_ARGUMENT_IS_CONST
+)
diff --git a/cmake/FindLastFMLib.cmake b/cmake/FindLastFMLib.cmake
new file mode 100644
index 0000000..e65016c
--- /dev/null
+++ b/cmake/FindLastFMLib.cmake
@@ -0,0 +1,8 @@
+INCLUDE (FindPackageHandleStandardArgs)
+
+find_package( PkgConfig REQUIRED )
+PKG_SEARCH_MODULE( LASTFMLIB REQUIRED liblastfm liblastfmlib )
+
+find_package_handle_standard_args(LASTFMLIB DEFAULT_MSG LASTFMLIB_FOUND)
+
+MARK_AS_ADVANCED( LASTFMLIB_LIBRARIES LASTFMLIB_INCLUDE_DIRS )
diff --git a/cmake/FindLibMagic.cmake b/cmake/FindLibMagic.cmake
new file mode 100644
index 0000000..8775e41
--- /dev/null
+++ b/cmake/FindLibMagic.cmake
@@ -0,0 +1,11 @@
+INCLUDE (FindPackageHandleStandardArgs)
+
+FIND_PATH(MAGIC_INCLUDE_DIR magic.h)
+FIND_LIBRARY(MAGIC_LIBRARIES NAMES magic)
+
+# handle the QUIETLY and REQUIRED arguments and set MAGIC_FOUND to TRUE
+find_package_handle_standard_args(MAGIC DEFAULT_MSG MAGIC_INCLUDE_DIR)
+
+MARK_AS_ADVANCED(
+    MAGIC_LIBRARIES
+    MAGIC_INCLUDE_DIRS )
\ No newline at end of file
diff --git a/cmake/FindLibUUID.cmake b/cmake/FindLibUUID.cmake
new file mode 100644
index 0000000..e346da2
--- /dev/null
+++ b/cmake/FindLibUUID.cmake
@@ -0,0 +1,51 @@
+# - Try to find LIBUUID 
+# Find LIBUUID headers, libraries and the answer to all questions.
+#
+#  LIBUUID_FOUND               True if libuuid got found
+#  LIBUUID_INCLUDE_DIRS        Location of libuuid headers 
+#  LIBUUID_LIBRARIES           List of libraries to use libuuid 
+#
+# Copyright (c) 2008 Bjoern Ricks <bjoern.ricks at googlemail.com>
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+INCLUDE( FindPkgConfig )
+
+IF ( LibUuid_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "REQUIRED" )
+ELSE( LibUuid_FIND_REQUIRED )
+	SET( _pkgconfig_REQUIRED "" )	
+ENDIF ( LibUuid_FIND_REQUIRED )
+
+IF ( LIBUUID_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBUUID ${_pkgconfig_REQUIRED} uuid>=${LIBUUID_MIN_VERSION} )
+ELSE ( LIBUUID_MIN_VERSION )
+	PKG_SEARCH_MODULE( LIBUUID ${_pkgconfig_REQUIRED} uuid )
+ENDIF ( LIBUUID_MIN_VERSION )
+
+
+IF( NOT LIBUUID_FOUND )
+	FIND_PATH( LIBUUID_INCLUDE_DIRS uuid/uuid.h )
+	FIND_LIBRARY( LIBUUID_LIBRARIES uuid)
+
+	# Report results
+	IF ( LIBUUID_LIBRARIES AND LIBUUID_INCLUDE_DIRS )	
+		SET( LIBUUID_FOUND 1 )
+		IF ( NOT LIBUUID_FIND_QUIETLY )
+			MESSAGE( STATUS "Found libuuid: ${LIBUUID_LIBRARIES}" )
+		ENDIF ( NOT LIBUUID_FIND_QUIETLY )
+	ELSE ()
+		IF ( LIBUUID_FIND_REQUIRED )
+			MESSAGE( SEND_ERROR "Could NOT find libuuid" )
+		ELSE ( LIBUUID_FIND_REQUIRED )
+			IF ( NOT LIBUUID_FIND_QUIETLY )
+				MESSAGE( STATUS "Could NOT find libuuid" )	
+			ENDIF ( NOT LIBUUID_FIND_QUIETLY )
+		ENDIF ( LIBUUID_FIND_REQUIRED )
+	ENDIF ()
+ENDIF()
+
+MARK_AS_ADVANCED( LIBUUID_LIBRARIES LIBUUID_INCLUDE_DIRS )
\ No newline at end of file
diff --git a/cmake/FindLibUpnp.cmake b/cmake/FindLibUpnp.cmake
new file mode 100644
index 0000000..a7a10ed
--- /dev/null
+++ b/cmake/FindLibUpnp.cmake
@@ -0,0 +1,51 @@
+# - Try to find LibUPnP (pupnp) 1.8
+# Once done this will define
+#  UPNP_FOUND - System has LibUPnP
+#  UPNP_INCLUDE_DIRS - The LibUPnP include directories
+#  UPNP_LIBRARIES - The libraries needed to use LibUPnP
+#  UPNP_VERSION_STRING - The version of LinUPnP found
+#  UPNP_HAS_IPV6 - If LinUPnP was built with IPv6 support
+#  UPNP_HAS_REUSEADDR - If LinUPnP was built with SO_REUSEADDR support
+
+find_package(PkgConfig QUIET)
+pkg_check_modules (PC_UPNP QUIET libupnp-1.8)
+
+find_path(UPNP_INCLUDE_DIR upnp-1.8/upnp.h
+    HINTS ${PC_UPNP_INCLUDEDIR} ${PC_UPNP_INCLUDE_DIRS}
+    PATH_SUFFIXES upnp)
+find_library(UPNP_UPNP_LIBRARY
+    NAMES libupnp-1.8 upnp-1.8 upnp4
+    HINTS ${PC_UPNP_LIBDIR} ${PC_UPNP_LIBRARY_DIRS})
+find_library(UPNP_IXML_LIBRARY
+    NAMES libixml-1.8 ixml-1.8 ixml4
+    HINTS ${PC_UPNP_LIBDIR} ${PC_UPNP_LIBRARY_DIRS})
+
+if(EXISTS "${UPNP_INCLUDE_DIR}/upnp-1.8/upnpconfig.h")
+    file (STRINGS ${UPNP_INCLUDE_DIR}/upnp-1.8/upnpconfig.h _UPNP_DEFS REGEX "^[ \t]*#define[ \t]+UPNP_VERSION_(MAJOR|MINOR|PATCH)")
+    string (REGEX REPLACE ".*UPNP_VERSION_MAJOR ([0-9]+).*" "\\1" UPNP_MAJOR_VERSION "${_UPNP_DEFS}")
+    string (REGEX REPLACE ".*UPNP_VERSION_MINOR ([0-9]+).*" "\\1" UPNP_MINOR_VERSION "${_UPNP_DEFS}")
+    string (REGEX REPLACE ".*UPNP_VERSION_PATCH ([0-9]+).*" "\\1" UPNP_PATCH_VERSION "${_UPNP_DEFS}")
+    set (UPNP_VERSION_STRING "${UPNP_MAJOR_VERSION}.${UPNP_MINOR_VERSION}.${UPNP_PATCH_VERSION}")
+
+    # Check for IPv6
+    file (STRINGS ${UPNP_INCLUDE_DIR}/upnp-1.8/upnpconfig.h UPNP_HAS_IPV6 REGEX "^[ \t]*#define[ \t]+UPNP_ENABLE_IPV6[ \t]+(1)$")
+    # Check for SO_REUSEADDR
+    file (STRINGS ${UPNP_INCLUDE_DIR}/upnp-1.8/upnpconfig.h UPNP_HAS_REUSEADDR REGEX "^[ \t]*#define[ \t]+UPNP_MINISERVER_REUSEADDR[ \t]+(1)$")
+
+endif()
+
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(UPnP
+    REQUIRED_VARS UPNP_UPNP_LIBRARY UPNP_INCLUDE_DIR
+    VERSION_VAR UPNP_VERSION_STRING)
+
+if (UPNP_FOUND)
+    set (UPNP_LIBRARIES ${UPNP_UPNP_LIBRARY} ${UPNP_IXML_LIBRARY})
+    set (UPNP_INCLUDE_DIRS ${UPNP_INCLUDE_DIR} )
+endif ()
+
+MARK_AS_ADVANCED(
+    UPNP_INCLUDE_DIR
+    UPNP_IXML_LIBRARY
+    UPNP_UPNP_LIBRARY
+)
diff --git a/cmake/FindMySQL.cmake b/cmake/FindMySQL.cmake
new file mode 100644
index 0000000..69430e0
--- /dev/null
+++ b/cmake/FindMySQL.cmake
@@ -0,0 +1,113 @@
+#--------------------------------------------------------
+# Copyright (C) 1995-2007 MySQL AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# There are special exceptions to the terms and conditions of the GPL
+# as it is applied to this software. View the full text of the exception
+# in file LICENSE.exceptions in the top-level directory of this software
+# distribution.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+#
+# The MySQL Connector/ODBC is licensed under the terms of the
+# GPL, like most MySQL Connectors. There are special exceptions
+# to the terms and conditions of the GPL as it is applied to
+# this software, see the FLOSS License Exception available on
+# mysql.com.
+
+##########################################################################
+
+
+#-------------- FIND MYSQL_INCLUDE_DIR ------------------
+FIND_PATH(MYSQL_INCLUDE_DIR mysql.h
+  /usr/include/mysql
+  /usr/local/include/mysql
+  /opt/mysql/mysql/include
+  /opt/mysql/mysql/include/mysql
+  /opt/mysql/include
+  /opt/local/include/mysql5
+  /usr/local/mysql/include
+  /usr/local/mysql/include/mysql
+  $ENV{ProgramFiles}/MySQL/*/include
+  $ENV{SystemDrive}/MySQL/*/include)
+
+#----------------- FIND MYSQL_LIB_DIR -------------------
+IF (WIN32)
+  # Set lib path suffixes
+  # dist = for mysql binary distributions
+  # build = for custom built tree
+  IF (CMAKE_BUILD_TYPE STREQUAL Debug)
+    SET(libsuffixDist debug)
+    SET(libsuffixBuild Debug)
+  ELSE (CMAKE_BUILD_TYPE STREQUAL Debug)
+    SET(libsuffixDist opt)
+    SET(libsuffixBuild Release)
+    ADD_DEFINITIONS(-DDBUG_OFF)
+  ENDIF (CMAKE_BUILD_TYPE STREQUAL Debug)
+
+  FIND_LIBRARY(MYSQL_LIB NAMES mysqlclient
+    PATHS
+    $ENV{MYSQL_DIR}/lib/${libsuffixDist}
+    $ENV{MYSQL_DIR}/libmysql
+    $ENV{MYSQL_DIR}/libmysql/${libsuffixBuild}
+    $ENV{MYSQL_DIR}/client/${libsuffixBuild}
+    $ENV{MYSQL_DIR}/libmysql/${libsuffixBuild}
+    $ENV{ProgramFiles}/MySQL/*/lib/${libsuffixDist}
+    $ENV{SystemDrive}/MySQL/*/lib/${libsuffixDist})
+ELSE (WIN32)
+  FIND_LIBRARY(MYSQL_LIB NAMES mysqlclient_r mysqlclient
+    PATHS
+    /usr/lib/mysql
+    /usr/local/lib/mysql
+    /usr/local/mysql/lib
+    /usr/local/mysql/lib/mysql
+    /opt/local/mysql5/lib
+    /opt/local/lib/mysql5/mysql
+    /opt/mysql/mysql/lib/mysql
+    /opt/mysql/lib/mysql)
+ENDIF (WIN32)
+
+IF(MYSQL_LIB)
+  GET_FILENAME_COMPONENT(MYSQL_LIB_DIR ${MYSQL_LIB} PATH)
+ENDIF(MYSQL_LIB)
+
+IF (MYSQL_INCLUDE_DIR AND MYSQL_LIB_DIR)
+  SET(MYSQL_FOUND TRUE)
+
+  INCLUDE_DIRECTORIES(${MYSQL_INCLUDE_DIR})
+  LINK_DIRECTORIES(${MYSQL_LIB_DIR})
+
+  FIND_LIBRARY(MYSQL_ZLIB zlib PATHS ${MYSQL_LIB_DIR})
+  FIND_LIBRARY(MYSQL_TAOCRYPT taocrypt PATHS ${MYSQL_LIB_DIR})
+  IF (MYSQL_LIB)
+    SET(MYSQL_CLIENT_LIBS ${MYSQL_LIB})
+  ELSE()
+    SET(MYSQL_CLIENT_LIBS mysqlclient_r)
+  ENDIF()
+  IF (MYSQL_ZLIB)
+    SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} zlib)
+  ENDIF (MYSQL_ZLIB)
+  IF (MYSQL_TAOCRYPT)
+    SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} taocrypt)
+  ENDIF (MYSQL_TAOCRYPT)
+  # Added needed mysqlclient dependencies on Windows
+  IF (WIN32)
+    SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} ws2_32)
+  ENDIF (WIN32)
+
+  MESSAGE(STATUS "MySQL Include dir: ${MYSQL_INCLUDE_DIR}  library dir: ${MYSQL_LIB_DIR}")
+  MESSAGE(STATUS "MySQL client libraries: ${MYSQL_CLIENT_LIBS}")
+ELSEIF (MySQL_FIND_REQUIRED)
+  MESSAGE(FATAL_ERROR "Cannot find MySQL. Include dir: ${MYSQL_INCLUDE_DIR}  library dir: ${MYSQL_LIB_DIR}")
+ENDIF (MYSQL_INCLUDE_DIR AND MYSQL_LIB_DIR)
diff --git a/cmake/FindSQLite3.cmake b/cmake/FindSQLite3.cmake
new file mode 100644
index 0000000..dae70b4
--- /dev/null
+++ b/cmake/FindSQLite3.cmake
@@ -0,0 +1,85 @@
+# - Try to find Sqlite3
+# Once done this will define
+#
+#  SQLITE3_FOUND - system has Sqlite3
+#  SQLITE3_INCLUDE_DIRS - the Sqlite3 include directory
+#  SQLITE3_LIBRARIES - Link these to use Sqlite3
+#  SQLITE3_DEFINITIONS - Compiler switches required for using Sqlite3
+#
+#  Copyright (c) 2008 Andreas Schneider <mail at cynapses.org>
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+if (SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS)
+  # in cache already
+  set(SQLITE3_FOUND TRUE)
+else (SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS)
+  # use pkg-config to get the directories and then use these values
+  # in the FIND_PATH() and FIND_LIBRARY() calls
+  if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
+    include(UsePkgConfig)
+    pkgconfig(sqlite3 _SQLITE3_INCLUDEDIR _SQLITE3_LIBDIR _SQLITE3_LDFLAGS _SQLITE3_CFLAGS)
+  else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
+    find_package(PkgConfig)
+    if (PKG_CONFIG_FOUND)
+      pkg_check_modules(_SQLITE3 sqlite3)
+    endif (PKG_CONFIG_FOUND)
+  endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
+  find_path(SQLITE3_INCLUDE_DIR
+    NAMES
+      sqlite3.h
+    PATHS
+      ${_SQLITE3_INCLUDEDIR}
+      /usr/include
+      /usr/local/include
+      /opt/local/include
+      /sw/include
+  )
+
+  find_library(SQLITE3_LIBRARY
+    NAMES
+      sqlite3
+    PATHS
+      ${_SQLITE3_LIBDIR}
+      /usr/lib
+      /usr/local/lib
+      /opt/local/lib
+      /sw/lib
+  )
+
+  if (SQLITE3_LIBRARY)
+    set(SQLITE3_FOUND TRUE)
+  endif (SQLITE3_LIBRARY)
+
+  set(SQLITE3_INCLUDE_DIRS
+    ${SQLITE3_INCLUDE_DIR}
+  )
+
+  if (SQLITE3_FOUND)
+    set(SQLITE3_LIBRARIES
+      ${SQLITE3_LIBRARIES}
+      ${SQLITE3_LIBRARY}
+    )
+  endif (SQLITE3_FOUND)
+
+  if (SQLITE3_INCLUDE_DIRS AND SQLITE3_LIBRARIES)
+     set(SQLITE3_FOUND TRUE)
+  endif (SQLITE3_INCLUDE_DIRS AND SQLITE3_LIBRARIES)
+
+  if (SQLITE3_FOUND)
+    if (NOT Sqlite3_FIND_QUIETLY)
+      message(STATUS "Found Sqlite3: ${SQLITE3_LIBRARIES}")
+    endif (NOT Sqlite3_FIND_QUIETLY)
+  else (SQLITE3_FOUND)
+    if (Sqlite3_FIND_REQUIRED)
+      message(FATAL_ERROR "Could not find Sqlite3")
+    endif (Sqlite3_FIND_REQUIRED)
+  endif (SQLITE3_FOUND)
+
+  # show the SQLITE3_INCLUDE_DIRS and SQLITE3_LIBRARIES variables only in the advanced view
+  mark_as_advanced(SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES)
+
+endif (SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS)
diff --git a/cmake/FindTaglib.cmake b/cmake/FindTaglib.cmake
new file mode 100644
index 0000000..827c40f
--- /dev/null
+++ b/cmake/FindTaglib.cmake
@@ -0,0 +1,89 @@
+# - Try to find the Taglib library
+# Once done this will define
+#
+#  TAGLIB_FOUND - system has the taglib library
+#  TAGLIB_CFLAGS - the taglib cflags
+#  TAGLIB_LIBRARIES - The libraries needed to use taglib
+
+# Copyright (c) 2006, Laurent Montel, <montel at kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+IF(TAGLIB_FOUND)
+	MESSAGE(STATUS "Using manually specified taglib locations")
+ELSE()
+
+	if(NOT TAGLIB_MIN_VERSION)
+	  set(TAGLIB_MIN_VERSION "1.11")
+	endif(NOT TAGLIB_MIN_VERSION)
+
+	if(NOT WIN32)
+		find_program(TAGLIBCONFIG_EXECUTABLE NAMES taglib-config PATHS
+		   ${BIN_INSTALL_DIR}
+		)
+	endif(NOT WIN32)
+
+	#reset vars
+	set(TAGLIB_LIBRARIES)
+	set(TAGLIB_CFLAGS)
+
+#	MESSAGE( STATUS "PATHS: ${PATHS}")
+	# if taglib-config has been found
+	if(TAGLIBCONFIG_EXECUTABLE)
+
+	  exec_program(${TAGLIBCONFIG_EXECUTABLE} ARGS --version RETURN_VALUE _return_VALUE OUTPUT_VARIABLE TAGLIB_VERSION)
+
+	  if(TAGLIB_VERSION VERSION_LESS "${TAGLIB_MIN_VERSION}")
+		 message(STATUS "TagLib version not found: version searched: ${TAGLIB_MIN_VERSION}, found: ${TAGLIB_VERSION}")
+		 set(TAGLIB_FOUND FALSE)
+	  else(TAGLIB_VERSION VERSION_LESS "${TAGLIB_MIN_VERSION}")
+
+		 exec_program(${TAGLIBCONFIG_EXECUTABLE} ARGS --libs RETURN_VALUE _return_VALUE OUTPUT_VARIABLE TAGLIB_LIBRARIES)
+
+		 exec_program(${TAGLIBCONFIG_EXECUTABLE} ARGS --cflags RETURN_VALUE _return_VALUE OUTPUT_VARIABLE TAGLIB_CFLAGS)
+
+		 if(TAGLIB_LIBRARIES AND TAGLIB_CFLAGS)
+			set(TAGLIB_FOUND TRUE)
+#			message(STATUS "Found taglib: ${TAGLIB_LIBRARIES}")
+		 endif(TAGLIB_LIBRARIES AND TAGLIB_CFLAGS)
+		 string(REGEX REPLACE " *-I" ";" TAGLIB_INCLUDES "${TAGLIB_CFLAGS}")
+	  endif(TAGLIB_VERSION VERSION_LESS "${TAGLIB_MIN_VERSION}")
+	  mark_as_advanced(TAGLIB_CFLAGS TAGLIB_LIBRARIES TAGLIB_INCLUDES)
+
+	else(TAGLIBCONFIG_EXECUTABLE)
+
+	  include(FindLibraryWithDebug)
+	  include(FindPackageHandleStandardArgs)
+
+	  find_path(TAGLIB_INCLUDES
+		NAMES
+		tag.h
+		PATH_SUFFIXES taglib
+		PATHS
+		${KDE4_INCLUDE_DIR}
+		${INCLUDE_INSTALL_DIR}
+	  )
+
+	  find_library_with_debug(TAGLIB_LIBRARIES
+		WIN32_DEBUG_POSTFIX d
+		NAMES tag
+		PATHS
+		${KDE4_LIB_DIR}
+		${LIB_INSTALL_DIR}
+	  )
+	  
+	  find_package_handle_standard_args(Taglib DEFAULT_MSG 
+										TAGLIB_INCLUDES TAGLIB_LIBRARIES)
+	endif(TAGLIBCONFIG_EXECUTABLE)
+ENDIF()
+
+if(TAGLIB_FOUND)
+  if(NOT Taglib_FIND_QUIETLY AND TAGLIBCONFIG_EXECUTABLE)
+    message(STATUS "Found TagLib: ${TAGLIB_LIBRARIES}")
+  endif(NOT Taglib_FIND_QUIETLY AND TAGLIBCONFIG_EXECUTABLE)
+else(TAGLIB_FOUND)
+  if(Taglib_FIND_REQUIRED)
+    message(FATAL_ERROR "Could not find Taglib")
+  endif(Taglib_FIND_REQUIRED)
+endif(TAGLIB_FOUND)
diff --git a/config/Makefile.am b/config/Makefile.am
deleted file mode 100644
index fe226d4..0000000
--- a/config/Makefile.am
+++ /dev/null
@@ -1,12 +0,0 @@
-_DIST_FILES_CONFIG = \
-    mappings.xml \
-    sqlite3.sql \
-    mysql.sql
-
-EXTRA_DIST=mediatomb-conf-fedora \
-		   mediatomb-conf-optware \
-		   mediatomb-default-optware \
-    	config.xsd
-
-dist_pkgdata_DATA = $(_DIST_FILES_CONFIG)
-
diff --git a/config/config.xsd b/config/config2.xsd
similarity index 86%
copy from config/config.xsd
copy to config/config2.xsd
index 3d584f3..4b70e5a 100644
--- a/config/config.xsd
+++ b/config/config2.xsd
@@ -3,34 +3,34 @@
         "-//W3C//DTD XMLSCHEMA 200102//EN"
         "http://www.w3.org/2001/XMLSchema.dtd">  -->
 <!--*MT*
-    
+
     MediaTomb - http://www.mediatomb.cc/
-    
+
     config.xsd - this file is part of MediaTomb.
-    
+
     Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
                        Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
+
     Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
                             Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
                             Leonhard Wimmer <leo at mediatomb.cc>
-    
+
     MediaTomb is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2
     as published by the Free Software Foundation.
-    
+
     MediaTomb is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-    
+
     You should have received a copy of the GNU General Public License
     version 2 along with MediaTomb; if not, write to the Free Software
     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
+
     $Id$
 -->
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://mediatomb.cc/config/1" xmlns="http://mediatomb.cc/config/1">
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://mediatomb.cc/config/2" xmlns="http://mediatomb.cc/config/2">
 
     <xs:simpleType name="boolean">
         <xs:restriction base="xs:string">
@@ -46,7 +46,7 @@
                 <xs:element ref="import" minOccurs="0"/>
                 <xs:element ref="transcoding" minOccurs="0"/>
             </xs:all>
-            <xs:attribute name="version" type="xs:positiveInteger" fixed="1"/>
+            <xs:attribute name="version" type="xs:positiveInteger" fixed="2"/>
         </xs:complexType>
     </xs:element>
 
@@ -56,7 +56,7 @@
                 <xs:element ref="ui" minOccurs="0"/>
                 <xs:element ref="port" minOccurs="0"/>
                 <xs:element ref="name" minOccurs="0"/>
-                
+
                 <!-- required, but autogenerated by MediaTomb at startup -->
                 <xs:element ref="udn" minOccurs="0"/>
 
@@ -78,6 +78,7 @@
                 <xs:element ref="modelDescription" minOccurs="0"/>
                 <xs:element ref="serialNumber" minOccurs="0"/>
                 <xs:element ref="protocolInfo" minOccurs="0"/>
+                <xs:element ref="extended-runtime-options" minOccurs="0"/>
                 <xs:element ref="pc-directory" minOccurs="0"/>
                 <xs:element ref="tmpdir" minOccurs="0"/>
                 <xs:element ref="retries-on-timeout" minOccurs="0"/>
@@ -145,6 +146,60 @@
         </xs:complexType>
     </xs:element>
 
+    <xs:element name="extended-runtime-options">
+        <xs:complexType>
+            <xs:all>
+                <xs:element ref="mark-played-items" minOccurs="0"/>
+            </xs:all>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="mark-played-items">
+        <xs:complexType>
+            <xs:all>
+                <xs:element ref="string" minOccurs="0"/>
+                <xs:element ref="mark" minOccurs="0"/>
+            </xs:all>
+            <xs:attribute name="enabled" type="boolean" default="no"/>
+            <xs:attribute name="suppress-cds-updates" type="boolean" default="yes"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="string">
+        <xs:complexType>
+            <xs:simpleContent>
+                <xs:extension base="xs:string">
+                    <xs:attribute name="mode" default="prepend">
+                        <xs:simpleType>
+                            <xs:restriction base="xs:string">
+                                <xs:enumeration value="append"/>
+                                <xs:enumeration value="prepend"/>
+                            </xs:restriction>
+                        </xs:simpleType>
+                    </xs:attribute>
+                </xs:extension>
+            </xs:simpleContent>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="mark">
+        <xs:complexType>
+            <xs:all>
+                <xs:element ref="content" minOccurs="1"/>
+            </xs:all>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="content">
+        <xs:simpleType>
+            <xs:restriction base="xs:string">
+                <xs:enumeration value="audio"/>
+                <xs:enumeration value="image"/>
+                <xs:enumeration value="video"/>
+            </xs:restriction>
+        </xs:simpleType>
+    </xs:element>
+
     <xs:element name="add">
         <xs:complexType>
             <xs:attribute name="header" type="xs:string" use="required"/>
@@ -176,6 +231,7 @@
             <xs:attribute name="poll-interval" type="xs:positiveInteger" default="2"/>
             <xs:attribute name="enabled" type="boolean" default="yes"/>
             <xs:attribute name="poll-when-idle" type="boolean" default="no"/>
+            <xs:attribute name="show-tooltips" type="boolean" default="yes"/>
         </xs:complexType>
     </xs:element>
 
@@ -206,7 +262,7 @@
     </xs:element>
 
     <xs:element name="option" type="xs:positiveInteger"/>
-    
+
     <!--  Storage -->
 
     <xs:element name="storage">
@@ -266,6 +322,7 @@
                 <xs:element ref="username" minOccurs="0"/>
                 <xs:element ref="password" minOccurs="0"/>
                 <xs:element ref="database" minOccurs="0"/>
+                <xs:element ref="socket" minOccurs="0"/>
             </xs:all>
             <xs:attribute name="enabled" type="boolean" default="yes"/>
         </xs:complexType>
@@ -275,7 +332,8 @@
     <xs:element name="username" type="xs:string" default="mediatomb"/>
     <xs:element name="password" type="xs:string"/>
     <xs:element name="database" type="xs:string" default="localhost"/>
-    
+    <xs:element name="socket" type="xs:string"/>
+
     <!-- Import -->
 
     <xs:element name="import">
@@ -356,7 +414,7 @@
     <xs:element name="directory">
         <xs:complexType>
             <xs:attribute name="location" type="xs:string" use="required"/>
-            
+
             <!-- required only for "timed" mode -->
             <xs:attribute name="interval" type="xs:string"/>
 
@@ -457,7 +515,7 @@
             </xs:sequence>
         </xs:complexType>
     </xs:element>
-    
+
     <xs:element name="id3">
         <xs:complexType>
             <xs:sequence>
@@ -568,9 +626,9 @@
     </xs:element>
 
     <xs:element name="resolution" type="xs:string"/>
-    
+
     <xs:element name="thumbnail" type="boolean"/>
-    
+
     <!-- online-content -->
 
     <xs:element name="online-content">
@@ -586,80 +644,69 @@
     <xs:element name="YouTube">
         <xs:complexType>
             <xs:choice minOccurs="0" maxOccurs="unbounded">
+                <xs:element ref="standardfeed"/>
                 <xs:element ref="favorites"/>
-                <xs:element ref="featured"/>
-                <xs:element ref="tag"/>
-                <xs:element ref="user"/>
-                <xs:element ref="playlist"/>
-                <xs:element ref="popular"/>
-                <xs:element ref="category-and-tag"/>
+                <xs:element ref="subscriptions"/>
+                <xs:element ref="playlists"/>
+                <xs:element ref="uploads"/>
             </xs:choice>
             <xs:attribute name="enabled" type="boolean" default="no"/>
             <xs:attribute name="refresh" type="xs:nonNegativeInteger" default="0"/>
             <xs:attribute name="purge-after" type="xs:nonNegativeInteger" default="0"/>
             <xs:attribute name="update-at-start" type="boolean" default="no"/>
-            <xs:attribute name="dev-id" type="xs:string" use="required"/>
-        </xs:complexType>
-    </xs:element>
-
-    <xs:element name="favorites">
-        <xs:complexType>
-            <xs:attribute name="user" type="xs:string" use="required"/>
+            <xs:attribute name="format" default="mp4">
+                <xs:simpleType>
+                    <xs:restriction base="xs:string">
+                        <xs:enumeration value="flv"/>
+                        <xs:enumeration value="mp4"/>
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
+            <xs:attribute name="hd" type="boolean" default="no"/>
+            <xs:attribute name="racy-content" default="exclude">
+                <xs:simpleType>
+                    <xs:restriction base="xs:string">
+                        <xs:enumeration value="exclude"/>
+                        <xs:enumeration value="include"/>
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
 
-    <xs:element name="featured"/>
-
-    <xs:element name="tag">
+    <xs:element name="standardfeed">
         <xs:complexType>
-            <xs:attribute name="tag" type="xs:string" use="required"/>
-            <xs:attribute name="start-page" type="xs:nonNegativeInteger" use="required"/>
-            <!-- to be done better; can be a number or "all" -->
-            <xs:attribute name="amount" type="xs:string" use="required"/>
+            <xs:attribute name="feed" type="xs:string" use="required"/>
+            <xs:attribute name="region-id" type="xs:string"/>
+            <xs:attribute name="time-range" type="xs:string"/>
+            <xs:attribute name="start-index" type="xs:nonNegativeInteger"/>
+            <xs:attribute name="amount" type="xs:string"/>
         </xs:complexType>
     </xs:element>
 
-    <xs:element name="user">
+    <xs:element name="favorites">
         <xs:complexType>
             <xs:attribute name="user" type="xs:string" use="required"/>
-            <xs:attribute name="start-page" type="xs:nonNegativeInteger" use="required"/>
-            <!-- to be done better; can be a number or "all" -->
-            <xs:attribute name="amount" type="xs:string" use="required"/>
         </xs:complexType>
     </xs:element>
 
-    <xs:element name="playlist">
+    <xs:element name="subscriptions">
         <xs:complexType>
-            <xs:attribute name="id" type="xs:string" use="required"/>
-            <xs:attribute name="start-page" type="xs:nonNegativeInteger" use="required"/>
-            <!-- to be done better; can be a number or "all" -->
-            <xs:attribute name="amount" type="xs:string" use="required"/>
-            <xs:attribute name="name" type="xs:string" use="required"/>
+            <xs:attribute name="user" type="xs:string" use="required"/>
         </xs:complexType>
     </xs:element>
 
-    <xs:element name="popular">
+    <xs:element name="playlists">
         <xs:complexType>
-            <xs:attribute name="time-range" use="required">
-                <xs:simpleType>
-                    <xs:restriction base="xs:string">
-                        <xs:enumeration value="all"/>
-                        <xs:enumeration value="day"/>
-                        <xs:enumeration value="week"/>
-                        <xs:enumeration value="month"/>
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
+            <xs:attribute name="user" type="xs:string" use="required"/>
         </xs:complexType>
     </xs:element>
 
-    <xs:element name="category-and-tag">
+    <xs:element name="uploads">
         <xs:complexType>
-            <xs:attribute name="category" type="xs:string" use="required"/>
-            <xs:attribute name="tag" type="xs:string" use="required"/>
-            <xs:attribute name="start-page" type="xs:nonNegativeInteger" use="required"/>
-            <!-- to be done better; can be a number or "all" -->
-            <xs:attribute name="amount" type="xs:string" use="required"/>
+            <xs:attribute name="user" type="xs:string" use="required"/>
+            <xs:attribute name="start-index" type="xs:nonNegativeInteger"/>
+            <xs:attribute name="amount" type="xs:string"/>
         </xs:complexType>
     </xs:element>
 
diff --git a/config/mediatomb-conf-fedora b/config/mediatomb-conf-fedora
index 1d1cc57..fb7260f 100644
--- a/config/mediatomb-conf-fedora
+++ b/config/mediatomb-conf-fedora
@@ -1,4 +1,4 @@
-## This is a sambel configuration file for the MediaTomb daemon script
+## This is a sample configuration file for the MediaTomb daemon script
 ## used on Fedora Core
 
 ## By default the configuration will be created in /etc/mediatomb
diff --git a/config/mediatomb-conf-optware b/config/mediatomb-conf-optware
index 08c2575..ee36dc7 100644
--- a/config/mediatomb-conf-optware
+++ b/config/mediatomb-conf-optware
@@ -1,4 +1,4 @@
-## This is a sambel configuration file for the MediaTomb daemon script
+## This is a sample configuration file for the MediaTomb daemon script
 ## used on Optware
 
 ## By default the configuration will be created in /etc/mediatomb
diff --git a/configure.ac b/configure.ac
deleted file mode 100644
index 2b50ce8..0000000
--- a/configure.ac
+++ /dev/null
@@ -1,1733 +0,0 @@
-#*MT*
-#    
-#    MediaTomb - http://www.mediatomb.cc/
-#    
-#    configure.ac - this file is part of MediaTomb.
-#    
-#    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-#                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-#    
-#    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-#                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-#                            Leonhard Wimmer <leo at mediatomb.cc>
-#    
-#    MediaTomb is free software; you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License version 2
-#    as published by the Free Software Foundation.
-#    
-#    MediaTomb is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU General Public License for more details.
-#    
-#    You should have received a copy of the GNU General Public License
-#    version 2 along with MediaTomb; if not, write to the Free Software
-#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-#    
-#    $Id$
-#
-#*MT*
-
-AC_PREREQ(2.65)
-AC_INIT([MediaTomb], [0.12.2], [jin at mediatomb.cc])
-AC_CONFIG_HEADERS([autoconfig.h tombupnp/upnp/inc/upnpconfig.h])
-AC_CONFIG_AUX_DIR(configure_aux)
-AC_CONFIG_SRCDIR([src/common.h])
-AM_INIT_AUTOMAKE([1.10 -Wall])
-m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
-
-if test "x${prefix}" = "xNONE"; then
-    prefix="${ac_default_prefix}"
-fi
-
-SEARCH_DIR="/usr/local"
-   
-DARWIN_OS=0
-CYGWIN_OS=0
-FREEBSD_OS=0
-OPENBSD_OS=0
-
-LIBS_SAVE="$LIBS"
-
-AC_CANONICAL_HOST
-
-case $host in
-    *-*-darwin*)
-        DARWIN_OS=1
-        SEARCH_DIR="/opt/local"
-        ;;
-    *-*-solaris*)
-        AC_DEFINE([SOLARIS], [1], [we are on solaris])
-        ;;
-    *-*-cygwin*)
-        CYGWIN_OS=1
-        ;;
-    *-*-freebsd*)
-        FREEBSD_OS=1
-        ;;
-    *-*-openbsd*)
-        OPENBSD_OS=1
-        ;;
-esac
-
-MT_SET_SEARCHPATH
-
-SEARCH_DIR_HEADERS="$SEARCH_DIR/include"
-SEARCH_DIR_LIBS="$SEARCH_DIR/lib"
-SEARCH_DIR_PROGS="$SEARCH_DIR/bin"
-
-PKG_PROG_PKG_CONFIG
-
-AC_ARG_WITH(js-pkgconfig,
-    AC_HELP_STRING([--with-js-pkgconfig=DIR], [search for libjs.pc or mozjs185.c in DIR]),
-    [
-        if test "x$withval" != "x"; then
-            AC_MSG_NOTICE([Will also search for packages in $withval])
-            export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$withval
-        fi
-    ])
-
-AC_ARG_WITH(iconv-h,
-        AC_HELP_STRING([--with-iconv-h=DIR], [search for iconv headers in DIR]),
-        [
-            ICONV_SEARCH_HEADERS="$withval"
-            AC_MSG_NOTICE([Will search for iconv headers in $withval])
-        ]
-)
-
-AC_ARG_WITH(iconv-libs,
-        AC_HELP_STRING([--with-iconv-libs=DIR], [search for iconv libraries in DIR]),
-        [
-            ICONV_SEARCH_LIBS="$withval"
-            AC_MSG_NOTICE([Will search for iconv libraries in $withval])
-        ]
-)
-
-MT_OPTION([static], [enable],
-          [build a static version of MediaTomb],
-          [
-            CFLAGS="$CFLAGS -static"
-            CXXFLAGS="$CXXFLAGS -static"
-            AC_MSG_NOTICE([Building a static executable.])
-          ],
-          [])
-
-MT_OPTION([db-autocreate], [disable],
-          [automatic creation of the database],[],[])
-
-MT_OPTION([debug-malloc0], [enable],
-          [only for debugging purposes: abort when we try to call malloc or realloc with a value of zero],
-          [
-            AC_DEFINE([DEBUG_MALLOC_0], [1], 
-                      [debug: abort on malloc/realloc of zero bytes])
-          ],
-          [])
-
-MT_OPTION([pthread-lib], [enable],
-          [if this option is set we will try to link with -lpthread, else the flag for pthread will be autodetected], [], [])
-
-MT_OPTION([iconv-lib], [enable],
-          [if this option is set we will try to link with -liconv, else we will first try to use iconv built into glibc and only then search for libiconv],
-          [],[])
-
-
-ATOMIC_X86_SMP=0
-ATOMIC_X86_SMP_REQ=0
-X86=0
-case $host_cpu in
-    *86)
-        ATOMIC_X86_SMP=1
-        X86=1
-    ;;
-    *86*64)
-        ATOMIC_X86_SMP=1
-        X86=1
-    ;;
-esac
-
-ATOMIC_X86=0
-
-MT_OPTION([atomic-x86-single], [enable], 
-          [use x86 singleprocessor code for atomic arithmetic operations, this will increase performance but you must not use the compiled binary on an SMP system. Doing so might result in crashes and unexpected behaviour],
-          [
-              if test "$X86" -eq 1; then
-                    ATOMIC_X86=1
-                    ATOMIC_X86_SMP=0
-              else
-                    AC_MSG_ERROR([Tried to activate x86 specific option for a non x86 host!])
-              fi
-          ],
-          [])
-
-AC_ARG_ENABLE([atomic-pthread],
-              [
-AC_HELP_STRING([--enable-atomic-pthread],
-[use pthreads for atomic arithmetic operations, this will deliver the worst performance but is the only portable option (default: automatic, depending on architecture])
-            ],
-            [
-                if test "x$enableval" = xyes; then
-                    if test "$ATOMIC_X86" -eq 1; then
-                        AC_MSG_ERROR([You can not use atomic-x86-single and atomic-pthread code at the same time!])
-                    else
-                        ATOMIC_X86=0 
-                        ATOMIC_X86_SMP=0 
-                    fi
-                fi
-            ]
-)
-
-MT_OPTION([atomic], [disable],
-          [NEVER disable this! This is only for devel/debugging - disables all atomic arithmetics code],
-          [],
-          [
-              ATOMIC_X86=0
-              ATOMIC_X86_SMP=0
-              AC_MSG_WARN(You disabled the use of atomic arithmetics! You have been warned!)
-               AC_DEFINE([ATOMIC_TORTURE], [1], [NEVER use this! This is only for devel/debugging - disables all atomic arithmetics code.])
-          ])
-
-if ((test $ATOMIC_X86_SMP -eq 1) && (test $ATOMIC_X86 -eq 1)); then
-    AC_MSG_ERROR([Cannot use atomic-x86-smp and atomic-x86 options at the same time!])
-fi
-
-if (((test $ATOMIC_X86_SMP -eq 1) || (test $ATOMIC_X86 -eq 1)) && 
-     (test "$X86" -eq 0)); then
-    AC_MSG_ERROR([Cannot use x86 specific code on a non a $host_cpu system!])
-fi
-
-if test $ATOMIC_X86_SMP -eq 1; then
-    AC_DEFINE([ATOMIC_X86_SMP], [1], [use x86 assembler code for atomic arithmetic operations - default for SMP and UP systems])
-elif test $ATOMIC_X86 -eq 1; then
-    AC_DEFINE([ATOMIC_X86], [1], [use x86 assembler code for atomic arithmetic operations that will only work on singleprocessor systems - compiled binary will be buggy on SMP])
-    AC_MSG_WARN(You specified to use atomic arithmetics code for x86 single processor systems! The resulting binary must not be used on SMP machines!)
-fi
-
-
-SIGHUP=0
-if test $X86 -eq 1; then
-    SIGHUP=1
-fi
-
-AC_ARG_ENABLE([sighup],
-              [
-AC_HELP_STRING([--enable-sighup],
-[enable SIGHUP handling, by default this is only enabled for x86 platforms, consult the README for more information (default: auto)])
-            ],
-            [
-                if test "x$enableval" = xno; then
-                    SIGHUP=0
-                else
-                    SIGHUP=1
-                fi
-            ]
-)
-
-if test $SIGHUP -eq 1; then
-    AC_DEFINE([ENABLE_SIGHUP], [1], [enable SIGHUP handling])
-fi
-
-MT_OPTION([mrreg-service], [enable],
-          [Enable the X_MS_MediaReceiverRegistrar UPnP service. This is for future XBox 360 support, other renderers will probably not need it],
-          [
-            AC_DEFINE([ENABLE_MRREG], [1], [Enable the X_MS_MediaReceiverRegistrar UPnP service. This is for future XBox 360 support, other renderers will probably not need it])
-          ],[])
-
-MT_OPTION([external-transcoding], [disable],
-          [external transcoding support],
-          [],[EXTERNAL_TRANSCODING_OPTION_ENABLED=disabled])
-
-MT_OPTION([youtube], [disable],
-          [YouTube service support],
-          [],[YOUTUBE_OPTION_ENABLED=disabled])
-
-#MT_OPTION([weborama], [disable],
-#          [Weborama service support],
-#          [],[WEBORAMA_OPTION_ENABLED=disabled])
-
-MT_OPTION([sqlite-backup-defaults], [enable],
-          [enable sqlite database backup settings in config.xml by default],
-          [],[])
-
-MT_OPTION([protocolinfo-extension], [disable],
-          [This is required for Playstation 3 support, it adds certain tags to the protocolInfo attribute],
-          [
-            AC_DEFINE([EXTEND_PROTOCOLINFO], [1], [This is required for Playstation 3 support, it adds certain tags to the protocolInfo attribute])
-          ],[])
-
-MT_OPTION([curl], [disable],
-          [Enable curl, required for YouTube support, provides additional functionality for the external transcoding feature],
-          [],[])
-
-AC_ARG_WITH([curl-cfg],
-            [
-AC_HELP_STRING([--with-curl-cfg=curl-config],
-                    [absolute path/name of curl-config])
-            ],
-            [
-                CURL_SEARCH_CONFIG="$withval"
-                AC_MSG_NOTICE([Will search for curl-config in $withval])
-            ]
-)
-
-MT_OPTION([fseeko-check], [disable],
-          [This is a workaround for a bug on some Debian distros, use this if configure fails complaining about off_t],
-          [],[])
-
-MT_OPTION([lastfm], [disable],
-          [Enable lastfmlib support],[],[])
-
-dnl some libupnp / tombupnp definitions
-UPNP_V_MAJOR=0
-UPNP_V_MINOR=4
-UPNP_V_PATCH=1
-AC_DEFINE_UNQUOTED([UPNP_VERSION_STRING],"$PACKAGE_VERSION", [see upnpconfig.h])
-AC_DEFINE_UNQUOTED([UPNP_VERSION_MAJOR], $UPNP_V_MAJOR, [see upnpconfig.h])
-AC_DEFINE_UNQUOTED([UPNP_VERSION_MINOR], $UPNP_V_MINOR, [see upnpconfig.h])
-AC_DEFINE_UNQUOTED([UPNP_VERSION_PATCH], $UPNP_V_PATCH, [see upnpconfig.h])
-dnl this is not optional, we need the device and the internal webserver
-AC_DEFINE([UPNP_HAVE_DEVICE], [1], [Compile device API])
-AC_DEFINE([UPNP_HAVE_WEBSERVER], [1], [Compile internal web server])    
-
-
-AC_PROG_CXX
-AC_PROG_CC
-AC_PROG_RANLIB
-AC_PROG_GCC_TRADITIONAL
-AC_HEADER_DIRENT
-AC_HEADER_STDC
-AC_HEADER_SYS_WAIT
-AC_HEADER_STDBOOL
-AC_HEADER_TIME
-AC_HEADER_STAT
-AC_LANG_C
-AM_PROG_CC_C_O
-AM_PROG_AR
-
-AC_CHECK_SIZEOF(off_t, 4)
-AC_CHECK_SIZEOF(size_t, 4)
-AC_CHECK_SIZEOF(time_t, 4)
-AC_CHECK_SIZEOF(unsigned int)
-AC_CHECK_SIZEOF(unsigned long)
-AC_CHECK_FUNCS(strtoll nl_langinfo setlocale,[],[])
-AC_CHECK_FUNCS(backtrace backtrace_symbols,[],[])
-AC_CHECK_FUNCS(arc4random,[],[])
-AC_C_CONST
-AC_C_INLINE
-AC_C_VOLATILE
-AC_SYS_LARGEFILE
-AC_TYPE_OFF_T
-AC_TYPE_SIGNAL
-AC_TYPE_PID_T
-AC_TYPE_UINT32_T
-AC_TYPE_INT64_T
-AC_TYPE_SIZE_T
-AC_TYPE_SSIZE_T
-AC_STRUCT_TM
-AC_C_BIGENDIAN
-
-AC_CHECK_HEADERS([time.h syslog.h stddef.h unistd.h arpa/inet.h fcntl.h], [],
-                 [AC_MSG_ERROR(required header not found)]) 
-
-AC_CHECK_HEADERS([limits.h netdb.h netinet/in.h stdlib.h string.h sys/file.h],
-                 [],
-                 [AC_MSG_ERROR(required header not found)]) 
-AC_CHECK_HEADERS([sys/ioctl.h sys/socket.h sys/time.h sys/types.h sys/wait.h],
-                 [],
-                 [AC_MSG_ERROR(required header not found)]) 
-
-AC_CHECK_HEADERS([langinfo.h locale.h],[],[AC_MSG_WARN(Header that is required to retrieve system locale not found, will use default value)])
-
-AC_CHECK_HEADERS([sys/utsname.h])
-
-AC_CHECK_HEADERS([sched.h ctype.h],[],[])
-AC_CHECK_FUNCS([sched_getparam sched_setparam sched_get_priority_min sched_get_priority_max],[],[])
-   
-AC_CHECK_FUNCS([mkdir], [],
-              [AC_MSG_ERROR(required function not found)])
-
-AC_CHECK_HEADERS([getopt.h],
-        [
-            AC_CHECK_FUNCS([getopt_long],[],
-                           [AC_MSG_WARN(
-             getopt_long not found - all command line options disabled)
-                           ])
-
-        ],
-        [
-    AC_MSG_WARN(getopt.h not found - all command line options disabled)
-        ])
-
-AC_CACHE_SAVE
-
-CPPFLAGS_SAVE="$CPPFLAGS"
-CFLAGS_SAVE="$CFLAGS"
-CXXFLAGS_SAVE="$CXXFLAGS"
-LDFLAGS_SAVE="$LDFLAGS"
-
-if test "x$EXTERNAL_TRANSCODING_OPTION_ENABLED" = xyes; then
-    AC_CHECK_FUNCS([mkfifo],
-       [
-            AC_DEFINE([EXTERNAL_TRANSCODING], [1], [external transcoding feature])
-       ],
-       [
-           if test "x$EXTERNAL_TRANSCODING_OPTION_REQUESTED" = xyes; then
-               AC_MSG_ERROR([mkfifo is required by the external transcoding feature])
-           else
-               AC_MSG_WARN([mkfifo is required by the external transcoding feature])
-               EXTERNAL_TRANSCODING_OPTION_ENABLED=disabled
-
-           fi
-       ]
-    )
-fi
-
-ICONV_CXXFLAGS=
-ICONV_LIBS=
-
-if test -n "$ICONV_SEARCH_HEADERS"; then
-AC_CHECK_HEADER([$ICONV_SEARCH_HEADERS/iconv.h],
-        [
-            ICONV_CXXFLAGS="-I$ICONV_SEARCH_HEADERS"
-        ],
-        [
-            AC_MSG_ERROR(iconv.h not found in requested location $ICONV_SEARCH_HEADERS)
-        ]
-)
-        
-else
-AC_CHECK_HEADER([iconv.h],
-        [ICONV_OK=yes],
-        [
-            unset ac_cv_header_iconv_h
-            AC_CHECK_HEADER([/usr/local/include/iconv.h],
-                [
-                    ICONV_CXXFLAGS="-I/usr/local/include"
-                    if test -z "$ICONV_SEARCH_LIBS"; then
-                        LDFLAGS="-L/usr/local/lib"
-                    fi
-                ],
-                [
-                    unset ac_cv_header_iconv_h
-                    AC_CHECK_HEADER([$SEARCH_DIR_HEADERS/iconv.h],
-                        [
-                            ICONV_CXXFLAGS="-I$SEARCH_DIR_HEADERS"
-                            if test -z "$ICONV_SEARCH_LIBS"; then
-                                LDFLAGS="-L$SEARCH_DIR_LIBS"
-                            fi
-                        ],
-                        [AC_MSG_ERROR(required header iconv.h not found on your system)]
-                    )
-                ]
-            )
-        ]
-)
-fi
-
-LIBICONV=0
-if test -n "$ICONV_SEARCH_LIBS"; then
-    if test "x$ICONV_LIB_OPTION_ENABLED" = xno; then
-        LDFLAGS="-L$ICONV_SEARCH_LIBS"
-        AC_CHECK_FUNC([iconv],
-            [
-                ICONV_LIBS="-L$ICONV_SEARCH_LIBS"
-            ],
-            [
-                LDFLAGS="-L$ICONV_SEARCH_LIBS -liconv"
-                AC_CHECK_LIB(iconv, iconv,
-                    [
-                        ICONV_LIBS="-L$ICONV_SEARCH_LIBS -liconv"
-                        LIBICONV=1
-                    ],
-                    [
-                        AC_CHECK_LIB(iconv, libiconv,
-                            [
-                                ICONV_LIBS="-L$ICONV_SEARCH_LIBS -liconv"
-                                LIBICONV=1
-                            ],
-                            [AC_MSG_ERROR(required library iconv not found in requested location $ICONV_SEARCH_LIBS)]
-                        )
-                    ]
-                ) 
-            ]
-        ) 
-    else
-        LDFLAGS="-L$ICONV_SEARCH_LIBS -liconv"
-        AC_CHECK_LIB(iconv, iconv,
-                [
-                    ICONV_LIBS="-L$ICONV_SEARCH_LIBS -liconv"
-                    LIBICONV=1
-                ],
-                [AC_MSG_ERROR(You specified to use libiconv but it was not found in the requested location $ICONV_SEARCH_LIBS)]
-        )
-    fi
-else
-    if test "x$ICONV_LIB_OPTION_ENABLED" = xno; then
-        AC_CHECK_FUNC([iconv],
-            [
-                ICONV_LIBS="$LDFLAGS"
-            ],
-            [
-                AC_MSG_ERROR(You specified to use libiconv but the library was not found)
-            ]
-        )
-    else
-        LDFLAGS="$LDFLAGS -liconv"
-        AC_CHECK_LIB(iconv, iconv,
-                [
-                    ICONV_LIBS="$LDFLAGS"
-                    LIBICONV=1
-                ],
-                [
-                    AC_MSG_ERROR(You specified to use libiconv but the library was not found)
-                ]
-       )
-    fi
-fi
-
-if test $LIBICONV -eq 1; then
-    AC_DEFINE([HAVE_LIBICONV], [1], [we are using the libiconv library])
-fi
-
-AC_SUBST(ICONV_CXXFLAGS)
-AC_SUBST(ICONV_LIBS)
-
-CFLAGS="$CFLAGS $ICONV_CXXFLAGS -Werror"
-AC_MSG_CHECKING([if iconv declaration requires const char cast])
-AC_COMPILE_IFELSE(
-     [AC_LANG_PROGRAM(
-         [
-             #include <stdlib.h>
-             #include <iconv.h>
-         ],
-         [
-            char **ptr = NULL;
-            size_t len;
-            iconv_t cd = NULL;
-            (void)iconv(cd, ptr, &len, ptr, &len);
-         ]
-     )],
-     [
-         AC_MSG_RESULT([no])
-     ],
-     [
-         AC_DEFINE([ICONV_CONST], [1], 
-                   [iconv needs const char cast])
-
-         AC_MSG_RESULT([yes])
-     ])
-
-CFLAGS="$CFLAGS_SAVE"
-CXXFLAGS="$CXXFLAGS_SAVE"
-LDFLAGS="$LDFLAGS_SAVE"
-
-AC_CHECK_HEADERS(execinfo.h,[],[])
-
-AC_CHECK_TYPES([time_t], [], [], [#include <sys/types.h>])
-
-AC_CACHE_SAVE
-
-if test "x$FSEEKO_CHECK_OPTION_ENABLED" = xyes; then
-    AC_FUNC_FSEEKO
-
-    if test "$ac_cv_func_fseeko" = no || test "$ac_cv_sys_largefile_source" = unknown; then
-        AC_MSG_WARN([fseeko has not been found on your system, will use fseek instead.])
-        AC_MSG_WARN([This has not been tested, please report if you have any problems.])
-        AC_DEFINE([fseeko], [fseek], [fseeko not present])
-    fi
-else
-    AC_MSG_WARN([Skipping fseeko test! (requested by user)])
-fi
-
-dnl This needs improvement!
-AC_CHECK_DECL(LONG_MAX,
-        [
-            AC_DEFINE([HAVE_LONG_MAX], [1], [LONG_MAX definition available])
-            have_long_max=1
-        ], , [#include <limits.h>])
-
-
-AC_CHECK_DECL(LLONG_MAX,
-        [
-            AC_DEFINE([MAXLLONG], [LLONG_MAX], [LLONG_MAX definition])
-        ],
-        [
-            AC_CHECK_DECL(__LONG_LONG_MAX__, 
-                [
-                    AC_DEFINE([MAXLLONG], [__LONG_LONG_MAX__], 
-                    [LLONG_MAX definition])],
-                [
-                    if test "$have_long_max" -eq 1; then
-                        AC_DEFINE([MAXLLONG], [LONG_MAX], [LLONG_MAX not available])
-                    fi
-                ], [#include <limits.h>])
-        ]
-        , [#include <limits.h>])
-
-AC_ARG_ENABLE(rpl-malloc, 
-        AC_HELP_STRING([--disable-rpl-malloc], [disable redefinition of malloc to rpl_malloc and realloc to rpl_realloc. Use this if you are sure that you are compiling for the GNU C library (default: enabled)]),
-        [
-            if test "x$enableval" = xno; then
-                ac_cv_func_malloc_0_nonnull=yes
-                ac_cv_func_realloc_0_nonnull=yes
-                AC_MSG_NOTICE([Disabling redefinition of malloc to rpl_malloc])
-                AC_MSG_NOTICE([Disabling redefinition of realloc to rpl_realloc])
-                AC_MSG_WARN([Use this feature only if you are sure that you are building for GNU C!])
-            fi
-        ]
-)
-
-
-# Checks for library functions.
-AC_FUNC_ALLOCA
-AC_FUNC_CLOSEDIR_VOID
-AC_FUNC_ERROR_AT_LINE
-AC_FUNC_FORK
-AC_FUNC_MALLOC
-AC_FUNC_MEMCMP
-AC_FUNC_REALLOC
-AC_FUNC_SELECT_ARGTYPES
-AC_FUNC_STAT
-AC_FUNC_STRTOD
-AC_FUNC_VPRINTF
-AC_FUNC_STRERROR_R
-AC_FUNC_STRFTIME
-
-AC_LANG_CPLUSPLUS
-
-AC_CHECK_FUNCS([gethostname gettimeofday localtime_r memmove memset],
-               [],
-               [AC_MSG_ERROR(required library function not found)])
-AC_CHECK_FUNCS([regcomp select strcasecmp strchr strdup strerror strncasecmp],
-               [],
-               [AC_MSG_ERROR(required library function not found)])
-AC_CHECK_FUNCS([strrchr strstr strtol strtoul uname], [],
-               [AC_MSG_ERROR(required library function not found)])
-
-AC_CHECK_FUNCS([sigaction sigprocmask],[],
-               [AC_MSG_ERROR(required library function not found)]) 
- 
-AC_CHECK_FUNCS([ioctl tolower toupper],[],
-               [AC_MSG_ERROR(required library function not found)]) 
-               
-AC_CACHE_SAVE
-
-AC_CHECK_FUNCS([inet_ntoa],
-               [],
-               [
-                    AC_CHECK_LIB(nsl, inet_ntoa,
-                                 [],
-                                 [
-                                    AC_MSG_ERROR(required library function not found)
-                                 ])
-               ])
-
-AC_CHECK_FUNCS([socket],
-               [],
-               [AC_CHECK_LIB(socket, socket,
-                                 [],
-                                 [
-                                    AC_MSG_ERROR(required library function not found)
-                                 ])
-               ])
-               
-
-
-AC_CHECK_FUNCS([gethostbyname],
-               [],
-               [
-                    AC_CHECK_LIB(nsl, gethostbyname, 
-                                 [],
-                                 [
-                                    AC_MSG_ERROR(required library function not found)
-                                 ]) 
-               ])
-
-if test $DARWIN_OS -eq 1 ; then
-        AC_MSG_NOTICE([You are running OSX, assuming threadsafe gethostbyname version])
-elif test $CYGWIN_OS -eq 1; then
-        AC_MSG_NOTICE([Your are building under Cygwin, assuming threadsafe gethostbyname implementation])
-fi
-
-AC_CHECK_FUNCS([gethostbyname_r],[],
-        [
-            AC_CHECK_HEADERS([lwres/netdb.h],
-                [
-                    AC_CHECK_LIB(lwres, lwres_gethostbyname_r,
-                                 [
-                                    LWRES_LIBS="-llwres"
-                                    AC_DEFINE(HAVE_LIBLWRES, 1, [lwres library presence])
-                                    AC_SUBST(LWRES_LIBS)
-                                 ],
-                                 [AC_MSG_ERROR(required library function not found)])
-                ],
-                [
-                    if ((test $DARWIN_OS -eq 0) && (test $CYGWIN_OS -eq 0) && (test $OPENBSD_OS -eq 0)) ; then
-                        AC_MSG_ERROR([required header not found])
-                    fi
-                ])
-        ])
-
-AC_CHECK_FUNCS([if_nameindex],[],
-        [
-            AC_CHECK_LIB(nsl, if_nameindex,
-                [
-                    NSL_LIBS="-lnsl"
-                    AC_SUBST(NSL_LIBS)
-                ],
-                [
-                    if test $CYGWIN_OS -eq 0; then
-                        AC_MSG_ERROR(required library function not found)
-                    fi
-                ]
-            )
-        ]
-)
-
-AC_CHECK_FUNCS([if_freenameindex],[],
-        [
-            AC_CHECK_LIB(nsl, if_freenameindex,[],
-                [
-                    if ((test $CYGWIN_OS -eq 0) && (test $OPENBSD_OS -eq 0)); then
-                        AC_MSG_ERROR(required library function not found)
-                    fi
-                ]
-            )
-        ]
-)
-    
-ADD_PTHREAD_CFLAGS=
-
-# see acinclude.m4 for the definition of ACX_PTHREAD
-if test "x$PTHREAD_LIB_OPTION_ENABLED" = xyes; then
-    MT_CHECK_LIBRARY([pthread], [pthread], [pthread_create])
-    if test "x$PTHREAD_STATUS" != xyes; then
-        AC_MSG_ERROR([pthread library not found, try running configure without the --enable-pthread-lib option])
-    fi
-else
-    ACX_PTHREAD(,AC_MSG_ERROR(POSIX threads missing))
-
-    if test $FREEBSD_OS -eq 1; then
-        ADD_PTHREAD_CFLAGS="$PTHREAD_CFLAGS $PTHREAD_LIBS"
-    fi
-
-    if test "x$STATIC_OPTION_ENABLED" = xyes; then
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-        LIBS="$LIBS $PTHREAD_LIBS"
-        CFLAGS_SAVE="$CFLAGS_SAVE $PTHREAD_CFLAGS"
-        LIBS_SAVE="$LIBS_SAVE $PTHREAD_LIBS"
-    fi
-
-    AC_SUBST(PTHREAD_LIBS)
-    AC_SUBST(PTHREAD_CFLAGS)
-fi
-
-unset LIBS
-
-# we might need librt for sqlite
-MT_CHECK_LIBRARY([rt], [rt], [clock_gettime])
-
-if test "x$RT_STATUS" != xyes; then
-    AC_CHECK_FUNC(clock_gettime)
-fi
-
-############ zlib
-
-ZLIB_STATUS="no"
-
-if  test "x$DB_AUTOCREATE_OPTION_ENABLED" = xyes; then
-PKG_CHECK_MODULES([ZLIB], [zlib],
-    [
-        AC_DEFINE([HAVE_ZLIB], [1], [zlib is available])
-        ZLIB_STATUS="yes"
-    ],
-    [
-        AC_MSG_WARN([$ZLIB_PKG_ERRORS])
-    ])
-fi
-
-if test "x$ZLIB_STATUS" = "xyes"; then
-    if test "x$DB_AUTOCREATE_OPTION_ENABLED" = xyes; then
-        AC_DEFINE([AUTO_CREATE_DATABASE], [1], [create database automatically if it does not exist])
-    fi
-else
-    if test "x$DB_AUTOCREATE_OPTION_ENABLED" = xyes; then
-        if test "x$DB_AUTOCREATE_OPTION_REQUESTED" = xyes; then
-            AC_MSG_ERROR([Automatic database creation not possible due to missing zlib headers/libraries])
-        else
-            AC_MSG_WARN([Automatic database creation not possible due to missing zlib headers/libraries])
-            DB_AUTOCREATE_OPTION_ENABLED=disabled
-        fi
-    fi
-fi
-
-AC_CACHE_SAVE
-
-######### SQLite3
-
-if test "x$RT_STATUS" = xyes; then
-    LDFLAGS="$LDFLAGS $RT_LDFLAGS $RT_LIBS"
-fi
-
-MT_OPTION([sqlite3], [disable],
-          [compile with sqlite3 support],[],[])
-
-SQLITE3_STATUS="no"
-if test "x$SQLITE3_OPTION_ENABLED" = "xyes"; then
-    PKG_CHECK_MODULES([SQLITE3], [sqlite3],
-        [
-            SQLITE3_STATUS="yes"
-            AC_DEFINE([HAVE_SQLITE3], [1], [sqlite is available])
-        ],
-        [
-            if test "x$SQLITE3_OPTION_REQUESTED" = "xyes"; then
-                AC_MSG_ERROR([$SQLITE3_PKG_ERRORS])
-            else
-                AC_MSG_WARN([$SQLITE3_PKG_ERRORS])
-                SQLITE3_STATUS="missing"
-            fi
-        ])
-fi
-
-if ((test "x$SQLITE3_OPTION_ENABLED" != "xyes") &&
-    (test "x$SQLITE3_OPTION_REQUESTED" = "xyes")); then
-    SQLITE3_STATUS="disabled"
-fi
-
-if test "x$SQLITE3_STATUS" = "xyes"; then
-    if test "x$SQLITE_BACKUP_OPTION_ENABLED" = xyes; then
-        AC_DEFINE([SQLITE_BACKUP_ENABLED], [1], [enable sqlite db backup settings in config.xml by default])
-    fi
-else
-    if (test "x$SQLITE_BACKUP_OPTION_ENABLED" = xyes) &&
-       (test "x$SQLITE_BACKUP_OPTION_REQUESTED" = xyes); then
-        AC_MSG_ERROR(You specified the option to use sqlite backup settings but the sqlite support could not be configured)
-    fi
-
-fi
-
-LDFLAGS="$LDFLAGS_SAVE"
-CPPFLAGS="$CPPFLAGS_SAVE"
-CXXFLAGS="$CXXFLAGS_SAVE"
-
-########## MySQL
-
-MT_CHECK_OPTIONAL_PACKAGE_CFG([mysql], 
-                              [disable],
-                              [mysql database support],
-                              [mysql_config],
-                              [mysql.h],
-                              [], [mysql_init],[--libs_r])
-
-if test "x$MYSQL_STATUS" = xyes; then
-    AC_MSG_CHECKING(mysql version)
-    MYSQL_VERSION_MAJOR=`echo $MYSQL_VERSION | sed 's/^\([[0-9]]\{1,\}\)\.\([[0-9]]\{1,\}\).\([[0-9]]\{1,\}\).*$/\1/'`
-    MYSQL_VERSION_MINOR=`echo $MYSQL_VERSION | sed 's/^\([[0-9]]\{1,\}\)\.\([[0-9]]\{1,\}\).\([[0-9]]\{1,\}\).*$/\2/'`
-    AC_MSG_RESULT($MYSQL_VERSION)
-    if test -z $MYSQL_VERSION_MAJOR || test -z $MYSQL_VERSION_MINOR; then
-        AC_MSG_WARN([could not parse mysql version string])
-        MYSQL_STATUS=missing
-    elif test $MYSQL_VERSION_MAJOR -le 3 ; then
-       AC_MSG_WARN(MySQL version too old, we only support version 4.0.x or later)
-       MYSQL_STATUS=missing
-    fi
-fi
-
-LDFLAGS="$LDFLAGS_SAVE"
-LIBS="$LIBS $MYSQL_LIBS"
-CFLAGS="$CFLAGS $MYSQL_CFLAGS"
-CXXFLAGS="$CXXFLAGS $MYSQL_CFLAGS"
-CPPFLAGS="$CFLAGS $MYSQL_CFLAGS"
-
-if test "x$MYSQL_STATUS" = xyes; then
-    AC_DEFINE([HAVE_MYSQL], [1], [MySQL library presence])
-    AC_SUBST(MYSQL_LIBS)
-    AC_SUBST(MYSQL_CFLAGS)
-    AC_CHECK_FUNCS([mysql_stmt_init],[],[])
-    
-    AC_MSG_CHECKING([MYSQL_OPT_RECONNECT])
-    AC_COMPILE_IFELSE(
-        [AC_LANG_PROGRAM(
-            [
-                #include <mysql.h>
-            ],
-            [
-                (int)mysql_options(0, MYSQL_OPT_RECONNECT, 0);
-            ]
-        )],
-        [
-            AC_MSG_RESULT([yes])
-            AC_DEFINE([HAVE_MYSQL_OPT_RECONNECT], [1], [MYSQL_OPT_RECONNECT parameter available])
-        ],
-        [
-            AC_MSG_RESULT([no])
-        ]
-    )
-else
-    MYSQL_CFLAGS=
-    MYSQL_LIBS=
-fi
-
-CPPFLAGS="$CPPFLAGS_SAVE"
-CXXFLAGS="$CXXFLAGS_SAVE"
-CFLAGS="$CFLAGS_SAVE"
-LDFLAGS="$LDFLAGS_SAVE"
-LIBS="$LIBS_SAVE"
-
-#########  check if at least one database available
-
-if ((test "x$SQLITE3_STATUS" != xyes) && (test "x$MYSQL_STATUS" != xyes)); then
-    AC_MSG_ERROR(Support of at least one of mysql or sqlite3 must be configured)
-fi
-
-######### javascript
-
-JS_STATUS="disabled"
-MT_OPTION([libjs], [disable],
-          [compile with spidermonkey support],[],[])
-
-if test "x$LIBJS_OPTION_ENABLED" = "xyes"; then
-    PKG_CHECK_MODULES([LIBJS], [libjs >= 1.8.5],
-        [
-            JS_STATUS="yes"
-            AC_DEFINE([HAVE_JS], [1], [libjs presence])
-        ],
-        [
-            AC_MSG_WARN([$LIBJS_PKG_ERRORS])
-            PKG_CHECK_MODULES([LIBJS], [mozjs185],
-                [
-                    JS_STATUS="yes"
-                    AC_DEFINE([HAVE_JS], [1], [libjs presence])
-                ],
-                [
-                    if test "x$LIBJS_OPTION_REQUESTED" = "xyes"; then
-                        AC_MSG_ERROR([$LIBJS_PKG_ERRORS])
-                    else
-                        AC_MSG_WARN([$LIBJS_PKG_ERRORS])
-                    fi
-                    JS_STATUS="missing"
-                ])
-        ])
-
-fi
-
-CXXFLAGS="$CXXFLAGS_SAVE"
-CPPFLAGS="$CPPFLAGS_SAVE"
-LDFLAGS="$LDFLAGS_SAVE"
-
-########### libmagic
-MT_OPTION([libmagic], [disable],
-          [filemagic for automatic mimetype recognition],[],[])
-
-if test "x$LIBMAGIC_OPTION_ENABLED" = xyes; then
-    MT_CHECK_PACKAGE([libmagic], [magic], [magic], [magic_load])
-
-    if test "x$LIBMAGIC_STATUS" != xyes; then
-        if test "x$ZLIB_STATUS" != xyes; then
-            MT_CHECK_LIBRARY([zlib], [z], [compress])
-            LDFLAGS="$LDFLAGS $ZLIB_LDFLAGS"
-            LIBS="$LIBS $ZLIB_LIBS"
-            AC_MSG_NOTICE([retrying libmagic check with zlib flags])
-            MT_CHECK_PACKAGE([libmagic], [magic], [magic], [magic_load])
-            if test "x$LIBMAGIC_STATUS" = xyes; then
-                LIBMAGIC_LIBS="$LIBMAGIC_LIBS $ZLIB_LIBS"
-                LIBMAGIC_LDFLAGS="$LIBMAGIC_LDFLAGS $ZLIB_LDFLAGS"
-            fi
-        else
-            LDFLAGS="$LDFLAGS $ZLIB_LDFLAGS"
-            LIBS="$LIBS $ZLIB_LIBS"
-            AC_MSG_NOTICE([retrying libmagic check with zlib flags])
-            MT_CHECK_PACKAGE([libmagic], [magic], [magic], [magic_load])
-            if test "x$LIBMAGIC_STATUS" = xyes; then
-                LIBMAGIC_LIBS="$LIBMAGIC_LIBS $ZLIB_LIBS"
-                LIBMAGIC_LDFLAGS="$LIBMAGIC_LDFLAGS $ZLIB_LDFLAGS"
-            fi
-        fi
-
-        AC_SUBST(LIBMAGIC_LIBS)
-        AC_SUBST(LIBMAGIC_LDFLAGS)
-    fi
-fi
-
-if test "x$LIBMAGIC_STATUS" = xyes; then
-    AC_MSG_CHECKING([if libmagic is broken (Slackware check)])
-    CFLAGS="$CFLAGS $LIBMAGIC_CXXLAGS"
-    CXXFLAGS="$CXXFLAGS $LIBMAGIC_CFLAGS"
-    LDFLAGS="$LDFLAGS $LIBMAGIC_LDFLAGS $LIBMAGIC_LIBS"
-    AC_LANG_SAVE
-    AC_LANG_C
-    AC_RUN_IFELSE(
-    [
-        AC_LANG_PROGRAM(
-         [[ #include <magic.h> ]],
-         [[
-            struct magic_set *ms;
-            ms = magic_open(MAGIC_MIME);
-            if (ms == 0)
-                return 0;
-            magic_load(ms, 0);
-            magic_close(ms);
-            return 0;
-         ]])
-    ],
-    [
-        AC_MSG_RESULT([no]);
-    ],
-    [
-        AC_MSG_RESULT([yes])
-        MAGIC_OK=broken
-        AC_MSG_WARN([your magic library is broken, if you are using Slackware install the 'file' package manually])
-    ],
-    [
-        AC_MSG_RESULT([passing for cross compiling])
-    ])
-
-   AC_LANG_RESTORE
-fi
-
-if test "x$LIBMAGIC_STATUS" = xyes; then
-    AC_DEFINE([HAVE_MAGIC], [1], [filemagic library presence])
-else
-    if (test "x$LIBMAGIC_OPTION_REQUESTED" = xyes) && 
-       (test "x$LIBMAGIC_OPTION_ENABLED" = xyes); then
-        AC_MSG_ERROR(unable to configure libmagic support)
-    fi
-fi
-
-CFLAGS="$CFLAGS_SAVE"
-CXXFLAGS="$CXXFLAGS_SAVE"
-CPPFLAFS="$CPPFLAFS_SAVE"
-LDFLGAS="$LDFLAGS_SAVE"
-
-######### taglib or id3lib selection
-
-TAGLIB_STATUS=
-ID3LIB_STATUS=
-
-MT_OPTION([id3lib], [disable],
-          [id3 metadata extraction with the help of id3lib],[],[])
-
-MT_OPTION([taglib], [disable],
-          [id3 metadata extraction with the help of taglib],[],[])
-
-if ((test "x$TAGLIB_OPTION_ENABLED" = xno) && (test "x$ID3LIB_OPTION_ENABLED" = xyes)) ; then
-    TAGLIB_STATUS=disabled
-    TAGLIB_OPTION_ENABLED=no
-    AC_MSG_WARN([taglib disabled])
-elif ((test "x$TAGLIB_OPTION_ENABLED" = xyes) && (test "x$ID3LIB_OPTION_ENABLED" = xno)) ; then
-    ID3LIB_STATUS=disabled
-    ID3LIB_OPTION_ENABLED=no
-    AC_MSG_WARN([id3lib disabled])
-elif ((test "x$TAGLIB_OPTION_ENABLED" = xyes) && (test "x$ID3LIB_OPTION_ENABLED" = xyes)) ; then
-    if ((test "x$TAGLIB_OPTION_REQUESTED" = xyes) && (test "x$ID3LIB_OPTION_REQUESTED" = xyes)); then
-        AC_MSG_ERROR([Please select either taglib or id3lib, but not both.])
-    elif ((test "x$TAGLIB_OPTION_REQUESTED" = xyes) && (test "x$ID3LIB_OPTION_REQUESTED" != xyes)); then
-        ID3LIB_OPTION_ENABLED=no
-    elif ((test "x$TAGLIB_OPTION_REQUESTED" != xyes) && (test "x$ID3LIB_OPTION_REQUESTED" = xyes)); then
-        TAGLIB_OPTION_ENABLED=no
-    fi
-fi
-
-if test "x$TAGLIB_OPTION_ENABLED" = xyes; then
-    MT_CHECK_PACKAGE_CFG([taglib],  
-                         [taglib-config], 
-                         [taglib.h fileref.h tag.h audioproperties.h tstring.h textidentificationframe.h attachedpictureframe.h],
-                         [tag], [main])
-else
-    TAGLIB_STATUS=disabled
-    if test "x$ID3_OPTION_REQUESTED" = no; then
-        ID3_OPTION_ENABLED=yes
-    fi
-fi
-
-if test "x$TAGLIB_STATUS" = xyes; then
-    AC_DEFINE([HAVE_ID3_ALBUMART], [1], [not aware of taglib versions that do not support album art])
-    ID3LIB_STATUS=disabled
-    ID3LIB_OPTION_ENABLED=no
-else
-    if (test "x$TAGLIB_OPTION_REQUESTED" = xyes) && 
-       (test "x$TAGLIB_OPTION_ENABLED" = xyes); then
-        AC_MSG_ERROR([unable to configure taglib support])
-    fi
-fi
-
-######### id3lib
-
-if test "x$ID3LIB_OPTION_ENABLED" = xyes; then
-    MT_CHECK_PACKAGE([id3lib], [id3/tag], [id3], [main])
-
-    if test "x$ID3LIB_STATUS" != xyes; then
-        if test "x$ZLIB_STATUS" != xyes; then
-            MT_CHECK_LIBRARY([zlib], [z], [compress])
-            LDFLAGS="$LDFLAGS $ZLIB_LDFLAGS"
-            LIBS="$LIBS $ZLIB_LIBS"
-            AC_MSG_NOTICE([retrying id3lib check with zlib flags])
-            MT_CHECK_PACKAGE([id3lib], [id3/tag], [id3], [main])
-            if test "x$ID3LIB_STATUS" = xyes; then
-                ID3LIB_LIBS="$ID3LIB_LIBS $ZLIB_LIBS"
-                ID3LIB_LDFLAGS="$ID3LIB_LDFLAGS $ZLIB_LDFLAGS"
-            fi
-        else
-            LDFLAGS="$LDFLAGS $ZLIB_LDFLAGS"
-            LIBS="$LIBS $ZLIB_LIBS"
-            AC_MSG_NOTICE([retrying id3lib check with zlib flags])
-            MT_CHECK_PACKAGE([id3lib], [id3/tag], [id3], [main])
-            if test "x$ID3LIB_STATUS" = xyes; then
-                ID3LIB_LIBS="$ID3LIB_LIBS $ZLIB_LIBS"
-                ID3LIB_LDFLAGS="$ID3LIB_LDFLAGS $ZLIB_LDFLAGS"
-            fi
-        fi
-
-        AC_SUBST(ID3LIB_LIBS)
-        AC_SUBST(ID3LIB_LDFLAGS)
-    fi
-fi
-
-if test "x$ID3LIB_STATUS" = xyes; then
-   CFLAGS="$CFLAGS $ID3_CFLAGS"
-   CXXFLAGS="$CXXFLAGS $ID3_CFLAGS"
-   LDFLAGS="$LDFLAGS $ID3LIB_LDFLAGS $ID3LIB_LIBS"
-   AC_LANG_SAVE
-   AC_LANG_CPLUSPLUS
-   AC_MSG_CHECKING([for album art support in id3lib])
-   AC_COMPILE_IFELSE(
-        [AC_LANG_PROGRAM(
-            [
-                #include <id3/tag.h>
-                #include <id3/misc_support.h>
-            ],
-            [
-                (void)ID3_HasPicture(0);
-            ]
-        )],
-        [
-            AC_MSG_RESULT([yes])
-            AC_DEFINE([HAVE_ID3_ALBUMART], [1], 
-                      [this version of id3lib has album art support])
-        ],
-        [
-            AC_MSG_RESULT([no])
-        ])
-   AC_LANG_RESTORE
-else
-    if (test "x$ID3LIB_OPTION_REQUESTED" = xyes) &&
-       (test "x$ID3LIB_OPTION_ENABLED" = xyes); then
-        if test "x$TAGLIB_STATUS" = xyes; then
-            AC_MSG_ERROR([Please select either taglib or id3lib, but not both.])
-        else
-            AC_MSG_ERROR(unable to configure id3lib support)
-        fi
-    else
-        ID3LIB_STATUS=disabled
-    fi
-fi
-
-LDFLAGS="$LDFLAGS_SAVE"
-LIBS="$LIBS_SAVE"
-CXXFLAGS="$CXXFLAGS_SAVE"
-CPPFLAGS="$CPPFLAGS_SAVE"
-
-######### FLAC
-
-FLAC_STATUS=
-
-MT_OPTION([flac], [disable],
-          [FLAC metadata extraction with the help of FLAC library],[],[])
-
-if test "x$FLAC_OPTION_ENABLED" = xyes; then
-    MT_CHECK_PACKAGE([FLAC], [FLAC/metadata], [FLAC], [main])
-else
-    FLAC_STATUS=disabled
-fi
-
-if test "x$FLAC_STATUS" != xyes; then
-    if (test "x$FLAC_OPTION_REQUESTED" = xyes) &&
-       (test "x$FLAC_OPTION_ENABLED" = xyes); then
-        AC_MSG_ERROR([unable to configure FLAC support])
-    fi
-else
-    CFLAGS="$CFLAGS $FLAC_CFLAGS"
-    CXXFLAGS="$CXXFLAGS $FLAC_CFLAGS"
-    LDFLAGS="$LDFLAGS $FLAC_LDFLAGS $FLAC_LIBS"
-    AC_LANG_SAVE
-    AC_LANG_CPLUSPLUS
-fi
-
-######## curl
-
-if ((test "x$YOUTUBE_OPTION_ENABLED" = xyes) && (test "x$YOUTUBE_OPTION_REQUESTED" = xyes) && (test "x$CURL_OPTION_ENABLED" = "xno") && (test "x$CURL_OPTION_REQUESTED" = "xyes")); then
-    AC_MSG_ERROR([You enabled YouTube but disabled curl, however curl is required by the YouTube feature])
-fi
-
-if ((test "x$WEBORAMA_OPTION_ENABLED" = xyes) && (test "x$WEBORAMA_OPTION_REQUESTED" = xyes) && (test "x$CURL_OPTION_ENABLED" = "xno") && (test "x$CURL_OPTION_REQUESTED" = "xyes")); then
-    AC_MSG_ERROR([You enabled Weborama but disabled curl, however curl is required by the Weborama feature])
-fi
-
-if ((test "x$ATRAILERS_OPTION_ENABLED" = xyes) && (test "x$ATRAILERS_OPTION_REQUESTED" = xyes) && (test "x$CURL_OPTION_ENABLED" = "xno") && (test "x$CURL_OPTION_REQUESTED" = "xyes")); then
-    AC_MSG_ERROR([You enabled Apple Trailers but disabled curl, however curl is required by the Apple Trailers feature])
-fi
-
-if ((test "x$YOUTUBE_OPTION_ENABLED" != xyes) && (test "x$SOPCAST_OPTION_ENABLED" != xyes) && (test "x$EXTERNAL_TRANSCODING_OPTION" != xyes) && (test "x$ATRAILERS_OPTION_ENABLED" != xyes) && (test "x$WEBORAMA_OPTION_ENABLED" != xyes)); then
-    if test "x$CURL_OPTION_ENABLED" = "xyes"; then
-        if test "x$CURL_OPTION_REQUESTED" = "xyes"; then
-            AC_MSG_ERROR([You enabled curl support but the external transcoding, YouTube and SopCast features are disabled - curl is not needed without it])
-        else
-            CURL_OPTION_ENABLED="xno"
-        fi
-    fi
-fi
-
-CURL_FOUND="no"
-if (((test "x$YOUTUBE_OPTION_ENABLED" = xyes) || (test "x$SOPCAST_OPTION_ENABLED" = xyes) || (test "x$ATRAILERS_OPTION_ENABLED" = xyes) || (test "x$WEBORAMA_OPTION_ENABLED" = xyes) || (test "x$EXTERNAL_TRANSCODING_OPTION" = xyes)) && (test "x$CURL_OPTION_ENABLED" = "xyes")); then
-    AC_MSG_NOTICE([Checking for curl (needed for extended external transcoding/YouTube support)])
-
-    PKG_CHECK_MODULES([CURL], [libcurl],
-        [
-            AC_DEFINE([HAVE_CURL], [1], [libcurl is available])
-            CURL_FOUND="yes"
-        ],
-        [
-            AC_MSG_WARN([$CURL_PKG_ERRORS])
-        ])
-fi
-
-if test "x$CURL_FOUND" = "xno"; then
-    if (test "x$YOUTUBE_OPTION_ENABLED" = xyes) && (test "x$YOUTUBE_OPTION_REQUESTED" = xyes); then
-        AC_MSG_ERROR([unable to configure curl which is required for YouTube support!])
-    fi
-
-    if (test "x$YOUTUBE_OPTION_ENABLED" = xyes) && (test "x$YOUTUBE_OPTION_REQUESTED" != xyes); then
-        AC_MSG_WARN([curl not found, disabling YouTube])
-        YOUTUBE_OPTION_ENABLED="missing"
-    fi
-
-    if (test "x$WEBORAMA_OPTION_ENABLED" = xyes) && (test "x$WEBORAMA_OPTION_REQUESTED" = xyes); then
-        AC_MSG_ERROR([unable to configure curl which is required for Weborama support!])
-    fi
-
-    if (test "x$WEBORAMA_OPTION_ENABLED" = xyes) && (test "x$WEBORAMA_OPTION_REQUESTED" != xyes); then
-        AC_MSG_WARN([curl not found, disabling Weborama])
-        WEBORAMA_OPTION_ENABLED="missing"
-    fi
-
-    if (test "x$ATRAILERS_OPTION_ENABLED" = xyes) && (test "x$ATRAILERS_OPTION_REQUESTED" = xyes); then
-        AC_MSG_ERROR([unable to configure curl which is required for Apple Trailers support!])
-    fi
-
-    if (test "x$ATRAILERS_OPTION_ENABLED" = xyes) && (test "x$ATRAILERS_OPTION_REQUESTED" != xyes); then
-        AC_MSG_WARN([curl not found, disabling Apple Trailers])
-        ATRAILERS_OPTION_ENABLED="missing"
-    fi
-
-    if (test "x$SOPCAST_OPTION_ENABLED" = xyes) && (test "x$SOPCAST_OPTION_REQUESTED" = xyes); then
-        AC_MSG_ERROR([unable to configure curl which is required for SopCast support!])
-    fi
-
-    if (test "x$SOPCAST_OPTION_ENABLED" = xyes) && (test "x$SOPCAST_OPTION_REQUESTED" != xyes); then
-        AC_MSG_WARN([curl not found, disabling SopCast])
-        SOPCAST_OPTION_ENABLED="missing"
-    fi
-
-    if test "x$EXTERNAL_TRANSCODING_OPTION" = xyes; then
-        if ((test "x$CURL_OPTION_ENABLED" = "xyes") && (test "x$CURL_OPTION_REQUESTED" = "xno")); then
-            AC_MSG_WARN([unable to configure curl, external transcoding will have limited functionality!])
-        fi
-
-        if ((test "x$CURL_OPTION_ENABLED" = "xyes") && (test "x$CURL_OPTION_REQUESTED" = "xyes")); then
-            AC_MSG_ERROR([You enabled curl support but the curl library could not be configured])
-        fi
-    fi
-
-    if (test "x$YOUTUBE_OPTION_ENABLED" != xyes) && (test "x$WEBORAMA_OPTION_ENABLED" != xyes) && (test "x$ATRAILERS_OPTION_ENABLED" != xyes) && (test "x$EXTERNAL_TRANSCODING_OPTION" = !xyes) && (test "x$SOPCAST_OPTION_ENABLED" != xyes); then
-        CURL_CFLAGS=
-        CURL_LIBS=
-        CURL_LDFLAGS=
-        AC_SUBST(CURL_CFLAGS)
-        AC_SUBST(CURL_LIBS)
-        AC_SUBST(CURL_LDFLAGS)
-    fi
-fi
-CPPFLAGS="$CPPFLAGS_SAVE"
-CXXFLAGS="$CXXFLAGS_SAVE"
-LDFLAGS="$LDFLAGS_SAVE"
-
-######## ffmpeg or extractor?
-
-FFMPEG_STATUS=
-
-MT_OPTION([ffmpeg], [disable],
-          [metadata extraction with the help of ffmpeg],[],[])
-
-######## ffmpeg
-
-if test "x$FFMPEG_OPTION_ENABLED" = "xyes"; then
-    AVFORMAT_STATUS="no"
-    PKG_CHECK_MODULES([AVFORMAT], [libavformat >= 54.29.104 ],
-        [
-            AVFORMAT_STATUS="yes"
-        ],
-        [
-            if test "x$FFMPEG_OPTION_REQUESTED" = "xyes"; then
-                AC_MSG_ERROR([$AVFORMAT_PKG_ERRORS])
-            else
-                AC_MSG_WARN([$AVFORMAT_PKG_ERRORS])
-            fi
-        ])
-    AVUTIL_STATUS="no"
-    PKG_CHECK_MODULES([AVUTIL], [libavutil >= 51.73.101 ],
-        [
-            AVUTIL_STATUS="yes"
-        ],
-        [
-            if test "x$FFMPEG_OPTION_REQUESTED" = "xyes"; then
-                AC_MSG_ERROR([$AVUTIL_PKG_ERRORS])
-            else
-                AC_MSG_WARN([$AVUTIL_PKG_ERRORS])
-            fi
-        ])
-
-    if (test "x$AVFORMAT_STATUS" == "xyes") &&
-       (test "x$AVUTIL_STATUS" == "xyes"); then
-            AC_DEFINE([HAVE_FFMPEG], [1], [ffmpeg libavformat is available])
-            FFMPEG_STATUS="yes"
-    else
-            FFMPEG_STATUS="missing"
-    fi
-fi
-
-FFMPEGTHUMBNAILER_USES_OLD_API=
-
-MT_CHECK_OPTIONAL_PACKAGE([ffmpegthumbnailer], [disable], 
-        [compile with ffmpegthumbnailer support for video thumbnail generation],
-        [libffmpegthumbnailer/videothumbnailerc], 
-        [ffmpegthumbnailer], [video_thumbnailer_create], [pass])
-
-if (test "x$FFMPEGTHUMBNAILER_STATUS" != xyes); then
-    MT_CHECK_OPTIONAL_PACKAGE([ffmpegthumbnailer], [disable], 
-        [compile with ffmpegthumbnailer support for video thumbnail generation],
-        [libffmpegthumbnailer/videothumbnailerc], 
-        [ffmpegthumbnailer], [create_thumbnailer])
-
-    if (test "x$FFMPEGTHUMBNAILER_STATUS" = xyes); then
-        AC_DEFINE([FFMPEGTHUMBNAILER_OLD_API], [1], [use ffmpegthumbnailer API])
-        FFMPEGTHUMBNAILER_USES_OLD_API=yes
-    fi
-fi
-
-if ((test "x$FFMPEG_STATUS" != xyes) && (test "x$FFMPEGTHUMBNAILER_STATUS" = xyes)); then
-    if test "x$FFMPEGTHUMBNAILER_OPTION_REQUESTED" = xyes; then
-      AC_MSG_ERROR([ffmpeg libraries are required in order to use ffmpegthumbnailer])
-    else
-      AC_MSG_WARN([ffmpegthumbnailer disabled: ffmpeg libraries required])
-      FFMPEGTHUMBNAILER_STATUS="disabled"
-      FFMPEGTHUMBNAILER_CFLAGS=""
-      FFMPEGTHUMBNAILER_LDFLAGS=""
-      FFMPEGTHUMBNAILER_LIBS=""
-    fi
-
-fi
-CXXFLAGS="$CXXFLAGS_SAVE"
-LDFLAGS="$LDFLAGS_SAVE"
-CPPFLAGS="$CPPFLAGS_SAVE"
-
-######## lastfm
-LASTFMLIB_STATUS="no"
-if test "x$LASTFM_OPTION_ENABLED" = "xyes"; then
-    PKG_CHECK_MODULES([LASTFMLIB], [liblastfmlib],
-        [
-            AC_DEFINE([HAVE_LASTFMLIB], [1], [liblastfmlib is available])
-            LASTFMLIB_STATUS="yes"
-        ],
-        [
-            if test "x$LASTFM_OPTION_REQUESTED" = "xyes"; then
-                AC_MSG_ERROR([$LASTFMLIB_PKG_ERRORS])
-            else
-                AC_MSG_WARN([$LASTFMLIB_PKG_ERRORS])
-            fi
-        ])
-fi
-
-######## libexif
-
-MT_CHECK_OPTIONAL_PACKAGE([libexif], [disable], 
-             [compile with libexif for exif thumbnail and metadata extraction], 
-             [libexif/exif-content], [exif], [exif_data_new_from_file])
-
-if test "x$LIBEXIF_STATUS" = xyes; then
-    CFLAGS="$CFLAGS $LIBEXIF_CFLAGS"
-    CXXFLAGS="$CXXFLAGS $LIBEXIF_CFLAGS"
-    LDFLAGS="$LDFLAGS $LIBEXIF_LDFLAGS $LIBEXIF_LIBS"
-
-    # try 1 argument signature
-    AC_MSG_CHECKING([exif_entry_get_value signature])
-    AC_COMPILE_IFELSE(
-        [AC_LANG_PROGRAM(
-            [
-                #include <libexif/exif-data.h>
-                #include <libexif/exif-content.h>
-            ],
-            [
-                (void)exif_entry_get_value(0);
-            ]
-        )],
-        [
-            AC_MSG_RESULT([requires 1 argument])
-            EXIF_EGV_1=yes
-        ],
-        [
-            # try 3 argument signature
-            AC_COMPILE_IFELSE(
-                [AC_LANG_PROGRAM(
-                    [
-                        #include <libexif/exif-data.h>
-                        #include <libexif/exif-content.h>
-                    ],
-                    [
-                        (void)exif_entry_get_value(0, 0, 0);
-                    ]
-                )],
-                [
-                    AC_MSG_RESULT([requires 3 arguments])
-                    EXIF_EGV_3=yes
-                ],
-                [
-                    AC_MSG_RESULT([unsupported, disabling])
-                    EXIF_OK="disabled (unsupported version)"
-                ]
-            )
-        ]
-    )
-
-    if test "x$EXIF_EGV_1" = xyes; then
-        AC_DEFINE([EXIF_EGV_1], [1], [exif_entry_get_value() has 1 parameter])
-    fi
-    if test "x$EXIF_EGV_3" = xyes; then
-        AC_DEFINE([EXIF_EGV_3], [1], [exif_entry_get_value() has 3 parameters])
-    fi
-fi
-
-LDFLAGS="$LDFLAGS_SAVE"
-CFLAGS="$CFLAGS_SAVE"
-CXXFLAGS="$CXXFLAGS_SAVE"
-
-######## expat
-
-MT_CHECK_REQUIRED_PACKAGE([expat], [expat], [expat], [XML_ParserCreate])
-
-####### libmp4v2
-
-MP4_HEADER="mp4"
-
-# prefer newer mp4v2
-MT_CHECK_HEADER([libmp4v2], [mp4v2/mp4v2], [pass])
-
-if test "x$LIBMP4V2_STATUS" = xyes; then
-    MP4_HEADER="mp4v2/mp4v2"
-fi
-
-LIBMP4V2_STATUS=
-
-MT_CHECK_OPTIONAL_PACKAGE([libmp4v2], [disable],
-                 [libmp4v2 support for mp4 metadata extraction],
-                 [$MP4_HEADER], [mp4v2], [MP4Read], [], [], [undef]) 
-
-if test "x$LIBMP4V2_STATUS" = xyes; then
-   CFLAGS="$CFLAGS $LIBMP4V2_CFLAGS"
-   CXXFLAGS="$CXXFLAGS $LIBMP4V2_CFLAGS"
-   LDFLAGS="$LDFLAGS $LIBMP4V2_LDFLAGS $LIBMP4V2_LIBS"
-   AC_DEFINE_UNQUOTED([LIBMP4V2_INCLUDE], [<$MP4_HEADER.h>], [$MP4_HEADER.h])
-   AC_LANG_SAVE
-   AC_LANG_CPLUSPLUS
-   AC_MSG_CHECKING([for libmp4v2 compatibility])
-   AC_COMPILE_IFELSE(
-        [AC_LANG_PROGRAM(
-            [
-                #include <$MP4_HEADER.h>
-            ],
-            [
-                (void)MP4GetMetadataName(0, 0);
-            ]
-        )],
-        [
-            AC_MSG_RESULT([yes])
-            AC_DEFINE([HAVE_LIBMP4V2], [1], [libmp4v2 library presence])
-        ],
-        [
-            AC_MSG_RESULT([not compatible])
-            if test "x$LIBMP4V2_OPTION_REQUESTED" = "xyes"; then
-                AC_MSG_ERROR([Unable to configure libmp4v2 support])
-            else
-                LIBMP4V2_STATUS="not compatible"
-            fi
-        ])
-    LDFLAGS="$LDFLAGS_SAVE"
-    CFLAGS="$CFLAGS_SAVE"
-    CXXFLAGS="$CXXFLAGS_SAVE"
-fi
-
-if test "x$LIBMP4V2_STATUS" = "xyes"; then
-   CFLAGS="$CFLAGS $LIBMP4V2_CFLAGS"
-   CXXFLAGS="$CXXFLAGS $LIBMP4V2_CFLAGS"
-   LDFLAGS="$LDFLAGS $LIBMP4V2_LDFLAGS $LIBMP4V2_LIBS"
-   AC_MSG_CHECKING([for MP4GetMetadataCoverArtCount() in libmp4v2])
-   AC_COMPILE_IFELSE(
-        [AC_LANG_PROGRAM(
-            [
-                #include <$MP4_HEADER.h>
-            ],
-            [
-                (void)MP4GetMetadataCoverArtCount(0);
-            ]
-        )],
-        [
-            AC_MSG_RESULT([yes])
-            AC_DEFINE([HAVE_MP4_GET_METADATA_COVER_ART_COUNT], [1],
-                      [this version of libmp4v2 has MP4GetMetadataCoverArtCount() support])
-        ],
-        [
-            AC_MSG_RESULT([no])
-        ])
-
-   AC_MSG_CHECKING([for MP4GetTrackAudioChannels() in libmp4v2])
-   AC_COMPILE_IFELSE(
-        [AC_LANG_PROGRAM(
-            [
-                #include <$MP4_HEADER.h>
-            ],
-            [
-                (void)MP4GetTrackAudioChannels(0, 0);
-            ]
-        )],
-        [
-            AC_MSG_RESULT([yes])
-            AC_DEFINE([HAVE_MP4_GET_TRACK_AUDIO_CHANNELS], [1],
-                      [this version of libmp4 has MP4GetTrackAudioChannels support])
-        ],
-        [
-            AC_MSG_RESULT([no])
-        ])
-
-    AC_LANG_RESTORE
-    LDFLAGS="$LDFLAGS_SAVE"
-    CFLAGS="$CFLAGS_SAVE"
-    CXXFLAGS="$CXXFLAGS_SAVE"
-fi
-
-########## INOTIFY TOOLS
-
-MT_OPTION([inotify], [disable], [inotify support for imporved autoscan], [], 
-          [INOTIFY_STATUS=disabled])
-
-if test "x$INOTIFY_OPTION_ENABLED" = xyes; then
-    MT_CHECK_HEADER([inotify], [sys/inotify])
-fi
-
-if test "x$INOTIFY_STATUS" = xyes; then
-    AC_CHECK_FUNCS([inotify_init], [], [INOTIFY_STATUS=missing])
-fi
-
-if test "x$INOTIFY_STATUS" = xyes; then
-dnl The check below was inspired by configure.ac from the inotify tools
-dnl package, see the "Acknowledgements" section in our README file for more 
-dnl information.
-    CXXFLAGS="$CXXFLAGS $INOTIFY_CFLAGS"
-    CFLAGS="$CFLAGS $INOTIFY_CFLAGS"
-    AC_MSG_CHECKING([whether sys/inotify.h works])
-    AC_RUN_IFELSE(
-    [
-        AC_LANG_PROGRAM(
-            [[ #include <sys/inotify.h> ]],
-            [[ return (-1 == inotify_init()); ]]
-        )
-    ],
-    [
-        AC_MSG_RESULT([yes]); 
-        AC_DEFINE([SYS_INOTIFY_H_OK],[1],[sys/inotify.h exists and works on this system])],
-    [
-        AC_MSG_RESULT([no, using own inotify headers])
-        AC_MSG_CHECKING([whether inotify-nosys.h works on this system])
-        AC_RUN_IFELSE(
-        [
-            AC_LANG_PROGRAM(
-                [[ #include "src/inotify-nosys.h" ]],
-                [[ return (-1 == inotify_init()); ]]
-            )
-        ],
-        [
-            AC_MSG_RESULT([yes]);
-        ],
-        [
-            if ((test "x$INOTIFY_OPTION_REQUESTED" != xyes) &&
-                (test "x$INOTIFY_OPTION_ENABLED" = xyes)); then
-                AC_MSG_RESULT([no, disabling inotify support])
-            elif ((test "x$INOTIFY_OPTION_REQUESTED" != xyes) &&
-               (test "x$INOTIFY_OPTION_ENABLED" != xyes)); then
-                AC_MSG_RESULT([no])
-            fi
-                INOTIFY_STATUS=no
-        ],
-        [
-            if ((test "x$INOTIFY_OPTION_REQUESTED" = xyes) &&
-                (test "x$INOTIFY_OPTION_ENABLED" = xyes)); then
-                AC_MSG_RESULT([selecting yes for cross compiling]) 
-                INOTIFY_STATUS=yes
-            else
-                AC_MSG_RESULT([selecting no for cross compiling]) 
-                INOTIFY_STATUS=no
-            fi
-        ])
-    ],
-    [
-        if ((test "x$INOTIFY_OPTION_REQUESTED" = xyes) &&
-            (test "x$INOTIFY_OPTION_ENABLED" = xyes)); then
-           AC_MSG_RESULT([selecting yes for cross compiling]) 
-           INOTIFY_STATUS=yes
-        else
-           AC_MSG_RESULT([selecting no for cross compiling]) 
-           INOTIFY_STATUS=no
-        fi
-    ])
-fi
-
-if test "x$INOTIFY_STATUS" = xyes; then
-    AC_DEFINE([HAVE_INOTIFY], [1], [inotify presence])
-    AC_SUBST(INOTIFY_CFLAGS)
-else
-    if ((test "x$INOTIFY_OPTION_REQUESTED" = xyes) &&
-        (test "x$INOTIFY_OPTION_ENABLED" = xyes)); then
-        AC_MSG_NOTICE([enabling runtime inotify detection])
-        # if system inotify header exists, go with it, otherwise take our own
-        if test "x$ac_cv_header_sys_inotify_h" = xyes; then
-             AC_DEFINE([SYS_INOTIFY_H_OK],[1],[sys/inotify.h exists])
-        fi
-        AC_DEFINE([HAVE_INOTIFY], [1], [inotify presence])
-        AC_SUBST(INOTIFY_CFLAGS)
-        INOTIFY_STATUS=yes
-    fi
-fi
-
-LDFLAGS="$LDFLAGS_SAVE"
-CPPFLAGS="$CPPFLAGS_SAVE"
-CXXFLAGS="$CXXFLAGS_SAVE"
-
-AC_DEFINE([__STDC_CONSTANT_MACROS], [1], [needed for stdint.h])
-AC_DEFINE([__STDC_LIMIT_MACROS], [1], [needed for stdint.h])
-
-#MT_CHECK_OPTIONAL_PACKAGE_CFG([libdvdnav], [enable],
-#             [compile with libdvdnav support for extended DVD image parsing],
-#             [dvdnav-config],
-#             [dvdnav/dvdnav.h], [dvdnav], [dvdnav_get_audio_attr], [])
-#
-
-MT_OPTION([tombdebug], [enable], [enable debug code for MediaTomb],
-          [
-            AC_DEFINE(TOMBDEBUG, 1, [if defined compile with debug log output])
-          ],
-          [])
-
-MT_OPTION([upnpdebug], [enable], [enable debug output for TombUPnP/libupnp],
-          [
-            AC_DEFINE(UPNP_HAVE_DEBUG, 1, [see upnpconfig.h])
-            AC_DEFINE(DEBUG, 1, [Define to 1 to compile debug code])
-          ],
-          [])
-
-if (test "x$TOMBDEBUG_OPTION_ENABLED" != xyes) && 
-   (test "x$UPNPDEBUG_OPTION_ENABLED" != xyes); then
-    AC_DEFINE(NDEBUG, 1, [make sure there are no asserts in the retail build])
-fi
-
-MT_OPTION([log], [disable], [disable all console output],
-          [
-            AC_DEFINE(LOG_ENABLED, 1, [if defined compile with log output])
-          ],
-          [])
-
-MT_OPTION([debug-log], [disable], [compile without debug messages],
-          [
-            AC_DEFINE(DEBUG_LOG_ENABLED, 1, [compile with debug messages])
-          ],
-          [])
-
-
-eval PACKAGE_DATADIR="${datadir}/${PACKAGE}"
-eval PACKAGE_DATADIR="${PACKAGE_DATADIR}"
-AC_DEFINE_UNQUOTED(PACKAGE_DATADIR, "$PACKAGE_DATADIR", [MediaTomb data directory])
-
-if (test "x$YOUTUBE_OPTION_ENABLED" = xyes) || (test "x$WEBORAMA_OPTION_ENABLED" = xyes) || (test "x$ATRAILERS_OPTION_ENABLED" = xyes) || (test "x$SOPCAST_OPTION_ENABLED" = xyes); then
-    AC_DEFINE(ONLINE_SERVICES, 1, [at least one online service is supported])
-fi
-
-if (test "x$YOUTUBE_OPTION_ENABLED" = xyes); then
-    AC_DEFINE([YOUTUBE], [1], [Enable support for the YouTube service])
-fi
-
-if (test "x$WEBORAMA_OPTION_ENABLED" = xyes); then
-    AC_DEFINE([WEBORAMA], [1], [Enable support for the Weborama service])
-fi
-
-if (test "x$ATRAILERS_OPTION_ENABLED" = xyes); then
-    AC_DEFINE([ATRAILERS], [1], [Enable support for the apple trailers])
-fi
-
-if (test "x$SOPCAST_OPTION_ENABLED" = xyes); then
-    AC_DEFINE([SOPCAST], [1], [Enable support for the SopCast service])
-fi
-
-AC_DEFINE_UNQUOTED([COMPILE_INFO], "\thost:\t\t\t$host\n\tsqlite3:\t\t$SQLITE3_STATUS\n\tmysql:\t\t\t$MYSQL_STATUS\n\tlibjs:\t\t\t$JS_OK\n\tlibmagic:\t\t$LIBMAGIC_STATUS\n\tinotify:\t\t$INOTIFY_STATUS\n\tlibexif:\t\t$LIBEXIF_STATUS\n\tid3lib:\t\t\t$ID3LIB_STATUS\n\ttaglib:\t\t\t$TAGLIB_STATUS\n\tFLAC:\t\t\t$FLAC_STATUS\n\tffmpeg\t\t\t$FFMPEG_STATUS\n\tlibmp4v2:\t\t$LIBMP4V2_STATUS\n\texternal transcoding:\t$EXTERNAL_TRANSCODING_OPTION_ENABLED\n\tcurl:\t\t\t$CURL_OK\n\tYouTube:\t\t$YOUTUBE_OPTION_ENABLED\n\tlibextractor\t\t$LIBEXTRACTOR_STATUS\n\tdb-autocreate:\t\t$DB_AUTOCREATE_OPTION_ENABLED\n\tdebug log:\t\t$DEBUG_LOG_OPTION_ENABLED\n\tprotocol info extension:$PROTOCOLINFO_EXTENSION_OPTION_ENABLED\n\tffmpegthumbnailer:\t$FFMPEGTHUMBNAILER_STATUS\n\tlastfmlib:\t\t$LASTFMLIB_STATUS\n\tdata directory:\t\t$PACKAGE_DATADIR", [compile option summary])
-
-###############
-AC_CONFIG_FILES([
-    Makefile
-    build/Makefile
-    doc/Makefile
-    scripts/Makefile
-    scripts/js/Makefile
-    scripts/mediatomb-service-optware
-    tombupnp/Makefile
-    tombupnp/build/Makefile
-    web/Makefile
-    config/Makefile
-    artwork/Makefile
-    mediatomb.spec
-])
-
-AC_OUTPUT
-
-echo
-echo "CONFIGURATION SUMMARY ----"
-#                        disabled
-echo
-echo "sqlite3               : $SQLITE3_STATUS"
-echo "mysql                 : $MYSQL_STATUS"
-echo "libjs                 : $JS_STATUS"
-echo "libmagic              : $LIBMAGIC_STATUS"
-echo "inotify               : $INOTIFY_STATUS"
-echo "libexif               : $LIBEXIF_STATUS"
-echo "expat                 : $EXPAT_STATUS"
-echo "id3lib                : $ID3LIB_STATUS"
-echo "taglib                : $TAGLIB_STATUS"
-echo "FLAC                  : $FLAC_STATUS"
-echo "libmp4v2              : $LIBMP4V2_STATUS"
-echo "ffmpeg                : $FFMPEG_STATUS"
-echo "ffmpegthumbnailer     : $FFMPEGTHUMBNAILER_STATUS"
-echo "lastfmlib             : $LASTFMLIB_STATUS"
-echo "external transcoding  : $EXTERNAL_TRANSCODING_OPTION_ENABLED"
-echo "curl                  : $CURL_FOUND"
-echo "YouTube               : $YOUTUBE_OPTION_ENABLED"
-#echo "Weborama              : $WEBORAMA_OPTION_ENABLED"
-echo "db-autocreate         : $DB_AUTOCREATE_OPTION_ENABLED"
-        
-if test "x$TOMBDEBUG_OPTION_ENABLED" = xyes; then
-    echo "debug log             : $TOMBDEBUG_OPTION_ENABLED"
-fi
-
-if test "x$UPNPDEBUG_OPTION_ENABLED" = xyes; then
-    echo "upnpdebug             : $UPNPDEBUG_OPTION_ENABLED"
-fi
-
-if test "x$STATIC_OPTION_ENABLED" = xyes; then
-    echo "static build          : $STATIC_OPTION_ENABLED"
-fi
-
-echo
-
diff --git a/devconf b/devconf
deleted file mode 100755
index d6537c4..0000000
--- a/devconf
+++ /dev/null
@@ -1 +0,0 @@
-./configure CFLAGS="-g -O0 -Wall" CXXFLAGS="-g -O0 -Wall" --enable-tombdebug $@
diff --git a/doc/Makefile.am b/doc/Makefile.am
deleted file mode 100644
index 8c103da..0000000
--- a/doc/Makefile.am
+++ /dev/null
@@ -1,16 +0,0 @@
-
-_DIST_FILES_CONF = \
-    doxygen.conf \
-    scripting.txt \
-    scripting_utf8.txt \
-    transcoding.txt \
-    transcoding_utf8.txt \
-    ui.txt \
-    ui_utf8.txt \
-    manpage.xml
-
-man1_MANS=mediatomb.1
-
-EXTRA_DIST = $(_DIST_FILES_CONF) $(man1_MANS)
-
-
diff --git a/doc/mediatomb.1 b/doc/gerbera.1
similarity index 58%
rename from doc/mediatomb.1
rename to doc/gerbera.1
index 7d45e62..f564e05 100644
--- a/doc/mediatomb.1
+++ b/doc/gerbera.1
@@ -1,23 +1,24 @@
-.\"     Title: MEDIATOMB
+.\"     Title: GERBERA
 .\"    Author: <collabname>Sergey Bostandzhyan</collabname>
 .\" Generator: DocBook XSL Stylesheets v1.73.2 <http://docbook.sf.net/>
 .\"      Date: 2008-02-23
+.\"      Date: 2017-03-26 updated for Gerbera
 .\"    Manual: User commands
-.\"    Source: MediaTomb 0.11.0
+.\"    Source: Gerbera 1.0.0 & up
 .\"
-.TH "MEDIATOMB" "1" "2008\-02\-23" "MediaTomb 0.11.0" "User commands"
+.TH "GERBERA" "1" "2017\-03\-26" "GERBERA" "User commands"
 .\" disable hyphenation
 .nh
 .\" disable justification (adjust text to left margin only)
 .ad l
 .SH "NAME"
-mediatomb - UPnP MediaServer
+gerbera - UPnP Media Server
 .SH "SYNOPSIS"
 .HP 10
-\fBmediatomb\fR [\fB\-i\ \fR\fB\fIIP\ address\fR\fR\fB\ \fR] [\fB\-e\ \fR\fB\fIinterface\fR\fR\fB\ \fR] [\fB\-p\ \fR\fB\fIport\fR\fR\fB\ \fR] [\fB\-c\ \fR\fB\fIconfig\ file\fR\fR\fB\ \fR] [\fB\-d\fR] [\fB\-m\ \fR\fB\fIhome\ dir\fR\fR\fB\ \fR] [\fB\-f\ \fR\fB\fIconfig\ dir\fR\fR\fB\ \fR] [\fB\-P\ \fR\fB\fIPID\ file\fR\fR\fB\ \fR] [\fB\-u\ \fR\fB\fIuser\fR\fR\fB\ \fR] [\fB\-g\ \fR\fB\fIgroup\fR\fR\fB\ \fR] [\fB\-a\ \fR\fB\fIpath\fR\fR\fB\ \fR] [\fB\-l\ \fR\fB\fIlogfile\fR\fR\fB\ \fR] [\fB\-D\fR] [\fB\-\-compile\-info\fR] [\fB\-\-version\fR] [\fB\-h\fR]
+\fBgerbera\fR [\fB\-i\ \fR\fB\fIIP\ address\fR\fR\fB\ \fR] [\fB\-e\ \fR\fB\fIinterface\fR\fR\fB\ \fR] [\fB\-p\ \fR\fB\fIport\fR\fR\fB\ \fR] [\fB\-c\ \fR\fB\fIconfig\ file\fR\fR\fB\ \fR] [\fB\-d\fR] [\fB\-m\ \fR\fB\fIhome\ dir\fR\fR\fB\ \fR] [\fB\-f\ \fR\fB\fIconfig\ dir\fR\fR\fB\ \fR] [\fB\-P\ \fR\fB\fIPID\ file\fR\fR\fB\ \fR] [\fB\-u\ \fR\fB\fIuser\fR\fR\fB\ \fR] [\fB\-g\ \fR\fB\fIgroup\fR\fR\fB\ \fR] [\fB\-a\ \fR\fB\fIpath\fR\fR\fB\ \fR] [\fB\-l\ \fR\fB\fIlogfile\fR\fR\fB\ \fR] [\fB\-D\fR] [\fB\-\-compile\-info\fR] [\fB\-\-version\fR] [\fB\-h\fR]
 .SH "DESCRIPTION"
 .PP
-This manual page describes the command line parameters for MediaTomb\. For a detailed documentation please see the README file which is distributed with MediaTomb or visit http://mediatomb\.cc/\.
+This manual page describes the command line parameters for Gerbera\. For a detailed documentation please see the README file which is distributed with Gerbera or visit https://gerbera.io/\.
 .SH "OPTIONS"
 .PP
 \fB\-i\fR, \fB\-\-ip\fR
@@ -37,24 +38,24 @@ Specify the server port that will be used for the web user interface, for servin
 .PP
 \fB\-c\fR, \fB\-\-config\fR
 .RS 4
-By default MediaTomb will search for a file named "config\.xml" in the ~/\.mediatomb directory\. This option allows you to specify a config file by the name and location of your choice\. The file name must be absolute\.
+By default Gerbera will search for a file named "config\.xml" in the ~/\.gerbera directory\. This option allows you to specify a config file by the name and location of your choice\. The file name must be absolute\.
 .RE
 .PP
 \fB\-d\fR, \fB\-\-daemon\fR
 .RS 4
-Run the server in background, MediaTomb will shutdown on SIGTERM, SIGINT and restart on SIGHUP\.
+Run the server in background, Gerbera will shutdown on SIGTERM, SIGINT and restart on SIGHUP\.
 .RE
 .PP
 \fB\-m\fR, \fB\-\-home\fR
 .RS 4
-Specify an alternative home directory\. By default MediaTomb will try to retrieve the users home directory from the environment, then it will look for a \.mediatomb directory in users home\. If \.mediatomb was found we will try to find the default configuration file (config\.xml), if not found we will create both, the \.mediatomb directory and the default config file\.
+Specify an alternative home directory\. By default Gerbera will try to retrieve the users home directory from the environment, then it will look for a \.mediatomb directory in users home\. If \.gerbera was found we will try to find the default configuration file (config\.xml), if not found we will create both, the \.gerbera directory and the default config file\.
 .sp
 This option is useful in two cases: when the home directory can not be retrieved from the environment (in this case you could also use \-c to point MediaTomb to your configuration file or when you want to create a new configuration in a non standard location (for example, when setting up daemon mode)\. In the latter case you can combine this parameter with the parameter described in Section 5\.6, "Config Directory"
 .RE
 .PP
 \fB\-f\fR, \fB\-\-cfgdir\fR
 .RS 4
-The default configuration directory is combined out of the users home and the default that equals to \.mediatomb, this option allows you to override the default directory naming\. This is useful when you want to setup the server in a nonstandard location, but want that the default configuration to be written by the server\.
+The default configuration directory is combined out of the users home and the default that equals to \.gerbera, this option allows you to override the default directory naming\. This is useful when you want to setup the server in a nonstandard location, but want that the default configuration to be written by the server\.
 .RE
 .PP
 \fB\-P\fR, \fB\-\-pidfile\fR
@@ -64,12 +65,12 @@ Specify a file that will hold the server process ID, the filename must be absolu
 .PP
 \fB\-u\fR, \fB\-\-user\fR
 .RS 4
-Run MediaTomb under the specified user name, this is especially useful in combination with the daemon mode\.
+Run Gerbera under the specified user name, this is especially useful in combination with the daemon mode\.
 .RE
 .PP
 \fB\-g\fR, \fB\-\-group\fR
 .RS 4
-Run MediaTomb under the specified group, this is especially useful in combination with the daemon mode\.
+Run Gerbera under the specified group, this is especially useful in combination with the daemon mode\.
 .RE
 .PP
 \fB\-a\fR, \fB\-\-add\fR
@@ -112,7 +113,7 @@ Copyright \(co 2005 Gena Batsyan, Sergey Bostandzhyan
 Copyright \(co 2006-2008 Gena Batsyan, Sergey Bostandzhyan, Leonhard Wimmer
 .br
 .PP
-This manual page is part of MediaTomb\.
+This manual page is part of Gerbera\.
 .PP
 Permission is granted to copy, distribute and/or modify this document under the terms of the
 GNU
diff --git a/doc/scripting_utf8.txt b/doc/scripting_utf8.txt
deleted file mode 100644
index 6472753..0000000
--- a/doc/scripting_utf8.txt
+++ /dev/null
@@ -1,1580 +0,0 @@
-MediaTomb Scripting
-
-   This documentation is valid for MediaTomb version 0.12.1.
-
-   Copyright © 2005 Gena Batsyan, Sergey Bostandzhyan
-
-   Copyright © 2006-2010 Gena Batsyan, Sergey Bostandzhyan,
-   Leonhard Wimmer
-
-   THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR
-   OWN RISK!
-     __________________________________________________________
-
-   Table of Contents
-
-   1. Introduction
-   2. How It Works
-
-        2.1. Understanding Virtual Objects.
-        2.2. Theory Of Operation
-
-   3. Global Variables And Constants
-
-        3.1. The Media Object
-        3.2. Constants
-
-   4. Functions
-
-        4.1. Native Server Functions
-        4.2. Helper Functions
-
-   5. Walkthrough
-
-        5.1. Import Script
-        5.2. Playlist Script
-        5.3. DVD Import Script
-
-1. Introduction
-
-   MediaTomb allows you to customize the structure of how your
-   media is being presented to your renderer. One of the most
-   important features introduced since the version 0.8 are the
-   virtual containers and virtual items. Let's think of possible
-   scenarios:
-     * you may want to separate your content by music, photo,
-       video, maybe create a special container with all non
-       playable stuff
-     * you may want your music to be sorted by genre, year,
-       artist, album, or maybe by starting letters, so you can
-       more easily find your favorite song when browsing the
-       server
-     * you want to have your photos that you took with your
-       favorite digital camera to appear in a special folder, or
-       maybe you even want to separate the photos that you took
-       with flash-on from the ones that you made without flash
-     * your media player does not support video, so you do not
-       even want to see the Video container
-     * it's up to your imagination :)
-
-   The scenarios described above and much more can be achieved
-   with the help of an import script.
-
-   Version 0.10.0 introduces a playlist parsing feature, which is
-   also handled by scripting and version 0.12.0 adds a script for
-   creating a virtual layout out of a DVD iso image.
-
-2. How It Works
-
-   This section will give you some overview on how virtual objects
-   work and on how they are related to scripting.
-
-   NOTE:
-          In order to use the import scripting feature you have to
-          change the layout type from builtin to js in config.xml
-          !
-
-   NOTE:
-          The sorting of Video and Photo items using the
-          “rootpath” object is still somewhat experimental and not
-          described here.
-
-2.1. Understanding Virtual Objects.
-
-   When you add a file or directory to the database via the web
-   interface several things happen.
-    1. The object is inserted into the PC Directory. PC Directory
-       is simply a special non-removable container. Any media file
-       added will have an entry inside the PC Directory tree. PC
-       Directory's hierarchy reflects the file system hierarchy,
-       all objects inside the PC Directory including itself are
-       NON-VIRTUAL objects. All virtual objects may have a
-       different title, description, etc., but they are still
-       references to objects in the PC-Directory. That's why it is
-       not possible to change a location of a virtual object - the
-       only exceptions are URL items and Active items.
-    2. Once an item is added to the PC Directory it is forwarded
-       to the virtual object engine. The virtual object engine's
-       mission is to organize and present the media database in a
-       logical hierarchy based on the available metadata of the
-       items.
-
-   Each UPnP server implements this so called virtual object
-   hierarchy in a different way. Audio files are usually sorted by
-   artist, album, some servers may just present a view similar to
-   the file system and so on. Most servers have strong limitations
-   on the structure of the virtual containers, they usually offer
-   a predefined layout of data and the user has to live with it.
-   In MediaTomb we try to address this shortcoming by introducing
-   the scriptable virtual object engine. It is designed to be:
-     * maximally flexible
-     * easily customizable and extendable
-     * robust and efficient
-
-   We try to achieve these goals by embedding a scripting runtime
-   environment that allows the execution of ECMAScript-262 conform
-   scripts better known as JavaScript. We are using Mozilla's
-   JavaScript implementation called SpiderMonkey, it is a
-   stand-alone easily embeddable javascript engine, supporting
-   JavaScript versions 1.0 through 1.4.
-
-2.2. Theory Of Operation
-
-   After an item is added to the PC Directory it is automatically
-   fed as input to the import script. The script then creates one
-   or more virtual items for the given original item. Items
-   created from scripts are always marked virtual.
-
-   When the virtual object engine gets notified of an added item,
-   following happens: a javascript object is created mirroring the
-   properties of the item. The object is introduced to the script
-   environment and bound to the predefined variable 'orig'. This
-   way a variable orig is always defined for every script
-   invocation and represents the original data of the added item.
-   Then the script is invoked.
-
-   In the current implementation, if you modify the script then
-   you will have to restart the server for the new logic to take
-   effect. Note, that the script is only triggered when new
-   objects are added to the database, also note that the script
-   does not modify any objects that already exist in the database
-   - it only processes new objects that are being added. When a
-   playlist item is encountered, it is automatically fed as input
-   to the playlist script. The playlist script attempts to parse
-   the playlist and adds new item to the database, the item is
-   then processed by the import script.
-
-3. Global Variables And Constants
-
-   In this section we will introduce the properties of the object
-   that will be processed by the script, as well as functions that
-   are offered by the server.
-
-3.1. The Media Object
-
-   As described in Section 2.2, each time an item is added to the
-   database the import script is invoked. So, one script
-   invocation processes exactly one non virtual item, and creates
-   a number of virtual items and containers. The original item is
-   made available in the form of the global variable 'orig'.
-   Additionally, when the object being imported is a playlist, it
-   is made available to the playlist parser script in the form of
-   the global variable 'playlist'. It is usually a good idea to
-   only read from these variables and to create and only modify
-   local copies.
-
-   Note:
-          modifying the properties of the orig object will not
-          propagate the changes to the database, only a call to
-          the addCdsObject() will permanently add the object.
-
-3.1.1. General Properties
-
-   Here is a list of properties of an object, you can set them you
-   create a new object or when you modify a copy of the 'orig'
-   object.
-
-   RW means read/write, i.e. - changes made to that property will
-   be transferred into the database.
-
-   RO means, that this is a read only property, any changes made
-   to it will get lost.
-     *
-orig.objectType
-
-       RW
-       This defines the object type, following types are
-       available:
-          +
-OBJECT_TYPE_CONTAINER
-
-            Object is a container.
-          +
-OBJECT_TYPE_ITEM
-
-            Object is an item.
-          +
-OBJECT_TYPE_ACTIVE_ITEM
-
-            Object is an active item.
-          +
-OBJECT_TYPE_ITEM_EXTERNAL_URL
-
-            Object is a link to a resource on the Internet.
-          +
-OBJECT_TYPE_ITEM_INTERNAL_URL
-
-            Object is an internal link.
-     *
-orig.title
-
-       RW
-       This is the title of the original object, since the object
-       represents an entry in the PC-Directory, the title will be
-       set to it's file name. This field corresponds to dc:title
-       in the DIDL-Lite XML.
-     *
-orig.id
-
-       RO
-       The object ID, make sure to set all refID's (reference IDs)
-       of your virtual objects to that ID.
-     *
-orig.parentID
-
-       RO
-       The object ID of the parent container.
-     *
-orig.upnpclass
-
-       RW
-       The UPnP class of the item, this corresponds to upnp:class
-       in the DIDL-Lite XML.
-     *
-orig.location
-
-       RO
-       Location on disk, given by the absolute path and file name.
-     *
-orig.theora
-
-       RO
-       This property is a boolean value, it is non zero if the
-       particular item is of type OGG Theora. This is useful to
-       allow proper sorting of media and thus placing OGG Vorbis
-       into the Audio container and OGG Theora into the Video
-       container.
-     *
-orig.onlineservice
-
-       RO
-       Identifies if the item belongs to an online service and
-       thus has extended properties. Following types are
-       available:
-          +
-ONLINE_SERVICE_NONE
-
-            The item does not belong to an online service and does
-            not have extended properties.
-          +
-ONLINE_SERVICE_YOUTUBE
-
-            The item belongs to the YouTube service and has
-            extended properties.
-          +
-ONLINE_SERVICE_WEBORAMA
-
-            The item belongs to the Weborama service and has
-            extended properties.
-          +
-ONLINE_SERVICE_APPLE_TRAILERS
-
-            The item belongs to the Apple Trailers service and has
-            extended properties.
-     *
-orig.mimetype
-
-       RW
-       Mimetype of the object.
-     *
-orig.meta
-
-       RW
-       Array holding the metadata that was extracted from the
-       object (i.e. id3/exif/etc. information)
-          +
-orig.meta[M_TITLE]
-
-            RW
-            Extracted title (for example the id3 title if the
-            object is an mp3 file), if you want that your new
-            virtual object is displayed under this title you will
-            have to set obj.title = orig.meta[M_TITLE]
-          +
-orig.meta[M_ARTIST]
-
-            RW
-            Artist information, this corresponds to upnp:artist in
-            the DIDL-Lite XML.
-          +
-orig.meta[M_ALBUM]
-
-            RW
-            Album information, this corresponds to upnp:album in
-            the DIDL-Lite XML.
-          +
-orig.meta[M_DATE]
-
-            RW
-            Date, must be in the format of YYYY-MM-DD (required by
-            the UPnP spec), this corresponds to dc:date in the
-            DIDL-Lite XML.
-          +
-orig.meta[M_GENRE]
-
-            RW
-            Genre of the item, this corresponds to upnp:genre in
-            the DIDL-Lite XML.
-          +
-orig.meta[M_DESCRIPTION]
-
-            RW
-            Description of the item, this corresponds to
-            dc:description in the DIDL-Lite XML.
-          +
-orig.meta[M_REGION]
-
-            RW
-            Region description of the item, this corresponds to
-            upnp:region in the DIDL-Lite XML.
-          +
-orig.meta[M_TRACKNUMBER]
-
-            RW
-            Track number of the item, this corresponds to
-            upnp:originalTrackNumber in the DIDL-Lite XML.
-          +
-orig.meta[M_AUTHOR]
-
-            RW
-            Author of the media, this corresponds to upnp:author
-            in the DIDL-Lite XML.
-          +
-orig.meta[M_DIRECTOR]
-
-            RW
-            Director of the media, this corresponds to
-            upnp:director in the DIDL-Lite XML.
-          +
-orig.meta[M_PUBLISHER]
-
-            RW
-            Director of the media, this corresponds to
-            dc:publisher in the DIDL-Lite XML.
-          +
-orig.meta[M_RATING]
-
-            RW
-            Director of the media, this corresponds to upnp:rating
-            in the DIDL-Lite XML.
-          +
-orig.meta[M_ACTOR]
-
-            RW
-            Director of the media, this corresponds to upnp:actor
-            in the DIDL-Lite XML.
-          +
-orig.meta[M_PRODUCER]
-
-            RW
-            Director of the media, this corresponds to
-            upnp:producer in the DIDL-Lite XML.
-     *
-orig.aux
-
-       RO
-       Array holding the so called auxiliary data. Aux data is
-       metadata that is not part of UPnP, for example - this can
-       be a camera model that was used to make a photo, or the
-       information if the photo was taken with or without flash.
-       Currently aux data can be gathered from libexif and
-       libextractor (see the Import section in the main
-       documentation for more details). So, this array will hold
-       the tags that you specified in your config.xml, allowing
-       you to create your virtual structure according to your
-       liking.
-     *
-orig.playlistOrder
-
-       RW
-       This property is only available if the object is being
-       created by the playlist script. It's similar to ID3 track
-       number, but is used to set the position of the newly
-       created object inside a parsed playlist container. Usually
-       you will increment the number for each new object that you
-       create while parsing the playlist, thus ensuring that the
-       resulting order is the same as in the original playlist.
-
-3.1.2. YouTube Properties
-
-   When the obj.onlineservice variable equals
-   ONLINE_SERVICE_YOUTUBE the item has the following additional
-   properties:
-     *
-orig.yt_request
-
-       RO
-       Identifies the YouTube request type, following types are
-       available:
-          +
-YOUTUBE_REQUEST_NONE
-
-            No request/invalid.
-          +
-YOUTUBE_REQUEST_USER_FAVORITES
-
-            The item was created as a result of a favorites
-            request.
-          +
-YOUTUBE_REQUEST_VIDEO_SEARCH
-
-            The item was created as a result of a search request.
-          +
-YOUTUBE_REQUEST_USER_UPLOADS
-
-            The item was created as a result of a request for
-            videos that were uploaded by a particular user.
-          +
-YOUTUBE_REQUEST_STANDARD_FEED
-
-            The item was created as a result of a request for one
-            of the standard feeds.
-          +
-YOUTUBE_REQUEST_USER_PLAYLISTS
-
-            The item was created as a result of a request for
-            users playlists.
-          +
-YOUTUBE_REQUEST_USER_SUBSCRIPTIONS
-
-            The item was created as a result of for users
-            subscriptions.
-
-   The following aux keys can be used to retrieve additional
-   information about the item, the data is stored in the form of
-   strings. Note, that depending on the requests some tags may not
-   be set and will return empty values.
-     *
-orig.aux[YOUTUBE_AUXDATA_KEYWORDS]
-
-       RO
-       Contains a space separated list of keywords for the
-       particular item.
-     *
-orig.aux[YOUTUBE_AUXDATA_AVG_RATING]
-
-       RO
-       Contains the average rating value.
-     *
-orig.aux[YOUTUBE_AUXDATA_AUTHOR]
-
-       RO
-       Contains the author name.
-     *
-orig.aux[YOUTUBE_AUXDATA_FEED]
-
-       RO
-       Contains the name of the feed.
-     *
-orig.aux[YOUTUBE_AUXDATA_VIEW_COUNT]
-
-       RO
-       Contains the view count of the video on the YouTube
-       website.
-     *
-orig.aux[YOUTUBE_AUXDATA_REGION]
-
-       RO
-       Contains the name of the region.
-     *
-orig.aux[YOUTUBE_AUXDATA_RATING_COUNT]
-
-       RO
-       Contains the rating count of the video on the YouTube
-       website.
-     *
-orig.aux[YOUTUBE_AUXDATA_REQUEST]
-
-       RO
-       Contains the name of the request that produced this item
-       (i.e. Favorites, Popular, etc.), this is the human readable
-       representation of the orig.yt_request property.
-     *
-orig.aux[YOUTUBE_AUXDATA_SUBREQUEST_NAME]
-
-       RO
-       Contains the additional name that accompanies the request,
-       it is only set for the playlist and subcription requests.
-     *
-orig.aux[YOUTUBE_AUXDATA_CATEGORY]
-
-       RO
-       Contains the name of the category of the item.
-
-3.1.3. Weborama Properties
-
-   When the obj.onlineservice variable equals
-   ONLINE_SERVICE_WEBORAMA the item has the following additional
-   aux property:
-orig.aux[WEBORAMA_AUXDATA_REQUEST_NAME]
-
-   This property holds the name of the request that generated this
-   object, it is the name that you specify in the config.xml file,
-   i.e. in the below example the value of
-   orig.aux[WEBORAMA_AUXDATA_REQUEST_NAME] will be 'My Playlist':
-<playlist name="My Playlist" type="playlist" mood="dark"/>
-
-3.1.4. Apple Trailers Properties
-
-   When the obj.onlineservice variable equals
-   ONLINE_SERVICE_APPLE_TRAILERS the item has the following
-   additional aux property:
-orig.aux[APPLE_TRAILERS_AUXDATA_POST_DATE]
-
-   This property holds the date when the trailer was posted, the
-   date format is YYYY-MM-DD.
-
-   Note:
-          the orig.meta[M_DATE] property holds the release date of
-          the movie.
-
-3.1.5. DVD Properties
-
-   Version 0.12.0 introduces an additional import script for DVD
-   images. The DVD image is parsed with the help of libdvdread,
-   the information about the available titles, chapters,
-   languages, etc. is gathered and provided to the DVD import
-   script. The usual object properties apply here as well, however
-   the dvd object offers several extensions that can be accessed
-   via the aux property:
-dvd.aux[DVD]
-
-     *
-dvd.aux[DVD].titles
-
-       RO
-       This is an array that contains information about titles
-       that are found on the DVD. The length of the array (and
-       thus the number of available titles can be retrieved by:
-dvd.aux[DVD].titles.length
-
-       Further, being a normal JavaScript array it supports all
-       associated JS functions.
-     *
-dvd.aux[DVD].titles[t_index].audio_tracks
-
-       RO
-       Each title object in the titles array provides information
-       about available audio tracks, the audio_tracks is an array
-       as well. The t_index variable is only used as an example in
-       this case and represents an integer index value in the
-       range:
-dvd.aux[DVD].titles.length > t_index >= 0
-
-     *
-dvd.aux[DVD].titles[t_index].audio_tracks[a_index].format
-
-       RO
-       A string, containing the format name of the audio track
-       (i.e. ac3, dts, etc.). The a_index variable is only used as
-       an example, it represents an integer index value in the
-       range:
-dvd.aux[DVD].titles[t_index].audio_tracks.length > a_index >= 0
-
-     *
-dvd.aux[DVD].titles[t_index].audio_tracks[a_index].language
-
-       RO
-       A string, containing the name of the language of the audio
-       track.
-     *
-dvd.aux[DVD].titles[t_index].chapters
-
-       RO
-       This property is an array which contains chapter
-       information for the particular title.
-     *
-dvd.aux[DVD].titles[t_index].chapters[c_index].duration
-
-       RO
-       Duration from the start of the chapter to the end of the
-       movie. Chapter at index 0 will always have the duration of
-       the whole title. The c_index variable is only used as an
-       example, it represents an integer index value in the range:
-dvd.aux[DVD].titles[t_index].chapters.length > c_index >= 0
-
-3.2. Constants
-
-   Actually there are no such things as constants in JS, so those
-   are actually predefined global variables that are set during JS
-   engine initialization. Do not assign any values to them,
-   otherwise following script invocation will be using wrong
-   values.
-     *
-UPNP_CLASS_CONTAINER
-
-       Type: string
-       Value: object.container
-     *
-UPNP_CLASS_CONTAINER_MUSIC_ARTIST
-
-       Type: string
-       Value: object.container.person.musicArtist
-     *
-UPNP_CLASS_CONTAINER_MUSIC_GENRE
-
-       Type: string
-       Value: object.container.genre.musicGenre
-     *
-UPNP_CLASS_CONTAINER_MUSIC_ALBUM
-
-       Type: string
-       Value: object.container.album.musicAlbum
-
-        Note:
-                this container class will be treated by the server
-                in a special way, all music items in this
-                container will be sorted by ID3 track number.
-
-     *
-UPNP_CLASS_PLAYLIST_CONTAINER
-
-       Type: string
-       Value: object.container.playlistContainer
-
-        Note:
-                this container class will be treated by the server
-                in a special way, all items in this container will
-                be sorted by the number specified in the
-                playlistOrder property (this is set when an object
-                is created by the playlist script).
-
-     *
-UPNP_CLASS_ITEM
-
-       Type: string
-       Value: object.item
-     *
-UPNP_CLASS_ITEM_MUSIC_TRACK
-
-       Type: string
-       Value: object.item.audioItem.musicTrack
-     *
-UPNP_CLASS_ITEM_VIDEO
-
-       Type: string
-       Value: object.item.videoItem
-     *
-UPNP_CLASS_ITEM_IMAGE
-
-       Type: string
-       Value: object.item.imageItem
-     *
-OBJECT_TYPE_CONTAINER
-
-       Type: integer
-       Value: 1
-     *
-OBJECT_TYPE_ITEM
-
-       Type: integer
-       Value: 2
-     *
-OBJECT_TYPE_ACTIVE_ITEM
-
-       Type: integer
-       Value: 4
-     *
-OBJECT_TYPE_ITEM_EXTERNAL_URL
-
-       Type: integer
-       Value: 8
-     *
-OBJECT_TYPE_ITEM_INTERNAL_URL
-
-       Type: integer
-       Value: 16
-
-4. Functions
-
-   The server offers various native functions that can be called
-   from the scripts, additionally there are some js helper
-   functions that can be used.
-
-4.1. Native Server Functions
-
-   The so called native functions are implemented in C++ in the
-   server and can be called from the scripts.
-
-4.1.1. Native Functions Available To All Scripts
-
-   The server offers three functions which can be called from
-   within the import and/or the playlist script:
-     *
-addCdsObject(object, containerChain, lastContainerClass);
-
-       This function adds a virtual object to the server database,
-       the path in the database is defined by the containerChain
-       parameter. The third argument is optional, it allows to set
-       the upnp:class of the last container in the chain.
-       Parameters:
-          +
-object
-
-            A virtual object that is either a copy of or a
-            reference to 'orig', see Section 3.2 for a list of
-            properties.
-          +
-containerChain
-
-            A string, defining where the object will be added in
-            the database hierarchy. The containers in the chain
-            are separated by a slash '/', for example, a value of
-            '/Audio/All Music' will add the object to the Audio,
-            All Music container in the server hierarchy. Make sure
-            to properly escape the slash characters in container
-            names. You will find more information on container
-            chain escaping later in this chapter.
-          +
-lastContainerClass
-
-            A string, defining the upnp:class of the container
-            that appears last in the chain. This parameter can be
-            omitted, in this case the default value
-            'object.container' will be taken. Setting specific
-            upnp container classes is useful to define the special
-            meaning of a particular container; for example, the
-            server will always sort songs by track number if upnp
-            class of a container is set to
-            'object.container.album.musicAlbum'.
-     *
-copyObject(originalObject);
-
-       This function returns a copy of the virtual object.
-     *
-print(...);
-
-       This function is useful for debugging scripts, it simply
-       prints to the standard output.
-     *
-f2i(string)
-
-     *
-m2i(string)
-
-     *
-p2i(string)
-
-     *
-j2i(string)
-
-       The above set of functions converts predefined characters
-       sets to UTF-8. The 'from' charsets can be defined in the
-       server configuration:
-          + f2i: filesystem charset to internal
-          + m2i: metadata charset to internal
-          + j2i: js charset to internal
-          + p2i: playlist charset to internal
-
-4.1.2. Native Functions Available To The Playlist Script
-
-   The following function is only available to the playlist
-   script.
-     *
-readln();
-
-       This function reads and returns exactly one line of text
-       from the playlist that is currently being processed, end of
-       line is identified by carriage return/line feed characters.
-       Each subsequent call will return the next line, there is no
-       way to go back.
-       The idea is, that you can process your playlist line by
-       line and gather the required information to create new
-       objects which can be added to the database.
-
-4.1.3. Native Functions Available To The DVD Import Script
-
-   The following function is only available to the DVD import
-   script.
-     *
-addCdsObject(object, containerChain, lastContainerClass);
-
-       This function adds a virtual object to the server database,
-       the path in the database is defined by the containerChain
-       parameter. The third argument is optional, it allows to set
-       the upnp:class of the last container in the chain.
-       Parameters:
-          +
-object
-
-            A virtual object that is either a copy of or a
-            reference to 'orig', see Section 3.2 for a list of
-            properties.
-          +
-containerChain
-
-            A string, defining where the object will be added in
-            the database hierarchy. The containers in the chain
-            are separated by a slash '/', for example, a value of
-            '/Audio/All Music' will add the object to the Audio,
-            All Music container in the server hierarchy. Make sure
-            to properly escape the slash characters in container
-            names. You will find more information on container
-            chain escaping later in this chapter.
-          +
-lastContainerClass
-
-            A string, defining the upnp:class of the container
-            that appears last in the chain. This parameter can be
-            omitted, in this case the default value
-            'object.container' will be taken. Setting specific
-            upnp container classes is useful to define the special
-            meaning of a particular container; for example, the
-            server will always sort songs by track number if upnp
-            class of a container is set to
-            'object.container.album.musicAlbum'.
-     *
-addDVDObject(dvd, t, c, a, createContainerChain(chain));
-
-       This function reads and returns exactly one line of text
-       from the playlist that is currently being processed, end of
-       line is identified by carriage return/line feed characters.
-       Each subsequent call will return the next line, there is no
-       way to go back.
-       The idea is, that you can process your playlist line by
-       line and gather the required information to create new
-       objects which can be added to the database.
-
-4.2. Helper Functions
-
-   There is a set of helper JavaScript functions which reside in
-   the common.js script. They can be used by the import and by the
-   playlist script.
-     *
-function escapeSlash(name);
-
-
-       The first function escapes slash '/' characters in a
-       string. This is necessary, because the container chain is
-       defined by a slash separated string, where slash has a
-       special meaning - it defines the container hierarchy. That
-       means, that slashes that appear in the object's title need
-       to be properly escaped.
-     *
-
-
-       The following function makes it easier to work with
-       container chains; it takes an array of container names as
-       argument, makes sure that the names are properly escaped
-       and adds the slash separators as necessary. It returns a
-       string that is formatted to be used as a parameter for the
-       addCdsObject function.
-function createContainerChain(arr)
-{
-    var path = '';
-    for (var i = 0; i < arr.length; i++)
-    {
-        path = path + '/' + escapeSlash(arr[i]);
-    }
-    return path;
-}
-
-     * This function retrieves the year from a yyyy-mm-dd
-       formatted string.
-function getYear(date)
-{
-    var matches = date.match(/^([0-9]{4})-/);
-    if (matches)
-        return matches[1];
-    else
-        return date;
-}
-
-     * This function identifies the type of the playlist by the
-       mimetype, it is used in the playlist script to select an
-       appropriate parser.
-function getPlaylistType(mimetype)
-{
-    if (mimetype == 'audio/x-mpegurl')
-        return 'm3u';
-    if (mimetype == 'audio/x-scpls')
-        return 'pls';
-    return '';
-}
-
-5. Walkthrough
-
-   Now it is time to take a closer look at the default scripts
-   that are supplied with MediaTomb. Usually it is installed in
-   the /usr/share/mediatomb/js/ directory, but you will also find
-   it in scripts/js/ in the MediaTomb source tree.
-
-   Note:
-          this is not a JavaScript tutorial, if you are new to JS
-          you should probably make yourself familiar with the
-          language.
-
-5.1. Import Script
-
-   We start with a walkthrough of the default import script, it is
-   called import.js in the MediaTomb distribution.
-
-   Below are the import script functions that organize our content
-   in the database by creating the virtual structure. Each media
-   type - audio, image and video is handled by a separate
-   function.
-
-5.1.1. Audio Content Handler
-
-   The biggest one is the function that handles audio - the reason
-   is simple: mp3 files offer a lot of metadata like album,
-   artist, genre, etc. information, this allows us to create a
-   nice container layout.
-function addAudio(obj)
-{
-    var desc = '';
-    var artist_full;
-    var album_full;
-
-   First we will gather all the metadata that is provided by our
-   object, of course it is possible that some fields are empty -
-   we will have to check that to make sure that we handle this
-   case correctly.
-    var title = obj.meta[M_TITLE];
-
-   Note the difference between obj.title and obj.meta[M_TITLE] -
-   while object.title will originally be set to the file name,
-   obj.meta[M_TITLE] will contain the parsed title - in this
-   particular example the ID3 title of an MP3.
-
-    if (!title) title = obj.title;
-    var artist = obj.meta[M_ARTIST];
-    if (!artist)
-    {
-        artist = 'Unknown';
-        artist_full = null;
-    }
-    else
-    {
-        artist_full = artist;
-        desc = artist;
-    }
-
-   var album = obj.meta[M_ALBUM];
-   if (!album)
-    {
-        album = 'Unknown';
-        album_full = null;
-    }
-    else
-    {
-        desc = desc + ', ' + album;
-        album_full = album;
-    }
-
-    if (desc)
-        desc = desc + ', ';
-
-    desc = desc + title;
-
-    var date = obj.meta[M_DATE];
-    if (!date)
-    {
-        date = 'Unknown';
-    }
-    else
-    {
-        date = normalizeDate(date);
-        desc = desc + ', ' + date;
-    }
-
-    var genre = obj.meta[M_GENRE];
-    if (!genre)
-    {
-        genre = 'Unknown';
-    }
-    else
-    {
-        desc = desc + ', ' + genre;
-    }
-
-    var description = obj.meta[M_DESCRIPTION];
-    if (!description)
-    {
-
-   Note how we are setting properties of an object - in this case
-   we put together a description and we are setting for objects
-   that did not already have one.
-        obj.meta[M_DESCRIPTION] = desc;
-    }
-
-   We finally gathered all data that we need, so let's create a
-   nice layout for our audio files. Note how we are constructing
-   the chain, in the line below the array 'chain' will be
-   converted to 'Audio/All audio' by the createContainerChain()
-   function.
-    var chain = new Array('Audio', 'All audio');
-    obj.title = title;
-
-   The UPnP class argument to addCdsObject() is optional, if it is
-   not supplied the default UPnP class will be used. However, it
-   is suggested to correctly set UPnP classes of containers and
-   objects - this information may be used by some renderers to
-   identify the type of the container and present the content in a
-   different manner .
-    addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER
-_MUSIC);
-
-    chain = new Array('Audio', 'Artists', artist, 'All songs');
-    addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER
-_MUSIC);
-
-    chain = new Array('Audio', 'All - full name');
-    var temp = '';
-    if (artist_full)
-        temp = artist_full;
-
-    if (album_full)
-        temp = temp + ' - ' + album_full + ' - ';
-
-    obj.title = temp + title;
-
-    addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER
-_MUSIC);
-
-    chain = new Array('Audio', 'Artists', artist, 'All - full name');
-    addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER
-_MUSIC);
-
-    chain = new Array('Audio', 'Artists', artist, album);
-    obj.title = track + title;
-
-   Remember, the server will sort all items by ID3 track if the
-   container class is set to UPNP_CLASS_CONTAINER_MUSIC_ALBUM.
-    addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER
-_MUSIC_ALBUM);
-
-    chain = new Array('Audio', 'Albums', album);
-    obj.title = track + title;
-    addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER
-_MUSIC_ALBUM);
-
-    chain = new Array('Audio', 'Genres', genre);
-    addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER
-_MUSIC_GENRE);
-
-    chain = new Array('Audio', 'Year', date);
-    addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER
-_MUSIC);
-}
-
-5.1.2. Weborama Content Handler
-
-   Weborama content handler is really simple, the service aims at
-   providing 'radio on demand', so everything here maps to a
-   search query that you specified in the config.xml:
-function addWeborama(obj)
-{
-    var req_name = obj.aux[WEBORAMA_AUXDATA_REQUEST_NAME];
-    if (req_name)
-    {
-        var chain = new Array('Online Services', 'Weborama', req_name);
-        addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_PLAYL
-IST_CONTAINER);
-    }
-}
-
-5.1.3. Image Content Handler
-
-   This function takes care of images. Currently it does very
-   little sorting, but could easily be extended - photos made by
-   digital cameras provide lots of information in the Exif tag, so
-   you could easily add code to sort your pictures by camera model
-   or anything Exif field you might be interested in.
-
-   Note:
-          if you want to use those additional Exif fields you need
-          to compile MediaTomb with libexif support and also
-          specify the fields of interest in the import section of
-          your configuration file (See documentation about
-          library-options).
-
-function addImage(obj)
-{
-    var chain = new Array('Photos', 'All Photos');
-    addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER
-);
-
-    var date = obj.meta[M_DATE];
-    if (date)
-    {
-        chain = new Array('Photos', 'Date', date);
-        addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTA
-INER);
-    }
-}
-
-   Just like in the addAudio() function - we simply construct our
-   container chain and add the object.
-
-5.1.4. Video Content Handler
-
-   Not much to say here... I think libextractor is capable of
-   retrieving some information from video files, however I seldom
-   encountered any video files populated with metadata. You could
-   also try ffmpeg to get more information, however by default we
-   keep it very simple - we just put everything into the 'All
-   Video' container.
-function addVideo(obj)
-{
-    var chain = new Array('Video');
-    addCdsObject(obj, createContainerChain(chain));
-}
-
-5.1.5. YouTube Content Handler
-
-   This helper function processes items that are imported from the
-   YouTube service; these items have extended properties that were
-   described in detail earlier in this document. Let's have a look
-   at how they are used:
-function addYouTube(obj)
-{
-   var chain;
-
-   First, we want to sort the content by average rating. Remember
-   - all properties in the obj.aux array are strings, so we will
-   do an extra conversion because we want to round the rating.
-   var temp = parseInt(obj.aux[YOUTUBE_AUXDATA_AVG_RATING], 10);
-
-   Make sure to check that we got a number.
-   if (temp != Number.NaN)
-   {
-       temp = Math.round(temp);
-
-   Here is the place if you want to have a different range of
-   ratings in your tree structure:
-       if (temp > 3)
-       {
-           var chain = new Array('Online Services', 'YouTube',
-                                  'Rating', temp.toString());
-           addCdsObject(obj, createContainerChain(chain));
-       }
-   }
-
-   Next, we process the request, i.e. - description of the request
-   to the YouTube service that created the item. Some requests may
-   contain additional information like the name of the region.
-    temp = obj.aux[YOUTUBE_AUXDATA_REQUEST];
-    if (temp)
-    {
-        var subName = (obj.aux[YOUTUBE_AUXDATA_SUBREQUEST_NAME]);
-        var feedName = (obj.aux[YOUTUBE_AUXDATA_FEED]);
-        var region = (obj.aux[YOUTUBE_AUXDATA_REGION]);
-
-        chain = new Array('Online Services', 'YouTube', temp);
-
-   All items will go to /Online Services/YouTube/RequestName/,
-   below we will do additional refinement. Do not forget to check
-   if the values are valid, some requests may not have all of the
-   tags set (for example - if no specific region was defined in
-   the config, then the associated request will not provide the
-   REGION auxdata)
-       if (subName)
-           chain.push(subName);
-
-       if (feedName)
-           chain.push(feedName);
-
-       if (region)
-           chain.push(region);
-
-       addCdsObject(obj, createContainerChain(chain));
-    }
-}
-
-5.1.6. Apple Trailers Content Handler
-
-   This function processes items that are importent via the Apple
-   Trailers feature. We will organize the trailers by genre, post
-   date and release date, additionally we will also add a
-   container holding all trailers.
-function addTrailer(obj)
-{
-    var chain;
-
-   First we will add the item to the 'All Trailers' container, so
-   that we get a nice long playlist:
-    chain = new Array('Online Services', 'Apple Trailers', 'All Trailer
-s');
-    addCdsObject(obj, createContainerChain(chain));
-
-   We also want to sort the trailers by genre, however we need to
-   take some extra care here: the genre property here is a comma
-   separated value list, so one trailer can have several matching
-   genres that will be returned as one string. We will split that
-   string and create individual genre containers.
-    var genre = obj.meta[M_GENRE];
-    if (genre)
-    {
-
-   A genre string "Science Fiction, Thriller" will be split to
-   "Science Fiction" and "Thriller" respectively.
-        genres = genre.split(', ');
-        for (var i = 0; i < genres.length; i++)
-        {
-            chain = new Array('Online Services', 'Apple Trailers', 'Gen
-res',
-                              genres[i]);
-            addCdsObject(obj, createContainerChain(chain));
-        }
-    }
-
-   The release date is offered in a YYYY-MM-DD format, we won't do
-   too much extra checking regading validity, however we only want
-   to group the trailers by year and month:
-    var reldate = obj.meta[M_DATE];
-    if ((reldate) && (reldate.length >= 7))
-    {
-        chain = new Array('Online Services', 'Apple Trailers', 'Release
- Date',
-                          reldate.slice(0, 7));
-        addCdsObject(obj, createContainerChain(chain));
-    }
-
-   We also want to group the trailers by the date when they were
-   originally posted, the post date is available via the aux
-   array. Similar to the release date, we will cut off the day and
-   create our containres in the YYYY-MM format.
-    var postdate = obj.aux[APPLE_TRAILERS_AUXDATA_POST_DATE];
-    if ((postdate) && (postdate.length >= 7))
-    {
-        chain = new Array('Online Services', 'Apple Trailers', 'Post Da
-te',
-                          postdate.slice(0, 7));
-        addCdsObject(obj, createContainerChain(chain));
-    }
-}
-
-5.1.7. Putting it all together
-
-   This is the main part of the script, it looks at the mimetype
-   of the original object and feeds the object to the appropriate
-   content handler.
-if (getPlaylistType(orig.mimetype) == '')
-{
-    var arr = orig.mimetype.split('/');
-    var mime = arr[0];
-
-    var obj = orig;
-
-   All virtual objects are references to objects in the
-   PC-Directory, so make sure to correctly set the reference ID!
-    obj.refID = orig.id;
-
-    if ((mime == 'audio'))
-    {
-
-   We support the Weborama online radio service, so we will do
-   some extra handling for those items:
-        if (obj.onlineservice == ONLINE_SERVICE_WEBORAMA)
-            addWeborama(obj);
-        else
-            addAudio(obj);
-    }
-
-    if (mime == 'video')
-    {
-
-   We support the YouTube service which offers video items, so we
-   will do an extra check to sort it properly:
-        if (obj.onlineservice == ONLINE_SERVICE_YOUTUBE)
-            addYouTube(obj);
-        else
-            addVideo(obj);
-    }
-
-    if (mime == 'image')
-    {
-         addImage(obj);
-    }
-
-   We now also have OGG Theora recognition, so we can ensure that
-   Vorbis
-    if (orig.mimetype == 'application/ogg')
-    {
-    if (obj.theora == 1)
-            addVideo(obj);
-        else
-            addAudio(obj);
-    }
-}
-
-5.2. Playlist Script
-
-   The default playlist parsing script is called playlists.js,
-   similar to the import script it works with a global object
-   which is called 'playlist', the fields are similar to the
-   'orig' that is used in the import script with the exception of
-   the playlistOrder field which is special to playlists.
-
-   Another big difference between playlist and import scripts is,
-   that playlist scripts can add new media to the database, while
-   import scripts only process already existing objects (the ones
-   found in PC Directory) and just add additional virtual items.
-
-   The default playlist script implementation supports parsing of
-   m3u and pls formats, but you can add support for parsing of any
-   ASCII based playlist format.
-
-5.2.1. Adding Items
-
-   We will first look at a helper function:
-addPlaylistItem(location, title, playlistChain);
-
-   It is defined in playlists.js, it receives the location (path
-   on disk or HTTP URL), the title and the desired position of the
-   item in the database layout (remember the container chains used
-   in the import script).
-
-   The function first decides if we are dealing with an item that
-   represents a resource on the web, or if we are dealing with a
-   local file. After that it populates all item fields accordingly
-   and calls the addCdsObject() that was introduced earlier. Note,
-   that if the object that is being added by the playlist script
-   is not yet in the database, the import script will be invoked.
-   Below is the complete function with some comments:
-function addPlaylistItem(location, title, playlistChain)
-{
-
-   Determine if the item that we got is an URL or a local file.
-    if (location.match(/^.*:\/\//))
-    {
-        var exturl = new Object();
-
-   Setting the mimetype is crucial and tricky... if you get it
-   wrong your renderer may show the item as unsupported and refuse
-   to play it. Unfortunately most playlist formats do not provide
-   any mimetype information.
-        exturl.mimetype = 'audio/mpeg';
-
-   Make sure to correctly set the object type, then populate the
-   remaining fields.
-        exturl.objectType = OBJECT_TYPE_ITEM_EXTERNAL_URL;
-        exturl.location = location;
-        exturl.title = (title ? title : location);
-        exturl.protocol = 'http-get';
-        exturl.upnpclass = UPNP_CLASS_ITEM_MUSIC_TRACK;
-        exturl.description = "Song from " + playlist.title;
-
-   This is a special field which ensures that your playlist files
-   will be displayed in the correct order inside a playlist
-   container. It is similar to the id3 track number that is used
-   to sort the media in album containers.
-        exturl.playlistOrder = playlistOrder++;
-
-   Your item will be added to the container named by the playlist
-   that you are currently parsing.
-        addCdsObject(exturl, playlistChain,  UPNP_CLASS_PLAYLIST_CONTAI
-NER);
-    }
-
-   Here we are dealing with a local file.
-    else
-    {
-        if (location.substr(0,1) != '/')
-            location = playlistLocation + location;
-        var item  = new Object();
-        item.location = location;
-        if (title)
-            item.title = title;
-        else
-         {
-            var locationParts = location.split('/');
-            item.title = locationParts[locationParts.length - 1];
-            if (! item.title)
-                item.title = location;
-        }
-        item.objectType = OBJECT_TYPE_ITEM;
-        item.playlistOrder = playlistOrder++;
-        addCdsObject(item, playlistChain,  UPNP_CLASS_PLAYLIST_CONTAINE
-R);
-    }
-}
-
-5.2.2. Main Parsing
-
-   The actual parsing is done in the main part of the script.
-   First, the type of the playlist is determined (based on the
-   playlist mimetype), then the correct parser is chosen. The
-   parsing itself is a loop, where each call to readln() returns
-   exactly one line of text from the playlist. There is no
-   possibility to go back, each readln() invocation will retrieve
-   the next line until end of file is reached.
-
-   To keep things easy we will only list the m3u parsing here.
-   Again, if you are not familiar with regular expressions, now is
-   probably the time to take a closer look.
-...
-else if (type == 'm3u')
-{
-    var line;
-    var title = null;
-
-   Here is the do - while loop which will read the playlist line
-   by line.
-    do
-    {
-
-   Read the line:
-        line = readln();
-
-   Perform m3u specific parsing:
-        if (line.match(/^#EXTINF:(\d+),(\S.+)$/i))
-        {
-            // duration = RegExp.$1; // currently unused
-            title = RegExp.$2;
-        }
-        else if (! line.match(/^(#|\s*$)/))
-        {
-
-   Call the helper function to add the item once you gathered the
-   data:
-            addPlaylistItem(line, title, playlistChain);
-            title = null;
-        }
-    }
-
-   We will exit the loop when end of the playlist file is reached.
-    while (line);
-}
-...
-
-5.3. DVD Import Script
-
-   The DVD import script receives an object that represents a DVD
-   image. The object provides information about the number of
-   titles, chapters, audio tracks and about languages that are
-   available in the image. You can not play the ISO directly (most
-   players will not support this), so we weill create special
-   virtual DVD objects, which will deliver an MPEG PES stream for
-   the selected Title/Audio Track/Chapter.
-
-   The DVD import script is separated from the main script, the
-   script that is shipped with the default installation is called
-   import-dvd.js.
-
-   Let's have a closer look!
-
-
-   The title of the DVD will be set to the file name of the ISO
-   image, we want to get rid of the .iso extension:
-var title = dvd.title;
-var index = title.lastIndexOf('.');
-if (index > 1)
-    title = title.substring(0, index);
-
-
-   Since the object that we receive is the original ISO it will
-   not have the correct video UPnP class, so we have to set it
-   ourselves:
-dvd.upnpclass = UPNP_CLASS_ITEM_VIDEO;
-
-   Now we will get the number of titles and loop through them,
-   creating a virtual structure for the chapters, languages and
-   audio formats:
-var title_count = dvd.aux[DVD].titles.length;
-for (var t = 0; t < title_count; t++)
-{
-    var title_name = 'Title';
-
-   Since the sorting is based on the titles we need a leading
-   zero. Also note the (t + 1) part, the very first position in
-   the array has an index of zero, however we want that the title
-   count starts with one in the UI:
-    if (t < 9)
-        title_name = title_name + ' 0' + (t + 1);
-    else
-        title_name = title_name + ' ' + (t + 1);
-
-   Get the number of chapters and audio tracks for this title and
-   loop through them:
-    var chapter_count = dvd.aux[DVD].titles[t].chapters.length;
-    var audio_track_count = dvd.aux[DVD].titles[t].audio_tracks.length;
-    for (var a = 0; a < audio_track_count; a++)
-    {
-        var chain;
-
-   Again, note the (a + 1) part, we want the first track in the UI
-   to show as Track 01 and not Track 00:
-        var audio_name = ' - Audio Track ' + (a + 1);
-
-   We will create a structure, sorting the media by audio
-   languages and formats:
-        var audio_language = dvd.aux[DVD].titles[t].audio_tracks[a].lan
-guage;
-        var audio_format = dvd.aux[DVD].titles[t].audio_tracks[a].forma
-t;
-        if (audio_format != '')
-        {
-            if (audio_language != '')
-                audio_name = audio_name + ' - ' + audio_language;
-
-            chain = new Array('Video', 'DVD', title, 'Audio Formats',
-                              audio_format, title_name + audio_name);
-
-   The code above was only dealing with containers, this loop will
-   create the actual playable items:
-            for (var c = 0; c < chapter_count; c++)
-            {
-                if (c < 9)
-                    dvd.title = "Chapter 0" + (c + 1);
-                else
-                    dvd.title = "Chapter " + (c + 1);
-
-   When attempted to play, the item created below will deliver the
-   MPEG PES with title index t, chapter index c and audio track
-   index a - we created the chain appropriately so that the audio
-   index matches the language and audio format that we used in the
-   container names:
-                addDVDObject(dvd, t, c, a, createContainerChain(chain))
-;
-            }
-        }
-
-   Same for the language:
-        if (audio_language != '')
-        {
-            chain = new Array('Video', 'DVD', title, 'Languages',
-                              audio_language);
-            if (audio_format != '')
-                chain.push(title_name + audio_name + ' - ' + audio_form
-at);
-            else
-                chain.push(title_name + audio_name);
-            for (var c = 0; c < chapter_count; c++)
-            {
-                if (c < 9)
-                    dvd.title = "Chapter 0" + (c + 1);
-                else
-                    dvd.title = "Chapter " + (c + 1);
-
-                addDVDObject(dvd, t, c, a, createContainerChain(chain))
-;
-            }
-        }
-
-   And we also want a list of titles with appropriate format and
-   language information:
-        chain = new Array('Video', 'DVD', title, 'Titles');
-        var titles = title_name + ' - Audio Track ' + (a + 1);
-        if (audio_format != '')
-            titles = titles + ' - ' + audio_format;
-
-        if (audio_language != '')
-            titles = titles + ' - ' + audio_language;
-
-        chain.push(titles);
-
-        for (var c = 0; c < chapter_count; c++)
-        {
-            if (c < 9)
-                dvd.title = "Chapter 0" + (c + 1);
-            else
-                dvd.title = "Chapter " + (c + 1);
-
-            addDVDObject(dvd, t, c, a, createContainerChain(chain));
-        }
-    }
-}
-
-   Happy scripting!
diff --git a/doc/transcoding_utf8.txt b/doc/transcoding_utf8.txt
deleted file mode 100644
index 41717bc..0000000
--- a/doc/transcoding_utf8.txt
+++ /dev/null
@@ -1,461 +0,0 @@
-Transcoding Content With MediaTomb
-
-   This documentation is valid for MediaTomb version 0.12.1.
-
-   Copyright © 2005 Gena Batsyan, Sergey Bostandzhyan
-
-   Copyright © 2006-2010 Gena Batsyan, Sergey Bostandzhyan,
-   Leonhard Wimmer
-
-   THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR
-   OWN RISK!
-     __________________________________________________________
-
-   Table of Contents
-
-   1. Introduction
-   2. Theory Of Operation
-
-        2.1. What Happens On The User Level
-        2.2. Technical Background
-
-   3. Sample Configuration
-
-        3.1. Profile Selection
-        3.2. Profile Definition
-        3.3. Advanced Settings
-
-   4. Testing And Troubleshooting
-
-        4.1. Testing The Transcoder
-        4.2. Troubleshooting
-
-1. Introduction
-
-   MediaTomb version 0.11.0 introduces a new feature -
-   transcoding. It allows you to perform format conversion of your
-   content on the fly allowing you to view media that is otherwise
-   not supported by your player.
-
-   For example, you might have your music collection stored in the
-   OGG format, but your player only supports MP3 or you have your
-   movies stored in DivX format, but your player only supports
-   MPEG2 and MPEG4. Of course you could sit down and convert
-   everything before viewing, but that is usually a time consuming
-   procedure, besides, you often you want to keep your original
-   data untouched and end up storing both, the converted and the
-   original content - wasting space on your hard disk. That's
-   where on the fly transcoding comes into play.
-
-   Another use case is online content - it is often presented in
-   flv or asf formats, you may get mms or rtp streams which your
-   player can not handle. The transcoding feature makes it
-   possible to access such content.
-
-   Last but not least - subtitles. Only a few devices provide
-   subtitle support, usually it's a proprietary solution not
-   covered by UPnP. Using transcoding you can enable subtitles
-   independent of the player device.
-
-2. Theory Of Operation
-
-   This chapter describes the idea behind the current transcoding
-   implementation.
-
-2.1. What Happens On The User Level
-
-   So how does this work? First, let's look at the normal
-   situation where you are playing content that is natively
-   supported by your player, let's say a DivX movie. You add it to
-   the server, browse the content on your device, hit play and
-   start streaming the content. Content that the player can not
-   handle is usually grayed out in the on screen display or marked
-   as unsupported.
-
-   Now, what happens if transcoding is in place?
-
-   First, you define transcoding profiles, specifying which
-   formats should be converted, let's assume that you have some
-   music stored in the FLAC format, but your device only supports
-   MP3 and WAV. So, you can define that all FLAC media should be
-   transcoded to WAV. You then start MediaTomb and browse the
-   content as usual on your device, if everything was set up
-   correctly you should see that your FLAC files are marked as
-   playable now. You hit play, just like usual, and you will see
-   that your device starts playback.
-
-   Here is what happens in the background: when you browse
-   MediaTomb, we will look at the transcoding profile that you
-   specified and, assuming the example above, tell your player
-   that each FLAC file is actually a WAV file. Remember, we
-   assumed that the player is capable of playing WAV content, so
-   it will display the items as playable. As soon as you press
-   play, we will use the options defined in the transcoding
-   profile to launch the transcoder, we will feed it the original
-   FLAC file and serve the transcoded WAV output directly to your
-   player. The transcoding is done on the fly, the files are not
-   stored on disk and do not require additional disk space.
-
-2.2. Technical Background
-
-   The current implementation allows to plug in any application to
-   do the transcoding. The only important thing is, that the
-   application is capable of writing the output to a FIFO.
-   Additionally, if the application is not capable of accessing
-   online content directly we can proxy the online data and
-   provide a FIFO for reading.
-
-   The application can be any executable and is launched as a
-   process with a set of given parameters that are defined in the
-   profile configuration. The special command line tokes %in and
-   %out that are used in the profile will be substituted by the
-   input file name or input URL and the output FIFO name.
-
-   So, the parameters tell the transcoding application: read
-   content from this file, transcode it, and write the output to
-   this FIFO. MediaTomb will read the output from the FIFO and
-   serve the transcoded stream to the player device.
-
-   Buffering is implemented to allow smooth playback and
-   compensate for high bitrate scenes that may require more CPU
-   power in the transcoding process.
-
-   Once you press stop or once you reach end of file we will make
-   sure that the transcoding process is killed and we will clean
-   up the FIFOs.
-
-   The chosen approach is extremely flexible and gives you maximum
-   freedom of choice - you can also use this framework view mms
-   and rtp streams even if this is originally not supported by
-   your player, blend in subtitles or even listen to text
-   documents using a text to speech processor.
-
-   Note:
-          it is possible and may be more convenient to call a
-          wrapper script and not the transcoding application
-          directly, however, in this case make sure that your
-          shell script uses exec when calling the transcoder.
-          Otherwise we will not be able to kill it.
-
-3. Sample Configuration
-
-   We will not go through all possible configuration tags here,
-   they are described in detail in the main documentation.
-   Instead, we will show an sample configuration and describe the
-   creation process.
-
-   First of all you need to decide what content has to be
-   transcoded. It makes no sens to transcode something that can be
-   played natively by your device. Next, you have to figure out
-   how smart your device is - UPnP defines a way in which it is
-   possible to provide several resources (or several format
-   representations) of the same content, however most devices only
-   look at the first resource and ignore the rest. We implemented
-   options to overcome this, however it may get tricky if you have
-   several devices around and if each of them needs different
-   settings.
-
-   All settings apply to your config.xml.
-
-3.1. Profile Selection
-
-   What do we want to transcode? Let's assume that you have some
-   .flv files on your drive or that you want to watch YouTube
-   videos on your device using MediaTomb. I have not yet heard of
-   a UPnP player device that natively supports flash video, so
-   let's tell MediaTomb what we want to transcode all .flv content
-   to something that our device understands.
-
-   This can be done in the mimetype-profile section under
-   transcoding, mappings:
-<transcode mimetype="video/x-flv" using="vlcprof"/>
-
-   So, we told MediaTomb to transcode all video/x-flv content
-   using the profile named “vlcprof”.
-
-3.2. Profile Definition
-
-   We define vlcprof in the profiles section:
-<profile name="vlcprof" enabled="yes" type="external">
-  <mimetype>video/mpeg</mimetype>
-  <agent command="vlc" arguments="-I dummy %in --sout #transcode{venc=f
-fmpeg,vcodec=mp2v,vb=4096,fps=25,aenc=ffmpeg,acodec=mpga,ab=192,sampler
-ate=44100,channels=2}:standard{access=file,mux=ps,dst=%out} vlc:quit"/>
-  <buffer size="10485760" chunk-size="131072" fill-size="2621440"/>
-  <accept-url>yes</accept-url>
-  <first-resource>yes</first-resource>
-</profile>
-
-   Let's have a closer look:
-<profile name="vlcprof" enabled="yes" type="external">
-
-   The profile tag defines the name of the profile - in our
-   example it's “vlcprof”, it allows you to quickly switch the
-   profile on and off by setting the enabled parameter to “yes” or
-   “no” and also defines the profile type. Currently only one
-   transcoding type is supported - “external”.
-
-3.2.1. Specifying The Target Mime Type
-
-   We need to define which mime type we are transcoding to -
-   that's what the player device will see. It must be something it
-   supports and there are also some other limitations: the output
-   format must be streamable - meaning, it must be a format which
-   can be played back without the need of seeking in the stream.
-   AVI is a good example - it contains the index at the end of the
-   file, so the player needs to seek (or use HTTP range requests)
-   to read the index. Because of that you will not be able to
-   transcode to AVI on the fly. A good target format is MPEG2 - it
-   does not require the player to seek in the stream and it can be
-   encoded on the fly with reasonable CPU power.
-
-   So, let's specify our target mime type:
-  <mimetype>video/mpeg</mimetype>
-
-   Bear in mind that this line only tells your player device about
-   the content format, it does not tell anything to the transcoder
-   application.
-
-3.2.2. Choosing The Transcoder
-
-   Now it is time to look at the agent parameter - this tells us
-   which application to execute and it also provides the necessary
-   command line options for it:
-<agent command="vlc" arguments="-I dummy %in --sout #transcode{venc=ffm
-peg,vcodec=mp2v,vb=4096,fps=25,aenc=ffmpeg,acodec=mpga,ab=192,samplerat
-e=44100,channels=2}:standard{access=file,mux=ps,dst=%out} vlc:quit"/>
-
-   In the above example the command to be executed is “vlc, it
-   will be called with parameter specified in the arguments
-   attribute. Note the special %in and %out tokens - they are not
-   part of the vlc command line but have a special meaning in
-   MediaTomb. The %in token will be replaced by the input file
-   name (i.e. the file that needs to be transcoded) and the %out
-   token will be replaced by the output FIFO name, from where the
-   transcoded content will be read by MediaTomb and sent to the
-   player.
-
-   Just to make it clearer:
-<agent command="executable name" arguments="command line %in %out/>
-
-   So, an agent tag defines the command which is an executable
-   (make sure that it is in $PATH and that you have permissions to
-   run it), and arguments which are the command line options and
-   where %in and %out tokens are used in the place of the input
-   and output file names.
-
-   Note:
-          the output format produced by the transcoder must match
-          the target mime type setting.
-
-3.2.3. Buffer Settings
-
-   There are no defaults for the buffer settings, they need to be
-   tuned to the performance of your system and also to the type of
-   transcoded media if you want to achieve the best result.
-
-   The idea behind buffering is the following: let's assume that
-   you are transcoding a high quality video, the source format has
-   a variable bitrate. Your CPU can handle most scenes in real
-   time, but occasionally some scenes have a higher bitrate which
-   require more processing power. Without buffering you would not
-   have a fluent playback - you would see stuttering during those
-   high bitrate scenes. That's where buffering comes into play.
-   Before sending the data to your player for the very first time,
-   we will delay the start of the playback until the buffer is
-   filled to a certain amount. This should give you enough slack
-   to overcome those higher bitrate scenes and watch the movie
-   without any stuttering or dropouts. Also, your CPU will not
-   transcode the stream as fast as it is being played (i.e. real
-   time), but work as fast as it can, filling up the buffer during
-   lower bitrate scenes and thus giving you the chance to overcome
-   even long scenes with high bitrate.
-
-   The buffer accepts three parameters and is defined like this:
-<buffer size="5242880" chunk-size="102400" fill-size="1048576"/>
-
-   Size is the total size of the buffer, fill-size is the amount
-   that has to be filled before sending out data from the buffer
-   for the first time. Chunk-size is somewhat tricky, as you know
-   we read the transcoded stream from a FIFO, we then put it into
-   the buffer from where it gets served to the player. We read the
-   data from the transcoder in chunks, once we fill up the chunk
-   we put it into the buffer, so this setting is defining the size
-   of those chunks. Lower values will make the buffer feel more
-   responsive (i.e. it will be filled at a more fluent rate),
-   however too low values will decrease performance. Also, do not
-   set a too high value here since it may prevent smooth playback
-   - data from the buffer is being played out, if you wait for a
-   too big chunk at the same time you may empty the buffer.
-
-3.2.4. Accepting Or Proxying Online Content
-
-   With MediaTomb it is possible to add items that are not
-   pointing to local content, but to online resources. It can be
-   an mp3 stream, a YouTube video or some photos stored on the
-   web. In case that the online media is stored in a format that
-   is not supported by your player, you can use transcoding to
-   convert it. Some transcoding applications, like VLC, handle
-   online content pretty well, so you can give a URL directly to
-   the transcoder and it will handle the data download itself. You
-   can even use that to stream mms or rtsp streams, even if they
-   are not directly supported by your player device. Some
-   transcoders however, can not access online content directly but
-   can only work with local data. For this situation we offer a
-   special option:
-<accept-url>no</accept-url>
-
-   If this option is set to “no” MediaTomb will handle the
-   download of the content and will feed the input to the
-   transcoder via a FIFO. Of course the transcoding application
-   must be capable of handling input from a FIFO. This only works
-   for the HTTP protocol, we do not handle RTSP or MMS streams,
-   use VLC is you want to handle those. When this option is set to
-   “yes” we will give the URL to the transcoder.
-
-3.2.5. Resource Index
-
-   What is a resource? In this case it's the <res> tag in the XML
-   that is being sent to the player when it browses the server.
-   Each item can have one or more resources, each resource
-   describes the type of the content by specifying it's mime type
-   and also tells the player how and where to get the content. So,
-   resources within the item point to same content, but allow to
-   present it in different formats. In case of transcoding we will
-   offer the original data as well as the transcoded data by using
-   the resource tags. A well implemented player will look at all
-   resources that are available for the given item and choose the
-   one that it supports. Unfortunately most players only look at
-   the first resource and ignore the rest, this feature tells us
-   to place the transcoded resource at the first position so that
-   those renderers will see and take it.
-<first-resource>yes</first-resource>
-
-3.2.6. Hiding Original Resource
-
-   Sometimes it may be required that you only present the
-   transcoded resource (read the previous section for explanation
-   about resources) to the player. This option allows to do so:
-<hide-original-resource>yes</hide-original-resource>
-
-3.3. Advanced Settings
-
-   Sometimes you encounter a container format but want to
-   transcode it only if it has a specific codec inside. Provided
-   that MediaTomb was compiled with ffmpeg support we offer fourcc
-   based transcoding settings for AVI files. A sample
-   configuration for a profile with fourcc specific settings would
-   look like that:
-<avi-fourcc-list mode="ignore">
-    <fourcc>XVID</fourcc>
-    <fourcc>DX50</fourcc>
-</avi-fourcc-list>
-
-   Please refer to the main documentation on more information
-   regarding the options.
-
-   We also provide a way to specify that a profile should only
-   process the Theora codec if an OGG container is encountered:
-<accept-ogg-theora>yes</accept-ogg-theora>
-
-   A new feature that was added in the 0.12 version possibility to
-   specify that transcoded streams should be sent out using
-   chunked HTTP encoding. This is now the default setting, since
-   chunked encoding is preferred with content where the content
-   length is not known. The setting can be controlled on a per
-   profile basis using the following parameter:
-<use-chunked-encoding>yes</use-chunked-encoding>
-
-4. Testing And Troubleshooting
-
-   The external transcoding feature is very flexible, however
-   there is a price for flexibility: a lot of things can go wrong.
-   This section will try to cover the most common problems and
-   present some methods on how things can be tested outside of
-   MediaTomb.
-
-4.1. Testing The Transcoder
-
-   It's a good idea to test your transcoding application before
-   putting together a profile. As described in the previous
-   sections we get the transcoded stream via a FIFO, so it's
-   important that the transcoder is capable of writing the output
-   to a FIFO. This can be easily tested in the Linux command
-   prompt.
-
-   Open a terminal and issue the following command:
-mkfifo /tmp/tr-test
-
-   This will create a FIFO called tr-test in the /tmp directory.
-   Open a second terminal, we will use one terminal to run the
-   transcoder, and another one to examine the output.
-
-   For this test we will assume that we want to transcode an OGG
-   file to WAV, the easiest way to do so is to use the ogg123
-   program which is part of the vorbis-tools package. Running
-   ogg123 with the -d wav -f outfile parameter is exactly what we
-   want, just remember that our outfile is the FIFO. So, run the
-   following command, replacing some audio file with an OGG file
-   that is available on your system, in one of the terminals:
-ogg123 -d wav -f /tmp/tr-test /some/audio/file.ogg
-
-   The program will start and will appear to be hanging - it's
-   blocked because noone is reading from the FIFO. While ogg123 is
-   hanging, go to the second terminal and try playing directly
-   from the FIFO (in this example we will use VLC to do that):
-vlc /tmp/tr-test
-
-   If all goes well you should see that ogg123 is coming to life
-   and you should hear the output from VLC - it should play the
-   transcoded WAV stream.
-
-4.2. Troubleshooting
-
-   This section will try to cover the most common problems related
-   to the external transcoding feature.
-
-4.2.1. Media Is Unplayable
-
-   What if the resulting stream is unplayable?
-
-   This can be the case with some media formats and contaeinrs. A
-   good example is the AVI container - it contains the index at
-   the very end of the file, meaning, that a player needs to seek
-   to the end to get the index before rendering the video. Since
-   seeking is not possible in transcoded streams you will not be
-   able to transcode something to AVI and watch it from the FIFO.
-
-4.2.2. Transcoding Does Not Start
-
-   As explained in the previous sections, transcoding only starts
-   when your player issues an HTTP GET request to the server.
-   Further, the request must be made to the transcoding URL.
-
-   Most common cases are:
-     * wrong mime type mapping: are you sure that you specified
-       the source mime type correctly? Recheck the settings in the
-       <mimetype-profile> section. If you are not sure about the
-       source mime type of your media you can always check that
-       via the web UI - just pick one of the files in question and
-       click on the Edit icon.
-     * wrong output mime type: make sure that the mime type
-       specified in the profile matches the media format that is
-       produced by your transcoder.
-     * no permissions to execute the transcoding application:
-       check that the user under which MediaTomb is running has
-       sufficient permissions to run the transcoding script or
-       application.
-     * transcoding script is not executable or is not in $PATH: if
-       you use a wrapper script around your transcoder, make sure
-       that it is executable and can be found in $PATH (unless you
-       specified an absolute name)
-
-4.2.3. Problem Transcoding Online Streams
-
-   Some transcoding applications do not accept online content
-   directly or have problems transcoding online media. If this is
-   the case, set the <accept-url> option appropriately (currently
-   MediaTomb only supports proxying of HTTP streams). This will
-   put the transcoder between two FIFOs, the online content will
-   be downloaded by MediaTomb and fed to the transcoder via a
-   FIFO.
diff --git a/doc/ui_utf8.txt b/doc/ui_utf8.txt
deleted file mode 100644
index b5115b0..0000000
--- a/doc/ui_utf8.txt
+++ /dev/null
@@ -1,402 +0,0 @@
-MediaTomb - User Interface
-
-   This documentation is valid for MediaTomb version 0.12.1.
-
-   Copyright © 2005 Gena Batsyan, Sergey Bostandzhyan
-
-   Copyright © 2006-2010 Gena Batsyan, Sergey Bostandzhyan,
-   Leonhard Wimmer
-
-   THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR
-   OWN RISK!
-     __________________________________________________________
-
-   Table of Contents
-
-   1. Introduction
-   2. Icon Reference
-
-        2.1. Database View
-        2.2. Filesystem View
-        2.3. UI Status
-
-1. Introduction
-
-   MediaTomb comes with an AJAX driven web user interface that
-   allows to add or remove media from the database and modify
-   properties of media items. It also provides the means of
-   selecting various Autoscan options. The UI is constantly
-   improving, our goal is to offer a wide range of features to
-   allow the user to easily control the server.
-
-   Note:
-          the link to the Web UI is printed upon server startup in
-          the console. Consult the main docs for more information.
-
-2. Icon Reference
-
-   Here is a list of icons used in the MediaTomb UI.
-
-2.1. Database View
-
-   The database view presents the content that was added to the
-   servers database - this is the hierarchy that will be served to
-   UPnP devices.
-
-2.1.1.  [document-new.png] Create New Object
-
-   Manually creates a new object in the database.
-
-   An object type can be selected from the drop down list and is
-   one of the following:
-     *
-Container
-
-       A container, that can hold other containers or items.
-       Allowed settings:
-          +
-Title
-
-            Title of the container as it will appear in the UI or
-            as it will be presented to UPnP devices.
-          +
-Class
-
-            UPnP class of the container, leave the default setting
-            if you are unsure.
-     *
-Item
-
-       A media item, typically an audio, photo or video file that
-       resides on the servers local file system.
-       Allowed settings:
-          +
-Title
-
-            Title of the item as it will appear in the UI or as it
-            will be presented to UPnP devices, this can be
-            anything and does not have to be the actual file name.
-          +
-Location
-
-            The location of the file on disk, must be given by an
-            absolute path.
-          +
-Class
-
-            UPnP class of the container, leave the default setting
-            if you are unsure.
-          +
-Description
-
-            Free text describing the item, it may be shown on the
-            UPnP device depending on its implementation and
-            capabilities.
-          +
-Mimetype
-
-            This identifies the mime type of the media and is
-            probably one of the most important fields - this will
-            tell your device what kind of file it is dealing with.
-            If you are unsure, use the file utility to retrieve
-            the mime type information, type the following in a
-            console (this example uses a jpg image):
-file -i /opt/media/photos/key70113.jpg
-
-            The output from the file utility will be something
-            like:
-/opt/media/photos/key70113.jpg: image/jpeg
-
-            For the example above you would have to enter
-            image/jpeg in the Mimetype field.
-     *
-Active Item
-
-       Active Item is an experimental feature, it allows you to
-       execute a script or a program on the server when this item
-       is being downloaded - or “triggered”. Refer to the Active
-       Item documentation for more information.
-          +
-Title
-
-            Title of the item as it will appear in the UI or as it
-            will be presented to UPnP devices, this can be
-            anything and does not have to be the actual file name.
-          +
-Location
-
-            The location of the file on disk, must be given by an
-            absolute path.
-          +
-Class
-
-            UPnP class of the container, leave the default setting
-            if you are unsure.
-          +
-Description
-
-            Free text describing the item, it may be shown on the
-            UPnP device depending on its implementation and
-            capabilities.
-          +
-Mimetype
-
-            This identifies the mime type of the media and is
-            probably one of the most important fields - this will
-            tell your device what kind of file it is dealing with.
-          +
-Action Script
-
-            Location of the Action Script, take a look at an
-            example script demo_toggle.py in the mediatomb/scripts
-            directory.
-          +
-State
-
-            Arbitrary string, identifying the current state of the
-            Active Item. It is made available to the script and
-            allows the script to decide which action to take (for
-            example when implementing “ON” - “OFF” switches).
-     *
-External Link (URL)
-
-       An online stream or file, located somewhere on the web.
-       Allowed settings:
-          +
-Title
-
-            Title of the item as it will appear in the UI or as it
-            will be presented to UPnP devices, this can be
-            anything and does not have to be the actual file name.
-          +
-URL
-
-            The URL to the stream, for example
-            http://www.deadlock.dhs.org/192/Deadlock_Veteran.04.Uz
-            nik.mp3
-          +
-Protocol
-
-            Usually http-get will be fine, but you can specify
-            settings for rtsp and other streaming protocols
-            depending on the presentation of the online content.
-          +
-Class
-
-            UPnP class of the container, leave the default setting
-            if you are unsure.
-          +
-Description
-
-            Free text describing the item, it may be shown on the
-            UPnP device depending on its implementation and
-            capabilities.
-          +
-Mimetype
-
-            This identifies the mime type of the media and is
-            probably one of the most important fields - this will
-            tell your device what kind of file it is dealing with.
-     *
-Internal Link (Local URL)
-
-       A media item, typically an audio, photo or video file that
-       resides in the servedir as defined in the servers
-       configuration file, see main documentation for an example.
-       Allowed settings:
-          +
-Title
-
-            Title of the item as it will appear in the UI or as it
-            will be presented to UPnP devices, this can be
-            anything and does not have to be the actual file name.
-          +
-URL
-
-            The location of the file on disk, relative to the
-            servedir entry.
-          +
-Class
-
-            UPnP class of the container, leave the default setting
-            if you are unsure.
-          +
-Description
-
-            Free text describing the item, it may be shown on the
-            UPnP device depending on its implementation and
-            capabilities.
-          +
-Mimetype
-
-            This identifies the mime type of the media and is
-            probably one of the most important fields - this will
-            tell your device what kind of file it is dealing with.
-
-2.1.2.  [stock_edit.png] Edit Object
-
-   Allows to edit various object properties. The available fields
-   vary, depending on the type of the object but will be generally
-   the same as described above.
-
-   Note:
-          you can not modify the title and the location of objects
-          in the PC-Directory because it is a special container
-          that must guarantee a 1:1 mapping to the file system.
-
-   Note:
-          by editing object properties you do not change the
-          original file on your drive (i.e. you do not modify any
-          id3 or other information), the properties are edited in
-          the MediaTomb database.
-
-2.1.3.  [remove_this.png] Remove This
-
-   Removes the object from the database. This icon is available
-   for virtual items (items that were created by the import
-   script) and also for icons in PC Directory. When used on a
-   virtual item it will only remove the current reference, but it
-   will keep the original object in PC-Directory. When used on an
-   item in PC-Directory it will remove the item and all it's
-   references.
-
-   Note:
-          the remove feature does not touch the files on your
-          drive, the remove operation is only performed in the
-          MediaTomb database.
-
-2.1.4.  [remove_all.png] Remove Linked
-
-   Removes the object and all its references from the database.
-   This icon is only available for virtual items, not only will it
-   erase the current reference, but it will also remove the
-   original item in the PC-Directory container and all associated
-   items.
-
-   Note:
-          the remove feature does not touch the files on your
-          drive, the remove operation is only performed in the
-          MediaTomb database.
-
-2.1.5.  [add_as_autoscan.png] Set Autoscan Properties
-
-   You can use the autoscan feature to monitor data in a certain
-   directory, changes will be periodically synced with the
-   database.
-
-   In the database view this icon is only available for containers
-   in the PC-Directory. Here are the possible settings:
-     *
-Scan Mode
-
-       Defines the autoscan mode, can be one of the following:
-          +
-None
-
-            The directory is not being autoscanned.
-          +
-Timed
-
-            Enable timed rescans. The directory will be rescanned
-            in intervals specified below.
-          +
-Inotify
-
-            Enable filesystem event based rescans - this is only
-            available when MediaTomb was compiled with the inotify
-            feature.
-     *
-Scan Level
-
-       Defines the autoscan type, can be one of the following:
-          +
-Basic
-
-            The “Basic” autoscan type will only keep track if
-            files have been added to or have been removed from the
-            monitored directory. It will not detect changes inside
-            the files, i.e. if you modify an id3 tag of your MP3,
-            the metadata in the database will not be updated.
-          +
-Full
-
-            The “Full” autoscan type will not only keep track of
-            deleted or newly added files, but it will also watch
-            the modification times and re add the media if it
-            detects any changes. This might be useful if you
-            updated the id3 information of an mp3 file or exif
-            information of an image file.
-     *
-Recursive
-
-       Operate recursively, also monitoring files in
-       subdirectories.
-     *
-Include hidden files/directories
-
-       Process or ignore hidden files and directories, i.e. those
-       starting with a dot.
-     *
-Scan Interval
-
-       Interval in seconds, the directory will be rescanned in
-       given intervals.
-
-        Note:
-                the countdown for the next rescan starts only
-                after the current scan is complete.
-
-2.1.6.  [autoscan_inotify_folder_open.png] Inotify Autoscan Container
-
-   Identifies an autoscan container of the Inotify scan type.
-
-2.1.7.  [autoscan_inotify_config_folder_open.png] Persistent Inotify
-Autoscan Container
-
-   Identifies an autoscan container of the Inotify scan type that
-   was setup via the server configuratoin file. It is treated as
-   persistent and can not be removed in the UI.
-
-2.1.8.  [autoscan_timed_folder_open.png] Timed Autoscan Container
-
-   Identifies an autoscan container of the Timed scan type.
-
-2.1.9.  [autoscan_timed_config_folder_open.png] Persistent Timed
-Autoscan Container
-
-   Identifies an autoscan container of the Timed scan type that
-   was setup via the server configuratoin file. It is treated as
-   persistent and can not be removed in the UI.
-
-2.2. Filesystem View
-
-   The Filesystem View allows you to browse the contents of your
-   harddrive and add media to the severs database.
-
-2.2.1.  [stock-add.png] Add File or Directory
-
-   Adds a file or directory to the servers database, use this to
-   make your media available to UPnP devices.
-
-2.2.2.  [add_as_autoscan.png] Set Autoscan Properties
-
-   Same as Section 2.1.5, “ [add_as_autoscan.png] Set Autoscan
-   Properties”
-
-2.3. UI Status
-
-2.3.1.  [status_loading.png] Loading
-
-   Red eyes indicate that the UI is currently loading
-   data/building up the tree structure.
-
-2.3.2.  [status_updates_pending.png] Updates Pending
-
-   Orange eyes indicate that the database has changed and that the
-   UI needs to be updated in order to reflect those changes. The
-   update will usually take place after a certain timeout, which
-   depends on your actions. If you are constantly navigating, the
-   update will be delayed further to prevent the case that the
-   tree gets updated during navigation - this would be very
-   annoying. You can skip the timeout and cause an immediate
-   update by clicking on the skull icon.
diff --git a/mediatomb.spec.in b/mediatomb.spec.in
deleted file mode 100644
index 0942ad0..0000000
--- a/mediatomb.spec.in
+++ /dev/null
@@ -1,132 +0,0 @@
-%define name mediatomb 
-%define version @VERSION@
-%define release 1%{?dist}
-
-Version: %{version}
-Summary: MediaTomb - UPnP AV Mediaserver for Linux
-Name: %{name}
-Release: %{release}
-License: GPLv2
-Group: Applications/Multimedia
-Source: http://downloads.sourceforge.net/mediatomb/%{name}-%{version}.tar.gz
-URL: http://mediatomb.cc
-Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) 
-BuildRequires: sqlite-devel, mysql-devel, libexif-devel, taglib-devel, file-devel, js-devel, zlib-devel
-Requires: mysql
-Requires(pre): shadow-utils
-Requires(post): /sbin/chkconfig
-Requires(preun): /sbin/chkconfig
-Requires(preun): /sbin/service
-
-%description
-MediaTomb is an open source (GPL) UPnP MediaServer with a nice web user 
-interface, it allows you to stream your digital media through your home
-network and listen to/watch it on a variety of UPnP compatible devices.
-
-MediaTomb implements the UPnP MediaServer V 1.0 specification that can 
-be found on http://www.upnp.org/.
-%prep 
-%setup -q
-
-%build
-%configure --enable-taglib
-%{__make} %{?_smp_mflags}
-
-
-%install
-%{__rm} -rf $RPM_BUILD_ROOT
-
-%{__install} -p -D -m0755 scripts/mediatomb-service-fedora $RPM_BUILD_ROOT%{_initrddir}/mediatomb
-%{__install} -p -D -m0644 config/mediatomb-conf-fedora $RPM_BUILD_ROOT%{_sysconfdir}/mediatomb.conf
-make install DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p"
-
-# make all files under %%_sysconfdir/mediatomb are owned by
-# this package
-%{__mkdir_p} $RPM_BUILD_ROOT%{_sysconfdir}/mediatomb
-touch $RPM_BUILD_ROOT%{_sysconfdir}/mediatomb/{config.xml,mediatomb.db,mediatomb.html}
-%{__mkdir_p}  $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d
-
-%{__cat} > $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/%{name} << 'EOF'
-/var/log/mediatomb {
-create 644 root root
-	monthly
-        compress
-        missingok
-}
-EOF
-
-%clean
-%{__rm} -rf $RPM_BUILD_ROOT
-
-%pre
-getent group mediatomb >/dev/null || groupadd -r mediatomb
-getent passwd mediatomb >/dev/null || \
-useradd -r -g mediatomb -d %{_sysconfdir}/mediatomb -s /sbin/nologin \
-    -c "To run Mediatomb" mediatomb
-exit 0
-
-%post
-/sbin/chkconfig --add mediatomb
-
-%preun
-if [ $1 = 0 ]; then
-        /sbin/service mediatomb stop >/dev/null 2>&1
-        /sbin/chkconfig --del mediatomb
-fi
-
-%files
-%defattr(-,root,root,-)
-%doc README README.UTF_8 AUTHORS ChangeLog COPYING doc/doxygen.conf
-%doc doc/scripting.txt doc/scripting_utf8.txt
-%attr(-,mediatomb,mediatomb)%config(noreplace) %{_sysconfdir}/mediatomb.conf
-%attr(-,mediatomb,mediatomb)%dir %{_sysconfdir}/%{name}/
-%attr(-,mediatomb,mediatomb)%ghost %{_sysconfdir}/%{name}/*
-%config(noreplace) %{_sysconfdir}/logrotate.d/%{name}
-%{_bindir}/mediatomb
-%{_datadir}/%{name}/*
-%{_mandir}/man1/*
-%{_initrddir}/mediatomb
-
-%changelog
-* Fri Jan 4 2008 Sergey Bostandzhyan <jin at mediatomb.cc> 0.10.0-8
-- Removed libextractor and enabled taglib instead of id3lib
-
-* Thu Jan 3 2008 Marc Wiriadisastra <marc at mwiriadi.id.au> 0.10.0-7
-- Added mysql-devel to build requires
-
-* Thu Jan 3 2008 Marc Wiriadisastra <marc at mwiriadi.id.au> 0.10.0-6
-- Cleaned up spec file
-
-* Wed Jan 2 2008 Marc Wiriadisastra <marc at mwiriadi.id.au> 0.10.0-5
-- Added mysql-libs for build requires instead of mysql-devel
-
-* Wed Jan 2 2008 Marc Wiriadisastra <marc at mwiriadi.id.au> 0.10.0-4
-- Actually added the patches to the file.
-- Added the ownership changes (Mamoru Tasaka)
-- Libextractor enabled
-
-* Wed Jan 2 2008 Marc Wiriadisastra <marc at mwiriadi.id.au> 0.10.0-3
-- Added patchs to patch ownership of /etc/mediatomb.conf and /etc/mediatomb
-- Adjusted pre and post scripts and add user and group mediatomb
-- Changed attributes so files are owned by mediatomb
-- Cleaned Requires and added two files for build-requires
-
-* Sun Dec 23 2007 Marc Wiriadisastra <marc at mwiriadi.id.au> 0.10.0-2
-- Altered spec file for inclusion into Fedora
-* Wed Jul 11 2007 Sergey Bostandzhyan <jin at mediatomb.cc> 0.10.0-1
-- Version is now filled in by the configure script.
-* Sun May 27 2007 Sergey Bostandzhyan <jin at mediatomb.cc> 0.9.1-1
-- updated the init script
-* Sun Mar 25 2007 Sergey Bostandzhyan <jin at mediatomb.cc> 0.9.0-1
-- Synced with the new script naming and adjusted for the release,
-  added man page.
-* Mon Feb 26 2007 Sergey Bostandzhyan <jin at mediatomb.cc>
-- Removed some files that were no longer needed.
-* Wed Sep  7 2005 Sergey Bostandzhyan <jin at mediatomb.cc>
-- Removed some buildrequires, our configure script should handle different
-  scenarios itself.
-* Wed Jun 15 2005 Sergey Bostandzhyan <jin at mediatomb.cc>
-- Added init.d script + chkconfig
-* Thu Apr 14 2005 Sergey Bostandzhyan <jin at mediatomb.cc>
-- Initial release
-
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
deleted file mode 100644
index fd15406..0000000
--- a/scripts/Makefile.am
+++ /dev/null
@@ -1,9 +0,0 @@
-SUBDIRS = js
-
-_DIST_FILES = \
-    demo_toggle.py \
-    mediatomb-service-fedora \
-	mediatomb-service-optware \
-	mediatomb-prerm-optware
-
-EXTRA_DIST = $(_DIST_FILES)
diff --git a/scripts/gen_readme.sh b/scripts/gen_readme.sh
deleted file mode 100755
index c2347ba..0000000
--- a/scripts/gen_readme.sh
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/sh
-# $Id$
-
-gen_readme () {
-
-if [ -e $FILENAME.lyx ]; then
-    rm -f $FILENAME.xml && \
-    lyx -e docbook-xml $FILENAME.lyx && \
-    xmlto xhtml-nochunks -m sections.xsl $FILENAME.xml && \
-    perl ../scripts/readme_xhtml_div_extract.pl < ${FILENAME}.html > ${FILENAME}_part.html && \
-    xmlto txt -m sections.xsl $FILENAME.xml && \
-    mv $FILENAME.txt $FILENAME_UTF_8 && \
-    perl ../scripts/readme_utf-8_acsii_convert.pl < $FILENAME_UTF_8 > $FILENAME_ASCII && \
-    echo finished successfully
-else
-    echo $FILENAME.lyx not found
-fi
-
-}
-
-FILENAME=readme
-FILENAME_ASCII=README
-FILENAME_UTF_8=$FILENAME_ASCII.UTF_8
-gen_readme
-
-FILENAME=scripting
-FILENAME_ASCII=scripting.txt
-FILENAME_UTF_8=scripting_utf8.txt
-gen_readme
-
-FILENAME=ui
-FILENAME_ASCII=ui.txt
-FILENAME_UTF_8=ui_utf8.txt
-gen_readme
-
-FILENAME=transcoding
-FILENAME_ASCII=transcoding.txt
-FILENAME_UTF_8=transcoding_utf8.txt
-gen_readme
-
diff --git a/scripts/install-duktape.sh b/scripts/install-duktape.sh
new file mode 100755
index 0000000..4599d33
--- /dev/null
+++ b/scripts/install-duktape.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -ex
+wget http://duktape.org/duktape-2.1.0.tar.xz
+tar -xJvf duktape-2.1.0.tar.xz
+cd duktape-2.1.0
+make -f Makefile.sharedlibrary && sudo make -f Makefile.sharedlibrary install
\ No newline at end of file
diff --git a/scripts/install-pupnp18.sh b/scripts/install-pupnp18.sh
new file mode 100755
index 0000000..dd3155a
--- /dev/null
+++ b/scripts/install-pupnp18.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+set -ex
+wget https://github.com/mrjimenez/pupnp/archive/release-1.8.1.tar.gz -O pupnp-1.8.1.tgz
+tar -xzvf pupnp-1.8.1.tgz
+cd pupnp-release-1.8.1
+./bootstrap && ./configure --prefix=/usr --enable-ipv6 --enable-reuseaddr && make && sudo make install
diff --git a/scripts/install-taglib111.sh b/scripts/install-taglib111.sh
new file mode 100755
index 0000000..e51fffb
--- /dev/null
+++ b/scripts/install-taglib111.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+set -ex
+wget http://taglib.github.io/releases/taglib-1.11.1.tar.gz
+tar -xzvf taglib-1.11.1.tar.gz
+mkdir taglib-build
+cd taglib-build
+if [[ $CXX == clang++* ]]; then
+	cmake -DCMAKE_CXX_FLAGS="-stdlib=libc++" ../taglib-1.11.1
+else
+	cmake ../taglib-1.11.1
+fi
+make && sudo make install
diff --git a/scripts/js/Makefile.am b/scripts/js/Makefile.am
deleted file mode 100644
index 429b97d..0000000
--- a/scripts/js/Makefile.am
+++ /dev/null
@@ -1,7 +0,0 @@
-_DIST_FILES_JS = \
-    import.js \
-    playlists.js \
-    common.js
-
-jsdir = $(pkgdatadir)/js
-dist_js_DATA = $(_DIST_FILES_JS)
diff --git a/scripts/js/import-dvd.js b/scripts/js/import-dvd.js
deleted file mode 100644
index 3edd97c..0000000
--- a/scripts/js/import-dvd.js
+++ /dev/null
@@ -1,112 +0,0 @@
-// Default MediaTomb dvd import script.
-// see MediaTomb scripting documentation for more information
-
-/*MT_F*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    import-dvd.js - this file is part of MediaTomb.
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    This file is free software; the copyright owners give unlimited permission
-    to copy and/or redistribute it; with or without modifications, as long as
-    this notice is preserved.
-    
-    This file is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-    
-    $Id$
-*/
-
-var title = dvd.title;
-var index = title.lastIndexOf('.');
-if (index > 1)
-    title = title.substring(0, index);
-
-// we got the ISO here but our virtual items should have the video class
-dvd.upnpclass = UPNP_CLASS_ITEM_VIDEO;
-
-var title_count = dvd.aux[DVD].titles.length;
-for (var t = 0; t < title_count; t++)
-{
-    var title_name = 'Title';
-
-    if (t < 9)
-        title_name = title_name + ' 0' + (t + 1);
-    else
-        title_name = title_name + ' ' + (t + 1);
-
-    var chapter_count = dvd.aux[DVD].titles[t].chapters.length;
-    var audio_track_count = dvd.aux[DVD].titles[t].audio_tracks.length;
-    for (var a = 0; a < audio_track_count; a++)
-    {
-        var chain;
-        var audio_name = ' - Audio Track ' + (a + 1);
-        var audio_language = dvd.aux[DVD].titles[t].audio_tracks[a].language;
-        var audio_format = dvd.aux[DVD].titles[t].audio_tracks[a].format;
-        if (audio_format != '')
-        {
-            if (audio_language != '')
-                audio_name = audio_name + ' - ' + audio_language;
-
-            chain = new Array('Video', 'DVD', title, 'Audio Formats', 
-                              audio_format, title_name + audio_name);
-
-            for (var c = 0; c < chapter_count; c++) 
-            {
-                if (c < 9)
-                    dvd.title = "Chapter 0" + (c + 1);
-                else
-                    dvd.title = "Chapter " + (c + 1);
-
-                addDVDObject(dvd, t, c, a, createContainerChain(chain));
-            } 
-        }
-
-        if (audio_language != '')
-        {
-            chain = new Array('Video', 'DVD', title, 'Languages', 
-                              audio_language);
-            if (audio_format != '')
-                chain.push(title_name + audio_name + ' - ' + audio_format);
-            else 
-                chain.push(title_name + audio_name);
-
-            for (var c = 0; c < chapter_count; c++)
-            {
-                if (c < 9)
-                    dvd.title = "Chapter 0" + (c + 1);
-                else
-                    dvd.title = "Chapter " + (c + 1);
-
-                addDVDObject(dvd, t, c, a, createContainerChain(chain));
-            } 
-        }
-
-        chain = new Array('Video', 'DVD', title, 'Titles');
-
-        var titles = title_name + ' - Audio Track ' + (a + 1);
-
-        if (audio_format != '')
-            titles = titles + ' - ' + audio_format;
-
-        if (audio_language != '')
-            titles = titles + ' - ' + audio_language;
-
-        chain.push(titles);
-        
-        for (var c = 0; c < chapter_count; c++)
-        {
-            if (c < 9)
-                dvd.title = "Chapter 0" + (c + 1);
-            else
-                dvd.title = "Chapter " + (c + 1);
-
-            addDVDObject(dvd, t, c, a, createContainerChain(chain));
-        } 
-    }
-}
diff --git a/scripts/js/import.js b/scripts/js/import.js
index 742f543..6a74fb8 100644
--- a/scripts/js/import.js
+++ b/scripts/js/import.js
@@ -151,7 +151,7 @@ function addVideo(obj)
     var chain = new Array('Video', 'All Video');
     addCdsObject(obj, createContainerChain(chain));
 
-    var dir = getRootPath(object_root_path, obj.location);
+    var dir = getRootPath(object_script_path, obj.location);
 
     if (dir.length > 0)
     {
@@ -162,16 +162,6 @@ function addVideo(obj)
     }
 }
 
-function addWeborama(obj)
-{
-    var req_name = obj.aux[WEBORAMA_AUXDATA_REQUEST_NAME];
-    if (req_name)
-    {
-        var chain = new Array('Online Services', 'Weborama', req_name);
-        addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_PLAYLIST_CONTAINER);
-    }
-}
-
 function addImage(obj)
 {
     var chain = new Array('Photos', 'All Photos');
@@ -194,7 +184,7 @@ function addImage(obj)
         addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER);
     }
 
-    var dir = getRootPath(object_root_path, obj.location);
+    var dir = getRootPath(object_script_path, obj.location);
 
     if (dir.length > 0)
     {
@@ -295,9 +285,6 @@ if (getPlaylistType(orig.mimetype) == '')
     
     if (mime == 'audio')
     {
-        if (obj.onlineservice == ONLINE_SERVICE_WEBORAMA)
-            addWeborama(obj);
-        else
             addAudio(obj);
     }
     
diff --git a/scripts/make_server_icons.sh b/scripts/make_server_icons.sh
new file mode 100755
index 0000000..12aabfe
--- /dev/null
+++ b/scripts/make_server_icons.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+# run as
+# make_icons-mediatomb.sh mylogo.jpg
+# Will generate all the required mediatomb icons
+
+src="${1}"
+
+
+convert "${src}" -filter Lanczos -resize x32 -background black -flatten bmp:"mt-icon32.bmp"
+convert "${src}" -filter Lanczos -resize x32 -background black -flatten png:"mt-icon32.png"
+convert "${src}" -filter Lanczos -resize x32 -background black -flatten jpg:"mt-icon32.jpg"
+
+convert "${src}" -filter Lanczos -resize x48 -background black -flatten bmp:"mt-icon48.bmp"
+convert "${src}" -filter Lanczos -resize x48 -background black -flatten png:"mt-icon48.png"
+convert "${src}" -filter Lanczos -resize x48 -background black -flatten jpg:"mt-icon48.jpg"
+
+convert "${src}" -filter Lanczos -resize x120 -background black -flatten bmp:"mt-icon120.bmp"
+convert "${src}" -filter Lanczos -resize x120 -background black -flatten png:"mt-icon120.png"
+convert "${src}" -filter Lanczos -resize x120 -background black -flatten jpg:"mt-icon120.jpg"
diff --git a/scripts/mediatomb-prerm-optware b/scripts/mediatomb-prerm-optware
deleted file mode 100644
index 4e1e174..0000000
--- a/scripts/mediatomb-prerm-optware
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-/opt/etc/init.d/S90mediatomb stop
-
diff --git a/scripts/mediatomb-service-fedora b/scripts/mediatomb-service-fedora
deleted file mode 100755
index de37456..0000000
--- a/scripts/mediatomb-service-fedora
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/bin/sh
-#
-# mediatomb This script starts and stops the mediatomb daemon
-#
-# chkconfig: - 95 30
-# processname: mediatomb
-# description: mediatomb is a daemon process which provides a UPnP service
-# config: /etc/mediatomb
-# config: /etc/mediatomb/config.xml
-# pidfile: /var/run/mediatomb.pid
-
-
-# Source function library.
-. /etc/rc.d/init.d/functions
-
-# Source networking configuration.
-. /etc/sysconfig/network
-
-# Check that networking is up.
-[ ${NETWORKING} = "no" ] && exit 0
-
-# Set default mediatomb configuration.
-
-# either make an installation in /etc/mediatomb and leave this blank,
-# or specify an alternative config file location using the -c option
-# Note: be aware, that -i parameter is used to set the ip of the 
-# interface specified above
-
-. /etc/mediatomb.conf
-
-###############################
-# make sure to run it as nobody
-MEDIATOMB="-d -u $MT_USER -g $MT_GROUP -P $MT_PIDFILE -l $MT_LOGFILE -m $MT_HOME -f $MT_CFGDIR -p $MT_PORT"
-
-[ -f /usr/bin/mediatomb ] || exit 0
-[ ${MT_INTERFACE} = "NOT_SET" ] && echo "Please edit /etc/mediatomb.conf and change \
-the MT_INTERFACE variable to your network device (eth0, eth1, etc.)" && exit 0
-
-PATH=$PATH:/usr/bin:/usr/local/bin
-
-# By default it's all good
-RETVAL=0
-
-# See how we were called.
-case "$1" in
-  start)
-    # Start daemon.
-    echo -n "Applying multicast settings to $MT_INTERFACE... "
-    # those settings are necessary for us to react to M-SEARCH requests
-    route add -net 239.0.0.0 netmask 255.0.0.0 $MT_INTERFACE >/dev/null 2>&1
-    ifconfig $MT_INTERFACE allmulti
-    touch $MT_PIDFILE
-    chown mediatomb $MT_PIDFILE
-
-    mkdir -p "/$MT_HOME/$MT_CFGDIR"
-    chown mediatomb "/$MT_HOME/$MT_CFGDIR"
-    
-    echo -n "Starting mediatomb: "
-    
-    daemon $NICELEVEL mediatomb $MEDIATOMB -e $MT_INTERFACE $MT_OPTIONS
-    
-    RETVAL=$?
-        echo
-        [ $RETVAL = 0 ] && touch /var/lock/subsys/mediatomb
-        ;;
-  stop)
-        # Stop daemons.
-        echo -n "Shutting down mediatomb: "
-        killproc mediatomb
-        RETVAL=$?
-        echo
-        [ $RETVAL = 0 ] && rm -f /var/lock/subsys/mediatomb
-        ;;
-  restart)
-        $0 stop
-        $0 start
-        ;;
-  condrestart)
-       [ -e /var/lock/subsys/mediatomb ] && $0 restart
-       ;;
-  status)
-    status mediatomb
-    RETVAL=$?
-    ;;
-  *)
-    echo "Usage: $0 {start|stop|restart|status|condrestart}"
-    RETVAL=1
-    ;;
-esac
-
-exit $RETVAL
diff --git a/scripts/mediatomb-service-optware.in b/scripts/mediatomb-service-optware.in
deleted file mode 100755
index 10468ef..0000000
--- a/scripts/mediatomb-service-optware.in
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/bin/sh
-#
-# mediatomb This script starts and stops the mediatomb daemon
-#
-# chkconfig: - 95 30
-# processname: mediatomb
-# description: mediatomb is a daemon process which provides a UPnP service
-# config: @prefix@/etc/mediatomb
-# config: @prefix@/etc/mediatomb/config.xml
-# pidfile: @prefix@/var/run/mediatomb.pid
-
-# Source default mediatomb configuration
-. @prefix@/etc/mediatomb.conf
-
-MEDIATOMB="-d -u $MT_USER -g $MT_GROUP -P $MT_PIDFILE -l $MT_LOGFILE -m $MT_HOME -f $MT_CFGDIR -p $MT_PORT"
-
-[ -f @prefix@/bin/mediatomb ] || exit 0
-
-[ -e @prefix@/etc/default/mediatomb ] && . @prefix@/etc/default/mediatomb
-
-# By default it's all good
-RETVAL=0
-
-# See how we were called.
-case "$1" in
-  start)
-    if [ ${MT_ENABLE} = false ] ; then
-        echo "mediatomb startup is disabled in @prefix@/etc/default/mediatomb"
-        exit 0
-    fi
-
-    # Check if MT is already running
-    if [ -e @prefix@/var/lock/mediatomb ] ; then
-        $0 stop
-    fi
-
-    # Start daemon.
-    touch $MT_PIDFILE
-    chown $MT_USER.$MT_GROUP $MT_PIDFILE
-
-    mkdir -p "/$MT_HOME/$MT_CFGDIR"
-    chown  $MT_USER.$MT_GROUP "/$MT_HOME/$MT_CFGDIR"
-    
-    echo -n "Starting mediatomb: "
-    
-    @prefix@/bin/mediatomb $MEDIATOMB $MT_OPTIONS
-    
-    RETVAL=$?
-        if [ $RETVAL = 0 ] ; then 
-            touch @prefix@/var/lock/mediatomb
-            echo "ok"
-        else
-            rm -f ${MT_PIDFILE}
-            echo "failed"
-        fi
-        ;;
-  stop)
-        # Stop daemons.
-        echo -n "Shutting down mediatomb: "
-
-    if [ -f ${MT_PIDFILE} ] ; then
-        kill `cat ${MT_PIDFILE}` 2>/dev/null
-    else
-        killall mediatomb 2>/dev/null
-    fi
-        RETVAL=$?
-        if [ $RETVAL = 0 ] ; then
-            rm -f @prefix@/var/lock/mediatomb
-            rm -f ${MT_PIDFILE}
-            echo "ok"
-        else
-            echo "failed"
-        fi
-        
-        ;;
-  restart)
-        $0 stop
-        $0 start
-        ;;
-  condrestart)
-       [ -e @prefix@/var/lock/mediatomb ] && $0 restart
-       ;;
-  *)
-    $0 start
-    ;;
-esac
-
-exit $RETVAL
diff --git a/scripts/mediatomb_0.9.0.bb b/scripts/mediatomb_0.9.0.bb
deleted file mode 100644
index 33b76c2..0000000
--- a/scripts/mediatomb_0.9.0.bb
+++ /dev/null
@@ -1,30 +0,0 @@
-DESCRIPTION = "MediaTomb - UPnP AV MediaServer for Linux"
-HOMEPAGE = "http://mediatomb.cc/"
-LICENSE = "GPLv2"
-DEPENDS = "sqlite3 libexif js zlib file id3lib"
-PR = "r0"
-
-SRC_URI = "${SOURCEFORGE_MIRROR}/mediatomb/mediatomb-${PV}.tar.gz"
-
-inherit autotools pkgconfig
-
-EXTRA_OECONF = "--disable-mysql \
-                --disable-rpl-malloc \
-                --enable-sqlite3 \
-                --enable-libjs \
-                --enable-libmagic \
-                --enable-id3lib \
-                --enable-libexif \
-                --disable-largefile \
-                --with-sqlite3-h=${STAGING_INCDIR} \
-                --with-sqlite3-libs=${STAGING_LIBDIR} \
-                --with-magic-h=${STAGING_INCDIR} \
-                --with-magic-libs=${STAGING_LIBDIR} \
-                --with-exif-h=${STAGING_INCDIR} \
-                --with-exif-libs=${STAGING_LIBDIR} \
-                --with-zlib-h=${STAGING_INCDIR} \
-                --with-zlib-libs=${STAGING_LIBDIR} \
-                --with-js-h=${STAGING_INCDIR}/js \
-                --with-js-libs=${STAGING_LIBDIR} \
-                --with-id3lib-h=${STAGING_INCDIR} \
-                --with-id3lib-libs=${STAGING_LIBDIR}"
diff --git a/scripts/mediatomb_svn.bb b/scripts/mediatomb_svn.bb
deleted file mode 100644
index 9a2451b..0000000
--- a/scripts/mediatomb_svn.bb
+++ /dev/null
@@ -1,33 +0,0 @@
-DESCRIPTION = "MediaTomb - UPnP AV MediaServer for Linux"
-HOMEPAGE = "http://mediatomb.org/"
-LICENSE = "GPLv2"
-DEPENDS = "sqlite3 libexif js zlib file id3lib"
-PV = "0.8+0.9pre1+svn${SRCDATE}-sqlite"
-PR = "r1"
-
-SRC_URI = "svn://mediatomb.svn.sourceforge.net/svnroot/mediatomb/trunk;proto=https;module=mediatomb"
-
-S = "${WORKDIR}/mediatomb"
-
-inherit autotools pkgconfig
-
-EXTRA_OECONF = "--disable-mysql \
-                --disable-rpl-malloc \
-                --enable-sqlite3 \
-                --enable-libjs \
-                --enable-libmagic \
-                --enable-id3lib \
-                --enable-libexif \
-                --disable-largefile \
-                --with-sqlite3-h=${STAGING_INCDIR} \
-                --with-sqlite3-libs=${STAGING_LIBDIR} \
-                --with-magic-h=${STAGING_INCDIR} \
-                --with-magic-libs=${STAGING_LIBDIR} \
-                --with-exif-h=${STAGING_INCDIR} \
-                --with-exif-libs=${STAGING_LIBDIR} \
-                --with-zlib-h=${STAGING_INCDIR} \
-                --with-zlib-libs=${STAGING_LIBDIR} \
-                --with-js-h=${STAGING_INCDIR}/js \
-                --with-js-libs=${STAGING_LIBDIR} \
-                --with-id3lib-h=${STAGING_INCDIR} \
-                --with-id3lib-libs=${STAGING_LIBDIR}"
diff --git a/scripts/readme_utf-8_acsii_convert.pl b/scripts/readme_utf-8_acsii_convert.pl
deleted file mode 100755
index fc73091..0000000
--- a/scripts/readme_utf-8_acsii_convert.pl
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/perl
-
-use Text::Iconv;
-
-my $converter = Text::Iconv->new("UTF-8", "ASCII");
-
-while (<>)
-{
-    s/━/-/g;
-    s/●/*/g;
-    s/â—‹/o/g;
-    s/â–¡/-/g;
-    s/“/"/g;
-    s/”/"/g;
-    s/ / /g;
-    s/ä/ae/g;
-    s/ü/ue/g;
-    s/ö/oe/g;
-    s/ß/ss/g;
-    s/©/(c)/g;
-    s/é/e/g;
-    
-    my $converted = $converter->convert($_);
-    if ($converted)
-    {
-        print $converted;
-    }
-    else
-    {
-        print STDERR  "$0: cannot convert (line $.): $_\n";
-        exit 1;
-    }
-    #print;
-}
diff --git a/scripts/readme_xhtml_div_extract.pl b/scripts/readme_xhtml_div_extract.pl
deleted file mode 100755
index c5795cc..0000000
--- a/scripts/readme_xhtml_div_extract.pl
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/perl
-
-use XML::DOM;
-use XML::XQL;
-use XML::XQL::DOM;
-use utf8;
-
-binmode STDOUT, ":utf8";
-
-sub my_tag_compression
-{
-    my ($tag, $elem) = @_;
-    
-    # Print empty br, hr and img tags like this: <br />
-    return 2 if $tag =~ /^(br|hr|img)$/;
-    
-    # Print other empty tags like this: <empty></empty>
-    return 1;
-}
-
-XML::DOM::setTagCompression (\&my_tag_compression);
-
-my $parser = new XML::DOM::Parser;
-#my $doc = $parser->parsefile ("readme.html");
-my $doc = $parser->parse(\*STDIN);
-
-my @res = $doc->xql('//div[h2/@class="title"]');
-if (! @res)
-{
-    @res = $doc->xql('//div[h1/@class="title"]');
-}
-
-#$res[0]->getParentNode()->removeChild($res[0]);
-
- at res = $doc->xql("/html/body/div/*");
-
-foreach (@res)
-{
-    print $_->toString();
-}
diff --git a/scripts/systemd/gerbera-mysql.service b/scripts/systemd/gerbera-mysql.service
new file mode 100644
index 0000000..deefe4d
--- /dev/null
+++ b/scripts/systemd/gerbera-mysql.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Gerbera Media Server with MySQL
+After=mysql.target network.target
+
+[Service]
+Type=simple
+User=gerbera
+Group=gerbera
+ExecStart=/usr/bin/gerbera -c /etc/gerbera/config.xml
+Restart=on-failure
+RestartSec=5
+
+[Install]
+WantedBy=multi-user.target
diff --git a/scripts/systemd/gerbera.service b/scripts/systemd/gerbera.service
new file mode 100644
index 0000000..71e0cc7
--- /dev/null
+++ b/scripts/systemd/gerbera.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Gerbera Media Server
+After=network.target
+
+[Service]
+Type=simple
+User=gerbera
+Group=gerbera
+ExecStart=/usr/bin/gerbera -c /etc/gerbera/config.xml
+Restart=on-failure
+RestartSec=5
+
+[Install]
+WantedBy=multi-user.target
diff --git a/src/action_request.cc b/src/action_request.cc
index 6a78a16..056c662 100644
--- a/src/action_request.cc
+++ b/src/action_request.cc
@@ -29,28 +29,22 @@
 
 /// \file action_request.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "action_request.h"
 
 using namespace zmm;
 using namespace mxml;
 
-ActionRequest::ActionRequest(Upnp_Action_Request *upnp_request) : Object()
+ActionRequest::ActionRequest(UpnpActionRequest *upnp_request) : Object(),
+    upnp_request(upnp_request),
+    errCode(UPNP_E_SUCCESS),
+    actionName(UpnpActionRequest_get_ActionName_cstr(upnp_request)),
+    UDN(UpnpActionRequest_get_DevUDN_cstr(upnp_request)),
+    serviceID(UpnpActionRequest_get_ServiceID_cstr(upnp_request))
 {
-    this->upnp_request = upnp_request;
-
-    errCode = UPNP_E_SUCCESS;
-    actionName = upnp_request->ActionName;
-    UDN = upnp_request->DevUDN;
-    serviceID = upnp_request->ServiceID;
-
-    DOMString cxml = ixmlPrintDocument(upnp_request->ActionRequest);
+    DOMString cxml = ixmlPrintDocument(UpnpActionRequest_get_ActionRequest(upnp_request));
     String xml = cxml;
     ixmlFreeDOMString(cxml);
-   
+
     Ref<Parser> parser(new Parser());
 
     request = parser->parseString(xml)->getRoot();
@@ -84,24 +78,28 @@ void ActionRequest::setErrorCode(int errCode)
 
 void ActionRequest::update()
 {
-    if(response != nil)
+    if(response != nullptr)
     {
         String xml = response->print();
         int ret;
 
-        //log_debug("ActionRequest::update(): \n%s\n\n", xml.c_str());
-        
-        ret = ixmlParseBufferEx(xml.c_str(), &upnp_request->ActionResult);
+        log_debug("ActionRequest::update(): \n%s\n\n", xml.c_str());
+
+        IXML_Document *result = ixmlDocument_createDocument();
+        ret = ixmlParseBufferEx(xml.c_str(), &result);
+
         if (ret != IXML_SUCCESS)
         {
             log_error("ActionRequest::update(): could not convert to iXML\n");
             log_debug("Dump:\n%s\n", xml.c_str());
-            upnp_request->ErrCode = UPNP_E_ACTION_FAILED;    
+
+            UpnpActionRequest_set_ErrCode(upnp_request, UPNP_E_ACTION_FAILED);
         } 
         else
         {
-//            log_debug("ActionRequest::update(): converted to iXML, code %d\n", errCode);
-            upnp_request->ErrCode = errCode;    
+            log_debug("ActionRequest::update(): converted to iXML, code %d\n", errCode);
+            UpnpActionRequest_set_ActionResult(upnp_request, result);
+            UpnpActionRequest_set_ErrCode(upnp_request, errCode);
         }
     }
     else
@@ -111,10 +109,10 @@ void ActionRequest::update()
         // then we keep it
         // if it did not do so - we set an error code of our own
         if (errCode == UPNP_E_SUCCESS) 
-        {   
-            upnp_request->ErrCode = UPNP_E_ACTION_FAILED;
+        {
+            UpnpActionRequest_set_ErrCode(upnp_request, UPNP_E_ACTION_FAILED);
         }
         
-        log_error("ActionRequest::update(): response is nil, code %d\n", errCode);
+        log_error("ActionRequest::update(): response is nullptr, code %d\n", errCode);
     }
 }
diff --git a/src/action_request.h b/src/action_request.h
index b150af1..7c1d97a 100644
--- a/src/action_request.h
+++ b/src/action_request.h
@@ -33,31 +33,32 @@
 #ifndef __ACTION_REQUEST_H__
 #define __ACTION_REQUEST_H__
 
+#include <upnp-1.8/upnp.h>
+
 #include "common.h"
-#include "upnp.h"
 #include "mxml/mxml.h"
 
 /// \brief This class represents the Upnp_Action_Request type from the SDK.
 ///
 /// When we get a Upnp_Action_Request from the SDK we convert it to our
 /// structure. The idea is to get the XML of the request, process it outside
-/// of the class, create a response XML and put it back in. Before pasing
+/// of the class, create a response XML and put it back in. Before passing
 /// *upnp_request back to the SDK the update() function MUST be called.
 class ActionRequest : public zmm::Object
 {
 protected:
     /// \brief Upnp_Action_Request that comes from the SDK.
-    Upnp_Action_Request *upnp_request;
+    UpnpActionRequest *upnp_request;
 
     /// \brief Error code that is returned to the SDK.
     int errCode;
 
     /// \brief Name of the action.
-    ///
+    ////request///
     /// Returned by getActionName()
     zmm::String actionName;
 
-    /// \brief UDN of the recepient device (it should be our UDN)
+    /// \brief UDN of the recipient device (it should be our UDN)
     ///
     /// Returned by getUDN()
     zmm::String UDN;
@@ -80,12 +81,12 @@ protected:
 public:
     /// \brief The Constructor takes the values from the upnp_request and fills in internal variables.
     /// \param *upnp_request Pointer to the Upnp_Action_Request structure.
-    ActionRequest(Upnp_Action_Request *upnp_request);
+    ActionRequest(UpnpActionRequest *upnp_request);
 
     /// \brief Returns the name of the action. 
     zmm::String getActionName();
 
-    /// \brief Returns the UDN of the recepient device (should be ours)
+    /// \brief Returns the UDN of the recipient device (should be ours)
     zmm::String getUDN();
 
     /// \brief Returns the ID of the service (the action is for this service id)
diff --git a/src/atrailers_content_handler.cc b/src/atrailers_content_handler.cc
index c9d40c1..90f1b5a 100644
--- a/src/atrailers_content_handler.cc
+++ b/src/atrailers_content_handler.cc
@@ -30,10 +30,6 @@
 /// \file atrailers_content_handler.cc
 /// \brief Implementation of the ATrailersContentHandler class.
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #if defined(ATRAILERS)
 
 #include "atrailers_content_handler.h"
@@ -81,8 +77,8 @@ Ref<CdsObject> ATrailersContentHandler::getNextObject()
 
         current_trailer_index++;
       
-        if (n == nil)
-            return nil;
+        if (n == nullptr)
+            return nullptr;
 
         if (n->getType() != mxml_node_element)
             continue;
@@ -97,7 +93,7 @@ Ref<CdsObject> ATrailersContentHandler::getNextObject()
         item->addResource(resource);
 
         Ref<Element> info = trailer->getChildByName(_("info"));
-        if (info == nil)
+        if (info == nullptr)
             continue;
 
         temp = info->getChildText(_("title"));
@@ -123,7 +119,7 @@ Ref<CdsObject> ATrailersContentHandler::getNextObject()
         item->setServiceID(temp);
 
         Ref<Element> preview = trailer->getChildByName(_("preview"));
-        if (preview == nil)
+        if (preview == nullptr)
         {
             log_warning("Failed to retrieve Trailer location for \"%s\", "
                         "skipping...\n", item->getTitle().c_str());
@@ -176,7 +172,7 @@ Ref<CdsObject> ATrailersContentHandler::getNextObject()
         }
 
         Ref<Element> cast = trailer->getChildByName(_("cast"));
-        if (cast != nil)
+        if (cast != nullptr)
         {
             String actors;
             for (int i = 0; i < cast->childCount(); i++)
@@ -205,7 +201,7 @@ Ref<CdsObject> ATrailersContentHandler::getNextObject()
         }
 
         Ref<Element> genre = trailer->getChildByName(_("genre"));
-        if (genre != nil)
+        if (genre != nullptr)
         {
             String genres;
             for (int i = 0; i < genre->childCount(); i++)
@@ -240,7 +236,7 @@ Ref<CdsObject> ATrailersContentHandler::getNextObject()
             I add the fastscaler
 
         Ref<Element> poster = trailer->getChildByName(_("poster"));
-        if (poster != nil)
+        if (poster != nullptr)
         {
         }
         */
@@ -255,14 +251,14 @@ Ref<CdsObject> ATrailersContentHandler::getNextObject()
             item->validate();
             return RefCast(item, CdsObject);
         }
-        catch (Exception ex)
+        catch (const Exception & ex)
         {
             log_warning("Failed to validate newly created Trailer item: %s\n",
                         ex.getMessage().c_str());
             continue;
         }
     } // while
-    return nil;
+    return nullptr;
 }
 
 #endif//ATRAILERS
diff --git a/src/atrailers_content_handler.h b/src/atrailers_content_handler.h
index 73ac300..6885bb5 100644
--- a/src/atrailers_content_handler.h
+++ b/src/atrailers_content_handler.h
@@ -57,9 +57,9 @@ public:
     ///
     /// Each invokation of this funtion will return a new object,
     /// when the whole service XML is parsed and no more objects are left,
-    /// this function will return nil.
+    /// this function will return nullptr.
     ///
-    /// \return CdsObject or nil if there are no more objects to parse.
+    /// \return CdsObject or nullptr if there are no more objects to parse.
     zmm::Ref<CdsObject> getNextObject();
 
 
diff --git a/src/atrailers_service.cc b/src/atrailers_service.cc
index 2bfde48..c397328 100644
--- a/src/atrailers_service.cc
+++ b/src/atrailers_service.cc
@@ -29,10 +29,6 @@
 
 /// \file atrailers_service.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef ATRAILERS 
 
 #include "zmm/zmm.h"
@@ -84,7 +80,7 @@ String ATrailersService::getServiceName()
 Ref<Object> ATrailersService::defineServiceTask(Ref<Element> xmlopt, Ref<Object> params)
 {
     // there are no configurable tasks here, we fetch an XML and parse it
-    return nil;
+    return nullptr;
 }
 
 Ref<Element> ATrailersService::getData()
@@ -100,18 +96,18 @@ Ref<Element> ATrailersService::getData()
         buffer = url->download(service_url, &retcode, 
                                curl_handle, false, true, true);
     }
-    catch (Exception ex)
+    catch (const Exception & ex)
     {
         log_error("Failed to download Apple Trailers XML data: %s\n", 
                   ex.getMessage().c_str());
-        return nil;
+        return nullptr;
     }
 
-    if (buffer == nil)
-        return nil;
+    if (buffer == nullptr)
+        return nullptr;
 
     if (retcode != 200)
-        return nil;
+        return nullptr;
 
     log_debug("GOT BUFFER\n%s\n", buffer->toString().c_str()); 
     Ref<Parser> parser(new Parser());
@@ -119,22 +115,22 @@ Ref<Element> ATrailersService::getData()
     {
         return parser->parseString(sc->convert(buffer->toString()))->getRoot();
     }
-    catch (ParseException pe)
+    catch (const ParseException & pe)
     {
         log_error("Error parsing Apple Trailers XML %s line %d:\n%s\n",
                pe.context->location.c_str(),
                pe.context->line,
                pe.getMessage().c_str());
-        return nil;
+        return nullptr;
     }
-    catch (Exception ex)
+    catch (const Exception & ex)
     {
         log_error("Error parsing Apple Trailers XML %s\n", 
                   ex.getMessage().c_str());
-        return nil;
+        return nullptr;
     }
     
-    return nil;
+    return nullptr;
 }
 
 bool ATrailersService::refreshServiceData(Ref<Layout> layout)
@@ -156,7 +152,7 @@ bool ATrailersService::refreshServiceData(Ref<Layout> layout)
     Ref<Element> reply = getData();
 
     Ref<ATrailersContentHandler> sc(new ATrailersContentHandler());
-    if (reply != nil)
+    if (reply != nullptr)
         sc->setServiceContent(reply);
     else
     {
@@ -168,18 +164,18 @@ bool ATrailersService::refreshServiceData(Ref<Layout> layout)
     do
     {
         obj = sc->getNextObject();
-        if (obj == nil)
+        if (obj == nullptr)
             break;
 
         obj->setVirtual(true);
 
         Ref<CdsObject> old = Storage::getInstance()->loadObjectByServiceID(RefCast(obj, CdsItem)->getServiceID());
-        if (old == nil)
+        if (old == nullptr)
         {
             log_debug("Adding new Trailers object\n");
             
-            if (layout != nil)
-                layout->processCdsObject(obj, nil);
+            if (layout != nullptr)
+                layout->processCdsObject(obj, nullptr);
         }
         else
         {
@@ -198,7 +194,7 @@ bool ATrailersService::refreshServiceData(Ref<Layout> layout)
             return false;
 
     }
-    while (obj != nil);
+    while (obj != nullptr);
 
     return false;
 }
diff --git a/src/atrailers_service.h b/src/atrailers_service.h
index f0eb2e5..2c3f704 100644
--- a/src/atrailers_service.h
+++ b/src/atrailers_service.h
@@ -81,4 +81,4 @@ protected:
 
 #endif//__ONLINE_SERVICE_H__
 
-#endif//WEBORAMA
+#endif//ATRAILERS
diff --git a/src/autoscan.cc b/src/autoscan.cc
index 948ea8e..e8e3e21 100644
--- a/src/autoscan.cc
+++ b/src/autoscan.cc
@@ -29,15 +29,12 @@
 
 /// \file autoscan.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "autoscan.h"
-#include "storage.h"
 #include "content_manager.h"
+#include "storage.h"
 
 using namespace zmm;
+using namespace std;
 
 AutoscanDirectory::AutoscanDirectory()
 {
@@ -46,30 +43,30 @@ AutoscanDirectory::AutoscanDirectory()
     storageID = INVALID_OBJECT_ID;
     last_mod_previous_scan = 0;
     last_mod_current_scan = 0;
-    timer_parameter = Ref<Object> ((Object *)new ContentManager::TimerParameter(ContentManager::TimerParameter::IDAutoscan, INVALID_SCAN_ID));
+    timer_parameter = Ref<Timer::Parameter>(new Timer::Parameter(Timer::Parameter::IDAutoscan, INVALID_SCAN_ID));
 }
 
-AutoscanDirectory::AutoscanDirectory(String location, scan_mode_t mode,
-        scan_level_t level, bool recursive, bool persistent,
-        int id, unsigned int interval, bool hidden)
+AutoscanDirectory::AutoscanDirectory(String location, ScanMode mode,
+    ScanLevel level, bool recursive, bool persistent,
+    int id, unsigned int interval, bool hidden)
+    : location(location)
+    , mode(mode)
+    , level(level)
+    , recursive(recursive)
+    , hidden(hidden)
+    , persistent_flag(persistent)
+    , interval(interval)
+    , taskCount(0)
+    , scanID(id)
+    , objectID(INVALID_OBJECT_ID)
+    , storageID(INVALID_OBJECT_ID)
+    , last_mod_previous_scan(0)
+    , last_mod_current_scan(0)
 {
-    this->location = location;
-    this->mode = mode;
-    this->level = level;
-    this->recursive = recursive;
-    this->hidden = hidden;
-    this->interval = interval;
-    this->persistent_flag = persistent;
-    scanID = id;
-    taskCount = 0;
-    objectID = INVALID_OBJECT_ID;
-    storageID = INVALID_OBJECT_ID;
-    last_mod_previous_scan = 0;
-    last_mod_current_scan = 0;
-    timer_parameter = Ref<Object> ((Object *)new ContentManager::TimerParameter(ContentManager::TimerParameter::IDAutoscan, INVALID_SCAN_ID));
+    timer_parameter = Ref<Timer::Parameter>(new Timer::Parameter(Timer::Parameter::IDAutoscan, INVALID_SCAN_ID));
 }
 
-void AutoscanDirectory::setCurrentLMT(time_t lmt) 
+void AutoscanDirectory::setCurrentLMT(time_t lmt)
 {
     if (lmt > last_mod_current_scan)
         last_mod_current_scan = lmt;
@@ -77,25 +74,23 @@ void AutoscanDirectory::setCurrentLMT(time_t lmt)
 
 AutoscanList::AutoscanList()
 {
-    mutex = Ref<Mutex>(new Mutex(true));
-    list = Ref<Array<AutoscanDirectory> > (new Array<AutoscanDirectory>());
+    list = Ref<Array<AutoscanDirectory>>(new Array<AutoscanDirectory>());
 }
 
 void AutoscanList::updateLMinDB()
 {
-    AUTOLOCK(mutex);
-    for (int i = 0; i < list->size(); i++)
-    {
+    AutoLock lock(mutex);
+    for (int i = 0; i < list->size(); i++) {
         log_debug("i: %d\n", i);
         Ref<AutoscanDirectory> ad = list->get(i);
-        if (ad != nil)
+        if (ad != nullptr)
             Storage::getInstance()->autoscanUpdateLM(ad);
     }
 }
 
 int AutoscanList::add(Ref<AutoscanDirectory> dir)
 {
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     return _add(dir);
 }
 
@@ -104,28 +99,22 @@ int AutoscanList::_add(Ref<AutoscanDirectory> dir)
 
     String loc = dir->getLocation();
     int nil_index = -1;
-    
-    for (int i = 0; i < list->size(); i++)
-    {
-        if (list->get(i) == nil)
-        {
+
+    for (int i = 0; i < list->size(); i++) {
+        if (list->get(i) == nullptr) {
             nil_index = i;
             continue;
         }
-        
-        if (loc == list->get(i)->getLocation())
-        {
+
+        if (loc == list->get(i)->getLocation()) {
             throw _Exception(_("Attempted to add same autoscan path twice"));
         }
     }
-    
-    if (nil_index != -1)
-    {
+
+    if (nil_index != -1) {
         dir->setScanID(nil_index);
         list->set(dir, nil_index);
-    }
-    else
-    {
+    } else {
         dir->setScanID(list->size());
         list->append(dir);
     }
@@ -135,21 +124,20 @@ int AutoscanList::_add(Ref<AutoscanDirectory> dir)
 
 void AutoscanList::addList(zmm::Ref<AutoscanList> list)
 {
-    AUTOLOCK(mutex);
-    
-    for (int i = 0; i < list->list->size(); i++)
-    {
-        if (list->list->get(i) == nil)
+    AutoLock lock(mutex);
+
+    for (int i = 0; i < list->list->size(); i++) {
+        if (list->list->get(i) == nullptr)
             continue;
 
         _add(list->list->get(i));
     }
 }
 
-Ref<Array<AutoscanDirectory> > AutoscanList::getArrayCopy()
+Ref<Array<AutoscanDirectory>> AutoscanList::getArrayCopy()
 {
-    AUTOLOCK(mutex);
-    Ref<Array<AutoscanDirectory> > copy(new Array<AutoscanDirectory>(list->size()));
+    AutoLock lock(mutex);
+    Ref<Array<AutoscanDirectory>> copy(new Array<AutoscanDirectory>(list->size()));
     for (int i = 0; i < list->size(); i++)
         copy->append(list->get(i));
 
@@ -158,58 +146,51 @@ Ref<Array<AutoscanDirectory> > AutoscanList::getArrayCopy()
 
 Ref<AutoscanDirectory> AutoscanList::get(int id)
 {
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
 
     if ((id < 0) || (id >= list->size()))
-        return nil;
+        return nullptr;
 
     return list->get(id);
 }
 
 Ref<AutoscanDirectory> AutoscanList::getByObjectID(int objectID)
 {
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
 
-    for (int i = 0; i < list->size(); i++)
-    {
-        if (list->get(i) != nil && objectID == list->get(i)->getObjectID())
+    for (int i = 0; i < list->size(); i++) {
+        if (list->get(i) != nullptr && objectID == list->get(i)->getObjectID())
             return list->get(i);
     }
-    return nil;
+    return nullptr;
 }
 
 Ref<AutoscanDirectory> AutoscanList::get(String location)
 {
-    AUTOLOCK(mutex);
-    for (int i = 0; i < list->size(); i++)
-    {
-        if (list->get(i) != nil && (location == list->get(i)->getLocation()))
+    AutoLock lock(mutex);
+    for (int i = 0; i < list->size(); i++) {
+        if (list->get(i) != nullptr && (location == list->get(i)->getLocation()))
             return list->get(i);
     }
-    return nil;
-
+    return nullptr;
 }
 
 void AutoscanList::remove(int id)
 {
-    AUTOLOCK(mutex);
-    
-    if ((id < 0) || (id >= list->size()))
-    {
+    AutoLock lock(mutex);
+
+    if ((id < 0) || (id >= list->size())) {
         log_debug("No such ID %d!\n", id);
         return;
     }
-   
+
     Ref<AutoscanDirectory> dir = list->get(id);
     dir->setScanID(INVALID_SCAN_ID);
 
-    if (id == list->size()-1)
-    {
+    if (id == list->size() - 1) {
         list->removeUnordered(id);
-    }
-    else
-    {
-        list->set(nil, id);
+    } else {
+        list->set(nullptr, id);
     }
 
     log_debug("ID %d removed!\n", id);
@@ -217,21 +198,16 @@ void AutoscanList::remove(int id)
 
 int AutoscanList::removeByObjectID(int objectID)
 {
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
 
-    for (int i = 0; i < list->size(); i++)
-    {
-        if (list->get(i) != nil && objectID == list->get(i)->getObjectID())
-        {
+    for (int i = 0; i < list->size(); i++) {
+        if (list->get(i) != nullptr && objectID == list->get(i)->getObjectID()) {
             Ref<AutoscanDirectory> dir = list->get(i);
             dir->setScanID(INVALID_SCAN_ID);
-            if (i == list->size()-1)
-            {
+            if (i == list->size() - 1) {
                 list->removeUnordered(i);
-            }
-            else
-            {
-                list->set(nil, i);
+            } else {
+                list->set(nullptr, i);
             }
             return i;
         }
@@ -241,21 +217,16 @@ int AutoscanList::removeByObjectID(int objectID)
 
 int AutoscanList::remove(String location)
 {
-    AUTOLOCK(mutex);
-    
-    for (int i = 0; i < list->size(); i++)
-    {
-        if (list->get(i) != nil && location == list->get(i)->getLocation())
-        {
+    AutoLock lock(mutex);
+
+    for (int i = 0; i < list->size(); i++) {
+        if (list->get(i) != nullptr && location == list->get(i)->getLocation()) {
             Ref<AutoscanDirectory> dir = list->get(i);
             dir->setScanID(INVALID_SCAN_ID);
-            if (i == list->size()-1)
-            {
+            if (i == list->size() - 1) {
                 list->removeUnordered(i);
-            }
-            else
-            {
-                list->set(nil, i);
+            } else {
+                list->set(nullptr, i);
             }
             return i;
         }
@@ -265,19 +236,16 @@ int AutoscanList::remove(String location)
 
 Ref<AutoscanList> AutoscanList::removeIfSubdir(String parent, bool persistent)
 {
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
 
     Ref<AutoscanList> rm_id_list(new AutoscanList());
 
-    for (int i = 0; i < list->size(); i++)
-    {
-        if (list->get(i) != nil && (list->get(i)->getLocation().startsWith(parent)))
-        {
+    for (int i = 0; i < list->size(); i++) {
+        if (list->get(i) != nullptr && (list->get(i)->getLocation().startsWith(parent))) {
             Ref<AutoscanDirectory> dir = list->get(i);
-            if (dir == nil)
+            if (dir == nullptr)
                 continue;
-            if (dir->persistent() && (persistent == false))
-            {
+            if (dir->persistent() && !persistent) {
                 continue;
             }
             Ref<AutoscanDirectory> copy(new AutoscanDirectory());
@@ -285,13 +253,10 @@ Ref<AutoscanList> AutoscanList::removeIfSubdir(String parent, bool persistent)
             rm_id_list->add(copy);
             copy->setScanID(dir->getScanID());
             dir->setScanID(INVALID_SCAN_ID);
-            if (i == list->size()-1)
-            {
+            if (i == list->size() - 1) {
                 list->removeUnordered(i);
-            }
-            else
-            {
-                list->set(nil, i);
+            } else {
+                list->set(nullptr, i);
             }
         }
     }
@@ -299,126 +264,82 @@ Ref<AutoscanList> AutoscanList::removeIfSubdir(String parent, bool persistent)
     return rm_id_list;
 }
 
-
-/*
-void AutoscanList::subscribeAll(Ref<TimerSubscriber> obj)
+void AutoscanList::notifyAll(Timer::Subscriber* sub)
 {
-    AUTOLOCK(mutex);
-    
-    Ref<Timer> timer = Timer::getInstance();
-    for (int i = 0; i < list->size(); i++)
-    {
-        Ref<AutoscanDirectory> dir = list->get(i);
-        if (dir == nil)
-            continue;
-        timer->addTimerSubscriber(obj, dir->getInterval(), dir->getScanID(), true);
-    }
-}
-*/
+    if (sub == nullptr)
+        return;
+    AutoLock lock(mutex);
 
-void AutoscanList::notifyAll(Ref<TimerSubscriberSingleton<Object> > cm)
-{
-    AUTOLOCK(mutex);
-    
     Ref<Timer> timer = Timer::getInstance();
-    for (int i = 0; i < list->size(); i++)
-    {
-        if (list->get(i) == nil)
+    for (int i = 0; i < list->size(); i++) {
+        if (list->get(i) == nullptr)
             continue;
-       cm->timerNotify(list->get(i)->getTimerParameter());
+        sub->timerNotify(list->get(i)->getTimerParameter());
     }
 }
 
-/*
-void AutoscanList::subscribeDir(zmm::Ref<TimerSubscriber> obj, int id, bool once)
-{
-    AUTOLOCK(mutex);
-
-    if ((id < 0) || (id >= list->size()))
-        return;
-  
-    Ref<Timer> timer = Timer::getInstance();
-    Ref<AutoscanDirectory> dir = list->get(id);
-    timer->addTimerSubscriber(obj, dir->getInterval(), dir->getScanID(), once);
-}
-*/
-
-/*
-void AutoscanList::dump()
-{
-    log_debug("Dumping autoscan list: %d elements\n", list->size());
-    for (int i = 0; i < list->size();i++)
-    {
-        Ref<AutoscanDirectory> dir = list->get(i);
-        log_debug("Position: %d", i);
-        if (dir == nil)
-            printf("[nil]\n");
-        else
-            printf("[scanid=%d objectid=%d location=%s]\n",
-                    dir->getScanID(), dir->getObjectID(),
-                    dir->getLocation().c_str());
-    }
-}
-*/
-
 void AutoscanDirectory::setLocation(String location)
 {
-    if (this->location == nil)
+    if (this->location == nullptr)
         this->location = location;
     else
         throw _Exception(_("UNALLOWED LOCATION CHANGE!"));
-
 }
 
-void AutoscanDirectory::setScanID(int id) 
+void AutoscanDirectory::setScanID(int id)
 {
-    scanID = id; 
-    RefCast(timer_parameter, ContentManager::TimerParameter)->setID(id); 
-} 
-
+    scanID = id;
+    timer_parameter->setID(id);
+}
 
-String AutoscanDirectory::mapScanmode(scan_mode_t scanmode)
+String AutoscanDirectory::mapScanmode(ScanMode scanmode)
 {
-    String scanmode_str = nil;
-    switch (scanmode)
-    {
-        case TimedScanMode: scanmode_str = _("timed"); break;
-        case InotifyScanMode: scanmode_str = _("inotify"); break;
+    String scanmode_str = nullptr;
+    switch (scanmode) {
+        case ScanMode::Timed:
+        scanmode_str = _("timed");
+        break;
+    case ScanMode::INotify:
+        scanmode_str = _("inotify");
+        break;
     }
-    if (scanmode_str == nil)
-        throw Exception(_("illegal scanmode given to mapScanmode(): ") + scanmode);
+    if (scanmode_str == nullptr)
+        throw Exception(_("illegal scanmode given to mapScanmode()"));
     return scanmode_str;
 }
 
-scan_mode_t AutoscanDirectory::remapScanmode(String scanmode)
+ScanMode AutoscanDirectory::remapScanmode(String scanmode)
 {
     if (scanmode == "timed")
-        return TimedScanMode;
+        return ScanMode::Timed;
     if (scanmode == "inotify")
-        return InotifyScanMode;
+        return ScanMode::INotify;
     else
         throw _Exception(_("illegal scanmode (") + scanmode + ") given to remapScanmode()");
 }
 
-String AutoscanDirectory::mapScanlevel(scan_level_t scanlevel)
+String AutoscanDirectory::mapScanlevel(ScanLevel scanlevel)
 {
-    String scanlevel_str = nil;
-    switch (scanlevel)
-    {
-        case BasicScanLevel: scanlevel_str = _("basic"); break;
-        case FullScanLevel: scanlevel_str = _("full"); break;
+    String scanlevel_str = nullptr;
+    switch (scanlevel) {
+    case ScanLevel::Basic:
+        scanlevel_str = _("basic");
+        break;
+    case ScanLevel::Full:
+        scanlevel_str = _("full");
+        break;
     }
-    if (scanlevel_str == nil)
-        throw Exception(_("illegal scanlevel given to mapScanlevel(): ") + scanlevel);
+    if (scanlevel_str == nullptr)
+        throw Exception(_("illegal scanlevel given to mapScanlevel()"));
     return scanlevel_str;
 }
 
-scan_level_t AutoscanDirectory::remapScanlevel(String scanlevel)
+ScanLevel AutoscanDirectory::remapScanlevel(String scanlevel)
 {
     if (scanlevel == "basic")
-        return BasicScanLevel;
+        return ScanLevel::Basic;
     else if (scanlevel == "full")
-        return FullScanLevel;
+        return ScanLevel::Full;
     else
         throw _Exception(_("illegal scanlevel (") + scanlevel + ") given to remapScanlevel()");
 }
@@ -441,38 +362,7 @@ void AutoscanDirectory::copyTo(Ref<AutoscanDirectory> copy)
     copy->timer_parameter = timer_parameter;
 }
 
-/*
-void AutoscanDirectory::setTimerParamter(Ref<Object> parameter)
+Ref<Timer::Parameter> AutoscanDirectory::getTimerParameter()
 {
-    timer_parameter = parameter;
+    return timer_parameter;
 }
-*/
-
-Ref<Object> AutoscanDirectory::getTimerParameter()
-{
-    return timer_parameter; 
-}
-
-
-/*
-bool AutoscanDirectory::equals(Ref<AutoscanDirectory> dir)
-{
-    if ((dir->location == location) &&
-         (dir->mode == mode) &&
-         (dir->level == level) &&
-         (dir->recursive == recursive) &&
-         (dir->hidden == hidden) &&
-         (dir->persistent_flag == persistent_flag) &&
-         (dir->interval == interval) &&
-         (dir->taskCount == taskCount) &&
-         (dir->scanID == scanID) &&
-         (dir->objectID == objectID) &&
-         (dir->storageID == storageID) &&
-         (dir->last_mod_previous_scan == last_mod_previous_scan) &&
-         (dir->last_mod_current_scan == last_mod_current_scan))
-        return true;
-    else
-        return false;
-
-}
-*/
diff --git a/src/autoscan.h b/src/autoscan.h
index 20899f3..270630a 100644
--- a/src/autoscan.h
+++ b/src/autoscan.h
@@ -28,43 +28,40 @@
 */
 
 /// \file autoscan.h
-///\brief Definitions of the Autoscan classes. 
+///\brief Definitions of the Autoscan classes.
 
 #ifndef __AUTOSCAN_H__
 #define __AUTOSCAN_H__
 
-#include "zmmf/zmmf.h"
-#include "sync.h"
 #include "timer.h"
+#include "zmm/zmmf.h"
+#include <mutex>
 
 #define INVALID_SCAN_ID -1
 
 ///\brief Scan level - the way how exactly directories should be scanned.
-enum scan_level_t
-{
-    BasicScanLevel, // file was added or removed from the directory
-    FullScanLevel   // file was modified/added/removed
+enum class ScanLevel {
+    Basic, // file was added or removed from the directory
+    Full // file was modified/added/removed
 };
 
 ///\brief Scan mode - type of scan (timed, inotify, fam, etc.)
-enum scan_mode_t
-{
-    TimedScanMode,
-    InotifyScanMode
+enum class ScanMode {
+    Timed,
+    INotify
 };
 
 class AutoscanDirectory;
 
-class AutoscanList : public zmm::Object
-{
+class AutoscanList : public zmm::Object {
 public:
     AutoscanList();
-    
-    /// \brief Adds a new AutoscanDirectory to the list. 
-    /// 
-    /// The scanID of the directory is invalidated and set to 
+
+    /// \brief Adds a new AutoscanDirectory to the list.
+    ///
+    /// The scanID of the directory is invalidated and set to
     /// the index in the AutoscanList.
-    /// 
+    ///
     /// \param dir AutoscanDirectory to add to the list.
     /// \return scanID of the newly added AutoscanDirectory
     int add(zmm::Ref<AutoscanDirectory> dir);
@@ -74,16 +71,16 @@ public:
     zmm::Ref<AutoscanDirectory> get(int id);
 
     zmm::Ref<AutoscanDirectory> get(zmm::String location);
-    
+
     zmm::Ref<AutoscanDirectory> getByObjectID(int objectID);
 
     int size() { return list->size(); }
-   
+
     /// \brief removes the AutoscanDirectory given by its scan ID
     void remove(int id);
 
     int removeByObjectID(int objectID);
-    
+
     /// \brief removes the AutoscanDirectory with the given location
     /// \param location the location to remove
     /// \return the scanID, that was removed; if nothing removed: INVALID_SCAN_ID
@@ -98,40 +95,41 @@ public:
     /*
     /// \brief Add timer for each directory in the list.
     /// \param obj instance of the class that will receive notifications.
-    void subscribeAll(zmm::Ref<TimerSubscriber> obj);
+    void subscribeAll(zmm::Ref<Subscriber> obj);
     */
 
     /// \brief Send notification for each directory that is stored in the list.
-    /// 
-    /// \param obj instance of the class that will receive the notifications.
-    void notifyAll(zmm::Ref<TimerSubscriberSingleton<Object> > obj);
-        
+    ///
+    /// \param sub instance of the class that will receive the notifications.
+    void notifyAll(Timer::Subscriber* sub);
+
     /*
     /// \brief Add timer for given directory.
     /// \param obj instance of the class that will receive notifications.
     /// \param id dir id.
-    void subscribeDir(zmm::Ref<TimerSubscriber> obj, int id, bool once = true);
+    void subscribeDir(zmm::Ref<Subscriber> obj, int id, bool once = true);
     */
-    
+
     /// \brief updates the last_modified data for all AutoscanDirectories.
     void updateLMinDB();
 
     /// \brief returns a copy of the autoscan list in the form of an array
-    zmm::Ref<zmm::Array<AutoscanDirectory> > getArrayCopy();
+    zmm::Ref<zmm::Array<AutoscanDirectory>> getArrayCopy();
 
-/*
+    /*
     void dump();
 */
 
 protected:
-    zmm::Ref<Mutex> mutex;
-    zmm::Ref<zmm::Array<AutoscanDirectory> > list;
+    std::recursive_mutex mutex;
+    using AutoLock = std::lock_guard<std::recursive_mutex>;
+
+    zmm::Ref<zmm::Array<AutoscanDirectory>> list;
     int _add(zmm::Ref<AutoscanDirectory> dir);
 };
 
 /// \brief Provides information about one autoscan directory.
-class AutoscanDirectory : public zmm::Object
-{
+class AutoscanDirectory : public zmm::Object {
 public:
     AutoscanDirectory();
 
@@ -143,56 +141,56 @@ public:
     /// \param interval rescan interval in seconds (only for timed scan mode)
     /// \param hidden include hidden files
     /// zero means none.
-    AutoscanDirectory(zmm::String location, scan_mode_t mode, 
-                      scan_level_t level, bool recursive,
-                      bool persistent,
-                      int id = INVALID_SCAN_ID, unsigned int interval = 0, bool hidden = false);
+    AutoscanDirectory(zmm::String location, ScanMode mode,
+        ScanLevel level, bool recursive,
+        bool persistent,
+        int id = INVALID_SCAN_ID, unsigned int interval = 0, bool hidden = false);
 
     void setStorageID(int storageID) { this->storageID = storageID; }
 
     int getStorageID() { return storageID; }
 
-    /// \brief The location can only be set once! 
+    /// \brief The location can only be set once!
     void setLocation(zmm::String location);
 
     zmm::String getLocation() { return location; }
 
-    scan_mode_t getScanMode() { return mode; }
+    ScanMode getScanMode() { return mode; }
 
-    void setScanMode(scan_mode_t mode) { this->mode = mode; }
+    void setScanMode(ScanMode mode) { this->mode = mode; }
 
-    scan_level_t getScanLevel() { return level; }
+    ScanLevel getScanLevel() { return level; }
 
-    void setScanLevel(scan_level_t level) { this->level = level; }
+    void setScanLevel(ScanLevel level) { this->level = level; }
 
     bool getRecursive() { return recursive; }
-   
+
     void setHidden(bool hidden) { this->hidden = hidden; }
 
     bool getHidden() { return hidden; }
 
     void setRecursive(bool recursive) { this->recursive = recursive; }
-    
+
     unsigned int getInterval() { return interval; }
 
     void setInterval(unsigned int interval) { this->interval = interval; }
 
-    /// \brief Increments the task count. 
+    /// \brief Increments the task count.
     ///
     /// When recursive autoscan is in progress, we only want to subcribe to
     /// a timer event when the scan is finished. However, recursive scans
-    /// spawn tasks for each directory. When adding a rescan task for 
+    /// spawn tasks for each directory. When adding a rescan task for
     /// subdirectories, the taskCount will be incremented. When a task is
-    /// done the count will be decremented. When timer gets to zero, 
+    /// done the count will be decremented. When timer gets to zero,
     /// we will resubscribe.
     void incTaskCount() { taskCount++; }
-    
+
     void decTaskCount() { taskCount--; }
 
     int getTaskCount() { return taskCount; }
 
     void setTaskCount(int taskCount) { this->taskCount = taskCount; }
-  
+
     /// \brief Sets the task ID.
     ///
     /// The task ID helps us to identify to which scan a particular task
@@ -209,7 +207,7 @@ public:
     bool persistent() { return persistent_flag; }
 
     /// \brief Sets the last modification time of the current ongoing scan.
-    /// 
+    ///
     /// When doing a FullScan we look at modification times of the files.
     /// During the recursion of one AutoscanDirectory (which will be the
     /// starting point and which may have subcontainers) we must compare
@@ -217,35 +215,39 @@ public:
     /// overwrite it until we are done.
     /// The time will be only set if it is higher than the previous value!
     void setCurrentLMT(time_t lmt);
-    
+
     time_t getPreviousLMT() { return last_mod_previous_scan; }
-    
+
     void updateLMT() { last_mod_previous_scan = last_mod_current_scan; }
 
-    void resetLMT() { last_mod_previous_scan = 0; last_mod_current_scan = 0; }
- 
+    void resetLMT()
+    {
+        last_mod_previous_scan = 0;
+        last_mod_current_scan = 0;
+    }
+
     /// \brief copies all properties to another object
     void copyTo(zmm::Ref<AutoscanDirectory> copy);
 
     /// \brief Set the parameter for timer notify that is associated with
     /// the particular autoscan directory.
-//    void setTimerParamter(zmm::Ref<zmm::Object> parameter);
+    //    void setTimerParamter(zmm::Ref<zmm::Object> parameter);
 
     /// \brief Get the timer notify parameter associated with this directory.
-    zmm::Ref<zmm::Object> getTimerParameter();
+    zmm::Ref<Timer::Parameter> getTimerParameter();
+
+    //    bool equals(Ref<AutoscanDirectory> dir);
 
-//    bool equals(Ref<AutoscanDirectory> dir);
-   
     /* helpers for autoscan stuff */
-    static zmm::String mapScanmode(scan_mode_t scanmode);
-    static scan_mode_t remapScanmode(zmm::String scanmode);
-    static zmm::String mapScanlevel(scan_level_t scanlevel);
-    static scan_level_t remapScanlevel(zmm::String scanlevel);
-    
+    static zmm::String mapScanmode(ScanMode scanmode);
+    static ScanMode remapScanmode(zmm::String scanmode);
+    static zmm::String mapScanlevel(ScanLevel scanlevel);
+    static ScanLevel remapScanlevel(zmm::String scanlevel);
+
 protected:
     zmm::String location;
-    scan_mode_t mode;
-    scan_level_t level;
+    ScanMode mode;
+    ScanLevel level;
     bool recursive;
     bool hidden;
     bool persistent_flag;
@@ -254,9 +256,9 @@ protected:
     int scanID;
     int objectID;
     int storageID;
-    time_t  last_mod_previous_scan; 
-    time_t  last_mod_current_scan;
-    zmm::Ref<zmm::Object> timer_parameter;
+    time_t last_mod_previous_scan;
+    time_t last_mod_current_scan;
+    zmm::Ref<Timer::Parameter> timer_parameter;
 };
 
 #endif
diff --git a/src/autoscan_inotify.cc b/src/autoscan_inotify.cc
index 6381b9e..3de2764 100644
--- a/src/autoscan_inotify.cc
+++ b/src/autoscan_inotify.cc
@@ -29,12 +29,10 @@
 
 /// \file autoscan_inotify.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_INOTIFY
 
+#include <cassert>
+
 #include "autoscan_inotify.h"
 #include "content_manager.h"
 
@@ -43,58 +41,42 @@
 
 #define AUTOSCAN_INOTIFY_INITIAL_QUEUE_SIZE 20
 
-// always use a prime!
-#define AUTOSCAN_INOTIFY_HASH_SIZE 30851
-
 #define INOTIFY_MAX_USER_WATCHES_FILE "/proc/sys/fs/inotify/max_user_watches"
+
 using namespace zmm;
+using namespace std;
 
 AutoscanInotify::AutoscanInotify()
 {
-    mutex = Ref<Mutex>(new Mutex());
-    cond = Ref<Cond>(new Cond(mutex));
-
-    int hash_size = AUTOSCAN_INOTIFY_HASH_SIZE;
-
-    if (check_path(_(INOTIFY_MAX_USER_WATCHES_FILE)))
-    {
-        int max_watches = -1;
-        try
-        {
-            max_watches = trim_string(read_text_file(_(INOTIFY_MAX_USER_WATCHES_FILE))).toInt();
+    if (check_path(_(INOTIFY_MAX_USER_WATCHES_FILE))) {
+        try {
+            int max_watches = trim_string(read_text_file(_(INOTIFY_MAX_USER_WATCHES_FILE))).toInt();
             log_debug("Max watches on the system: %d\n", max_watches);
-        }
-        catch (Exception ex)
-        {
+        } catch (const Exception& ex) {
             log_error("Could not determine maximum number of inotify user watches: %s\n", ex.getMessage().c_str());
         }
-
-        if (max_watches > 0)
-            hash_size = max_watches * 5;
     }
 
-    watches = Ref<DBOHash<int, Wd> >(new DBOHash<int, Wd>(hash_size, -1, -2));
+    watches = make_shared<unordered_map<int, Ref<Wd>>>();
     shutdownFlag = true;
-    monitorQueue = Ref<ObjectQueue<AutoscanDirectory> >(new ObjectQueue<AutoscanDirectory>(AUTOSCAN_INOTIFY_INITIAL_QUEUE_SIZE));
-    unmonitorQueue = Ref<ObjectQueue<AutoscanDirectory> >(new ObjectQueue<AutoscanDirectory>(AUTOSCAN_INOTIFY_INITIAL_QUEUE_SIZE));
+    monitorQueue = Ref<ObjectQueue<AutoscanDirectory>>(new ObjectQueue<AutoscanDirectory>(AUTOSCAN_INOTIFY_INITIAL_QUEUE_SIZE));
+    unmonitorQueue = Ref<ObjectQueue<AutoscanDirectory>>(new ObjectQueue<AutoscanDirectory>(AUTOSCAN_INOTIFY_INITIAL_QUEUE_SIZE));
     events = IN_CLOSE_WRITE | IN_CREATE | IN_MOVED_FROM | IN_MOVED_TO | IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT;
 }
 
 void AutoscanInotify::init()
 {
-    AUTOLOCK(mutex);
-    if (shutdownFlag)
-    {
+    AutoLock lock(mutex);
+    if (shutdownFlag) {
         shutdownFlag = false;
         inotify = Ref<Inotify>(new Inotify());
         log_debug("starting inotify thread...\n");
         int ret = pthread_create(
             &thread,
-            NULL,
+            nullptr,
             AutoscanInotify::staticThreadProc,
-            this
-        );
-        
+            this);
+
         if (ret)
             throw _Exception(_("failed to start inotify thread: ") + ret);
     }
@@ -107,231 +89,195 @@ AutoscanInotify::~AutoscanInotify()
 
 void AutoscanInotify::shutdown()
 {
-    AUTOLOCK(mutex);
-    if (! shutdownFlag)
-    {
+    unique_lock<std::mutex> lock(mutex);
+    if (!shutdownFlag) {
         log_debug("start\n");
         shutdownFlag = true;
         inotify->stop();
-        AUTOUNLOCK();
+        lock.unlock();
         if (thread)
-            pthread_join(thread, NULL);
+            pthread_join(thread, nullptr);
         thread = 0;
         log_debug("inotify thread died.\n");
-        inotify = nil;
+        inotify = nullptr;
         watches->clear();
     }
 }
 
-void *AutoscanInotify::staticThreadProc(void *arg)
+void* AutoscanInotify::staticThreadProc(void* arg)
 {
     log_debug("started inotify thread.\n");
-    AutoscanInotify *inst = (AutoscanInotify *)arg;
+    auto* inst = (AutoscanInotify*)arg;
     inst->threadProc();
     Storage::getInstance()->threadCleanup();
     log_debug("exiting inotify thread...\n");
-    pthread_exit(NULL);
-    return NULL;
+    pthread_exit(nullptr);
 }
 
 void AutoscanInotify::threadProc()
 {
     Ref<ContentManager> cm;
     Ref<Storage> st;
-    
-    inotify_event *event;
-    
-    Ref<StringBuffer> pathBuf (new StringBuffer());
-    
-    try
-    {
+
+    inotify_event* event;
+
+    Ref<StringBuffer> pathBuf(new StringBuffer());
+
+    try {
         cm = ContentManager::getInstance();
         st = Storage::getInstance();
-    }
-    catch (Exception e)
-    {
+    } catch (const Exception& e) {
         log_error("Inotify thread caught: %s\n", e.getMessage().c_str());
         e.printStackTrace();
         shutdownFlag = true;
-        inotify = nil;
+        inotify = nullptr;
     }
-    while(! shutdownFlag)
-    {
-        try
-        {
+    while (!shutdownFlag) {
+        try {
             Ref<AutoscanDirectory> adir;
-            
-            AUTOLOCK(mutex);
-            while ((adir = unmonitorQueue->dequeue()) != nil)
-            {
-                AUTOUNLOCK();
-                
+
+            unique_lock<std::mutex> lock(mutex);
+            while ((adir = unmonitorQueue->dequeue()) != nullptr) {
+                lock.unlock();
+
                 String location = normalizePathNoEx(adir->getLocation());
-                if (! string_ok(location))
-                {
-                    AUTORELOCK();
+                if (!string_ok(location)) {
+                    lock.lock();
                     continue;
                 }
-                
-                if (adir->getRecursive())
-                {
+
+                if (adir->getRecursive()) {
                     log_debug("removing recursive watch: %s\n", location.c_str());
                     monitorUnmonitorRecursive(location, true, adir, location, true);
-                }
-                else
-                {
+                } else {
                     log_debug("removing non-recursive watch: %s\n", location.c_str());
                     unmonitorDirectory(location, adir);
                 }
-                
-                AUTORELOCK();
+
+                lock.lock();
             }
-            
-            while ((adir = monitorQueue->dequeue()) != nil)
-            {
-                AUTOUNLOCK();
-                
+
+            while ((adir = monitorQueue->dequeue()) != nullptr) {
+                lock.unlock();
+
                 String location = normalizePathNoEx(adir->getLocation());
-                if (! string_ok(location))
-                {
-                    AUTORELOCK();
+                if (!string_ok(location)) {
+                    lock.lock();
                     continue;
                 }
-                
-                if (adir->getRecursive())
-                {
+
+                if (adir->getRecursive()) {
                     log_debug("adding recursive watch: %s\n", location.c_str());
                     monitorUnmonitorRecursive(location, false, adir, location, true);
-                }
-                else
-                {
+                } else {
                     log_debug("adding non-recursive watch: %s\n", location.c_str());
                     monitorDirectory(location, adir, location, true);
                 }
-                cm->rescanDirectory(adir->getObjectID(), adir->getScanID(), adir->getScanMode(), nil, false);
-                
-                AUTORELOCK();
+                cm->rescanDirectory(adir->getObjectID(), adir->getScanID(), adir->getScanMode(), nullptr, false);
+
+                lock.lock();
             }
-            
-            AUTOUNLOCK();
-            
+
+            lock.unlock();
+
             /* --- get event --- (blocking) */
             event = inotify->nextEvent();
             /* --- */
-            
-            if (event)
-            {
+
+            if (event) {
                 int wd = event->wd;
                 int mask = event->mask;
                 String name = event->name;
                 log_debug("inotify event: %d %x %s\n", wd, mask, name.c_str());
-                
-                Ref<Wd> wdObj = watches->get(wd);
-                if (wdObj == nil)
-                {
+
+                Ref<Wd> wdObj = nullptr;
+                try {
+                    wdObj = watches->at(wd);
+                } catch (const out_of_range& ex) {
                     inotify->removeWatch(wd);
                     continue;
                 }
-                
-                
+
                 pathBuf->clear();
                 *pathBuf << wdObj->getPath();
-                if (! (mask & (IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT)))
+                if (!(mask & (IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT)))
                     *pathBuf << name;
                 String path = pathBuf->toString();
-                
+
                 Ref<AutoscanDirectory> adir;
                 Ref<WatchAutoscan> watchAs = getAppropriateAutoscan(wdObj, path);
-                if (watchAs != nil)
+                if (watchAs != nullptr)
                     adir = watchAs->getAutoscanDirectory();
                 else
-                    adir = nil;
-                
-                if (mask & IN_MOVE_SELF)
-                {
+                    adir = nullptr;
+
+                if (mask & IN_MOVE_SELF) {
                     checkMoveWatches(wd, wdObj);
                 }
-                
-                if (mask & (IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT))
-                {
+
+                if (mask & (IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT)) {
                     recheckNonexistingMonitors(wd, wdObj);
                 }
-                
-                if (mask & IN_ISDIR)
-                {
-                    if (mask & (IN_CREATE | IN_MOVED_TO))
-                    {
+
+                if (mask & IN_ISDIR) {
+                    if (mask & (IN_CREATE | IN_MOVED_TO)) {
                         recheckNonexistingMonitors(wd, wdObj);
                     }
-                    
-                    if (adir != nil && adir->getRecursive())
-                    {
-                        if (mask & IN_CREATE)
-                        {
-                            if (adir->getHidden() || name.charAt(0) != '.')
-                            {
+
+                    if (adir != nullptr && adir->getRecursive()) {
+                        if (mask & IN_CREATE) {
+                            if (adir->getHidden() || name.charAt(0) != '.') {
                                 log_debug("new dir detected, adding to inotify: %s\n", path.c_str());
                                 monitorUnmonitorRecursive(path, false, adir, watchAs->getNormalizedAutoscanPath(), false);
-                            }
-                            else
-                            {
+                            } else {
                                 log_debug("new dir detected, irgnoring because it's hidden: %s\n", path.c_str());
                             }
                         }
                     }
                 }
-                
-                if (adir != nil && mask & (IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_CLOSE_WRITE | IN_MOVED_FROM | IN_MOVED_TO | IN_UNMOUNT))
-                {
+
+                if (adir != nullptr && mask & (IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_CLOSE_WRITE | IN_MOVED_FROM | IN_MOVED_TO | IN_UNMOUNT | IN_CREATE)) {
                     String fullPath;
                     if (mask & IN_ISDIR)
                         fullPath = path + DIR_SEPARATOR;
                     else
                         fullPath = path;
-                    
-                    if (! (mask & IN_MOVED_TO))
-                    {
+
+                    if (!(mask & (IN_MOVED_TO | IN_CREATE))) {
                         log_debug("deleting %s\n", fullPath.c_str());
-                        
-                        if (mask & (IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT))
-                        {
+
+                        if (mask & (IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT)) {
                             if (IN_MOVE_SELF)
                                 inotify->removeWatch(wd);
                             Ref<WatchAutoscan> watch = getStartPoint(wdObj);
-                            if (watch != nil)
-                            {
-                                if (adir->persistent())
-                                {
+                            if (watch != nullptr) {
+                                if (adir->persistent()) {
                                     monitorNonexisting(path, watch->getAutoscanDirectory(), watch->getNormalizedAutoscanPath());
-                                    cm->handlePeristentAutoscanRemove(adir->getScanID(), InotifyScanMode);
+                                    cm->handlePeristentAutoscanRemove(adir->getScanID(), ScanMode::INotify);
                                 }
                             }
                         }
-                        
+
                         int objectID = st->findObjectIDByPath(fullPath);
                         if (objectID != INVALID_OBJECT_ID)
                             cm->removeObject(objectID);
                     }
-                    if (mask & (IN_CLOSE_WRITE | IN_MOVED_TO))
-                    {
+                    if (mask & (IN_CLOSE_WRITE | IN_MOVED_TO | IN_CREATE)) {
                         log_debug("adding %s\n", path.c_str());
                         // path, recursive, async, hidden, low priority, cancellable
                         cm->addFile(fullPath, adir->getRecursive(), true, adir->getHidden(), true, false);
-                        
+
                         if (mask & IN_ISDIR)
                             monitorUnmonitorRecursive(path, false, adir, watchAs->getNormalizedAutoscanPath(), false);
                     }
                 }
-                if (mask & IN_IGNORED)
-                {
+                if (mask & IN_IGNORED) {
                     removeWatchMoves(wd);
                     removeDescendants(wd);
-                    watches->remove(wd);
+                    watches->erase(wd);
                 }
             }
-        }
-        catch (Exception e)
-        {
+        } catch (const Exception& e) {
             log_error("Inotify thread caught exception: %s\n", e.getMessage().c_str());
             e.printStackTrace();
         }
@@ -342,10 +288,10 @@ void AutoscanInotify::monitor(zmm::Ref<AutoscanDirectory> dir)
 {
     if (shutdownFlag)
         init();
-    assert(dir->getScanMode() == InotifyScanMode);
-    log_debug("---> INCOMING REQUEST TO MONITOR [%s]\n", 
-            dir->getLocation().c_str());
-    AUTOLOCK(mutex);
+    assert(dir->getScanMode() == ScanMode::INotify);
+    log_debug("---> INCOMING REQUEST TO MONITOR [%s]\n",
+        dir->getLocation().c_str());
+    AutoLock lock(mutex);
     monitorQueue->enqueue(dir);
     inotify->stop();
 }
@@ -353,22 +299,21 @@ void AutoscanInotify::monitor(zmm::Ref<AutoscanDirectory> dir)
 void AutoscanInotify::unmonitor(zmm::Ref<AutoscanDirectory> dir)
 {
     // must not be persistent
-    assert(! dir->persistent());
-    
-    log_debug("---> INCOMING REQUEST TO UNMONITOR [%s]\n", 
-            dir->getLocation().c_str());
-    AUTOLOCK(mutex);
+    assert(!dir->persistent());
+
+    log_debug("---> INCOMING REQUEST TO UNMONITOR [%s]\n",
+        dir->getLocation().c_str());
+    AutoLock lock(mutex);
     unmonitorQueue->enqueue(dir);
     inotify->stop();
 }
 
 int AutoscanInotify::watchPathForMoves(String path, int wd)
 {
-    Ref<Array<StringBase> > pathAr = split_string(path, DIR_SEPARATOR);
+    Ref<Array<StringBase>> pathAr = split_string(path, DIR_SEPARATOR);
     Ref<StringBuffer> buf(new StringBuffer());
     int parentWd = INOTIFY_ROOT;
-    for (int i = -1; i < pathAr->size() - 1; i++)
-    {
+    for (int i = -1; i < pathAr->size() - 1; i++) {
         if (i != 0)
             *buf << DIR_SEPARATOR;
         if (i >= 0)
@@ -382,34 +327,32 @@ int AutoscanInotify::watchPathForMoves(String path, int wd)
 int AutoscanInotify::addMoveWatch(String path, int removeWd, int parentWd)
 {
     int wd = inotify->addWatch(path, events);
-    if (wd >= 0)
-    {
+    if (wd >= 0) {
         bool alreadyThere = false;
-        Ref<Wd> wdObj = watches->get(wd);
-        if (wdObj == nil)
-        {
-            wdObj = Ref<Wd>(new Wd(path, wd, parentWd));
-            watches->put(wd, wdObj);
-        }
-        else
-        {
+
+        Ref<Wd> wdObj = nullptr;
+        try {
+            wdObj = watches->at(wd);
+
             int parentWdSet = wdObj->getParentWd();
-            if (parentWdSet >= 0)
-            {
-                if (parentWd != parentWdSet)
-                {
+            if (parentWdSet >= 0) {
+                if (parentWd != parentWdSet) {
                     log_debug("error: parentWd doesn't match wd: %d, parent is: %d, should be: %d\n", wd, parentWdSet, parentWd);
                     wdObj->setParentWd(parentWd);
                 }
-            }
-            else
+            } else
                 wdObj->setParentWd(parentWd);
-                
+
             //find
-            //alreadyThere =... 
+            //alreadyThere =...
+            //FIXME: not finished?
+
+        } catch (const out_of_range& ex) {
+            wdObj = Ref<Wd>(new Wd(path, wd, parentWd));
+            watches->emplace(wd, wdObj);
         }
-        if (! alreadyThere)
-        {
+
+        if (!alreadyThere) {
             Ref<WatchMove> watch(new WatchMove(removeWd));
             wdObj->getWdWatches()->append(RefCast(watch, Watch));
         }
@@ -420,42 +363,35 @@ int AutoscanInotify::addMoveWatch(String path, int removeWd, int parentWd)
 void AutoscanInotify::monitorNonexisting(String path, Ref<AutoscanDirectory> adir, String normalizedAutoscanPath)
 {
     String pathTmp = path;
-    Ref<Array<StringBase> > pathAr = split_string(path, DIR_SEPARATOR);
+    Ref<Array<StringBase>> pathAr = split_string(path, DIR_SEPARATOR);
     recheckNonexistingMonitor(-1, pathAr, adir, normalizedAutoscanPath);
 }
 
-void AutoscanInotify::recheckNonexistingMonitor(int curWd, Ref<Array<StringBase> > pathAr, Ref<AutoscanDirectory> adir, String normalizedAutoscanPath)
+void AutoscanInotify::recheckNonexistingMonitor(int curWd, Ref<Array<StringBase>> pathAr, Ref<AutoscanDirectory> adir, String normalizedAutoscanPath)
 {
     Ref<StringBuffer> buf(new StringBuffer());
     bool first = true;
-    for (int i = pathAr->size(); i >= 0; i--)
-    {
+    for (int i = pathAr->size(); i >= 0; i--) {
         buf->clear();
         if (i == 0)
             *buf << DIR_SEPARATOR;
-        else
-        {
-            for (int j = 0; j < i; j++)
-            {
+        else {
+            for (int j = 0; j < i; j++) {
                 *buf << DIR_SEPARATOR << pathAr->get(j);
-//                log_debug("adding: %s\n", pathAr->get(j)->data);
+                //                log_debug("adding: %s\n", pathAr->get(j)->data);
             }
         }
         bool pathExists = check_path(buf->toString(), true);
-//        log_debug("checking %s: %d\n", buf->c_str(), pathExists);
-        if (pathExists)
-        {
+        //        log_debug("checking %s: %d\n", buf->c_str(), pathExists);
+        if (pathExists) {
             if (curWd != -1)
-                removeNonexistingMonitor(curWd, watches->get(curWd), pathAr);
-            
+                removeNonexistingMonitor(curWd, watches->at(curWd), pathAr);
+
             String path = buf->toString() + DIR_SEPARATOR;
-            if (first)
-            {
+            if (first) {
                 monitorDirectory(path, adir, normalizedAutoscanPath, true);
                 ContentManager::getInstance()->handlePersistentAutoscanRecreate(adir->getScanID(), adir->getScanMode());
-            }
-            else
-            {
+            } else {
                 monitorDirectory(path, adir, normalizedAutoscanPath, false, pathAr);
             }
             break;
@@ -469,48 +405,42 @@ void AutoscanInotify::checkMoveWatches(int wd, Ref<Wd> wdObj)
 {
     Ref<Watch> watch;
     Ref<WatchMove> watchMv;
-    Ref<Array<Watch> > wdWatches = wdObj->getWdWatches();
-    for (int i = 0; i < wdWatches->size(); i++)
-    {
+    Ref<Array<Watch>> wdWatches = wdObj->getWdWatches();
+    for (int i = 0; i < wdWatches->size(); i++) {
         watch = wdWatches->get(i);
-        if (watch->getType() == WatchMoveType)
-        {
-            if (wdWatches->size() == 1)
-            {
+        if (watch->getType() == WatchMoveType) {
+            if (wdWatches->size() == 1) {
                 inotify->removeWatch(wd);
-            }
-            else
-            {
+            } else {
                 wdWatches->removeUnordered(i);
             }
-            
+
             watchMv = RefCast(watch, WatchMove);
             int removeWd = watchMv->getRemoveWd();
-            Ref<Wd> wdToRemove = watches->get(removeWd);
-            if (wdToRemove != nil)
-            {
+            try {
+                Ref<Wd> wdToRemove = watches->at(removeWd);
+
                 recheckNonexistingMonitors(removeWd, wdToRemove);
-                
+
                 String path = wdToRemove->getPath();
                 log_debug("found wd to remove because of move event: %d %s\n", removeWd, path.c_str());
-                
+
                 inotify->removeWatch(removeWd);
                 Ref<ContentManager> cm = ContentManager::getInstance();
                 Ref<WatchAutoscan> watch = getStartPoint(wdToRemove);
-                if (watch != nil)
-                {
+                if (watch != nullptr) {
                     Ref<AutoscanDirectory> adir = watch->getAutoscanDirectory();
-                    if (adir->persistent())
-                    {
+                    if (adir->persistent()) {
                         monitorNonexisting(path, adir, watch->getNormalizedAutoscanPath());
-                        cm->handlePeristentAutoscanRemove(adir->getScanID(), InotifyScanMode);
+                        cm->handlePeristentAutoscanRemove(adir->getScanID(), ScanMode::INotify);
                     }
-                    
+
                     int objectID = Storage::getInstance()->findObjectIDByPath(path);
                     if (objectID != INVALID_OBJECT_ID)
                         cm->removeObject(objectID);
                 }
-            }
+            } catch (const out_of_range& ex) {
+            } // Not found in map
         }
     }
 }
@@ -519,44 +449,35 @@ void AutoscanInotify::recheckNonexistingMonitors(int wd, Ref<Wd> wdObj)
 {
     Ref<Watch> watch;
     Ref<WatchAutoscan> watchAs;
-    Ref<Array<Watch> > wdWatches = wdObj->getWdWatches();
-    for (int i = 0; i < wdWatches->size(); i++)
-    {
+    Ref<Array<Watch>> wdWatches = wdObj->getWdWatches();
+    for (int i = 0; i < wdWatches->size(); i++) {
         watch = wdWatches->get(i);
-        if (watch->getType() == WatchAutoscanType)
-        {
+        if (watch->getType() == WatchAutoscanType) {
             watchAs = RefCast(watch, WatchAutoscan);
-            Ref<Array<StringBase> > pathAr = watchAs->getNonexistingPathArray();
-            if (pathAr != nil)
-            {
+            Ref<Array<StringBase>> pathAr = watchAs->getNonexistingPathArray();
+            if (pathAr != nullptr) {
                 recheckNonexistingMonitor(wd, pathAr, watchAs->getAutoscanDirectory(), watchAs->getNormalizedAutoscanPath());
             }
         }
     }
 }
 
-void AutoscanInotify::removeNonexistingMonitor(int wd, Ref<Wd> wdObj, Ref<Array<StringBase> > pathAr)
+void AutoscanInotify::removeNonexistingMonitor(int wd, Ref<Wd> wdObj, Ref<Array<StringBase>> pathAr)
 {
     Ref<Watch> watch;
     Ref<WatchAutoscan> watchAs;
-    Ref<Array<Watch> > wdWatches = wdObj->getWdWatches();
-    for (int i = 0; i < wdWatches->size(); i++)
-    {
+    Ref<Array<Watch>> wdWatches = wdObj->getWdWatches();
+    for (int i = 0; i < wdWatches->size(); i++) {
         watch = wdWatches->get(i);
-        if (watch->getType() == WatchAutoscanType)
-        {
+        if (watch->getType() == WatchAutoscanType) {
             watchAs = RefCast(watch, WatchAutoscan);
-            if (watchAs->getNonexistingPathArray() == pathAr)
-            {
-                if (wdWatches->size() == 1)
-                {
+            if (watchAs->getNonexistingPathArray() == pathAr) {
+                if (wdWatches->size() == 1) {
                     // should be done automatically, because removeWatch triggers an IGNORED event
                     //watches->remove(wd);
-                    
+
                     inotify->removeWatch(wd);
-                }
-                else
-                {
+                } else {
                     wdWatches->removeUnordered(i);
                 }
                 return;
@@ -570,96 +491,86 @@ void AutoscanInotify::monitorUnmonitorRecursive(String startPath, bool unmonitor
     String location;
     if (unmonitor)
         unmonitorDirectory(startPath, adir);
-    else
-    {
+    else {
         bool ok = (monitorDirectory(startPath, adir, normalizedAutoscanPath, startPoint) > 0);
-        if (! ok)
+        if (!ok)
             return;
     }
-    
-    struct dirent *dent;
+
+    struct dirent* dent;
     struct stat statbuf;
-    
-    DIR *dir = opendir(startPath.c_str());
-    if (! dir)
-    {
+
+    DIR* dir = opendir(startPath.c_str());
+    if (!dir) {
         log_warning("Could not open %s\n", startPath.c_str());
         return;
     }
-    
-    while ((dent = readdir(dir)) != NULL && ! shutdownFlag)
-    {
-        char *name = dent->d_name;
-        if (name[0] == '.')
-        {
+
+    while ((dent = readdir(dir)) != nullptr && !shutdownFlag) {
+        char* name = dent->d_name;
+        if (name[0] == '.') {
             if (name[1] == 0)
                 continue;
             else if (name[1] == '.' && name[2] == 0)
                 continue;
         }
-        
+
         String fullPath = startPath + DIR_SEPARATOR + name;
-        
+
         if (stat(fullPath.c_str(), &statbuf) != 0)
             continue;
-        
-        if (S_ISDIR(statbuf.st_mode))
-        {
+
+        if (S_ISDIR(statbuf.st_mode)) {
             monitorUnmonitorRecursive(fullPath, unmonitor, adir, normalizedAutoscanPath, false);
         }
     }
-    
+
     closedir(dir);
 }
 
-int AutoscanInotify::monitorDirectory(String pathOri, Ref<AutoscanDirectory> adir, String normalizedAutoscanPath, bool startPoint, Ref<Array<StringBase> > pathArray)
+int AutoscanInotify::monitorDirectory(String pathOri, Ref<AutoscanDirectory> adir, String normalizedAutoscanPath, bool startPoint, Ref<Array<StringBase>> pathArray)
 {
-    String path = pathOri + DIR_SEPARATOR;
-    
+    String path = pathOri;
+    if (path.length() > 0 && path[path.length() - 1] != DIR_SEPARATOR) {
+        path = path + DIR_SEPARATOR;
+    }
+
     int wd = inotify->addWatch(path, events);
-    if (wd < 0)
-    {
-        if (startPoint && adir->persistent())
-        {
+    if (wd < 0) {
+        if (startPoint && adir->persistent()) {
             monitorNonexisting(path, adir, normalizedAutoscanPath);
         }
-    }
-    else
-    {
+    } else {
         bool alreadyWatching = false;
-        Ref<Wd> wdObj = watches->get(wd);
         int parentWd = INOTIFY_UNKNOWN_PARENT_WD;
         if (startPoint)
-                parentWd = watchPathForMoves(pathOri, wd);
-        if (wdObj == nil)
-        {
-            wdObj = Ref<Wd>(new Wd(path, wd, parentWd));
-            watches->put(wd, wdObj);
-        }
-        else
-        {
-            if (parentWd >= 0 && wdObj->getParentWd() < 0)
-            {
+            parentWd = watchPathForMoves(pathOri, wd);
+
+        Ref<Wd> wdObj = nullptr;
+        try {
+            wdObj = watches->at(wd);
+            if (parentWd >= 0 && wdObj->getParentWd() < 0) {
                 wdObj->setParentWd(parentWd);
             }
-            
-            if (pathArray == nil)
-                alreadyWatching = (getAppropriateAutoscan(wdObj, adir) != nil);
-            
+
+            if (pathArray == nullptr)
+                alreadyWatching = (getAppropriateAutoscan(wdObj, adir) != nullptr);
+
             // should we check for already existing "nonexisting" watches?
             // ...
+        } catch (const out_of_range& ex) {
+            wdObj = Ref<Wd>(new Wd(path, wd, parentWd));
+            watches->emplace(wd, wdObj);
         }
-        if (! alreadyWatching)
-        {
+
+        if (!alreadyWatching) {
             Ref<WatchAutoscan> watch(new WatchAutoscan(startPoint, adir, normalizedAutoscanPath));
-            if (pathArray != nil)
-            {
-               watch->setNonexistingPathArray(pathArray);
+            if (pathArray != nullptr) {
+                watch->setNonexistingPathArray(pathArray);
             }
             wdObj->getWdWatches()->append(RefCast(watch, Watch));
-            
-            if (! startPoint)
-            {
+
+            if (!startPoint) {
                 int startPointWd = inotify->addWatch(normalizedAutoscanPath, events);
                 log_debug("getting start point for %s -> %s wd=%d\n", pathOri.c_str(), normalizedAutoscanPath.c_str(), startPointWd);
                 if (wd >= 0)
@@ -672,43 +583,37 @@ int AutoscanInotify::monitorDirectory(String pathOri, Ref<AutoscanDirectory> adi
 
 void AutoscanInotify::unmonitorDirectory(String path, Ref<AutoscanDirectory> adir)
 {
-    path = path + DIR_SEPARATOR;
-    
+    if (path.length() > 0 && path[path.length() - 1] != DIR_SEPARATOR) {
+        path = path + DIR_SEPARATOR;
+    }
+
     // maybe there is a faster method...
     // we use addWatch, because it returns the wd to the filename
     // this should not add a new watch, because it should be already watched
     int wd = inotify->addWatch(path, events);
-    
-    if (wd < 0)
-    {
+
+    if (wd < 0) {
         // doesn't seem to be monitored currently
         log_debug("unmonitorDirectory called, but it isn't monitored? (%s)\n", path.c_str());
         return;
     }
-    
-    Ref<Wd> wdObj = watches->get(wd);
-    if (wdObj == nil)
-    {
+
+    Ref<Wd> wdObj = watches->at(wd);
+    if (wdObj == nullptr) {
         log_error("wd not found in watches!? (%d, %s)\n", wd, path.c_str());
         return;
     }
-    
+
     Ref<WatchAutoscan> watchAs = getAppropriateAutoscan(wdObj, adir);
-    if (watchAs == nil)
-    {
+    if (watchAs == nullptr) {
         log_debug("autoscan not found in watches? (%d, %s)\n", wd, path.c_str());
-    }
-    else
-    {
-        if (wdObj->getWdWatches()->size() == 1)
-        {
+    } else {
+        if (wdObj->getWdWatches()->size() == 1) {
             // should be done automatically, because removeWatch triggers an IGNORED event
             //watches->remove(wd);
-            
+
             inotify->removeWatch(wd);
-        }
-        else
-        {
+        } else {
             removeFromWdObj(wdObj, watchAs);
         }
     }
@@ -718,53 +623,41 @@ Ref<AutoscanInotify::WatchAutoscan> AutoscanInotify::getAppropriateAutoscan(Ref<
 {
     Ref<Watch> watch;
     Ref<WatchAutoscan> watchAs;
-    Ref<Array<Watch> > wdWatches = wdObj->getWdWatches();
-    for (int i = 0; i < wdWatches->size(); i++)
-    {
+    Ref<Array<Watch>> wdWatches = wdObj->getWdWatches();
+    for (int i = 0; i < wdWatches->size(); i++) {
         watch = wdWatches->get(i);
-        if (watch->getType() == WatchAutoscanType)
-        {
+        if (watch->getType() == WatchAutoscanType) {
             watchAs = RefCast(watch, WatchAutoscan);
-            if (watchAs->getNonexistingPathArray() == nil)
-            {
-                if (watchAs->getAutoscanDirectory()->getLocation() == adir->getLocation())
-                {
+            if (watchAs->getNonexistingPathArray() == nullptr) {
+                if (watchAs->getAutoscanDirectory()->getLocation() == adir->getLocation()) {
                     return watchAs;
                 }
             }
         }
     }
-    return nil;
+    return nullptr;
 }
 
 Ref<AutoscanInotify::WatchAutoscan> AutoscanInotify::getAppropriateAutoscan(Ref<Wd> wdObj, String path)
 {
     String pathBestMatch;
-    Ref<WatchAutoscan> bestMatch = nil;
+    Ref<WatchAutoscan> bestMatch = nullptr;
     Ref<Watch> watch;
     Ref<WatchAutoscan> watchAs;
-    Ref<Array<Watch> > wdWatches = wdObj->getWdWatches();
-    for (int i = 0; i < wdWatches->size(); i++)
-    {
+    Ref<Array<Watch>> wdWatches = wdObj->getWdWatches();
+    for (int i = 0; i < wdWatches->size(); i++) {
         watch = wdWatches->get(i);
-        if (watch->getType() == WatchAutoscanType)
-        {
+        if (watch->getType() == WatchAutoscanType) {
             watchAs = RefCast(watch, WatchAutoscan);
-            if (watchAs->getNonexistingPathArray() == nil)
-            {
+            if (watchAs->getNonexistingPathArray() == nullptr) {
                 String testLocation = watchAs->getNormalizedAutoscanPath();
-                if (path.startsWith(testLocation))
-                {
-                    if (string_ok(pathBestMatch))
-                    {
-                        if (pathBestMatch.length() < testLocation.length())
-                        {
+                if (path.startsWith(testLocation)) {
+                    if (string_ok(pathBestMatch)) {
+                        if (pathBestMatch.length() < testLocation.length()) {
                             pathBestMatch = testLocation;
                             bestMatch = watchAs;
                         }
-                    }
-                    else
-                    {
+                    } else {
                         pathBestMatch = testLocation;
                         bestMatch = watchAs;
                     }
@@ -778,32 +671,31 @@ Ref<AutoscanInotify::WatchAutoscan> AutoscanInotify::getAppropriateAutoscan(Ref<
 void AutoscanInotify::removeWatchMoves(int wd)
 {
     Ref<Wd> wdObj;
-    Ref<Array<Watch> > wdWatches;
+    Ref<Array<Watch>> wdWatches;
     Ref<Watch> watch;
     Ref<WatchMove> watchMv;
     bool first = true;
     int checkWd = wd;
-    do
-    {
-        wdObj = watches->get(checkWd);
-        if (wdObj == nil)
+    do {
+        wdObj = nullptr;
+        try {
+            wdObj = watches->at(checkWd);
+        } catch (const out_of_range& ex) {
             break;
+        }
+
         wdWatches = wdObj->getWdWatches();
-        if (wdWatches == nil)
+        if (wdWatches == nullptr)
             break;
-        
-        if (first)
+
+        if (first) {
             first = false;
-        else
-        {
-            for (int i = 0; i < wdWatches->size(); i++)
-            {
+        } else {
+            for (int i = 0; i < wdWatches->size(); i++) {
                 watch = wdWatches->get(i);
-                if (watch->getType() == WatchMoveType)
-                {
+                if (watch->getType() == WatchMoveType) {
                     watchMv = RefCast(watch, WatchMove);
-                    if (watchMv->getRemoveWd() == wd)
-                    {
+                    if (watchMv->getRemoveWd() == wd) {
                         log_debug("removing watch move\n");
                         if (wdWatches->size() == 1)
                             inotify->removeWatch(checkWd);
@@ -814,19 +706,16 @@ void AutoscanInotify::removeWatchMoves(int wd)
             }
         }
         checkWd = wdObj->getParentWd();
-    }
-    while(checkWd >= 0);
+    } while (checkWd >= 0);
 }
 
 bool AutoscanInotify::removeFromWdObj(Ref<Wd> wdObj, Ref<Watch> toRemove)
 {
-    Ref<Array<Watch> > wdWatches = wdObj->getWdWatches();
+    Ref<Array<Watch>> wdWatches = wdObj->getWdWatches();
     Ref<Watch> watch;
-    for (int i = 0; i < wdWatches->size(); i++)
-    {
+    for (int i = 0; i < wdWatches->size(); i++) {
         watch = wdWatches->get(i);
-        if (watch == toRemove)
-        {
+        if (watch == toRemove) {
             if (wdWatches->size() == 1)
                 inotify->removeWatch(wdObj->getWd());
             else
@@ -851,57 +740,61 @@ Ref<AutoscanInotify::WatchAutoscan> AutoscanInotify::getStartPoint(Ref<Wd> wdObj
 {
     Ref<Watch> watch;
     Ref<WatchAutoscan> watchAs;
-    Ref<Array<Watch> > wdWatches = wdObj->getWdWatches();
-    for (int i = 0; i < wdWatches->size(); i++)
-    {
+    Ref<Array<Watch>> wdWatches = wdObj->getWdWatches();
+    for (int i = 0; i < wdWatches->size(); i++) {
         watch = wdWatches->get(i);
-        if (watch->getType() == WatchAutoscanType)
-        {
+        if (watch->getType() == WatchAutoscanType) {
             watchAs = RefCast(watch, WatchAutoscan);
             if (watchAs->isStartPoint())
                 return watchAs;
         }
     }
-    return nil;
+    return nullptr;
 }
 
 void AutoscanInotify::addDescendant(int startPointWd, int addWd, Ref<AutoscanDirectory> adir)
 {
-//    log_debug("called for %d, (adir->path=%s); adding %d\n", startPointWd, adir->getLocation().c_str(), addWd);
-    Ref<Wd> wdObj = watches->get(startPointWd);
-    if (wdObj == nil)
+    //    log_debug("called for %d, (adir->path=%s); adding %d\n", startPointWd, adir->getLocation().c_str(), addWd);
+    Ref<Wd> wdObj = nullptr;
+    try {
+        wdObj = watches->at(startPointWd);
+    } catch (const std::out_of_range& ex) {
         return;
-//   log_debug("found wdObj\n");
+    }
+    if (wdObj == nullptr)
+        return;
+
+    //   log_debug("found wdObj\n");
     Ref<WatchAutoscan> watch = getAppropriateAutoscan(wdObj, adir);
-    if (watch == nil)
+    if (watch == nullptr)
         return;
-//    log_debug("adding descendant\n");
+    //    log_debug("adding descendant\n");
     watch->addDescendant(addWd);
-//    log_debug("added descendant to %d (adir->path=%s): %d; now: %s\n", startPointWd, adir->getLocation().c_str(), addWd, watch->getDescendants()->toCSV().c_str());
+    //    log_debug("added descendant to %d (adir->path=%s): %d; now: %s\n", startPointWd, adir->getLocation().c_str(), addWd, watch->getDescendants()->toCSV().c_str());
 }
 
 void AutoscanInotify::removeDescendants(int wd)
 {
-    Ref<Wd> wdObj = watches->get(wd);
-    if (wdObj == nil)
+    Ref<Wd> wdObj = nullptr;
+    try {
+        wdObj = watches->at(wd);
+    } catch (const out_of_range& ex) {
         return;
-    Ref<Array<Watch> > wdWatches = wdObj->getWdWatches();
-    if (wdWatches == nil)
+    }
+
+    Ref<Array<Watch>> wdWatches = wdObj->getWdWatches();
+    if (wdWatches == nullptr)
         return;
-    
+
     Ref<Watch> watch;
     Ref<WatchAutoscan> watchAs;
-    for (int i = 0; i < wdWatches->size(); i++)
-    {
+    for (int i = 0; i < wdWatches->size(); i++) {
         watch = wdWatches->get(i);
-        if (watch->getType() == WatchAutoscanType)
-        {
+        if (watch->getType() == WatchAutoscanType) {
             watchAs = RefCast(watch, WatchAutoscan);
             Ref<IntArray> descendants = watchAs->getDescendants();
-            if (descendants != nil)
-            {
-                for (int i = 0; i < descendants->size(); i++)
-                {
+            if (descendants != nullptr) {
+                for (int i = 0; i < descendants->size(); i++) {
                     int descWd = descendants->get(i);
                     inotify->removeWatch(descWd);
                 }
@@ -912,14 +805,11 @@ void AutoscanInotify::removeDescendants(int wd)
 
 String AutoscanInotify::normalizePathNoEx(String path)
 {
-    try
-    {
+    try {
         return normalizePath(path);
-    }
-    catch (Exception e)
-    {
+    } catch (const Exception& e) {
         log_error("%s\n", e.getMessage().c_str());
-        return nil;
+        return nullptr;
     }
 }
 
diff --git a/src/autoscan_inotify.h b/src/autoscan_inotify.h
index a0fdb60..62e068e 100644
--- a/src/autoscan_inotify.h
+++ b/src/autoscan_inotify.h
@@ -31,11 +31,14 @@
 #ifndef __AUTOSCAN_INOTIFY_H__
 #define __AUTOSCAN_INOTIFY_H__
 
-#include "zmmf/zmmf.h"
-#include "sync.h"
-#include "hash.h"
+#include <memory>
+#include <mutex>
+#include <unordered_map>
+
+#include "zmm/zmmf.h"
 #include "autoscan.h"
 #include "mt_inotify.h"
+#include "singleton.h"
 
 #define INOTIFY_ROOT -1
 #define INOTIFY_UNKNOWN_PARENT_WD -2
@@ -46,17 +49,17 @@ enum inotify_watch_type_t
     InotifyWatchTypeAutoscan
 };
 
-class AutoscanInotify : public zmm::Object
+class AutoscanInotify : public Singleton<AutoscanInotify, std::mutex>
 {
 public:
     AutoscanInotify();
     virtual ~AutoscanInotify();
-    void init();
+    void init() override;
     
     /// \brief shutdown the inotify thread
     /// 
     /// warning: currently doesn't remove all the remaining inotify watches!
-    void shutdown();
+    void shutdown() override;
     
     /// \brief Start monitoring a directory
     void monitor(zmm::Ref<AutoscanDirectory> dir);
@@ -71,10 +74,10 @@ private:
     pthread_t thread;
     
     zmm::Ref<Inotify> inotify;
-    
-    zmm::Ref<Cond> cond;
-    zmm::Ref<Mutex> mutex;
-    
+
+    std::mutex mutex;
+    using AutoLock = std::lock_guard<std::mutex>;
+
     zmm::Ref<zmm::ObjectQueue<AutoscanDirectory> > monitorQueue;
     zmm::Ref<zmm::ObjectQueue<AutoscanDirectory> > unmonitorQueue;
     
@@ -106,9 +109,9 @@ private:
         {
             setAutoscanDirectory(adir);
             setNormalizedAutoscanPath(normalizedAutoscanPath);
-            setNonexistingPathArray(nil);
+            setNonexistingPathArray(nullptr);
             this->startPoint = startPoint;
-            this->descendants = nil;
+            this->descendants = nullptr;
         }
         zmm::Ref<AutoscanDirectory> getAutoscanDirectory() { return adir; }
         void setAutoscanDirectory(zmm::Ref<AutoscanDirectory> adir) { this->adir = adir; }
@@ -119,7 +122,7 @@ private:
         void setNonexistingPathArray(zmm::Ref<zmm::Array<zmm::StringBase> > nonexistingPathArray) { this->nonexistingPathArray = nonexistingPathArray; }
         void addDescendant(int wd)
         {
-            if (descendants == nil)
+            if (descendants == nullptr)
                 descendants = zmm::Ref<zmm::IntArray>(new zmm::IntArray());
             descendants->append(wd);
         }
@@ -165,13 +168,13 @@ private:
         int parentWd;
         int wd;
     };
-    
-    zmm::Ref<DBOHash<int, Wd> > watches;
+
+    std::shared_ptr<std::unordered_map<int, zmm::Ref<Wd>> > watches;
     
     zmm::String normalizePathNoEx(zmm::String path);
     
     void monitorUnmonitorRecursive(zmm::String startPath, bool unmonitor, zmm::Ref<AutoscanDirectory> adir, zmm::String normalizedAutoscanPath, bool startPoint);
-    int monitorDirectory(zmm::String path, zmm::Ref<AutoscanDirectory> adir, zmm::String normalizedAutoscanPath, bool startPoint, zmm::Ref<zmm::Array<zmm::StringBase> > pathArray = nil);
+    int monitorDirectory(zmm::String path, zmm::Ref<AutoscanDirectory> adir, zmm::String normalizedAutoscanPath, bool startPoint, zmm::Ref<zmm::Array<zmm::StringBase> > pathArray = nullptr);
     void unmonitorDirectory(zmm::String path, zmm::Ref<AutoscanDirectory> adir);
     
     zmm::Ref<WatchAutoscan> getAppropriateAutoscan(zmm::Ref<Wd> wdObj, zmm::Ref<AutoscanDirectory> adir);
diff --git a/src/buffered_io_handler.cc b/src/buffered_io_handler.cc
index 8da13c0..90b2774 100644
--- a/src/buffered_io_handler.cc
+++ b/src/buffered_io_handler.cc
@@ -29,19 +29,19 @@
 
 /// \file buffered_io_handler.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
+#include <cassert>
 
 #include "buffered_io_handler.h"
 #include "tools.h"
 
+
 using namespace zmm;
+using namespace std;
 
 BufferedIOHandler::BufferedIOHandler(Ref<IOHandler> underlyingHandler, size_t bufSize, size_t maxChunkSize, size_t initialFillSize) : IOHandlerBufferHelper(bufSize, initialFillSize)
 {
-    if (underlyingHandler == nil)
-        throw _Exception(_("underlyingHandler must not be nil"));
+    if (underlyingHandler == nullptr)
+        throw _Exception(_("underlyingHandler must not be nullptr"));
     if (maxChunkSize <= 0)
         throw _Exception(_("maxChunkSize must be positive"));
     this->underlyingHandler = underlyingHandler;
@@ -75,7 +75,7 @@ void BufferedIOHandler::threadProc()
     bool first_log = true;
 #endif
     
-    AUTOLOCK(mutex);
+    unique_lock<std::mutex> lock(mutex);
     do
     {
         
@@ -129,7 +129,7 @@ void BufferedIOHandler::threadProc()
                 /// \todo do we need to wait for initialFillSize again?
                 
                 doSeek = false;
-                cond->signal();
+                cond.notify_one();
             }
         }
         
@@ -144,7 +144,7 @@ void BufferedIOHandler::threadProc()
                 empty = true;
                 a = b = 0;
             }
-            catch (Exception e)
+            catch (const Exception & e)
             {
                 log_error("Error while seeking in buffer: %s\n", e.getMessage().c_str());
                 e.printStackTrace();
@@ -154,20 +154,20 @@ void BufferedIOHandler::threadProc()
             waitForInitialFillSize = (initialFillSize > 0);
             
             doSeek = false;
-            cond->signal();
+            cond.notify_one();
         }
         
         maxWrite = (empty ? bufSize : (a < b ? bufSize - b : a - b));
         if (maxWrite == 0)
         {
-            cond->wait();
+            cond.wait(lock);
         }
         else
         {
-            AUTOUNLOCK();
+            lock.unlock();
             size_t chunkSize = (maxChunkSize > maxWrite ? maxWrite : maxChunkSize);
             readBytes = underlyingHandler->read(buffer + b, chunkSize);
-            AUTORELOCK();
+            lock.lock();
             if (readBytes > 0)
             {
                 b += readBytes;
@@ -177,7 +177,7 @@ void BufferedIOHandler::threadProc()
                 if (empty)
                 {
                     empty = false;
-                    cond->signal();
+                    cond.notify_one();
                 }
                 if (waitForInitialFillSize)
                 {
@@ -188,14 +188,14 @@ void BufferedIOHandler::threadProc()
                     {
                         log_debug("buffer: initial fillsize reached\n");
                         waitForInitialFillSize = false;
-                        cond->signal();
+                        cond.notify_one();
                     }
                 }
             }
             else if (readBytes == CHECK_SOCKET)
             {
                 checkSocket = true;
-                cond->signal();
+                cond.notify_one();
             }
         }
     }
@@ -208,5 +208,5 @@ void BufferedIOHandler::threadProc()
             readError = true;
     }
     // ensure that read() doesn't wait for me to fill the buffer
-    cond->signal();
+    cond.notify_one();
 }
diff --git a/src/buffered_io_handler.h b/src/buffered_io_handler.h
index f6fd69b..541a8e1 100644
--- a/src/buffered_io_handler.h
+++ b/src/buffered_io_handler.h
@@ -32,8 +32,9 @@
 #ifndef __BUFFERED_IO_HANDLER_H__
 #define __BUFFERED_IO_HANDLER_H__
 
+#include <upnp-1.8/upnp.h>
+
 #include "common.h"
-#include "upnp.h"
 #include "io_handler_buffer_helper.h"
 
 /// \brief a IOHandler with buffer support
diff --git a/src/cached_url.cc b/src/cached_url.cc
index 48af05b..dc3d2a9 100644
--- a/src/cached_url.cc
+++ b/src/cached_url.cc
@@ -29,11 +29,7 @@
 
 /// \file cached_url.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include <time.h>
+#include <ctime>
 
 #include "cached_url.h"
 #include "tools.h"
@@ -44,14 +40,13 @@ CachedURL::CachedURL(int object_id, zmm::String url)
 {
     this->object_id = object_id;
     this->url = url;
-    this->creation_time = time(NULL);
+    this->creation_time = time(nullptr);
     if (this->creation_time == -1)
     {
         throw _Exception(_("Failed to get current time: ") + 
                          mt_strerror(errno));
     }
     this->last_access_time = creation_time;
-    mutex = Ref<Mutex>(new Mutex(false)); // non recursive mutex
 }
 
 int CachedURL::getObjectID()
@@ -61,8 +56,8 @@ int CachedURL::getObjectID()
     
 String CachedURL::getURL()
 {
-    AUTOLOCK(mutex);
-    last_access_time = time(NULL);
+    AutoLock lock(mutex);
+    last_access_time = time(nullptr);
     if (last_access_time == -1)
     {
         throw _Exception(_("Failed to get current time: ") + 
@@ -79,6 +74,6 @@ time_t CachedURL::getCreationTime()
     /// \brief Retrieves the time when the last access time of the data.
 time_t CachedURL::getLastAccessTime()
 {
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     return last_access_time;
 }
diff --git a/src/cached_url.h b/src/cached_url.h
index 1cd690e..98bd1ca 100644
--- a/src/cached_url.h
+++ b/src/cached_url.h
@@ -33,9 +33,9 @@
 #ifndef __CACHED_URL_H__
 #define __CACHED_URL_H__
 
-#include "zmmf/zmmf.h"
+#include <mutex>
+#include "zmm/zmmf.h"
 #include "zmm/zmm.h"
-#include "sync.h"
 
 /// \brief Stores information about cached URLs
 class CachedURL : public zmm::Object
@@ -62,7 +62,8 @@ protected:
     time_t creation_time;
     time_t last_access_time;
 
-    zmm::Ref<Mutex> mutex;
+    std::mutex mutex;
+    using AutoLock = std::lock_guard<std::mutex>;
 };
 
 #endif//__CACHED_URL_H__
diff --git a/src/cds_objects.cc b/src/cds_objects.cc
index 8edcef3..3e225b6 100644
--- a/src/cds_objects.cc
+++ b/src/cds_objects.cc
@@ -29,10 +29,6 @@
 
 /// \file cds_objects.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "cds_objects.h"
 #include "tools.h"
 #include "storage.h"
@@ -49,6 +45,8 @@ CdsObject::CdsObject() : Object()
     id = INVALID_OBJECT_ID;
     parentID = INVALID_OBJECT_ID;
     refID = INVALID_OBJECT_ID;
+    mtime = 0;
+    sizeOnDisk = 0;
     virt = 0;
     sortPriority = 0;
     objectFlags = OBJECT_FLAG_RESTRICTED;
@@ -62,6 +60,8 @@ void CdsObject::copyTo(Ref<CdsObject> obj)
     obj->setTitle(title);
     obj->setClass(upnpClass);
     obj->setLocation(location);
+    obj->setMTime(mtime);
+    obj->setSizeOnDisk(sizeOnDisk);
     obj->setVirtual(virt);
     obj->setMetadata(metadata->clone());
     obj->setAuxData(auxdata->clone());
@@ -90,6 +90,8 @@ int CdsObject::equals(Ref<CdsObject> obj, bool exactly)
     
     if (exactly && !
         (location == obj->getLocation() &&
+         mtime == obj->getMTime() &&
+         sizeOnDisk == obj->getSizeOnDisk() &&
          virt == obj->isVirtual() &&
          auxdata->equals(obj->auxdata) &&
          objectFlags == obj->getFlags()
@@ -162,7 +164,7 @@ CdsItem::CdsItem() : CdsObject()
     upnpClass = _("object.item");
     mimeType = _(MIMETYPE_DEFAULT);
     trackNumber = 0;
-    serviceID = nil;
+    serviceID = nullptr;
 }
 
 void CdsItem::copyTo(Ref<CdsObject> obj)
diff --git a/src/cds_objects.h b/src/cds_objects.h
index a531e34..3298b07 100644
--- a/src/cds_objects.h
+++ b/src/cds_objects.h
@@ -32,6 +32,8 @@
 #ifndef __CDS_OBJECTS_H__
 #define __CDS_OBJECTS_H__
 
+#include <sys/types.h>
+
 #include "common.h"
 #include "dictionary.h"
 #include "cds_resource.h"
@@ -64,7 +66,6 @@
 #define OBJECT_FLAG_PROXY_URL             0x00000020
 #define OBJECT_FLAG_ONLINE_SERVICE        0x00000040
 #define OBJECT_FLAG_OGG_THEORA            0x00000080
-#define OBJECT_FLAG_DVD_IMAGE             0x00000100
 #define OBJECT_FLAG_PLAYED                0x00000200
 
 #define OBJECT_AUTOSCAN_NONE    0
@@ -95,6 +96,13 @@ protected:
     /// \brief Physical location of the media.
     zmm::String location;
 
+    /// \brief Last modification time in the file system.
+    /// In seconds since UNIX epoch.
+    time_t mtime;
+
+    /// \brief File size on disk (in bytes).
+    off_t sizeOnDisk;
+
     /// \brief virtual object flag
     int virt;
 
@@ -168,6 +176,18 @@ public:
     /// \brief Retrieve media location.
     inline zmm::String getLocation() { return location; }
 
+    /// \brief Set modification time of the media file.
+    inline void setMTime(time_t mtime) { this->mtime = mtime; }
+
+    /// \brief Retrieve the file modification time (in seconds since UNIX epoch).
+    inline time_t getMTime() { return mtime; }
+
+    /// \brief Set file size.
+    inline void setSizeOnDisk(off_t sizeOnDisk) { this->sizeOnDisk = sizeOnDisk; }
+
+    /// \brief Retrieve the file size (in bytes).
+    inline off_t getSizeOnDisk() { return sizeOnDisk; }
+
     /// \brief Set the virtual flag.
     inline void setVirtual(bool virt) { this->virt = virt; }
 
diff --git a/src/cds_resource.cc b/src/cds_resource.cc
index c7f4e5e..645ffc8 100644
--- a/src/cds_resource.cc
+++ b/src/cds_resource.cc
@@ -29,10 +29,6 @@
 
 /// \file cds_resource.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "tools.h"
 #include "cds_resource.h"
 
diff --git a/src/cds_resource_manager.cc b/src/cds_resource_manager.cc
index 824905c..cfb1472 100644
--- a/src/cds_resource_manager.cc
+++ b/src/cds_resource_manager.cc
@@ -29,10 +29,6 @@
 
 /// \file cds_resource_manager.cc
 
-#ifdef HAVE_CONFIG_H
-#include "autoconfig.h"
-#endif
-
 #include "cds_resource_manager.h"
 #include "dictionary.h"
 #include "object_dictionary.h"
@@ -75,7 +71,7 @@ String CdsResourceManager::renderExtension(String contentType, String location)
             }
         }
     }
-    return nil;
+    return nullptr;
 }
 
 void CdsResourceManager::addResources(Ref<CdsItem> item, Ref<Element> element)
@@ -141,14 +137,14 @@ void CdsResourceManager::addResources(Ref<CdsItem> item, Ref<Element> element)
     Ref<TranscodingProfileList> tlist = config->getTranscodingProfileListOption(
             CFG_TRANSCODING_PROFILE_LIST);
     Ref<ObjectDictionary<TranscodingProfile> > tp_mt = tlist->get(item->getMimeType());
-    if (tp_mt != nil)
+    if (tp_mt != nullptr)
     {
         Ref<Array<ObjectDictionaryElement<TranscodingProfile> > > profiles = tp_mt->getElements();
         for (int p = 0; p < profiles->size(); p++)
         {
             Ref<TranscodingProfile> tp = profiles->get(p)->getValue();
 
-            if (tp == nil)
+            if (tp == nullptr)
                 throw _Exception(_("Invalid profile encountered!"));
 
             String ct = mappings->get(item->getMimeType());
@@ -203,9 +199,6 @@ void CdsResourceManager::addResources(Ref<CdsItem> item, Ref<Element> element)
                 }
             }
 
-            if (!item->getFlag(OBJECT_FLAG_DVD_IMAGE) && (tp->onlyDVD()))
-                continue;
-
             Ref<CdsResource> t_res(new CdsResource(CH_TRANSCODE));
             t_res->addParameter(_(URL_PARAM_TRANSCODE_PROFILE_NAME), tp->getName());
             // after transcoding resource was added we can not rely on
@@ -289,14 +282,15 @@ void CdsResourceManager::addResources(Ref<CdsItem> item, Ref<Element> element)
 #endif // EXTERNAL_TRANSCODING
 
     int resCount = item->getResourceCount();
-    for (int i = 0; i < resCount; i++)
-    {
+    for (int i = 0; i < resCount; i++) {
+
         /// \todo what if the resource has a different mimetype than the item??
         /*        String mimeType = item->getMimeType();
                   if (!string_ok(mimeType)) mimeType = DEFAULT_MIMETYPE; */
 
-        Ref<Dictionary> res_attrs = item->getResource(i)->getAttributes();
-        Ref<Dictionary> res_params = item->getResource(i)->getParameters();
+        Ref<CdsResource> res = item->getResource(i);
+        Ref<Dictionary> res_attrs = res->getAttributes();
+        Ref<Dictionary> res_params = res->getParameters();
         String protocolInfo = res_attrs->get(MetadataHandler::getResAttrName(R_PROTOCOLINFO));
         String mimeType = getMTFromProtocolInfo(protocolInfo);
 
@@ -310,7 +304,7 @@ void CdsResourceManager::addResources(Ref<CdsItem> item, Ref<Element> element)
         String contentType = mappings->get(mimeType);
         String url;
 
-        /// \todo who will sync mimetype that is part of the protocl info and
+        /// \todo who will sync mimetype that is part of the protocol info and
         /// that is lying in the resources with the information that is in the
         /// resource tags?
 
@@ -343,7 +337,7 @@ void CdsResourceManager::addResources(Ref<CdsItem> item, Ref<Element> element)
                 url = urlBase->urlBase + _(URL_VALUE_TRANSCODE_NO_RES_ID);
             else
             {
-                assert(urlBase_tr != nil);
+                assert(urlBase_tr != nullptr);
                 url = urlBase_tr->urlBase + _(URL_VALUE_TRANSCODE_NO_RES_ID);
             }
         }
@@ -353,7 +347,7 @@ void CdsResourceManager::addResources(Ref<CdsItem> item, Ref<Element> element)
         else
             url = urlBase->urlBase;
 #endif
-        if ((res_params != nil) && (res_params->size() > 0))
+        if ((res_params != nullptr) && (res_params->size() > 0))
         {
             url = url + _(_URL_PARAM_SEPARATOR);
             url = url + res_params->encodeSimple();
@@ -361,51 +355,50 @@ void CdsResourceManager::addResources(Ref<CdsItem> item, Ref<Element> element)
 
         // ok this really sucks, I guess another rewrite of the resource manager
         // is necessary
-        if ((i > 0) && (item->getResource(i)->getHandlerType() == CH_EXTURL) &&
-           ((item->getResource(i)->getOption(_(RESOURCE_CONTENT_TYPE)) == 
-            THUMBNAIL) || 
-            (item->getResource(i)->getOption(_(RESOURCE_CONTENT_TYPE)) ==
-                            ID3_ALBUM_ART)))
+        if ((i > 0) && (res->getHandlerType() == CH_EXTURL) &&
+           ((res->getOption(_(RESOURCE_CONTENT_TYPE)) == THUMBNAIL) ||
+            (res->getOption(_(RESOURCE_CONTENT_TYPE)) == ID3_ALBUM_ART)))
         {
-            url = item->getResource(i)->getOption(_(RESOURCE_OPTION_URL));
+            url = res->getOption(_(RESOURCE_OPTION_URL));
             if (!string_ok(url))
                 throw _Exception(_("missing thumbnail URL!"));
 
             isExtThumbnail = true;
         }
 
-        /// \todo currently resource is misused for album art
-#ifdef HAVE_ID3_ALBUMART
+        /// FIXME: currently resource is misused for album art
+
         // only add upnp:AlbumArtURI if we have an AA, skip the resource
-        if ((i > 0) && ((item->getResource(i)->getHandlerType() == CH_ID3) ||
-                        (item->getResource(i)->getHandlerType() == CH_MP4) ||
-                        (item->getResource(i)->getHandlerType() == CH_FLAC) ||
-                        (item->getResource(i)->getHandlerType() == CH_EXTURL)))
-        {
-            String rct;
-            if (item->getResource(i)->getHandlerType() == CH_EXTURL)
-                rct = item->getResource(i)->getOption(_(RESOURCE_CONTENT_TYPE));
-            else    
-                rct = item->getResource(i)->getParameter(_(RESOURCE_CONTENT_TYPE));
-            if (rct == ID3_ALBUM_ART)
-            {
-                Ref<Element> aa(new Element(MetadataHandler::getMetaFieldName(M_ALBUMARTURI)));
-                aa->setText(url);
+        if (i > 0) {
+            int handlerType = res->getHandlerType();
+
+            if (handlerType == CH_ID3 || (handlerType == CH_MP4) ||
+                handlerType == CH_FLAC || handlerType == CH_FANART ||
+                handlerType == CH_EXTURL) {
+
+                String rct;
+                if (res->getHandlerType() == CH_EXTURL)
+                    rct = res->getOption(_(RESOURCE_CONTENT_TYPE));
+                else
+                    rct = res->getParameter(_(RESOURCE_CONTENT_TYPE));
+                if (rct == ID3_ALBUM_ART) {
+                    Ref<Element> aa(new Element(MetadataHandler::getMetaFieldName(M_ALBUMARTURI)));
+                    aa->setText(url);
 #ifdef EXTEND_PROTOCOLINFO
-                if (config->getBoolOption(CFG_SERVER_EXTEND_PROTOCOLINFO))
-                {
-                    /// \todo clean this up, make sure to check the mimetype and
-                    /// provide the profile correctly
-                    aa->setAttribute(_("xmlns:dlna"), 
-                                     _("urn:schemas-dlna-org:metadata-1-0"));
-                    aa->setAttribute(_("dlna:profileID"), _("JPEG_TN"));
-                }
+                    if (config->getBoolOption(CFG_SERVER_EXTEND_PROTOCOLINFO)) {
+                        /// \todo clean this up, make sure to check the mimetype and
+                        /// provide the profile correctly
+                        aa->setAttribute(_("xmlns:dlna"),
+                                         _("urn:schemas-dlna-org:metadata-1-0"));
+                        aa->setAttribute(_("dlna:profileID"), _("JPEG_TN"));
+                    }
 #endif
-                element->appendElementChild(aa);
-                continue;
+                    element->appendElementChild(aa);
+                    continue;
+                }
             }
         }
-#endif
+
         if (!isExtThumbnail)
         {
 #ifdef EXTERNAL_TRANSCODING
@@ -416,7 +409,7 @@ void CdsResourceManager::addResources(Ref<CdsItem> item, Ref<Element> element)
             if (!skipURL)
             {
                 if (transcoded)
-                    url = url + renderExtension(contentType, nil);
+                    url = url + renderExtension(contentType, nullptr);
                 else
                     url = url + renderExtension(contentType, item->getLocation()); 
             }
@@ -553,19 +546,6 @@ Ref<CdsResourceManager::UrlBase> CdsResourceManager::addResources_getUrlBase(Ref
         }
     }
 
-#ifdef HAVE_LIBDVDNAV_DISABLED
-    if (IS_CDS_ITEM(objectType) && (item->getFlag(OBJECT_FLAG_DVD_IMAGE)))
-    {
-        urlBase->urlBase = Server::getInstance()->getVirtualURL() +
-                          _(_URL_PARAM_SEPARATOR) +
-                           CONTENT_DVD_IMAGE_HANDLER + _(_URL_PARAM_SEPARATOR) +
-                           dict->encodeSimple() + _(_URL_PARAM_SEPARATOR) +
-                           _(URL_RESOURCE_ID) + _(_URL_PARAM_SEPARATOR);
-        urlBase->addResID = true;
-        return urlBase;
-    }
-#endif
-        
     urlBase->urlBase = Server::getInstance()->getVirtualURL() +
                        _(_URL_PARAM_SEPARATOR) +
                        CONTENT_MEDIA_HANDLER + _(_URL_PARAM_SEPARATOR) + 
@@ -584,3 +564,15 @@ String CdsResourceManager::getFirstResource(Ref<CdsItem> item)
     else
         return urlBase->urlBase;
 }
+
+String CdsResourceManager::getArtworkUrl(zmm::Ref<CdsItem> item) {
+    // FIXME: This is temporary until we do artwork properly.
+    log_debug("Building Art url for %d\n", item->getID());
+
+    Ref<UrlBase> urlBase = addResources_getUrlBase(item);
+
+    if (urlBase->addResID)
+        return urlBase->urlBase + 1 + "/rct/aa";
+    else
+        return urlBase->urlBase;
+}
\ No newline at end of file
diff --git a/src/cds_resource_manager.h b/src/cds_resource_manager.h
index e2f86cf..315838f 100644
--- a/src/cds_resource_manager.h
+++ b/src/cds_resource_manager.h
@@ -60,7 +60,12 @@ public:
     /// \param item Item for which the resources should be built.
     /// \return The URL
     static zmm::String getFirstResource(zmm::Ref<CdsItem> item);
-    
+
+    /// \brief Gets the URL of the artwork.
+    /// \param item Item for which the resources should be built.
+    /// \return The URL
+    static zmm::String getArtworkUrl(zmm::Ref<CdsItem> item);
+
 protected:
     class UrlBase : public zmm::Object
     {
@@ -68,7 +73,7 @@ protected:
         zmm::String urlBase;
         bool addResID;
     };
-    
+
     /// \brief Gets the baseUrl for a CdsItem.
     /// \param item Item for which the baseUrl should be built.
     ///
diff --git a/src/common.h b/src/common.h
index e888302..83cc615 100644
--- a/src/common.h
+++ b/src/common.h
@@ -35,7 +35,7 @@
 
 #include "memory.h"
 #include "logger.h"
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 #include "exceptions.h"
 
 #define CONFIG_XML_VERSION_0_11_0       1
@@ -96,9 +96,6 @@
 #define YES                             "yes"
 #define NO                              "no"
 
-#define TRUE                            "1"
-#define FALSE                           "0"
-
 // URL FORMATTING CONSTANTS
 #define URL_OBJECT_ID                   "object_id"
 #define URL_REQUEST_TYPE                "req_type"
@@ -114,7 +111,6 @@
 #define CONTENT_SERVE_HANDLER           "serve"
 #define CONTENT_ONLINE_HANDLER          "online"
 #define CONTENT_UI_HANDLER              "interface"
-#define CONTENT_DVD_IMAGE_HANDLER       "dvd"
 // REQUEST TYPES
 #define REQ_TYPE_BROWSE                 "browse"
 #define REQ_TYPE_LOGIN                  "login"
@@ -144,8 +140,8 @@
 #define DESC_SPEC_VERSION_MAJOR         "1"
 #define DESC_SPEC_VERSION_MINOR         "0"
 #define DESC_FRIENDLY_NAME              PACKAGE_NAME 
-#define DESC_MANUFACTURER               "(c) 2005-2008 Gena Batyan <bgeradz at mediatomb.cc>, Sergey Bostandzhyan <jin at mediatomb.cc>, Leonhard Wimmer <leo at mediatomb.cc>"
-#define DESC_MANUFACTURER_URL           "http://mediatomb.cc/"
+#define DESC_MANUFACTURER               "Gerbera Contributors"
+#define DESC_MANUFACTURER_URL           "http://gerbera.io/"
 #define DESC_MODEL_DESCRIPTION          "Free UPnP AV MediaServer, GNU GPL"
 #define DESC_MODEL_NAME                 PACKAGE_NAME
 #define DESC_MODEL_NUMBER               VERSION 
@@ -201,33 +197,26 @@
 
 // default values
 #define DEFAULT_INTERNAL_CHARSET        "UTF-8"
-#define DEFAULT_FILESYSTEM_CHARSET      "ISO-8859-1"
-#define DEFAULT_METADATA_CHARSET        "ISO-8859-1"
+#define DEFAULT_FILESYSTEM_CHARSET      "UTF-8"
 #define DEFAULT_FALLBACK_CHARSET        "US-ASCII"
 #define DEFAULT_JS_CHARSET              "UTF-8"
 
-#if defined(__CYGWIN__)
-    #define DEFAULT_CONFIG_HOME         "MediaTomb"
-#else
-    #define DEFAULT_CONFIG_HOME         ".mediatomb"
-#endif
-#define DEFAULT_SYSTEM_HOME             "mediatomb"
-#define DEFAULT_ETC                     "etc"
+#define DEFAULT_CONFIG_HOME             ".config/gerbera"
 #define DEFAULT_TMPDIR                  "/tmp/"
 #define DEFAULT_CONFIG_NAME             "config.xml"
 #define DEFAULT_UI_EN_VALUE             YES
 #define DEFAULT_UI_SHOW_TOOLTIPS_VALUE  YES
 #define DEFAULT_POLL_WHEN_IDLE_VALUE    NO
-#define DEFAULT_POLL_INTERVAL           2 
+#define DEFAULT_POLL_INTERVAL           2
 #define DEFAULT_ACCOUNTS_EN_VALUE       NO
-#define DEFAULT_ACCOUNT_USER            "mediatomb"
-#define DEFAULT_ACCOUNT_PASSWORD        "mediatomb"
+#define DEFAULT_ACCOUNT_USER            "gerbera"
+#define DEFAULT_ACCOUNT_PASSWORD        "gerbera"
 #define DEFAULT_ALIVE_INTERVAL          1800 // seconds
+#define ALIVE_INTERVAL_MIN              62 // seconds
 #define DEFAULT_BOOKMARK_FILE           "mediatomb.html"
 #define DEFAULT_IGNORE_UNKNOWN_EXTENSIONS NO
 #define DEFAULT_CASE_SENSITIVE_EXTENSION_MAPPINGS NO
 #define DEFAULT_IMPORT_SCRIPT           "import.js"
-#define DEFAULT_DVD_SCRIPT              "import-dvd.js"
 #define DEFAULT_PLAYLISTS_SCRIPT        "playlists.js"
 #define DEFAULT_PLAYLIST_CREATE_LINK    YES
 #define DEFAULT_COMMON_SCRIPT           "common.js"
@@ -274,11 +263,6 @@
     #define DEFAULT_SOPCAST_ENABLED     NO
     #define DEFAULT_SOPCAST_UPDATE_AT_START NO
 #endif
-#ifdef WEBORAMA 
-    #define DEFAULT_WEBORAMA_ENABLED     NO
-    #define DEFAULT_WEBORAMA_UPDATE_AT_START NO
-    #define DEFAULT_WEBORAMA_REFRESH    28800
-#endif
 #ifdef ATRAILERS
     #define DEFAULT_ATRAILERS_ENABLED     NO
     #define DEFAULT_ATRAILERS_UPDATE_AT_START NO
@@ -370,6 +354,8 @@
     #define DEFAULT_FFMPEGTHUMBNAILER_FILMSTRIP_OVERLAY YES
     #define DEFAULT_FFMPEGTHUMBNAILER_WORKAROUND_BUGS   NO
     #define DEFAULT_FFMPEGTHUMBNAILER_IMAGE_QUALITY     8
+    #define DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED YES
+    #define DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR         ""
 #endif
 
 #if defined(HAVE_LASTFMLIB)
@@ -394,6 +380,4 @@
                                           CONTENT_SERVE_HANDLER  "/"
 #define LINK_URL_REQUEST_HANDLER          "/" SERVER_VIRTUAL_DIR "/" \
                                           CONTENT_ONLINE_HANDLER "/"
-#define LINK_DVD_REQUEST_HANDLER          "/" SERVER_VIRTUAL_DIR "/" \
-                                          CONTENT_DVD_IMAGE_HANDLER "/"
 #endif // __COMMON_H__
diff --git a/src/config_manager.cc b/src/config_manager.cc
index 2d069c7..ac82b33 100644
--- a/src/config_manager.cc
+++ b/src/config_manager.cc
@@ -29,66 +29,62 @@
 
 /// \file config_manager.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include <stdio.h>
-#include "uuid/uuid.h"
-#include "common.h"
 #include "config_manager.h"
+#include "common.h"
+#include "metadata_handler.h"
 #include "storage.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "tools.h"
 #include "string_converter.h"
-#include "metadata_handler.h"
+#include "tools.h"
+#include "uuid/uuid.h"
+#include <cstdio>
+#include <sys/stat.h>
+#include <sys/types.h>
 
 #ifdef HAVE_INOTIFY
-    #include "mt_inotify.h"
+#include "mt_inotify.h"
 #endif
 
 #ifdef YOUTUBE
-    #include "youtube_service.h"
-#endif
-
-#ifdef WEBORAMA
-    #include "weborama_service.h"
+#include "youtube_service.h"
 #endif
 
-#if defined(HAVE_LANGINFO_H) && defined(HAVE_LOCALE_H)
-    #include <langinfo.h>
-    #include <locale.h>
+#if defined(HAVE_NL_LANGINFO) && defined(HAVE_SETLOCALE)
+#include <clocale>
+#include <langinfo.h>
 #endif
 
 #ifdef HAVE_CURL
-    #include <curl/curl.h>
+#include <curl/curl.h>
 #endif
 
 using namespace zmm;
 using namespace mxml;
 
-SINGLETON_MUTEX(ConfigManager, false);
-
-String ConfigManager::filename = nil;
-String ConfigManager::userhome = nil;
+String ConfigManager::filename = nullptr;
+String ConfigManager::userhome = nullptr;
 String ConfigManager::config_dir = _(DEFAULT_CONFIG_HOME);
 String ConfigManager::prefix_dir = _(PACKAGE_DATADIR);
-String ConfigManager::magic = nil;
+String ConfigManager::magic = nullptr;
 bool ConfigManager::debug_logging = false;
+String ConfigManager::ip = nullptr;
+String ConfigManager::interface = nullptr;
+int ConfigManager::port = -1;
 
 ConfigManager::~ConfigManager()
 {
-    filename = nil;
-    userhome = nil;
+    filename = nullptr;
+    userhome = nullptr;
     config_dir = _(DEFAULT_CONFIG_HOME);
     prefix_dir = _(PACKAGE_DATADIR);
-    magic = nil;
+    magic = nullptr;
+    ip = nullptr;
+    interface = nullptr;
 }
 
-void ConfigManager::setStaticArgs(String _filename, String _userhome, 
-                                  String _config_dir, String _prefix_dir,
-                                  String _magic, bool _debug_logging)
+void ConfigManager::setStaticArgs(String _filename, String _userhome,
+    String _config_dir, String _prefix_dir,
+    String _magic, bool _debug_logging,
+    String _ip, String _interface, int _port)
 {
     filename = _filename;
     userhome = _userhome;
@@ -96,53 +92,50 @@ void ConfigManager::setStaticArgs(String _filename, String _userhome,
     prefix_dir = _prefix_dir;
     magic = _magic;
     debug_logging = _debug_logging;
+    ip = _ip;
+    interface = _interface;
+    port = _port;
 }
 
-ConfigManager::ConfigManager() : Singleton<ConfigManager>()
+ConfigManager::ConfigManager()
+    : Singleton<ConfigManager, std::mutex>()
+{}
+
+void ConfigManager::init()
 {
-    options = Ref<Array<ConfigOption> > (new Array<ConfigOption>(CFG_MAX));
+    options = Ref<Array<ConfigOption> >(new Array<ConfigOption>(CFG_MAX));
 
     String home = userhome + DIR_SEPARATOR + config_dir;
     bool home_ok = true;
-    
-    if (filename == nil)
-    {
-        // we are looking for ~/.mediatomb
-        if (home_ok && (!check_path(userhome + DIR_SEPARATOR + config_dir + DIR_SEPARATOR + DEFAULT_CONFIG_NAME)))
-        {
+
+    if (filename == nullptr) {
+        // No config file path provided, so lets find one.
+        if (home_ok && (!check_path(userhome + DIR_SEPARATOR + config_dir + DIR_SEPARATOR + DEFAULT_CONFIG_NAME))) {
             home_ok = false;
-        }
-        else
-        {
+        } else {
             filename = home + DIR_SEPARATOR + DEFAULT_CONFIG_NAME;
         }
-        
-        if ((!home_ok) && (string_ok(userhome)))
-        {
+
+        if ((!home_ok) && (string_ok(userhome))) {
             userhome = normalizePath(userhome);
             filename = createDefaultConfig(userhome);
         }
-        
     }
-    
-    if (filename == nil)
-    {       
-        throw _Exception(_("\nThe server configuration file could not be found in ~/.mediatomb\n") +
-                "MediaTomb could not determine your home directory - automatic setup failed.\n" + 
-                "Try specifying an alternative configuration file on the command line.\n" + 
-                "For a list of options run: mediatomb -h\n");
+
+    if (filename == nullptr) {
+        throw _Exception(_("\nThe server configuration file could not be found in ~/.gerbera\n") + "Gerbera could not determine your home directory - automatic setup failed.\n" + "Try specifying an alternative configuration file on the command line.\n" + "For a list of options run: mediatomb -h\n");
     }
-    
+
     log_info("Loading configuration from: %s\n", filename.c_str());
     load(filename);
-    
+
     prepare_udn();
     validate(home);
 #ifdef TOMBDEBUG
-//    dumpOptions();
+    dumpOptions();
 #endif
     // now the XML is no longer needed we can destroy it
-    root = nil;
+    root = nullptr;
 }
 
 String ConfigManager::construct_path(String path)
@@ -151,14 +144,9 @@ String ConfigManager::construct_path(String path)
 
     if (path.charAt(0) == '/')
         return path;
-#if defined(__CYGWIN__)
-
-    if ((path.length() > 1) && (path.charAt(1) == ':'))
-        return path;
-#endif  
     if (home == "." && path.charAt(0) == '.')
         return path;
-    
+
     if (home == "")
         return _(".") + DIR_SEPARATOR + path;
     else
@@ -186,7 +174,7 @@ Ref<Element> ConfigManager::renderTranscodingSection()
 {
     Ref<Element> transcoding(new Element(_("transcoding")));
     transcoding->setAttribute(_("enabled"), _(DEFAULT_TRANSCODING_ENABLED));
-    
+
     Ref<Element> mt_prof_map(new Element(_("mimetype-profile-mappings")));
 
     Ref<Element> prof_flv(new Element(_("transcode")));
@@ -230,12 +218,12 @@ Ref<Element> ConfigManager::renderTranscodingSection()
     oggflac->appendElementChild(oggflac_agent);
 
     Ref<Element> oggflac_buffer(new Element(_("buffer")));
-    oggflac_buffer->setAttribute(_("size"), 
-            String::from(DEFAULT_AUDIO_BUFFER_SIZE));
-    oggflac_buffer->setAttribute(_("chunk-size"), 
-            String::from(DEFAULT_AUDIO_CHUNK_SIZE));
-    oggflac_buffer->setAttribute(_("fill-size"), 
-            String::from(DEFAULT_AUDIO_FILL_SIZE));
+    oggflac_buffer->setAttribute(_("size"),
+        String::from(DEFAULT_AUDIO_BUFFER_SIZE));
+    oggflac_buffer->setAttribute(_("chunk-size"),
+        String::from(DEFAULT_AUDIO_CHUNK_SIZE));
+    oggflac_buffer->setAttribute(_("fill-size"),
+        String::from(DEFAULT_AUDIO_FILL_SIZE));
     oggflac->appendElementChild(oggflac_buffer);
 
     profiles->appendElementChild(oggflac);
@@ -256,12 +244,12 @@ Ref<Element> ConfigManager::renderTranscodingSection()
     vlcmpeg->appendElementChild(vlcmpeg_agent);
 
     Ref<Element> vlcmpeg_buffer(new Element(_("buffer")));
-    vlcmpeg_buffer->setAttribute(_("size"), 
-            String::from(DEFAULT_VIDEO_BUFFER_SIZE));
-    vlcmpeg_buffer->setAttribute(_("chunk-size"), 
-            String::from(DEFAULT_VIDEO_CHUNK_SIZE));
+    vlcmpeg_buffer->setAttribute(_("size"),
+        String::from(DEFAULT_VIDEO_BUFFER_SIZE));
+    vlcmpeg_buffer->setAttribute(_("chunk-size"),
+        String::from(DEFAULT_VIDEO_CHUNK_SIZE));
     vlcmpeg_buffer->setAttribute(_("fill-size"),
-            String::from(DEFAULT_VIDEO_FILL_SIZE));
+        String::from(DEFAULT_VIDEO_FILL_SIZE));
     vlcmpeg->appendElementChild(vlcmpeg_buffer);
 
     profiles->appendElementChild(vlcmpeg);
@@ -278,28 +266,28 @@ Ref<Element> ConfigManager::renderExtendedRuntimeSection()
 #if defined(HAVE_FFMPEG) && defined(HAVE_FFMPEGTHUMBNAILER)
     Ref<Element> ffth(new Element(_("ffmpegthumbnailer")));
     ffth->setAttribute(_("enabled"), _(DEFAULT_FFMPEGTHUMBNAILER_ENABLED));
-    
-    ffth->appendTextChild(_("thumbnail-size"), 
-                          String::from(DEFAULT_FFMPEGTHUMBNAILER_THUMBSIZE));
+
+    ffth->appendTextChild(_("thumbnail-size"),
+        String::from(DEFAULT_FFMPEGTHUMBNAILER_THUMBSIZE));
     ffth->appendTextChild(_("seek-percentage"),
-                       String::from(DEFAULT_FFMPEGTHUMBNAILER_SEEK_PERCENTAGE));
+        String::from(DEFAULT_FFMPEGTHUMBNAILER_SEEK_PERCENTAGE));
     ffth->appendTextChild(_("filmstrip-overlay"),
-                          _(DEFAULT_FFMPEGTHUMBNAILER_FILMSTRIP_OVERLAY));
+        _(DEFAULT_FFMPEGTHUMBNAILER_FILMSTRIP_OVERLAY));
     ffth->appendTextChild(_("workaround-bugs"),
-                          _(DEFAULT_FFMPEGTHUMBNAILER_WORKAROUND_BUGS));
+        _(DEFAULT_FFMPEGTHUMBNAILER_WORKAROUND_BUGS));
     ffth->appendTextChild(_("image-quality"),
-                         String::from(DEFAULT_FFMPEGTHUMBNAILER_IMAGE_QUALITY));
+        String::from(DEFAULT_FFMPEGTHUMBNAILER_IMAGE_QUALITY));
 
     extended->appendElementChild(ffth);
 #endif
 
     Ref<Element> mark(new Element(_("mark-played-items")));
     mark->setAttribute(_("enabled"), _(DEFAULT_MARK_PLAYED_ITEMS_ENABLED));
-    mark->setAttribute(_("suppress-cds-updates"), 
-                        _(DEFAULT_MARK_PLAYED_ITEMS_SUPPRESS_CDS_UPDATES));
+    mark->setAttribute(_("suppress-cds-updates"),
+        _(DEFAULT_MARK_PLAYED_ITEMS_SUPPRESS_CDS_UPDATES));
     Ref<Element> mark_string(new Element(_("string")));
-    mark_string->setAttribute(_("mode"), 
-                              _(DEFAULT_MARK_PLAYED_ITEMS_STRING_MODE));
+    mark_string->setAttribute(_("mode"),
+        _(DEFAULT_MARK_PLAYED_ITEMS_STRING_MODE));
     mark_string->setText(_(DEFAULT_MARK_PLAYED_ITEMS_STRING));
     mark->appendElementChild(mark_string);
 
@@ -326,25 +314,25 @@ Ref<Element> ConfigManager::renderOnlineSection()
 {
     Ref<Element> onlinecontent(new Element(_("online-content")));
 #ifdef YOUTUBE
-//    Ref<Comment> ytinfo(new Comment(_(" Make sure to setup a transcoding profile for flv "), true));
-//    onlinecontent->appendChild(RefCast(ytinfo, Node));
+    //    Ref<Comment> ytinfo(new Comment(_(" Make sure to setup a transcoding profile for flv "), true));
+    //    onlinecontent->appendChild(RefCast(ytinfo, Node));
 
     Ref<Element> yt(new Element(_("YouTube")));
     yt->setAttribute(_("enabled"), _(DEFAULT_YOUTUBE_ENABLED));
     // 8 hours refresh cycle
-    yt->setAttribute(_("refresh"), String::from(DEFAULT_YOUTUBE_REFRESH)); 
+    yt->setAttribute(_("refresh"), String::from(DEFAULT_YOUTUBE_REFRESH));
     yt->setAttribute(_("update-at-start"), _(DEFAULT_YOUTUBE_UPDATE_AT_START));
     // items that were not updated for 4 days will be purged
-    yt->setAttribute(_("purge-after"), 
-            String::from(DEFAULT_YOUTUBE_PURGE_AFTER));
+    yt->setAttribute(_("purge-after"),
+        String::from(DEFAULT_YOUTUBE_PURGE_AFTER));
     yt->setAttribute(_("racy-content"), _(DEFAULT_YOUTUBE_RACY_CONTENT));
     yt->setAttribute(_("format"), _(DEFAULT_YOUTUBE_FORMAT));
     yt->setAttribute(_("hd"), _(DEFAULT_YOUTUBE_HD));
-   
+
     Ref<Element> favs(new Element(_("favorites")));
     favs->setAttribute(_("user"), _("mediatomb"));
     yt->appendElementChild(favs);
-    
+
     Ref<Element> most_viewed(new Element(_("standardfeed")));
     most_viewed->setAttribute(_("feed"), _("most_viewed"));
     most_viewed->setAttribute(_("time-range"), _("today"));
@@ -365,31 +353,6 @@ Ref<Element> ConfigManager::renderOnlineSection()
 
     onlinecontent->appendElementChild(yt);
 #endif
-#ifdef WEBORAMA
-    Ref<Element> wb(new Element(_("Weborama")));
-    wb->setAttribute(_("enabled"), _(DEFAULT_WEBORAMA_ENABLED));
-    wb->setAttribute(_("refresh"), String::from(DEFAULT_WEBORAMA_REFRESH));
-    wb->setAttribute(_("update-at-start"), _(DEFAULT_WEBORAMA_UPDATE_AT_START));
-
-    Ref<Element> play1(new Element(_("playlist")));
-    play1->setAttribute(_("name"), _("Active"));
-    play1->setAttribute(_("type"), _("playlist"));
-    play1->setAttribute(_("mood"), _("active"));
-    wb->appendElementChild(play1);
-
-    Ref<Element> play2(new Element(_("playlist")));
-    play2->setAttribute(_("name"), _("Metal"));
-    play2->setAttribute(_("type"), _("playlist"));
-
-    Ref<Element> filter(new Element(_("filter")));
-    Ref<Element> genres(new Element(_("genres")));
-    genres->setText(_("metal"));
-    filter->appendElementChild(genres);
-    play2->appendElementChild(filter);
-    wb->appendElementChild(play2);
-
-    onlinecontent->appendElementChild(wb);
-#endif
 
 #ifdef ATRAILERS
     Ref<Element> at(new Element(_("AppleTrailers")));
@@ -410,12 +373,9 @@ String ConfigManager::createDefaultConfig(String userhome)
 
     String homepath = userhome + DIR_SEPARATOR + config_dir;
 
-    if (!check_path(homepath, true))
-    {
-        if (mkdir(homepath.c_str(), 0777) < 0)
-        {
-            throw _Exception(_("Could not create directory ") + homepath + 
-                    " : " + strerror(errno));
+    if (!check_path(homepath, true)) {
+        if (mkdir(homepath.c_str(), 0777) < 0) {
+            throw _Exception(_("Could not create directory ") + homepath + " : " + strerror(errno));
         }
     }
 
@@ -426,13 +386,21 @@ String ConfigManager::createDefaultConfig(String userhome)
     config->setAttribute(_("xmlns"), _(XML_XMLNS) + CONFIG_XML_VERSION);
     config->setAttribute(_("xmlns:xsi"), _(XML_XMLNS_XSI));
     config->setAttribute(_("xsi:schemaLocation"), _(XML_XMLNS) + CONFIG_XML_VERSION + " " + XML_XMLNS + CONFIG_XML_VERSION + ".xsd");
+
+    Ref<Comment> docinfo(new Comment(_("\n\
+     See http://gerbera.io or read the docs for more\n\
+     information on creating and using config.xml configration files.\n\
+    "),
+        true));
+    config->appendChild(RefCast(docinfo, Node));
+
     Ref<Element> server(new Element(_("server")));
-   
+
     Ref<Element> ui(new Element(_("ui")));
     ui->setAttribute(_("enabled"), _(DEFAULT_UI_EN_VALUE));
     ui->setAttribute(_("show-tooltips"), _(DEFAULT_UI_SHOW_TOOLTIPS_VALUE));
 
-    Ref<Element>accounts(new Element(_("accounts")));
+    Ref<Element> accounts(new Element(_("accounts")));
     accounts->setAttribute(_("enabled"), _(DEFAULT_ACCOUNTS_EN_VALUE));
     accounts->setAttribute(_("session-timeout"), String::from(DEFAULT_SESSION_TIMEOUT));
 
@@ -442,25 +410,36 @@ String ConfigManager::createDefaultConfig(String userhome)
     accounts->appendElementChild(account);
 
     ui->appendElementChild(accounts);
-    
+
     server->appendElementChild(ui);
     server->appendTextChild(_("name"), _(PACKAGE_NAME));
-    
+
     Ref<Element> udn(new Element(_("udn")));
     server->appendElementChild(udn);
 
     server->appendTextChild(_("home"), homepath);
-    server->appendTextChild(_("webroot"), prefix_dir + 
-                                                 DIR_SEPARATOR +  
-                                                 _(DEFAULT_WEB_DIR));
-    
+    server->appendTextChild(_("webroot"), prefix_dir + DIR_SEPARATOR + _(DEFAULT_WEB_DIR));
+    Ref<Comment> aliveinfo(new Comment(
+        _("\n\
+        How frequently (in seconds) to send ssdp:alive advertisements.\n\
+        Minimum alive value accepted is: ")
+            + String::from(ALIVE_INTERVAL_MIN) + _("\n\n\
+        The advertisement will be sent every (A/2)-30 seconds,\n\
+        and will have a cache-control max-age of A where A is\n\
+        the value configured here. Ex: A value of 62 will result\n\
+        in an SSDP advertisement being sent every second.\n\
+    "),
+        true));
+    server->appendChild(RefCast(aliveinfo, Node));
+    server->appendTextChild(_("alive"), String::from(DEFAULT_ALIVE_INTERVAL));
+
     Ref<Element> storage(new Element(_("storage")));
 #ifdef HAVE_SQLITE3
     Ref<Element> sqlite3(new Element(_("sqlite3")));
     sqlite3->setAttribute(_("enabled"), _(DEFAULT_SQLITE_ENABLED));
     sqlite3->appendTextChild(_("database-file"), _(DEFAULT_SQLITE3_DB_FILENAME));
 #ifdef SQLITE_BACKUP_ENABLED
-//    <backup enabled="no" interval="6000"/>
+    //    <backup enabled="no" interval="6000"/>
     Ref<Element> backup(new Element(_("backup")));
     backup->setAttribute(_("enabled"), _(YES));
     backup->setAttribute(_("interval"), String::from(DEFAULT_SQLITE_BACKUP_INTERVAL));
@@ -469,7 +448,7 @@ String ConfigManager::createDefaultConfig(String userhome)
     storage->appendElementChild(sqlite3);
 #endif
 #ifdef HAVE_MYSQL
-    Ref<Element>mysql(new Element(_("mysql")));
+    Ref<Element> mysql(new Element(_("mysql")));
 #ifndef HAVE_SQLITE3
     mysql->setAttribute(_("enabled"), _(DEFAULT_MYSQL_ENABLED));
     mysql_flag = true;
@@ -478,7 +457,7 @@ String ConfigManager::createDefaultConfig(String userhome)
 #endif
     mysql->appendTextChild(_("host"), _(DEFAULT_MYSQL_HOST));
     mysql->appendTextChild(_("username"), _(DEFAULT_MYSQL_USER));
-//    storage->appendTextChild(_("password"), _(DEFAULT_MYSQL_PASSWORD));
+    //    storage->appendTextChild(_("password"), _(DEFAULT_MYSQL_PASSWORD));
     mysql->appendTextChild(_("database"), _(DEFAULT_MYSQL_DB));
 
     storage->appendElementChild(mysql);
@@ -489,14 +468,15 @@ String ConfigManager::createDefaultConfig(String userhome)
     protocolinfo->setAttribute(_("extend"), _(DEFAULT_EXTEND_PROTOCOLINFO));
 
     server->appendElementChild(protocolinfo);
-   
+
     Ref<Comment> ps3protinfo(new Comment(_(" For PS3 support change to \"yes\" ")));
     server->appendChild(RefCast(ps3protinfo, Node));
-    
+
     Ref<Comment> redinfo(new Comment(_("\n\
        Uncomment the lines below to get rid of jerky avi playback on the\n\
        DSM320 or to enable subtitles support on the DSM units\n\
-    "), true));
+    "),
+        true));
 
     Ref<Comment> redsonic(new Comment(_("\n\
     <custom-http-headers>\n\
@@ -505,19 +485,20 @@ String ConfigManager::createDefaultConfig(String userhome)
 \n\
     <manufacturerURL>redsonic.com</manufacturerURL>\n\
     <modelNumber>105</modelNumber>\n\
-    "), true));
+    "),
+        true));
 
     Ref<Comment> tg100info(new Comment(_(" Uncomment the line below if you have a Telegent TG100 "), true));
     Ref<Comment> tg100(new Comment(_("\n\
        <upnp-string-limit>101</upnp-string-limit>\n\
-    "), true));
+    "),
+        true));
 
     server->appendChild(RefCast(redinfo, Node));
     server->appendChild(RefCast(redsonic, Node));
     server->appendChild(RefCast(tg100info, Node));
     server->appendChild(RefCast(tg100, Node));
 
-
     server->appendElementChild(renderExtendedRuntimeSection());
 
     config->appendElementChild(server);
@@ -526,8 +507,7 @@ String ConfigManager::createDefaultConfig(String userhome)
     import->setAttribute(_("hidden-files"), _(DEFAULT_HIDDEN_FILES_VALUE));
 
 #ifdef HAVE_MAGIC
-    if (string_ok(magic))
-    {
+    if (string_ok(magic)) {
         Ref<Element> magicfile(new Element(_("magic-file")));
         magicfile->setText(magic);
         import->appendElementChild(magicfile);
@@ -541,31 +521,12 @@ String ConfigManager::createDefaultConfig(String userhome)
     Ref<Element> layout(new Element(_("virtual-layout")));
     layout->setAttribute(_("type"), _(DEFAULT_LAYOUT_TYPE));
 #ifdef HAVE_JS
-    layout->appendTextChild(_("import-script"), prefix_dir +
-                                                DIR_SEPARATOR + 
-                                                _(DEFAULT_JS_DIR) +
-                                                DIR_SEPARATOR +
-                                                _(DEFAULT_IMPORT_SCRIPT));
-#ifdef HAVE_LIBDVDNAV
-    layout->appendTextChild(_("dvd-script"), prefix_dir +
-                                                DIR_SEPARATOR + 
-                                                _(DEFAULT_JS_DIR) +
-                                                DIR_SEPARATOR +
-                                                _(DEFAULT_DVD_SCRIPT));
-#endif
-    scripting->appendTextChild(_("common-script"), 
-                prefix_dir + 
-                DIR_SEPARATOR + 
-                _(DEFAULT_JS_DIR) + 
-                DIR_SEPARATOR +
-                _(DEFAULT_COMMON_SCRIPT));
+    layout->appendTextChild(_("import-script"), prefix_dir + DIR_SEPARATOR + _(DEFAULT_JS_DIR) + DIR_SEPARATOR + _(DEFAULT_IMPORT_SCRIPT));
+    scripting->appendTextChild(_("common-script"),
+        prefix_dir + DIR_SEPARATOR + _(DEFAULT_JS_DIR) + DIR_SEPARATOR + _(DEFAULT_COMMON_SCRIPT));
 
     scripting->appendTextChild(_("playlist-script"),
-                prefix_dir +
-                DIR_SEPARATOR +
-                _(DEFAULT_JS_DIR) +
-                DIR_SEPARATOR +
-                _(DEFAULT_PLAYLISTS_SCRIPT));
+        prefix_dir + DIR_SEPARATOR + _(DEFAULT_JS_DIR) + DIR_SEPARATOR + _(DEFAULT_PLAYLISTS_SCRIPT));
 
 #endif
     scripting->appendElementChild(layout);
@@ -587,14 +548,14 @@ String ConfigManager::createDefaultConfig(String userhome)
     ext2mt->appendElementChild(map_from_to(_("wax"), _("audio/x-ms-wax")));
     ext2mt->appendElementChild(map_from_to(_("wmv"), _("video/x-ms-wmv")));
     ext2mt->appendElementChild(map_from_to(_("wvx"), _("video/x-ms-wvx")));
-    ext2mt->appendElementChild(map_from_to(_("wm"),  _("video/x-ms-wm")));
+    ext2mt->appendElementChild(map_from_to(_("wm"), _("video/x-ms-wm")));
     ext2mt->appendElementChild(map_from_to(_("wmx"), _("video/x-ms-wmx")));
     ext2mt->appendElementChild(map_from_to(_("m3u"), _("audio/x-mpegurl")));
     ext2mt->appendElementChild(map_from_to(_("pls"), _("audio/x-scpls")));
     ext2mt->appendElementChild(map_from_to(_("flv"), _("video/x-flv")));
     ext2mt->appendElementChild(map_from_to(_("mkv"), _("video/x-matroska")));
     ext2mt->appendElementChild(map_from_to(_("mka"), _("audio/x-matroska")));
-    
+
     Ref<Comment> ps3info(new Comment(_(" Uncomment the line below for PS3 divx support "), true));
     Ref<Comment> ps3avi(new Comment(_(" <map from=\"avi\" to=\"video/divx\"/> "), true));
     ext2mt->appendChild(RefCast(ps3info, Node));
@@ -604,52 +565,54 @@ String ConfigManager::createDefaultConfig(String userhome)
     Ref<Comment> dsmzavi(new Comment(_(" <map from=\"avi\" to=\"video/avi\"/> "), true));
     ext2mt->appendChild(RefCast(dsmzinfo, Node));
     ext2mt->appendChild(RefCast(dsmzavi, Node));
-        
+
     mappings->appendElementChild(ext2mt);
 
     Ref<Element> mtupnp(new Element(_("mimetype-upnpclass")));
-    mtupnp->appendElementChild(map_from_to(_("audio/*"), 
-                               _(UPNP_DEFAULT_CLASS_MUSIC_TRACK)));
-    mtupnp->appendElementChild(map_from_to(_("video/*"), 
-                               _(UPNP_DEFAULT_CLASS_VIDEO_ITEM)));
-    mtupnp->appendElementChild(map_from_to(_("image/*"), 
-                               _("object.item.imageItem")));
+    mtupnp->appendElementChild(map_from_to(_("audio/*"),
+        _(UPNP_DEFAULT_CLASS_MUSIC_TRACK)));
+    mtupnp->appendElementChild(map_from_to(_("video/*"),
+        _(UPNP_DEFAULT_CLASS_VIDEO_ITEM)));
+    mtupnp->appendElementChild(map_from_to(_("image/*"),
+        _("object.item.imageItem")));
+    mtupnp->appendElementChild(map_from_to(_("application/ogg"),
+        _(UPNP_DEFAULT_CLASS_MUSIC_TRACK)));
 
     mappings->appendElementChild(mtupnp);
 
     Ref<Element> mtcontent(new Element(_("mimetype-contenttype")));
     mtcontent->appendElementChild(treat_as(_("audio/mpeg"),
-                                           _(CONTENT_TYPE_MP3)));
+        _(CONTENT_TYPE_MP3)));
     mtcontent->appendElementChild(treat_as(_("application/ogg"),
-                                           _(CONTENT_TYPE_OGG)));
+        _(CONTENT_TYPE_OGG)));
     mtcontent->appendElementChild(treat_as(_("audio/ogg"),
-                                           _(CONTENT_TYPE_OGG)));
+        _(CONTENT_TYPE_OGG)));
     mtcontent->appendElementChild(treat_as(_("audio/x-flac"),
-                                           _(CONTENT_TYPE_FLAC)));
+        _(CONTENT_TYPE_FLAC)));
     mtcontent->appendElementChild(treat_as(_("audio/x-ms-wma"),
-                                           _(CONTENT_TYPE_WMA)));
+        _(CONTENT_TYPE_WMA)));
     mtcontent->appendElementChild(treat_as(_("audio/x-wavpack"),
-                                           _(CONTENT_TYPE_WAVPACK)));
+        _(CONTENT_TYPE_WAVPACK)));
     mtcontent->appendElementChild(treat_as(_("image/jpeg"),
-                                           _(CONTENT_TYPE_JPG)));
+        _(CONTENT_TYPE_JPG)));
     mtcontent->appendElementChild(treat_as(_("audio/x-mpegurl"),
-                                           _(CONTENT_TYPE_PLAYLIST)));
+        _(CONTENT_TYPE_PLAYLIST)));
     mtcontent->appendElementChild(treat_as(_("audio/x-scpls"),
-                                           _(CONTENT_TYPE_PLAYLIST)));
+        _(CONTENT_TYPE_PLAYLIST)));
     mtcontent->appendElementChild(treat_as(_("audio/x-wav"),
-                                           _(CONTENT_TYPE_PCM)));
+        _(CONTENT_TYPE_PCM)));
     mtcontent->appendElementChild(treat_as(_("audio/L16"),
-                                           _(CONTENT_TYPE_PCM)));
+        _(CONTENT_TYPE_PCM)));
     mtcontent->appendElementChild(treat_as(_("video/x-msvideo"),
-                                           _(CONTENT_TYPE_AVI)));
+        _(CONTENT_TYPE_AVI)));
     mtcontent->appendElementChild(treat_as(_("video/mp4"),
-                                           _(CONTENT_TYPE_MP4)));
+        _(CONTENT_TYPE_MP4)));
     mtcontent->appendElementChild(treat_as(_("audio/mp4"),
-                                           _(CONTENT_TYPE_MP4)));
-    mtcontent->appendElementChild(treat_as(_("application/x-iso9660"),
-                                           _(CONTENT_TYPE_DVD)));
-    mtcontent->appendElementChild(treat_as(_("application/x-iso9660-image"),
-                                           _(CONTENT_TYPE_DVD)));
+        _(CONTENT_TYPE_MP4)));
+    mtcontent->appendElementChild(treat_as(_("video/x-matroska"),
+        _(CONTENT_TYPE_MKV)));
+    mtcontent->appendElementChild(treat_as(_("audio/x-matroska"),
+        _(CONTENT_TYPE_MKA)));
 
     mappings->appendElementChild(mtcontent);
     import->appendElementChild(mappings);
@@ -663,16 +626,14 @@ String ConfigManager::createDefaultConfig(String userhome)
 #ifdef EXTERNAL_TRANSCODING
     config->appendElementChild(renderTranscodingSection());
 #endif
-   
+
     config->indent();
     save_text(config_filename, config->print());
-    log_info("MediaTomb configuration was created in: %s\n", 
-            config_filename.c_str());
+    log_info("MediaTomb configuration was created in: %s\n",
+        config_filename.c_str());
 
-    if (mysql_flag)
-    {
-        throw _Exception(_("You are using MySQL! Please edit ") + config_filename +
-                " and enter your MySQL host/username/password!");
+    if (mysql_flag) {
+        throw _Exception(_("You are using MySQL! Please edit ") + config_filename + " and enter your MySQL host/username/password!");
     }
 
     return config_filename;
@@ -684,28 +645,25 @@ void ConfigManager::migrate()
     String version = root->getAttribute(_("version"));
 
     // pre 0.10.* to 0.11.0 -> storage layout has changed
-    if (!string_ok(version))
-    {
+    if (!string_ok(version)) {
         log_info("Migrating server configuration to config version 1\n");
-        root->setAttribute(_("version"), 
-                String::from(CONFIG_XML_VERSION_0_11_0));
-        root->setAttribute(_("xmlns"), 
-                _(XML_XMLNS) + CONFIG_XML_VERSION_0_11_0);
+        root->setAttribute(_("version"),
+            String::from(CONFIG_XML_VERSION_0_11_0));
+        root->setAttribute(_("xmlns"),
+            _(XML_XMLNS) + CONFIG_XML_VERSION_0_11_0);
         root->setAttribute(_("xmlns:xsi"), _(XML_XMLNS_XSI));
-        root->setAttribute(_("xsi:schemaLocation"), 
-                _(XML_XMLNS) + CONFIG_XML_VERSION_0_11_0 + " " + XML_XMLNS + 
-                CONFIG_XML_VERSION + ".xsd");
-        
+        root->setAttribute(_("xsi:schemaLocation"),
+            _(XML_XMLNS) + CONFIG_XML_VERSION_0_11_0 + " " + XML_XMLNS + CONFIG_XML_VERSION + ".xsd");
+
         Ref<Element> server = root->getChildByName(_("server"));
-        if (server == nil)
+        if (server == nullptr)
             throw _Exception(_("Migration failed! Could not find <server> tag!"));
 
         checkOptionString(_("/server/storage/attribute::driver"));
         String dbDriver = getOption(_("/server/storage/attribute::driver"));
         Ref<Element> storage(new Element(_("storage")));
 #ifdef HAVE_SQLITE3
-        if (dbDriver == "sqlite3")
-        {
+        if (dbDriver == "sqlite3") {
             String dbFile = getOption(_("/server/storage/database-file"));
 
             Ref<Element> sqlite3(new Element(_("sqlite3")));
@@ -716,25 +674,25 @@ void ConfigManager::migrate()
 #endif // HAVE_SQLITE3
 
 #ifdef HAVE_MYSQL
-        if (dbDriver == "mysql")
-        {
+        if (dbDriver == "mysql") {
             String host = getOption(_("/server/storage/host"));
             String db = getOption(_("/server/storage/database"));
             String username = getOption(_("/server/storage/username"));
             int port = -1;
 
-            if (server->getChildByName(_("storage"))->getChildByName(_("port")) != nil)
+            if (server->getChildByName(_("storage"))->getChildByName(_("port")) != nullptr)
                 port = getIntOption(_("/server/storage/port"));
 
-            String socket = nil;;
-            if (server->getChildByName(_("storage"))->getChildByName(_("socket")) != nil)
+            String socket = nullptr;
+            ;
+            if (server->getChildByName(_("storage"))->getChildByName(_("socket")) != nullptr)
                 socket = getOption(_("/server/storage/socket"));
 
-            String password = nil;
-            if (server->getChildByName(_("storage"))->getChildByName(_("password")) != nil)
+            String password = nullptr;
+            if (server->getChildByName(_("storage"))->getChildByName(_("password")) != nullptr)
                 password = getOption(_("/server/storage/password"));
 
-            Ref<Element>mysql(new Element(_("mysql")));
+            Ref<Element> mysql(new Element(_("mysql")));
             mysql->setAttribute(_("enabled"), _(YES));
 
             mysql->appendTextChild(_("host"), host);
@@ -742,11 +700,11 @@ void ConfigManager::migrate()
             if (port != -1)
                 mysql->appendTextChild(_("port"), String::from(port));
 
-            if (socket != nil)
+            if (socket != nullptr)
                 storage->appendTextChild(_("socket"), socket);
 
             mysql->appendTextChild(_("username"), username);
-            if (password != nil)
+            if (password != nullptr)
                 storage->appendTextChild(_("password"), password);
 
             mysql->appendTextChild(_("database"), db);
@@ -757,33 +715,29 @@ void ConfigManager::migrate()
 
         server->appendElementChild(storage);
 #ifdef EXTERNAL_TRANSCODING
-        if (root->getChildByName(_("transcoding")) == nil)
+        if (root->getChildByName(_("transcoding")) == nullptr)
             root->appendElementChild(renderTranscodingSection());
 #endif
 
         Ref<Element> import = root->getChildByName(_("import"));
-        if (import != nil)
-        {
+        if (import != nullptr) {
 #ifdef ONLINE_SERVICES
-            if (import->getChildByName(_("online-content")) == nil)
+            if (import->getChildByName(_("online-content")) == nullptr)
                 import->appendElementChild(renderOnlineSection());
 #endif
             Ref<Element> map = import->getChildByName(_("mappings"));
-            if (map != nil)
-            {
+            if (map != nullptr) {
                 Ref<Element> mtct = map->getChildByName(_("mimetype-contenttype"));
-                if ((mtct != nil) && (mtct->elementChildCount() > 0))
-                {
+                if ((mtct != nullptr) && (mtct->elementChildCount() > 0)) {
                     bool add_avi = true;
-                    for (int mc = 0; mc < mtct->elementChildCount(); mc++)
-                    {
+                    for (int mc = 0; mc < mtct->elementChildCount(); mc++) {
                         Ref<Element> treat = mtct->getElementChild(mc);
                         if (treat->getAttribute(_("as")) == "avi")
                             add_avi = false;
                     }
                     if (add_avi)
                         mtct->appendElementChild(treat_as(_("video/x-msvideo"),
-                                                          _("avi")));
+                            _("avi")));
                 }
             }
         }
@@ -793,115 +747,96 @@ void ConfigManager::migrate()
     }
 
     // from 0.11 to 0.12
-    if (string_ok(version) && version.toInt() == 1)
-    {
+    if (string_ok(version) && version.toInt() == 1) {
         log_info("Migrating server configuration to config version 2\n");
         root->setAttribute(_("version"), String::from(CONFIG_XML_VERSION));
         root->setAttribute(_("xmlns"), _(XML_XMLNS) + CONFIG_XML_VERSION);
-        root->setAttribute(_("xsi:schemaLocation"), 
-                _(XML_XMLNS) + CONFIG_XML_VERSION + " " + XML_XMLNS + 
-                CONFIG_XML_VERSION + ".xsd");
+        root->setAttribute(_("xsi:schemaLocation"),
+            _(XML_XMLNS) + CONFIG_XML_VERSION + " " + XML_XMLNS + CONFIG_XML_VERSION + ".xsd");
 
         Ref<Element> server = root->getChildByName(_("server"));
-        if (server == nil)
+        if (server == nullptr)
             throw _Exception(_("Migration failed! Could not find <server> tag!"));
 
         String temp;
-        try 
-        {
+        try {
             temp = getOption(_("/server/ui/attribute::show-tooltips"));
-        }
-        catch (Exception e)
-        {
+        } catch (const Exception& e) {
             Ref<Element> ui = server->getChildByName(_("ui"));
-            if (ui != nil)
-                ui->setAttribute(_("show-tooltips"), 
-                                           _(DEFAULT_UI_SHOW_TOOLTIPS_VALUE));
+            if (ui != nullptr)
+                ui->setAttribute(_("show-tooltips"),
+                    _(DEFAULT_UI_SHOW_TOOLTIPS_VALUE));
         }
-       
-        try
-        {
+
+        try {
             temp = getOption(_("/server/storage/attribute::caching"));
-        }
-        catch (Exception e)
-        {
+        } catch (const Exception& e) {
             Ref<Element> storage = server->getChildByName(_("storage"));
-            if (storage != nil)
-                storage->setAttribute(_("caching"), 
-                                        _(DEFAULT_STORAGE_CACHING_ENABLED));
+            if (storage != nullptr)
+                storage->setAttribute(_("caching"),
+                    _(DEFAULT_STORAGE_CACHING_ENABLED));
         }
-       
-        if (server->getChildByName(_("extended-runtime-options")) == nil)
+
+        if (server->getChildByName(_("extended-runtime-options")) == nullptr)
             server->appendElementChild(renderExtendedRuntimeSection());
 
         Ref<Element> import = root->getChildByName(_("import"));
-        if (import != nil)
-        {
+        if (import != nullptr) {
             // add ext 2 mimetype stuff
             Ref<Element> mappings = import->getChildByName(_("mappings"));
 
 #ifdef ONLINE_SERVICES
-            Ref<Element> online =  import->getChildByName(_("online-content"));
-            if (online == nil)
+            Ref<Element> online = import->getChildByName(_("online-content"));
+            if (online == nullptr)
                 import->appendElementChild(renderOnlineSection());
 #endif
         }
-        migrated_flag = true;            
+        migrated_flag = true;
     }
 
-    if (migrated_flag)
-    {
+    if (migrated_flag) {
         root->indent();
         save();
         log_info("Migration of configuration successfull\n");
     }
 }
 
-#define NEW_OPTION(optval) opt =  Ref<Option> (new Option(optval));
+#define NEW_OPTION(optval) opt = Ref<Option>(new Option(optval));
 #define SET_OPTION(opttype) options->set(RefCast(opt, ConfigOption), opttype);
 
-#define NEW_INT_OPTION(optval) int_opt = \
-                         Ref<IntOption> (new IntOption(optval));
+#define NEW_INT_OPTION(optval) int_opt = Ref<IntOption>(new IntOption(optval));
 #define SET_INT_OPTION(opttype) \
-                       options->set(RefCast(int_opt, ConfigOption), opttype);
+    options->set(RefCast(int_opt, ConfigOption), opttype);
 
-#define NEW_BOOL_OPTION(optval) bool_opt = \
-                         Ref<BoolOption> (new BoolOption(optval));
+#define NEW_BOOL_OPTION(optval) bool_opt = Ref<BoolOption>(new BoolOption(optval));
 #define SET_BOOL_OPTION(opttype) \
-                        options->set(RefCast(bool_opt, ConfigOption), opttype);
+    options->set(RefCast(bool_opt, ConfigOption), opttype);
 
-#define NEW_DICT_OPTION(optval) dict_opt =  \
-                         Ref<DictionaryOption> (new DictionaryOption(optval));
+#define NEW_DICT_OPTION(optval) dict_opt = Ref<DictionaryOption>(new DictionaryOption(optval));
 #define SET_DICT_OPTION(opttype) \
-                        options->set(RefCast(dict_opt, ConfigOption), opttype);
+    options->set(RefCast(dict_opt, ConfigOption), opttype);
 
-#define NEW_STRARR_OPTION(optval) str_array_opt = \
-                         Ref<StringArrayOption> (new StringArrayOption(optval));
+#define NEW_STRARR_OPTION(optval) str_array_opt = Ref<StringArrayOption>(new StringArrayOption(optval));
 #define SET_STRARR_OPTION(opttype) \
-                    options->set(RefCast(str_array_opt, ConfigOption), opttype);
+    options->set(RefCast(str_array_opt, ConfigOption), opttype);
 
-#define NEW_AUTOSCANLIST_OPTION(optval) alist_opt = \
-                       Ref<AutoscanListOption> (new AutoscanListOption(optval));
+#define NEW_AUTOSCANLIST_OPTION(optval) alist_opt = Ref<AutoscanListOption>(new AutoscanListOption(optval));
 #define SET_AUTOSCANLIST_OPTION(opttype) \
-                    options->set(RefCast(alist_opt, ConfigOption), opttype);
+    options->set(RefCast(alist_opt, ConfigOption), opttype);
 #ifdef EXTERNAL_TRANSCODING
-#define NEW_TRANSCODING_PROFILELIST_OPTION(optval) trlist_opt = \
-   Ref<TranscodingProfileListOption> (new TranscodingProfileListOption(optval));
+#define NEW_TRANSCODING_PROFILELIST_OPTION(optval) trlist_opt = Ref<TranscodingProfileListOption>(new TranscodingProfileListOption(optval));
 #define SET_TRANSCODING_PROFILELIST_OPTION(opttype) \
-                    options->set(RefCast(trlist_opt, ConfigOption), opttype);
-#endif//TRANSCODING
+    options->set(RefCast(trlist_opt, ConfigOption), opttype);
+#endif //TRANSCODING
 #ifdef ONLINE_SERVICES
-#define NEW_OBJARR_OPTION(optval) obj_array_opt = \
-    Ref<ObjectArrayOption> (new ObjectArrayOption(optval));
+#define NEW_OBJARR_OPTION(optval) obj_array_opt = Ref<ObjectArrayOption>(new ObjectArrayOption(optval));
 #define SET_OBJARR_OPTION(opttype) \
-                   options->set(RefCast(obj_array_opt, ConfigOption), opttype);
-#endif//ONLINE_SERVICES
+    options->set(RefCast(obj_array_opt, ConfigOption), opttype);
+#endif //ONLINE_SERVICES
 
-#define NEW_OBJDICT_OPTION(optval) obj_dict_opt = \
-    Ref<ObjectDictionaryOption> (new ObjectDictionaryOption(optval));
+#define NEW_OBJDICT_OPTION(optval) obj_dict_opt = Ref<ObjectDictionaryOption>(new ObjectDictionaryOption(optval));
 #define SET_OBJDICT_OPTION(opttype) \
-                   options->set(RefCast(obj_dict_opt, ConfigOption), opttype);
-
+    options->set(RefCast(obj_dict_opt, ConfigOption), opttype);
 
 void ConfigManager::validate(String serverhome)
 {
@@ -923,13 +858,13 @@ void ConfigManager::validate(String serverhome)
 #endif
 
     log_info("Checking configuration...\n");
-   
+
     // first check if the config file itself looks ok, it must have a config
     // and a server tag
     if (root->getName() != "config")
         throw _Exception(_("Error in config file: <config> tag not found"));
 
-    if (root->getChildByName(_("server")) == nil)
+    if (root->getChildByName(_("server")) == nullptr)
         throw _Exception(_("Error in config file: <server> tag not found"));
 
     String version = root->getAttribute(_("version"));
@@ -957,19 +892,17 @@ void ConfigManager::validate(String serverhome)
     SET_OPTION(CFG_SERVER_WEBROOT);
 
     temp = getOption(_("/server/tmpdir"), _(DEFAULT_TMPDIR));
-    if (!check_path(temp, true))
-    {
+    if (!check_path(temp, true)) {
         throw _Exception(_("Temporary directory ") + temp + " does not exist!");
     }
     temp = temp + _("/");
     NEW_OPTION(temp);
     SET_OPTION(CFG_SERVER_TMPDIR);
 
-    
     if (string_ok(getOption(_("/server/servedir"), _(""))))
         prepare_path(_("/server/servedir"), true);
 
-    NEW_OPTION(getOption(_("/server/servedir"))); 
+    NEW_OPTION(getOption(_("/server/servedir")));
     SET_OPTION(CFG_SERVER_SERVEDIR);
 
     // udn should be already prepared
@@ -982,32 +915,29 @@ void ConfigManager::validate(String serverhome)
     String sqlite3_en = _("no");
 
     tmpEl = getElement(_("/server/storage"));
-    if (tmpEl == nil)
+    if (tmpEl == nullptr)
         throw _Exception(_("Error in config file: <storage> tag not found"));
 
-
     temp = getOption(_("/server/storage/attribute::caching"),
-            _(DEFAULT_STORAGE_CACHING_ENABLED));
+        _(DEFAULT_STORAGE_CACHING_ENABLED));
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: incorrect parameter "
-                    "for <storage caching=\"\" /> attribute"));
+                           "for <storage caching=\"\" /> attribute"));
     NEW_BOOL_OPTION(temp == "yes" ? true : false);
     SET_BOOL_OPTION(CFG_SERVER_STORAGE_CACHING_ENABLED);
 
     tmpEl = getElement(_("/server/storage/mysql"));
-    if (tmpEl != nil)
-    {
+    if (tmpEl != nullptr) {
         mysql_en = getOption(_("/server/storage/mysql/attribute::enabled"),
-                _(DEFAULT_MYSQL_ENABLED));
+            _(DEFAULT_MYSQL_ENABLED));
         if (!validateYesNo(mysql_en))
             throw _Exception(_("Invalid <mysql enabled=\"\"> value"));
     }
 
     tmpEl = getElement(_("/server/storage/sqlite3"));
-    if (tmpEl != nil)
-    {
+    if (tmpEl != nullptr) {
         sqlite3_en = getOption(_("/server/storage/sqlite3/attribute::enabled"),
-                _(DEFAULT_SQLITE_ENABLED));
+            _(DEFAULT_SQLITE_ENABLED));
         if (!validateYesNo(sqlite3_en))
             throw _Exception(_("Invalid <sqlite3 enabled=\"\"> value"));
     }
@@ -1022,47 +952,39 @@ void ConfigManager::validate(String serverhome)
                            "one database driver must be active!"));
 
 #ifdef HAVE_MYSQL
-    if (mysql_en == "yes")
-    {
-        NEW_OPTION(getOption(_("/server/storage/mysql/host"), 
-                    _(DEFAULT_MYSQL_HOST)));
+    if (mysql_en == "yes") {
+        NEW_OPTION(getOption(_("/server/storage/mysql/host"),
+            _(DEFAULT_MYSQL_HOST)));
         SET_OPTION(CFG_SERVER_STORAGE_MYSQL_HOST);
 
-        NEW_OPTION(getOption(_("/server/storage/mysql/database"), 
-                    _(DEFAULT_MYSQL_DB)));
+        NEW_OPTION(getOption(_("/server/storage/mysql/database"),
+            _(DEFAULT_MYSQL_DB)));
         SET_OPTION(CFG_SERVER_STORAGE_MYSQL_DATABASE);
 
-        NEW_OPTION(getOption(_("/server/storage/mysql/username"), 
-                    _(DEFAULT_MYSQL_USER)));
+        NEW_OPTION(getOption(_("/server/storage/mysql/username"),
+            _(DEFAULT_MYSQL_USER)));
         SET_OPTION(CFG_SERVER_STORAGE_MYSQL_USERNAME);
 
         NEW_INT_OPTION(getIntOption(_("/server/storage/mysql/port"), 0));
         SET_INT_OPTION(CFG_SERVER_STORAGE_MYSQL_PORT);
 
-        if (getElement(_("/server/storage/mysql/socket")) == nil)
-        {
-            NEW_OPTION(nil);
-        }
-        else
-        {
+        if (getElement(_("/server/storage/mysql/socket")) == nullptr) {
+            NEW_OPTION(nullptr);
+        } else {
             NEW_OPTION(getOption(_("/server/storage/mysql/socket")));
         }
 
         SET_OPTION(CFG_SERVER_STORAGE_MYSQL_SOCKET);
 
-        if (getElement(_("/server/storage/mysql/password")) == nil)
-        {
-            NEW_OPTION(nil);
-        }
-        else
-        {
+        if (getElement(_("/server/storage/mysql/password")) == nullptr) {
+            NEW_OPTION(nullptr);
+        } else {
             NEW_OPTION(getOption(_("/server/storage/mysql/password")));
         }
         SET_OPTION(CFG_SERVER_STORAGE_MYSQL_PASSWORD);
     }
 #else
-    if (mysql_en == "yes")
-    {
+    if (mysql_en == "yes") {
         throw _Exception(_("You enabled MySQL storage in configuration, "
                            "however this version of MediaTomb was compiled "
                            "without MySQL support!"));
@@ -1070,18 +992,17 @@ void ConfigManager::validate(String serverhome)
 #endif // HAVE_MYSQL
 
 #ifdef HAVE_SQLITE3
-    
-    if (sqlite3_en == "yes")
-    {
+
+    if (sqlite3_en == "yes") {
         prepare_path(_("/server/storage/sqlite3/database-file"), false, true);
         NEW_OPTION(getOption(_("/server/storage/sqlite3/database-file")));
         SET_OPTION(CFG_SERVER_STORAGE_SQLITE_DATABASE_FILE);
-        
-        temp = getOption(_("/server/storage/sqlite3/synchronous"), 
-                _(DEFAULT_SQLITE_SYNC));
-                
+
+        temp = getOption(_("/server/storage/sqlite3/synchronous"),
+            _(DEFAULT_SQLITE_SYNC));
+
         temp_int = 0;
-        
+
         if (temp == "off")
             temp_int = MT_SQLITE_SYNC_OFF;
         else if (temp == "normal")
@@ -1096,7 +1017,7 @@ void ConfigManager::validate(String serverhome)
         SET_INT_OPTION(CFG_SERVER_STORAGE_SQLITE_SYNCHRONOUS);
 
         temp = getOption(_("/server/storage/sqlite3/on-error"),
-                _(DEFAULT_SQLITE_RESTORE));
+            _(DEFAULT_SQLITE_RESTORE));
 
         bool tmp_bool = true;
 
@@ -1112,28 +1033,27 @@ void ConfigManager::validate(String serverhome)
         SET_BOOL_OPTION(CFG_SERVER_STORAGE_SQLITE_RESTORE);
 #ifdef SQLITE_BACKUP_ENABLED
         temp = getOption(_("/server/storage/sqlite3/backup/attribute::enabled"),
-                _(YES));
+            _(YES));
 #else
         temp = getOption(_("/server/storage/sqlite3/backup/attribute::enabled"),
-                _(DEFAULT_SQLITE_BACKUP_ENABLED));
+            _(DEFAULT_SQLITE_BACKUP_ENABLED));
 #endif
         if (!validateYesNo(temp))
             throw _Exception(_("Error in config file: incorrect parameter "
-                        "for <backup enabled=\"\" /> attribute"));
+                               "for <backup enabled=\"\" /> attribute"));
         NEW_BOOL_OPTION(temp == "yes" ? true : false);
         SET_BOOL_OPTION(CFG_SERVER_STORAGE_SQLITE_BACKUP_ENABLED);
 
         temp_int = getIntOption(_("/server/storage/sqlite3/backup/attribute::interval"),
-                DEFAULT_SQLITE_BACKUP_INTERVAL);
+            DEFAULT_SQLITE_BACKUP_INTERVAL);
         if (temp_int < 1)
             throw _Exception(_("Error in config file: incorrect parameter for "
-                        "<backup interval=\"\" /> attribute"));
+                               "<backup interval=\"\" /> attribute"));
         NEW_INT_OPTION(temp_int);
         SET_INT_OPTION(CFG_SERVER_STORAGE_SQLITE_BACKUP_INTERVAL);
     }
 #else
-    if (sqlite3_en == "yes")
-    {
+    if (sqlite3_en == "yes") {
         throw _Exception(_("You enabled sqlite3 storage in configuration, "
                            "however this version of MediaTomb was compiled "
                            "without sqlite3 support!"));
@@ -1144,21 +1064,20 @@ void ConfigManager::validate(String serverhome)
     String dbDriver;
     if (sqlite3_en == "yes")
         dbDriver = _("sqlite3");
-    
+
     if (mysql_en == "yes")
         dbDriver = _("mysql");
 
     NEW_OPTION(dbDriver);
     SET_OPTION(CFG_SERVER_STORAGE_DRIVER);
 
-
-//    temp = checkOption_("/server/storage/database-file");
-//    check_path_ex(construct_path(temp));
+    //    temp = checkOption_("/server/storage/database-file");
+    //    check_path_ex(construct_path(temp));
 
     // now go through the optional settings and fix them if anything is missing
-   
+
     temp = getOption(_("/server/ui/attribute::enabled"),
-                     _(DEFAULT_UI_EN_VALUE));
+        _(DEFAULT_UI_EN_VALUE));
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: incorrect parameter "
                            "for <ui enabled=\"\" /> attribute"));
@@ -1166,7 +1085,7 @@ void ConfigManager::validate(String serverhome)
     SET_BOOL_OPTION(CFG_SERVER_UI_ENABLED);
 
     temp = getOption(_("/server/ui/attribute::show-tooltips"),
-                     _(DEFAULT_UI_SHOW_TOOLTIPS_VALUE));
+        _(DEFAULT_UI_SHOW_TOOLTIPS_VALUE));
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: incorrect parameter "
                            "for <ui show-tooltips=\"\" /> attribute"));
@@ -1174,23 +1093,23 @@ void ConfigManager::validate(String serverhome)
     SET_BOOL_OPTION(CFG_SERVER_UI_SHOW_TOOLTIPS);
 
     temp = getOption(_("/server/ui/attribute::poll-when-idle"),
-                     _(DEFAULT_POLL_WHEN_IDLE_VALUE));
+        _(DEFAULT_POLL_WHEN_IDLE_VALUE));
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: incorrect parameter "
                            "for <ui poll-when-idle=\"\" /> attribute"));
     NEW_BOOL_OPTION(temp == "yes" ? true : false);
     SET_BOOL_OPTION(CFG_SERVER_UI_POLL_WHEN_IDLE);
 
-    temp_int = getIntOption(_("/server/ui/attribute::poll-interval"), 
-                       DEFAULT_POLL_INTERVAL);
+    temp_int = getIntOption(_("/server/ui/attribute::poll-interval"),
+        DEFAULT_POLL_INTERVAL);
     if (temp_int < 1)
         throw _Exception(_("Error in config file: incorrect parameter for "
                            "<ui poll-interval=\"\" /> attribute"));
     NEW_INT_OPTION(temp_int);
     SET_INT_OPTION(CFG_SERVER_UI_POLL_INTERVAL);
 
-    temp_int = getIntOption(_("/server/ui/items-per-page/attribute::default"), 
-                           DEFAULT_ITEMS_PER_PAGE_2);
+    temp_int = getIntOption(_("/server/ui/items-per-page/attribute::default"),
+        DEFAULT_ITEMS_PER_PAGE_2);
     if (temp_int < 1)
         throw _Exception(_("Error in config file: incorrect parameter for "
                            "<items-per-page default=\"\" /> attribute"));
@@ -1200,36 +1119,28 @@ void ConfigManager::validate(String serverhome)
     // now get the option list for the drop down menu
     Ref<Element> element = getElement(_("/server/ui/items-per-page"));
     // create default structure
-    if (element->elementChildCount() == 0)
-    {
-        if ((temp_int != DEFAULT_ITEMS_PER_PAGE_1) && 
-            (temp_int != DEFAULT_ITEMS_PER_PAGE_2) &&
-            (temp_int != DEFAULT_ITEMS_PER_PAGE_3) && 
-            (temp_int != DEFAULT_ITEMS_PER_PAGE_4))
-        {
+    if (element->elementChildCount() == 0) {
+        if ((temp_int != DEFAULT_ITEMS_PER_PAGE_1) && (temp_int != DEFAULT_ITEMS_PER_PAGE_2) && (temp_int != DEFAULT_ITEMS_PER_PAGE_3) && (temp_int != DEFAULT_ITEMS_PER_PAGE_4)) {
             throw _Exception(_("Error in config file: you specified an "
                                "<items-per-page default=\"\"> value that is "
                                "not listed in the options"));
         }
 
-        element->appendTextChild(_("option"), 
-                                   String::from(DEFAULT_ITEMS_PER_PAGE_1));
-        element->appendTextChild(_("option"), 
-                                   String::from(DEFAULT_ITEMS_PER_PAGE_2));
-        element->appendTextChild(_("option"), 
-                                   String::from(DEFAULT_ITEMS_PER_PAGE_3));
-        element->appendTextChild(_("option"), 
-                                   String::from(DEFAULT_ITEMS_PER_PAGE_4));
-    }
-    else // validate user settings
+        element->appendTextChild(_("option"),
+            String::from(DEFAULT_ITEMS_PER_PAGE_1));
+        element->appendTextChild(_("option"),
+            String::from(DEFAULT_ITEMS_PER_PAGE_2));
+        element->appendTextChild(_("option"),
+            String::from(DEFAULT_ITEMS_PER_PAGE_3));
+        element->appendTextChild(_("option"),
+            String::from(DEFAULT_ITEMS_PER_PAGE_4));
+    } else // validate user settings
     {
         int i;
         bool default_found = false;
-        for (int j = 0; j < element->elementChildCount(); j++)
-        {
+        for (int j = 0; j < element->elementChildCount(); j++) {
             Ref<Element> child = element->getElementChild(j);
-            if (child->getName() == "option")
-            {
+            if (child->getName() == "option") {
                 i = child->getText().toInt();
                 if (i < 1)
                     throw _Exception(_("Error in config file: incorrect "
@@ -1244,13 +1155,11 @@ void ConfigManager::validate(String serverhome)
             throw _Exception(_("Error in config file: at least one <option> "
                                "under <items-per-page> must match the "
                                "<items-per-page default=\"\" /> attribute"));
-
     }
 
     // create the array from either user or default settings
-    Ref<Array<StringBase> > menu_opts (new Array<StringBase>());
-    for (int j = 0; j < element->elementChildCount(); j++)
-    {
+    Ref<Array<StringBase> > menu_opts(new Array<StringBase>());
+    for (int j = 0; j < element->elementChildCount(); j++) {
         Ref<Element> child = element->getElementChild(j);
         if (child->getName() == "option")
             menu_opts->append(child->getText());
@@ -1258,9 +1167,8 @@ void ConfigManager::validate(String serverhome)
     NEW_STRARR_OPTION(menu_opts);
     SET_STRARR_OPTION(CFG_SERVER_UI_ITEMS_PER_PAGE_DROPDOWN);
 
- 
-    temp = getOption(_("/server/ui/accounts/attribute::enabled"), 
-                     _(DEFAULT_ACCOUNTS_EN_VALUE));
+    temp = getOption(_("/server/ui/accounts/attribute::enabled"),
+        _(DEFAULT_ACCOUNTS_EN_VALUE));
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: incorrect parameter for "
                            "<accounts enabled=\"\" /> attribute"));
@@ -1273,17 +1181,16 @@ void ConfigManager::validate(String serverhome)
     SET_DICT_OPTION(CFG_SERVER_UI_ACCOUNT_LIST);
 
     temp_int = getIntOption(_("/server/ui/accounts/attribute::session-timeout"),
-                              DEFAULT_SESSION_TIMEOUT);
-    if (temp_int < 1)
-    {
+        DEFAULT_SESSION_TIMEOUT);
+    if (temp_int < 1) {
         throw _Exception(_("Error in config file: invalid session-timeout "
                            "(must be > 0)\n"));
     }
     NEW_INT_OPTION(temp_int);
     SET_INT_OPTION(CFG_SERVER_UI_SESSION_TIMEOUT);
-    
+
     temp = getOption(_("/import/attribute::hidden-files"),
-                     _(DEFAULT_HIDDEN_FILES_VALUE));
+        _(DEFAULT_HIDDEN_FILES_VALUE));
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: incorrect parameter for "
                            "<import hidden-files=\"\" /> attribute"));
@@ -1291,46 +1198,42 @@ void ConfigManager::validate(String serverhome)
     SET_BOOL_OPTION(CFG_IMPORT_HIDDEN_FILES);
 
     temp = getOption(
-            _("/import/mappings/extension-mimetype/attribute::ignore-unknown"),
-            _(DEFAULT_IGNORE_UNKNOWN_EXTENSIONS));
+        _("/import/mappings/extension-mimetype/attribute::ignore-unknown"),
+        _(DEFAULT_IGNORE_UNKNOWN_EXTENSIONS));
 
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: incorrect parameter for "
-                       "<extension-mimetype ignore-unknown=\"\" /> attribute"));
- 
+                           "<extension-mimetype ignore-unknown=\"\" /> attribute"));
+
     NEW_BOOL_OPTION(temp == "yes" ? true : false);
     SET_BOOL_OPTION(CFG_IMPORT_MAPPINGS_IGNORE_UNKNOWN_EXTENSIONS);
 
     temp = getOption(
-            _("/import/mappings/extension-mimetype/attribute::case-sensitive"),
-            _(DEFAULT_CASE_SENSITIVE_EXTENSION_MAPPINGS));
+        _("/import/mappings/extension-mimetype/attribute::case-sensitive"),
+        _(DEFAULT_CASE_SENSITIVE_EXTENSION_MAPPINGS));
 
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: incorrect parameter for "
-                       "<extension-mimetype case-sensitive=\"\" /> attribute"));
+                           "<extension-mimetype case-sensitive=\"\" /> attribute"));
 
     bool csens = false;
 
     if (temp == "yes")
         csens = true;
 
-
     NEW_BOOL_OPTION(csens);
     SET_BOOL_OPTION(CFG_IMPORT_MAPPINGS_EXTENSION_TO_MIMETYPE_CASE_SENSITIVE);
 
-    tmpEl = getElement( _("/import/mappings/extension-mimetype"));
-    NEW_DICT_OPTION(createDictionaryFromNodeset(tmpEl, _("map"), 
-                                       _("from"), _("to"), !csens));
+    tmpEl = getElement(_("/import/mappings/extension-mimetype"));
+    NEW_DICT_OPTION(createDictionaryFromNodeset(tmpEl, _("map"),
+        _("from"), _("to"), !csens));
     SET_DICT_OPTION(CFG_IMPORT_MAPPINGS_EXTENSION_TO_MIMETYPE_LIST);
 
     tmpEl = getElement(_("/import/mappings/mimetype-contenttype"));
-    if (tmpEl != nil)
-    {
-        mime_content = createDictionaryFromNodeset(tmpEl, _("treat"), 
-                       _("mimetype"), _("as"));
-    }
-    else
-    {
+    if (tmpEl != nullptr) {
+        mime_content = createDictionaryFromNodeset(tmpEl, _("treat"),
+            _("mimetype"), _("as"));
+    } else {
         mime_content = Ref<Dictionary>(new Dictionary());
         mime_content->put(_("audio/mpeg"), _(CONTENT_TYPE_MP3));
         mime_content->put(_("audio/mp4"), _(CONTENT_TYPE_MP4));
@@ -1341,19 +1244,21 @@ void ConfigManager::validate(String serverhome)
         mime_content->put(_("audio/x-mpegurl"), _(CONTENT_TYPE_PLAYLIST));
         mime_content->put(_("audio/x-scpls"), _(CONTENT_TYPE_PLAYLIST));
         mime_content->put(_("audio/x-wav"), _(CONTENT_TYPE_PCM));
+        mime_content->put(_("audio/wave"), _(CONTENT_TYPE_PCM));
+        mime_content->put(_("audio/wav"), _(CONTENT_TYPE_PCM));
+        mime_content->put(_("audio/vnd.wave"), _(CONTENT_TYPE_PCM));
         mime_content->put(_("audio/L16"), _(CONTENT_TYPE_PCM));
+        mime_content->put(_("audio/x-aiff"), _(CONTENT_TYPE_AIFF));
+        mime_content->put(_("audio/aiff"), _(CONTENT_TYPE_AIFF));
         mime_content->put(_("video/x-msvideo"), _(CONTENT_TYPE_AVI));
         mime_content->put(_("video/mpeg"), _(CONTENT_TYPE_MPEG));
-        mime_content->put(_("application/x-iso9660"), _(CONTENT_TYPE_DVD));
-        mime_content->put(_("application/x-iso9660-image"), _(CONTENT_TYPE_DVD));
     }
 
     NEW_DICT_OPTION(mime_content);
     SET_DICT_OPTION(CFG_IMPORT_MAPPINGS_MIMETYPE_TO_CONTENTTYPE_LIST);
 
 #if defined(HAVE_NL_LANGINFO) && defined(HAVE_SETLOCALE)
-    if (setlocale(LC_ALL, "") != NULL)
-    {
+    if (setlocale(LC_ALL, "") != nullptr) {
         temp = nl_langinfo(CODESET);
         log_debug("received %s from nl_langinfo\n", temp.c_str());
     }
@@ -1362,27 +1267,22 @@ void ConfigManager::validate(String serverhome)
         temp = _(DEFAULT_FILESYSTEM_CHARSET);
 #else
     temp = _(DEFAULT_FILESYSTEM_CHARSET);
-#endif      
+#endif
     // check if the one we take as default is actually available
-    try
-    {
+    try {
         Ref<StringConverter> conv(new StringConverter(temp,
-                                                 _(DEFAULT_INTERNAL_CHARSET)));
-    }
-    catch (Exception e)
-    {
+            _(DEFAULT_INTERNAL_CHARSET)));
+    } catch (const Exception& e) {
         temp = _(DEFAULT_FALLBACK_CHARSET);
     }
     String charset = getOption(_("/import/filesystem-charset"), temp);
-    try
-    {
-        Ref<StringConverter> conv(new StringConverter(charset, 
-                                                _(DEFAULT_INTERNAL_CHARSET)));
-    }
-    catch (Exception e)
-    {
+    try {
+        Ref<StringConverter> conv(new StringConverter(charset,
+            _(DEFAULT_INTERNAL_CHARSET)));
+    } catch (const Exception& e) {
         throw _Exception(_("Error in config file: unsupported "
-                           "filesystem-charset specified: ") + charset);
+                           "filesystem-charset specified: ")
+            + charset);
     }
 
     log_info("Setting filesystem import charset to %s\n", charset.c_str());
@@ -1390,15 +1290,13 @@ void ConfigManager::validate(String serverhome)
     SET_OPTION(CFG_IMPORT_FILESYSTEM_CHARSET);
 
     charset = getOption(_("/import/metadata-charset"), temp);
-    try
-    {
-        Ref<StringConverter> conv(new StringConverter(charset, 
-                                                _(DEFAULT_INTERNAL_CHARSET)));
-    }
-    catch (Exception e)
-    {
+    try {
+        Ref<StringConverter> conv(new StringConverter(charset,
+            _(DEFAULT_INTERNAL_CHARSET)));
+    } catch (const Exception& e) {
         throw _Exception(_("Error in config file: unsupported "
-                           "metadata-charset specified: ") + charset);
+                           "metadata-charset specified: ")
+            + charset);
     }
 
     log_info("Setting metadata import charset to %s\n", charset.c_str());
@@ -1406,13 +1304,10 @@ void ConfigManager::validate(String serverhome)
     SET_OPTION(CFG_IMPORT_METADATA_CHARSET);
 
     charset = getOption(_("/import/playlist-charset"), temp);
-    try
-    {
-        Ref<StringConverter> conv(new StringConverter(charset, 
-                                                _(DEFAULT_INTERNAL_CHARSET)));
-    }
-    catch (Exception e)
-    {
+    try {
+        Ref<StringConverter> conv(new StringConverter(charset,
+            _(DEFAULT_INTERNAL_CHARSET)));
+    } catch (const Exception& e) {
         throw _Exception(_("Error in config file: unsupported playlist-charset specified: ") + charset);
     }
 
@@ -1422,15 +1317,15 @@ void ConfigManager::validate(String serverhome)
 
 #ifdef EXTEND_PROTOCOLINFO
     temp = getOption(_("/server/protocolInfo/attribute::extend"),
-                     _(DEFAULT_EXTEND_PROTOCOLINFO));
+        _(DEFAULT_EXTEND_PROTOCOLINFO));
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: extend attribute of the "
-                          "protocolInfo tag must be either \"yes\" or \"no\""));
+                           "protocolInfo tag must be either \"yes\" or \"no\""));
 
     NEW_BOOL_OPTION(temp == "yes" ? true : false);
     SET_BOOL_OPTION(CFG_SERVER_EXTEND_PROTOCOLINFO);
 
-/*
+    /*
     temp = getOption(_("/server/protocolInfo/attribute::ps3-hack"),
                      _(DEFAULT_EXTEND_PROTOCOLINFO_CL_HACK));
     if (!validateYesNo(temp))
@@ -1441,33 +1336,40 @@ void ConfigManager::validate(String serverhome)
     SET_BOOL_OPTION(CFG_SERVER_EXTEND_PROTOCOLINFO_CL_HACK);
 */
     temp = getOption(_("/server/protocolInfo/attribute::samsung-hack"),
-                     _(DEFAULT_EXTEND_PROTOCOLINFO_SM_HACK));
+        _(DEFAULT_EXTEND_PROTOCOLINFO_SM_HACK));
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: samsung-hack attribute of the "
-                          "protocolInfo tag must be either \"yes\" or \"no\""));
+                           "protocolInfo tag must be either \"yes\" or \"no\""));
 
     NEW_BOOL_OPTION(temp == "yes" ? true : false);
     SET_BOOL_OPTION(CFG_SERVER_EXTEND_PROTOCOLINFO_SM_HACK);
 #endif
 
     temp = getOption(_("/server/pc-directory/attribute::upnp-hide"),
-                     _(DEFAULT_HIDE_PC_DIRECTORY));
+        _(DEFAULT_HIDE_PC_DIRECTORY));
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: hide attribute of the "
-                          "pc-directory tag must be either \"yes\" or \"no\""));
+                           "pc-directory tag must be either \"yes\" or \"no\""));
 
     NEW_BOOL_OPTION(temp == "yes" ? true : false);
     SET_BOOL_OPTION(CFG_SERVER_HIDE_PC_DIRECTORY);
 
-    temp = getOption(_("/server/interface"), _(""));
-
+    if (!string_ok(interface)) {
+        temp = getOption(_("/server/interface"), _(""));
+    } else {
+        temp = interface;
+    }
     if (string_ok(temp) && string_ok(getOption(_("/server/ip"), _(""))))
         throw _Exception(_("Error in config file: you can not specify interface and ip at the same time!"));
 
     NEW_OPTION(temp);
     SET_OPTION(CFG_SERVER_NETWORK_INTERFACE);
 
-    temp = getOption(_("/server/ip"), _("")); // bind to any IP address
+    if (!string_ok(ip)) {
+        temp = getOption(_("/server/ip"), _("")); // bind to any IP address
+    } else {
+        temp = ip;
+    }
     NEW_OPTION(temp);
     SET_OPTION(CFG_SERVER_IP);
 
@@ -1494,7 +1396,7 @@ void ConfigManager::validate(String serverhome)
     temp = getOption(_("/server/serialNumber"), _(DESC_SERIAL_NUMBER));
     NEW_OPTION(temp);
     SET_OPTION(CFG_SERVER_SERIAL_NUMBER);
-    
+
     temp = getOption(_("/server/manufacturerURL"), _(DESC_MANUFACTURER_URL));
     NEW_OPTION(temp);
     SET_OPTION(CFG_SERVER_MANUFACTURER_URL);
@@ -1503,30 +1405,26 @@ void ConfigManager::validate(String serverhome)
     NEW_OPTION(temp);
     SET_OPTION(CFG_SERVER_PRESENTATION_URL);
 
-    temp = getOption(_("/server/presentationURL/attribute::append-to"), 
-                     _(DEFAULT_PRES_URL_APPENDTO_ATTR));
+    temp = getOption(_("/server/presentationURL/attribute::append-to"),
+        _(DEFAULT_PRES_URL_APPENDTO_ATTR));
 
-    if ((temp != "none") && (temp != "ip") && (temp != "port"))
-    {
+    if ((temp != "none") && (temp != "ip") && (temp != "port")) {
         throw _Exception(_("Error in config file: "
                            "invalid \"append-to\" attribute value in "
                            "<presentationURL> tag"));
     }
 
-    if (((temp == "ip") || (temp == "port")) && 
-         !string_ok(getOption(_("/server/presentationURL"))))
-    {
+    if (((temp == "ip") || (temp == "port")) && !string_ok(getOption(_("/server/presentationURL")))) {
         throw _Exception(_("Error in config file: \"append-to\" attribute "
-                           "value in <presentationURL> tag is set to \"") + 
-                            temp + _("\" but no URL is specified"));
+                           "value in <presentationURL> tag is set to \"")
+            + temp + _("\" but no URL is specified"));
     }
     NEW_OPTION(temp);
     SET_OPTION(CFG_SERVER_APPEND_PRESENTATION_URL_TO);
 
-    temp_int = getIntOption(_("/server/upnp-string-limit"), 
-                              DEFAULT_UPNP_STRING_LIMIT);
-    if ((temp_int != -1) && (temp_int < 4))
-    {
+    temp_int = getIntOption(_("/server/upnp-string-limit"),
+        DEFAULT_UPNP_STRING_LIMIT);
+    if ((temp_int != -1) && (temp_int < 4)) {
         throw _Exception(_("Error in config file: invalid value for "
                            "<upnp-string-limit>"));
     }
@@ -1534,24 +1432,16 @@ void ConfigManager::validate(String serverhome)
     SET_INT_OPTION(CFG_SERVER_UPNP_TITLE_AND_DESC_STRING_LIMIT);
 
 #ifdef HAVE_JS
-    temp = getOption(_("/import/scripting/playlist-script"), 
-            prefix_dir +
-            DIR_SEPARATOR +
-            _(DEFAULT_JS_DIR) +
-            DIR_SEPARATOR +
-            _(DEFAULT_PLAYLISTS_SCRIPT));
+    temp = getOption(_("/import/scripting/playlist-script"),
+        prefix_dir + DIR_SEPARATOR + _(DEFAULT_JS_DIR) + DIR_SEPARATOR + _(DEFAULT_PLAYLISTS_SCRIPT));
     if (!string_ok(temp))
         throw _Exception(_("playlist script location invalid"));
     prepare_path(_("/import/scripting/playlist-script"));
     NEW_OPTION(getOption(_("/import/scripting/playlist-script")));
     SET_OPTION(CFG_IMPORT_SCRIPTING_PLAYLIST_SCRIPT);
 
-    temp = getOption(_("/import/scripting/common-script"), 
-           prefix_dir +
-            DIR_SEPARATOR +
-            _(DEFAULT_JS_DIR) +
-            DIR_SEPARATOR +
-            _(DEFAULT_COMMON_SCRIPT));
+    temp = getOption(_("/import/scripting/common-script"),
+        prefix_dir + DIR_SEPARATOR + _(DEFAULT_JS_DIR) + DIR_SEPARATOR + _(DEFAULT_COMMON_SCRIPT));
     if (!string_ok(temp))
         throw _Exception(_("common script location invalid"));
     prepare_path(_("/import/scripting/common-script"));
@@ -1559,8 +1449,8 @@ void ConfigManager::validate(String serverhome)
     SET_OPTION(CFG_IMPORT_SCRIPTING_COMMON_SCRIPT);
 
     temp = getOption(
-            _("/import/scripting/playlist-script/attribute::create-link"), 
-            _(DEFAULT_PLAYLIST_CREATE_LINK));
+        _("/import/scripting/playlist-script/attribute::create-link"),
+        _(DEFAULT_PLAYLIST_CREATE_LINK));
 
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: "
@@ -1571,32 +1461,27 @@ void ConfigManager::validate(String serverhome)
     SET_BOOL_OPTION(CFG_IMPORT_SCRIPTING_PLAYLIST_SCRIPT_LINK_OBJECTS);
 #endif
 
-    temp = getOption(_("/import/scripting/virtual-layout/attribute::type"), 
-                     _(DEFAULT_LAYOUT_TYPE));
+    temp = getOption(_("/import/scripting/virtual-layout/attribute::type"),
+        _(DEFAULT_LAYOUT_TYPE));
     if ((temp != "js") && (temp != "builtin") && (temp != "disabled"))
         throw _Exception(_("Error in config file: invalid virtual layout "
                            "type specified!"));
     NEW_OPTION(temp);
     SET_OPTION(CFG_IMPORT_SCRIPTING_VIRTUAL_LAYOUT_TYPE);
 
-
 #ifndef HAVE_JS
     if (temp == "js")
         throw _Exception(_("MediaTomb was compiled without js support, "
                            "however you specified \"js\" to be used for the "
                            "virtual-layout."));
 #else
-    charset = getOption(_("/import/scripting/attribute::script-charset"), 
-                        _(DEFAULT_JS_CHARSET));
-    if (temp == "js") 
-    {
-        try
-        {
-            Ref<StringConverter> conv(new StringConverter(charset, 
-                                                _(DEFAULT_INTERNAL_CHARSET)));
-        }
-        catch (Exception e)
-        {
+    charset = getOption(_("/import/scripting/attribute::script-charset"),
+        _(DEFAULT_JS_CHARSET));
+    if (temp == "js") {
+        try {
+            Ref<StringConverter> conv(new StringConverter(charset,
+                _(DEFAULT_INTERNAL_CHARSET)));
+        } catch (const Exception& e) {
             throw _Exception(_("Error in config file: unsupported import script charset specified: ") + charset);
         }
     }
@@ -1605,14 +1490,9 @@ void ConfigManager::validate(String serverhome)
     SET_OPTION(CFG_IMPORT_SCRIPTING_CHARSET);
 
     String script_path = getOption(
-                           _("/import/scripting/virtual-layout/import-script"), 
-                           prefix_dir +
-                             DIR_SEPARATOR + 
-                           _(DEFAULT_JS_DIR) +
-                             DIR_SEPARATOR +
-                           _(DEFAULT_IMPORT_SCRIPT));
-    if (temp == "js")
-    {
+        _("/import/scripting/virtual-layout/import-script"),
+        prefix_dir + DIR_SEPARATOR + _(DEFAULT_JS_DIR) + DIR_SEPARATOR + _(DEFAULT_IMPORT_SCRIPT));
+    if (temp == "js") {
         if (!string_ok(script_path))
             throw _Exception(_("Error in config file: you specified \"js\" to "
                                "be used for virtual layout, but script "
@@ -1620,52 +1500,37 @@ void ConfigManager::validate(String serverhome)
 
         prepare_path(_("/import/scripting/virtual-layout/import-script"));
         script_path = getOption(
-                        _("/import/scripting/virtual-layout/import-script"));
+            _("/import/scripting/virtual-layout/import-script"));
     }
 
     NEW_OPTION(script_path);
     SET_OPTION(CFG_IMPORT_SCRIPTING_IMPORT_SCRIPT);
-#ifdef HAVE_LIBDVDNAV
-    // add dvd script and make sure scripts can be enabled and disabled
-    script_path = getOption(_("/import/scripting/virtual-layout/dvd-script"),
-                            prefix_dir + DIR_SEPARATOR + _(DEFAULT_JS_DIR) +
-                            DIR_SEPARATOR + _(DEFAULT_DVD_SCRIPT));
-
-    if (temp == "js")
-    {
-        if (!string_ok(script_path))
-            throw _Exception(_("Error in config file: you specified \"js\" to "
-                               "be used for virtual layout, but dvd script "
-                               "location is invalid."));
-
-        prepare_path(_("/import/scripting/virtual-layout/dvd-script"));
-        script_path = getOption(
-                        _("/import/scripting/virtual-layout/dvd-script"));
- 
-    }
-
-    NEW_OPTION(script_path);
-    SET_OPTION(CFG_IMPORT_SCRIPTING_DVD_SCRIPT);
-#endif
 
 #endif
 
     // 0 means, that the SDK will any free port itself
-    temp_int = getIntOption(_("/server/port"), 0);
+    if (port < 0) {
+        temp_int = getIntOption(_("/server/port"), 0);
+    } else {
+        temp_int = port;
+    }
     NEW_INT_OPTION(temp_int);
     SET_INT_OPTION(CFG_SERVER_PORT);
 
     temp_int = getIntOption(_("/server/alive"), DEFAULT_ALIVE_INTERVAL);
+    if (temp_int < ALIVE_INTERVAL_MIN)
+        throw _Exception(_("Error in config file: incorrect parameter "
+                           "for /server/alive, must be at least ")
+            + ALIVE_INTERVAL_MIN);
     NEW_INT_OPTION(temp_int);
     SET_INT_OPTION(CFG_SERVER_ALIVE_INTERVAL);
 
     Ref<Element> el = getElement(_("/import/mappings/mimetype-upnpclass"));
-    if (el == nil)
-    {
+    if (el == nullptr) {
         getOption(_("/import/mappings/mimetype-upnpclass"), _(""));
     }
-    NEW_DICT_OPTION(createDictionaryFromNodeset(el, _("map"), 
-                                                    _("from"), _("to")));
+    NEW_DICT_OPTION(createDictionaryFromNodeset(el, _("map"),
+        _("from"), _("to")));
     SET_DICT_OPTION(CFG_IMPORT_MAPPINGS_MIMETYPE_TO_UPNP_CLASS_LIST);
 
     temp = getOption(_("/import/autoscan/attribute::use-inotify"), _("auto"));
@@ -1675,22 +1540,20 @@ void ConfigManager::validate(String serverhome)
 
     el = getElement(_("/import/autoscan"));
 
-    NEW_AUTOSCANLIST_OPTION(createAutoscanListFromNodeset(el, TimedScanMode));
+    NEW_AUTOSCANLIST_OPTION(createAutoscanListFromNodeset(el, ScanMode::Timed));
     SET_AUTOSCANLIST_OPTION(CFG_IMPORT_AUTOSCAN_TIMED_LIST);
 
-
 #ifdef HAVE_INOTIFY
     bool inotify_supported = false;
     inotify_supported = Inotify::supported();
 #endif
 
-    if (temp == _(YES))
-    {
+    if (temp == _(YES)) {
 #ifdef HAVE_INOTIFY
         if (!inotify_supported)
-            throw _Exception(_("You specified " 
+            throw _Exception(_("You specified "
                                "\"yes\" in \"<autoscan use-inotify=\"\">"
-                               " however your system does not have " 
+                               " however your system does not have "
                                "inotify support"));
 #else
         throw _Exception(_("You specified"
@@ -1698,27 +1561,21 @@ void ConfigManager::validate(String serverhome)
                            " however this version of MediaTomb was compiled "
                            "without inotify support"));
 #endif
-    } 
-   
+    }
+
 #ifdef HAVE_INOTIFY
-    if (temp == _("auto") || (temp == _(YES)))
-    {
-        if (inotify_supported)
-        {
-            NEW_AUTOSCANLIST_OPTION(createAutoscanListFromNodeset(el, InotifyScanMode));
+    if (temp == _("auto") || (temp == _(YES))) {
+        if (inotify_supported) {
+            NEW_AUTOSCANLIST_OPTION(createAutoscanListFromNodeset(el, ScanMode::INotify));
             SET_AUTOSCANLIST_OPTION(CFG_IMPORT_AUTOSCAN_INOTIFY_LIST);
 
             NEW_BOOL_OPTION(true);
             SET_BOOL_OPTION(CFG_IMPORT_AUTOSCAN_USE_INOTIFY);
-        }
-        else
-        {
+        } else {
             NEW_BOOL_OPTION(false);
             SET_BOOL_OPTION(CFG_IMPORT_AUTOSCAN_USE_INOTIFY);
         }
-    }
-    else
-    {
+    } else {
         NEW_BOOL_OPTION(false);
         SET_BOOL_OPTION(CFG_IMPORT_AUTOSCAN_USE_INOTIFY);
     }
@@ -1726,61 +1583,58 @@ void ConfigManager::validate(String serverhome)
 
 #ifdef EXTERNAL_TRANSCODING
     temp = getOption(
-            _("/transcoding/attribute::enabled"), 
-            _(DEFAULT_TRANSCODING_ENABLED));
+        _("/transcoding/attribute::enabled"),
+        _(DEFAULT_TRANSCODING_ENABLED));
 
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: incorrect parameter "
-                    "for <transcoding enabled=\"\"> attribute"));
-
+                           "for <transcoding enabled=\"\"> attribute"));
 
     if (temp == "yes")
         el = getElement(_("/transcoding"));
     else
-        el = nil;
+        el = nullptr;
 
     NEW_TRANSCODING_PROFILELIST_OPTION(createTranscodingProfileListFromNodeset(el));
     SET_TRANSCODING_PROFILELIST_OPTION(CFG_TRANSCODING_PROFILE_LIST);
 
 #ifdef HAVE_CURL
-    if (temp == "yes")
-    {
+    if (temp == "yes") {
         temp_int = getIntOption(
-                _("/transcoding/attribute::fetch-buffer-size"),
-                DEFAULT_CURL_BUFFER_SIZE);
+            _("/transcoding/attribute::fetch-buffer-size"),
+            DEFAULT_CURL_BUFFER_SIZE);
         if (temp_int < CURL_MAX_WRITE_SIZE)
             throw _Exception(_("Error in config file: incorrect parameter "
-                        "for <transcoding fetch-buffer-size=\"\"> attribute, "
-                        "must be at least ") + CURL_MAX_WRITE_SIZE);
+                               "for <transcoding fetch-buffer-size=\"\"> attribute, "
+                               "must be at least ")
+                + CURL_MAX_WRITE_SIZE);
         NEW_INT_OPTION(temp_int);
         SET_INT_OPTION(CFG_EXTERNAL_TRANSCODING_CURL_BUFFER_SIZE);
 
         temp_int = getIntOption(
-                _("/transcoding/attribute::fetch-buffer-fill-size"),
-                DEFAULT_CURL_INITIAL_FILL_SIZE);
+            _("/transcoding/attribute::fetch-buffer-fill-size"),
+            DEFAULT_CURL_INITIAL_FILL_SIZE);
         if (temp_int < 0)
             throw _Exception(_("Error in config file: incorrect parameter "
-                    "for <transcoding fetch-buffer-fill-size=\"\"> attribute"));
+                               "for <transcoding fetch-buffer-fill-size=\"\"> attribute"));
 
         NEW_INT_OPTION(temp_int);
         SET_INT_OPTION(CFG_EXTERNAL_TRANSCODING_CURL_FILL_SIZE);
     }
 
-#endif//HAVE_CURL
-#endif//EXTERNAL_TRANSCODING
+#endif //HAVE_CURL
+#endif //EXTERNAL_TRANSCODING
 
     el = getElement(_("/server/custom-http-headers"));
     NEW_STRARR_OPTION(createArrayFromNodeset(el, _("add"), _("header")));
     SET_STRARR_OPTION(CFG_SERVER_CUSTOM_HTTP_HEADERS);
 
-#ifdef HAVE_LIBEXIF    
+#ifdef HAVE_LIBEXIF
 
     el = getElement(_("/import/library-options/libexif/auxdata"));
-    if (el == nil)
-    {
+    if (el == nullptr) {
         getOption(_("/import/library-options/libexif/auxdata"),
-                  _(""));
-        
+            _(""));
     }
     NEW_STRARR_OPTION(createArrayFromNodeset(el, _("add-data"), _("tag")));
     SET_STRARR_OPTION(CFG_IMPORT_LIBOPTS_EXIF_AUXDATA_TAGS_LIST);
@@ -1789,8 +1643,7 @@ void ConfigManager::validate(String serverhome)
 
 #if defined(HAVE_ID3LIB) || defined(HAVE_TAGLIB)
     el = getElement(_("/import/library-options/id3/auxdata"));
-    if (el == nil)
-    {
+    if (el == nullptr) {
         getOption(_("/import/library-options/id3/auxdata"), _(""));
     }
     NEW_STRARR_OPTION(createArrayFromNodeset(el, _("add-data"), _("tag")));
@@ -1800,7 +1653,7 @@ void ConfigManager::validate(String serverhome)
 #if defined(HAVE_FFMPEG) && defined(HAVE_FFMPEGTHUMBNAILER)
     temp = getOption(_("/server/extended-runtime-options/ffmpegthumbnailer/"
                        "attribute::enabled"),
-                     _(DEFAULT_FFMPEGTHUMBNAILER_ENABLED));
+        _(DEFAULT_FFMPEGTHUMBNAILER_ENABLED));
 
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: "
@@ -1810,11 +1663,10 @@ void ConfigManager::validate(String serverhome)
     NEW_BOOL_OPTION(temp == YES ? true : false);
     SET_BOOL_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_ENABLED);
 
-    if (temp == YES)
-    {
+    if (temp == YES) {
         temp_int = getIntOption(_("/server/extended-runtime-options/ffmpegthumbnailer/"
-                                  "thumbnail-size"), 
-                                   DEFAULT_FFMPEGTHUMBNAILER_THUMBSIZE);
+                                  "thumbnail-size"),
+            DEFAULT_FFMPEGTHUMBNAILER_THUMBSIZE);
 
         if (temp_int <= 0)
             throw _Exception(_("Error in config file: ffmpegthumbnailer - "
@@ -1825,8 +1677,8 @@ void ConfigManager::validate(String serverhome)
         SET_INT_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_THUMBSIZE);
 
         temp_int = getIntOption(_("/server/extended-runtime-options/ffmpegthumbnailer/"
-                                  "seek-percentage"), 
-                                   DEFAULT_FFMPEGTHUMBNAILER_SEEK_PERCENTAGE);
+                                  "seek-percentage"),
+            DEFAULT_FFMPEGTHUMBNAILER_SEEK_PERCENTAGE);
 
         if (temp_int < 0)
             throw _Exception(_("Error in config file: ffmpegthumbnailer - "
@@ -1837,20 +1689,19 @@ void ConfigManager::validate(String serverhome)
         SET_INT_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_SEEK_PERCENTAGE);
 
         temp = getOption(_("/server/extended-runtime-options/ffmpegthumbnailer/"
-                              "filmstrip-overlay"),
-                             _(DEFAULT_FFMPEGTHUMBNAILER_FILMSTRIP_OVERLAY));
+                           "filmstrip-overlay"),
+            _(DEFAULT_FFMPEGTHUMBNAILER_FILMSTRIP_OVERLAY));
 
         if (!validateYesNo(temp))
             throw _Exception(_("Error in config file: ffmpegthumbnailer - "
                                "invalid value in <filmstrip-overlay> tag"));
 
-
         NEW_BOOL_OPTION(temp == YES ? true : false);
         SET_BOOL_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_FILMSTRIP_OVERLAY);
 
         temp = getOption(_("/server/extended-runtime-options/ffmpegthumbnailer/"
-                              "workaround-bugs"),
-                             _(DEFAULT_FFMPEGTHUMBNAILER_WORKAROUND_BUGS));
+                           "workaround-bugs"),
+            _(DEFAULT_FFMPEGTHUMBNAILER_WORKAROUND_BUGS));
 
         if (!validateYesNo(temp))
             throw _Exception(_("Error in config file: ffmpegthumbnailer - "
@@ -1860,8 +1711,8 @@ void ConfigManager::validate(String serverhome)
         SET_BOOL_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_WORKAROUND_BUGS);
 
         temp_int = getIntOption(_("/server/extended-runtime-options/"
-                                  "ffmpegthumbnailer/image-quality"), 
-                                   DEFAULT_FFMPEGTHUMBNAILER_IMAGE_QUALITY);
+                                  "ffmpegthumbnailer/image-quality"),
+            DEFAULT_FFMPEGTHUMBNAILER_IMAGE_QUALITY);
 
         if (temp_int < 0)
             throw _Exception(_("Error in config file: ffmpegthumbnailer - "
@@ -1875,12 +1726,31 @@ void ConfigManager::validate(String serverhome)
 
         NEW_INT_OPTION(temp_int);
         SET_INT_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_IMAGE_QUALITY);
+
+        temp = getOption("/server/extended-runtime-options/ffmpegthumbnailer/"
+                         "cache-dir",
+            DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR);
+
+        NEW_OPTION(temp);
+        SET_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR);
+
+        temp = getOption("/server/extended-runtime-options/ffmpegthumbnailer/"
+                         "cache-dir/attribute::enabled",
+            DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED);
+
+        if (!validateYesNo(temp))
+            throw _Exception(_("Error in config file: "
+                               "invalid \"enabled\" attribute value in "
+                               "ffmpegthumbnailer <cache-dir> tag"));
+
+        NEW_BOOL_OPTION(temp == YES ? true : false);
+        SET_BOOL_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED);
     }
 #endif
 
     temp = getOption(_("/server/extended-runtime-options/mark-played-items/"
                        "attribute::enabled"),
-                     _(DEFAULT_MARK_PLAYED_ITEMS_ENABLED));
+        _(DEFAULT_MARK_PLAYED_ITEMS_ENABLED));
 
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: "
@@ -1890,65 +1760,58 @@ void ConfigManager::validate(String serverhome)
     NEW_BOOL_OPTION(temp == YES ? true : false);
     SET_BOOL_OPTION(CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_ENABLED);
 
-    if (temp == YES)
-    {
-        temp = getOption(_("/server/extended-runtime-options/mark-played-items/"
-                           "attribute::suppress-cds-updates"),
-                           _(DEFAULT_MARK_PLAYED_ITEMS_SUPPRESS_CDS_UPDATES));
-        if (!validateYesNo(temp))
-            throw _Exception(_("Error in config file: "
-                               "invalid \":suppress-cds-updates\" attribute "
-                               "value in <mark-played-items> tag"));
+    temp = getOption(_("/server/extended-runtime-options/mark-played-items/"
+                       "attribute::suppress-cds-updates"),
+        _(DEFAULT_MARK_PLAYED_ITEMS_SUPPRESS_CDS_UPDATES));
+    if (!validateYesNo(temp))
+        throw _Exception(_("Error in config file: "
+                           "invalid \":suppress-cds-updates\" attribute "
+                           "value in <mark-played-items> tag"));
 
-        NEW_BOOL_OPTION(temp == YES ? true : false);
-        SET_BOOL_OPTION(CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_SUPPRESS_CDS_UPDATES);
+    NEW_BOOL_OPTION(temp == YES ? true : false);
+    SET_BOOL_OPTION(CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_SUPPRESS_CDS_UPDATES);
 
-        temp = getOption(_("/server/extended-runtime-options/mark-played-items/"
-                           "string/attribute::mode"),
-                         _(DEFAULT_MARK_PLAYED_ITEMS_STRING_MODE));
+    temp = getOption(_("/server/extended-runtime-options/mark-played-items/"
+                       "string/attribute::mode"),
+        _(DEFAULT_MARK_PLAYED_ITEMS_STRING_MODE));
 
-        if ((temp != "prepend") && (temp != "append"))
-            throw _Exception(_("Error in config file: "
-                               "invalid \"mode\" attribute value in "
-                               "<string> tag in the <mark-played-items> section"));
+    if ((temp != "prepend") && (temp != "append"))
+        throw _Exception(_("Error in config file: "
+                           "invalid \"mode\" attribute value in "
+                           "<string> tag in the <mark-played-items> section"));
 
-        NEW_BOOL_OPTION(temp == DEFAULT_MARK_PLAYED_ITEMS_STRING_MODE ? true : false);
-        SET_BOOL_OPTION(CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_STRING_MODE_PREPEND);
+    NEW_BOOL_OPTION(temp == DEFAULT_MARK_PLAYED_ITEMS_STRING_MODE ? true : false);
+    SET_BOOL_OPTION(CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_STRING_MODE_PREPEND);
 
-        temp = getOption(_("/server/extended-runtime-options/mark-played-items/"
-                           "string"), 
-                         _(DEFAULT_MARK_PLAYED_ITEMS_STRING));
-        if (!string_ok(temp))
-            throw _Exception(_("Error in config file: "
-                               "empty string given for the <string> tag in the "
-                               "<mark-played-items> section"));
-        NEW_OPTION(temp);
-        SET_OPTION(CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_STRING);
-
-        Ref<Array<StringBase> > mark_content_list(new Array<StringBase>());
-        tmpEl = getElement(_("/server/extended-runtime-options/mark-played-items/mark"));
-
-        if (tmpEl != nil)
-        {
-            for (int m = 0; m < tmpEl->elementChildCount(); m++)
-            {
-                Ref<Element> content = tmpEl->getElementChild(m);
-                if (content->getName() != "content")
-                    continue;
-
-                String mark_content = content->getText();
-                if (!string_ok(mark_content))
-                    throw _Exception(_("error in configuration, <mark-played-items>, empty <content> parameter!"));
-
-                if ((mark_content != DEFAULT_MARK_PLAYED_CONTENT_VIDEO) && 
-                    (mark_content != DEFAULT_MARK_PLAYED_CONTENT_AUDIO) &&
-                    (mark_content != DEFAULT_MARK_PLAYED_CONTENT_IMAGE))
-                        throw _Exception(_("error in configuration, <mark-played-items>, invalid <content> parameter! Allowed values are \"video\", \"audio\", \"image\""));
-
-                mark_content_list->append(mark_content);
-                NEW_STRARR_OPTION(mark_content_list);
-                SET_STRARR_OPTION(CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_CONTENT_LIST);
-            }
+    temp = getOption(_("/server/extended-runtime-options/mark-played-items/"
+                       "string"),
+        _(DEFAULT_MARK_PLAYED_ITEMS_STRING));
+    if (!string_ok(temp))
+        throw _Exception(_("Error in config file: "
+                           "empty string given for the <string> tag in the "
+                           "<mark-played-items> section"));
+    NEW_OPTION(temp);
+    SET_OPTION(CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_STRING);
+
+    Ref<Array<StringBase> > mark_content_list(new Array<StringBase>());
+    tmpEl = getElement(_("/server/extended-runtime-options/mark-played-items/mark"));
+
+    if (tmpEl != nullptr) {
+        for (int m = 0; m < tmpEl->elementChildCount(); m++) {
+            Ref<Element> content = tmpEl->getElementChild(m);
+            if (content->getName() != "content")
+                continue;
+
+            String mark_content = content->getText();
+            if (!string_ok(mark_content))
+                throw _Exception(_("error in configuration, <mark-played-items>, empty <content> parameter!"));
+
+            if ((mark_content != DEFAULT_MARK_PLAYED_CONTENT_VIDEO) && (mark_content != DEFAULT_MARK_PLAYED_CONTENT_AUDIO) && (mark_content != DEFAULT_MARK_PLAYED_CONTENT_IMAGE))
+                throw _Exception(_("error in configuration, <mark-played-items>, invalid <content> parameter! Allowed values are \"video\", \"audio\", \"image\""));
+
+            mark_content_list->append(mark_content);
+            NEW_STRARR_OPTION(mark_content_list);
+            SET_STRARR_OPTION(CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_CONTENT_LIST);
         }
     }
 
@@ -1963,10 +1826,9 @@ void ConfigManager::validate(String serverhome)
     NEW_BOOL_OPTION(temp == "yes" ? true : false);
     SET_BOOL_OPTION(CFG_SERVER_EXTOPTS_LASTFM_ENABLED);
 
-    if (temp == YES)
-    {
+    if (temp == YES) {
         temp = getOption(_("/server/extended-runtime-options/lastfm/username"),
-                         _(DEFAULT_LASTFM_USERNAME));
+            _(DEFAULT_LASTFM_USERNAME));
 
         if (!string_ok(temp))
             throw _Exception(_("Error in config file: lastfm - "
@@ -1977,7 +1839,7 @@ void ConfigManager::validate(String serverhome)
         SET_OPTION(CFG_SERVER_EXTOPTS_LASTFM_USERNAME);
 
         temp = getOption(_("/server/extended-runtime-options/lastfm/password"),
-                         _(DEFAULT_LASTFM_PASSWORD));
+            _(DEFAULT_LASTFM_PASSWORD));
 
         if (!string_ok(temp))
             throw _Exception(_("Error in config file: lastfm - "
@@ -1989,19 +1851,15 @@ void ConfigManager::validate(String serverhome)
     }
 #endif
 
-
 #ifdef HAVE_MAGIC
     String magic_file;
-    if (!string_ok(magic))
-    {
-        if (string_ok(getOption(_("/import/magic-file"), _(""))))
-        {
+    if (!string_ok(magic)) {
+        if (string_ok(getOption(_("/import/magic-file"), _("")))) {
             prepare_path(_("/import/magic-file"));
         }
 
         magic_file = getOption(_("/import/magic-file"));
-    }
-    else
+    } else
         magic_file = magic;
 
     NEW_OPTION(magic_file);
@@ -2010,14 +1868,12 @@ void ConfigManager::validate(String serverhome)
 
 #ifdef HAVE_INOTIFY
     tmpEl = getElement(_("/import/autoscan"));
-    Ref<AutoscanList> config_timed_list = createAutoscanListFromNodeset(tmpEl, TimedScanMode);
-    Ref<AutoscanList> config_inotify_list = createAutoscanListFromNodeset(tmpEl, InotifyScanMode);
+    Ref<AutoscanList> config_timed_list = createAutoscanListFromNodeset(tmpEl, ScanMode::Timed);
+    Ref<AutoscanList> config_inotify_list = createAutoscanListFromNodeset(tmpEl, ScanMode::INotify);
 
-    for (int i = 0; i < config_inotify_list->size(); i++)
-    {
+    for (int i = 0; i < config_inotify_list->size(); i++) {
         Ref<AutoscanDirectory> i_dir = config_inotify_list->get(i);
-        for (int j = 0; j < config_timed_list->size(); j++)
-        {
+        for (int j = 0; j < config_timed_list->size(); j++) {
             Ref<AutoscanDirectory> t_dir = config_timed_list->get(j);
             if (i_dir->getLocation() == t_dir->getLocation())
                 throw _Exception(_("Error in config file: same path used in both inotify and timed scan modes"));
@@ -2026,8 +1882,8 @@ void ConfigManager::validate(String serverhome)
 #endif
 
 #ifdef YOUTUBE
-    temp = getOption(_("/import/online-content/YouTube/attribute::enabled"), 
-                     _(DEFAULT_YOUTUBE_ENABLED));
+    temp = getOption(_("/import/online-content/YouTube/attribute::enabled"),
+        _(DEFAULT_YOUTUBE_ENABLED));
 
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: "
@@ -2037,30 +1893,28 @@ void ConfigManager::validate(String serverhome)
     NEW_BOOL_OPTION(temp == "yes" ? true : false);
     SET_BOOL_OPTION(CFG_ONLINE_CONTENT_YOUTUBE_ENABLED);
 
-    /// \todo well, tough scenario: YT service is disabled, but the database 
-    /// is populated with YT items from some time before. We still need to 
+    /// \todo well, tough scenario: YT service is disabled, but the database
+    /// is populated with YT items from some time before. We still need to
     /// support playing them, but that requires a valid YT section and thus
     /// forces us to check the options eventhough the service is disabled.
     // check other options only if the service is enabled
-//    if (temp == "yes")
+    //    if (temp == "yes")
     {
         temp = getOption(_("/import/online-content/YouTube/attribute::racy-content"),
-                         _(DEFAULT_YOUTUBE_RACY_CONTENT));
+            _(DEFAULT_YOUTUBE_RACY_CONTENT));
 
-        if ((temp != "include") && (temp != "exclude"))
-        {
+        if ((temp != "include") && (temp != "exclude")) {
             throw _Exception(_("Error in config file: "
                                "invalid racy-content value in <YouTube> tag"));
         }
 
         NEW_OPTION(temp);
         SET_OPTION(CFG_ONLINE_CONTENT_YOUTUBE_RACY);
-   
+
         temp = getOption(_("/import/online-content/YouTube/attribute::format"),
-                         _(DEFAULT_YOUTUBE_FORMAT));
+            _(DEFAULT_YOUTUBE_FORMAT));
 
-        if ((temp != "mp4") && (temp != "flv"))
-        {
+        if ((temp != "mp4") && (temp != "flv")) {
             throw _Exception(_("Error in config file: "
                                "invalid format value in <YouTube> tag"));
         }
@@ -2069,7 +1923,7 @@ void ConfigManager::validate(String serverhome)
         SET_BOOL_OPTION(CFG_ONLINE_CONTENT_YOUTUBE_FORMAT_MP4);
 
         temp = getOption(_("/import/online-content/YouTube/attribute::hd"),
-                         _(DEFAULT_YOUTUBE_HD));
+            _(DEFAULT_YOUTUBE_HD));
 
         if (!validateYesNo(temp))
             throw _Exception(_("Error in config file: "
@@ -2086,9 +1940,8 @@ void ConfigManager::validate(String serverhome)
         SET_INT_OPTION(CFG_ONLINE_CONTENT_YOUTUBE_REFRESH);
 
         temp_int = getIntOption(_("/import/online-content/YouTube/attribute::purge-after"), DEFAULT_YOUTUBE_PURGE_AFTER);
-        if (getIntOption(_("/import/online-content/YouTube/attribute::refresh")) >= temp_int)
-        {
-            if (temp_int != 0) 
+        if (getIntOption(_("/import/online-content/YouTube/attribute::refresh")) >= temp_int) {
+            if (temp_int != 0)
                 throw _Exception(_("Error in config file: YouTube purge-after value must be greater than refresh interval"));
         }
 
@@ -2096,43 +1949,41 @@ void ConfigManager::validate(String serverhome)
         SET_INT_OPTION(CFG_ONLINE_CONTENT_YOUTUBE_PURGE_AFTER);
 
         temp = getOption(_("/import/online-content/YouTube/attribute::update-at-start"),
-                _(DEFAULT_YOUTUBE_UPDATE_AT_START));
+            _(DEFAULT_YOUTUBE_UPDATE_AT_START));
 
         if (!validateYesNo(temp))
             throw _Exception(_("Error in config file: "
-                        "invalid \"update-at-start\" attribute value in "
-                        "<YouTube> tag"));
+                               "invalid \"update-at-start\" attribute value in "
+                               "<YouTube> tag"));
 
         NEW_BOOL_OPTION(temp == "yes" ? true : false);
         SET_BOOL_OPTION(CFG_ONLINE_CONTENT_YOUTUBE_UPDATE_AT_START);
 
         el = getElement(_("/import/online-content/YouTube"));
-        if (el == nil)
-        {
+        if (el == nullptr) {
             getOption(_("/import/online-content/YouTube"),
-                    _(""));
+                _(""));
         }
         Ref<Array<Object> > yt_opts = createServiceTaskList(OS_YouTube, el);
-        if (getBoolOption(CFG_ONLINE_CONTENT_YOUTUBE_ENABLED) && 
-                (yt_opts->size() == 0))
+        if (getBoolOption(CFG_ONLINE_CONTENT_YOUTUBE_ENABLED) && (yt_opts->size() == 0))
             throw _Exception(_("Error in config file: "
-                        "YouTube service enabled but no imports "
-                        "specified."));
+                               "YouTube service enabled but no imports "
+                               "specified."));
 
         NEW_OBJARR_OPTION(yt_opts);
         SET_OBJARR_OPTION(CFG_ONLINE_CONTENT_YOUTUBE_TASK_LIST);
 
         log_warning("You enabled the YouTube feature, which allows you\n"
-"                             to watch YouTube videos on your UPnP device!\n"
-"                             Please check http://www.youtube.com/t/terms\n"
-"                             By using this feature you may be violating YouTube\n"
-"                             service terms and conditions!\n\n");
+                    "                             to watch YouTube videos on your UPnP device!\n"
+                    "                             Please check http://www.youtube.com/t/terms\n"
+                    "                             By using this feature you may be violating YouTube\n"
+                    "                             service terms and conditions!\n\n");
     }
 #endif
 
-#ifdef SOPCAST 
-    temp = getOption(_("/import/online-content/SopCast/attribute::enabled"), 
-                     _(DEFAULT_SOPCAST_ENABLED));
+#ifdef SOPCAST
+    temp = getOption(_("/import/online-content/SopCast/attribute::enabled"),
+        _(DEFAULT_SOPCAST_ENABLED));
 
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: "
@@ -2147,9 +1998,8 @@ void ConfigManager::validate(String serverhome)
     SET_INT_OPTION(CFG_ONLINE_CONTENT_SOPCAST_REFRESH);
 
     temp_int = getIntOption(_("/import/online-content/SopCast/attribute::purge-after"), 0);
-    if (getIntOption(_("/import/online-content/SopCast/attribute::refresh")) >= temp_int)
-    {
-        if (temp_int != 0) 
+    if (getIntOption(_("/import/online-content/SopCast/attribute::refresh")) >= temp_int) {
+        if (temp_int != 0)
             throw _Exception(_("Error in config file: SopCast purge-after value must be greater than refresh interval"));
     }
 
@@ -2157,7 +2007,7 @@ void ConfigManager::validate(String serverhome)
     SET_INT_OPTION(CFG_ONLINE_CONTENT_SOPCAST_PURGE_AFTER);
 
     temp = getOption(_("/import/online-content/SopCast/attribute::update-at-start"),
-                     _(DEFAULT_SOPCAST_UPDATE_AT_START));
+        _(DEFAULT_SOPCAST_UPDATE_AT_START));
 
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: "
@@ -2168,52 +2018,9 @@ void ConfigManager::validate(String serverhome)
     SET_BOOL_OPTION(CFG_ONLINE_CONTENT_SOPCAST_UPDATE_AT_START);
 #endif
 
-#ifdef WEBORAMA 
-    temp = getOption(_("/import/online-content/Weborama/attribute::enabled"), 
-                     _(DEFAULT_WEBORAMA_ENABLED));
-
-    if (!validateYesNo(temp))
-        throw _Exception(_("Error in config file: "
-                           "invalid \"enabled\" attribute value in "
-                           "<Weborama> tag"));
-
-    NEW_BOOL_OPTION(temp == "yes" ? true : false);
-    SET_BOOL_OPTION(CFG_ONLINE_CONTENT_WEBORAMA_ENABLED);
-
-    if (temp == "yes")
-    {
-        el = getElement(_("/import/online-content/Weborama"));
-        Ref<Array<Object> > wb_opts = createServiceTaskList(OS_Weborama, el);
-        if (wb_opts->size() == 0)
-            throw _Exception(_("Error in config file: "
-                        "Weborama service enabled but no imports "
-                        "specified."));
-
-        NEW_OBJARR_OPTION(wb_opts);
-        SET_OBJARR_OPTION(CFG_ONLINE_CONTENT_WEBORAMA_TASK_LIST);
-    }
-
-
-    temp_int = getIntOption(_("/import/online-content/Weborama/attribute::refresh"), DEFAULT_WEBORAMA_REFRESH);
-    NEW_INT_OPTION(temp_int);
-    SET_INT_OPTION(CFG_ONLINE_CONTENT_WEBORAMA_REFRESH);
-    SET_INT_OPTION(CFG_ONLINE_CONTENT_WEBORAMA_PURGE_AFTER);
-
-    temp = getOption(_("/import/online-content/Weborama/attribute::update-at-start"),
-                     _(DEFAULT_WEBORAMA_UPDATE_AT_START));
-
-    if (!validateYesNo(temp))
-        throw _Exception(_("Error in config file: "
-                           "invalid \"update-at-start\" attribute value in "
-                           "<Weborama> tag"));
-
-    NEW_BOOL_OPTION(temp == "yes" ? true : false);
-    SET_BOOL_OPTION(CFG_ONLINE_CONTENT_WEBORAMA_UPDATE_AT_START);
-#endif
-
 #ifdef ATRAILERS
-    temp = getOption(_("/import/online-content/AppleTrailers/attribute::enabled"), 
-                     _(DEFAULT_ATRAILERS_ENABLED));
+    temp = getOption(_("/import/online-content/AppleTrailers/attribute::enabled"),
+        _(DEFAULT_ATRAILERS_ENABLED));
 
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: "
@@ -2229,7 +2036,7 @@ void ConfigManager::validate(String serverhome)
     SET_INT_OPTION(CFG_ONLINE_CONTENT_ATRAILERS_PURGE_AFTER);
 
     temp = getOption(_("/import/online-content/AppleTrailers/attribute::update-at-start"),
-                     _(DEFAULT_ATRAILERS_UPDATE_AT_START));
+        _(DEFAULT_ATRAILERS_UPDATE_AT_START));
 
     if (!validateYesNo(temp))
         throw _Exception(_("Error in config file: "
@@ -2240,9 +2047,8 @@ void ConfigManager::validate(String serverhome)
     SET_BOOL_OPTION(CFG_ONLINE_CONTENT_ATRAILERS_UPDATE_AT_START);
 
     temp = getOption(_("/import/online-content/AppleTrailers/attribute::resolution"),
-                                 String::from(DEFAULT_ATRAILERS_RESOLUTION));
-    if ((temp != "640") && (temp != "720p"))
-    {
+        String::from(DEFAULT_ATRAILERS_RESOLUTION));
+    if ((temp != "640") && (temp != "720p")) {
         throw _Exception(_("Error in config file: "
                            "invalid \"resolution\" attribute value in "
                            "<AppleTrailers> tag, only \"640\" and \"720p\" is "
@@ -2253,42 +2059,39 @@ void ConfigManager::validate(String serverhome)
     SET_OPTION(CFG_ONLINE_CONTENT_ATRAILERS_RESOLUTION);
 #endif
 
-
-
     log_info("Configuration check succeeded.\n");
 
     //root->indent();
-    
+
     log_debug("Config file dump after validation: \n%s\n", rootDoc->print().c_str());
 }
 
 void ConfigManager::prepare_udn()
 {
     bool need_to_save = false;
- 
+
     if (root->getName() != "config")
         return;
 
     Ref<Element> server = root->getChildByName(_("server"));
-    if (server == nil)
+    if (server == nullptr)
         return;
 
     Ref<Element> element = server->getChildByName(_("udn"));
-    if (element == nil || element->getText() == nil || element->getText() == "")
-    {
-        char   uuid_str[37];
+    if (element == nullptr || element->getText() == nullptr || element->getText() == "") {
+        char uuid_str[37];
         uuid_t uuid;
-                
+
         uuid_generate(uuid);
         uuid_unparse(uuid, uuid_str);
 
-        log_info("UUID generated: %s\n", uuid_str);
-       
+        log_debug("UUID generated: %s\n", uuid_str);
+
         getOption(_("/server/udn"), _("uuid:") + uuid_str);
 
         need_to_save = true;
     }
-    
+
     if (need_to_save)
         save();
 }
@@ -2304,7 +2107,7 @@ void ConfigManager::prepare_path(String xpath, bool needDir, bool existenceUnnee
     check_path_ex(temp, needDir, existenceUnneeded);
 
     Ref<Element> script = getElement(xpath);
-    if (script != nil)
+    if (script != nullptr)
         script->setText(temp);
 }
 
@@ -2315,24 +2118,20 @@ void ConfigManager::save()
 
 void ConfigManager::save_text(String filename, String content)
 {
-    FILE *file = fopen(filename.c_str(), "wb");
-    if (file == NULL)
-    {
-        throw _Exception(_("could not open file ") +
-                        filename + " for writing : " + strerror(errno));
+    FILE* file = fopen(filename.c_str(), "wb");
+    if (file == nullptr) {
+        throw _Exception(_("could not open file ") + filename + " for writing : " + strerror(errno));
     }
-    
+
     size_t bytesWritten = fwrite(XML_HEADER, sizeof(char),
-                              strlen(XML_HEADER), file);
-    
+        strlen(XML_HEADER), file);
+
     bytesWritten = fwrite(content.c_str(), sizeof(char),
-                              content.length(), file);
-    if (bytesWritten < (size_t)content.length())
-    {
-        throw _Exception(_("could not write to config file ") +
-                        filename + " : " + strerror(errno));
+        content.length(), file);
+    if (bytesWritten < (size_t)content.length()) {
+        throw _Exception(_("could not write to config file ") + filename + " : " + strerror(errno));
     }
-    
+
     fclose(file);
 }
 
@@ -2342,61 +2141,55 @@ void ConfigManager::load(String filename)
     Ref<Parser> parser(new Parser());
     rootDoc = parser->parseFile(filename);
     root = rootDoc->getRoot();
-    
-    if (rootDoc == nil)
-    {
+
+    if (rootDoc == nullptr) {
         throw _Exception(_("Unable to parse server configuration!"));
     }
 }
 
 String ConfigManager::getOption(String xpath, String def)
-{      
+{
     Ref<XPath> rootXPath(new XPath(root));
     String value = rootXPath->getText(xpath);
     if (string_ok(value))
         return trim_string(value);
 
     log_debug("Config: option not found: %s using default value: %s\n",
-           xpath.c_str(), def.c_str());
-    
+        xpath.c_str(), def.c_str());
+
     String pathPart = XPath::getPathPart(xpath);
     String axisPart = XPath::getAxisPart(xpath);
 
-    Ref<Array<StringBase> >parts = split_string(pathPart, '/');
-    
+    Ref<Array<StringBase> > parts = split_string(pathPart, '/');
+
     Ref<Element> cur = root;
-    String attr = nil;
-    
+    String attr = nullptr;
+
     int i;
     Ref<Element> child;
-    for (i = 0; i < parts->size(); i++)
-    {
+    for (i = 0; i < parts->size(); i++) {
         String part = parts->get(i);
         child = cur->getChildByName(part);
-        if (child == nil)
+        if (child == nullptr)
             break;
         cur = child;
     }
     // here cur is the last existing element in the path
-    for (; i < parts->size(); i++)
-    {
+    for (; i < parts->size(); i++) {
         String part = parts->get(i);
         child = Ref<Element>(new Element(part));
         cur->appendElementChild(child);
         cur = child;
     }
-    
-    if (axisPart != nil)
-    {
+
+    if (axisPart != nullptr) {
         String axis = XPath::getAxis(axisPart);
         String spec = XPath::getSpec(axisPart);
-        if (axis != "attribute")
-        {
+        if (axis != "attribute") {
             throw _Exception(_("ConfigManager::getOption: only attribute:: axis supported"));
         }
         cur->setAttribute(spec, def);
-    } 
-    else
+    } else
         cur->setText(def);
 
     return def;
@@ -2407,20 +2200,20 @@ int ConfigManager::getIntOption(String xpath, int def)
     String sDef;
 
     sDef = String::from(def);
-    
+
     String sVal = getOption(xpath, sDef);
     return sVal.toInt();
 }
 
 String ConfigManager::getOption(String xpath)
-{      
+{
     Ref<XPath> rootXPath(new XPath(root));
     String value = rootXPath->getText(xpath);
 
     /// \todo is this ok?
-//    if (string_ok(value))
-//        return value;
-    if (value != nil)
+    //    if (string_ok(value))
+    //        return value;
+    if (value != nullptr)
         return trim_string(value);
     throw _Exception(_("Config: option not found: ") + xpath);
 }
@@ -2432,37 +2225,31 @@ int ConfigManager::getIntOption(String xpath)
     return val;
 }
 
-
 Ref<Element> ConfigManager::getElement(String xpath)
-{      
+{
     Ref<XPath> rootXPath(new XPath(root));
     return rootXPath->getElement(xpath);
 }
 
 void ConfigManager::writeBookmark(String ip, String port)
 {
-    FILE    *f;
-    String  filename;
-    String  path;
-    String  data; 
-    int     size; 
-  
-    if (!getBoolOption(CFG_SERVER_UI_ENABLED))
-    {
+    FILE* f;
+    String filename;
+    String path;
+    String data;
+    int size;
+
+    if (!getBoolOption(CFG_SERVER_UI_ENABLED)) {
         data = http_redirect_to(ip, port, _("disabled.html"));
-    }
-    else
-    {
+    } else {
         data = http_redirect_to(ip, port);
     }
 
     filename = getOption(CFG_SERVER_BOOKMARK_FILE);
     path = construct_path(filename);
-    
-        
+
     f = fopen(path.c_str(), "w");
-    if (f == NULL)
-    {
+    if (f == nullptr) {
         throw _Exception(_("writeBookmark: failed to open: ") + path);
     }
 
@@ -2471,7 +2258,6 @@ void ConfigManager::writeBookmark(String ip, String port)
 
     if (size < data.length())
         throw _Exception(_("write_Bookmark: failed to write to: ") + path);
-
 }
 
 String ConfigManager::checkOptionString(String xpath)
@@ -2489,20 +2275,15 @@ Ref<Dictionary> ConfigManager::createDictionaryFromNodeset(Ref<Element> element,
     String key;
     String value;
 
-    if (element != nil)
-    {
-        for (int i = 0; i < element->elementChildCount(); i++)
-        {
+    if (element != nullptr) {
+        for (int i = 0; i < element->elementChildCount(); i++) {
             Ref<Element> child = element->getElementChild(i);
-            if (child->getName() == nodeName)
-            {
+            if (child->getName() == nodeName) {
                 key = child->getAttribute(keyAttr);
                 value = child->getAttribute(valAttr);
 
-                if (string_ok(key) && string_ok(value))
-                {
-                    if (tolower)
-                    {
+                if (string_ok(key) && string_ok(value)) {
+                    if (tolower) {
                         key = key.toLower();
                     }
                     dict->put(key, value);
@@ -2527,8 +2308,8 @@ Ref<TranscodingProfileList> ConfigManager::createTranscodingProfileListFromNodes
     zmm::String param;
 
     Ref<TranscodingProfileList> list(new TranscodingProfileList());
-    if (element == nil)
-        return list;     
+    if (element == nullptr)
+        return list;
 
     Ref<Array<DictionaryElement> > mt_mappings(new Array<DictionaryElement>());
 
@@ -2536,23 +2317,17 @@ Ref<TranscodingProfileList> ConfigManager::createTranscodingProfileListFromNodes
     String pname;
 
     mtype_profile = element->getChildByName(_("mimetype-profile-mappings"));
-    if (mtype_profile != nil)
-    {
-        for (int e = 0; e < mtype_profile->elementChildCount(); e++)
-        {
+    if (mtype_profile != nullptr) {
+        for (int e = 0; e < mtype_profile->elementChildCount(); e++) {
             Ref<Element> child = mtype_profile->getElementChild(e);
-            if (child->getName() == "transcode")
-            {
+            if (child->getName() == "transcode") {
                 mt = child->getAttribute(_("mimetype"));
                 pname = child->getAttribute(_("using"));
 
-                if (string_ok(mt) && string_ok(pname))
-                {
+                if (string_ok(mt) && string_ok(pname)) {
                     Ref<DictionaryElement> del(new DictionaryElement(mt, pname));
                     mt_mappings->append(del);
-                }
-                else
-                {
+                } else {
                     throw _Exception(_("error in configuration: invalid or missing mimetype to profile mapping"));
                 }
             }
@@ -2560,11 +2335,10 @@ Ref<TranscodingProfileList> ConfigManager::createTranscodingProfileListFromNodes
     }
 
     Ref<Element> profiles = element->getChildByName(_("profiles"));
-    if (profiles == nil)
+    if (profiles == nullptr)
         return list;
 
-    for (int i = 0; i < profiles->elementChildCount(); i++)
-    {
+    for (int i = 0; i < profiles->elementChildCount(); i++) {
         Ref<Element> child = profiles->getElementChild(i);
         if (child->getName() != "profile")
             continue;
@@ -2572,14 +2346,14 @@ Ref<TranscodingProfileList> ConfigManager::createTranscodingProfileListFromNodes
         param = child->getAttribute(_("enabled"));
         if (!validateYesNo(param))
             throw _Exception(_("Error in config file: incorrect parameter "
-                           "for <profile enabled=\"\" /> attribute"));
+                               "for <profile enabled=\"\" /> attribute"));
 
         if (param == "no")
             continue;
 
         param = child->getAttribute(_("type"));
         if (!string_ok(param))
-             throw _Exception(_("error in configuration: missing transcoding type in profile"));
+            throw _Exception(_("error in configuration: missing transcoding type in profile"));
 
         if (param == "external")
             tr_type = TR_External;
@@ -2601,24 +2375,21 @@ Ref<TranscodingProfileList> ConfigManager::createTranscodingProfileListFromNodes
             throw _Exception(_("error in configuration: invalid target mimetype in transcoding profile"));
         prof->setTargetMimeType(param);
 
-        if (child->getChildByName(_("resolution")) != nil)
-        {
+        if (child->getChildByName(_("resolution")) != nullptr) {
             param = child->getChildText(_("resolution"));
-            if (string_ok(param))
-            {
+            if (string_ok(param)) {
                 if (check_resolution(param))
                     prof->addAttribute(MetadataHandler::getResAttrName(R_RESOLUTION), param);
             }
         }
 
         Ref<Element> avi_fcc = child->getChildByName(_("avi-fourcc-list"));
-        if (avi_fcc != nil)
-        {
+        if (avi_fcc != nullptr) {
             String mode = avi_fcc->getAttribute(_("mode"));
             if (!string_ok(mode))
                 throw _Exception(_("error in configuration: avi-fourcc-list requires a valid \"mode\" attribute"));
 
-            avi_fourcc_listmode_t fcc_mode; 
+            avi_fourcc_listmode_t fcc_mode;
             if (mode == "ignore")
                 fcc_mode = FCC_Ignore;
             else if (mode == "process")
@@ -2628,11 +2399,9 @@ Ref<TranscodingProfileList> ConfigManager::createTranscodingProfileListFromNodes
             else
                 throw _Exception(_("error in configuration: invalid mode given for avi-fourcc-list: \"") + mode + _("\""));
 
-            if (fcc_mode != FCC_None)
-            {
+            if (fcc_mode != FCC_None) {
                 Ref<Array<StringBase> > fcc_list(new Array<StringBase>());
-                for (int f = 0; f < avi_fcc->elementChildCount(); f++)
-                {
+                for (int f = 0; f < avi_fcc->elementChildCount(); f++) {
                     Ref<Element> fourcc = avi_fcc->getElementChild(f);
                     if (fourcc->getName() != "fourcc")
                         continue;
@@ -2647,8 +2416,7 @@ Ref<TranscodingProfileList> ConfigManager::createTranscodingProfileListFromNodes
             }
         }
 
-        if (child->getChildByName(_("accept-url")) != nil)
-        {
+        if (child->getChildByName(_("accept-url")) != nullptr) {
             param = child->getChildText(_("accept-url"));
             if (!validateYesNo(param))
                 throw _Exception(_("Error in config file: incorrect parameter "
@@ -2659,15 +2427,13 @@ Ref<TranscodingProfileList> ConfigManager::createTranscodingProfileListFromNodes
                 prof->setAcceptURL(false);
         }
 
-        if (child->getChildByName(_("sample-frequency")) != nil)
-        {
+        if (child->getChildByName(_("sample-frequency")) != nullptr) {
             param = child->getChildText(_("sample-frequency"));
             if (param == "source")
                 prof->setSampleFreq(SOURCE);
             else if (param == "off")
                 prof->setSampleFreq(OFF);
-            else
-            {
+            else {
                 int freq = param.toInt();
                 if (freq <= 0)
                     throw _Exception(_("Error in config file: incorrect "
@@ -2678,15 +2444,13 @@ Ref<TranscodingProfileList> ConfigManager::createTranscodingProfileListFromNodes
             }
         }
 
-        if (child->getChildByName(_("audio-channels")) != nil)
-        {
+        if (child->getChildByName(_("audio-channels")) != nullptr) {
             param = child->getChildText(_("audio-channels"));
             if (param == "source")
                 prof->setNumChannels(SOURCE);
             else if (param == "off")
                 prof->setNumChannels(OFF);
-            else
-            {
+            else {
                 int chan = param.toInt();
                 if (chan <= 0)
                     throw _Exception(_("Error in config file: incorrect "
@@ -2696,8 +2460,7 @@ Ref<TranscodingProfileList> ConfigManager::createTranscodingProfileListFromNodes
             }
         }
 
-        if (child->getChildByName(_("hide-original-resource")) != nil)
-        {
+        if (child->getChildByName(_("hide-original-resource")) != nullptr) {
             param = child->getChildText(_("hide-original-resource"));
             if (!validateYesNo(param))
                 throw _Exception(_("Error in config file: incorrect parameter "
@@ -2708,33 +2471,7 @@ Ref<TranscodingProfileList> ConfigManager::createTranscodingProfileListFromNodes
                 prof->setHideOriginalResource(false);
         }
 
-        if (child->getChildByName(_("dvd-only")) != nil)
-        {
-            param = child->getChildText(_("dvd-only"));
-            if (!validateYesNo(param))
-                throw _Exception(_("Error in config file: incorrect parameter "
-                                   "for <dvd-only> tag"));
-            if (param == "yes")
-                prof->setOnlyDVD(true);
-            else
-                prof->setOnlyDVD(false);
-        }
-
-        if (child->getChildByName(_("accept-dvd-mpeg")) != nil)
-        {
-            param = child->getChildText(_("accept-dvd-mpeg"));
-            if (!validateYesNo(param))
-                throw _Exception(_("Error in config file: incorrect parameter "
-                                   "for <accept-dvd-mpeg> tag"));
-            if (param == "yes")
-                prof->setTheora(true);
-            else
-                prof->setTheora(false);
- 
-        }
-
-        if (child->getChildByName(_("thumbnail")) != nil)
-        {
+        if (child->getChildByName(_("thumbnail")) != nullptr) {
             param = child->getChildText(_("thumbnail"));
             if (!validateYesNo(param))
                 throw _Exception(_("Error in config file: incorrect parameter "
@@ -2745,12 +2482,11 @@ Ref<TranscodingProfileList> ConfigManager::createTranscodingProfileListFromNodes
                 prof->setThumbnail(false);
         }
 
-        if (child->getChildByName(_("first-resource")) != nil)
-        {
+        if (child->getChildByName(_("first-resource")) != nullptr) {
             param = child->getChildText(_("first-resource"));
             if (!validateYesNo(param))
                 throw _Exception(_("Error in config file: incorrect parameter "
-                            "for <profile first-resource=\"\" /> attribute"));
+                                   "for <profile first-resource=\"\" /> attribute"));
 
             if (param == "yes")
                 prof->setFirstResource(true);
@@ -2758,12 +2494,11 @@ Ref<TranscodingProfileList> ConfigManager::createTranscodingProfileListFromNodes
                 prof->setFirstResource(false);
         }
 
-        if (child->getChildByName(_("use-chunked-encoding")) != nil)
-        {
+        if (child->getChildByName(_("use-chunked-encoding")) != nullptr) {
             param = child->getChildText(_("use-chunked-encoding"));
             if (!validateYesNo(param))
                 throw _Exception(_("Error in config file: incorrect parameter "
-                            "for use-chunked-encoding tag"));
+                                   "for use-chunked-encoding tag"));
 
             if (param == "yes")
                 prof->setChunked(true);
@@ -2772,309 +2507,242 @@ Ref<TranscodingProfileList> ConfigManager::createTranscodingProfileListFromNodes
         }
 
         Ref<Element> sub = child->getChildByName(_("agent"));
-        if (sub == nil)
+        if (sub == nullptr)
             throw _Exception(_("error in configuration: transcoding "
-                               "profile \"") + prof->getName() + 
-                               "\" is missing the <agent> option");
+                               "profile \"")
+                + prof->getName() + "\" is missing the <agent> option");
 
         param = sub->getAttribute(_("command"));
         if (!string_ok(param))
-            throw _Exception(_("error in configuration: transcoding " 
-                               "profile \"") + prof->getName() + 
-                               "\" has an invalid command setting");
+            throw _Exception(_("error in configuration: transcoding "
+                               "profile \"")
+                + prof->getName() + "\" has an invalid command setting");
         prof->setCommand(param);
 
         String tmp_path;
-        if (param.startsWith(_(_DIR_SEPARATOR)))
-        {
+        if (param.startsWith(_(_DIR_SEPARATOR))) {
             if (!check_path(param))
                 throw _Exception(_("error in configuration, transcoding "
-                                   "profile \"") + prof->getName() +
-                              "\" could not find transcoding command " + param);
+                                   "profile \"")
+                    + prof->getName() + "\" could not find transcoding command " + param);
             tmp_path = param;
-        }
-        else
-        {
+        } else {
             tmp_path = find_in_path(param);
             if (!string_ok(tmp_path))
                 throw _Exception(_("error in configuration, transcoding "
-                                   "profile \"") + prof->getName() + 
-                      "\" could not find transcoding command " + param +
-                      " in $PATH");
+                                   "profile \"")
+                    + prof->getName() + "\" could not find transcoding command " + param + " in $PATH");
         }
 
         int err = 0;
         if (!is_executable(tmp_path, &err))
             throw _Exception(_("error in configuration, transcoding "
-                               "profile ") + prof->getName() + 
-                               ": transcoder " + param + 
-                               "is not executable - " + strerror(err));
+                               "profile ")
+                + prof->getName() + ": transcoder " + param + "is not executable - " + strerror(err));
 
         param = sub->getAttribute(_("arguments"));
         if (!string_ok(param))
-            throw _Exception(_("error in configuration: transcoding profile ") +
-                    prof->getName() + " has an empty argument string");
+            throw _Exception(_("error in configuration: transcoding profile ") + prof->getName() + " has an empty argument string");
 
         prof->setArguments(param);
 
-        sub = child->getChildByName(_("buffer")); 
-        if (sub == nil)
+        sub = child->getChildByName(_("buffer"));
+        if (sub == nullptr)
             throw _Exception(_("error in configuration: transcoding "
-                               "profile \"") + prof->getName() + 
-                               "\" is missing the <buffer> option");
+                               "profile \"")
+                + prof->getName() + "\" is missing the <buffer> option");
 
         param = sub->getAttribute(_("size"));
         if (!string_ok(param))
             throw _Exception(_("error in configuration: transcoding "
-                               "profile \"") + prof->getName() + 
-                               "\" <buffer> tag is missing the size attribute");
+                               "profile \"")
+                + prof->getName() + "\" <buffer> tag is missing the size attribute");
         itmp = param.toInt();
         if (itmp < 0)
             throw _Exception(_("error in configuration: transcoding "
-                               "profile \"") + prof->getName() + 
-                               "\" buffer size can not be negative");
+                               "profile \"")
+                + prof->getName() + "\" buffer size can not be negative");
         bs = itmp;
 
         param = sub->getAttribute(_("chunk-size"));
         if (!string_ok(param))
             throw _Exception(_("error in configuration: transcoding "
-                               "profile \"") + prof->getName() + 
-                               "\" <buffer> tag is missing the chunk-size " 
-                               "attribute");
+                               "profile \"")
+                + prof->getName() + "\" <buffer> tag is missing the chunk-size "
+                                    "attribute");
         itmp = param.toInt();
         if (itmp < 0)
             throw _Exception(_("error in configuration: transcoding "
-                               "profile \"") + prof->getName() + 
-                               "\" chunk size can not be negative");
+                               "profile \"")
+                + prof->getName() + "\" chunk size can not be negative");
         cs = itmp;
 
         if (cs > bs)
             throw _Exception(_("error in configuration: transcoding "
-                               "profile \"") + prof->getName() + 
-                               "\" chunk size can not be greater than "
-                               "buffer size");
+                               "profile \"")
+                + prof->getName() + "\" chunk size can not be greater than "
+                                    "buffer size");
 
         param = sub->getAttribute(_("fill-size"));
         if (!string_ok(param))
             throw _Exception(_("error in configuration: transcoding "
-                               "profile \"") + prof->getName() + 
-                               "\" <buffer> tag is missing the fill-size "
-                               "attribute");
+                               "profile \"")
+                + prof->getName() + "\" <buffer> tag is missing the fill-size "
+                                    "attribute");
         itmp = param.toInt();
         if (i < 0)
             throw _Exception(_("error in configuration: transcoding "
-                               "profile \"") + prof->getName() + 
-                               "\" fill size can not be negative");
+                               "profile \"")
+                + prof->getName() + "\" fill size can not be negative");
         fs = itmp;
 
         if (fs > bs)
             throw _Exception(_("error in configuration: transcoding "
-                               "profile \"") + prof->getName() + 
-                               "\" fill size can not be greater than "
-                               "buffer size");
+                               "profile \"")
+                + prof->getName() + "\" fill size can not be greater than "
+                                    "buffer size");
 
         prof->setBufferOptions(bs, cs, fs);
 
-        if (mtype_profile == nil)
-        {
+        if (mtype_profile == nullptr) {
             throw _Exception(_("error in configuration: transcoding "
                                "profiles exist, but no mimetype to profile "
                                "mappings specified"));
         }
 
-        for (int k = 0; k < mt_mappings->size(); k++)
-        {
-            if (mt_mappings->get(k)->getValue() == prof->getName())
-            {
+        for (int k = 0; k < mt_mappings->size(); k++) {
+            if (mt_mappings->get(k)->getValue() == prof->getName()) {
                 list->add(mt_mappings->get(k)->getKey(), prof);
                 set = true;
             }
         }
 
         if (!set)
-             throw _Exception(_("error in configuration: you specified" 
-                                "a mimetype to transcoding profile mapping, "
-                                "but no match for profile \"") + 
-                                prof->getName() + "\" exists");
+            throw _Exception(_("error in configuration: you specified"
+                               "a mimetype to transcoding profile mapping, "
+                               "but no match for profile \"")
+                + prof->getName() + "\" exists");
         else
             set = false;
     }
 
     return list;
 }
-#endif//TRANSCODING
+#endif //TRANSCODING
 
-Ref<AutoscanList> ConfigManager::createAutoscanListFromNodeset(zmm::Ref<mxml::Element> element, scan_mode_t scanmode)
+Ref<AutoscanList> ConfigManager::createAutoscanListFromNodeset(zmm::Ref<mxml::Element> element, ScanMode scanmode)
 {
     Ref<AutoscanList> list(new AutoscanList());
-    String location;
-    String temp;
-    scan_level_t level;
-    scan_mode_t mode;
-    bool recursive;
-    bool hidden;
-    unsigned int interval;
-  
-    if (element == nil)
+
+    if (element == nullptr)
         return list;
 
-    for (int i = 0; i < element->elementChildCount(); i++)
-    {
-        hidden = false;
-        recursive = false;
+    for (int i = 0; i < element->elementChildCount(); i++) {
 
         Ref<Element> child = element->getElementChild(i);
-        if (child->getName() == "directory")
-        {
-            location = child->getAttribute(_("location"));
-            if (!string_ok(location))
-            {
-                throw _Exception(_("autoscan directory with invalid location!\n"));
-            }
 
-            try
-            {
-                location = normalizePath(location);
-            }
-            catch (Exception e)
-            {
-                throw _Exception(_("autoscan directory \"") + 
-                        location + "\": " +  e.getMessage());
-            }
+        // We only want directories
+        if (child->getName() != "directory")
+            continue;
 
-            if (check_path(location, false))
-            {
-                throw _Exception(_("autoscan ") + location + 
-                                  " - not a directory!");
-            }
-            
-            temp = child->getAttribute(_("mode"));
-            if (!string_ok(temp) || ((temp != "timed") && (temp != "inotify")))
-            {
-                throw _Exception(_("autoscan directory ") + location + 
-                        ": mode attribute is missing or invalid");
-            }
-            else if (temp == "timed")
-            {
-                mode = TimedScanMode;
-            }
-            else
-                mode = InotifyScanMode;
-
-            if (mode != scanmode)
-                continue; // skip scan modes that we are not interested in (content manager needs one mode type per array)
-
-            interval = 0;
-            if (mode == TimedScanMode)
-            {
-                temp =  child->getAttribute(_("level"));
-                if (!string_ok(temp))
-                {
-                    throw _Exception(_("autoscan directory ") + 
-                            location + 
-                            ": level attribute is missing or invalid");
-                }
-                else
-                {
-                    if (temp == "basic")
-                        level = BasicScanLevel;
-                    else if (temp == "full")
-                        level = FullScanLevel;
-                    else
-                    {
-                        throw _Exception(_("autoscan directory ")
-                                         + location + ": level attribute " +
-                                         temp + "is invalid");
-                    }
-                }
+        String location = child->getAttribute(_("location"));
+        if (!string_ok(location)) {
+            throw _Exception(_("autoscan directory with invalid location!\n"));
+        }
 
-                temp = child->getAttribute(_("interval"));
-                if (!string_ok(temp))
-                {
-                    throw _Exception(_("autoscan directory ") 
-                            + location +
-                           ": interval attribute is required for timed mode");
-                }
+        try {
+            location = normalizePath(location);
+        } catch (const Exception& e) {
+            throw _Exception(_("autoscan directory \"") + location + "\": " + e.getMessage());
+        }
 
-                interval = temp.toUInt();
+        if (check_path(location, false)) {
+            throw _Exception(_("autoscan ") + location + " - not a directory!");
+        }
 
-                if (interval == 0)
-                {
-                    throw _Exception(_("autoscan directory ") + 
-                            location + ": invalid interval attribute");
-                    continue;
+        ScanMode mode;
+        String temp = child->getAttribute(_("mode"));
+        if (!string_ok(temp) || ((temp != "timed") && (temp != "inotify"))) {
+            throw _Exception(_("autoscan directory ") + location + ": mode attribute is missing or invalid");
+        } else if (temp == "timed") {
+            mode = ScanMode::Timed;
+        } else {
+            mode = ScanMode::INotify;
+        }
+
+        if (mode != scanmode) {
+            continue; // skip scan modes that we are not interested in (content manager needs one mode type per array)
+        }
+
+        unsigned int interval = 0;
+        ScanLevel level;
+
+
+        if (mode == ScanMode::Timed) {
+            temp = child->getAttribute(_("level"));
+            if (!string_ok(temp)) {
+                throw _Exception(_("autoscan directory ") + location + ": level attribute is missing or invalid");
+            } else {
+                if (temp == "basic")
+                    level = ScanLevel::Basic;
+                else if (temp == "full")
+                    level = ScanLevel::Full;
+                else {
+                    throw _Exception(_("autoscan directory ")
+                        + location + ": level attribute " + temp + "is invalid");
                 }
             }
-            // level is irrelevant for inotify scan, nevertheless we will set
-            // it to somthing valid
-            else
-                level = FullScanLevel;
 
-            temp = child->getAttribute(_("recursive"));
-            if (!string_ok(temp))
-            {
-                throw _Exception(_("autoscan directory ") + location +
-                        ": recursive attribute is missing or invalid");
-            }
-            else
-            {
-               if (temp == "yes")
-                   recursive = true;
-               else if (temp == "no")
-                   recursive = false;
-               else
-               {
-                   throw _Exception(_("autoscan directory ") + location
-                          + ": recusrive attribute " + temp + " is invalid");
-               }
+            temp = child->getAttribute(_("interval"));
+            if (!string_ok(temp)) {
+                throw _Exception(_("autoscan directory ")
+                    + location + ": interval attribute is required for timed mode");
             }
 
-            temp = child->getAttribute(_("hidden-files"));
-            if (!string_ok(temp))
-            {
-                temp = getOption(_("/import/attribute::hidden-files"));
-            }
+            interval = temp.toUInt();
 
-            if (temp == "yes")
-                hidden = true;
-            else if (temp == "no")
-                hidden = false;
-            else
-            {
-                throw _Exception(_("autoscan directory ") + location +
-                            ": hidden attribute " + temp + " is invalid");
+            if (interval == 0) {
+                throw _Exception(_("autoscan directory ") + location + ": invalid interval attribute");
+                continue;
             }
+        } else {
+            // level is irrelevant for inotify scan, nevertheless we will set
+            // it to something valid
+            level = ScanLevel::Full;
+        }
 
-            temp = child->getAttribute(_("interval"));
-            interval = 0;
-            if (mode == TimedScanMode)
-            {
-                if (!string_ok(temp))
-                {
-                    throw _Exception(_("autoscan directory ") 
-                            + location +
-                           ": interval attribute is required for timed mode");
-                }
+        temp = child->getAttribute(_("recursive"));
+        if (!string_ok(temp))
+            throw _Exception(_("autoscan directory ") + location + ": recursive attribute is missing or invalid");
+
+        bool recursive;
+        if (temp == "yes")
+            recursive = true;
+        else if (temp == "no")
+            recursive = false;
+        else {
+            throw _Exception(_("autoscan directory ") + location
+                + ": recusrive attribute " + temp + " is invalid");
+        }
 
-                interval = temp.toUInt();
+        bool hidden;
+        temp = child->getAttribute(_("hidden-files"));
+        if (!string_ok(temp))
+            temp = getOption(_("/import/attribute::hidden-files"));
 
-                if (interval == 0)
-                {
-                    throw _Exception(_("autoscan directory ") + 
-                            location + ": invalid interval attribute");
-                }
-            }
-            
-            Ref<AutoscanDirectory> dir(new AutoscanDirectory(location, mode, level, recursive, true, -1, interval, hidden));
-            try
-            {
-                list->add(dir); 
-            }
-            catch (Exception e)
-            {
-                throw _Exception(_("Could not add ") + location + ": "
-                        + e.getMessage());
-            }
+        if (temp == "yes")
+            hidden = true;
+        else if (temp == "no")
+            hidden = false;
+        else
+            throw _Exception(_("autoscan directory ") + location + ": hidden attribute " + temp + " is invalid");
+
+        Ref<AutoscanDirectory> dir(new AutoscanDirectory(location, mode, level, recursive, true, -1, interval, hidden));
+        try {
+            list->add(dir);
+        } catch (const Exception& e) {
+            throw _Exception(_("Could not add ") + location + ": "
+                + e.getMessage());
         }
     }
 
@@ -3085,26 +2753,22 @@ void ConfigManager::dumpOptions()
 {
 #ifdef TOMBDEBUG
     log_debug("Dumping options!\n");
-    for (int i = 0; i < (int)CFG_MAX; i++)
-    {
-        try
-        {
+    for (int i = 0; i < (int)CFG_MAX; i++) {
+        try {
             log_debug("    Option %02d - %s\n", i,
-                    getOption((config_option_t)i).c_str());
+                getOption((config_option_t)i).c_str());
+        } catch (const Exception& e) {
         }
-        catch (Exception e) {}
-        try
-        {
+        try {
             log_debug(" IntOption %02d - %d\n", i,
-                    getIntOption((config_option_t)i));
+                getIntOption((config_option_t)i));
+        } catch (const Exception& e) {
         }
-        catch (Exception e) {}
-        try
-        {
+        try {
             log_debug("BoolOption %02d - %s\n", i,
-                    (getBoolOption((config_option_t)i) ? "true" : "false"));
+                (getBoolOption((config_option_t)i) ? "true" : "false"));
+        } catch (const Exception& e) {
         }
-        catch (Exception e) {}
     }
 #endif
 }
@@ -3114,13 +2778,10 @@ Ref<Array<StringBase> > ConfigManager::createArrayFromNodeset(Ref<mxml::Element>
     String attrValue;
     Ref<Array<StringBase> > arr(new Array<StringBase>());
 
-    if (element != nil)
-    {
-        for (int i = 0; i < element->elementChildCount(); i++)
-        {
+    if (element != nullptr) {
+        for (int i = 0; i < element->elementChildCount(); i++) {
             Ref<Element> child = element->getElementChild(i);
-            if (child->getName() == nodeName)
-            {
+            if (child->getName() == nodeName) {
                 attrValue = child->getAttribute(attrName);
 
                 if (string_ok(attrValue))
@@ -3133,20 +2794,32 @@ Ref<Array<StringBase> > ConfigManager::createArrayFromNodeset(Ref<mxml::Element>
 }
 
 // The validate function ensures that the array is completely filled!
-// None of the options->get() calls will ever return nil!
+// None of the options->get() calls will ever return nullptr!
 String ConfigManager::getOption(config_option_t option)
 {
-    return options->get(option)->getOption();
+    Ref<ConfigOption> r = options->get(option);
+    if (r.getPtr() == nullptr) {
+        throw _Exception(_("option not set"));
+    }
+    return r->getOption();
 }
 
 int ConfigManager::getIntOption(config_option_t option)
 {
-    return options->get(option)->getIntOption();
+    Ref<ConfigOption> o = options->get(option);
+    if (o.getPtr() == nullptr) {
+        throw _Exception(_("option not set"));
+    }
+    return o->getIntOption();
 }
 
 bool ConfigManager::getBoolOption(config_option_t option)
 {
-    return options->get(option)->getBoolOption();
+    Ref<ConfigOption> o = options->get(option);
+    if (o.getPtr() == nullptr) {
+        throw _Exception(_("option not set"));
+    }
+    return o->getBoolOption();
 }
 
 Ref<Dictionary> ConfigManager::getDictionaryOption(config_option_t option)
@@ -3185,37 +2858,21 @@ Ref<TranscodingProfileList> ConfigManager::getTranscodingProfileListOption(confi
 
 #ifdef ONLINE_SERVICES
 Ref<Array<Object> > ConfigManager::createServiceTaskList(service_type_t service,
-                                                         Ref<Element> element)
+    Ref<Element> element)
 {
     Ref<Array<Object> > arr(new Array<Object>());
 
-    if (element == nil)
+    if (element == nullptr)
         return arr;
 #ifdef YOUTUBE
-    if (service == OS_YouTube)
-    {
+    if (service == OS_YouTube) {
         Ref<YouTubeService> yt(new YouTubeService());
-        for (int i = 0; i < element->elementChildCount(); i++)
-        {
+        for (int i = 0; i < element->elementChildCount(); i++) {
             Ref<Object> option = yt->defineServiceTask(element->getElementChild(i), RefCast(options->get(CFG_ONLINE_CONTENT_YOUTUBE_RACY), Object));
             arr->append(option);
         }
     }
 #endif
-#ifdef WEBORAMA
-    if (service == OS_Weborama)
-    {
-        Ref<WeboramaService> wb(new WeboramaService());
-        for (int i = 0; i < element->elementChildCount(); i++)
-        {
-            // existence is checked in validate
-            Ref<Option> stropt(new Option(element->getAttribute(_("userid"))));
-            
-            Ref<Object> option = wb->defineServiceTask(element->getElementChild(i), RefCast(stropt, Object));
-            arr->append(option);
-        }
-    }
-#endif
     return arr;
 }
 #endif
diff --git a/src/config_manager.h b/src/config_manager.h
index e48d257..9915605 100644
--- a/src/config_manager.h
+++ b/src/config_manager.h
@@ -72,8 +72,8 @@ typedef enum
 #ifdef EXTERNAL_TRANSCODING
     CFG_SERVER_EXTEND_PROTOCOLINFO_CL_HACK,
 #endif
-#endif//EXTEND_PROTOCOLINFO
     CFG_SERVER_EXTEND_PROTOCOLINFO_SM_HACK,
+#endif//EXTEND_PROTOCOLINFO
     CFG_SERVER_HIDE_PC_DIRECTORY,
     CFG_SERVER_BOOKMARK_FILE,
     CFG_SERVER_CUSTOM_HTTP_HEADERS,
@@ -111,6 +111,8 @@ typedef enum
     CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_FILMSTRIP_OVERLAY,
     CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_WORKAROUND_BUGS,
     CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_IMAGE_QUALITY,
+    CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED,
+    CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR,
 #endif
     CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_ENABLED,
     CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_STRING_MODE_PREPEND,
@@ -132,9 +134,6 @@ typedef enum
     CFG_IMPORT_SCRIPTING_PLAYLIST_SCRIPT,
     CFG_IMPORT_SCRIPTING_PLAYLIST_SCRIPT_LINK_OBJECTS,
     CFG_IMPORT_SCRIPTING_IMPORT_SCRIPT,
-#ifdef HAVE_LIBDVDNAV
-    CFG_IMPORT_SCRIPTING_DVD_SCRIPT,
-#endif
 #endif // JS
     CFG_IMPORT_SCRIPTING_VIRTUAL_LAYOUT_TYPE,
 #ifdef HAVE_MAGIC
@@ -179,13 +178,6 @@ typedef enum
     CFG_ONLINE_CONTENT_SOPCAST_UPDATE_AT_START,
     CFG_ONLINE_CONTENT_SOPCAST_PURGE_AFTER,
 #endif
-#ifdef WEBORAMA 
-    CFG_ONLINE_CONTENT_WEBORAMA_ENABLED,
-    CFG_ONLINE_CONTENT_WEBORAMA_REFRESH,
-    CFG_ONLINE_CONTENT_WEBORAMA_UPDATE_AT_START,
-    CFG_ONLINE_CONTENT_WEBORAMA_PURGE_AFTER,
-    CFG_ONLINE_CONTENT_WEBORAMA_TASK_LIST,
-#endif
 #ifdef ATRAILERS
     CFG_ONLINE_CONTENT_ATRAILERS_ENABLED,
     CFG_ONLINE_CONTENT_ATRAILERS_REFRESH,
@@ -196,11 +188,13 @@ typedef enum
     CFG_MAX
 } config_option_t;
 
-class ConfigManager : public Singleton<ConfigManager>
+class ConfigManager : public Singleton<ConfigManager, std::mutex>
 {
 public:
     ConfigManager();
-    
+
+    void init() override;
+
     virtual ~ConfigManager();
     
     /// \brief Returns the name of the config file that was used to launch the server.
@@ -247,12 +241,13 @@ public:
 
     /// \brief sets static configuration parameters that will be used by
     /// when the ConfigManager class initializes
-    static void setStaticArgs(zmm::String _filename, zmm::String _userhome, 
+    static void setStaticArgs(zmm::String _filename, zmm::String _userhome,
                               zmm::String _config_dir = _(DEFAULT_CONFIG_HOME),
-                              zmm::String _prefix_dir = _(PACKAGE_DATADIR), 
-                              zmm::String _magic = nil,
-                              bool _debug_logging = false);
-    
+                              zmm::String _prefix_dir = _(PACKAGE_DATADIR),
+                              zmm::String _magic = nullptr,
+                              bool _debug_logging = false,
+                              zmm::String _ip = nullptr, zmm::String _interface = nullptr, int _port = -1);
+
     static bool isDebugLogging() { return debug_logging; };
 
     /// \brief Creates a html file that is a redirector to the current server i
@@ -284,6 +279,9 @@ protected:
     static zmm::String prefix_dir;
     static zmm::String magic;
     static bool debug_logging;
+    static zmm::String ip;
+    static zmm::String interface;
+    static int port;
 
     zmm::Ref<mxml::Document> rootDoc;
     zmm::Ref<mxml::Element> root;
@@ -345,11 +343,10 @@ protected:
     /// key:value paris: "1":"2", "3":"4"
     zmm::Ref<Dictionary> createDictionaryFromNodeset(zmm::Ref<mxml::Element> element, zmm::String nodeName, zmm::String keyAttr, zmm::String valAttr, bool tolower = false);
  
-    /// \brief Creates an aray of AutoscanDirectory objects from
-    /// an XML nodeset.
-    /// \param element starting element of the ndoeset.
+    /// \brief Creates an array of AutoscanDirectory objects from a XML nodeset.
+    /// \param element starting element of the nodeset.
     /// \param scanmode add only directories with the specified scanmode to the array
-    zmm::Ref<AutoscanList> createAutoscanListFromNodeset(zmm::Ref<mxml::Element> element, scan_mode_t scanmode);
+    zmm::Ref<AutoscanList> createAutoscanListFromNodeset(zmm::Ref<mxml::Element> element, ScanMode scanmode);
   
 #ifdef EXTERNAL_TRANSCODING
     /// \brief Creates ab aray of TranscodingProfile objects from an XML 
diff --git a/src/config_options.h b/src/config_options.h
index b9cf777..1939f89 100644
--- a/src/config_options.h
+++ b/src/config_options.h
@@ -33,7 +33,8 @@
 #ifndef __CONFIG_OPTIONS_H__
 #define __CONFIG_OPTIONS_H__
 
-#include "zmmf/zmmf.h"
+#include <assert.h>
+#include "zmm/zmmf.h"
 #include "exceptions.h"
 #include "autoscan.h"
 #include "object_dictionary.h"
@@ -47,57 +48,48 @@ class ConfigOption : public zmm::Object
 public:
     virtual zmm::String getOption()
     {
-        assert(0);
         throw _Exception(_("Wrong option type"));
     };
 
     virtual int getIntOption()
     {
-        assert(0);
         throw _Exception(_("Wrong option type"));
     };
 
     virtual bool getBoolOption()
     {
-        assert(0);
         throw _Exception(_("Wrong option type"));
     };
 
 
     virtual zmm::Ref<Dictionary> getDictionaryOption()
     {
-        assert(0);
         throw _Exception(_("Wrong option type"));
     };
 
     virtual zmm::Ref<AutoscanList> getAutoscanListOption()
     {
-        assert(0);
         throw _Exception(_("Wrong option type"));
     };
 
     virtual zmm::Ref<zmm::Array<zmm::StringBase> > getStringArrayOption()
     {
-        assert(0);
         throw _Exception(_("Wrong option type"));
     };
 #ifdef EXTERNAL_TRANSCODING
     virtual zmm::Ref<TranscodingProfileList> getTranscodingProfileListOption()
     {
-        assert(0);
         throw _Exception(_("Wrong option type"));
     };
 #endif
 #ifdef ONLINE_SERVICES
     virtual zmm::Ref<zmm::Array<zmm::Object> > getObjectArrayOption()
     {
-        assert(0);
         throw _Exception(_("Wrong option type"));
     }
 #endif
     virtual zmm::Ref<ObjectDictionary<zmm::Object> > getObjectDictionaryOption()
     {
-        assert(0);
         throw _Exception(_("Wrong option type"));
     }
 };
diff --git a/src/content_manager.cc b/src/content_manager.cc
index 4400169..3bc6c69 100644
--- a/src/content_manager.cc
+++ b/src/content_manager.cc
@@ -29,60 +29,52 @@
 
 /// \file content_manager.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <cerrno>
+#include <cstring>
 #include <dirent.h>
-#include <errno.h>
-#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #include <unistd.h>
 
-#include "tools.h"
-#include "rexp.h"
-#include "content_manager.h"
 #include "config_manager.h"
-#include "update_manager.h"
-#include "string_converter.h"
+#include "content_manager.h"
+#include "filesystem.h"
+#include "layout/fallback_layout.h"
 #include "metadata_handler.h"
+#include "rexp.h"
 #include "session_manager.h"
+#include "string_converter.h"
 #include "timer.h"
-#include "layout/fallback_layout.h"
-#include "filesystem.h"
+#include "tools.h"
+#include "update_manager.h"
 
 #ifdef HAVE_JS
-    #include "layout/js_layout.h"
+#include "layout/js_layout.h"
 #endif
 
 #ifdef EXTERNAL_TRANSCODING
-    #include "process.h"
+#include "process.h"
 #endif
 
 #ifdef YOUTUBE
-    #include "youtube_service.h"
-    #include <time.h>
+#include "youtube_service.h"
+#include <ctime>
 #endif
 
 #ifdef SOPCAST
-    #include "sopcast_service.h"
-#endif
-
-#ifdef WEBORAMA
-    #include "weborama_service.h"
+#include "sopcast_service.h"
 #endif
 
 #ifdef ATRAILERS
-    #include "atrailers_service.h"
+#include "atrailers_service.h"
 #endif
 
 #ifdef ONLINE_SERVICES
-    #include "task_processor.h"
+#include "task_processor.h"
 #endif
 
-#define DEFAULT_DIR_CACHE_CAPACITY  10
-#define CM_INITIAL_QUEUE_SIZE       20
+#define DEFAULT_DIR_CACHE_CAPACITY 10
+#define CM_INITIAL_QUEUE_SIZE 20
 
 #ifdef HAVE_MAGIC
 // for older versions of filemagic
@@ -90,16 +82,15 @@ extern "C" {
 #include <magic.h>
 }
 
-struct magic_set *ms = NULL;
+struct magic_set* ms = nullptr;
 #endif
 
 using namespace zmm;
 using namespace mxml;
+using namespace std;
 
 #define MIMETYPE_REGEXP "^([a-z0-9_-]+/[a-z0-9_-]+)"
 
-SINGLETON_MUTEX(ContentManager, true);
-
 static String get_filename(String path)
 {
     if (path.charAt(path.length() - 1) == DIR_SEPARATOR) // cut off trailing slash
@@ -111,10 +102,9 @@ static String get_filename(String path)
         return path.substring(pos + 1);
 }
 
-ContentManager::ContentManager() : TimerSubscriberSingleton<ContentManager>()
+ContentManager::ContentManager()
 {
     int i;
-    cond = Ref<Cond>(new Cond(mutex));
     ignore_unknown_extensions = false;
     extension_map_case_sensitive = false;
 
@@ -122,119 +112,98 @@ ContentManager::ContentManager() : TimerSubscriberSingleton<ContentManager>()
     working = false;
     shutdownFlag = false;
     layout_enabled = false;
-    
+
     acct = Ref<CMAccounting>(new CMAccounting());
     taskQueue1 = Ref<ObjectQueue<GenericTask> >(new ObjectQueue<GenericTask>(CM_INITIAL_QUEUE_SIZE));
-    taskQueue2 = Ref<ObjectQueue<GenericTask> >(new ObjectQueue<GenericTask>(CM_INITIAL_QUEUE_SIZE));    
-    
+    taskQueue2 = Ref<ObjectQueue<GenericTask> >(new ObjectQueue<GenericTask>(CM_INITIAL_QUEUE_SIZE));
+
     Ref<ConfigManager> cm = ConfigManager::getInstance();
-    Ref<Element> tmpEl;  
-    
-    // loading extension - mimetype map  
+    Ref<Element> tmpEl;
+
+    // loading extension - mimetype map
     // we can always be sure to get a valid element because everything was prepared by the config manager
-    extension_mimetype_map = 
-        cm->getDictionaryOption(CFG_IMPORT_MAPPINGS_EXTENSION_TO_MIMETYPE_LIST);
+    extension_mimetype_map = cm->getDictionaryOption(CFG_IMPORT_MAPPINGS_EXTENSION_TO_MIMETYPE_LIST);
 
     ignore_unknown_extensions = cm->getBoolOption(CFG_IMPORT_MAPPINGS_IGNORE_UNKNOWN_EXTENSIONS);
 
-    if (ignore_unknown_extensions && (extension_mimetype_map->size() == 0))
-    {
+    if (ignore_unknown_extensions && (extension_mimetype_map->size() == 0)) {
         log_warning("Ignore unknown extensions set, but no mappings specified\n");
         log_warning("Please review your configuration!\n");
         ignore_unknown_extensions = false;
     }
-  
+
     extension_map_case_sensitive = cm->getBoolOption(CFG_IMPORT_MAPPINGS_EXTENSION_TO_MIMETYPE_CASE_SENSITIVE);
 
-    mimetype_upnpclass_map = 
-       cm->getDictionaryOption(CFG_IMPORT_MAPPINGS_MIMETYPE_TO_UPNP_CLASS_LIST);
-  
-    mimetype_contenttype_map = 
-      cm->getDictionaryOption(CFG_IMPORT_MAPPINGS_MIMETYPE_TO_CONTENTTYPE_LIST);
-    Ref<AutoscanList> config_timed_list = 
-        cm->getAutoscanListOption(CFG_IMPORT_AUTOSCAN_TIMED_LIST);
+    mimetype_upnpclass_map = cm->getDictionaryOption(CFG_IMPORT_MAPPINGS_MIMETYPE_TO_UPNP_CLASS_LIST);
 
-    for (i = 0; i < config_timed_list->size(); i++)
-    {
+    mimetype_contenttype_map = cm->getDictionaryOption(CFG_IMPORT_MAPPINGS_MIMETYPE_TO_CONTENTTYPE_LIST);
+    Ref<AutoscanList> config_timed_list = cm->getAutoscanListOption(CFG_IMPORT_AUTOSCAN_TIMED_LIST);
+
+    for (i = 0; i < config_timed_list->size(); i++) {
         Ref<AutoscanDirectory> dir = config_timed_list->get(i);
-        if (dir != nil)
-        {
+        if (dir != nullptr) {
             String path = dir->getLocation();
-            if (check_path(path, true))
-            {
+            if (check_path(path, true)) {
                 dir->setObjectID(ensurePathExistence(path));
             }
         }
     }
 
     Ref<Storage> storage = Storage::getInstance();
-    storage->updateAutoscanPersistentList(TimedScanMode, config_timed_list);
-    autoscan_timed = storage->getAutoscanList(TimedScanMode);
+    storage->updateAutoscanPersistentList(ScanMode::Timed, config_timed_list);
+    autoscan_timed = storage->getAutoscanList(ScanMode::Timed);
 
 #ifdef HAVE_INOTIFY
-    if (cm->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY))
-    {
-        Ref<AutoscanList> config_inotify_list = 
-            cm->getAutoscanListOption(CFG_IMPORT_AUTOSCAN_INOTIFY_LIST);
+    if (cm->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY)) {
+        Ref<AutoscanList> config_inotify_list = cm->getAutoscanListOption(CFG_IMPORT_AUTOSCAN_INOTIFY_LIST);
 
-        for (i = 0; i < config_inotify_list->size(); i++)
-        {
+        for (i = 0; i < config_inotify_list->size(); i++) {
             Ref<AutoscanDirectory> dir = config_inotify_list->get(i);
-            if (dir != nil)
-            {
+            if (dir != nullptr) {
                 String path = dir->getLocation();
-                if (check_path(path, true))
-                {
+                if (check_path(path, true)) {
                     dir->setObjectID(ensurePathExistence(path));
                 }
             }
         }
 
-        storage->updateAutoscanPersistentList(InotifyScanMode, 
-                                              config_inotify_list);
-        autoscan_inotify = storage->getAutoscanList(InotifyScanMode);
-    }
-    else
-        // make an empty list so we do not have to do extra checks on shutdown 
+        storage->updateAutoscanPersistentList(ScanMode::INotify,
+            config_inotify_list);
+        autoscan_inotify = storage->getAutoscanList(ScanMode::INotify);
+    } else {
+        // make an empty list so we do not have to do extra checks on shutdown
         autoscan_inotify = Ref<AutoscanList>(new AutoscanList());
+    }
 #endif
-    /* init filemagic */
+/* init filemagic */
 #ifdef HAVE_MAGIC
-    if (! ignore_unknown_extensions)
-    {
+    if (!ignore_unknown_extensions) {
         ms = magic_open(MAGIC_MIME);
-        if (ms == NULL)
-        {
+        if (ms == nullptr) {
             log_error("magic_open failed\n");
-        }
-        else
-        {
+        } else {
             String magicFile = cm->getOption(CFG_IMPORT_MAGIC_FILE);
-            if (! string_ok(magicFile))
-                magicFile = nil;
-            if (magic_load(ms, (magicFile == nil) ? NULL : magicFile.c_str()) == -1)
-            {
+            if (!string_ok(magicFile))
+                magicFile = nullptr;
+            if (magic_load(ms, (magicFile == nullptr) ? nullptr : magicFile.c_str()) == -1) {
                 log_warning("magic_load: %s\n", magic_error(ms));
                 magic_close(ms);
-                ms = NULL;
+                ms = nullptr;
             }
         }
     }
 #endif // HAVE_MAGIC
 
-    String layout_type = 
-                       cm->getOption(CFG_IMPORT_SCRIPTING_VIRTUAL_LAYOUT_TYPE);
+    String layout_type = cm->getOption(CFG_IMPORT_SCRIPTING_VIRTUAL_LAYOUT_TYPE);
     if ((layout_type == "builtin") || (layout_type == "js"))
         layout_enabled = true;
 
 #ifdef ONLINE_SERVICES
     online_services = Ref<OnlineServiceList>(new OnlineServiceList());
 #ifdef YOUTUBE
-    if (cm->getBoolOption(CFG_ONLINE_CONTENT_YOUTUBE_ENABLED))
-    {
-        try 
-        {
-            Ref<OnlineService> yt((OnlineService *)new YouTubeService());
+    if (cm->getBoolOption(CFG_ONLINE_CONTENT_YOUTUBE_ENABLED)) {
+        try {
+            Ref<OnlineService> yt((OnlineService*)new YouTubeService());
 
             i = cm->getIntOption(CFG_ONLINE_CONTENT_YOUTUBE_REFRESH);
             yt->setRefreshInterval(i);
@@ -245,35 +214,28 @@ ContentManager::ContentManager() : TimerSubscriberSingleton<ContentManager>()
             if (cm->getBoolOption(CFG_ONLINE_CONTENT_YOUTUBE_UPDATE_AT_START))
                 i = CFG_DEFAULT_UPDATE_AT_START;
 
-            Ref<TimerParameter> yt_param(new TimerParameter(TimerParameter::IDOnlineContent, OS_YouTube));
-            yt->setTimerParameter(RefCast(yt_param, Object));
+            Ref<Timer::Parameter> yt_param(new Timer::Parameter(Timer::Parameter::IDOnlineContent, OS_YouTube));
+            yt->setTimerParameter(yt_param);
             online_services->registerService(yt);
-            
-            if (i > 0)
-            {
-                Timer::getInstance()->addTimerSubscriber(AS_TIMER_SUBSCRIBER_SINGLETON(this), i, yt->getTimerParameter(), true);
+
+            if (i > 0) {
+                Timer::getInstance()->addTimerSubscriber(this, i, yt->getTimerParameter(), true);
             }
-        }
-        catch (Exception ex)
-        {
-            log_error("Could not setup YouTube: %s\n", 
-                    ex.getMessage().c_str());
+        } catch (const Exception& ex) {
+            log_error("Could not setup YouTube: %s\n",
+                ex.getMessage().c_str());
         }
     }
     // if YT is disabled in the configuration it is still possible that the DB
     // is populated with YT objects, so we need to allow playing them
-    cached_urls = Ref<ReentrantArray<CachedURL> >
-        (new ReentrantArray<CachedURL>(MAX_CACHED_URLS));
-    urlcache_mutex = Ref<Mutex>(new Mutex(false));
+    cached_urls = Ref<ReentrantArray<CachedURL> >(new ReentrantArray<CachedURL>(MAX_CACHED_URLS));
 
 #endif //YOUTUBE
 
 #ifdef SOPCAST
-    if (cm->getBoolOption(CFG_ONLINE_CONTENT_SOPCAST_ENABLED))
-    {
-        try
-        {
-            Ref<OnlineService> sc((OnlineService *)new SopCastService());
+    if (cm->getBoolOption(CFG_ONLINE_CONTENT_SOPCAST_ENABLED)) {
+        try {
+            Ref<OnlineService> sc((OnlineService*)new SopCastService());
 
             i = cm->getIntOption(CFG_ONLINE_CONTENT_SOPCAST_REFRESH);
             sc->setRefreshInterval(i);
@@ -284,59 +246,23 @@ ContentManager::ContentManager() : TimerSubscriberSingleton<ContentManager>()
             if (cm->getBoolOption(CFG_ONLINE_CONTENT_SOPCAST_UPDATE_AT_START))
                 i = CFG_DEFAULT_UPDATE_AT_START;
 
-            Ref<TimerParameter> sc_param(new TimerParameter(TimerParameter::IDOnlineContent, OS_SopCast));
+            Ref<Parameter> sc_param(new Parameter(Parameter::IDOnlineContent, OS_SopCast));
             sc->setTimerParameter(RefCast(sc_param, Object));
             online_services->registerService(sc);
-            if (i > 0)
-            {
-                Timer::getInstance()->addTimerSubscriber(AS_TIMER_SUBSCRIBER_SINGLETON(this), i, sc->getTimerParameter(), true);
+            if (i > 0) {
+                Timer::getInstance()->addTimerSubscriber(this, i, sc->getTimerParameter(), true);
             }
-        }
-        catch (Exception ex)
-        {
+        } catch (const Exception& ex) {
             log_error("Could not setup SopCast: %s\n",
-                    ex.getMessage().c_str());
+                ex.getMessage().c_str());
         }
     }
 #endif //SOPCAST
 
-#ifdef WEBORAMA
-    if (cm->getBoolOption(CFG_ONLINE_CONTENT_WEBORAMA_ENABLED))
-    {
-        try
-        {
-            Ref<OnlineService> wb((OnlineService *)new WeboramaService());
-            i = cm->getIntOption(CFG_ONLINE_CONTENT_WEBORAMA_REFRESH);
-            wb->setRefreshInterval(i);
-
-            i = cm->getIntOption(CFG_ONLINE_CONTENT_WEBORAMA_PURGE_AFTER);
-            wb->setItemPurgeInterval(i);
-
-            if (cm->getBoolOption(CFG_ONLINE_CONTENT_WEBORAMA_UPDATE_AT_START))
-                i = CFG_DEFAULT_UPDATE_AT_START;
-
-            Ref<TimerParameter> wb_param(new TimerParameter(TimerParameter::IDOnlineContent, OS_Weborama));
-            wb->setTimerParameter(RefCast(wb_param, Object));
-            online_services->registerService(wb);
-            if (i > 0)
-            {
-                Timer::getInstance()->addTimerSubscriber(AS_TIMER_SUBSCRIBER_SINGLETON(this), i, wb->getTimerParameter(), true);
-            }
-        }
-        catch (Exception ex)
-        {
-            log_error("Could not setup Weborama: %s\n",
-                    ex.getMessage().c_str());
-        }
-    }
-#endif //WEBORAMA
-
 #ifdef ATRAILERS
-    if (cm->getBoolOption(CFG_ONLINE_CONTENT_ATRAILERS_ENABLED))
-    {
-        try
-        {
-            Ref<OnlineService> at((OnlineService *)new ATrailersService());
+    if (cm->getBoolOption(CFG_ONLINE_CONTENT_ATRAILERS_ENABLED)) {
+        try {
+            Ref<OnlineService> at((OnlineService*)new ATrailersService());
             i = cm->getIntOption(CFG_ONLINE_CONTENT_ATRAILERS_REFRESH);
             at->setRefreshInterval(i);
 
@@ -345,21 +271,18 @@ ContentManager::ContentManager() : TimerSubscriberSingleton<ContentManager>()
             if (cm->getBoolOption(CFG_ONLINE_CONTENT_ATRAILERS_UPDATE_AT_START))
                 i = CFG_DEFAULT_UPDATE_AT_START;
 
-            Ref<TimerParameter> at_param(new TimerParameter(TimerParameter::IDOnlineContent, OS_ATrailers));
+            Ref<Parameter> at_param(new Parameter(Parameter::IDOnlineContent, OS_ATrailers));
             at->setTimerParameter(RefCast(at_param, Object));
             online_services->registerService(at);
-            if (i > 0)
-            {
-                Timer::getInstance()->addTimerSubscriber(AS_TIMER_SUBSCRIBER_SINGLETON(this), i, at->getTimerParameter(), true);
+            if (i > 0) {
+                Timer::getInstance()->addTimerSubscriber(this, i, at->getTimerParameter(), true);
             }
-        }
-        catch (Exception ex)
-        {
+        } catch (const Exception& ex) {
             log_error("Could not setup Apple Trailers: %s\n",
-                    ex.getMessage().c_str());
+                ex.getMessage().c_str());
         }
     }
-#endif//ATRAILERS
+#endif //ATRAILERS
 
 #endif //ONLINE_SERVICES
 }
@@ -370,54 +293,40 @@ ContentManager::~ContentManager()
 }
 
 void ContentManager::init()
-{   
-    int ret;
-
+{
     reMimetype = Ref<RExp>(new RExp());
     reMimetype->compile(_(MIMETYPE_REGEXP));
-    
-    /*
-    pthread_attr_t attr;
-    ret = pthread_attr_init(&attr);
-    if (ret != 0)
-    {
-        throw _Exception(_("Could not initialize attribute"));
-    }
-   
-    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-    */
-    
-    ret = pthread_create(
+
+    int ret = pthread_create(
         &taskThread,
-        NULL, //&attr, // attr
+        nullptr, //&attr, // attr
         ContentManager::staticThreadProc,
-        this
-    );
-    if (ret != 0)
-    {
+        this);
+    if (ret != 0) {
         throw _Exception(_("Could not start task thread"));
     }
-    
-    //pthread_attr_destroy(&attr);
-    
-    //loadAccounting(false);
-    
-    autoscan_timed->notifyAll(AS_TIMER_SUBSCRIBER_SINGLETON(this));
+
+    autoscan_timed->notifyAll(this);
 
 #ifdef HAVE_INOTIFY
-    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY))
-    {
-        inotify = Ref<AutoscanInotify>(new AutoscanInotify());
+    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY)) {
         /// \todo change this (we need a new autoscan architecture)
-        for (int i = 0; i < autoscan_inotify->size(); i++)
-        {
+        Ref<AutoscanInotify> inotify = AutoscanInotify::getInstance();
+        for (int i = 0; i < autoscan_inotify->size(); i++) {
             Ref<AutoscanDirectory> dir = autoscan_inotify->get(i);
-            if (dir != nil)
+            if (dir != nullptr)
                 inotify->monitor(dir);
         }
     }
 #endif
 
+    for (int i = 0; i < autoscan_timed->size(); i++) {
+        Ref<AutoscanDirectory> dir = autoscan_timed->get(i);
+        Ref<Timer::Parameter> param(new Timer::Parameter(Timer::Parameter::timer_param_t::IDAutoscan, dir->getScanID()));
+        log_debug("Adding timed scan with interval %d\n", dir->getInterval());
+        Timer::getInstance()->addTimerSubscriber(this, dir->getInterval(), param, false);
+    }
+
 #ifdef EXTERNAL_TRANSCODING
     process_list = Ref<Array<Executor> >(new Array<Executor>());
 #endif
@@ -426,7 +335,7 @@ void ContentManager::init()
 #if defined(EXTERNAL_TRANSCODING) || defined(SOPCAST)
 void ContentManager::registerExecutor(Ref<Executor> exec)
 {
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     process_list->append(exec);
 }
 
@@ -441,102 +350,86 @@ void ContentManager::unregisterExecutor(Ref<Executor> exec)
     if (shutdownFlag)
         return;
 
-    AUTOLOCK(mutex);
-    for (int i = 0; i < process_list->size(); i++)
-    {
+    AutoLock lock(mutex);
+    for (int i = 0; i < process_list->size(); i++) {
         if (process_list->get(i) == exec)
             process_list->remove(i);
     }
 }
 #endif
 
-void ContentManager::timerNotify(Ref<Object> parameter)
+void ContentManager::timerNotify(Ref<Timer::Parameter> parameter)
 {
-    if (parameter == nil)
+    if (parameter == nullptr)
         return;
-    
-    Ref<TimerParameter> tp = RefCast(parameter, TimerParameter);
-    if (tp->whoami() == TimerParameter::IDAutoscan)
-    {
-        Ref<AutoscanDirectory> dir = autoscan_timed->get(tp->getID());
-        if (dir == nil)
+
+    if (parameter->whoami() == Timer::Parameter::IDAutoscan) {
+        Ref<AutoscanDirectory> dir = autoscan_timed->get(parameter->getID());
+        if (dir == nullptr)
             return;
 
         int objectID = dir->getObjectID();
         rescanDirectory(objectID, dir->getScanID(), dir->getScanMode());
     }
 #ifdef ONLINE_SERVICES
-    else if (tp->whoami() == TimerParameter::IDOnlineContent)
-    {
-        fetchOnlineContent((service_type_t)(tp->getID()));
+    else if (parameter->whoami() == Timer::Parameter::IDOnlineContent) {
+        fetchOnlineContent((service_type_t)(parameter->getID()));
     }
 #ifdef YOUTUBE
-    else if (tp->whoami() == TimerParameter::IDURLCache)
-    {
+    else if (parameter->whoami() == Timer::Parameter::IDURLCache) {
         checkCachedURLs();
     }
 #endif
-#endif//ONLINE_SERVICES
-
+#endif //ONLINE_SERVICES
 }
 
 void ContentManager::shutdown()
 {
-#ifdef HAVE_INOTIFY
-    inotify = nil;
-#endif
     log_debug("start\n");
-    AUTOLOCK(mutex);
+    std::unique_lock<mutex_type> lock(mutex);
     log_debug("updating last_modified data for autoscan in database...\n");
     autoscan_timed->updateLMinDB();
 
 #ifdef HAVE_INOTIFY
-    for (int i = 0; i < autoscan_inotify->size(); i++)
-    {
+    for (int i = 0; i < autoscan_inotify->size(); i++) {
         Ref<AutoscanDirectory> dir = autoscan_inotify->get(i);
-        if (dir != nil)
-        {
-            try
-            {
+        if (dir != nullptr) {
+            try {
                 dir->resetLMT();
                 dir->setCurrentLMT(check_path_ex(dir->getLocation(), true));
                 dir->updateLMT();
-            }
-            catch (Exception ex)
-            {
+            } catch (const Exception& ex) {
                 continue;
             }
         }
     }
-    
+
     autoscan_inotify->updateLMinDB();
 #endif
 
     shutdownFlag = true;
 
-#ifdef EXTERNAL_TRANSCODING 
-    for (int i = 0; i < process_list->size(); i++)
-    {
+#ifdef EXTERNAL_TRANSCODING
+    for (int i = 0; i < process_list->size(); i++) {
         Ref<Executor> exec = process_list->get(i);
-        if (exec != nil)
+        if (exec != nullptr)
             exec->kill();
     }
 #endif
 
     log_debug("signalling...\n");
     signal();
-    AUTOUNLOCK();
+    lock.unlock();
     log_debug("waiting for thread...\n");
 
     if (taskThread)
-        pthread_join(taskThread, NULL);
+        pthread_join(taskThread, nullptr);
     taskThread = 0;
 
 #ifdef HAVE_MAGIC
-    if (ms)
-    {
+    if (ms) {
         magic_close(ms);
-        ms = NULL;
+        ms = nullptr;
     }
 #endif
     log_debug("end\n");
@@ -549,7 +442,7 @@ Ref<CMAccounting> ContentManager::getAccounting()
 Ref<GenericTask> ContentManager::getCurrentTask()
 {
     Ref<GenericTask> task;
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     task = currentTask;
     return task;
 }
@@ -558,10 +451,9 @@ Ref<Array<GenericTask> > ContentManager::getTasklist()
 {
     int i;
 
-    AUTOLOCK(mutex);
-   
+    AutoLock lock(mutex);
 
-    Ref<Array<GenericTask> > taskList = nil;
+    Ref<Array<GenericTask> > taskList = nullptr;
 #ifdef ONLINE_SERVICES
     taskList = TaskProcessor::getInstance()->getTasklist();
 #endif
@@ -569,36 +461,33 @@ Ref<Array<GenericTask> > ContentManager::getTasklist()
 
     // if there is no current task, then the queues are empty
     // and we do not have to allocate the array
-    if ((t == nil) && (taskList == nil))
-        return nil;
+    if ((t == nullptr) && (taskList == nullptr))
+        return nullptr;
 
-    if (taskList == nil)
+    if (taskList == nullptr)
         taskList = Ref<Array<GenericTask> >(new Array<GenericTask>());
 
-    if (t != nil)
-        taskList->append(t); 
+    if (t != nullptr)
+        taskList->append(t);
 
     int qsize = taskQueue1->size();
 
-    for (i = 0; i < qsize; i++)
-    {
+    for (i = 0; i < qsize; i++) {
         Ref<GenericTask> t = taskQueue1->get(i);
         if (t->isValid())
             taskList->append(t);
     }
 
     qsize = taskQueue2->size();
-    for (i = 0; i < qsize; i++)
-    {
+    for (i = 0; i < qsize; i++) {
         Ref<GenericTask> t = taskQueue2->get(i);
         if (t->isValid())
-            taskList = Ref<Array<GenericTask> >(new Array<GenericTask>()); 
+            taskList = Ref<Array<GenericTask> >(new Array<GenericTask>());
     }
 
     return taskList;
 }
 
-
 void ContentManager::_loadAccounting()
 {
     Ref<Storage> storage = Storage::getInstance();
@@ -612,33 +501,28 @@ void ContentManager::addVirtualItem(Ref<CdsObject> obj, bool allow_fifo)
     check_path_ex(path, false, false);
     Ref<Storage> storage = Storage::getInstance();
     Ref<CdsObject> pcdir = storage->findObjectByPath(path);
-    if (pcdir == nil)
-    {
+    if (pcdir == nullptr) {
         pcdir = createObjectFromFile(path, true, allow_fifo);
-        if (pcdir == nil)
-        {
+        if (pcdir == nullptr) {
             throw _Exception(_("Could not add ") + path);
         }
-        if (IS_CDS_ITEM(pcdir->getObjectType()))
-        {
+        if (IS_CDS_ITEM(pcdir->getObjectType())) {
             this->addObject(pcdir);
             obj->setRefID(pcdir->getID());
         }
     }
 
     addObject(obj);
-
 }
 
 int ContentManager::_addFile(String path, String rootpath, bool recursive, bool hidden, Ref<GenericTask> task)
 {
-    if (hidden == false)
-    {
+    if (hidden == false) {
         String filename = get_filename(path);
         if (string_ok(filename) && filename.charAt(0) == '.')
             return INVALID_OBJECT_ID;
     }
-    
+
     // never add the server configuration file
     if (ConfigManager::getInstance()->getConfigFilename() == path)
         return INVALID_OBJECT_ID;
@@ -649,59 +533,43 @@ int ContentManager::_addFile(String path, String rootpath, bool recursive, bool
 #ifdef HAVE_JS
     initJS();
 #endif
-    
+
     Ref<Storage> storage = Storage::getInstance();
-    
+
     Ref<UpdateManager> um = UpdateManager::getInstance();
     //Ref<StringConverter> f2i = StringConverter::f2i();
- 
+
     Ref<CdsObject> obj = storage->findObjectByPath(path);
-    if (obj == nil)
-    {
+    if (obj == nullptr) {
         obj = createObjectFromFile(path);
-        if (obj == nil) // object ignored
+        if (obj == nullptr) // object ignored
             return INVALID_OBJECT_ID;
-        if (IS_CDS_ITEM(obj->getObjectType()))
-        {
+        if (IS_CDS_ITEM(obj->getObjectType())) {
             addObject(obj);
-            if (layout != nil)
-            {
-                try
-                {
-                    if (!string_ok(rootpath) && (task != nil))
+            if (layout != nullptr) {
+                try {
+                    if (!string_ok(rootpath) && (task != nullptr))
                         rootpath = RefCast(task, CMAddFileTask)->getRootPath();
 
                     layout->processCdsObject(obj, rootpath);
-                    
+
                     String mimetype = RefCast(obj, CdsItem)->getMimeType();
                     String content_type = mimetype_contenttype_map->get(mimetype);
 #ifdef HAVE_JS
-                    if ((playlist_parser_script != nil) &&
-                        (content_type == CONTENT_TYPE_PLAYLIST))
-                            playlist_parser_script->processPlaylistObject(obj, task);
-#ifdef HAVE_LIBDVDNAV
-                    if ((dvd_import_script != nil) &&
-                        (content_type == CONTENT_TYPE_DVD))
-                           dvd_import_script->processDVDObject(obj);
-#else
-                    if (content_type == CONTENT_TYPE_DVD)
-                        log_warning("DVD Image %s will not be parsed: MediaTomb was compiled without libdvdnav  support!\n", obj->getLocation().c_str());
-#endif // DVD
+                    if ((playlist_parser_script != nullptr) && (content_type == CONTENT_TYPE_PLAYLIST))
+                        playlist_parser_script->processPlaylistObject(obj, task);
 #else
                     if (content_type == CONTENT_TYPE_PLAYLIST)
                         log_warning("Playlist %s will not be parsed: MediaTomb was compiled without JS support!\n", obj->getLocation().c_str());
 #endif // JS
-                }
-                catch (Exception e)
-                {
+                } catch (const Exception& e) {
                     throw e;
                 }
             }
         }
     }
-        
-    if (recursive && IS_CDS_CONTAINER(obj->getObjectType()))
-    {
+
+    if (recursive && IS_CDS_CONTAINER(obj->getObjectType())) {
         addRecursive(path, hidden, task);
     }
     return obj->getID();
@@ -715,17 +583,16 @@ void ContentManager::_removeObject(int objectID, bool all)
         throw _Exception(_("cannot remove PC-Directory container"));
     if (IS_FORBIDDEN_CDS_ID(objectID))
         throw _Exception(_("tried to remove illegal object id"));
-    
+
     Ref<Storage> storage = Storage::getInstance();
-    
+
     Ref<Storage::ChangedContainers> changedContainers = storage->removeObject(objectID, all);
-    
-    if (changedContainers != nil)
-    {
+
+    if (changedContainers != nullptr) {
         SessionManager::getInstance()->containerChangedUI(changedContainers->ui);
         UpdateManager::getInstance()->containersChanged(changedContainers->upnp);
     }
-    
+
     // reload accounting
     //loadAccounting();
 }
@@ -734,55 +601,46 @@ int ContentManager::ensurePathExistence(zmm::String path)
 {
     int updateID;
     int containerID = Storage::getInstance()->ensurePathExistence(path, &updateID);
-    if (updateID != INVALID_OBJECT_ID)
-    {
+    if (updateID != INVALID_OBJECT_ID) {
         UpdateManager::getInstance()->containerChanged(updateID);
         SessionManager::getInstance()->containerChangedUI(updateID);
     }
     return containerID;
 }
 
-void ContentManager::_rescanDirectory(int containerID, int scanID, scan_mode_t scanMode, scan_level_t scanLevel, Ref<GenericTask> task)
+void ContentManager::_rescanDirectory(int containerID, int scanID, ScanMode scanMode, ScanLevel scanLevel, Ref<GenericTask> task)
 {
     log_debug("start\n");
     int ret;
-    struct dirent *dent;
+    struct dirent* dent;
     struct stat statbuf;
     String location;
     String path;
     Ref<CdsObject> obj;
 
     if (scanID == INVALID_SCAN_ID)
-        return; 
+        return;
 
     Ref<AutoscanDirectory> adir = getAutoscanDirectory(scanID, scanMode);
-    if (adir == nil)
-        throw _Exception(_("ID valid but nil returned? this should never happen"));
+    if (adir == nullptr)
+        throw _Exception(_("ID valid but nullptr returned? this should never happen"));
 
     Ref<Storage> storage = Storage::getInstance();
-   
-    if (containerID != INVALID_OBJECT_ID)
-    {
-        try
-        {
+
+    if (containerID != INVALID_OBJECT_ID) {
+        try {
             obj = storage->loadObject(containerID);
-            if (!IS_CDS_CONTAINER(obj->getObjectType()))
-            {
+            if (!IS_CDS_CONTAINER(obj->getObjectType())) {
                 throw _Exception(_("Not a container"));
             }
             if (containerID == CDS_ID_FS_ROOT)
                 location = _(FS_ROOT_DIRECTORY);
             else
                 location = obj->getLocation();
-        }
-        catch (Exception e)
-        {
-            if (adir->persistent())
-            {
+        } catch (const Exception& e) {
+            if (adir->persistent()) {
                 containerID = INVALID_OBJECT_ID;
-            }
-            else
-            {
+            } else {
                 adir->setTaskCount(-1);
                 removeAutoscanDirectory(scanID, scanMode);
                 storage->removeAutoscanDirectory(adir->getStorageID());
@@ -791,18 +649,13 @@ void ContentManager::_rescanDirectory(int containerID, int scanID, scan_mode_t s
         }
     }
 
-    if (containerID == INVALID_OBJECT_ID)
-    {
-        if (!check_path(adir->getLocation(), true))
-        {
+    if (containerID == INVALID_OBJECT_ID) {
+        if (!check_path(adir->getLocation(), true)) {
             adir->setObjectID(INVALID_OBJECT_ID);
             storage->updateAutoscanDirectory(adir);
-            if (adir->persistent())
-            {
+            if (adir->persistent()) {
                 return;
-            }
-            else
-            {
+            } else {
                 adir->setTaskCount(-1);
                 removeAutoscanDirectory(scanID, scanMode);
                 storage->removeAutoscanDirectory(adir->getStorageID());
@@ -816,31 +669,26 @@ void ContentManager::_rescanDirectory(int containerID, int scanID, scan_mode_t s
         location = adir->getLocation();
     }
 
-    time_t last_modified_current_max = adir->getPreviousLMT(); 
-       
+    time_t last_modified_current_max = adir->getPreviousLMT();
+
     log_debug("Rescanning location: %s\n", location.c_str());
 
-    if (!string_ok(location))
-    {
+    if (!string_ok(location)) {
         log_error("Container with ID %d has no location information\n", containerID);
         return;
         //        continue;
         //throw _Exception(_("Container has no location information!\n"));
     }
 
-    DIR *dir = opendir(location.c_str());
-    if (!dir)
-    {
+    DIR* dir = opendir(location.c_str());
+    if (!dir) {
         log_warning("Could not open %s: %s\n", location.c_str(), strerror(errno));
-        if (adir->persistent())
-        {
+        if (adir->persistent()) {
             removeObject(containerID, false);
             adir->setObjectID(INVALID_OBJECT_ID);
             storage->updateAutoscanDirectory(adir);
             return;
-        }
-        else
-        {
+        } else {
             adir->setTaskCount(-1);
             removeObject(containerID, false);
             removeAutoscanDirectory(scanID, scanMode);
@@ -850,64 +698,49 @@ void ContentManager::_rescanDirectory(int containerID, int scanID, scan_mode_t s
     }
 
     // request only items if non-recursive scan is wanted
-    Ref<DBRHash<int> > list = storage->getObjects(containerID, !adir->getRecursive());
+    shared_ptr<unordered_set<int> > list = storage->getObjects(containerID, !adir->getRecursive());
 
     unsigned int thisTaskID;
-    if (task != nil)
-    {
+    if (task != nullptr) {
         thisTaskID = task->getID();
-    }
-    else
+    } else
         thisTaskID = 0;
 
-    while (((dent = readdir(dir)) != NULL) && (!shutdownFlag) && (task == nil || ((task != nil) && task->isValid())))
-    {
-        char *name = dent->d_name;
-        if (name[0] == '.')
-        {
-            if (name[1] == 0)
-            {
+    while (((dent = readdir(dir)) != nullptr) && (!shutdownFlag) && (task == nullptr || ((task != nullptr) && task->isValid()))) {
+        char* name = dent->d_name;
+        if (name[0] == '.') {
+            if (name[1] == 0) {
                 continue;
-            }
-            else if (name[1] == '.' && name[2] == 0)
-            {
+            } else if (name[1] == '.' && name[2] == 0) {
+                continue;
+            } else if (!adir->getHidden()) {
                 continue;
-            }
-            else if (!adir->getHidden())
-            {
-                continue;    
             }
         }
 
-        path = location + DIR_SEPARATOR + name; 
+        path = location + DIR_SEPARATOR + name;
         ret = stat(path.c_str(), &statbuf);
-        if (ret != 0)
-        {
+        if (ret != 0) {
             log_error("Failed to stat %s, %s\n", path.c_str(), mt_strerror(errno).c_str());
             continue;
         }
 
         // it is possible that someone hits remove while the container is being scanned
         // in this case we will invalidate the autoscan entry
-        if (adir->getScanID() == INVALID_SCAN_ID)
-        {
+        if (adir->getScanID() == INVALID_SCAN_ID) {
             closedir(dir);
             return;
         }
 
-        if (S_ISREG(statbuf.st_mode))
-        {
+        if (S_ISREG(statbuf.st_mode)) {
             int objectID = storage->findObjectIDByPath(String(path));
-            if (objectID > 0)
-            {
-                if (list != nil)
-                    list->remove(objectID);
+            if (objectID > 0) {
+                if (list != nullptr)
+                    list->erase(objectID);
 
-                if (scanLevel == FullScanLevel)
-                {
+                if (scanLevel == ScanLevel::Full) {
                     // check modification time and update file if chagned
-                    if (last_modified_current_max < statbuf.st_mtime)
-                    {
+                    if (last_modified_current_max < statbuf.st_mtime) {
                         // readd object - we have to do this in order to trigger
                         // layout
                         removeObject(objectID, false);
@@ -915,82 +748,68 @@ void ContentManager::_rescanDirectory(int containerID, int scanID, scan_mode_t s
                         // update time variable
                         last_modified_current_max = statbuf.st_mtime;
                     }
-                }
-                else if (scanLevel == BasicScanLevel)
+                } else if (scanLevel == ScanLevel::Basic)
                     continue;
                 else
                     throw _Exception(_("Unsupported scan level!"));
 
-            }
-            else
-            {
+            } else {
                 // add file, not recursive, not async
                 // make sure not to add the current config.xml
-                if (ConfigManager::getInstance()->getConfigFilename() != path)
-                {
+                if (ConfigManager::getInstance()->getConfigFilename() != path) {
                     addFileInternal(path, location, false, false, adir->getHidden());
                     if (last_modified_current_max < statbuf.st_mtime)
                         last_modified_current_max = statbuf.st_mtime;
                 }
             }
-        }
-        else if (S_ISDIR(statbuf.st_mode) && (adir->getRecursive()))
-        {
+        } else if (S_ISDIR(statbuf.st_mode) && (adir->getRecursive())) {
             int objectID = storage->findObjectIDByPath(path + DIR_SEPARATOR);
-            if (objectID > 0)
-            {
-                if (list != nil)
-                    list->remove(objectID);
+            if (objectID > 0) {
+                if (list != nullptr)
+                    list->erase(objectID);
                 // add a task to rescan the directory that was found
                 rescanDirectory(objectID, scanID, scanMode, path + DIR_SEPARATOR, task->isCancellable());
-            }
-            else
-            {
+            } else {
                 // we have to make sure that we will never add a path to the task list
                 // if it is going to be removed by a pending remove task.
                 // this lock will make sure that remove is not in the process of invalidating
                 // the AutocsanDirectories in the autoscan_timed list at the time when we
                 // are checking for validity.
-                AUTOLOCK(mutex);
-                
+                AutoLock lock(mutex);
+
                 // it is possible that someone hits remove while the container is being scanned
                 // in this case we will invalidate the autoscan entry
-                if (adir->getScanID() == INVALID_SCAN_ID)
-                {
+                if (adir->getScanID() == INVALID_SCAN_ID) {
                     closedir(dir);
                     return;
                 }
-                
+
                 // add directory, recursive, async, hidden flag, low priority
                 addFileInternal(path, location, true, true, adir->getHidden(), true, thisTaskID, task->isCancellable());
             }
         }
     } // while
-    
+
     closedir(dir);
 
-    if ((shutdownFlag) || ((task != nil) && !task->isValid()))
+    if ((shutdownFlag) || ((task != nullptr) && !task->isValid()))
         return;
 
-    if (list != nil && list->size() > 0)
-    {
+    if (list != nullptr && list->size() > 0) {
         Ref<Storage::ChangedContainers> changedContainers = storage->removeObjects(list);
-        if (changedContainers != nil)
-        {
+        if (changedContainers != nullptr) {
             SessionManager::getInstance()->containerChangedUI(changedContainers->ui);
             UpdateManager::getInstance()->containersChanged(changedContainers->upnp);
         }
     }
 
-
     adir->setCurrentLMT(last_modified_current_max);
 }
 
 /* scans the given directory and adds everything recursively */
 void ContentManager::addRecursive(String path, bool hidden, Ref<GenericTask> task)
 {
-    if (hidden == false)
-    {
+    if (hidden == false) {
         log_debug("Checking path %s\n", path.c_str());
         if (path.charAt(0) == '.')
             return;
@@ -1000,34 +819,25 @@ void ContentManager::addRecursive(String path, bool hidden, Ref<GenericTask> tas
 
     Ref<UpdateManager> um = UpdateManager::getInstance();
     Ref<Storage> storage = Storage::getInstance();
-    DIR *dir = opendir(path.c_str());
-    if (!dir)
-    {
-        throw _Exception(_("could not list directory ")+
-                        path + " : " + strerror(errno));
+    DIR* dir = opendir(path.c_str());
+    if (!dir) {
+        throw _Exception(_("could not list directory ") + path + " : " + strerror(errno));
     }
     int parentID = storage->findObjectIDByPath(path + DIR_SEPARATOR);
-    struct dirent *dent;
+    struct dirent* dent;
     // abort loop if either:
     // no valid directory returned, server is about to shutdown, the task is there and was invalidated
-    if (task != nil)
-    {
+    if (task != nullptr) {
         log_debug("IS TASK VALID? [%d], taskoath: [%s]\n", task->isValid(), path.c_str());
     }
-    while (((dent = readdir(dir)) != NULL) && (!shutdownFlag) && (task == nil || ((task != nil) && task->isValid())))
-    {
-        char *name = dent->d_name;
-        if (name[0] == '.')
-        {
-            if (name[1] == 0)
-            {
+    while (((dent = readdir(dir)) != nullptr) && (!shutdownFlag) && (task == nullptr || ((task != nullptr) && task->isValid()))) {
+        char* name = dent->d_name;
+        if (name[0] == '.') {
+            if (name[1] == 0) {
                 continue;
-            }
-            else if (name[1] == '.' && name[2] == 0)
-            {
+            } else if (name[1] == '.' && name[2] == 0) {
                 continue;
-            }
-            else if (hidden == false)
+            } else if (hidden == false)
                 continue;
         }
         String newPath = path + DIR_SEPARATOR + name;
@@ -1035,76 +845,57 @@ void ContentManager::addRecursive(String path, bool hidden, Ref<GenericTask> tas
         if (ConfigManager::getInstance()->getConfigFilename() == newPath)
             continue;
 
-        try
-        {
-            Ref<CdsObject> obj = nil;
+        try {
+            Ref<CdsObject> obj = nullptr;
             if (parentID > 0)
                 obj = storage->findObjectByPath(String(newPath));
-            if (obj == nil) // create object
+            if (obj == nullptr) // create object
             {
                 obj = createObjectFromFile(newPath);
-                
-                if (obj == nil) // object ignored
+
+                if (obj == nullptr) // object ignored
                 {
                     log_warning("file ignored: %s\n", newPath.c_str());
-                }
-                else
-                {
+                } else {
                     //obj->setParentID(parentID);
-                    if (IS_CDS_ITEM(obj->getObjectType()))
-                    {
+                    if (IS_CDS_ITEM(obj->getObjectType())) {
                         addObject(obj);
                         parentID = obj->getParentID();
                     }
                 }
             }
-            if (obj != nil)
-            {
-//#ifdef HAVE_JS
-                if (IS_CDS_ITEM(obj->getObjectType()))
-                {
-                    if (layout != nil)
-                    {
-                        try
-                        {
-                            String rootpath = nil;
-                            if (task != nil)
+            if (obj != nullptr) {
+                //#ifdef HAVE_JS
+                if (IS_CDS_ITEM(obj->getObjectType())) {
+                    if (layout != nullptr) {
+                        try {
+                            String rootpath = nullptr;
+                            if (task != nullptr)
                                 rootpath = RefCast(task, CMAddFileTask)->getRootPath();
                             layout->processCdsObject(obj, rootpath);
 #ifdef HAVE_JS
                             Ref<Dictionary> mappings = ConfigManager::getInstance()->getDictionaryOption(CFG_IMPORT_MAPPINGS_MIMETYPE_TO_CONTENTTYPE_LIST);
                             String mimetype = RefCast(obj, CdsItem)->getMimeType();
                             String content_type = mappings->get(mimetype);
-                           
-                            if ((playlist_parser_script != nil) &&
-                                (content_type == CONTENT_TYPE_PLAYLIST))
+
+                            if ((playlist_parser_script != nullptr) && (content_type == CONTENT_TYPE_PLAYLIST))
                                 playlist_parser_script->processPlaylistObject(obj, task);
-#ifdef HAVE_LIBDVDNAV
-                            if ((dvd_import_script != nil) &&
-                                (content_type == CONTENT_TYPE_DVD))
-                                    dvd_import_script->processDVDObject(obj);
-#endif // DVD
 
 #endif // JS
-                        }
-                        catch (Exception e)
-                        {
+                        } catch (const Exception& e) {
                             throw e;
                         }
                     }
-                    
+
                     /// \todo Why was this statement here??? - It seems to be unnecessary
                     //obj = createObjectFromFile(newPath);
                 }
-//#endif
-                if (IS_CDS_CONTAINER(obj->getObjectType()))
-                {
+                //#endif
+                if (IS_CDS_CONTAINER(obj->getObjectType())) {
                     addRecursive(newPath, hidden, task);
                 }
             }
-        }
-        catch(Exception e)
-        {
+        } catch (const Exception& e) {
             log_warning("skipping %s : %s\n", newPath.c_str(), e.getMessage().c_str());
         }
     }
@@ -1129,31 +920,28 @@ void ContentManager::updateObject(int objectID, Ref<Dictionary> parameters)
     int objectType = obj->getObjectType();
 
     /// \todo if we have an active item, does it mean we first go through IS_ITEM and then thorugh IS_ACTIVE item? ask Gena
-    if (IS_CDS_ITEM(objectType))
-    {
+    if (IS_CDS_ITEM(objectType)) {
         Ref<CdsItem> item = RefCast(obj, CdsItem);
         Ref<CdsObject> clone = CdsObject::createObject(objectType);
         item->copyTo(clone);
 
-        if (string_ok(title)) clone->setTitle(title);
-        if (string_ok(upnp_class)) clone->setClass(upnp_class);
-        if (string_ok(location)) clone->setLocation(location);
+        if (string_ok(title))
+            clone->setTitle(title);
+        if (string_ok(upnp_class))
+            clone->setClass(upnp_class);
+        if (string_ok(location))
+            clone->setLocation(location);
 
         Ref<CdsItem> cloned_item = RefCast(clone, CdsItem);
- 
-        if (string_ok(mimetype) && (string_ok(protocol)))
-        {
+
+        if (string_ok(mimetype) && (string_ok(protocol))) {
             cloned_item->setMimeType(mimetype);
             Ref<CdsResource> resource = cloned_item->getResource(0);
             resource->addAttribute(_("protocolInfo"), renderProtocolInfo(mimetype, protocol));
-        }
-        else if (!string_ok(mimetype) && (string_ok(protocol)))
-        {
+        } else if (!string_ok(mimetype) && (string_ok(protocol))) {
             Ref<CdsResource> resource = cloned_item->getResource(0);
             resource->addAttribute(_("protocolInfo"), renderProtocolInfo(cloned_item->getMimeType(), protocol));
-        }
-        else if (string_ok(mimetype) && (!string_ok(protocol)))
-        {
+        } else if (string_ok(mimetype) && (!string_ok(protocol))) {
             cloned_item->setMimeType(mimetype);
             Ref<CdsResource> resource = cloned_item->getResource(0);
             Ref<Array<StringBase> > parts = split_string(resource->getAttribute(_("protocolInfo")), ':');
@@ -1161,20 +949,15 @@ void ContentManager::updateObject(int objectID, Ref<Dictionary> parameters)
             resource->addAttribute(_("protocolInfo"), renderProtocolInfo(mimetype, protocol));
         }
 
-        if (string_ok(description)) 
-        {
+        if (string_ok(description)) {
             cloned_item->setMetadata(MetadataHandler::getMetaFieldName(M_DESCRIPTION),
-                                     description);
-        }
-        else
-        {
+                description);
+        } else {
             cloned_item->removeMetadata(MetadataHandler::getMetaFieldName(M_DESCRIPTION));
         }
 
-
         log_debug("updateObject: checking equality of item %s\n", item->getTitle().c_str());
-        if (!item->equals(clone, true))
-        {
+        if (!item->equals(clone, true)) {
             cloned_item->validate();
             int containerChanged = INVALID_OBJECT_ID;
             storage->updateObject(clone, &containerChanged);
@@ -1184,8 +967,7 @@ void ContentManager::updateObject(int objectID, Ref<Dictionary> parameters)
             um->containerChanged(item->getParentID());
         }
     }
-    if (IS_CDS_ACTIVE_ITEM(objectType))
-    {
+    if (IS_CDS_ACTIVE_ITEM(objectType)) {
         String action = parameters->get(_("action"));
         String state = parameters->get(_("state"));
 
@@ -1193,29 +975,30 @@ void ContentManager::updateObject(int objectID, Ref<Dictionary> parameters)
         Ref<CdsObject> clone = CdsObject::createObject(objectType);
         item->copyTo(clone);
 
-        if (string_ok(title)) clone->setTitle(title);
-        if (string_ok(upnp_class)) clone->setClass(upnp_class);
+        if (string_ok(title))
+            clone->setTitle(title);
+        if (string_ok(upnp_class))
+            clone->setClass(upnp_class);
 
         Ref<CdsActiveItem> cloned_item = RefCast(clone, CdsActiveItem);
 
         // state and description can be an empty strings - if you want to clear it
-        if (string_ok(description)) 
-        {
+        if (string_ok(description)) {
             cloned_item->setMetadata(MetadataHandler::getMetaFieldName(M_DESCRIPTION),
-                                     description);
-        }
-        else
-        {
+                description);
+        } else {
             cloned_item->removeMetadata(MetadataHandler::getMetaFieldName(M_DESCRIPTION));
         }
 
-        if (state != nil) cloned_item->setState(state);
+        if (state != nullptr)
+            cloned_item->setState(state);
 
-        if (string_ok(mimetype)) cloned_item->setMimeType(mimetype);
-        if (string_ok(action)) cloned_item->setAction(action);
+        if (string_ok(mimetype))
+            cloned_item->setMimeType(mimetype);
+        if (string_ok(action))
+            cloned_item->setAction(action);
 
-        if (!item->equals(clone, true))
-        {
+        if (!item->equals(clone, true)) {
             cloned_item->validate();
             int containerChanged = INVALID_OBJECT_ID;
             storage->updateObject(clone, &containerChanged);
@@ -1223,18 +1006,17 @@ void ContentManager::updateObject(int objectID, Ref<Dictionary> parameters)
             sm->containerChangedUI(containerChanged);
             um->containerChanged(item->getParentID());
         }
-    }
-    else if (IS_CDS_CONTAINER(objectType))
-    {
+    } else if (IS_CDS_CONTAINER(objectType)) {
         Ref<CdsContainer> cont = RefCast(obj, CdsContainer);
         Ref<CdsObject> clone = CdsObject::createObject(objectType);
         cont->copyTo(clone);
 
-        if (string_ok(title)) clone->setTitle(title);
-        if (string_ok(upnp_class)) clone->setClass(upnp_class);
+        if (string_ok(title))
+            clone->setTitle(title);
+        if (string_ok(upnp_class))
+            clone->setClass(upnp_class);
 
-        if (!cont->equals(clone, true))
-        {
+        if (!cont->equals(clone, true)) {
             clone->validate();
             int containerChanged = INVALID_OBJECT_ID;
             storage->updateObject(clone, &containerChanged);
@@ -1244,7 +1026,6 @@ void ContentManager::updateObject(int objectID, Ref<Dictionary> parameters)
             sm->containerChangedUI(cont->getParentID());
         }
     }
-
 }
 
 void ContentManager::addObject(zmm::Ref<CdsObject> obj)
@@ -1256,42 +1037,38 @@ void ContentManager::addObject(zmm::Ref<CdsObject> obj)
     Ref<SessionManager> sm = SessionManager::getInstance();
     int containerChanged = INVALID_OBJECT_ID;
     log_debug("Adding: parent ID is %d\n", obj->getParentID());
-    if (!IS_CDS_ITEM_EXTERNAL_URL(obj->getObjectType()))
-    {
+    if (!IS_CDS_ITEM_EXTERNAL_URL(obj->getObjectType())) {
         obj->setLocation(obj->getLocation().reduce(DIR_SEPARATOR));
     }
     storage->addObject(obj, &containerChanged);
     log_debug("After adding: parent ID is %d\n", obj->getParentID());
-    
+
     um->containerChanged(containerChanged);
     sm->containerChangedUI(containerChanged);
-    
+
     parent_id = obj->getParentID();
-    if ((parent_id != -1) && (storage->getChildCount(parent_id) == 1))
-    {
+    if ((parent_id != -1) && (storage->getChildCount(parent_id) == 1)) {
         Ref<CdsObject> parent; //(new CdsObject());
         parent = storage->loadObject(parent_id);
         log_debug("Will update ID %d\n", parent->getParentID());
         um->containerChanged(parent->getParentID());
     }
-    
+
     um->containerChanged(obj->getParentID());
     if (IS_CDS_CONTAINER(obj->getObjectType()))
         sm->containerChangedUI(obj->getParentID());
-    
-    if (! obj->isVirtual() && IS_CDS_ITEM(obj->getObjectType()))
+
+    if (!obj->isVirtual() && IS_CDS_ITEM(obj->getObjectType()))
         ContentManager::getInstance()->getAccounting()->totalFiles++;
 }
 
-
 void ContentManager::addContainer(int parentID, String title, String upnpClass)
 {
     Ref<Storage> storage = Storage::getInstance();
     addContainerChain(storage->buildContainerPath(parentID, escape(title, VIRTUAL_CONTAINER_ESCAPE, VIRTUAL_CONTAINER_SEPARATOR)), upnpClass);
 }
 
-
-int ContentManager::addContainerChain(String chain, String lastClass, int lastRefID)
+int ContentManager::addContainerChain(String chain, String lastClass, int lastRefID, Ref<Dictionary> lastMetadata)
 {
     Ref<Storage> storage = Storage::getInstance();
     int updateID = INVALID_OBJECT_ID;
@@ -1299,10 +1076,10 @@ int ContentManager::addContainerChain(String chain, String lastClass, int lastRe
 
     if (!string_ok(chain))
         throw _Exception(_("addContainerChain() called with empty chain parameter"));
-    
+
     log_debug("received chain: %s\n", chain.c_str());
-    storage->addContainerChain(chain, lastClass, lastRefID,
-                              &containerID, &updateID);
+    storage->addContainerChain(chain, lastClass, lastRefID, &containerID, &updateID, lastMetadata);
+
     // if (updateID != INVALID_OBJECT_ID)
     // an invalid updateID is checked by containerChanged()
     UpdateManager::getInstance()->containerChanged(updateID);
@@ -1315,12 +1092,11 @@ void ContentManager::updateObject(Ref<CdsObject> obj, bool send_updates)
 {
     obj->validate();
     Ref<Storage> storage = Storage::getInstance();
-   
+
     int containerChanged = INVALID_OBJECT_ID;
     storage->updateObject(obj, &containerChanged);
 
-    if (send_updates)
-    {
+    if (send_updates) {
         Ref<UpdateManager> um = UpdateManager::getInstance();
         Ref<SessionManager> sm = SessionManager::getInstance();
 
@@ -1338,10 +1114,8 @@ Ref<CdsObject> ContentManager::convertObject(Ref<CdsObject> oldObj, int newType)
     int oldType = oldObj->getObjectType();
     if (oldType == newType)
         return oldObj;
-    if (! IS_CDS_ITEM(oldType) || ! IS_CDS_ITEM(newType))
-    {
-        throw _Exception(_("Cannot convert object type ") + oldType +
-                        " to " + newType);
+    if (!IS_CDS_ITEM(oldType) || !IS_CDS_ITEM(newType)) {
+        throw _Exception(_("Cannot convert object type ") + oldType + " to " + newType);
     }
 
     Ref<CdsObject> newObj = CdsObject::createObject(newType);
@@ -1351,7 +1125,7 @@ Ref<CdsObject> ContentManager::convertObject(Ref<CdsObject> oldObj, int newType)
     return newObj;
 }
 
-// returns nil if file ignored due to configuration
+// returns nullptr if file ignored due to configuration
 Ref<CdsObject> ContentManager::createObjectFromFile(String path, bool magic, bool allow_fifo)
 {
     String filename = get_filename(path);
@@ -1360,8 +1134,7 @@ Ref<CdsObject> ContentManager::createObjectFromFile(String path, bool magic, boo
     int ret;
 
     ret = stat(path.c_str(), &statbuf);
-    if (ret != 0)
-    {
+    if (ret != 0) {
         throw _Exception(_("Failed to stat ") + path + _(" , ") + mt_strerror(errno));
     }
 
@@ -1382,24 +1155,20 @@ Ref<CdsObject> ContentManager::createObjectFromFile(String path, bool magic, boo
         if (magic)
             mimetype = extension2mimetype(extension);
 
-        if (mimetype == nil && magic)
-        {
+        if (mimetype == nullptr && magic) {
             if (ignore_unknown_extensions)
-                return nil; // item should be ignored
-#ifdef HAVE_MAGIC        
+                return nullptr; // item should be ignored
+#ifdef HAVE_MAGIC
             mimetype = get_mime_type(ms, reMimetype, path);
 #endif
         }
-        if (mimetype != nil)
-        {
+        if (mimetype != nullptr) {
             upnp_class = mimetype2upnpclass(mimetype);
         }
 
-        if (!string_ok(upnp_class))
-        {
+        if (!string_ok(upnp_class)) {
             String content_type = mimetype_contenttype_map->get(mimetype);
-            if (content_type == CONTENT_TYPE_OGG)
-            {
+            if (content_type == CONTENT_TYPE_OGG) {
                 if (isTheora(path))
                     upnp_class = _(UPNP_DEFAULT_CLASS_VIDEO_ITEM);
                 else
@@ -1410,17 +1179,17 @@ Ref<CdsObject> ContentManager::createObjectFromFile(String path, bool magic, boo
         Ref<CdsItem> item(new CdsItem());
         obj = RefCast(item, CdsObject);
         item->setLocation(path);
-        if (mimetype != nil)
+        item->setMTime(statbuf.st_mtime);
+        item->setSizeOnDisk(statbuf.st_size);
+        if (mimetype != nullptr)
             item->setMimeType(mimetype);
-        if (upnp_class != nil)
+        if (upnp_class != nullptr)
             item->setClass(upnp_class);
         Ref<StringConverter> f2i = StringConverter::f2i();
         obj->setTitle(f2i->convert(filename));
         if (magic)
             MetadataHandler::setMetadata(item);
-    }
-    else if (S_ISDIR(statbuf.st_mode))
-    {
+    } else if (S_ISDIR(statbuf.st_mode)) {
         Ref<CdsContainer> cont(new CdsContainer());
         obj = RefCast(cont, CdsObject);
         /* adding containers is done by Storage now
@@ -1432,21 +1201,19 @@ Ref<CdsObject> ContentManager::createObjectFromFile(String path, bool magic, boo
         Ref<StringConverter> f2i = StringConverter::f2i();
         obj->setTitle(f2i->convert(filename));
         */
-    }
-    else
-    {
+    } else {
         // only regular files and directories are supported
         throw _Exception(_("ContentManager: skipping file ") + path.c_str());
     }
-//    Ref<StringConverter> f2i = StringConverter::f2i();
-//    obj->setTitle(f2i->convert(filename));
+    //    Ref<StringConverter> f2i = StringConverter::f2i();
+    //    obj->setTitle(f2i->convert(filename));
     return obj;
 }
 
 String ContentManager::extension2mimetype(String extension)
 {
-    if (extension_mimetype_map == nil)
-        return nil;
+    if (extension_mimetype_map == nullptr)
+        return nullptr;
 
     if (!extension_map_case_sensitive)
         extension = extension.toLower();
@@ -1456,77 +1223,60 @@ String ContentManager::extension2mimetype(String extension)
 
 String ContentManager::mimetype2upnpclass(String mimeType)
 {
-    if (mimetype_upnpclass_map == nil)
-        return nil;
+    if (mimetype_upnpclass_map == nullptr)
+        return nullptr;
     String upnpClass = mimetype_upnpclass_map->get(mimeType);
-    if (upnpClass != nil)
+    if (upnpClass != nullptr)
         return upnpClass;
     // try to match foo
     Ref<Array<StringBase> > parts = split_string(mimeType, '/');
     if (parts->size() != 2)
-        return nil;
+        return nullptr;
     return mimetype_upnpclass_map->get((String)parts->get(0) + "/*");
 }
 
 void ContentManager::initLayout()
 {
 
-    if (layout == nil)
-    {
-        AUTOLOCK(mutex);
-        if (layout == nil)
-            try
-            {
-                String layout_type = 
-                    ConfigManager::getInstance()->getOption(CFG_IMPORT_SCRIPTING_VIRTUAL_LAYOUT_TYPE);
-                if (layout_type == "js")
-                {
+    if (layout == nullptr) {
+        AutoLock lock(mutex);
+        if (layout == nullptr)
+            try {
+                String layout_type = ConfigManager::getInstance()->getOption(CFG_IMPORT_SCRIPTING_VIRTUAL_LAYOUT_TYPE);
+                if (layout_type == "js") {
 #ifdef HAVE_JS
-                    layout = Ref<Layout>((Layout *)new JSLayout());
+                    layout = Ref<Layout>((Layout*)new JSLayout());
 #else
                     log_error("Cannot init layout: MediaTomb compiled without js support but js script was requested.");
 #endif
+                } else if (layout_type == "builtin") {
+                    layout = Ref<Layout>((FallbackLayout*)new FallbackLayout());
                 }
-                else if (layout_type == "builtin")
-                {
-                    layout = Ref<Layout>((FallbackLayout *)new FallbackLayout());
-                }
+            } catch (const Exception& e) {
+                layout = nullptr;
+                log_error("ContentManager virtual container layout: %s\n", e.getMessage().c_str());
             }
-        catch (Exception e)
-        {
-            layout = nil;
-            log_error("ContentManager virtual container layout: %s\n", e.getMessage().c_str());
-        }
     }
 }
 
 #ifdef HAVE_JS
 void ContentManager::initJS()
 {
-    if (playlist_parser_script == nil)
+    if (playlist_parser_script == nullptr)
         playlist_parser_script = Ref<PlaylistParserScript>(new PlaylistParserScript(Runtime::getInstance()));
 
-#ifdef HAVE_LIBDVDNAV
-    if ((ConfigManager::getInstance()->getOption(CFG_IMPORT_SCRIPTING_VIRTUAL_LAYOUT_TYPE) == "js") && (dvd_import_script == nil))
-    {
-        dvd_import_script = Ref<DVDImportScript>(new DVDImportScript(Runtime::getInstance()));
-    }
-#endif
 }
 
 void ContentManager::destroyJS()
 {
-    playlist_parser_script = nil;
-#ifdef HAVE_LIBDVDNAV
-    dvd_import_script = nil;
-#endif
+    playlist_parser_script = nullptr;
 }
 
 #endif // HAVE_JS
 
 void ContentManager::destroyLayout()
 {
-    layout = nil;
+    layout = nullptr;
 }
 
 void ContentManager::reloadLayout()
@@ -1538,63 +1288,56 @@ void ContentManager::reloadLayout()
 void ContentManager::threadProc()
 {
     Ref<GenericTask> task;
-    AUTOLOCK(mutex);
+    std::unique_lock<mutex_type> lock(mutex);
     working = true;
-    while(! shutdownFlag)
-    {
-        currentTask = nil;
-        if(((task = taskQueue1->dequeue()) == nil) && ((task = taskQueue2->dequeue()) == nil))
-        {
+    while (!shutdownFlag) {
+        currentTask = nullptr;
+        if (((task = taskQueue1->dequeue()) == nullptr) && ((task = taskQueue2->dequeue()) == nullptr)) {
             working = false;
             /* if nothing to do, sleep until awakened */
-            cond->wait();
+            cond.wait(lock);
             working = true;
             continue;
-        }
-        else
-        {
+        } else {
             currentTask = task;
         }
-        AUTOUNLOCK();
+        lock.unlock();
 
-//        log_debug(("Async START %s\n", task->getDescription().c_str()));
-        try
-        {
+        // log_debug("content manager Async START %s\n", task->getDescription().c_str());
+        try {
             if (task->isValid())
                 task->run();
-        }
-        catch (ServerShutdownException se)
-        {
+        } catch (const ServerShutdownException& se) {
             shutdownFlag = true;
-        }
-        catch (Exception e)
-        {
+        } catch (const Exception& e) {
             log_error("Exception caught: %s\n", e.getMessage().c_str());
             e.printStackTrace();
         }
-//        log_debug(("ASYNC STOP  %s\n", task->getDescription().c_str()));
-        if (! shutdownFlag)
-            AUTORELOCK();
+        // log_debug("content manager ASYNC STOP  %s\n", task->getDescription().c_str());
+
+        if (!shutdownFlag) {
+            lock.lock();
+        }
     }
 
     Storage::getInstance()->threadCleanup();
 }
 
-void *ContentManager::staticThreadProc(void *arg)
+void* ContentManager::staticThreadProc(void* arg)
 {
-    ContentManager *inst = (ContentManager *)arg;
+    auto* inst = (ContentManager*)arg;
     inst->threadProc();
-    pthread_exit(NULL);
-    return NULL;
+    pthread_exit(nullptr);
+    return nullptr;
 }
 
 void ContentManager::addTask(zmm::Ref<GenericTask> task, bool lowPriority)
 {
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
 
     task->setID(taskID++);
 
-    if (! lowPriority)
+    if (!lowPriority)
         taskQueue1->enqueue(task);
     else
         taskQueue2->enqueue(task);
@@ -1604,20 +1347,17 @@ void ContentManager::addTask(zmm::Ref<GenericTask> task, bool lowPriority)
 /* sync / async methods */
 void ContentManager::loadAccounting(bool async)
 {
-    if (async)
-    {
+    if (async) {
         Ref<GenericTask> task(new CMLoadAccountingTask());
         task->setDescription(_("Initializing statistics"));
         addTask(task);
-    }
-    else
-    {
+    } else {
         _loadAccounting();
     }
 }
 
-int ContentManager::addFile(zmm::String path, bool recursive, bool async, 
-                            bool hidden, bool lowPriority, bool cancellable)
+int ContentManager::addFile(zmm::String path, bool recursive, bool async,
+    bool hidden, bool lowPriority, bool cancellable)
 {
     String rootpath;
     if (check_path(path, true))
@@ -1626,122 +1366,58 @@ int ContentManager::addFile(zmm::String path, bool recursive, bool async,
 }
 
 int ContentManager::addFileInternal(String path, String rootpath,
-                                    bool recursive, 
-                                    bool async, bool hidden, bool lowPriority, 
-                                    unsigned int parentTaskID, 
-                                    bool cancellable)
+    bool recursive,
+    bool async, bool hidden, bool lowPriority,
+    unsigned int parentTaskID,
+    bool cancellable)
 {
-    if (async)
-    {
+    if (async) {
         Ref<GenericTask> task(new CMAddFileTask(path, rootpath, recursive, hidden, cancellable));
         task->setDescription(_("Adding: ") + path);
         task->setParentID(parentTaskID);
         addTask(task, lowPriority);
         return INVALID_OBJECT_ID;
-    }
-    else
-    {
+    } else {
         return _addFile(path, rootpath, recursive, hidden);
     }
 }
 
 #ifdef ONLINE_SERVICES
 void ContentManager::fetchOnlineContent(service_type_t service,
-                                        bool lowPriority, bool cancellable,
-                                        bool unscheduled_refresh)
+    bool lowPriority, bool cancellable,
+    bool unscheduled_refresh)
 {
     Ref<OnlineService> os = online_services->getService(service);
-    if (os == nil)
-    {
+    if (os == nullptr) {
         log_debug("No surch service! %d\n", service);
         throw _Exception(_("Service not found!"));
     }
     fetchOnlineContentInternal(os, lowPriority, cancellable, 0,
-                               unscheduled_refresh);
+        unscheduled_refresh);
 }
 
-void ContentManager::fetchOnlineContentInternal(Ref<OnlineService> service, 
-                                        bool lowPriority, bool cancellable,
-                                        unsigned int parentTaskID, 
-                                        bool unscheduled_refresh)
+void ContentManager::fetchOnlineContentInternal(Ref<OnlineService> service,
+    bool lowPriority, bool cancellable,
+    unsigned int parentTaskID,
+    bool unscheduled_refresh)
 {
     if (layout_enabled)
         initLayout();
 
-    Ref<GenericTask> task(new CMFetchOnlineContentTask(service, layout, cancellable, 
-                                                  unscheduled_refresh));
-    task->setDescription(_("Updating content from ") + 
-                         service->getServiceName());
+    Ref<GenericTask> task(new CMFetchOnlineContentTask(service, layout, cancellable,
+        unscheduled_refresh));
+    task->setDescription(_("Updating content from ") + service->getServiceName());
     task->setParentID(parentTaskID);
     service->incTaskCount();
-    addTask(task, lowPriority);    
-}
-
-void ContentManager::_fetchOnlineContent(Ref<OnlineService> service, 
-                                         unsigned int parentTaskID, 
-                                         bool unscheduled_refresh)
-{
-    throw _Exception(_("Should not be called anymore!"));
-    log_debug("Fetching online content!\n");
-    if (layout_enabled)
-        initLayout();
-
-    if (service->refreshServiceData(layout) && (!shutdownFlag))
-    {
-        log_debug("Scheduling another task for online service: %s\n",
-                  service->getServiceName().c_str());
-
-        if ((service->getRefreshInterval() > 0) || unscheduled_refresh)
-            fetchOnlineContentInternal(service, true, true, parentTaskID, 
-                                       unscheduled_refresh);
-    }
-    else
-    {
-        log_debug("Finished fetch cycle for service: %s\n",
-                  service->getServiceName().c_str());
-
-        if (service->getItemPurgeInterval() > 0)
-        {
-            Ref<Storage> storage = Storage::getInstance();
-            Ref<IntArray> ids = storage->getServiceObjectIDs(service->getStoragePrefix());
-
-            struct timespec current, last;
-            getTimespecNow(&current);
-            last.tv_nsec = 0;
-            String temp;
-
-            for (int i = 0; i < ids->size(); i++)
-            {
-                int object_id = ids->get(i);
-                Ref<CdsObject> obj = storage->loadObject(object_id);
-                if (obj == nil)
-                    continue;
-
-                temp = obj->getAuxData(_(ONLINE_SERVICE_LAST_UPDATE));
-                if (!string_ok(temp))
-                    continue;
-
-                last.tv_sec = temp.toLong();
-
-                if ((service->getItemPurgeInterval() > 0) && 
-                    ((current.tv_sec - last.tv_sec) > service->getItemPurgeInterval()))
-                {
-                    log_debug("Purging old online service object %s\n", 
-                            obj->getTitle().c_str());
-                    removeObject(object_id, false);
-                }
-            } 
-        }
-    }
+    addTask(task, lowPriority);
 }
 
 void ContentManager::cleanupOnlineServiceObjects(zmm::Ref<OnlineService> service)
 {
     log_debug("Finished fetch cycle for service: %s\n",
-            service->getServiceName().c_str());
+        service->getServiceName().c_str());
 
-    if (service->getItemPurgeInterval() > 0)
-    {
+    if (service->getItemPurgeInterval() > 0) {
         Ref<Storage> storage = Storage::getInstance();
         Ref<IntArray> ids = storage->getServiceObjectIDs(service->getStoragePrefix());
 
@@ -1750,11 +1426,10 @@ void ContentManager::cleanupOnlineServiceObjects(zmm::Ref<OnlineService> service
         last.tv_nsec = 0;
         String temp;
 
-        for (int i = 0; i < ids->size(); i++)
-        {
+        for (int i = 0; i < ids->size(); i++) {
             int object_id = ids->get(i);
             Ref<CdsObject> obj = storage->loadObject(object_id);
-            if (obj == nil)
+            if (obj == nullptr)
                 continue;
 
             temp = obj->getAuxData(_(ONLINE_SERVICE_LAST_UPDATE));
@@ -1763,11 +1438,9 @@ void ContentManager::cleanupOnlineServiceObjects(zmm::Ref<OnlineService> service
 
             last.tv_sec = temp.toLong();
 
-            if ((service->getItemPurgeInterval() > 0) &&
-                    ((current.tv_sec - last.tv_sec) > service->getItemPurgeInterval()))
-            {
+            if ((service->getItemPurgeInterval() > 0) && ((current.tv_sec - last.tv_sec) > service->getItemPurgeInterval())) {
                 log_debug("Purging old online service object %s\n",
-                        obj->getTitle().c_str());
+                    obj->getTitle().c_str());
                 removeObject(object_id, false);
             }
         }
@@ -1778,11 +1451,9 @@ void ContentManager::cleanupOnlineServiceObjects(zmm::Ref<OnlineService> service
 
 void ContentManager::invalidateAddTask(Ref<GenericTask> t, String path)
 {
-    if (t->getType() == AddFile)
-    {
+    if (t->getType() == AddFile) {
         log_debug("comparing, task path: %s, remove path: %s\n", RefCast(t, CMAddFileTask)->getPath().c_str(), path.c_str());
-        if ((RefCast(t, CMAddFileTask)->getPath().startsWith(path)))
-        {
+        if ((RefCast(t, CMAddFileTask)->getPath().startsWith(path))) {
             log_debug("Invalidating task with path %s\n", RefCast(t, CMAddFileTask)->getPath().c_str());
             t->invalidate();
         }
@@ -1793,35 +1464,28 @@ void ContentManager::invalidateTask(unsigned int taskID, task_owner_t taskOwner)
 {
     int i;
 
-    if (taskOwner == ContentManagerTask)
-    {
-        AUTOLOCK(mutex);
+    if (taskOwner == ContentManagerTask) {
+        AutoLock lock(mutex);
         Ref<GenericTask> t = getCurrentTask();
-        if (t != nil)
-        {
-            if ((t->getID() == taskID) || (t->getParentID() == taskID))
-            {
+        if (t != nullptr) {
+            if ((t->getID() == taskID) || (t->getParentID() == taskID)) {
                 t->invalidate();
             }
         }
 
         int qsize = taskQueue1->size();
 
-        for (i = 0; i < qsize; i++)
-        {
+        for (i = 0; i < qsize; i++) {
             Ref<GenericTask> t = taskQueue1->get(i);
-            if ((t->getID() == taskID) || (t->getParentID() == taskID))
-            {
+            if ((t->getID() == taskID) || (t->getParentID() == taskID)) {
                 t->invalidate();
             }
         }
 
         qsize = taskQueue2->size();
-        for (i = 0; i < qsize; i++)
-        {
+        for (i = 0; i < qsize; i++) {
             Ref<GenericTask> t = taskQueue2->get(i);
-            if ((t->getID() == taskID) || (t->getParentID() == taskID))
-            {
+            if ((t->getID() == taskID) || (t->getParentID() == taskID)) {
                 t->invalidate();
             }
         }
@@ -1834,8 +1498,7 @@ void ContentManager::invalidateTask(unsigned int taskID, task_owner_t taskOwner)
 
 void ContentManager::removeObject(int objectID, bool async, bool all)
 {
-    if (async)
-    {
+    if (async) {
         /*
         // building container path for the description
         Ref<Storage> storage = Storage::getInstance();
@@ -1851,87 +1514,75 @@ void ContentManager::removeObject(int objectID, bool async, bool all)
         String path;
         Ref<CdsObject> obj;
 
-        try
-        {
+        try {
             obj = storage->loadObject(objectID);
             path = obj->getLocation();
 
             String vpath = obj->getVirtualPath();
             if (string_ok(vpath))
                 task->setDescription(_("Removing: ") + obj->getVirtualPath());
-        }
-        catch (Exception e)
-        {
+        } catch (const Exception& e) {
             log_debug("trying to remove an object ID which is no longer in the database! %d\n", objectID);
             return;
         }
 
-        if (IS_CDS_CONTAINER(obj->getObjectType()))
-        {
+        if (IS_CDS_CONTAINER(obj->getObjectType())) {
             int i;
 
-            // make sure to remove possible child autoscan directories from the scanlist 
+            // make sure to remove possible child autoscan directories from the scanlist
             Ref<AutoscanList> rm_list = autoscan_timed->removeIfSubdir(path);
-            for (i = 0; i < rm_list->size(); i++)
-            {
-                Timer::getInstance()->removeTimerSubscriber(AS_TIMER_SUBSCRIBER_SINGLETON(this), rm_list->get(i)->getTimerParameter(), true);
+            for (i = 0; i < rm_list->size(); i++) {
+                Timer::getInstance()->removeTimerSubscriber(this, rm_list->get(i)->getTimerParameter(), true);
             }
 #ifdef HAVE_INOTIFY
-            if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY))
-            {
+            if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY)) {
                 rm_list = autoscan_inotify->removeIfSubdir(path);
-                for (i = 0; i < rm_list->size(); i++)
-                {
+                for (i = 0; i < rm_list->size(); i++) {
                     Ref<AutoscanDirectory> dir = rm_list->get(i);
-                    inotify->unmonitor(dir);
+                    AutoscanInotify::getInstance()->unmonitor(dir);
                 }
             }
 #endif
 
-            AUTOLOCK(mutex);
+            AutoLock lock(mutex);
             int qsize = taskQueue1->size();
 
             // we have to make sure that a currently running autoscan task will not
             // launch add tasks for directories that anyway are going to be deleted
-            for (i = 0; i < qsize; i++)
-            {
+            for (i = 0; i < qsize; i++) {
                 Ref<GenericTask> t = taskQueue1->get(i);
                 invalidateAddTask(t, path);
             }
 
             qsize = taskQueue2->size();
-            for (i = 0; i < qsize; i++)
-            {
+            for (i = 0; i < qsize; i++) {
                 Ref<GenericTask> t = taskQueue2->get(i);
                 invalidateAddTask(t, path);
             }
 
             Ref<GenericTask> t = getCurrentTask();
-            if (t != nil)
-            {
+            if (t != nullptr) {
                 invalidateAddTask(t, path);
             }
-        } 
+        }
 
         addTask(task);
-    }
-    else
-    {
+    } else {
         _removeObject(objectID, all);
     }
 }
 
-void ContentManager::rescanDirectory(int objectID, int scanID, scan_mode_t scanMode, String descPath, bool cancellable)
+void ContentManager::rescanDirectory(int objectID, int scanID, ScanMode scanMode, String descPath, bool cancellable)
 {
     // building container path for the description
     Ref<GenericTask> task(new CMRescanDirectoryTask(objectID, scanID, scanMode, cancellable));
     Ref<AutoscanDirectory> dir = getAutoscanDirectory(scanID, scanMode);
-    if (dir == nil)
+    if (dir == nullptr)
         return;
 
     dir->incTaskCount();
     String level;
-    if (dir->getScanLevel() == BasicScanLevel)
+    if (dir->getScanLevel() == ScanLevel::Basic)
         level = _("basic");
     else
         level = _("full");
@@ -1943,37 +1594,32 @@ void ContentManager::rescanDirectory(int objectID, int scanID, scan_mode_t scanM
     addTask(task, true); // adding with low priority
 }
 
-
-Ref<AutoscanDirectory> ContentManager::getAutoscanDirectory(int scanID, scan_mode_t scanMode)
+Ref<AutoscanDirectory> ContentManager::getAutoscanDirectory(int scanID, ScanMode scanMode)
 {
-    if (scanMode == TimedScanMode)
-    {
+    if (scanMode == ScanMode::Timed) {
         return autoscan_timed->get(scanID);
     }
 
 #if HAVE_INOTIFY
-    else if (scanMode == InotifyScanMode)
-    {
+    else if (scanMode == ScanMode::INotify) {
         return autoscan_inotify->get(scanID);
     }
 #endif
-    return nil;
+    return nullptr;
 }
 
-Ref<Array<AutoscanDirectory> > ContentManager::getAutoscanDirectories(scan_mode_t scanMode)
+Ref<Array<AutoscanDirectory> > ContentManager::getAutoscanDirectories(ScanMode scanMode)
 {
-    if (scanMode == TimedScanMode)
-    {
+    if (scanMode == ScanMode::Timed) {
         return autoscan_timed->getArrayCopy();
     }
 
 #if HAVE_INOTIFY
-    else if (scanMode == InotifyScanMode)
-    {
+    else if (scanMode == ScanMode::INotify) {
         return autoscan_inotify->getArrayCopy();
     }
 #endif
-    return nil;
+    return nullptr;
 }
 
 Ref<Array<AutoscanDirectory> > ContentManager::getAutoscanDirectories()
@@ -1982,8 +1628,8 @@ Ref<Array<AutoscanDirectory> > ContentManager::getAutoscanDirectories()
 
 #if HAVE_INOTIFY
     Ref<Array<AutoscanDirectory> > ino = autoscan_inotify->getArrayCopy();
-    if (ino != nil)
-        for (int i = 0; i < ino->size(); i ++)
+    if (ino != nullptr)
+        for (int i = 0; i < ino->size(); i++)
             all->append(ino->get(i));
 #endif
     return all;
@@ -1994,71 +1640,63 @@ Ref<AutoscanDirectory> ContentManager::getAutoscanDirectory(String location)
     // \todo change this when more scanmodes become available
     Ref<AutoscanDirectory> dir = autoscan_timed->get(location);
 #if HAVE_INOTIFY
-    if (dir == nil)
+    if (dir == nullptr)
         dir = autoscan_inotify->get(location);
 #endif
     return dir;
 }
 
-void ContentManager::removeAutoscanDirectory(int scanID, scan_mode_t scanMode)
+void ContentManager::removeAutoscanDirectory(int scanID, ScanMode scanMode)
 {
-    if (scanMode == TimedScanMode)
-    {
+    if (scanMode == ScanMode::Timed) {
         Ref<Storage> storage = Storage::getInstance();
         Ref<AutoscanDirectory> adir = autoscan_timed->get(scanID);
-        if (adir == nil)
+        if (adir == nullptr)
             throw _Exception(_("can not remove autoscan directory - was not an autoscan"));
 
         autoscan_timed->remove(scanID);
         storage->removeAutoscanDirectory(adir->getStorageID());
         SessionManager::getInstance()->containerChangedUI(adir->getObjectID());
-        
-        // if 3rd parameter is true: won't fail if scanID doesn't exist
-        Timer::getInstance()->removeTimerSubscriber(AS_TIMER_SUBSCRIBER_SINGLETON(this), adir->getTimerParameter(), true);
 
+        // if 3rd parameter is true: won't fail if scanID doesn't exist
+        Timer::getInstance()->removeTimerSubscriber(this, adir->getTimerParameter(), true);
     }
 #ifdef HAVE_INOTIFY
-    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY))
-    {
-        if (scanMode == InotifyScanMode)
-        {
+    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY)) {
+        if (scanMode == ScanMode::INotify) {
             Ref<Storage> storage = Storage::getInstance();
             Ref<AutoscanDirectory> adir = autoscan_inotify->get(scanID);
-            if (adir == nil)
+            if (adir == nullptr)
                 throw _Exception(_("can not remove autoscan directory - was not an autoscan"));
             autoscan_inotify->remove(scanID);
             storage->removeAutoscanDirectory(adir->getStorageID());
             SessionManager::getInstance()->containerChangedUI(adir->getObjectID());
-            inotify->unmonitor(adir);
+            AutoscanInotify::getInstance()->unmonitor(adir);
         }
     }
 #endif
-    
 }
 
 void ContentManager::removeAutoscanDirectory(int objectID)
 {
     Ref<Storage> storage = Storage::getInstance();
     Ref<AutoscanDirectory> adir = storage->getAutoscanDirectory(objectID);
-    if (adir == nil)
+    if (adir == nullptr)
         throw _Exception(_("can not remove autoscan directory - was not an autoscan"));
 
-    if (adir->getScanMode() == TimedScanMode)
-    {
+    if (adir->getScanMode() == ScanMode::Timed) {
         autoscan_timed->remove(adir->getLocation());
         storage->removeAutoscanDirectoryByObjectID(objectID);
         SessionManager::getInstance()->containerChangedUI(objectID);
-        Timer::getInstance()->removeTimerSubscriber(AS_TIMER_SUBSCRIBER_SINGLETON(this), adir->getTimerParameter(), true);
+        Timer::getInstance()->removeTimerSubscriber(this, adir->getTimerParameter(), true);
     }
 #ifdef HAVE_INOTIFY
-    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY))
-    {
-        if (adir->getScanMode() == InotifyScanMode)
-        {
+    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY)) {
+        if (adir->getScanMode() == ScanMode::INotify) {
             autoscan_inotify->remove(adir->getLocation());
             storage->removeAutoscanDirectoryByObjectID(objectID);
             SessionManager::getInstance()->containerChangedUI(objectID);
-            inotify->unmonitor(adir);
+            AutoscanInotify::getInstance()->unmonitor(adir);
         }
     }
 #endif
@@ -2069,35 +1707,31 @@ void ContentManager::removeAutoscanDirectory(String location)
     /// \todo change this when more scanmodes become avaiable
     Ref<AutoscanDirectory> adir = autoscan_timed->get(location);
 #ifdef HAVE_INOTIFY
-    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY))
-    {
-        if (adir == nil)
+    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY)) {
+        if (adir == nullptr)
             adir = autoscan_inotify->get(location);
     }
 #endif
-    if (adir == nil)
+    if (adir == nullptr)
         throw _Exception(_("can not remove autoscan directory - was not an autoscan"));
-    
+
     removeAutoscanDirectory(adir->getObjectID());
 }
 
-void ContentManager::handlePeristentAutoscanRemove(int scanID, scan_mode_t scanMode)
+void ContentManager::handlePeristentAutoscanRemove(int scanID, ScanMode scanMode)
 {
     Ref<AutoscanDirectory> adir = getAutoscanDirectory(scanID, scanMode);
     Ref<Storage> st = Storage::getInstance();
-    if (adir->persistent())
-    {
+    if (adir->persistent()) {
         adir->setObjectID(INVALID_OBJECT_ID);
         st->updateAutoscanDirectory(adir);
-    }
-    else
-    {
+    } else {
         removeAutoscanDirectory(adir->getScanID(), adir->getScanMode());
         st->removeAutoscanDirectory(adir->getStorageID());
     }
 }
 
-void ContentManager::handlePersistentAutoscanRecreate(int scanID, scan_mode_t scanMode)
+void ContentManager::handlePersistentAutoscanRecreate(int scanID, ScanMode scanMode)
 {
     Ref<AutoscanDirectory> adir = getAutoscanDirectory(scanID, scanMode);
     int id = ensurePathExistence(adir->getLocation());
@@ -2113,53 +1747,47 @@ void ContentManager::setAutoscanDirectory(Ref<AutoscanDirectory> dir)
     // We will have to change this for other scan modes
     original = autoscan_timed->getByObjectID(dir->getObjectID());
 #ifdef HAVE_INOTIFY
-    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY))
-    {
-        if (original == nil)
+    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY)) {
+        if (original == nullptr)
             original = autoscan_inotify->getByObjectID(dir->getObjectID());
     }
 #endif
 
-    if (original != nil)
+    if (original != nullptr)
         dir->setStorageID(original->getStorageID());
 
     storage->checkOverlappingAutoscans(dir);
 
     // adding a new autoscan directory
-    if (original == nil)
-    {
+    if (original == nullptr) {
         if (dir->getObjectID() == CDS_ID_FS_ROOT)
             dir->setLocation(_(FS_ROOT_DIRECTORY));
-        else
-        {
+        else {
             log_debug("objectID: %d\n", dir->getObjectID());
             Ref<CdsObject> obj = storage->loadObject(dir->getObjectID());
-            if (obj == nil
-                    || ! IS_CDS_CONTAINER(obj->getObjectType())
-                    || obj->isVirtual())
+            if (obj == nullptr
+                || !IS_CDS_CONTAINER(obj->getObjectType())
+                || obj->isVirtual())
                 throw _Exception(_("tried to remove an illegal object (id) from the list of the autoscan directories"));
-            
+
             log_debug("location: %s\n", obj->getLocation().c_str());
-            
+
             if (!string_ok(obj->getLocation()))
                 throw _Exception(_("tried to add an illegal object as autoscan - no location information available!"));
-    
+
             dir->setLocation(obj->getLocation());
         }
         dir->resetLMT();
         storage->addAutoscanDirectory(dir);
-        if (dir->getScanMode() == TimedScanMode)
-        {
+        if (dir->getScanMode() == ScanMode::Timed) {
             autoscan_timed->add(dir);
             timerNotify(dir->getTimerParameter());
         }
 #ifdef HAVE_INOTIFY
-        if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY))
-        {
-            if (dir->getScanMode() == InotifyScanMode)
-            {
+        if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY)) {
+            if (dir->getScanMode() == ScanMode::INotify) {
                 autoscan_inotify->add(dir);
-                inotify->monitor(dir);
+                AutoscanInotify::getInstance()->monitor(dir);
             }
         }
 #endif
@@ -2167,14 +1795,12 @@ void ContentManager::setAutoscanDirectory(Ref<AutoscanDirectory> dir)
         return;
     }
 
-    if (original->getScanMode() == TimedScanMode)
-        Timer::getInstance()->removeTimerSubscriber(AS_TIMER_SUBSCRIBER_SINGLETON(this), original->getTimerParameter(), true);
+    if (original->getScanMode() == ScanMode::Timed)
+        Timer::getInstance()->removeTimerSubscriber(this, original->getTimerParameter(), true);
 #ifdef HAVE_INOTIFY
-    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY))
-    {
-        if (original->getScanMode() == InotifyScanMode)
-        {
-            inotify->unmonitor(original);
+    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY)) {
+        if (original->getScanMode() == ScanMode::INotify) {
+            AutoscanInotify::getInstance()->unmonitor(original);
         }
     }
 #endif
@@ -2183,15 +1809,10 @@ void ContentManager::setAutoscanDirectory(Ref<AutoscanDirectory> dir)
     original->copyTo(copy);
 
     // changing from full scan to basic scan need to reset last modification time
-    if ((copy->getScanLevel() == FullScanLevel) && (dir->getScanLevel() == BasicScanLevel))
-    {
-        copy->setScanLevel(BasicScanLevel);
+    if ((copy->getScanLevel() == ScanLevel::Full) && (dir->getScanLevel() == ScanLevel::Basic)) {
+        copy->setScanLevel(ScanLevel::Basic);
         copy->resetLMT();
-    } 
-    else if (((copy->getScanLevel() == FullScanLevel) &&
-             (dir->getScanLevel() == FullScanLevel)) && 
-             (!copy->getRecursive() && dir->getRecursive()))
-    {
+    } else if (((copy->getScanLevel() == ScanLevel::Full) && (dir->getScanLevel() == ScanLevel::Full)) && (!copy->getRecursive() && dir->getRecursive())) {
         copy->resetLMT();
     }
 
@@ -2200,15 +1821,12 @@ void ContentManager::setAutoscanDirectory(Ref<AutoscanDirectory> dir)
     copy->setRecursive(dir->getRecursive());
     copy->setInterval(dir->getInterval());
 
-    if (copy->getScanMode() == TimedScanMode)
-    {
+    if (copy->getScanMode() == ScanMode::Timed) {
         autoscan_timed->remove(copy->getScanID());
     }
 #ifdef HAVE_INOTIFY
-    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY))
-    {
-        if (copy->getScanMode() == InotifyScanMode)
-        {
+    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY)) {
+        if (copy->getScanMode() == ScanMode::INotify) {
             autoscan_inotify->remove(copy->getScanID());
         }
     }
@@ -2216,18 +1834,15 @@ void ContentManager::setAutoscanDirectory(Ref<AutoscanDirectory> dir)
 
     copy->setScanMode(dir->getScanMode());
 
-    if (dir->getScanMode() == TimedScanMode)
-    {
+    if (dir->getScanMode() == ScanMode::Timed) {
         autoscan_timed->add(copy);
         timerNotify(copy->getTimerParameter());
     }
 #ifdef HAVE_INOTIFY
-    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY))
-    {
-        if (dir->getScanMode() == InotifyScanMode)
-        {
+    if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY)) {
+        if (dir->getScanMode() == ScanMode::INotify) {
             autoscan_inotify->add(copy);
-            inotify->monitor(copy);
+            AutoscanInotify::getInstance()->monitor(copy);
         }
     }
 #endif
@@ -2238,87 +1853,76 @@ void ContentManager::setAutoscanDirectory(Ref<AutoscanDirectory> dir)
 }
 
 #ifdef HAVE_MAGIC
-zmm::String ContentManager::getMimeTypeFromBuffer(void *buffer, size_t length)
+zmm::String ContentManager::getMimeTypeFromBuffer(const void* buffer, size_t length)
 {
-    return get_mime_type_from_buffer(ms, reMimetype, buffer, length); 
+    return get_mime_type_from_buffer(ms, reMimetype, buffer, length);
 }
 #endif
 
 #ifdef YOUTUBE
 void ContentManager::checkCachedURLs()
 {
-    AUTOLOCK(urlcache_mutex);
+    AutoLockYT lock(urlcache_mutex);
 
-    time_t now = time(NULL);
+    time_t now = time(nullptr);
 
     log_debug("Checking cached URLs..stored: %d\n", cached_urls->size());
     int count = 0;
     int i = 0;
 
-    while (count < cached_urls->size())
-    {
+    while (count < cached_urls->size()) {
         Ref<CachedURL> cached = cached_urls->get(i);
-        if (cached != nil)
-        {
+        if (cached != nullptr) {
             // do not increment index because remove unordered places the
             // last array element into the removed slot
-            if ((cached->getLastAccessTime() + URL_CACHE_LIFETIME) < now)
-            {
+            if ((cached->getLastAccessTime() + URL_CACHE_LIFETIME) < now) {
                 log_debug("URL of object: %d, url: %s exceeds "
-                          "lifetime (%lld < %lld), purging...\n", 
-                          cached_urls->get(i)->getObjectID(), 
-                          cached_urls->get(i)->getURL().c_str(), 
-                        (long long)(cached->getLastAccessTime() + 
-                            URL_CACHE_LIFETIME), 
-                        (long long)now);
+                          "lifetime (%lld < %lld), purging...\n",
+                    cached_urls->get(i)->getObjectID(),
+                    cached_urls->get(i)->getURL().c_str(),
+                    (long long)(cached->getLastAccessTime() + URL_CACHE_LIFETIME),
+                    (long long)now);
                 cached_urls->removeUnordered(i);
-            }
-            else
+            } else
                 i++;
         }
-        count++; 
+        count++;
     }
 
     log_debug("URL Cache check complete, remaining items: %d\n",
-            cached_urls->size());
+        cached_urls->size());
 
-    if (cached_urls->size() > 0)
-    {
-        Ref<TimerParameter> url_cache_check(new 
-                TimerParameter(TimerParameter::IDURLCache, -1));
+    if (cached_urls->size() > 0) {
+        Ref<Timer::Parameter> url_cache_check(new Timer::Parameter(Timer::Parameter::IDURLCache, -1));
 
         Timer::getInstance()->addTimerSubscriber(
-                AS_TIMER_SUBSCRIBER_SINGLETON(this), 
-                URL_CACHE_CHECK_INTERVAL, 
-                RefCast(url_cache_check, Object), true);
+            this,
+            URL_CACHE_CHECK_INTERVAL,
+            url_cache_check, true);
     }
 }
 
 void ContentManager::cacheURL(zmm::Ref<CachedURL> url)
 {
-    AUTOLOCK(urlcache_mutex);
-    time_t oldest = time(NULL); 
+    AutoLockYT lock(urlcache_mutex);
+    time_t oldest = time(nullptr);
     int oldest_index = -1;
     bool added = false;
     int old_size = cached_urls->size();
 
     log_debug("Request to cache id %d, URL %s\n", url->getObjectID(),
-              url->getURL().c_str());
-    for (int i = 0; i < cached_urls->size(); i++)
-    {
+        url->getURL().c_str());
+    for (int i = 0; i < cached_urls->size(); i++) {
         Ref<CachedURL> cached = cached_urls->get(i);
-        if (cached != nil)
-        {
+        if (cached != nullptr) {
             // get time of the first replacement candidate
-            if (cached->getLastAccessTime() < oldest)
-            {
+            if (cached->getLastAccessTime() < oldest) {
                 oldest = cached->getLastAccessTime();
                 oldest_index = i;
             }
 
-            // this is an update for the same object 
-            if (url->getObjectID() == cached->getObjectID())
-            {
+            // this is an update for the same object
+            if (url->getObjectID() == cached->getObjectID()) {
                 log_debug("Updating cache for object %d\n", url->getObjectID());
                 cached_urls->set(url, i);
                 added = true;
@@ -2327,64 +1931,54 @@ void ContentManager::cacheURL(zmm::Ref<CachedURL> url)
         }
     }
 
-    if (!added)
-    {
+    if (!added) {
         // if our storage capacity is exceeded, we will purge an existing item
-        if (cached_urls->size() >= MAX_CACHED_URLS)
-        {
+        if (cached_urls->size() >= MAX_CACHED_URLS) {
             log_debug("Checking if we need to remove something old...");
-            if ((oldest_index > -1) && (oldest_index <= MAX_CACHED_URLS))
-            {
-                log_debug("Removing old url from cache of object %d\n", 
-                        cached_urls->get(oldest_index)->getObjectID());
+            if ((oldest_index > -1) && (oldest_index <= MAX_CACHED_URLS)) {
+                log_debug("Removing old url from cache of object %d\n",
+                    cached_urls->get(oldest_index)->getObjectID());
                 cached_urls->removeUnordered(oldest_index);
-            }
-            else
-            {
-                throw _Exception(_("Index exceeds URL cache size: ") +
-                                 String::from(oldest_index));
+            } else {
+                throw _Exception(_("Index exceeds URL cache size: ") + String::from(oldest_index));
             }
         }
-           
+
         log_debug("Appeinding url to the cache: %d\n", url->getObjectID());
         cached_urls->append(url);
     }
 
-    if ((cached_urls->size() > 0) && (old_size == 0)) 
-    {
+    if ((cached_urls->size() > 0) && (old_size == 0)) {
         log_debug("URL Cache is not empty, adding invalidation timer!\n");
-        Ref<TimerParameter> url_cache_check(new 
-                TimerParameter(TimerParameter::IDURLCache, -1));
+        Ref<Timer::Parameter> url_cache_check(new Timer::Parameter(Timer::Parameter::IDURLCache, -1));
 
         Timer::getInstance()->addTimerSubscriber(
-                AS_TIMER_SUBSCRIBER_SINGLETON(this), 
-                URL_CACHE_CHECK_INTERVAL, 
-                RefCast(url_cache_check, Object), true);
+            this,
+            URL_CACHE_CHECK_INTERVAL,
+            url_cache_check, true);
     }
 }
 
 String ContentManager::getCachedURL(int objectID)
 {
-    AUTOLOCK(urlcache_mutex);
+    AutoLockYT lock(urlcache_mutex);
     log_debug("Asked for an url from cache...\n");
-    for (int i = 0; i < cached_urls->size(); i++)
-    {
+    for (int i = 0; i < cached_urls->size(); i++) {
         Ref<CachedURL> cached = cached_urls->get(i);
-        if (cached != nil)
-        {
-            if (cached->getObjectID() == objectID)
-            {
+        if (cached != nullptr) {
+            if (cached->getObjectID() == objectID) {
                 log_debug("Found URL in cache for object ID %d, URL: %s\n",
-                        objectID, cached->getURL().c_str());
+                    objectID, cached->getURL().c_str());
                 return cached->getURL();
             }
         }
     }
-    return nil;
+    return nullptr;
 }
 #endif
 
-CMAddFileTask::CMAddFileTask(String path, String rootpath, bool recursive, bool hidden, bool cancellable) : GenericTask(ContentManagerTask)
+CMAddFileTask::CMAddFileTask(String path, String rootpath, bool recursive, bool hidden, bool cancellable)
+    : GenericTask(ContentManagerTask)
 {
     this->path = path;
     this->rootpath = rootpath;
@@ -2407,10 +2001,11 @@ void CMAddFileTask::run()
 {
     log_debug("running add file task with path %s recursive: %d\n", path.c_str(), recursive);
     Ref<ContentManager> cm = ContentManager::getInstance();
-    cm->_addFile(path, nil, recursive, hidden, Ref<GenericTask> (this));
+    cm->_addFile(path, nullptr, recursive, hidden, Ref<GenericTask>(this));
 }
 
-CMRemoveObjectTask::CMRemoveObjectTask(int objectID, bool all) : GenericTask(ContentManagerTask)
+CMRemoveObjectTask::CMRemoveObjectTask(int objectID, bool all)
+    : GenericTask(ContentManagerTask)
 {
     this->objectID = objectID;
     this->all = all;
@@ -2424,7 +2019,8 @@ void CMRemoveObjectTask::run()
     cm->_removeObject(objectID, all);
 }
 
-CMRescanDirectoryTask::CMRescanDirectoryTask(int objectID, int scanID, scan_mode_t scanMode, bool cancellable) : GenericTask(ContentManagerTask)
+CMRescanDirectoryTask::CMRescanDirectoryTask(int objectID, int scanID, ScanMode scanMode, bool cancellable)
+    : GenericTask(ContentManagerTask)
 {
     this->scanID = scanID;
     this->scanMode = scanMode;
@@ -2437,25 +2033,23 @@ void CMRescanDirectoryTask::run()
 {
     Ref<ContentManager> cm = ContentManager::getInstance();
     Ref<AutoscanDirectory> dir = cm->getAutoscanDirectory(scanID, scanMode);
-    if (dir == nil)
+    if (dir == nullptr)
         return;
 
-    cm->_rescanDirectory(objectID, dir->getScanID(), dir->getScanMode(), dir->getScanLevel(), Ref<GenericTask> (this));
+    cm->_rescanDirectory(objectID, dir->getScanID(), dir->getScanMode(), dir->getScanLevel(), Ref<GenericTask>(this));
     dir->decTaskCount();
-    
-    if (dir->getTaskCount() == 0)
-    {
+
+    if (dir->getTaskCount() == 0) {
         dir->updateLMT();
-        if (dir->getScanMode() == TimedScanMode)
-            Timer::getInstance()->addTimerSubscriber(AS_TIMER_SUBSCRIBER_SINGLETON_FROM_REF(cm), dir->getInterval(), dir->getTimerParameter(), true);
     }
 }
 
 #ifdef ONLINE_SERVICES
 CMFetchOnlineContentTask::CMFetchOnlineContentTask(Ref<OnlineService> service,
-                                                   Ref<Layout> layout,
-                                                   bool cancellable,
-                                                   bool unscheduled_refresh) : GenericTask(ContentManagerTask)
+    Ref<Layout> layout,
+    bool cancellable,
+    bool unscheduled_refresh)
+    : GenericTask(ContentManagerTask)
 {
     this->layout = layout;
     this->service = service;
@@ -2466,26 +2060,23 @@ CMFetchOnlineContentTask::CMFetchOnlineContentTask(Ref<OnlineService> service,
 
 void CMFetchOnlineContentTask::run()
 {
-    if (this->service == nil)
-    {
+    if (this->service == nullptr) {
         log_debug("Received invalid service!\n");
         return;
     }
-    try
-    {
-        Ref<GenericTask> t(new TPFetchOnlineContentTask(service, layout, 
-                                                   cancellable, 
-                                                   unscheduled_refresh));
+    try {
+        Ref<GenericTask> t(new TPFetchOnlineContentTask(service, layout,
+            cancellable,
+            unscheduled_refresh));
         TaskProcessor::getInstance()->addTask(t);
-    }
-    catch (Exception ex)
-    {
+    } catch (const Exception& ex) {
         log_error("%s\n", ex.getMessage().c_str());
     }
 }
-#endif//ONLINE_SERVICES
+#endif //ONLINE_SERVICES
 
-CMLoadAccountingTask::CMLoadAccountingTask() : GenericTask(ContentManagerTask)
+CMLoadAccountingTask::CMLoadAccountingTask()
+    : GenericTask(ContentManagerTask)
 {
     this->taskType = LoadAccounting;
 }
@@ -2496,7 +2087,8 @@ void CMLoadAccountingTask::run()
     cm->_loadAccounting();
 }
 
-CMAccounting::CMAccounting() : Object()
+CMAccounting::CMAccounting()
+    : Object()
 {
     totalFiles = 0;
 }
diff --git a/src/content_manager.h b/src/content_manager.h
index 3dd6a71..0e6b032 100644
--- a/src/content_manager.h
+++ b/src/content_manager.h
@@ -31,23 +31,24 @@
 #ifndef __CONTENT_MANAGER_H__
 #define __CONTENT_MANAGER_H__
 
+#include <memory>
+#include <unordered_set>
+#include <mutex>
+#include <condition_variable>
+
 #include "common.h"
 #include "cds_objects.h"
 #include "storage.h"
 #include "dictionary.h"
-#include "sync.h"
 #include "autoscan.h"
 #include "timer.h"
 #include "generic_task.h"
+
 #ifdef HAVE_JS
     // this is somewhat not nice, the playlist header needs the cm header and
     // vice versa
     class PlaylistParserScript;
     #include "scripting/playlist_parser_script.h"
-#ifdef HAVE_LIBDVDNAV
-    class DVDImportScript;
-    #include "scripting/dvd_image_import_script.h"
-#endif
 
 #endif
 #include "layout/layout.h"
@@ -88,7 +89,7 @@ public:
                   bool hidden=false, bool cancellable = true);
     zmm::String getPath();
     zmm::String getRootPath();
-    virtual void run();
+    virtual void run() override;
 };
 
 class CMRemoveObjectTask : public GenericTask
@@ -98,14 +99,14 @@ protected:
     bool all;
 public:
     CMRemoveObjectTask(int objectID, bool all);
-    virtual void run();
+    virtual void run() override;
 };
 
 class CMLoadAccountingTask : public GenericTask
 {
 public:
     CMLoadAccountingTask();
-    virtual void run();
+    virtual void run() override;
 };
 
 class CMRescanDirectoryTask : public GenericTask
@@ -113,11 +114,11 @@ class CMRescanDirectoryTask : public GenericTask
 protected: 
     int objectID;
     int scanID;
-    scan_mode_t scanMode;
+    ScanMode scanMode;
 public:
-    CMRescanDirectoryTask(int objectID, int scanID, scan_mode_t scanMode,
+    CMRescanDirectoryTask(int objectID, int scanID, ScanMode scanMode,
                           bool cancellable);
-    virtual void run();
+    virtual void run() override;
 };
 
 class CMAccounting : public zmm::Object
@@ -140,7 +141,7 @@ public:
     CMFetchOnlineContentTask(zmm::Ref<OnlineService> service, 
                              zmm::Ref<Layout> layout,
                              bool cancellable, bool unscheduled_refresh);
-    virtual void run();
+    virtual void run() override;
 };
 #endif
 
@@ -172,47 +173,15 @@ public:
 };
 */
 
-class ContentManager : public TimerSubscriberSingleton<ContentManager>
+class ContentManager : public Timer::Subscriber, public Singleton<ContentManager, std::recursive_mutex>
 {
 public:
-    /// \brief This is the parameter class for timerNotify
-    class TimerParameter : public zmm::Object
-    {
-    public:
-        enum timer_param_t
-        {
-            IDAutoscan,
-#ifdef ONLINE_SERVICES
-            IDOnlineContent,
-#ifdef YOUTUBE
-            IDURLCache
-#endif
-
-#endif
-        };
-
-        TimerParameter(timer_param_t param, int id) 
-        { 
-            this->param = param; 
-            this->id = id;
-        }
-
-        timer_param_t whoami()  { return param;  }
-        void setID(int id)       { this->id = id; }
-        int getID()             { return id;     }
-
-    protected:
-        timer_param_t param;
-        int id;
-    };
-
-
     ContentManager();
-    virtual void init();
+    void init() override;
     virtual ~ContentManager();
-    void shutdown();
+    void shutdown() override;
     
-    virtual void timerNotify(zmm::Ref<zmm::Object> parameter);
+    virtual void timerNotify(zmm::Ref<Timer::Parameter> parameter);
     
     bool isBusy() { return working; }
     
@@ -221,7 +190,7 @@ public:
     /// \brief Returns the task that is currently being executed.
     zmm::Ref<GenericTask> getCurrentTask();
 
-    /// \brief Returns the list of all enqueued tasks, including the current or nil if no tasks are present.
+    /// \brief Returns the list of all enqueued tasks, including the current or nullptr if no tasks are present.
     zmm::Ref<zmm::Array<GenericTask> > getTasklist();
 
     /// \brief Find a task identified by the task ID and invalidate it.
@@ -246,8 +215,8 @@ public:
 
     int ensurePathExistence(zmm::String path);
     void removeObject(int objectID, bool async=true, bool all=false);
-    void rescanDirectory(int objectID, int scanID, scan_mode_t scanMode,
-                         zmm::String descPath = nil, bool cancellable = true);
+    void rescanDirectory(int objectID, int scanID, ScanMode scanMode,
+                         zmm::String descPath = nullptr, bool cancellable = true);
 
     /// \brief Updates an object in the database using the given parameters.
     /// \param objectID ID of the object to update
@@ -295,13 +264,13 @@ public:
     /// \brief Adds a virtual container chain specified by path.
     /// \param container path separated by '/'. Slashes in container
     /// titles must be escaped.
-    /// \param lastClass upnp:class of the last container in the chain, if nil
+    /// \param lastClass upnp:class of the last container in the chain, if nullptr
     /// then the default class will be taken
     /// \param lastRefID reference id of the last container in the chain,
     /// INVALID_OBJECT_ID indicates that the id will not be set. 
     /// \return ID of the last container in the chain.
-    int addContainerChain(zmm::String chain, zmm::String lastClass = nil,
-            int lastRefID = INVALID_OBJECT_ID);
+    int addContainerChain(zmm::String chain, zmm::String lastClass = nullptr,
+            int lastRefID = INVALID_OBJECT_ID, zmm::Ref<Dictionary> lastMetadata = nullptr);
     
     /// \brief Adds a virtual container specified by parentID and title
     /// \param parentID the id of the parent.
@@ -322,12 +291,12 @@ public:
     zmm::Ref<CdsObject> convertObject(zmm::Ref<CdsObject> obj, int objectType);
 
     /// \brief Gets an AutocsanDirectrory from the watch list.
-    zmm::Ref<AutoscanDirectory> getAutoscanDirectory(int scanID, scan_mode_t scanMode);
+    zmm::Ref<AutoscanDirectory> getAutoscanDirectory(int scanID, ScanMode scanMode);
 
     /// \brief Get an AutoscanDirectory given by location on disk from the watch list.
     zmm::Ref<AutoscanDirectory> getAutoscanDirectory(zmm::String location);
     /// \brief Removes an AutoscanDirectrory (found by scanID) from the watch list.
-    void removeAutoscanDirectory(int scanID, scan_mode_t scanMode);
+    void removeAutoscanDirectory(int scanID, ScanMode scanMode);
 
     /// \brief Removes an AutoscanDirectrory (found by location) from the watch list.
     void removeAutoscanDirectory(zmm::String location);
@@ -340,13 +309,13 @@ public:
     void setAutoscanDirectory(zmm::Ref<AutoscanDirectory> dir);
 
     /// \brief handles the removal of a persistent autoscan directory
-    void handlePeristentAutoscanRemove(int scanID, scan_mode_t scanMode);
+    void handlePeristentAutoscanRemove(int scanID, ScanMode scanMode);
 
     /// \brief handles the recreation of a persistent autoscan directory
-    void handlePersistentAutoscanRecreate(int scanID, scan_mode_t scanMode);
+    void handlePersistentAutoscanRecreate(int scanID, ScanMode scanMode);
 
     /// \brief returns an array of autoscan directories for the given scan mode
-    zmm::Ref<zmm::Array<AutoscanDirectory> > getAutoscanDirectories(scan_mode_t scanMode);
+    zmm::Ref<zmm::Array<AutoscanDirectory> > getAutoscanDirectories(ScanMode scanMode);
 
     /// \brief returns an array of all autoscan directories 
     zmm::Ref<zmm::Array<AutoscanDirectory> > getAutoscanDirectories();
@@ -374,7 +343,7 @@ public:
 #endif
 
 #ifdef HAVE_MAGIC
-    zmm::String getMimeTypeFromBuffer(void *buffer, size_t length);
+    zmm::String getMimeTypeFromBuffer(const void *buffer, size_t length);
 #endif
 protected:
     void initLayout();
@@ -397,11 +366,9 @@ protected:
     zmm::Ref<AutoscanList> autoscan_timed;
 #ifdef HAVE_INOTIFY
     zmm::Ref<AutoscanList> autoscan_inotify;
-    zmm::Ref<AutoscanInotify> inotify;
 #endif
  
 #if defined(EXTERNAL_TRANSCODING) || defined(SOPCAST)
-    zmm::Ref<Mutex> pr_mutex;
     zmm::Ref<zmm::Array<Executor> > process_list;
 #endif
 
@@ -413,11 +380,11 @@ protected:
                         bool lowPriority=false, 
                         unsigned int parentTaskID = 0,
                         bool cancellable = true);
-    int _addFile(zmm::String path, zmm::String rootpath, bool recursive=false, bool hidden=false, zmm::Ref<GenericTask> task=nil);
+    int _addFile(zmm::String path, zmm::String rootpath, bool recursive=false, bool hidden=false, zmm::Ref<GenericTask> task=nullptr);
     //void _addFile2(zmm::String path, bool recursive=0);
     void _removeObject(int objectID, bool all);
     
-    void _rescanDirectory(int containerID, int scanID, scan_mode_t scanMode, scan_level_t scanLevel, zmm::Ref<GenericTask> task=nil);
+    void _rescanDirectory(int containerID, int scanID, ScanMode scanMode, ScanLevel scanLevel, zmm::Ref<GenericTask> task=nullptr);
     /* for recursive addition */
     void addRecursive(zmm::String path, bool hidden, zmm::Ref<GenericTask> task);
     //void addRecursive2(zmm::Ref<DirCache> dirCache, zmm::String filename, bool recursive);
@@ -438,12 +405,9 @@ protected:
                                     unsigned int parentTaskID = 0,
                                     bool unscheduled_refresh = false);
 
-    void _fetchOnlineContent(zmm::Ref<OnlineService>, 
-                             unsigned int parentTaskID, 
-                             bool unscheduled_refresh);
-
 #ifdef YOUTUBE
-    zmm::Ref<Mutex> urlcache_mutex;
+    std::mutex urlcache_mutex;
+    using AutoLockYT = std::lock_guard<std::mutex>;
     zmm::Ref<ReentrantArray<CachedURL> > cached_urls;
     /// \brief Removes old URLs from the cache.
     void checkCachedURLs();
@@ -453,16 +417,13 @@ protected:
 
 #ifdef HAVE_JS
     zmm::Ref<PlaylistParserScript> playlist_parser_script;
-#ifdef HAVE_LIBDVDNAV
-    zmm::Ref<DVDImportScript> dvd_import_script;
-#endif
 #endif
 
     bool layout_enabled;
     
     void setLastModifiedTime(time_t lm);
     
-    inline void signal() { cond->signal(); }
+    inline void signal() { cond.notify_one(); }
     static void *staticThreadProc(void *arg);
     void threadProc();
     
@@ -471,7 +432,7 @@ protected:
     zmm::Ref<CMAccounting> acct;
     
     pthread_t taskThread;
-    zmm::Ref<Cond> cond;
+    std::condition_variable_any cond;
     
     bool working;
     
diff --git a/src/curl_io_handler.cc b/src/curl_io_handler.cc
index 0ee2193..9e0dcca 100644
--- a/src/curl_io_handler.cc
+++ b/src/curl_io_handler.cc
@@ -29,10 +29,6 @@
 
 /// \file curl_io_handler.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_CURL
 
 #include "config_manager.h"
@@ -40,6 +36,7 @@
 #include "curl_io_handler.h"
 
 using namespace zmm;
+using namespace std;
 
 CurlIOHandler::CurlIOHandler(String URL, CURL *curl_handle, size_t bufSize, size_t initialFillSize) : IOHandlerBufferHelper(bufSize, initialFillSize)
 {
@@ -49,7 +46,7 @@ CurlIOHandler::CurlIOHandler(String URL, CURL *curl_handle, size_t bufSize, size
         throw _Exception(_("bufSize must be at least CURL_MAX_WRITE_SIZE(")+CURL_MAX_WRITE_SIZE+')');
     
     this->URL = URL;
-    this->external_curl_handle = (curl_handle != NULL);
+    this->external_curl_handle = (curl_handle != nullptr);
     this->curl_handle = curl_handle;
     //bytesCurl = 0;
     signalAfterEveryRead = true;
@@ -61,10 +58,10 @@ CurlIOHandler::CurlIOHandler(String URL, CURL *curl_handle, size_t bufSize, size
 
 void CurlIOHandler::open(IN enum UpnpOpenFileMode mode)
 {
-    if (curl_handle == NULL)
+    if (curl_handle == nullptr)
     {
         curl_handle = curl_easy_init();
-        if (curl_handle == NULL)
+        if (curl_handle == nullptr)
             throw _Exception(_("failed to init curl"));
     }
     else
@@ -77,14 +74,14 @@ void CurlIOHandler::close()
 {
     IOHandlerBufferHelper::close();
     
-    if (external_curl_handle && curl_handle != NULL)
+    if (external_curl_handle && curl_handle != nullptr)
         curl_easy_cleanup(curl_handle);
 }
 
 void CurlIOHandler::threadProc()
 {
     CURLcode res;
-    assert(curl_handle != NULL);
+    assert(curl_handle != nullptr);
     assert(string_ok(URL));
     
     //char error_buffer[CURL_ERROR_SIZE] = {'\0'};
@@ -111,10 +108,10 @@ void CurlIOHandler::threadProc()
     curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, CurlIOHandler::curlCallback);
     curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)this);
     
-    AUTOLOCK_NOLOCK(mutex);
+    unique_lock<std::mutex> lock(mutex, std::defer_lock);
     do
     {
-        AUTORELOCK();
+        lock.lock();
         if (doSeek)
         {
             log_debug("SEEK: %lld %d\n", seekOffset, seekWhence);
@@ -139,9 +136,9 @@ void CurlIOHandler::threadProc()
             waitForInitialFillSize = (initialFillSize > 0);
             
             doSeek = false;
-            cond->signal();
+            cond.notify_one();
         }
-        AUTOUNLOCK();
+        lock.unlock();
         res = curl_easy_perform(curl_handle);
     }
     while (doSeek);
@@ -151,21 +148,21 @@ void CurlIOHandler::threadProc()
     else
         eof = true;
     
-    cond->signal();
+    cond.notify_one();
 }
 
 
 
 size_t CurlIOHandler::curlCallback(void *ptr, size_t size, size_t nmemb, void *data)
 {
-    CurlIOHandler * ego = (CurlIOHandler *) data;
+    auto * ego = (CurlIOHandler *) data;
     size_t wantWrite = size * nmemb;
     
     assert(wantWrite <= ego->bufSize);
     
     //log_debug("URL: %s; size: %d; nmemb: %d; wantWrite: %d\n", ego->URL.c_str(), size, nmemb, wantWrite);
     
-    AUTOLOCK(ego->mutex);
+    unique_lock<std::mutex> lock(ego->mutex);
     
     bool first = true;
     
@@ -201,7 +198,7 @@ size_t CurlIOHandler::curlCallback(void *ptr, size_t size, size_t nmemb, void *d
                 /// \todo do we need to wait for initialFillSize again?
             
                 ego->doSeek = false;
-                ego->cond->signal();
+                ego->cond.notify_one();
             }
         }
         
@@ -220,7 +217,7 @@ size_t CurlIOHandler::curlCallback(void *ptr, size_t size, size_t nmemb, void *d
         
         if (! first)
         {
-            ego->cond->wait();
+            ego->cond.wait(lock);
         }
         else
             first = false;
@@ -249,13 +246,13 @@ size_t CurlIOHandler::curlCallback(void *ptr, size_t size, size_t nmemb, void *d
     
     size_t bLocal = ego->b;
     
-    AUTOUNLOCK();
+    lock.unlock();
     
     memcpy(ego->buffer + bLocal, ptr, write1);
     if (write2)
         memcpy(ego->buffer, (char *)ptr + maxWrite, write2);
     
-    AUTORELOCK();
+    lock.lock();
     
     //ego->bytesCurl += wantWrite;
     ego->b += wantWrite;
@@ -264,7 +261,7 @@ size_t CurlIOHandler::curlCallback(void *ptr, size_t size, size_t nmemb, void *d
     if (ego->empty)
     {
         ego->empty = false;
-        ego->cond->signal();
+        ego->cond.notify_one();
     }
     if (ego->waitForInitialFillSize)
     {
@@ -275,7 +272,7 @@ size_t CurlIOHandler::curlCallback(void *ptr, size_t size, size_t nmemb, void *d
         {
             log_debug("buffer: initial fillsize reached\n");
             ego->waitForInitialFillSize = false;
-            ego->cond->signal();
+            ego->cond.notify_one();
         }
     }
     
diff --git a/src/curl_io_handler.h b/src/curl_io_handler.h
index 7d9944a..8cbc260 100644
--- a/src/curl_io_handler.h
+++ b/src/curl_io_handler.h
@@ -35,8 +35,9 @@
 #define __CURL_IO_HANDLER_H__
 
 #include <curl/curl.h>
+#include <upnp-1.8/upnp.h>
+
 #include "common.h"
-#include "upnp.h"
 #include "io_handler_buffer_helper.h"
 
 class CurlIOHandler : public IOHandlerBufferHelper
diff --git a/src/destroyer.cc b/src/destroyer.cc
index d179d06..9abcd66 100644
--- a/src/destroyer.cc
+++ b/src/destroyer.cc
@@ -29,10 +29,6 @@
 
 /// \file destroyer.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "destroyer.h"
 
 using namespace zmm;
@@ -51,6 +47,6 @@ void Destroyer::destroy()
     if (destroy_func)
     {
         destroy_func(data);
-        destroy_func = NULL;
+        destroy_func = nullptr;
     }
 }
diff --git a/src/dictionary.cc b/src/dictionary.cc
index 4a61907..b4a4206 100644
--- a/src/dictionary.cc
+++ b/src/dictionary.cc
@@ -29,13 +29,9 @@
 
 /// \file dictionary.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "dictionary.h"
 
-#include <string.h>
+#include <cstring>
 #include "tools.h"
 
 using namespace zmm;
@@ -98,7 +94,7 @@ String Dictionary::get(String key)
             return el->getValue();
         }
     }
-    return nil;
+    return nullptr;
 }
 
 int Dictionary::size()
@@ -146,16 +142,16 @@ String Dictionary::encodeSimple()
 
 void Dictionary::decode(String url)
 {
-    char *data = url.c_str();
-    char *dataEnd = data + url.length();
+    const char *data = url.c_str();
+    const char *dataEnd = data + url.length();
     while (data < dataEnd)
     {
-        char *ampPos = strchr(data, '&');
+        const char *ampPos = strchr(data, '&');
         if (!ampPos)
         {
             ampPos = dataEnd;
         }
-        char *eqPos = strchr(data, '=');
+        const char *eqPos = strchr(data, '=');
         if(eqPos && eqPos < ampPos)
         {
             String key(data, eqPos - data);
@@ -216,7 +212,7 @@ Ref<Dictionary> Dictionary::clone()
 
 void Dictionary::merge(Ref<Dictionary> other)
 {
-    if (other == nil)
+    if (other == nullptr)
         return;
 
     Ref<Array<DictionaryElement> > other_el = other->getElements();
@@ -235,9 +231,9 @@ bool Dictionary::isSubsetOf(Ref<Dictionary> other)
     {
         Ref<DictionaryElement> el = elements->get(i);
         if (el->getValue() != other->get(el->getKey()))
-            return 0;
+            return false;
     }
-    return 1;
+    return true;
 }
 bool Dictionary::equals(Ref<Dictionary> other)
 {
diff --git a/src/dictionary.h b/src/dictionary.h
index 9f1f07e..3ba7e7e 100644
--- a/src/dictionary.h
+++ b/src/dictionary.h
@@ -32,8 +32,8 @@
 #ifndef __DICTIONARY_H__
 #define __DICTIONARY_H__
 
-#include "zmmf/zmmf.h"
-#include "sync.h"
+#include <mutex>
+#include "zmm/zmmf.h"
 
 /// \brief This class should never be used directly, it is being used by the Dictionary class.
 class DictionaryElement : public zmm::Object
@@ -126,96 +126,65 @@ public:
 class Dictionary_r : public Dictionary
 {
 public:
-    Dictionary_r() : Dictionary()
-    {
-        mutex = zmm::Ref<Mutex>(new Mutex(true));
-    }
-    
-    inline void put(zmm::String key, zmm::String value)
-    {
-        mutex->lock();
+    inline void put(zmm::String key, zmm::String value) {
+        AutoLock lock(mutex);
         Dictionary::put(key, value);
-        mutex->unlock();
     }
     
-    inline zmm::String get(zmm::String key)
-    {
-        mutex->lock();
-        zmm::String ret = Dictionary::get(key);
-        mutex->unlock();
-        return ret;
+    inline zmm::String get(zmm::String key) {
+        AutoLock lock(mutex);
+        return Dictionary::get(key);
     }
     
-    inline void remove(zmm::String key)
-    {
-        mutex->lock();
+    inline void remove(zmm::String key) {
+        AutoLock lock(mutex);
         Dictionary::remove(key);
-        mutex->unlock();
     }
     
-    inline zmm::String encode()
-    {
-        mutex->lock();
-        zmm::String ret = Dictionary::encode();
-        mutex->unlock();
-        return ret;
+    inline zmm::String encode() {
+        AutoLock lock(mutex);
+        return Dictionary::encode();
     }
     
-    inline void clear()
-    {
-        mutex->lock();
+    inline void clear() {
+        AutoLock lock(mutex);
         Dictionary::clear();
-        mutex->unlock();
     }
     
-    inline void decode(zmm::String url)
-    {
-        mutex->lock();
+    inline void decode(zmm::String url) {
+        AutoLock lock(mutex);
         Dictionary::decode(url);
-        mutex->unlock();
     }
     
-    inline zmm::Ref<Dictionary_r> clone()
-    {
-        mutex->lock();
+    inline zmm::Ref<Dictionary_r> clone() {
+        AutoLock lock(mutex);
         zmm::Ref<Dictionary_r> ret = RefCast(Dictionary::clone(), Dictionary_r);
-        mutex->unlock();
         return ret;
     }
     
-    inline bool isSubsetOf(zmm::Ref<Dictionary> other)
-    {
-        mutex->lock();
-        bool ret = Dictionary::isSubsetOf(other);
-        mutex->unlock();
-        return ret;
+    inline bool isSubsetOf(zmm::Ref<Dictionary> other) {
+        AutoLock lock(mutex);
+        return Dictionary::isSubsetOf(other);
     }
     
-    inline bool equals(zmm::Ref<Dictionary> other)
-    {
-        mutex->lock();
-        bool ret = Dictionary::equals(other);
-        mutex->unlock();
-        return ret;
-    }                                                                         
+    inline bool equals(zmm::Ref<Dictionary> other) {
+        AutoLock lock(mutex);
+        return Dictionary::equals(other);
+    }
     
-    inline zmm::Ref<zmm::Array<DictionaryElement> > getElements()
-    {
-        mutex->lock();
-        zmm::Ref<zmm::Array<DictionaryElement> > ret = Dictionary::getElements();
-        mutex->unlock();
-        return ret;
+    inline zmm::Ref<zmm::Array<DictionaryElement> > getElements() {
+        AutoLock lock(mutex);
+        return Dictionary::getElements();
     }
     
-    inline void optimize()
-    {
-        mutex->lock();
+    inline void optimize() {
+        AutoLock lock(mutex);
         Dictionary::optimize();
-        mutex->unlock();
     }
     
 protected:
-    zmm::Ref<Mutex> mutex;
+    std::recursive_mutex mutex;
+    using AutoLock = std::lock_guard<decltype(mutex)>;
 };
 
 #endif // __DICTIONARY_H__
diff --git a/src/dvd_io_handler.cc b/src/dvd_io_handler.cc
deleted file mode 100644
index a450408..0000000
--- a/src/dvd_io_handler.cc
+++ /dev/null
@@ -1,172 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    dvd_io_handler.cc - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file dvd_io_handler.cc
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#ifdef HAVE_LIBDVDNAV
-
-#include <stdint.h>
-
-#include <sys/types.h>
-#include <dvdnav/dvdnav.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include "server.h"
-#include "common.h"
-#include "dvd_io_handler.h"
-
-using namespace zmm;
-using namespace mxml;
-
-DVDIOHandler::DVDIOHandler(String dvdname, int track, int chapter, 
-                           int audio_stream_id) : IOHandler()
-{
-    this->dvdname = dvdname;
-    small_buffer = (unsigned char *)MALLOC(DVD_VIDEO_LB_LEN);
-    if (small_buffer == NULL)
-        throw _Exception(_("Could not allocate memory for DVD small databuffer!"));
-    small_buffer[0] = '\0';
-    small_buffer_pos = NULL;
-    last_read = false;
-    dvd = Ref<DVDNavReader>(new DVDNavReader(dvdname));
-    dvd->selectPGC(track, chapter);
-}
-
-void DVDIOHandler::open(IN enum UpnpOpenFileMode mode)
-{
-    if (mode != UPNP_READ)
-        throw _Exception(_("DVDIOHandler::open: write not supported!"));
-}
-
-int DVDIOHandler::read(OUT char *buf, IN size_t length)
-{
-
-    char *pbuf = buf;
-    size_t count = 0;
-
-    if (last_read)
-        return 0;
-
-    // dvdnav reader returns a minimum of 2048 bytes, so we have to account
-    // for that
-    //
-    // rest buffer already has a remainder from the previous call
-    if (small_buffer_pos != NULL)
-    {
-        size_t rest = (small_buffer + DVD_VIDEO_LB_LEN) - small_buffer_pos;
-        if (rest >= length)
-        {
-            memcpy(pbuf, small_buffer_pos, length);
-            small_buffer_pos = small_buffer_pos + length;
-
-            if (rest == length)
-                small_buffer_pos = NULL;
-
-            return (int)length;
-        } 
-        else if (rest < length)
-        {
-            memcpy(pbuf, small_buffer_pos, rest);
-            pbuf = pbuf + rest;
-            count = count + rest;
-            length = length - rest;
-            small_buffer_pos = NULL;
-        }
-    }
-
-    if ((length) < DVD_VIDEO_LB_LEN)
-    {
-        size_t bytes = dvd->readSector((unsigned char *)small_buffer, DVD_VIDEO_LB_LEN);
-        if (bytes == 0)
-        {
-            last_read = true;
-            return count;
-        }
-        else if (bytes < 0)
-            return bytes;
-        else
-        {
-            small_buffer_pos = small_buffer;
-
-            memcpy(pbuf, small_buffer_pos, length);
-            count = count + length;
-            small_buffer_pos = small_buffer_pos + length;
-            return (int)count;
-        }
-    }
-    else
-    {
-        int ret = dvd->readSector((unsigned char *)pbuf, length);
-        if (ret == 0)
-        {
-            last_read = true;
-        }
-
-        if (ret >= 0)
-            ret = count + ret;
-       
-        return ret;
-    }
-
-    return -1;
-}
-
-int DVDIOHandler::write(IN char *buf, IN size_t length)
-{
-    throw _Exception(_("DVD write is not possible"));
-}
-
-void DVDIOHandler::seek(IN off_t offset, IN int whence)
-{
-}
-
-void DVDIOHandler::close()
-{
-    dvd = nil;
-    small_buffer_pos = NULL;
-}
-
-off_t DVDIOHandler::length()
-{
-    return -1;
-}
-
-DVDIOHandler::~DVDIOHandler()
-{
-    if (small_buffer)
-        FREE(small_buffer);
-}
-
-#endif//HAVE_LIBDVDNAV
diff --git a/src/dvd_io_handler.h b/src/dvd_io_handler.h
deleted file mode 100644
index 5828d73..0000000
--- a/src/dvd_io_handler.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    dvd_io_handler.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file dvd_io_handler.h
-
-/// \brief Definition of the DVDIOHandler class.
-#ifndef __DVD_IO_HANDLER_H__
-#define __DVD_IO_HANDLER_H__
-
-#include "common.h"
-#include "io_handler.h"
-#include "dvdnav_read.h"
-
-/// \brief Allows the web server to read from a dvd.
-class DVDIOHandler : public IOHandler
-{
-protected:
-    /// \brief Name of the DVD image.
-    zmm::String dvdname;
-
-    /// \brief Handle of the DVD.
-    zmm::Ref<DVDNavReader> dvd;
-
-    off_t total_size;
-
-    unsigned char *small_buffer;
-    unsigned char *small_buffer_pos;
-    bool last_read;
-
-public:
-    /// \brief Sets the dvdname to work with.
-    DVDIOHandler(zmm::String dvdname, int track, int chapter, 
-                 int audio_stream_id);
-
-    ~DVDIOHandler();
-    /// \brief Opens dvd for reading (writing is not supported)
-    virtual void open(IN enum UpnpOpenFileMode mode);
-
-    /// \brief Reads a previously opened dvd sequentially.
-    /// \param buf Data from the dvd will be copied into this buffer.
-    /// \param length Number of bytes to be copied into the buffer.
-    virtual int read(OUT char *buf, IN size_t length);
-   
-    /// \brief Writes to a previously opened dvd.
-    /// \param buf Data from the buffer will be written to the dvd.
-    /// \param length Number of bytes to be written from the buffer.
-    /// \return number of bytes written.
-    virtual int write(OUT char *buf, IN size_t length);
-
-    /// \brief Performs seek on an open dvd.
-    /// \param offset Number of bytes to move in the dvd. For seeking forwards
-    /// positive values are used, for seeking backwards - negative. Offset must
-    /// be positive if origin is set to SEEK_SET
-    /// \param whence The position to move relative to. SEEK_CUR to move relative
-    /// to current position, SEEK_END to move relative to the end of dvd,
-    /// SEEK_SET to specify an absolute offset.
-    virtual void seek(IN off_t offset, IN int whence);
-
-    /// \brief Close a previously opened dvd.
-    virtual void close();
-
-    /// \brief Returns the length of the stream in bytes
-    off_t length();
-};
-
-
-#endif // __DVD_IO_HANDLER_H__
diff --git a/src/dvdnav_read.cc b/src/dvdnav_read.cc
deleted file mode 100644
index 94fb4a5..0000000
--- a/src/dvdnav_read.cc
+++ /dev/null
@@ -1,415 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    dvdnav_read.cc - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/*
-    Significant amounts of code were derived from the menus.c example
-    program which is part of libdvdnav.
-
-    menus.c is (C) 2003 by the libdvdnav project under GPLv2 or later.
-
-    The dvdtime2msec() function as well as some other parts which are marked
-    by comments were taken from lsdvd, (C)  2003 by Chris Phillips, 
-    Henk Vergonet, licensed under GPL version 2.
- */
-
-/// \file dvdnav_read.cc
-
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#ifdef HAVE_LIBDVDNAV
-
-#include "dvdnav_read.h"
-#include <assert.h>
-
-#include "tools.h"
-
-using namespace zmm;
-
-static double frames_per_s[4] = {-1.0, 25.00, -1.0, 29.97};
-
-static struct { char code[3]; char name[20]; }
-// from lsdvd, ISO-639
-language[] = {
-    { "  ", "Not Specified"     }, { "aa", "Afar"           },       
-    { "ab", "Abkhazian"         }, { "af", "Afrikaans"      },      
-    { "am", "Amharic"           }, { "ar", "Arabic"         }, 
-    { "as", "Assamese"          }, { "ay", "Aymara"         },
-    { "az", "Azerbaijani"       }, { "ba", "Bashkir"        },
-    { "be", "Byelorussian"      }, { "bg", "Bulgarian"      }, 
-    { "bh", "Bihari"            }, { "bi", "Bislama"        }, 
-    { "bn", "Bengali; Bangla"   }, { "bo", "Tibetan"        }, 
-    { "br", "Breton"            }, { "ca", "Catalan"        }, 
-    { "co", "Corsican"          }, { "cs", "Czech"          },
-    { "cy", "Welsh"             }, { "da", "Dansk"          }, 
-    { "de", "Deutsch"           }, { "dz", "Bhutani"        }, 
-    { "el", "Greek"             }, { "en", "English"        },
-    { "eo", "Esperanto"         }, { "es", "Espanol"        }, 
-    { "et", "Estonian"          }, { "eu", "Basque"         }, 
-    { "fa", "Persian"           }, { "fi", "Suomi"          }, 
-    { "fj", "Fiji"              }, { "fo", "Faroese"        }, 
-    { "fr", "Francais"          }, { "fy", "Frisian"        }, 
-    { "ga", "Gaelic"            }, { "gd", "Scots Gaelic"   }, 
-    { "gl", "Galician"          }, { "gn", "Guarani"        }, 
-    { "gu", "Gujarati"          }, { "ha", "Hausa"          },
-    { "he", "Hebrew"            }, { "hi", "Hindi"          }, 
-    { "hr", "Hrvatski"          }, { "hu", "Magyar"         }, 
-    { "hy", "Armenian"          }, { "ia", "Interlingua"    }, 
-    { "id", "Indonesian"        }, { "ie", "Interlingue"    }, 
-    { "ik", "Inupiak"           }, { "in", "Indonesian"     },
-    { "is", "Islenska"          }, { "it", "Italiano"       }, 
-    { "iu", "Inuktitut"         }, { "iw", "Hebrew"         }, 
-    { "ja", "Japanese"          }, { "ji", "Yiddish"        }, 
-    { "jw", "Javanese"          }, { "ka", "Georgian"       }, 
-    { "kk", "Kazakh"            }, { "kl", "Greenlandic"    },
-    { "km", "Cambodian"         }, { "kn", "Kannada"        }, 
-    { "ko", "Korean"            }, { "ks", "Kashmiri"       }, 
-    { "ku", "Kurdish"           }, { "ky", "Kirghiz"        }, 
-    { "la", "Latin"             }, { "ln", "Lingala"        }, 
-    { "lo", "Laothian"          }, { "lt", "Lithuanian"     },
-    { "lv", "Latvian, Lettish"  }, { "mg", "Malagasy"       }, 
-    { "mi", "Maori"             }, { "mk", "Macedonian"     }, 
-    { "ml", "Malayalam"         }, { "mn", "Mongolian"      }, 
-    { "mo", "Moldavian"         }, { "mr", "Marathi"        }, 
-    { "ms", "Malay"             }, { "mt", "Maltese"        },
-    { "my", "Burmese"           }, { "na", "Nauru"          }, 
-    { "ne", "Nepali"            }, { "nl", "Nederlands"     }, 
-    { "no", "Norsk"             }, { "oc", "Occitan"        },
-    { "om", "Oromo"             }, { "or", "Oriya"          }, 
-    { "pa", "Punjabi"           }, { "pl", "Polish"         }, 
-    { "ps", "Pashto, Pushto"    }, { "pt", "Portugues"      }, 
-    { "qu", "Quechua"           }, { "rm", "Rhaeto-Romance" }, 
-    { "rn", "Kirundi"           }, { "ro", "Romanian"       },
-    { "ru", "Russian"           }, { "rw", "Kinyarwanda"    }, 
-    { "sa", "Sanskrit"          }, { "sd", "Sindhi"         }, 
-    { "sg", "Sangho"            }, { "sh", "Serbo-Croatian" }, 
-    { "si", "Sinhalese"         }, { "sk", "Slovak"         }, 
-    { "sl", "Slovenian"         }, { "sm", "Samoan"         },
-    { "sn", "Shona"             }, { "so", "Somali"         }, 
-    { "sq", "Albanian"          }, { "sr", "Serbian"        }, 
-    { "ss", "Siswati"           }, { "st", "Sesotho"        }, 
-    { "su", "Sundanese"         }, { "sv", "Svenska"        }, 
-    { "sw", "Swahili"           }, { "ta", "Tamil"          },
-    { "te", "Telugu"            }, { "tg", "Tajik"          }, 
-    { "th", "Thai"              }, { "ti", "Tigrinya"       }, 
-    { "tk", "Turkmen"           }, { "tl", "Tagalog"        },
-    { "tn", "Setswana"          }, { "to", "Tonga"          }, 
-    { "tr", "Turkish"           }, { "ts", "Tsonga"         }, 
-    { "tt", "Tatar"             }, { "tw", "Twi"            },
-    { "ug", "Uighur"            }, { "uk", "Ukrainian"      }, 
-    { "ur", "Urdu"              }, { "uz", "Uzbek"          }, 
-    { "vi", "Vietnamese"        }, { "vo", "Volapuk"        }, 
-    { "wo", "Wolof"             }, { "xh", "Xhosa"          }, 
-    { "yi", "Yiddish"           }, { "yo", "Yoruba"         }, 
-    { "za", "Zhuang"            }, { "zh", "Chinese"        }, 
-    { "zu", "Zulu"              }, { "xx", "Unknown"        }, 
-    { "\0", "Unknown" } 
-};
-
-static const char *audio_format[7] = 
-                        {"ac3", "?", "mpeg1", "mpeg2", "lpcm ", "sdds ", "dts"};
-static int   audio_id[7]     = {0x80, 0, 0xC0, 0xC0, 0xA0, 0, 0x88};
-
-DVDNavReader::DVDNavReader(String path)
-{
-    /*
-     * Threads: this function uses chdir() and getcwd().
-     * The current working directory is global to all threads,
-     * so using chdir/getcwd in another thread could give unexpected results.
-     */
-    /// \todo check the implications of the above comment, do we use chdir()
-    /// somewhere?
-    if (dvdnav_open(&dvd, path.c_str()) != DVDNAV_STATUS_OK)
-    {
-        throw _Exception(_("Could not open DVD ") + path);
-    }
-
-    dvd_path = path;
-
-    // set the PGC positioning flag to have position information relatively to 
-    // the whole feature instead of just relatively to the current chapter 
-    if (dvdnav_set_PGC_positioning_flag(dvd, 1) != DVDNAV_STATUS_OK)
-    {
-        throw _Exception(_("Failed to set PGC positioning flag on DVD ") + 
-                          path);
-    }
-
-    log_debug("Opened DVD %s\n", dvd_path.c_str());
-
-    mutex = Ref<Mutex>(new Mutex(true));
-
-    EOT = true;
-}
-
-DVDNavReader::~DVDNavReader()
-{
-    if (dvd)
-        dvdnav_close(dvd);
-    log_debug("Closing DVD %s\n", dvd_path.c_str());
-}
-
-int DVDNavReader::titleCount()
-{
-   int32_t t;
-    if (dvdnav_get_number_of_titles(dvd, &t) != DVDNAV_STATUS_OK)
-        throw _Exception(_("Failed to get title count for DVD ") + dvd_path + 
-                " : " + dvdnav_err_to_string(dvd));
-
-    return t;
-}
-
-int DVDNavReader::chapterCount(int title_idx)
-{
-    int32_t c;
-
-    title_idx++;
-
-    if ((title_idx < 1) || (title_idx > titleCount()))
-        throw _Exception(_("Requested title number exceeds available titles "
-                    "for DVD ") + dvd_path);
-
-    if (dvdnav_get_number_of_parts(dvd, title_idx, &c) != DVDNAV_STATUS_OK)
-        throw _Exception(_("Failed to get chapter count for title ") 
-                         + title_idx + " DVD " + dvd_path);
-
-    return c;
-}
-
-void DVDNavReader::selectPGC(int title_idx, int chapter_idx)
-{
-    title_idx++;
-    chapter_idx++;
-
-    if ((title_idx < 1) || (title_idx > titleCount()))
-        throw _Exception(_("Attmpted to select invalid title!"));
-
-    if ((chapter_idx < 1) || (chapter_idx > chapterCount(title_idx-1)))
-        throw _Exception(_("Attempted to select invalid chapter!"));
-
-    AUTOLOCK(mutex);
-
-   if (dvdnav_part_play(dvd, title_idx, chapter_idx) != DVDNAV_STATUS_OK)
-   {
-       throw _Exception(_("Failed to select PGC for DVD ") + dvd_path + " : " +
-                         dvdnav_err_to_string(dvd));
-   }
-
-   EOT = false;
-}
-
-size_t DVDNavReader::readSector(unsigned char *buffer, size_t length)
-{
-    AUTOLOCK(mutex);
-
-    unsigned char *p = buffer;
-    size_t consumed = 0;
-
-    if (length < DVD_VIDEO_LB_LEN)
-        throw _Exception(_("Buffer must be at least ") + DVD_VIDEO_LB_LEN);
-
-    while (!EOT)
-    {
-        int result, event, len;
-
-        result = dvdnav_get_next_block(dvd, (uint8_t *)p, &event, &len);
-        if (result == DVDNAV_STATUS_ERR)
-        {
-            throw _Exception(_("Error getting next block for DVD ") + dvd_path +
-                               " : " + dvdnav_err_to_string(dvd));
-        }
-
-        switch (event)
-        {
-            case DVDNAV_BLOCK_OK:
-                consumed = consumed + len;
-                if ((consumed + DVD_VIDEO_LB_LEN) > length)
-                    return consumed;
-                    
-                p = p + len;
-                break;
-            case DVDNAV_STILL_FRAME:
-                {
-                    dvdnav_still_event_t *still_event;
-                    still_event = (dvdnav_still_event_t *)p;
-                    if (still_event->length == 0xff)
-                        dvdnav_still_skip(dvd);
-                }
-                break;
-            case DVDNAV_WAIT:
-                dvdnav_wait_skip(dvd);
-                break;
-            case DVDNAV_CELL_CHANGE:
-                {
-                    int32_t tt = 0, ptt = 0;
-                    dvdnav_current_title_info(dvd, &tt, &ptt);
-                    if (tt == 0)
-                    {
-                        log_warning("Reached DVD menu, aborting.\n");
-                        EOT = true;
-                        return consumed;
-                    }
-                }
-                break;
-            case DVDNAV_STOP:
-                EOT = true;
-                return consumed;
-                break;
-            case DVDNAV_NAV_PACKET:
-            case DVDNAV_NOP:
-            case DVDNAV_SPU_CLUT_CHANGE:
-            case DVDNAV_SPU_STREAM_CHANGE:
-            case DVDNAV_AUDIO_STREAM_CHANGE:
-            case DVDNAV_HIGHLIGHT:
-            case DVDNAV_VTS_CHANGE:
-            case DVDNAV_HOP_CHANNEL:
-                break;
-            default:
-                log_error("Uknown event when playing DVD %s\n", dvd_path.c_str());
-                EOT = true;
-                return -1;
-                break;
-        }
-    }
-    return 0;
-}
-
-int DVDNavReader::audioTrackCount()
-{
-    AUTOLOCK(mutex);
-
-    uint8_t count = 0;
-    while (true)
-    {
-        if(dvdnav_get_audio_logical_stream(dvd, count) < 0)
-            break;
-
-        // afaik only 8 streams are supported?
-        // \todo check the exact amount of supported audio streams in the DVD
-        if (count > 10)
-            break;
-
-        count++;
-    }
-
-    return (int)count;
-}
-
-// from lsdvd
-String DVDNavReader::getLanguage(char *code)
-{
-    int k = 0;
-    while (memcmp(language[k].code, code, 2) && language[k].name[0] ) { k++; }
-    return _(language[k].name);
-}
-
-String DVDNavReader::audioLanguage(int stream_idx)
-{
-    char code[3];
-    audio_attr_t audio_attr;
-    
-    AUTOLOCK(mutex);
-
-    if (dvdnav_get_audio_attr(dvd, stream_idx, &audio_attr) != DVDNAV_STATUS_OK)
-        throw _Exception(_("Error error retrieving audio language from DVD ") +
-                           dvd_path + " : " + 
-                           dvdnav_err_to_string(dvd));
-
-    sprintf(code, "%c%c", audio_attr.lang_code >> 8, 
-                          audio_attr.lang_code & 0xff);
-    
-    if (!code[0])
-    { 
-        code[0] = 'x'; 
-        code[1] = 'x'; 
-    }
-
-    return getLanguage(code);
-}
-
-int DVDNavReader::audioSampleFrequency(int stream_idx)
-{
-    audio_attr_t audio_attr;
-    
-    AUTOLOCK(mutex);
-    
-    if (dvdnav_get_audio_attr(dvd, stream_idx, &audio_attr) != DVDNAV_STATUS_OK)
-        throw _Exception(_("Error error retrieving audio language from DVD ") +
-                           dvd_path + " : " + 
-                           dvdnav_err_to_string(dvd));
-
-    if (audio_attr.sample_frequency == 0)
-        return 48000;
-    else
-        return 96000;
-}
-
-int DVDNavReader::audioChannels(int stream_idx)
-{
-    audio_attr_t audio_attr;
-   
-    AUTOLOCK(mutex);
-
-    if (dvdnav_get_audio_attr(dvd, stream_idx, &audio_attr) != DVDNAV_STATUS_OK)
-        throw _Exception(_("Error error retrieving audio language from DVD ") +
-                           dvd_path + " : " + 
-                           dvdnav_err_to_string(dvd));
-
-    return audio_attr.channels + 1;
-}
-
-String DVDNavReader::audioFormat(int stream_idx)
-{
-    audio_attr_t audio_attr;
-    
-    AUTOLOCK(mutex);
-    
-    if (dvdnav_get_audio_attr(dvd, stream_idx, &audio_attr) != DVDNAV_STATUS_OK)
-        throw _Exception(_("Error error retrieving audio language from DVD ") +
-                           dvd_path + " : " +
-                           dvdnav_err_to_string(dvd));
-    return _(audio_format[audio_attr.audio_format]);
-}
-
-int DVDNavReader::audioStreamID(int stream_idx)
-{
-    audio_attr_t audio_attr;
-
-    AUTOLOCK(mutex);
-    
-    if (dvdnav_get_audio_attr(dvd, stream_idx, &audio_attr) != DVDNAV_STATUS_OK)
-        throw _Exception(_("Error error retrieving audio language from DVD ") +
-                           dvd_path + " : " +
-                           dvdnav_err_to_string(dvd));
-
-    return audio_id[audio_attr.audio_format]+stream_idx;
-}
-
-#endif//HAVE_LIBDVDNAV
diff --git a/src/dvdnav_read.h b/src/dvdnav_read.h
deleted file mode 100644
index b2c14ca..0000000
--- a/src/dvdnav_read.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    dvdnav_read.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file dvdnav_read.h
-/// \brief Definition of the FileIOHandler class.
-#ifndef __DVDNAV_READ_H__
-#define __DVDNAV_READ_H__
-
-#include <stdint.h>
-
-#include <sys/types.h>
-#include <dvdnav/dvdnav.h>
-#include "common.h"
-#include "sync.h"
-
-/// \brief Allows to read selected streams from a DVD image.
-///
-/// There are some constraints on the usage of this class:
-/// First of all - you *must* call the selectPGC() function before you 
-/// attempt to read data or get the stream length.
-///
-/// You must call selectPGC() each time when you want to reset read; calling
-/// read consequently will return the stream data and advance further in the
-/// stream.
-/// 
-/// The class is thread safe, meaning that locks are in place, however it's
-/// design does not suggest multithreaded usage. selectPGC(), read(), 
-/// getLength() will not work in parallel but block if one of the functions
-/// is running.
-class DVDNavReader : public zmm::Object
-{
-public:
-    /// \brief Sets the filename to work with. Can be an ISO, device or
-    /// directory.
-    DVDNavReader(zmm::String path);
-    ~DVDNavReader();
-
-    /// \brief returns the number of titles on the DVD
-    int titleCount();
-
-    /// \brief returns the number of chapters for a given title
-    /// \param title_idx index of the title
-    int chapterCount(int title_idx);
-
-    /// \brief Returns the number of audio streams for the selected PGC
-    int audioTrackCount();
-
-    /// \brief Selects the title, chapter and angle to play, returns the
-    /// number of bytes for the selection.
-    ///
-    /// The DVD is divided into titles, each title is didvided into chapters
-    /// and can have one or more angles. This function selects what data we
-    /// want to retrieve from the DVD (i.e. what stream we want to watch),
-    /// and returns the size of the stream in bytes. 
-    /// Note, that we will always treat the chapter as "starting point", i.e.
-    /// we will play from the given chapter to the very end, we will not stop
-    /// at the end of the chapter.
-    ///
-    /// \param title_idx index of the title
-    /// \param chapter_idx index of the chapter from where we start
-    void selectPGC(int title_idx, int chapter_idx);
-
-    /// \brief Reads the stream, specified by selectPGC from the DVD.
-    ///
-    /// \param buffer buffer to store the data
-    /// \param length length of the buffer
-    /// \return number of bytes read (can be shorter than buffer length), value
-    ///  of 0 indicates end of stream.
-    size_t readSector(unsigned char *buffer, size_t length);  
-
-    /// \brief Returns a human readable language string of the audio stream
-    zmm::String audioLanguage(int stream_idx);
-
-    /// \brief Returns the sampling frequency of the given audio stream
-    int audioSampleFrequency(int stream_idx);
-
-    /// \brief Returns the number of channels for the given audio stream
-    int audioChannels(int stream_idx);
-
-    /// \brief Returns the id of the audio stream
-    int audioStreamID(int stream_idx);
-
-    /// \brief Returns a human readable name of the audio format
-    zmm::String audioFormat(int stream_idx);
-
-protected:
-    /// \brief Name of the DVD file.
-    zmm::String dvd_path;
-
-    /// \brief DVD handle
-    dvdnav_t *dvd;
-
-    /// \brief end of title flag
-    bool EOT;
-
-    zmm::Ref<Mutex> mutex;
-
-    zmm::String getLanguage(char *code);
-};
-
-
-#endif // __DVDNAV_READ_H__
diff --git a/src/exceptions.cc b/src/exceptions.cc
index 6bf3e4f..1a8dd40 100644
--- a/src/exceptions.cc
+++ b/src/exceptions.cc
@@ -29,10 +29,6 @@
 
 /// \file exceptions.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "exceptions.h"
 
 using namespace zmm;
diff --git a/src/exceptions.h b/src/exceptions.h
index 7581c69..5b75466 100644
--- a/src/exceptions.h
+++ b/src/exceptions.h
@@ -32,9 +32,9 @@
 #ifndef __EXCEPTIONS_H__
 #define __EXCEPTIONS_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 
-#define EXCEPTION_DATA __FILE__, __LINE__, __func__
+#define EXCEPTION_DATA __FILENAME__, __LINE__, __func__
 #define _UpnpException(code, msg) UpnpException(code, msg, EXCEPTION_DATA)
 #define _StorageException(usermsg, debugmsg) StorageException(usermsg, debugmsg, EXCEPTION_DATA)
 #define _ObjectNotFoundException(msg) ObjectNotFoundException(msg, EXCEPTION_DATA)
@@ -48,7 +48,7 @@ protected:
 public:
     UpnpException(int errCode, zmm::String message);
     UpnpException(int errCode, zmm::String message, const char *file, int line, const char *function);
-    inline int getErrorCode() { return errCode; }
+    inline int getErrorCode() const { return errCode; }
 };
 
 class StorageException : public zmm::Exception
@@ -59,7 +59,7 @@ public:
     inline StorageException(zmm::String _userMessage, zmm::String message) : zmm::Exception(message) { userMessage = _userMessage; }
     inline StorageException(zmm::String _userMessage, zmm::String message, const char *file, int line, const char* function) : 
         zmm::Exception(message, file, line, function) { userMessage = _userMessage;  }
-    zmm::String getUserMessage() { return (userMessage != nil ? userMessage : message); } 
+    zmm::String getUserMessage() const { return (userMessage != nullptr ? userMessage : message); }
 };
 
 class ObjectNotFoundException : public StorageException
diff --git a/src/executor.h b/src/executor.h
index 4f304db..ca91a78 100644
--- a/src/executor.h
+++ b/src/executor.h
@@ -32,7 +32,7 @@
 #ifndef __EXECUTOR_H__
 #define __EXECUTOR_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 
 /// \brief wraps something executable e.g. a thread or a process
 class Executor : public zmm::Object
diff --git a/src/fd_io_handler.cc b/src/fd_io_handler.cc
index ef08d2b..26e4522 100644
--- a/src/fd_io_handler.cc
+++ b/src/fd_io_handler.cc
@@ -29,17 +29,13 @@
 
 /// \file fd_io_handler.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "server.h"
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <string.h>
-#include <stdio.h>
+#include <cstring>
+#include <cstdio>
 #include "common.h"
 #include "fd_io_handler.h"
 
@@ -50,16 +46,16 @@ FDIOHandler::FDIOHandler(String filename) : IOHandler()
 {
     this->filename = filename;
     this->fd = -1;
-    this->other = nil;
+    this->other = nullptr;
     this->reference_list = Ref<Array<Object> >(new Array<Object >(4));
     this->closed = false;
 }
 
 FDIOHandler::FDIOHandler(int fd) : IOHandler()
 {
-    this->filename = nil;
+    this->filename = nullptr;
     this->fd = fd;
-    this->other = nil;
+    this->other = nullptr;
     this->reference_list = Ref<Array<Object> >(new Array<Object >(4));
     this->closed = false;
 }
@@ -141,10 +137,10 @@ void FDIOHandler::close()
     log_debug("Closing...\n");
     try
     {
-        if (other != nil)
+        if (other != nullptr)
             other->close();
     }
-    catch (Exception ex)
+    catch (const Exception & ex)
     {
         log_debug("Error closing \"other\" handler: %s\n", ex.getMessage().c_str());
     }
diff --git a/src/file_io_handler.cc b/src/file_io_handler.cc
index 39c3f8d..d2d3e21 100644
--- a/src/file_io_handler.cc
+++ b/src/file_io_handler.cc
@@ -29,31 +29,27 @@
 
 /// \file file_io_handler.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include "server.h"
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
-#include <string.h>
-#include <stdio.h>
+#include <cstring>
+#include <cstdio>
+#include <upnp-1.8/ixml.h>
+
+#include "server.h"
 #include "common.h"
 #include "storage.h"
 #include "cds_objects.h"
 #include "process.h"
 #include "update_manager.h"
-#include "ixml.h"
 #include "file_io_handler.h"
 #include "dictionary.h"
 
 using namespace zmm;
 using namespace mxml;
 
-FileIOHandler::FileIOHandler(String filename) : IOHandler()
+FileIOHandler::FileIOHandler(String filename) : filename(filename), f(nullptr)
 {
-    this->filename = filename;
 }
 
 void FileIOHandler::open(IN enum UpnpOpenFileMode mode)
@@ -71,7 +67,7 @@ void FileIOHandler::open(IN enum UpnpOpenFileMode mode)
         throw _Exception(_("FileIOHandler::open: invdalid read/write mode"));
     }
 
-    if (f == NULL)
+    if (f == nullptr)
     {
         throw _Exception(_("FileIOHandler::open: failed to open: ") + filename.c_str());
     }
@@ -116,5 +112,5 @@ void FileIOHandler::close()
     {
         throw _Exception(_("fclose failed"));
     }
-    f = NULL;
+    f = nullptr;
 }
diff --git a/src/file_request_handler.cc b/src/file_request_handler.cc
index e7e84be..10107a4 100644
--- a/src/file_request_handler.cc
+++ b/src/file_request_handler.cc
@@ -29,39 +29,17 @@
 
 /// \file file_request_handler.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
+#include <sys/stat.h>
 
 #include "server.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include "common.h"
-#include "storage.h"
-#include "cds_objects.h"
 #include "process.h"
 #include "update_manager.h"
 #include "session_manager.h"
-#include "ixml.h"
 #include "file_io_handler.h"
-#include "dictionary.h"
 #include "file_request_handler.h"
 #include "metadata_handler.h"
-#include "tools.h"
 #include "play_hook.h"
 
-#ifdef HAVE_LIBDVDNAV
-    #include "dvd_io_handler.h"
-    #include "fd_io_handler.h"
-    #include "metadata/dvd_handler.h"
-    #include "mpegremux_processor.h"
-    #include "thread_executor.h"
-    #include "io_handler_chainer.h"
-#endif
-
 #ifdef EXTERNAL_TRANSCODING
     #include "transcoding/transcode_dispatcher.h"
 #endif
@@ -73,7 +51,7 @@ FileRequestHandler::FileRequestHandler() : RequestHandler()
 {
 }
 
-void FileRequestHandler::get_info(IN const char *filename, OUT struct File_Info *info)
+void FileRequestHandler::get_info(IN const char *filename, OUT UpnpFileInfo *info)
 {
     log_debug("start\n");
 
@@ -96,7 +74,7 @@ void FileRequestHandler::get_info(IN const char *filename, OUT struct File_Info
             filename, parameters.c_str());
 
     String objID = dict->get(_("object_id"));
-    if (objID == nil)
+    if (objID == nullptr)
     {
         //log_error("object_id not found in url\n");
         throw _Exception(_("get_info: object_id not found"));
@@ -127,11 +105,11 @@ void FileRequestHandler::get_info(IN const char *filename, OUT struct File_Info
 #ifdef EXTERNAL_TRANSCODING
     if (string_ok(s_res_id) && (s_res_id != _(URL_VALUE_TRANSCODE_NO_RES_ID)))
 #else
-        if (string_ok(s_res_id))
+    if (string_ok(s_res_id))
 #endif
-            res_id = s_res_id.toInt();
-        else
-            res_id = -1;
+        res_id = s_res_id.toInt();
+    else
+        res_id = -1;
 
     String ext = dict->get(_("ext"));
     int edot = ext.rindex('.');
@@ -167,11 +145,11 @@ void FileRequestHandler::get_info(IN const char *filename, OUT struct File_Info
 
     if (access(path.c_str(), R_OK) == 0)
     {
-        info->is_readable = 1;
+        UpnpFileInfo_set_IsReadable(info, 1);
     }
     else
     {
-        info->is_readable = 0;
+        UpnpFileInfo_set_IsReadable(info, 0);
     }
 
     String header;
@@ -184,7 +162,7 @@ void FileRequestHandler::get_info(IN const char *filename, OUT struct File_Info
             slash_pos++;
 
 
-            header = _("Content-Disposition: attachment; filename=\"") + 
+            header = _("Content-Disposition: attachment; filename=\"") +
                 path.substring(slash_pos) + _("\"");
         }
     }
@@ -193,7 +171,6 @@ void FileRequestHandler::get_info(IN const char *filename, OUT struct File_Info
     tr_profile = dict->get(_(URL_PARAM_TRANSCODE_PROFILE_NAME));
 #endif
 
-    info->http_header = NULL;
     // for transcoded resourecs res_id will always be negative
     log_debug("fetching resource id %d\n", res_id);
     String rh = dict->get(_(RESOURCE_HANDLER));
@@ -204,7 +181,7 @@ void FileRequestHandler::get_info(IN const char *filename, OUT struct File_Info
 
         log_debug("setting content length to unknown\n");
         /// \todo we could figure out the content length...
-        info->file_length = -1;
+        UpnpFileInfo_set_FileLength(info, -1);
 
         int res_handler;
         if (string_ok(rh))
@@ -215,7 +192,7 @@ void FileRequestHandler::get_info(IN const char *filename, OUT struct File_Info
             res_handler = resource->getHandlerType();
             // http-get:*:image/jpeg:*
             String protocolInfo = item->getResource(res_id)->getAttributes()->get(_("protocolInfo"));
-            if (protocolInfo != nil)
+            if (protocolInfo != nullptr)
             {
                 mimeType = getMTFromProtocolInfo(protocolInfo);
             }
@@ -225,153 +202,123 @@ void FileRequestHandler::get_info(IN const char *filename, OUT struct File_Info
         if (!string_ok(mimeType))
             mimeType = h->getMimeType();
 
-        /*        Ref<IOHandler> io_handler = */ h->serveContent(item, res_id, &(info->file_length));
+        off_t size = UpnpFileInfo_get_FileLength(info);
+        /*        Ref<IOHandler> io_handler = */ h->serveContent(item, res_id, &(size));
 
     }
-    else
-    {
+    else {
 #ifdef EXTERNAL_TRANSCODING
-        if (!is_srt && string_ok(tr_profile))
-        {
+		if (!is_srt && string_ok(tr_profile))
+		{
 
-            Ref<TranscodingProfile> tp = ConfigManager::getInstance()->getTranscodingProfileListOption(CFG_TRANSCODING_PROFILE_LIST)->getByName(tr_profile);
+			Ref<TranscodingProfile> tp = ConfigManager::getInstance()->getTranscodingProfileListOption(CFG_TRANSCODING_PROFILE_LIST)->getByName(tr_profile);
 
-            if (tp == nil)
-                throw _Exception(_("Transcoding of file ") + path +
-                        " but no profile matching the name " +
-                        tr_profile + " found");
+			if (tp == nullptr)
+				throw _Exception(_("Transcoding of file ") + path +
+						" but no profile matching the name " +
+						tr_profile + " found");
 
-            mimeType = tp->getTargetMimeType();
-            
-            Ref<Dictionary> mappings = ConfigManager::getInstance()->getDictionaryOption(CFG_IMPORT_MAPPINGS_MIMETYPE_TO_CONTENTTYPE_LIST);
-            if (mappings->get(mimeType) == CONTENT_TYPE_PCM)
-            {
-                String freq = item->getResource(0)->getAttribute(MetadataHandler::getResAttrName(R_SAMPLEFREQUENCY));
-                String nrch = item->getResource(0)->getAttribute(MetadataHandler::getResAttrName(R_NRAUDIOCHANNELS));
+			mimeType = tp->getTargetMimeType();
 
-                if (string_ok(freq))
-                    mimeType = mimeType + _(";rate=") + freq;
-                if (string_ok(nrch))
-                    mimeType = mimeType + _(";channels=") + nrch;
-            }
+			Ref<Dictionary> mappings = ConfigManager::getInstance()->getDictionaryOption(CFG_IMPORT_MAPPINGS_MIMETYPE_TO_CONTENTTYPE_LIST);
+			if (mappings->get(mimeType) == CONTENT_TYPE_PCM)
+			{
+				String freq = item->getResource(0)->getAttribute(MetadataHandler::getResAttrName(R_SAMPLEFREQUENCY));
+				String nrch = item->getResource(0)->getAttribute(MetadataHandler::getResAttrName(R_NRAUDIOCHANNELS));
 
-            info->file_length = -1;
-        }
-        else
+				if (string_ok(freq))
+					mimeType = mimeType + _(";rate=") + freq;
+				if (string_ok(nrch))
+					mimeType = mimeType + _(";channels=") + nrch;
+			}
+
+            UpnpFileInfo_set_FileLength(info, -1);
+		}
+		else
 #endif
-#ifdef HAVE_LIBDVDNAV
-            if (!is_srt && item->getFlag(OBJECT_FLAG_DVD_IMAGE))
-            {
-                String tmp = dict->get(DVDHandler::renderKey(DVD_Title));
-                if (!string_ok(tmp))
-                    throw _Exception(_("DVD Image requested but title parameter is missing!"));
-                int title = tmp.toInt();
-                if (title < 0)
-                    throw _Exception(_("DVD Image - requested invalid title!"));
-
-                tmp = dict->get(DVDHandler::renderKey(DVD_Chapter));
-                if (!string_ok(tmp))
-                    throw _Exception(_("DVD Image requested but chapter parameter is missing!"));
-                int chapter = tmp.toInt();
-                if (chapter < 0)
-                    throw _Exception(_("DVD Image - requested invalid chapter!"));
-
-                // actually we are retrieving the stream id here
-                tmp = dict->get(DVDHandler::renderKey(DVD_AudioStreamID));
-                if (!string_ok(tmp))
-                    throw _Exception(_("DVD Image requested but audio track parameter is missing!"));
-                int audio_track = tmp.toInt();
-                if (audio_track < 0)
-                    throw _Exception(_("DVD Image - requested invalid audio stream ID!"));
-
-                /// \todo make sure we can seek in the streams
-                info->file_length = -1;
-                header = nil;
+        {
+            UpnpFileInfo_set_FileLength(info,  statbuf.st_size);
+            // if we are dealing with a regular file we should add the
+            // Accept-Ranges: bytes header, in order to indicate that we support
+            // seeking
+            if (S_ISREG(statbuf.st_mode)) {
+                if (string_ok(header))
+                    header = header + _("\r\n");
+
+                header = header + _("Accept-Ranges: bytes");
+                /// \todo turned out that we are not always allowed to add this
+                /// header, since chunked encoding may be active and we do not
+                /// know that here
             }
-            else
-#endif
-            {
-                info->file_length = statbuf.st_size;
-                // if we are dealing with a regular file we should add the
-                // Accept-Ranges: bytes header, in order to indicate that we support
-                // seeking
-                if (S_ISREG(statbuf.st_mode))
-                {
-                    if (string_ok(header))
-                        header = header + _("\r\n");
-
-                    header = header + _("Accept-Ranges: bytes");
-                    /// \todo turned out that we are not always allowed to add this
-                    /// header, since chunked encoding may be active and we do not
-                    /// know that here
-                }
 
 #ifdef EXTEND_PROTOCOLINFO
-                    Ref<ConfigManager> cfg = ConfigManager::getInstance();
-                    if (cfg->getBoolOption(CFG_SERVER_EXTEND_PROTOCOLINFO_SM_HACK))
-                    {
-                        if (item->getMimeType().startsWith(_("video"))) {
-                            // Look for subtitle file and returns it's URL
-                            // in CaptionInfo.sec response header.
-                            // To be more compliant with original Samsung
-                            // server we should check for getCaptionInfo.sec: 1
-                            // request header.
-                            Ref<Array<StringBase> > subexts(new Array<StringBase>());
-                            subexts->append(_(".srt"));
-                            subexts->append(_(".ssa"));
-                            subexts->append(_(".smi"));
-                            subexts->append(_(".sub"));
-
-                            String bfilepath = path.substring(0, path.rindex('.'));
-                            String validext;
-                            for (int i=0; i<subexts->size(); i++) {
-                                String ext = subexts->get(i);
-
-                                String fpath = bfilepath + ext;
-                                if (access(fpath.c_str(), R_OK) == 0)
-                                {
-                                    validext = ext;
-                                    break;
-                                }
-                            }
-
-
-                            if (validext.length() > 0)
-                            {
-                                String burlpath = _(filename);
-                                burlpath = burlpath.substring(0, burlpath.rindex('.'));
-                                Ref<Server> server = Server::getInstance();
-                                String url = _("http://")
-                                    + server->getIP() + ":" + server->getPort() 
-                                    + burlpath + validext;
-
-                                if (string_ok(header))
-                                    header = header + _("\r\n");
-                                header = header + "CaptionInfo.sec: " + url;
-                            }
-                        }
+			Ref<ConfigManager> cfg = ConfigManager::getInstance();
+			if (cfg->getBoolOption(CFG_SERVER_EXTEND_PROTOCOLINFO_SM_HACK))
+			{
+				if (item->getMimeType().startsWith(_("video"))) {
+					// Look for subtitle file and returns it's URL
+					// in CaptionInfo.sec response header.
+					// To be more compliant with original Samsung
+					// server we should check for getCaptionInfo.sec: 1
+					// request header.
+					Ref<Array<StringBase> > subexts(new Array<StringBase>());
+					subexts->append(_(".srt"));
+					subexts->append(_(".ssa"));
+					subexts->append(_(".smi"));
+					subexts->append(_(".sub"));
+
+					String bfilepath = path.substring(0, path.rindex('.'));
+					String validext;
+					for (int i=0; i<subexts->size(); i++) {
+						String ext = subexts->get(i);
+
+						String fpath = bfilepath + ext;
+						if (access(fpath.c_str(), R_OK) == 0)
+						{
+							validext = ext;
+							break;
+						}
+					}
+
+
+					if (validext.length() > 0)
+					{
+						String burlpath = _(filename);
+						burlpath = burlpath.substring(0, burlpath.rindex('.'));
+						Ref<Server> server = Server::getInstance();
+						String url = _("http://")
+							+ server->getIP() + ":" + server->getPort()
+							+ burlpath + validext;
+
+						if (string_ok(header))
+							header = header + _("\r\n");
+						header = header + "CaptionInfo.sec: " + url;
+					}
+				}
 #endif
-                    }
-            }
+        }
+    }
 
-        if (!string_ok(mimeType))
-            mimeType = item->getMimeType();
+    if (!string_ok(mimeType))
+        mimeType = item->getMimeType();
+
+    //log_debug("sizeof off_t %d, statbuf.st_size %d\n", sizeof(off_t), sizeof(statbuf.st_size));
+    //log_debug("get_info: file_length: " OFF_T_SPRINTF "\n", statbuf.st_size);
 
-        //log_debug("sizeof off_t %d, statbuf.st_size %d\n", sizeof(off_t), sizeof(statbuf.st_size));
-        //log_debug("get_info: file_length: " OFF_T_SPRINTF "\n", statbuf.st_size);
-    }
-   
 #ifdef EXTEND_PROTOCOLINFO
     header = getDLNAtransferHeader(mimeType, header);
 #endif
 
     if (string_ok(header))
-        info->http_header = ixmlCloneDOMString(header.c_str());
-
-    info->last_modified = statbuf.st_mtime;
-    info->is_directory = S_ISDIR(statbuf.st_mode);
+        UpnpFileInfo_set_ExtraHeaders(info, ixmlCloneDOMString(header.c_str()));
+#ifdef UPNP_OLD_SNAPSHOT
+    UpnpFileInfo_set_LastModified(info, &(statbuf.st_mtime));
+#else
+    UpnpFileInfo_set_LastModified(info, statbuf.st_mtime);
+#endif
+    UpnpFileInfo_set_IsDirectory(info, S_ISDIR(statbuf.st_mode));
 
-    info->content_type = ixmlCloneDOMString(mimeType.c_str());
+    UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString(mimeType.c_str()));
 
     //    log_debug("get_info: Requested %s, ObjectID: %s, Location: %s\n, MimeType: %s\n",
     //          filename, object_id.c_str(), path.c_str(), info->content_type);
@@ -380,7 +327,6 @@ void FileRequestHandler::get_info(IN const char *filename, OUT struct File_Info
 }
 
 Ref<IOHandler> FileRequestHandler::open(IN const char *filename,
-                                        OUT struct File_Info *info,
                                         IN enum UpnpOpenFileMode mode,
                                         IN zmm::String range)
 {
@@ -406,11 +352,10 @@ Ref<IOHandler> FileRequestHandler::open(IN const char *filename,
 
     Ref<Dictionary> dict(new Dictionary());
     dict->decodeSimple(parameters);
-    log_debug("full url (filename): %s, parameters: %s\n",
-            filename, parameters.c_str());
+    log_debug("full url (filename): %s, parameters: %s\n", filename, parameters.c_str());
 
     String objID = dict->get(_("object_id"));
-    if (objID == nil)
+    if (objID == nullptr)
     {
         throw _Exception(_("object_id not found"));
     }
@@ -538,6 +483,7 @@ Ref<IOHandler> FileRequestHandler::open(IN const char *filename,
             throw _Exception(_("Failed to open ") + path + " - " + strerror(errno));
     }
 
+    /* TODO Is this needed? Info should be gotten by get_info()?
     if (access(path.c_str(), R_OK) == 0)
     {
         info->is_readable = 1;
@@ -552,7 +498,6 @@ Ref<IOHandler> FileRequestHandler::open(IN const char *filename,
     info->last_modified = statbuf.st_mtime;
     info->is_directory = S_ISDIR(statbuf.st_mode);
 
-
     log_debug("path: %s\n", path.c_str());
     int slash_pos = path.rindex(DIR_SEPARATOR);
     if (slash_pos >= 0)
@@ -566,7 +511,10 @@ Ref<IOHandler> FileRequestHandler::open(IN const char *filename,
                 path.substring(slash_pos) + _("\"");
         }
     }
+    */
+
     log_debug("fetching resource id %d\n", res_id);
+
 #ifdef EXTERNAL_TRANSCODING
     tr_profile = dict->get(_(URL_PARAM_TRANSCODE_PROFILE_NAME));
     if (string_ok(tr_profile))
@@ -581,7 +529,8 @@ Ref<IOHandler> FileRequestHandler::open(IN const char *filename,
     }
 #endif
 
-    info->http_header = NULL;
+    // FIXME upstream upnp
+    //info->http_header = NULL;
     // Per default and in case of a bad resource ID, serve the file
     // itself
 
@@ -592,7 +541,7 @@ Ref<IOHandler> FileRequestHandler::open(IN const char *filename,
     if (((res_id > 0) && (res_id < item->getResourceCount())) ||
         ((res_id > 0) && string_ok(rh)))
     {
-        info->file_length = -1;
+        //info->file_length = -1;
 
         int res_handler;
         if (string_ok(rh))
@@ -603,7 +552,7 @@ Ref<IOHandler> FileRequestHandler::open(IN const char *filename,
             res_handler = resource->getHandlerType();
             // http-get:*:image/jpeg:*
             String protocolInfo = item->getResource(res_id)->getAttributes()->get(_("protocolInfo"));
-            if (protocolInfo != nil)
+            if (protocolInfo != nullptr)
             {
                 mimeType = getMTFromProtocolInfo(protocolInfo);
             }
@@ -618,11 +567,15 @@ Ref<IOHandler> FileRequestHandler::open(IN const char *filename,
         header = getDLNAtransferHeader(mimeType, header);
 #endif
 
+        /* FIXME Upstream upnp
         if (string_ok(header))
                 info->http_header = ixmlCloneDOMString(header.c_str());
+        */
 
-        info->content_type = ixmlCloneDOMString(mimeType.c_str());
-        Ref<IOHandler> io_handler = h->serveContent(item, res_id, &(info->file_length));
+        //info->content_type = ixmlCloneDOMString(mimeType.c_str());
+        //Ref<IOHandler> io_handler = h->serveContent(item, res_id, &(info->file_length));
+        off_t filelength = -1;
+        Ref<IOHandler> io_handler = h->serveContent(item, res_id, &filelength);
         io_handler->open(mode);
         return io_handler;
     }
@@ -635,87 +588,16 @@ Ref<IOHandler> FileRequestHandler::open(IN const char *filename,
 
             Ref<TranscodeDispatcher> tr_d(new TranscodeDispatcher());
             Ref<TranscodingProfile> tp = ConfigManager::getInstance()->getTranscodingProfileListOption(CFG_TRANSCODING_PROFILE_LIST)->getByName(tr_profile);
-            return tr_d->open(tp, path, RefCast(item, CdsObject), info, range);
-        }
-        else
-#endif
-#ifdef HAVE_LIBDVDNAV
-        if (!is_srt && item->getFlag(OBJECT_FLAG_DVD_IMAGE))
-        {
-            String tmp = dict->get(DVDHandler::renderKey(DVD_Title));
-            if (!string_ok(tmp))
-                throw _Exception(_("DVD Image requested but title parameter is missing!"));
-            int title = tmp.toInt();
-            if (title < 0)
-                throw _Exception(_("DVD Image - requested invalid title!"));
-
-            tmp = dict->get(DVDHandler::renderKey(DVD_Chapter));
-            if (!string_ok(tmp))
-                throw _Exception(_("DVD Image requested but chapter parameter is missing!"));
-            int chapter = tmp.toInt();
-            if (chapter < 0)
-                throw _Exception(_("DVD Image - requested invalid chapter!"));
-
-            // actually we are retrieving the audio stream id here
-            tmp = dict->get(DVDHandler::renderKey(DVD_AudioStreamID));
-            if (!string_ok(tmp))
-                throw _Exception(_("DVD Image requested but audio track parameter is missing!"));
-            int audio_track = tmp.toInt();
-            if (audio_track < 0)
-                throw _Exception(_("DVD Image - requested invalid audio stream ID!"));
-
-            /// \todo make sure we can seek in the streams
-            info->file_length = -1;
-            info->force_chunked = 1;
-            header = nil;
-            if (mimeType == nil)
-                mimeType = item->getMimeType();
-
-            info->content_type = ixmlCloneDOMString(mimeType.c_str());
-            log_debug("Serving dvd image %s Title: %d Chapter: %d\n",
-                    path.c_str(), title, chapter);
-            /// \todo add angle support
-            Ref<IOHandler> dvd_io_handler(new DVDIOHandler(path, title, chapter,
-                           audio_track));
-
-            int from_dvd_fd[2];
-            if (pipe(from_dvd_fd) == -1)
-                throw _Exception(_("Failed to create DVD input pipe!"));
-
-            int from_remux_fd[2];
-            if (pipe(from_remux_fd) == -1)
-            {
-                close(from_dvd_fd[0]);
-                close(from_dvd_fd[1]);
-                throw _Exception(_("Failed to create remux output pipe!"));
-            }
-
-            Ref<IOHandler> fd_writer(new FDIOHandler(from_dvd_fd[1]));
-            Ref<ThreadExecutor> from_dvd(new IOHandlerChainer(dvd_io_handler, 
-                                                        fd_writer, 16384));
-
-            Ref<IOHandler> fd_reader(new FDIOHandler(from_remux_fd[0]));
-            fd_reader->open(mode);
-            
-            Ref<MPEGRemuxProcessor> remux(new MPEGRemuxProcessor(from_dvd_fd[0],
-                                          from_remux_fd[1], 
-                                          (unsigned char)audio_track));
-
-            RefCast(fd_reader, FDIOHandler)->addReference(RefCast(remux, Object));
-            RefCast(fd_reader, FDIOHandler)->addReference(RefCast(from_dvd, Object));
-            RefCast(fd_reader, FDIOHandler)->addReference(RefCast(fd_writer, Object));
-            RefCast(fd_reader, FDIOHandler)->closeOther(fd_writer);
-
-            PlayHook::getInstance()->trigger(obj);
-            return fd_reader;
+            return tr_d->open(tp, path, RefCast(item, CdsObject), range);
         }
         else
 #endif
 
         {
-            if (mimeType == nil)
+            if (mimeType == nullptr)
                 mimeType = item->getMimeType();
 
+            /* FIXME Upstream
             info->file_length = statbuf.st_size;
             info->content_type = ixmlCloneDOMString(mimeType.c_str());
 
@@ -731,13 +613,15 @@ Ref<IOHandler> FileRequestHandler::open(IN const char *filename,
 
                 header = header + _("Accept-Ranges: bytes");
             }
+             */
 
 #ifdef EXTEND_PROTOCOLINFO
             header = getDLNAtransferHeader(mimeType, header);
 #endif
+            /* FIXME Upstream upnp
             if (string_ok(header))
                 info->http_header = ixmlCloneDOMString(header.c_str());
-
+            */
 
             Ref<IOHandler> io_handler(new FileIOHandler(path));
             io_handler->open(mode);
diff --git a/src/file_request_handler.h b/src/file_request_handler.h
index 89b0369..eec904b 100644
--- a/src/file_request_handler.h
+++ b/src/file_request_handler.h
@@ -40,9 +40,10 @@ class FileRequestHandler : public RequestHandler
 {
 public:
     FileRequestHandler();
-    virtual void get_info(IN const char *filename, OUT struct File_Info *info);
+
+    virtual void get_info(IN const char *filename, OUT UpnpFileInfo *info);
     virtual zmm::Ref<IOHandler> open(
-            IN const char *filename, OUT struct File_Info *info,
+            IN const char *filename,
             IN enum UpnpOpenFileMode mode,
             IN zmm::String range);
 };
diff --git a/src/filesystem.cc b/src/filesystem.cc
index 37c55a5..6a3057a 100644
--- a/src/filesystem.cc
+++ b/src/filesystem.cc
@@ -29,10 +29,6 @@
 
 /// \file filesystem.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <dirent.h>
@@ -49,8 +45,8 @@ using namespace mxml;
 
 int FsObjectComparator(void *arg1, void *arg2)
 {
-    FsObject *o1 = (FsObject *)arg1;
-    FsObject *o2 = (FsObject *)arg2;
+    auto *o1 = (FsObject *)arg1;
+    auto *o2 = (FsObject *)arg2;
     if (o1->isDirectory)
     {
         if (o2->isDirectory)
@@ -73,7 +69,7 @@ Filesystem::Filesystem() : Object()
     Ref<ConfigManager> cm = ConfigManager::getInstance();
 /*    
     Ref<Element> rules = cm->getElement(_("filter"));
-    if (rules == nil)
+    if (rules == nullptr)
         return;
     for (int i = 0; i < rules->childCount(); i++)
     {
@@ -87,7 +83,7 @@ Filesystem::Filesystem() : Object()
             pattern->compile(pat);
             includeRules->append(pattern);
         }
-        catch (Exception e)
+        catch (const Exception & e)
         {
             e.printStackTrace();
         }
@@ -121,7 +117,7 @@ Ref<Array<FsObject> > Filesystem::readDirectory(String path, int mask,
                         path + " : " + strerror(errno));
     }
 
-    while ((dent = readdir(dir)) != NULL)
+    while ((dent = readdir(dir)) != nullptr)
     {
         char *name = dent->d_name;
         if (name[0] == '.')
@@ -165,7 +161,7 @@ Ref<Array<FsObject> > Filesystem::readDirectory(String path, int mask,
                     {
                         hasContent = have(childPath, childMask);
                     }
-                    catch (Exception e)
+                    catch (const Exception & e)
                     {
                         //continue;
                     }
@@ -217,7 +213,7 @@ bool Filesystem::have(String path, int mask)
     }
 
     bool result = false;
-    while ((dent = readdir(dir)) != NULL)
+    while ((dent = readdir(dir)) != nullptr)
     {
         char *name = dent->d_name;
         if (name[0] == '.')
diff --git a/src/filesystem.h b/src/filesystem.h
index 9d4e563..2873c2e 100644
--- a/src/filesystem.h
+++ b/src/filesystem.h
@@ -39,11 +39,7 @@
 #define FS_MASK_DIRECTORIES 2
 #define FS_MASK_HIDDEN 4 // accept hidden files (start with . "dot")
 
-#ifdef __CYGWIN__
-#define FS_ROOT_DIRECTORY "/cygdrive/"
-#else
 #define FS_ROOT_DIRECTORY "/"
-#endif
 
 class FsObject : public zmm::Object
 {
diff --git a/src/generic_task.cc b/src/generic_task.cc
index 49c88a6..59a94a9 100644
--- a/src/generic_task.cc
+++ b/src/generic_task.cc
@@ -1,10 +1,6 @@
 /*MT*
 */
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "generic_task.h"
 
 GenericTask::GenericTask(task_owner_t taskOwner) : Object()
diff --git a/src/hash.h b/src/hash.h
deleted file mode 100644
index 8694e5c..0000000
--- a/src/hash.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    hash.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file hash.h
-
-#ifndef __HASH_H__
-#define __HASH_H__
-
-#define HASH_PRIME 29
-#define HASH_MAX_ITERATIONS 100
-
-#include "common.h"
-
-struct hash_slot_struct
-{
-    int dummy;
-};
-typedef struct hash_slot_struct *hash_slot_t;
-
-#include "hash/db_hash.h"
-#include "hash/dbr_hash.h"
-#include "hash/dbb_hash.h"
-#include "hash/dbo_hash.h"
-#include "hash/dsb_hash.h"
-#include "hash/dso_hash.h"
-
-#endif // __HASH_H__
diff --git a/src/hash/db_hash.h b/src/hash/db_hash.h
deleted file mode 100644
index d6e42f4..0000000
--- a/src/hash/db_hash.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    db_hash.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file db_hash.h
-
-#ifndef __HASH_DB_HASH_H__
-#define __HASH_DB_HASH_H__
-
-#include "direct_hash_base.h"
-
-/// \brief Direct hash with base type keys only.
-template <typename KT>
-class DBHash : public DHashBase<KT, KT>
-{
-protected:
-    KT emptyKey;
-    KT deletedKey;
-public:
-    DBHash(int capacity, KT emptyKey, KT deletedKey) : DHashBase<KT, KT>(capacity)
-    {
-        // emptyKey and deletedKey must not be the same!
-        assert(emptyKey != deletedKey);
-        this->emptyKey = emptyKey;
-        this->deletedKey = deletedKey;
-        clear();
-    }
-
-    /* virtual methods */
-    virtual int hashCode(KT key)
-    {
-        return this->baseTypeHashCode((unsigned int)key);
-    }
-    virtual bool match(KT key, KT *slot)
-    {
-       return (key == *slot);
-    }
-    virtual bool isEmptySlot(KT *slot)
-    {
-        return (*slot == emptyKey);
-    }
-    
-    virtual bool isDeletedSlot(KT *slot)
-    {
-        return (*slot == deletedKey);
-    }
-    
-    void clear()
-    {
-        if (! emptyKey)
-            this->zero();
-        else
-        {
-            for (int i = 0; i < this->capacity; i++)
-                this->data[i] = emptyKey;
-            this->count = 0;
-        }
-    }
-    
-    inline bool remove(KT key)
-    {
-       KT *slot;
-        if (! search(key, &slot))
-            return false;
-        *slot = deletedKey;
-        this->count--;
-        return true;
-    }
-    
-    inline void put(KT key)
-    {
-        KT *slot;
-        if (! search(key, &slot))
-        {
-            *slot = key;
-            this->count++;
-        }
-    }
-    inline void put(KT key, hash_slot_t destSlot)
-    {
-        KT *slot = (KT *)destSlot;
-        if (*slot == emptyKey)
-        {
-            *slot = key;
-            this->count++;
-        }
-    }
-    
-    inline bool exists(KT key)
-    {
-        KT *slot;
-        return search(key, &slot);
-    }
-    inline bool exists(KT key, hash_slot_t *destSlot)
-    {
-        return search(key, (KT **)destSlot);
-    }
-};
-
-#endif // __HASH_DS_HASH_H__
diff --git a/src/hash/dbb_hash.h b/src/hash/dbb_hash.h
deleted file mode 100644
index a85ecdd..0000000
--- a/src/hash/dbb_hash.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    dbb_hash.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file dbb_hash.h
-
-#ifndef __HASH_DBB_HASH_H__
-#define __HASH_DBB_HASH_H__
-
-#include "direct_hash_base.h"
-
-template <typename KT, typename VT> struct dbb_hash_slot
-{
-    KT key;
-    VT value;
-};
-
-/// \brief Direct hash with base type keys and base type values.
-template <typename KT, typename VT>
-class DBBHash : public DHashBase<KT, struct dbb_hash_slot<KT, VT> >
-{
-protected:
-    KT emptyKey;
-public:
-    DBBHash(int capacity, KT emptyKey) : DHashBase<KT, struct dbb_hash_slot<KT, VT> >(capacity)
-    {
-        this->emptyKey = emptyKey;
-        clear();
-    }
-    
-    /* virtual methods */
-    virtual int hashCode(KT key)
-    {
-        return this->baseTypeHashCode((unsigned int)key);
-    }
-    virtual bool match(KT key, struct dbb_hash_slot<KT, VT> *slot)
-    {
-        return (key == slot->key);
-    }
-    virtual bool isEmptySlot(struct dbb_hash_slot<KT, VT> *slot)
-    {
-        return (slot->key == emptyKey);
-    }
-
-    void clear()
-    {
-        if (! emptyKey)
-            this->zero();
-        else
-        {
-            for (int i = 0; i < this->capacity; i++)
-                this->data[i].key = emptyKey;
-            this->count = 0;
-        }
-    }
-    
-    /* need to use deleted key
-    inline bool remove(KT key)
-    {
-        struct dbb_hash_slot<KT, VT> *slot;
-        if (! search(key, &slot))
-            return false;
-        slot->key = emptyKey;
-        this->count--;
-        return true;
-    }
-    */
-    
-    inline void put(KT key, VT value)
-    {
-        struct dbb_hash_slot<KT, VT> *slot;
-        bool found = search(key, &slot);
-        if (! found)
-        {
-            slot->key = key;
-            this->count++;
-        }
-        slot->value = value;
-    }
-    inline void put(KT key, hash_slot_t destSlot, VT value)
-    {
-        struct dbb_hash_slot<KT, VT> *slot = (struct dbb_hash_slot<KT, VT> *)destSlot;
-        if (slot->key == emptyKey)
-        {
-            slot->key = key;
-            this->count++;
-        }
-        slot->value = value;
-    }
-
-    inline bool get(KT key, VT *value)
-    {
-        struct dbb_hash_slot<KT, VT> *slot;
-        bool found = search(key, &slot);
-        if (found)
-            *value = slot->value;
-        return found;
-    }
-    bool get(KT key, hash_slot_t *destSlot, VT *value)
-    {
-        struct dbb_hash_slot<KT, VT> **slot = (struct dbb_hash_slot<KT, VT> **)destSlot;
-        bool found = search(key, slot);
-        if (found)
-            *value = (*slot)->value;
-        return found;
-    }
-    inline bool exists(KT key)
-    {
-        struct dbb_hash_slot<KT, VT> *slot;
-        return search(key, &slot);
-    }
-    inline bool exists(KT key, hash_slot_t *destSlot)
-    {
-        return search(key, (struct dbb_hash_slot<KT, VT> **)destSlot);
-    }
-};
-
-#endif // __HASH_DBB_HASH_H__
diff --git a/src/hash/dbo_hash.h b/src/hash/dbo_hash.h
deleted file mode 100644
index a75c649..0000000
--- a/src/hash/dbo_hash.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    dbo_hash.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file dbo_hash.h
-
-#ifndef __HASH_DBO_HASH_H__
-#define __HASH_DBO_HASH_H__
-
-#include "direct_hash_base.h"
-#include <assert.h>
-
-template <typename KT, typename VT> struct dbo_hash_slot
-{
-    KT key;
-    VT *value;
-};
-
-/// \brief Direct hash with base type keys and object ("Ref") values.
-template <typename KT, typename VT>
-class DBOHash : public DHashBase<KT, struct dbo_hash_slot<KT, VT> >
-{
-protected:
-    KT emptyKey;
-    KT deletedKey;
-public:
-    DBOHash(int capacity, KT emptyKey, KT deletedKey) : DHashBase<KT, struct dbo_hash_slot<KT, VT> >(capacity)
-    {
-        // emptyKey and deletedKey must not be the same!
-        assert(emptyKey != deletedKey);
-        this->emptyKey = emptyKey;
-        this->deletedKey = deletedKey;
-        init();
-    }
-    virtual ~DBOHash()
-    {
-        releaseData();
-    }
-protected:
-    void init()
-    {
-        if (! emptyKey)
-            this->zero();
-        else
-        {
-            for (int i = 0; i < this->capacity; i++)
-                this->data[i].key = emptyKey;
-            this->count = 0;
-        }
-    }
-    void releaseData()
-    {
-        dbo_hash_slot<KT, VT> *slot;
-        for (int i = 0; i < this->capacity; i++)
-        {
-            slot = this->data + i;
-            if (slot->key != emptyKey && slot->key != deletedKey)
-                slot->value->release();
-        }
-    }
-public:
-    void clear()
-    {
-        dbo_hash_slot<KT, VT> *slot;
-        for (int i = 0; i < this->capacity; i++)
-        {
-            slot = this->data + i;
-            if (slot->key != emptyKey && slot->key != deletedKey)
-            {
-                slot->key = emptyKey;
-                slot->value->release();
-            }
-            else if (slot->key == deletedKey)
-            {
-                slot->key = emptyKey;
-            }
-        }
-        this->count = 0;
-    }
-    
-    inline bool remove(KT key)
-    {
-        struct dbo_hash_slot<KT, VT> *slot;
-        if (! this->search(key, &slot))
-            return false;
-        slot->key = deletedKey;
-        slot->value->release();
-        this->count--;
-        return true;
-    }
-    
-    /* virtual methods */
-    virtual int hashCode(KT key)
-    {
-        return this->baseTypeHashCode((unsigned int)key);
-    }
-    virtual bool match(KT key, struct dbo_hash_slot<KT, VT> *slot)
-    {
-        return (key == slot->key);
-    }
-    virtual bool isEmptySlot(struct dbo_hash_slot<KT, VT> *slot)
-    {
-        return (slot->key == emptyKey);
-    }
-    
-    virtual bool isDeletedSlot(struct dbo_hash_slot<KT, VT> *slot)
-    {
-        return (slot->key == deletedKey);
-    }
-    
-    inline void put(KT key, zmm::Ref<VT> value)
-    {
-        struct dbo_hash_slot<KT, VT> *slot;
-        this->search(key, &slot);
-        put(key, (hash_slot_t)slot, value);
-    }
-    void put(KT key, hash_slot_t destSlot, zmm::Ref<VT> value)
-    {
-        struct dbo_hash_slot<KT, VT> *slot = (struct dbo_hash_slot<KT, VT> *)destSlot;
-        if (slot->key != emptyKey && slot->key != deletedKey)
-        {
-            VT *valuePtr = value.getPtr();
-            valuePtr->retain();
-            slot->value->release();
-            slot->value = valuePtr;
-        }
-        else
-        {
-            this->count++;
-            slot->key = key;
-            VT *valuePtr = value.getPtr();
-            valuePtr->retain();
-            slot->value = valuePtr;
-        }    
-    }
-
-    inline zmm::Ref<VT> get(KT key)
-    {
-        struct dbo_hash_slot<KT, VT> *slot;
-        bool found = this->search(key, &slot);
-        if (found)
-            return zmm::Ref<VT>(slot->value);
-        else
-            return nil;
-        
-        hash_slot_t destSlot;
-        return get(key, &destSlot);
-    }
-    inline zmm::Ref<VT> get(KT key, hash_slot_t *destSlot)
-    {
-        struct dbo_hash_slot<KT, VT> **slot = (struct dbo_hash_slot<KT, VT> **)destSlot;
-        bool found = this->search(key, slot);
-        if (found)
-            return zmm::Ref<VT>((*slot)->value);
-        else
-            return nil;
-    }
-};
-
-#endif // __HASH_DBO_HASH_H__
diff --git a/src/hash/dbr_hash.h b/src/hash/dbr_hash.h
deleted file mode 100644
index 1614b97..0000000
--- a/src/hash/dbr_hash.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    dbr_hash.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file dbr_hash.h
-
-#ifndef __HASH_DBR_HASH_H__
-#define __HASH_DBR_HASH_H__
-
-#include "direct_hash_base.h"
-
-template <typename KT> struct dbr_hash_slot
-{
-    KT key;
-    int array_slot;
-};
-
-template <typename KT> struct hash_data_array_t
-{
-    int size;
-    KT *data;
-};
-
-/// \brief Direct hash with base type keys only. It is NOT thread-safe!
-/// It has remove() and getAll() functions
-template <typename KT>
-class DBRHash : public DHashBase<KT, struct dbr_hash_slot<KT> >
-{
-protected:
-    KT emptyKey;
-    KT deletedKey;
-    KT *data_array;
-#ifdef TOMBDEBUG
-    int realCapacity;
-#endif
-public:
-    /// \param hashCapacity the size of the hashtable
-    /// \param realCapacityKT maximum number of elements "you" will store in this instance (has to be < than hashCapacity!)
-    /// WARNING: the number of stored entries MUST be <= realCapacity at all times!
-    DBRHash(int hashCapacity, int realCapacity, KT emptyKey, KT deletedKey) : DHashBase<KT, struct dbr_hash_slot<KT> >(hashCapacity)
-    {
-#ifdef TOMBDEBUG
-        if (realCapacity <=0)
-            throw zmm::Exception(_("illegal realCapacity (") + realCapacity + ")");
-        this->realCapacity = realCapacity;
-        if (realCapacity >= hashCapacity)
-            throw zmm::Exception(_("realCapacity (") + realCapacity + ") MUST be < hashCapacity (" + hashCapacity + ")");
-#endif
-        if (emptyKey == deletedKey)
-            throw zmm::Exception(_("emptyKey and deletedKey must not be the same!"));
-        this->emptyKey = emptyKey;
-        this->deletedKey = deletedKey;
-        data_array = (KT *)MALLOC(realCapacity * sizeof(KT));
-        clear();
-    }
-    
-    virtual ~DBRHash()
-    {
-        FREE(data_array);
-    }
-    
-    /* virtual methods */
-    virtual int hashCode(KT key)
-    {
-        return this->baseTypeHashCode((unsigned int)key);
-    }
-    
-    virtual bool match(KT key, struct dbr_hash_slot<KT> *slot)
-    {
-       return (key == slot->key);
-    }
-    
-    virtual bool isEmptySlot(struct dbr_hash_slot<KT> *slot)
-    {
-        return (slot->key == emptyKey);
-    }
-    
-    virtual bool isDeletedSlot(struct dbr_hash_slot<KT> *slot)
-    {
-        return (slot->key == deletedKey);
-    }
-    
-    void clear()
-    {
-        if (! emptyKey)
-            this->zero();
-        else
-        {
-            struct dbr_hash_slot<KT> *slot;
-            for (int i = 0; i < this->capacity; i++)
-            {
-                slot = this->data +i;
-                slot->key = emptyKey;
-            }
-            this->count = 0;
-        }
-    }
-    
-    inline bool remove(KT key)
-    {
-        struct dbr_hash_slot<KT> *slot;
-        if (! this->search(key, &slot))
-            return false;
-        slot->key = deletedKey;
-        int array_slot = slot->array_slot;
-        if (this->count == 1 || this->count-1 == array_slot)
-        {
-            this->count--;
-            return true;
-        }
-        data_array[array_slot] = data_array[--this->count];
-        if (! this->search(data_array[array_slot], &slot))
-        {
-            log_debug("DBR-Hash-Error: (%d; array_slot=%d; count=%d)\n", data_array[array_slot], array_slot, this->count);
-            throw zmm::Exception(_("DBR-Hash-Error: key in data_array not found in hashtable"));
-        }
-        slot->array_slot = array_slot;
-        return true;
-    }
-    
-    inline void put(KT key)
-    {
-        struct dbr_hash_slot<KT> *slot;
-        if (! this->search(key, &slot))
-        {
-#ifdef TOMBDEBUG
-            if (this->count >= realCapacity)
-                throw zmm::Exception(_("count (") + this->count + ") reached realCapacity (" + realCapacity + ")!\n");
-#endif
-            slot->key = key;
-            slot->array_slot = this->count;
-            data_array[this->count++] = key;
-        }
-    }
-    
-    /// \brief returns all keys as an array. After the deletion of the DBRHash object, the array is invalid!
-    inline void getAll(hash_data_array_t<KT> *hash_data_array)
-    {
-        hash_data_array->size = this->count;
-        hash_data_array->data = data_array;
-    }
-    
-    zmm::String debugGetAll()
-    {
-        zmm::Ref<zmm::StringBuffer> buf(new zmm::StringBuffer());
-        if (this->count == 0)
-            return _("");
-        *buf << data_array[0];
-        for (int i = 1; i < this->count; i++)
-        {
-            *buf << ", " << data_array[i];
-        }
-        return buf->toString();
-    }
-    
-    /*
-     * is this really needed? seems so make no sense...
-    inline void put(KT key, hash_slot_t destSlot)
-    {
-        KT *slot = (KT *)destSlot;
-        if (slot->key == emptyKey)
-        {
-            slot->key = key;
-            this->count++;
-        }
-    }
-    */
-    
-    inline bool exists(KT key)
-    {
-        struct dbr_hash_slot<KT> *slot;
-        return this->search(key, &slot);
-    }
-    
-    /*
-     * unneded, i think...
-     
-    inline bool exists(KT key, hash_slot_t *destSlot)
-    {
-        return search(key, (KT **)destSlot);
-    }
-    */
-};
-
-#endif // __HASH_DBR_HASH_H__
diff --git a/src/hash/direct_hash_base.h b/src/hash/direct_hash_base.h
deleted file mode 100644
index 5526f87..0000000
--- a/src/hash/direct_hash_base.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    direct_hash_base.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file direct_hash_base.h
-
-#ifndef __HASH_DIRECT_HASH_BASE_H__
-#define __HASH_DIRECT_HASH_BASE_H__
-
-#include "hash.h"
-
-template <typename KT, typename ST>
-class DHashBase : public zmm::Object
-{
-protected:
-    int capacity;
-    int count;
-    ST *data;
-public:
-    DHashBase(int capacity) : zmm::Object()
-    {
-        this->capacity = capacity;
-        count = 0;
-        data = (ST *)MALLOC(capacity * sizeof(ST));
-    }
-    virtual ~DHashBase()
-    {
-        FREE(data);
-    }
-    void zero()
-    {
-        count = 0;
-        memset(data, 0, capacity * sizeof(ST));
-    }
-    inline int size()
-    {
-        return count;
-    }
-    
-    /* abstract methods to be implemented in deriving classes */
-    virtual int hashCode(KT key) = 0;
-    virtual bool match(KT key, ST *slot) = 0;
-    virtual bool isEmptySlot(ST *slot) = 0;
-    virtual bool isDeletedSlot(ST *slot)
-    {
-        return false;
-    }
-    
-    inline int baseTypeHashCode(unsigned int key)
-    {
-        return ((key * 0xd2d84a61) ^ 0x7832c9f4) % capacity;
-    }
-/*
-    int stringHashCode(zmm::String key)
-    {
-        int i;
-            
-        int len = key.length();
-        int iLen = len >> 2;
-        int iRest = len & 3;
-        unsigned int *iData = (unsigned int *)key.c_str();
-        unsigned int sum = 0;
-        
-        for(i = 0; i < iLen; i++)
-            sum ^= iData[i];
-        if (iRest)
-        {
-            unsigned char *ptr = (unsigned char *)(iData + i);
-            unsigned int restSum = 0;
-            while (*ptr)
-                restSum = (restSum << 8) | *(ptr++);
-            sum ^= restSum;
-        }
-        return ((sum * 0xd2d84a61) ^ 0x7832c9f4) % capacity;
-    }
-*/
-    
-    int secondaryHashCode(int primary)
-    {
-        int h2 = (HASH_PRIME - (primary % HASH_PRIME));
-        if (h2 == 0)
-            h2 = HASH_PRIME;
-        return h2;
-    }
-   
-    // if found an empty slot, retSlot is set and false is returned
-    // if found a slot with the given key retSlot is set and true is returned
-    bool search(KT key, ST **retSlot)
-    {
-        // calculating primary hash
-        int h = hashCode(key);
-        // secondary hash
-        int h2 = 0;
-        
-        ST *deletedSlot = NULL;
-        
-        for (int i = 0; i < HASH_MAX_ITERATIONS; i++)
-        {
-            ST *slot = data + h;
-            
-            // found an empty slot
-            if (isEmptySlot(slot))
-            {
-                if (deletedSlot)
-                    *retSlot = deletedSlot;
-                else
-                    *retSlot = slot;
-                return false;
-            }
-            
-            if (isDeletedSlot(slot))
-            {
-                deletedSlot = slot;
-            }
-            else if (match(key, slot))
-            {
-                // found the key
-                *retSlot = slot;
-                return true;
-            }
-            
-            // collision, probing next slot
-            if (! h2)
-                h2 = secondaryHashCode(h);
-            h = (h + h2) % capacity;
-        }
-        log_error("AbstractHash::search() failed, maximal number of iterations exceeded: h:%d  h2:%d size:%d\n", h, h2, count);
-        throw zmm::Exception(_("AbstractHash::search() failed, maximal number of iterations exceeded: h:") + h + " h2:"+ h2);
-    }
-};
-
-#endif // __HASH_DIRECT_HASH_BASE_H__
diff --git a/src/hash/dsb_hash.h b/src/hash/dsb_hash.h
deleted file mode 100644
index a739e8f..0000000
--- a/src/hash/dsb_hash.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    dsb_hash.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file dsb_hash.h
-
-#ifndef __HASH_DSB_HASH_H__
-#define __HASH_DSB_HASH_H__
-
-#include "direct_hash_base.h"
-#include "tools.h"
-
-template <typename VT> struct dsb_hash_slot
-{
-    zmm::StringBase *key;
-    VT *value;
-};
-
-
-/// \brief Direct hash with string keys and base type values.
-template <typename VT>
-class DSBHash : public DHashBase<zmm::String, struct dsb_hash_slot<VT> >
-{
-public:
-    DSBHash(int capacity) : DHashBase<zmm::String, struct dsb_hash_slot<VT> >(capacity)
-    {
-        this->zero();
-    }
-    virtual ~DSBHash()
-    {
-        releaseData();
-    }
-    void releaseData()
-    {
-        for (int i = 0; i < this->capacity; i++)
-        {
-            dsb_hash_slot<VT> *slot = this->data + i;
-            if (slot->key)
-                slot->key->release();
-        }
-    }
-    
-    /* virtual methods */
-    virtual int hashCode(zmm::String key)
-    {
-        return stringHash(key);
-    }
-    virtual bool match(zmm::String key, struct dsb_hash_slot<VT> *slot)
-    {
-       return (! strcmp(key.c_str(), slot->key->data));
-    }
-    virtual bool isEmptySlot(struct dsb_hash_slot<VT> *slot)
-    {
-        return (slot->key == NULL);
-    }
-    
-    void clear()
-    {
-        releaseData();
-        this->zero();
-    }
-    
-    /* #error need to use deleted key
-    inline bool remove(zmm::String key)
-    {
-        struct dsb_hash_slot<VT> *slot;
-        if (! search(key, &slot))
-            return false;
-        slot->key->release();
-        slot->key = NULL;
-        this->count--;
-        return true;
-    }
-    */
-    
-    inline void put(zmm::String key, VT value)
-    {
-        struct dsb_hash_slot<VT> *slot;
-        search(key, &slot);
-        put(key, (hash_slot_t)slot, value);
-    }
-    void put(zmm::String key, hash_slot_t destSlot, VT value)
-    {
-        struct dsb_hash_slot<VT> *slot = (struct dsb_hash_slot<VT> *)destSlot;
-        if (slot->key != NULL)
-            slot->value = value;
-        else
-        {
-            this->count++;
-            zmm::StringBase *keyBase = key.getBase();
-            keyBase->retain();
-            slot->key = keyBase;
-            slot->value = value;
-        }    
-    }
-
-    inline VT get(zmm::String key)
-    {
-        struct dsb_hash_slot<VT> *slot;
-        bool found = search(key, &slot);
-        if (found)
-            return slot->value;
-        else
-            return nil;
-        
-        hash_slot_t destSlot;
-        return get(key, destSlot);
-    }
-    inline VT get(zmm::String key, hash_slot_t *destSlot)
-    {
-        struct dsb_hash_slot<VT> **slot = (struct dsb_hash_slot<VT> **)destSlot;
-        bool found = search(key, slot);
-        if (found)
-            return (*slot)->value;
-        else
-            return nil;
-    }
-};
-
-#endif // __HASH_DSB_HASH_H__
diff --git a/src/hash/dso_hash.h b/src/hash/dso_hash.h
deleted file mode 100644
index c132350..0000000
--- a/src/hash/dso_hash.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    dso_hash.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file dso_hash.h
-
-#ifndef __HASH_DSO_HASH_H__
-#define __HASH_DSO_HASH_H__
-
-#include "direct_hash_base.h"
-#include "tools.h"
-
-template <typename VT> struct dso_hash_slot
-{
-    zmm::StringBase *key;
-    VT *value;
-};
-
-/// \brief direct hash with string keys and object ("Ref") values
-template <typename VT>
-class DSOHash : public DHashBase<zmm::String, struct dso_hash_slot<VT> >
-{
-public:
-    DSOHash(int capacity) : DHashBase<zmm::String, struct dso_hash_slot<VT> >(capacity)
-    {
-        this->zero();
-        deletedKey = new zmm::StringBase("");
-    }
-    virtual ~DSOHash()
-    {
-        releaseData();
-        deletedKey->release();
-    }
-protected:
-    
-    zmm::StringBase *deletedKey;
-    
-    void releaseData()
-    {
-        for (int i = 0; i < this->capacity; i++)
-        {
-            dso_hash_slot<VT> *slot = this->data + i;
-            if (slot->key && slot->key != deletedKey)
-            {
-                slot->key->release();
-                slot->value->release();
-            }
-        }
-    }
-public:
-    /* virtual methods */
-    virtual int hashCode(zmm::String key)
-    {
-        return this->baseTypeHashCode(stringHash(key));
-    }
-    virtual bool match(zmm::String key, struct dso_hash_slot<VT> *slot)
-    {
-       return (! strcmp(key.c_str(), slot->key->data));
-    }
-    virtual bool isEmptySlot(struct dso_hash_slot<VT> *slot)
-    {
-        return (slot->key == NULL);
-    }
-    virtual bool isDeletedSlot(struct dso_hash_slot<VT> *slot)
-    {
-        return (slot->key == deletedKey);
-    }
-    
-    void clear()
-    {
-        releaseData();
-        this->zero();
-    }
-    
-    inline bool remove(zmm::String key)
-    {
-        struct dso_hash_slot<VT> *slot;
-        if (! this->search(key, &slot))
-            return false;
-        slot->key->release();
-        slot->value->release();
-        slot->key = deletedKey;
-        this->count--;
-        return true;
-    }
-    
-    inline void put(zmm::String key, zmm::Ref<VT> value)
-    {
-        struct dso_hash_slot<VT> *slot;
-        this->search(key, &slot);
-        put(key, (hash_slot_t)slot, value);
-    }
-    void put(zmm::String key, hash_slot_t destSlot, zmm::Ref<VT> value)
-    {
-        struct dso_hash_slot<VT> *slot = (struct dso_hash_slot<VT> *)destSlot;
-        if (slot->key != NULL && slot->key != deletedKey)
-        {
-            VT *valuePtr = value.getPtr();
-            valuePtr->retain();
-            slot->value->release();
-            slot->value = valuePtr;
-        }            
-        else
-        {
-            this->count++;
-            zmm::StringBase *keyBase = key.getBase();
-            keyBase->retain();
-            slot->key = keyBase;
-                
-            VT *valuePtr = value.getPtr();
-            valuePtr->retain();
-            slot->value = valuePtr;
-        }    
-    }
-
-    inline zmm::Ref<VT> get(zmm::String key)
-    {
-        struct dso_hash_slot<VT> *slot;
-        bool found = this->search(key, &slot);
-        if (found)
-            return zmm::Ref<VT>(slot->value);
-        else
-            return nil;
-        
-        hash_slot_t destSlot;
-        return get(key, &destSlot);
-    }
-    inline zmm::Ref<VT> get(zmm::String key, hash_slot_t *destSlot)
-    {
-        struct dso_hash_slot<VT> **slot = (struct dso_hash_slot<VT> **)destSlot;
-        bool found = this->search(key, slot);
-        if (found)
-            return zmm::Ref<VT>((*slot)->value);
-        else
-            return nil;
-    }
-};
-
-#endif // __HASH_DSO_HASH_H__
diff --git a/src/inotify-nosys.h b/src/inotify-nosys.h
deleted file mode 100644
index 5f7b11b..0000000
--- a/src/inotify-nosys.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * This header is used if <sys/inotify.h> cannot be found.
- *
- * Inode based directory notification for Linux
- *
- * Copyright (C) 2005 John McCutchan
- */
-
-#ifndef _LINUX_INOTIFY_H
-#define _LINUX_INOTIFY_H
-
-#include <stdint.h>
-#include <sys/syscall.h>
-#include <unistd.h>
-
-/*
- * struct inotify_event - structure read from the inotify device for each event
- *
- * When you are watching a directory, you will receive the filename for events
- * such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ..., relative to the wd.
- */
-struct inotify_event {
-	int		wd;		/* watch descriptor */
-	uint32_t		mask;		/* watch mask */
-	uint32_t		cookie;		/* cookie to synchronize two events */
-	uint32_t		len;		/* length (including nulls) of name */
-	char		name __flexarr;	/* stub for possible name */
-};
-
-/* the following are legal, implemented events that user-space can watch for */
-#define IN_ACCESS		0x00000001	/* File was accessed */
-#define IN_MODIFY		0x00000002	/* File was modified */
-#define IN_ATTRIB		0x00000004	/* Metadata changed */
-#define IN_CLOSE_WRITE		0x00000008	/* Writtable file was closed */
-#define IN_CLOSE_NOWRITE	0x00000010	/* Unwrittable file closed */
-#define IN_OPEN			0x00000020	/* File was opened */
-#define IN_MOVED_FROM		0x00000040	/* File was moved from X */
-#define IN_MOVED_TO		0x00000080	/* File was moved to Y */
-#define IN_CREATE		0x00000100	/* Subfile was created */
-#define IN_DELETE		0x00000200	/* Subfile was deleted */
-#define IN_DELETE_SELF		0x00000400	/* Self was deleted */
-#define IN_MOVE_SELF		0x00000800	/* Self was moved */
-
-/* the following are legal events.  they are sent as needed to any watch */
-#define IN_UNMOUNT		0x00002000	/* Backing fs was unmounted */
-#define IN_Q_OVERFLOW		0x00004000	/* Event queued overflowed */
-#define IN_IGNORED		0x00008000	/* File was ignored */
-
-/* helper events */
-#define IN_CLOSE		(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* close */
-#define IN_MOVE			(IN_MOVED_FROM | IN_MOVED_TO) /* moves */
-
-/* special flags */
-#define IN_ONLYDIR		0x01000000	/* only watch the path if it is a directory */
-#define IN_DONT_FOLLOW		0x02000000	/* don't follow a sym link */
-#define IN_MASK_ADD		0x20000000	/* add to the mask of an already existing watch */
-#define IN_ISDIR		0x40000000	/* event occurred against dir */
-#define IN_ONESHOT		0x80000000	/* only send event once */
-
-/*
- * All of the events - we build the list by hand so that we can add flags in
- * the future and not break backward compatibility.  Apps will get only the
- * events that they originally wanted.  Be sure to add new events here!
- */
-#define IN_ALL_EVENTS	(IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | \
-			 IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | \
-			 IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF | \
-			 IN_MOVE_SELF)
-
-#if defined (__alpha__)
-# define __NR_inotify_init 444
-# define __NR_inotify_add_watch 445
-# define __NR_inotify_rm_watch 446
-
-#elif defined (__arm__)
-# define __NR_inotify_init (__NR_SYSCALL_BASE+316)
-# define __NR_inotify_add_watch (__NR_SYSCALL_BASE+317)
-# define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+318)
-
-#elif defined (__frv__)
-# define __NR_inotify_init 291
-# define __NR_inotify_add_watch 292
-# define __NR_inotify_rm_watch 293
-
-#elif defined(__i386__)
-# define __NR_inotify_init 291
-# define __NR_inotify_add_watch 292
-# define __NR_inotify_rm_watch 293
-
-#elif defined (__ia64__)
-# define __NR_inotify_init 1277
-# define __NR_inotify_add_watch 1278
-# define __NR_inotify_rm_watch 1279
-
-#elif defined (__mips__)
-# if _MIPS_SIM == _MIPS_SIM_ABI32
-#  define __NR_inotify_init (__NR_Linux + 284)
-#  define __NR_inotify_add_watch (__NR_Linux + 285)
-#  define __NR_inotify_rm_watch (__NR_Linux + 286)
-# endif
-# if _MIPS_SIM == _MIPS_SIM_ABI64
-#  define __NR_inotify_init (__NR_Linux + 243)
-#  define __NR_inotify_add_watch (__NR_Linux + 243)
-#  define __NR_inotify_rm_watch (__NR_Linux + 243)
-# endif
-# if _MIPS_SIM == _MIPS_SIM_NABI32
-#  define __NR_inotify_init (__NR_Linux + 247)
-#  define __NR_inotify_add_watch (__NR_Linux + 248)
-#  define __NR_inotify_rm_watch (__NR_Linux + 249)
-# endif
-
-#elif defined(__parisc__)
-# define __NR_inotify_init (__NR_Linux + 269)
-# define __NR_inotify_add_watch (__NR_Linux + 270)
-# define __NR_inotify_rm_watch (__NR_Linux + 271)
-
-#elif defined(__powerpc__) || defined(__powerpc64__)
-# define __NR_inotify_init 275
-# define __NR_inotify_add_watch 276
-# define __NR_inotify_rm_watch 277
-
-#elif defined (__s390__)
-# define __NR_inotify_init 284
-# define __NR_inotify_add_watch 285
-# define __NR_inotify_rm_watch 286
-
-#elif defined (__sh__)
-# define __NR_inotify_init 290
-# define __NR_inotify_add_watch 291
-# define __NR_inotify_rm_watch 292
-
-#elif defined (__sh64__)
-# define __NR_inotify_init 318
-# define __NR_inotify_add_watch 319
-# define __NR_inotify_rm_watch 320
-
-#elif defined (__sparc__) || defined (__sparc64__)
-# define __NR_inotify_init 151
-# define __NR_inotify_add_watch 152
-# define __NR_inotify_rm_watch 156
-
-#elif defined(__x86_64__)
-# define __NR_inotify_init 253
-# define __NR_inotify_add_watch 254
-# define __NR_inotify_rm_watch 255
-
-#else
-# error "Unsupported architecture!"
-#endif
-
-static inline int inotify_init (void)
-{
-	return syscall (__NR_inotify_init);
-}
-
-static inline int inotify_add_watch (int fd, const char *name, uint32_t mask)
-{
-	return syscall (__NR_inotify_add_watch, fd, name, mask);
-}
-
-static inline int inotify_rm_watch (int fd, uint32_t wd)
-{
-	return syscall (__NR_inotify_rm_watch, fd, wd);
-}
-
-
-#endif	/* _LINUX_INOTIFY_H */
diff --git a/src/io_handler.cc b/src/io_handler.cc
index da5142d..3a1579f 100644
--- a/src/io_handler.cc
+++ b/src/io_handler.cc
@@ -30,24 +30,10 @@
 /// \file io_handler.cc
 /// This handles the VirtualDirCallbacks that come from the web server.
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
+#include <unistd.h>
+#include <upnp-1.8/ixml.h>
 
-#include "web_callbacks.h"
 #include "server.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include "common.h"
-#include "storage.h"
-#include "cds_objects.h"
-#include "process.h"
-#include "update_manager.h"
-#include "ixml.h"
-#include "io_handler.h"
 
 using namespace zmm;
 
diff --git a/src/io_handler.h b/src/io_handler.h
index 7f20caa..b62a439 100644
--- a/src/io_handler.h
+++ b/src/io_handler.h
@@ -32,8 +32,9 @@
 #ifndef __IO_HANDLER_H__
 #define __IO_HANDLER_H__
 
+#include <upnp-1.8/upnp.h>
+
 #include "common.h"
-#include "upnp.h"
 
 class IOHandler : public zmm::Object
 {
diff --git a/src/io_handler_buffer_helper.cc b/src/io_handler_buffer_helper.cc
index ad241f5..fca1be0 100644
--- a/src/io_handler_buffer_helper.cc
+++ b/src/io_handler_buffer_helper.cc
@@ -29,30 +29,23 @@
 
 /// \file io_handler_buffer_helper.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "io_handler_buffer_helper.h"
 #include "config_manager.h"
-#include "tools.h"
 
 using namespace zmm;
+using namespace std;
 
 IOHandlerBufferHelper::IOHandlerBufferHelper(size_t bufSize, size_t initialFillSize) : IOHandler()
 {
     if (bufSize <=0)
         throw _Exception(_("bufSize must be positive"));
-    if (initialFillSize < 0 || initialFillSize > bufSize)
-        throw _Exception(_("initialFillSize must be non-negative and must be lesser than or equal to the size of the buffer"));
-    
-    mutex = Ref<Mutex>(new Mutex());
-    cond = Ref<Cond>(new Cond(mutex));
+    if (initialFillSize > bufSize)
+        throw _Exception(_("initialFillSize must be lesser than or equal to the size of the buffer"));
     
     this->bufSize = bufSize;
     this->initialFillSize = initialFillSize;
     waitForInitialFillSize = (initialFillSize > 0);
-    buffer = NULL;
+    buffer = nullptr;
     isOpen = false;
     threadShutdown = false;
     eof = false;
@@ -71,7 +64,7 @@ void IOHandlerBufferHelper::open(IN enum UpnpOpenFileMode mode)
     if (isOpen)
         throw _Exception(_("tried to reopen an open IOHandlerBufferHelper"));
     buffer = (char *)MALLOC(bufSize);
-    if (buffer == NULL)
+    if (buffer == nullptr)
         throw _Exception(_("Failed to allocate memory for transcoding buffer!"));
 
     startBufferThread();
@@ -91,7 +84,7 @@ int IOHandlerBufferHelper::read(OUT char *buf, IN size_t length)
     // length must be positive
     assert(length > 0);
     
-    AUTOLOCK(mutex);
+    unique_lock<std::mutex> lock(mutex);
     
     while ((empty || waitForInitialFillSize) && ! (threadShutdown || eof || readError))
     {
@@ -101,7 +94,7 @@ int IOHandlerBufferHelper::read(OUT char *buf, IN size_t length)
             return CHECK_SOCKET;
         }
         else
-            cond->wait();
+            cond.wait(lock);
     }
     
     if (readError || threadShutdown)
@@ -110,7 +103,7 @@ int IOHandlerBufferHelper::read(OUT char *buf, IN size_t length)
         return 0;
     
     size_t bLocal = b;
-    AUTOUNLOCK();
+    lock.unlock();
     
     // we ensured with the while above that the buffer isn't empty
     int currentFillSize = bLocal - a;
@@ -129,13 +122,13 @@ int IOHandlerBufferHelper::read(OUT char *buf, IN size_t length)
     
     size_t didRead = read1+read2;
     
-    AUTORELOCK();
+    lock.lock();
     
     bool signalled = false;
     // was the buffer full or became it "full" while we read?
     if (signalAfterEveryRead || a == b)
     {
-        cond->signal();
+        cond.notify_one();
         signalled = true;
     }
     
@@ -146,7 +139,7 @@ int IOHandlerBufferHelper::read(OUT char *buf, IN size_t length)
     {
         empty = true;
         if (! signalled)
-            cond->signal();
+            cond.notify_one();
     }
     
     posRead += didRead;
@@ -170,7 +163,7 @@ void IOHandlerBufferHelper::seek(IN off_t offset, IN int whence)
     if (whence == SEEK_CUR && offset == 0)
         return;
     
-    AUTOLOCK(mutex);
+    unique_lock<std::mutex> lock(mutex);
     
     // if another seek isn't processed yet - well we don't care as this new seek
     // will change the position anyway
@@ -179,11 +172,12 @@ void IOHandlerBufferHelper::seek(IN off_t offset, IN int whence)
     seekWhence = whence;
     
     // tell the probably sleeping thread to process our seek
-    cond->signal();
+    cond.notify_one();
     
     // wait until the seek has been processed
-    while(doSeek && ! (threadShutdown || eof || readError))
-        cond->wait();
+    cond.wait(lock, [&](){
+            return !doSeek || threadShutdown || eof || readError;
+    });
 }
 
 void IOHandlerBufferHelper::close()
@@ -193,7 +187,7 @@ void IOHandlerBufferHelper::close()
     isOpen = false;
     stopBufferThread();
     FREE(buffer);
-    buffer = NULL;
+    buffer = nullptr;
 }
 
 // thread stuff...
@@ -202,7 +196,7 @@ void IOHandlerBufferHelper::startBufferThread()
 {
     pthread_create(
         &bufferThread,
-        NULL, // attr
+        nullptr, // attr
         IOHandlerBufferHelper::staticThreadProc,
         this
     );
@@ -210,21 +204,22 @@ void IOHandlerBufferHelper::startBufferThread()
 
 void IOHandlerBufferHelper::stopBufferThread()
 {
-    AUTOLOCK(mutex);
+    unique_lock<std::mutex> lock(mutex);
     threadShutdown = true;
-    cond->signal();
-    AUTOUNLOCK();
+    cond.notify_one();
+    lock.unlock();
+
     if (bufferThread)
-        pthread_join(bufferThread, NULL);
+        pthread_join(bufferThread, nullptr);
     bufferThread = 0;
 }
 
 void *IOHandlerBufferHelper::staticThreadProc(void *arg)
 {
     log_debug("starting buffer thread... thread: %d\n", pthread_self());
-    IOHandlerBufferHelper *inst = (IOHandlerBufferHelper *)arg;
+    auto *inst = (IOHandlerBufferHelper *)arg;
     inst->threadProc();
     log_debug("buffer thread shut down. thread: %d\n", pthread_self());
-    pthread_exit(NULL);
-    return NULL;
+    pthread_exit(nullptr);
+    return nullptr;
 }
diff --git a/src/io_handler_buffer_helper.h b/src/io_handler_buffer_helper.h
index b1be414..5f0cdc2 100644
--- a/src/io_handler_buffer_helper.h
+++ b/src/io_handler_buffer_helper.h
@@ -33,11 +33,12 @@
 #define __IO_HANDLER_BUFFER_HELPER_H__
 
 #include <pthread.h>
+#include <upnp-1.8/upnp.h>
+#include <mutex>
+#include <condition_variable>
 
 #include "common.h"
-#include "upnp.h"
 #include "io_handler.h"
-#include "sync.h"
 
 /// \brief a IOHandler with buffer support
 /// the buffer is only for read(). write() is not supported
@@ -92,8 +93,9 @@ protected:
     
     pthread_t bufferThread;
     bool threadShutdown;
-    zmm::Ref<Cond> cond;
-    zmm::Ref<Mutex> mutex;
+
+    std::condition_variable cond;
+    std::mutex mutex;
 };
 
 #endif // __IO_HANDLER_BUFFER_HELPER_H__
diff --git a/src/io_handler_chainer.cc b/src/io_handler_chainer.cc
index 19c95a5..c79651f 100644
--- a/src/io_handler_chainer.cc
+++ b/src/io_handler_chainer.cc
@@ -29,10 +29,6 @@
 
 /// \file io_handler_chainer.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "io_handler_chainer.h"
 #include "exceptions.h"
 
@@ -42,7 +38,7 @@ IOHandlerChainer::IOHandlerChainer(Ref<IOHandler> readFrom, Ref<IOHandler> write
 {
     if (chunkSize <=0)
         throw _Exception(_("chunkSize must be positive"));
-    if (readFrom == NULL || writeTo == NULL)
+    if (readFrom == nullptr || writeTo == nullptr)
         throw _Exception(_("readFrom and writeTo need to be set"));
     status = 0;
     this->chunkSize = chunkSize;
@@ -65,7 +61,7 @@ void IOHandlerChainer::threadProc()
                 writeTo->open(UPNP_WRITE);
                 again = false;
             }
-            catch (TryAgainException e)
+            catch (const TryAgainException & e)
             {
                 again = true;
                 sleep(1);
@@ -102,7 +98,7 @@ void IOHandlerChainer::threadProc()
             }
         }
     }
-    catch (Exception e)
+    catch (const Exception & e)
     {
         log_debug("%s", e.getMessage().c_str());
         status = IOHC_EXCEPTION;
@@ -114,7 +110,7 @@ void IOHandlerChainer::threadProc()
         readFrom->close();
         writeTo->close();
     }
-    catch (Exception e)
+    catch (const Exception & e)
     {
         log_debug("%s", e.getMessage().c_str());
         status = IOHC_EXCEPTION;
diff --git a/src/jpeg_resolution.cc b/src/jpeg_resolution.cc
index 4c0b98d..fa09d28 100644
--- a/src/jpeg_resolution.cc
+++ b/src/jpeg_resolution.cc
@@ -29,16 +29,12 @@
 
 /// \file jpeg_resolution.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "common.h"
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cerrno>
 
 #include "tools.h"
 typedef unsigned char uchar;
@@ -178,7 +174,7 @@ String get_jpeg_resolution(Ref<IOHandler> ioh)
     {
         get_jpeg_resolution(ioh, &w, &h);
     }
-    catch (Exception e)
+    catch (const Exception & e)
     {
         ioh->close();
         throw e;
diff --git a/src/lastfm_scrobbler.cc b/src/lastfm_scrobbler.cc
index 100ff62..f4f0490 100644
--- a/src/lastfm_scrobbler.cc
+++ b/src/lastfm_scrobbler.cc
@@ -29,10 +29,6 @@
 
 /// \file lastfm_scrobbler.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_LASTFMLIB
 
 #include "lastfm_scrobbler.h"
@@ -42,10 +38,8 @@
 using namespace zmm;
 
 
-SINGLETON_MUTEX(LastFm, false);
-
 LastFm::LastFm()
-: Singleton<LastFm>()
+: Singleton<LastFm, std::mutex>()
 , scrobbler(NULL)
 , currentTrackId(-1)
 {
@@ -107,12 +101,12 @@ void LastFm::startedPlaying(Ref<CdsItem> item)
     }
 
     submission_info* info = create_submission_info();
-    info->artist = artist.c_str();
-    info->track = title.c_str();
+    info->artist = const_cast<char *>(artist.c_str());
+    info->track = const_cast<char *>(title.c_str());
 
     String album = item->getMetadata(MetadataHandler::getMetaFieldName(M_ALBUM));
     if (string_ok(album))
-        info->album = album.c_str();
+        info->album = const_cast<char *>(album.c_str());
 
     String trackNr = 
         item->getMetadata(MetadataHandler::getMetaFieldName(M_TRACKNUMBER));
diff --git a/src/lastfm_scrobbler.h b/src/lastfm_scrobbler.h
index 5ff2efc..b4f85e3 100644
--- a/src/lastfm_scrobbler.h
+++ b/src/lastfm_scrobbler.h
@@ -42,7 +42,7 @@
 #include "cds_objects.h"
 #include <lastfmlib/lastfmscrobblerc.h>
 
-class LastFm : public Singleton<LastFm>
+class LastFm : public Singleton<LastFm, std::mutex>
 {
 public:
     LastFm();
diff --git a/src/layout/fallback_layout.cc b/src/layout/fallback_layout.cc
index fa60d94..10946f8 100644
--- a/src/layout/fallback_layout.cc
+++ b/src/layout/fallback_layout.cc
@@ -28,9 +28,6 @@
 */
 
 /// \file fallback_layout.cc
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
 
 #include "fallback_layout.h"
 #include "content_manager.h"
@@ -39,10 +36,6 @@
 #include "string_converter.h"
 #include "tools.h"
 
-#ifdef HAVE_LIBDVDNAV
-    #include "metadata/dvd_handler.h"
-#endif
-
 #ifdef ONLINE_SERVICES
 
 #include "online_service.h"
@@ -52,10 +45,6 @@
     #include "youtube_service.h"
 #endif
 
-#ifdef WEBORAMA
-    #include "weborama_content_handler.h"
-#endif
-
 #ifdef SOPCAST
     #include "sopcast_content_handler.h"
 #endif
@@ -122,171 +111,6 @@ void FallbackLayout::addVideo(zmm::Ref<CdsObject> obj, String rootpath)
     }
 }
 
-#ifdef HAVE_LIBDVDNAV
-
-Ref<CdsObject> FallbackLayout::prepareChapter(Ref<CdsObject> obj, int title_idx,
-                                              int chapter_idx)
-{
-    String chapter_name = _("Chapter ");
-            
-    obj->getResource(0)->addParameter(DVDHandler::renderKey(DVD_Chapter), 
-            String::from(chapter_idx));
-
-    if (chapter_idx < 9)
-        chapter_name = chapter_name + _("0") + (chapter_idx + 1); // remap
-    else
-        chapter_name = chapter_name + (chapter_idx + 1);
-
-    obj->setTitle(chapter_name);
-//    String tmp = obj->getAuxData(DVDHandler::renderKey(DVD_ChapterRestDuration,
-//                                 title_idx, chapter_idx));
-//    if (string_ok(tmp))
-//        obj->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_DURATION), tmp);
-
-    return obj;
-}
-
-void FallbackLayout::addDVD(Ref<CdsObject> obj)
-{
-    #define DVD_VPATH "/Video/DVD/"
-
-    int dot = obj->getTitle().rindex('.');
-    int pcd_id = obj->getID();
-    String dvd_name;
-
-    if (dot > -1)
-        dvd_name = obj->getTitle().substring(0, dot);
-    else
-        dvd_name = obj->getTitle();
-
-    String dvd_container = _(DVD_VPATH) + esc(dvd_name);
-    Ref<ContentManager> cm = ContentManager::getInstance();
-
-    int id = cm->addContainerChain(dvd_container, nil, pcd_id);
-
-    // we get the main object here, so the object that we will add below
-    // will be a reference of the main object, that's why we set the ref
-    // id to the object id - the add function will clear out the object
-    // id
-    if (obj->getID() != INVALID_OBJECT_ID)
-    {
-        obj->setRefID(obj->getID());
-        add(obj, id);
-    }
-    // the object is not yet in the database (probably we got it from a
-    // playlist script, so we set the ref id after adding - it will be used
-    // for all consequent virtual objects
-    else
-    {
-        add(obj, id);
-        obj->setRefID(obj->getID());
-    }
-
-    dvd_container = dvd_container + _("/");
-
-    int title_count = obj->getAuxData(DVDHandler::renderKey(DVD_TitleCount)).toInt();
-    // set common item attributes 
-    RefCast(obj, CdsItem)->setMimeType(mpeg_mimetype);
-    obj->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_PROTOCOLINFO), renderProtocolInfo(RefCast(obj, CdsItem)->getMimeType()));
-    obj->setClass(_(UPNP_DEFAULT_CLASS_VIDEO_ITEM));
-    /// \todo this has to be changed once we add seeking
-    obj->getResource(0)->removeAttribute(MetadataHandler::getResAttrName(R_SIZE));
-
-    for (int t = 0; t < title_count; t++)
-    {
-        int audio_track_count = obj->getAuxData(DVDHandler::renderKey(DVD_AudioTrackCount, t)).toInt();
-        obj->getResource(0)->addParameter(DVDHandler::renderKey(DVD_Title), 
-                                          String::from(t));
-        for (int a = 0; a < audio_track_count; a++)
-        {
-            // set common audio track resource attributes
-            obj->getResource(0)->addParameter(DVDHandler::renderKey(DVD_AudioStreamID), obj->getAuxData(DVDHandler::renderKey(DVD_AudioTrackStreamID, t, 0, a)));
-
-            String tmp = obj->getAuxData(DVDHandler::renderKey(DVD_AudioTrackChannels, t, 0, a));
-            if (string_ok(tmp))
-            {
-                obj->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_NRAUDIOCHANNELS), tmp);
-                log_debug("Setting Audio Channels, object %s -  num: %s\n",
-                          obj->getLocation().c_str(), tmp.c_str());
-            }
-
-            tmp = obj->getAuxData(DVDHandler::renderKey(DVD_AudioTrackSampleFreq, t, 0, a));
-            if (string_ok(tmp))
-                obj->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_SAMPLEFREQUENCY), tmp);
-
-            String title_container = _("Titles/");
-            String title_name;
-
-            if (t < 9) // 9 because of later remapping
-                title_name = _("Title 0") + (t + 1); // remap
-            else
-                title_name = _("Title ") + (t + 1); // remap
-            
-            String format = obj->getAuxData(DVDHandler::renderKey(DVD_AudioTrackFormat, t, 0, a));
-            String language = obj->getAuxData(DVDHandler::renderKey(DVD_AudioTrackLanguage, t, 0, a));
-
-            title_container = title_container + title_name;
-
-            title_container = title_container + _(" - Audio Track ") + (a + 1);
-            if (string_ok(format))
-                title_container = title_container + _(" - ") + esc(format);
-
-            if (string_ok(language))
-                title_container = title_container + _(" - ") + esc(language);
-
-            title_container = dvd_container + title_container;
-            id = cm->addContainerChain(title_container, nil, pcd_id);
-            int chapter_count = obj->getAuxData(DVDHandler::renderKey(DVD_ChapterCount, t)).toInt();
-
-            for (int c = 0; c < chapter_count; c++)
-            {
-                prepareChapter(obj, t, c);
-                add(obj, id, false);
-            }
-
-            if (string_ok(language))
-            {
-                String language_container = _("Languages/");
-                String chain = dvd_container + language_container +
-                               esc(language) + _("/") + title_name;
-
-                chain = chain + _(" - Audio Track ") + (a + 1); 
-
-                if (string_ok(format))
-                        chain = chain + _(" - ") + esc(format);
-
-                id = cm->addContainerChain(chain, nil, pcd_id);
-                
-                for (int c = 0; c < chapter_count; c++)
-                {
-                    prepareChapter(obj, t, c);
-                    add(obj, id, false);
-                }
-            }
-
-            if (string_ok(format))
-            {
-                String format_container = _("Audio Formats/");
-                String chain = dvd_container + format_container + esc(format) + 
-                               _("/") + title_name;
-
-                chain = chain + _(" - Audio Track ") + (a + 1); 
-                
-                if (string_ok(language))
-                    chain = chain + _(" - ") + esc(language);
-
-                id = cm->addContainerChain(chain, nil, pcd_id);
-                for (int c = 0; c < chapter_count; c++)
-                {
-                    prepareChapter(obj, t, c);
-                    add(obj, id, false);
-                }
-            } // format
-        } // audio track count
-    } // title count
-}
-#endif
-
 void FallbackLayout::addImage(Ref<CdsObject> obj, String rootpath)
 {
     int id;
@@ -463,11 +287,11 @@ void FallbackLayout::addAudio(zmm::Ref<CdsObject> obj)
 
     album = esc(album);
     chain = _("/Audio/Artists/") +  artist + _("/") + album;
-    id = ContentManager::getInstance()->addContainerChain(chain, _(UPNP_DEFAULT_CLASS_MUSIC_ALBUM));
+    id = ContentManager::getInstance()->addContainerChain(chain, _(UPNP_DEFAULT_CLASS_MUSIC_ALBUM), obj->getID());
     add(obj, id);
 
     chain = _("/Audio/Albums/") + album;
-    id = ContentManager::getInstance()->addContainerChain(chain, _(UPNP_DEFAULT_CLASS_MUSIC_ALBUM));
+    id = ContentManager::getInstance()->addContainerChain(chain, _(UPNP_DEFAULT_CLASS_MUSIC_ALBUM), obj->getID());
     add(obj, id);
 
     chain = _("/Audio/Genres/") + esc(genre);
@@ -507,7 +331,7 @@ void FallbackLayout::addYouTube(zmm::Ref<CdsObject> obj)
     temp = obj->getAuxData(_(YOUTUBE_AUXDATA_AVG_RATING));
     if (string_ok(temp))
     {
-        int rating = (int)temp.toDouble();
+        auto rating = (int)temp.toDouble();
         if (rating > 3)
         {
             chain = _(YT_VPATH "/Rating/") + esc(String::from(rating));
@@ -524,7 +348,7 @@ void FallbackLayout::addYouTube(zmm::Ref<CdsObject> obj)
     temp = obj->getAuxData(_(YOUTUBE_AUXDATA_REQUEST));
     if (string_ok(temp))
     {
-        yt_requests_t req = (yt_requests_t)temp.toInt();
+        auto req = (yt_requests_t)temp.toInt();
         temp = YouTubeService::getRequestName(req);
 
         String subName = obj->getAuxData(_(YOUTUBE_AUXDATA_SUBREQUEST_NAME));
@@ -540,11 +364,11 @@ void FallbackLayout::addYouTube(zmm::Ref<CdsObject> obj)
             chain = chain + '/' + esc(feedName);
 
         if (string_ok(region))
-        {   yt_regions_t reg = (yt_regions_t)region.toInt();
+        {   auto reg = (yt_regions_t)region.toInt();
             if (reg != YT_region_none)
             {
                 region = YouTubeService::getRegionName(reg);
-                if (string_ok(region));
+                if (string_ok(region))
                     chain = chain + '/' + esc(region);
             }
         }
@@ -589,36 +413,6 @@ void FallbackLayout::addSopCast(zmm::Ref<CdsObject> obj)
 }
 #endif
 
-#ifdef WEBORAMA
-void FallbackLayout::addWeborama(zmm::Ref<CdsObject> obj)
-{
-    #define WB_VPATH "/Online Services/Weborama"
-    String chain;
-    String temp;
-    int id;
-    bool ref_set = false;
-
-    if (obj->getID() != INVALID_OBJECT_ID)
-    {
-        obj->setRefID(obj->getID());
-        ref_set = true;
-    }
-
-    temp = obj->getAuxData(_(WEBORAMA_AUXDATA_REQUEST_NAME));
-    if (!string_ok(temp))
-    {
-        log_warning("Skipping Weborama item %s: missing playlist name\n", 
-                    obj->getTitle().c_str());
-        return;
-    }
-
-    chain = _(WB_VPATH "/") + esc(temp);
-    id = ContentManager::getInstance()->addContainerChain(chain, 
-                                      _(UPNP_DEFAULT_CLASS_PLAYLIST_CONTAINER));
-    add(obj, id, ref_set);
-}
-#endif
-
 #ifdef ATRAILERS
 void FallbackLayout::addATrailers(zmm::Ref<CdsObject> obj)
 {
@@ -666,9 +460,9 @@ void FallbackLayout::addATrailers(zmm::Ref<CdsObject> obj)
             if (string_ok(next))
                 genre = next;
             else
-                genre = nil;
+                genre = nullptr;
                     
-        } while (genre != nil);
+        } while (genre != nullptr);
     }
 
     temp = meta->get(MetadataHandler::getMetaFieldName(M_DATE));
@@ -695,12 +489,6 @@ FallbackLayout::FallbackLayout() : Layout()
     PROF_INIT_GLOBAL(layout_profiling, "fallback layout");
 #endif
 
-#ifdef HAVE_LIBDVDNAV
-    Ref<Dictionary> mappings = ConfigManager::getInstance()->getDictionaryOption(CFG_IMPORT_MAPPINGS_MIMETYPE_TO_CONTENTTYPE_LIST);
-    mpeg_mimetype = mappings->get(_(CONTENT_TYPE_MPEG));
-    if (!string_ok(mpeg_mimetype))
-        mpeg_mimetype = _("video/mpeg");
-#endif
 }
 
 void FallbackLayout::processCdsObject(zmm::Ref<CdsObject> obj, String rootpath)
@@ -711,7 +499,7 @@ void FallbackLayout::processCdsObject(zmm::Ref<CdsObject> obj, String rootpath)
 #endif
     Ref<CdsObject> clone = CdsObject::createObject(obj->getObjectType());
     obj->copyTo(clone);
-    clone->setVirtual(1);
+    clone->setVirtual(true);
 
 #ifdef ONLINE_SERVICES
     if (clone->getFlag(OBJECT_FLAG_ONLINE_SERVICE))
@@ -730,11 +518,6 @@ void FallbackLayout::processCdsObject(zmm::Ref<CdsObject> obj, String rootpath)
                 addSopCast(clone);
                 break;
 #endif
-#ifdef WEBORAMA
-            case OS_Weborama:
-                addWeborama(clone);
-                break;
-#endif
 #ifdef ATRAILERS
             case OS_ATrailers:
                 addATrailers(clone);
@@ -770,10 +553,6 @@ void FallbackLayout::processCdsObject(zmm::Ref<CdsObject> obj, String rootpath)
             else
                 addAudio(clone);
         }
-#ifdef HAVE_LIBDVDNAV
-        else if (content_type == CONTENT_TYPE_DVD)
-            addDVD(clone);
-#endif
 
 #ifdef ONLINE_SERVICES
     }
diff --git a/src/layout/fallback_layout.h b/src/layout/fallback_layout.h
index feab8c7..fe8bd8d 100644
--- a/src/layout/fallback_layout.h
+++ b/src/layout/fallback_layout.h
@@ -33,7 +33,7 @@
 #define __FALLBACK_LAYOUT_H__
 
 #include "layout.h"
-#include "cds_objects.h"
+#include "../cds_objects.h"
 
 #ifdef ENABLE_PROFILING
     #include "tools.h"
@@ -42,7 +42,7 @@ class FallbackLayout : public Layout
 {
 public:
     FallbackLayout();
-    virtual void processCdsObject(zmm::Ref<CdsObject> obj, zmm::String rootpath);
+    virtual void processCdsObject(zmm::Ref<CdsObject> obj, zmm::String rootpath) override;
 #ifdef ENABLE_PROFILING
     virtual ~FallbackLayout();
 #endif
@@ -52,21 +52,12 @@ protected:
     void addVideo(zmm::Ref<CdsObject> obj, zmm::String rootpath);
     void addImage(zmm::Ref<CdsObject> obj, zmm::String rootpath);
     void addAudio(zmm::Ref<CdsObject> obj);
-#ifdef HAVE_LIBDVDNAV
-    zmm::Ref<CdsObject> prepareChapter(zmm::Ref<CdsObject> obj, int title_idx,
-                                       int chapter_idx);
-    void addDVD(zmm::Ref<CdsObject> obj);
-    zmm::String mpeg_mimetype;
-#endif
 #ifdef YOUTUBE
     void addYouTube(zmm::Ref<CdsObject> obj);
 #endif
 #ifdef SOPCAST
     void addSopCast(zmm::Ref<CdsObject> obj);
 #endif
-#ifdef WEBORAMA
-    void addWeborama(zmm::Ref<CdsObject> obj);
-#endif
 #ifdef ATRAILERS
     void addATrailers(zmm::Ref<CdsObject> obj);
 #endif
diff --git a/src/layout/js_layout.cc b/src/layout/js_layout.cc
index 7d844e2..9cd20d2 100644
--- a/src/layout/js_layout.cc
+++ b/src/layout/js_layout.cc
@@ -29,10 +29,6 @@
 
 /// \file js_layout.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_JS
 
 #include "js_layout.h"
@@ -51,7 +47,7 @@ JSLayout::~JSLayout()
 
 void JSLayout::processCdsObject(Ref<CdsObject> obj, String rootpath)
 {
-    if (import_script == nil)
+    if (import_script == nullptr)
         return;
 
     import_script->processCdsObject(obj, rootpath);
diff --git a/src/layout/js_layout.h b/src/layout/js_layout.h
index 7fcf343..5a4a295 100644
--- a/src/layout/js_layout.h
+++ b/src/layout/js_layout.h
@@ -43,7 +43,7 @@ protected:
 public:
     JSLayout();
     virtual ~JSLayout();
-    virtual void processCdsObject(zmm::Ref<CdsObject> obj, zmm::String rootpath);
+    virtual void processCdsObject(zmm::Ref<CdsObject> obj, zmm::String rootpath) override;
 };
 
 #endif // __JS_LAYOUT_H__
diff --git a/src/logger.cc b/src/logger.cc
index 87c9ff8..4dd64dc 100644
--- a/src/logger.cc
+++ b/src/logger.cc
@@ -29,16 +29,12 @@
 
 /// \file logger.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <time.h>
+#include <cstdio>
+#include <cerrno>
+#include <cstring>
+#include <cstdlib>
+#include <cstdarg>
+#include <ctime>
 
 #ifdef HAVE_EXECINFO_H
     #include <execinfo.h>
@@ -68,7 +64,7 @@ void log_close()
     if (LOG_FILE)
     {
         fclose(LOG_FILE);
-        LOG_FILE = NULL;
+        LOG_FILE = nullptr;
     }
 }
 
@@ -132,11 +128,7 @@ void _log_js(const char *format, ...)
 void _log_debug(const char *format, const char *file, int line, const char *function, ...)
 {
     bool enabled;
-#ifdef TOMBDEBUG
-    enabled = !ConfigManager::isDebugLogging();
-#else
     enabled = ConfigManager::isDebugLogging();
-#endif
     if (enabled)
     {
         va_list ap;
@@ -155,11 +147,7 @@ void _print_backtrace(FILE* file)
 #if defined HAVE_BACKTRACE && defined HAVE_BACKTRACE_SYMBOLS
 
     bool enabled;
-#ifdef TOMBDEBUG
-    enabled = !ConfigManager::isDebugLogging();
-#else
     enabled = ConfigManager::isDebugLogging();
-#endif
     if (enabled)
     {
         void* b[100];
diff --git a/src/logger.h b/src/logger.h
index 2e9a484..689a62d 100644
--- a/src/logger.h
+++ b/src/logger.h
@@ -49,18 +49,13 @@ void log_close();
 #define log_error(format, ...) _log_error(format, ## __VA_ARGS__)
 #define log_js(format, ...) _log_js(format, ## __VA_ARGS__)
 
-#ifdef DEBUG_LOG_ENABLED
-    #define log_debug(format, ...) _log_debug(format, __FILE__, __LINE__, __func__, ## __VA_ARGS__)
-    #define print_backtrace() _print_backtrace()
-#else
 #ifdef TOMBDEBUG
-    #define log_debug(format, ...) _log_debug(format, __FILE__, __LINE__, __func__, ## __VA_ARGS__)
+    #define log_debug(format, ...) _log_debug(format, __FILENAME__, __LINE__, __func__, ## __VA_ARGS__)
     #define print_backtrace() _print_backtrace()
 #else
     #define log_debug(format, ...)
     #define print_backtrace()
 #endif
-#endif
 
 #else
 
diff --git a/src/main.cc b/src/main.cc
index 37123c6..ea86e86 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -31,107 +31,84 @@
 
 /// \mainpage Sourcecode Documentation.
 ///
-/// This documentation was generated using doxygen, you can reproduce it by 
+/// This documentation was generated using doxygen, you can reproduce it by
 /// running "doxygen doxygen.conf" from the mediatomb/doc/ directory.
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
+#include <getopt.h>
+
+#include <csignal>
+#include <mutex>
+#ifdef SOLARIS
+#include <iso/limits_iso.h>
 #endif
 
 #include "common.h"
-#include "singleton.h"
 #include "server.h"
-#include "process.h"
-
-#ifdef HAVE_GETOPT_H
-    #include <getopt.h>
-#endif
-
-#include "config_manager.h"
 #include "content_manager.h"
-#include "timer.h"
-#include "common.h"
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <syslog.h>
-#include <string.h>
-#include <pthread.h>
-#include <signal.h>
-#include <pwd.h>
-#include <grp.h>
-#include <limits.h>
-
-#ifdef HAVE_GETOPT_LONG
-    #define OPTSTR "i:e:p:c:m:f:u:g:a:l:P:dhD"
-#endif
+#define OPTSTR "i:e:p:c:m:f:a:l:P:dhD"
 
 using namespace zmm;
 
 int shutdown_flag = 0;
 int restart_flag = 0;
 pthread_t main_thread_id;
-Ref<Timer> timer = nil;
+
+std::mutex mutex;
+std::unique_lock<std::mutex> lock{mutex};
+std::condition_variable cond;
 
 void print_copyright()
 {
-    printf("\nMediaTomb UPnP Server version %s - %s\n\n", VERSION, 
-            DESC_MANUFACTURER_URL);
+    printf("\nGerbera UPnP Server version %s - %s\n\n", VERSION, DESC_MANUFACTURER_URL);
     printf("===============================================================================\n");
-    printf("Copyright 2005-2010 Gena Batsyan, Sergey Bostandzhyan, Leonhard Wimmer.\n");
-    printf("MediaTomb is free software, covered by the GNU General Public License version 2\n\n");
+    printf("Gerbera is free software, covered by the GNU General Public License version 2\n\n");
+    printf("Copyright 2016-2017 Gerbera Contributors.\n");
+    printf("Gerbera is based on MediaTomb: Copyright 2005-2010 Gena Batsyan, Sergey Bostandzhyan, Leonhard Wimmer.\n");
+}
+
+void log_copyright()
+{
+    log_info("Gerbera UPnP Server version %s - %s\n", VERSION, DESC_MANUFACTURER_URL);
+    log_info("===============================================================================\n");
+    log_info("Gerbera is free software, covered by the GNU General Public License version 2\n");
+    log_info("Copyright 2016-2017 Gerbera Contributors.\n");
+    log_info("Gerbera is based on MediaTomb: Copyright 2005-2010 Gena Batsyan, Sergey Bostandzhyan, Leonhard Wimmer.\n");
 }
+
 void signal_handler(int signum);
 
-int main(int argc, char **argv, char **envp)
+int main(int argc, char** argv, char** envp)
 {
-    char     * err = NULL;
-    int      port = -1;
-    bool     daemon = false;
-    struct   sigaction action;
+    char* err = nullptr;
+    int port = -1;
+    struct sigaction action;
     sigset_t mask_set;
 
-    int      devnull = -1;
-    int      redirect1 = -1;
-    int      redirect2 = -1;
-    struct   passwd *pwd;
-    struct   group  *grp;
-#ifdef HAVE_GETOPT_LONG
-    int      opt_index = 0;
-    int      o;
+    int opt_index = 0;
+    int o;
     static struct option long_options[] = {
-        {"ip", 1, 0, 'i'},          // 0
-        {"interface", 1, 0, 'e'},   // 1
-        {"port", 1, 0, 'p'},        // 2
-        {"config", 1, 0, 'c'},      // 3
-        {"home", 1, 0, 'm'},        // 4
-        {"cfgdir", 1, 0, 'f'},      // 5
-        {"user", 1, 0, 'u'},        // 6
-        {"group", 1, 0, 'g'},       // 7
-        {"daemon", 0, 0, 'd'},      // 8
-        {"pidfile", 1, 0, 'P'},     // 9
-        {"add", 1, 0, 'a'},         // 10
-        {"logfile", 1, 0, 'l'},     // 11
-        {"debug", 0, 0, 'D'},       // 12
-        {"compile-info", 0, 0, 0},  // 13
-        {"version", 0, 0, 0},       // 14
-        {"help", 0, 0, 'h'},        // 15
-        {0, 0, 0, 0}                
+        { (char*)"ip", 1, nullptr, 'i' }, // 0
+        { (char*)"interface", 1, nullptr, 'e' }, // 1
+        { (char*)"port", 1, nullptr, 'p' }, // 2
+        { (char*)"config", 1, nullptr, 'c' }, // 3
+        { (char*)"home", 1, nullptr, 'm' }, // 4
+        { (char*)"cfgdir", 1, nullptr, 'f' }, // 5
+        { (char*)"pidfile", 1, nullptr, 'P' }, // 8
+        { (char*)"add", 1, nullptr, 'a' }, // 9
+        { (char*)"logfile", 1, nullptr, 'l' }, // 10
+        { (char*)"debug", 0, nullptr, 'D' }, // 11
+        { (char*)"compile-info", 0, nullptr, 0 }, // 12
+        { (char*)"version", 0, nullptr, 0 }, // 13
+        { (char*)"help", 0, nullptr, 'h' }, // 14
+        { (char*)nullptr, 0, nullptr, 0 }
     };
-#endif
 
     String config_file;
     String home;
     String confdir;
-    String user;
-    String group;
     String pid_file;
-    FILE* pid_fd = NULL;
+    FILE* pid_fd = nullptr;
     String interface;
     String ip;
     String prefix;
@@ -143,12 +120,11 @@ int main(int argc, char **argv, char **envp)
 
 #ifdef SOLARIS
     String ld_preload;
-    char *preload = getenv("LD_PRELOAD");
+    char* preload = getenv("LD_PRELOAD");
     if (preload != NULL)
         ld_preload = String(preload);
 
-    if ((preload == NULL) || (ld_preload.find("0 at 0") == -1))
-    {
+    if ((preload == NULL) || (ld_preload.find("0 at 0") == -1)) {
         printf("MediaTomb: Solaris check failed!\n");
         printf("Please set the environment to match glibc behaviour!\n");
         printf("LD_PRELOAD=/usr/lib/0 at 0.so.1\n");
@@ -156,112 +132,90 @@ int main(int argc, char **argv, char **envp)
     }
 #endif
 
-#ifdef HAVE_GETOPT_LONG   
-    while (1)
-    {
+    while (true) {
         o = getopt_long(argc, argv, OPTSTR, long_options, &opt_index);
-        if (o == -1) break;
-
-        switch (o)
-        {
-            case 'i':
-                log_debug("Option ip with param %s\n", optarg);
-                ip = optarg;
-                break;
-
-            case 'e':
-                log_debug("Option interface with param %s\n", optarg);
-                interface = optarg;
-                break;
-
-            case 'p':
-                log_debug("Option port with param %s\n", optarg);
-                errno = 0;
-                port = strtol(optarg, &err, 10);
-                if ((port == 0) && (*err))
-                {
-                    log_error("Invalid port argument: %s\n", optarg);
-                    exit(EXIT_FAILURE);
-                }
-
-                if (port > USHRT_MAX)
-                {
-                    log_error("Invalid port value %d. Maximum allowed port value is %d\n", port, USHRT_MAX);
-                }
-                log_debug("port set to: %d\n", port);
-                break;
-
-            case 'c':
-                log_debug("Option config with param %s\n", optarg);
-                config_file = optarg;
-                break;
-
-            case 'd':
-                log_debug("Starting in deamon mode...");
-                daemon = true;
-                break;
-
-            case 'u':
-                log_debug("Running as user: %s\n", optarg);
-                user = optarg;
-                break;
-
-            case 'g':
-                log_debug("Running as group: %s\n", optarg);
-                group = optarg;
-                break;
-                
-            case 'a':
-                log_debug("Adding file/directory:: %s\n", optarg);
-                addFile->append(String::copy(optarg));
-                break;
-
-            case 'P':
-                log_debug("Pid file: %s\n", optarg);
-                pid_file = optarg;
-                break;
-                
-            case 'l':
-                log_debug("Log file: %s\n", optarg);
-                log_open(optarg);
-                break;
-
-            case 'm':
-                log_debug("Home setting: %s\n", optarg);
-                home = optarg;
-                break;
-              
-            case 'f':
-                log_debug("Confdir setting: %s\n", optarg);
-                confdir = optarg;
-                break;
-                
-            case 'D':
-                
-#ifndef DEBUG_LOG_ENABLED
-                print_copyright();
-                printf("ERROR: MediaTomb wasn't compiled with debug output, but was run with -D/--debug.\n");
+        if (o == -1)
+            break;
+
+        switch (o) {
+        case 'i':
+            log_debug("Option ip with param %s\n", optarg);
+            ip = optarg;
+            break;
+
+        case 'e':
+            log_debug("Option interface with param %s\n", optarg);
+            interface = optarg;
+            break;
+
+        case 'p':
+            log_debug("Option port with param %s\n", optarg);
+            errno = 0;
+            port = strtol(optarg, &err, 10);
+            if ((port == 0) && (*err)) {
+                log_error("Invalid port argument: %s\n", optarg);
                 exit(EXIT_FAILURE);
+            }
+
+            if (port > USHRT_MAX) {
+                log_error("Invalid port value %d. Maximum allowed port value is %d\n", port, USHRT_MAX);
+            }
+            log_debug("port set to: %d\n", port);
+            break;
+
+        case 'c':
+            log_debug("Option config with param %s\n", optarg);
+            config_file = optarg;
+            break;
+
+        case 'a':
+            log_debug("Adding file/directory:: %s\n", optarg);
+            addFile->append(String::copy(optarg));
+            break;
+
+        case 'P':
+            log_debug("Pid file: %s\n", optarg);
+            pid_file = optarg;
+            break;
+
+        case 'l':
+            log_debug("Log file: %s\n", optarg);
+            log_open(optarg);
+            break;
+
+        case 'm':
+            log_debug("Home setting: %s\n", optarg);
+            home = optarg;
+            break;
+
+        case 'f':
+            log_debug("Confdir setting: %s\n", optarg);
+            confdir = optarg;
+            break;
+
+        case 'D':
+
+#ifndef TOMBDEBUG
+            print_copyright();
+            printf("ERROR: MediaTomb wasn't compiled with debug output, but was run with -D/--debug.\n");
+            exit(EXIT_FAILURE);
 #endif
-                log_debug("enabling debug output\n");
-                debug_logging = true;
-                break;
-            case '?':
-            case 'h':
-                print_copyright();
-                printf("Usage: mediatomb [options]\n\
+            log_debug("enabling debug output\n");
+            debug_logging = true;
+            break;
+        case '?':
+        case 'h':
+            print_copyright();
+            printf("Usage: gerbera [options]\n\
                         \n\
 Supported options:\n\
     --ip or -i         ip address to bind to\n\
     --interface or -e  network interface to bind to\n\
     --port or -p       server port (the SDK only permits values >= 49152)\n\
     --config or -c     configuration file to use\n\
-    --daemon or -d     run server in background\n\
     --home or -m       define the home directory\n\
     --cfgdir or -f     name of the directory that is holding the configuration\n\
     --pidfile or -P    file to hold the process id\n\
-    --user or -u       run server under specified username\n\
-    --group or -g      run server under specified group\n\
     --add or -a        add the given file/directory\n\
     --logfile or -l    log to specified file\n\
     --debug or -D      enable debug output\n\
@@ -271,496 +225,272 @@ Supported options:\n\
 \n\
 For more information visit " DESC_MANUFACTURER_URL "\n\n");
 
-                exit(EXIT_FAILURE);
-                break;
-            case 0:
-                switch (opt_index)
-                {
-                case 13: // --compile-info
-                    print_copyright();
-                    printf("Compile info:\n");
-                    printf("-------------\n");
-                    printf("%s\n\n", COMPILE_INFO);
-                    exit(EXIT_SUCCESS);
-                    break;
-                case 14: // --version
-                    print_version = true;
-                    break;
-                }
-                break;
-            default:
+            exit(EXIT_FAILURE);
+            break;
+        case 0:
+            switch (opt_index) {
+            case 13: // --compile-info
+                print_copyright();
+                printf("Compile info:\n");
+                printf("-------------\n");
+                printf("%s\n\n", COMPILE_INFO);
+                exit(EXIT_SUCCESS);
+            case 14: // --version
+                print_version = true;
                 break;
-         }
+            }
+            break;
+        default:
+            break;
+        }
     }
-#else
-    log_warning("No getopt_long() support, all command line options disabled");
-#endif
 
-    if (print_version || ! daemon)
-    {
+    if (print_version) {
         print_copyright();
-       
-        if (print_version)
-            exit(EXIT_FAILURE);
+        exit(EXIT_FAILURE);
     }
 
-   // create pid file before dropping privileges
-    if (pid_file != nil)
-    {
+    log_copyright();
+
+    // create pid file
+    if (pid_file != nullptr) {
         pid_fd = fopen(pid_file.c_str(), "w");
-        if (pid_fd == NULL)
-        {
-            log_error("Could not write pid file %s : %s\n",
-                       pid_file.c_str(), strerror(errno));
-        }
-    }
 
-    // check if user and/or group parameter was specified and try to run the server
-    // under the given user and/or group name
-    if (group != nil)
-    {
-        grp = getgrnam(group.c_str());
-        if (grp == NULL)
-        {
-            log_error("Group %s not found!\n", group.c_str());
-            exit(EXIT_FAILURE);
-        }
-        
-        if (setgid(grp->gr_gid) < 0)
-        {
-            log_error("setgid failed %s\n", strerror(errno));
-            exit(EXIT_FAILURE);
-        }
-        
-        // remove supplementary groups
-        if (setgroups(0, NULL) < 0)
-        {
-            log_error("setgroups failed %s\n", strerror(errno));
-            exit(EXIT_FAILURE);
-        }
-    }
-    
-    if (user != nil)
-    {
-        pwd = getpwnam(user.c_str());
-        if (pwd == NULL)
-        {
-            log_error("User %s not found!\n", user.c_str());
-            exit(EXIT_FAILURE);
-        }
-        
-        // set supplementary groups
-        if (initgroups(user.c_str(), getegid()) < 0)
-        {
-            log_error("initgroups failed %s\n", strerror(errno));
-            exit(EXIT_FAILURE);
-        }
-        
-        if (setuid(pwd->pw_uid) < 0)
-        {
-            log_error("setuid failed %s\n", strerror(errno));
-            exit(EXIT_FAILURE);
+        if (pid_fd == nullptr) {
+            log_error("Could not write pid file %s : %s\n", pid_file.c_str(),
+                      strerror(errno));
+        } else {
+            pid_t cur_pid = getpid();
+            String pid = String::from(cur_pid);
+
+            size_t size =
+                fwrite(pid.c_str(), sizeof(char), pid.length(), pid_fd);
+            fclose(pid_fd);
+
+            if (static_cast<int>(size) < pid.length()) {
+                log_error("Error when writing pid file %s : %s\n",
+                          pid_file.c_str(), strerror(errno));
+            }
         }
-        
     }
 
-    try
-    {
-        // if home is not given by the user, get it from the environment
-        if (!string_ok(home) && (!string_ok(config_file)))
-        {
-#ifndef __CYGWIN__
-            char *h = getenv("HOME");
-            if (h != NULL)
-                home = h;
+    // If home is not given by the user, get it from the environment
+    if (!string_ok(config_file) && !string_ok(home)) {
 
-#else
-            char *h = getenv("HOMEPATH");
-            char *d = getenv("HOMEDRIVE");
-            if ((h != NULL)  && (d != NULL))
-                home = d + h;
+        if (!string_ok(confdir)) {
+            confdir = _(DEFAULT_CONFIG_HOME);
+        }
 
-#endif  // __CYGWIN__
+        // Check XDG first
+        char *h = getenv("XDG_CONFIG_HOME");
+        if (h != nullptr) {
+            home = h;
+            confdir = "gerbera";
+        } else {
+            // Then look for home
+            h = getenv("HOME");
+            if (h != nullptr)
+                home = h;
         }
 
-        if (!string_ok(home) && (!string_ok(config_file)))
-        {
+        if (!string_ok(home)) {
             log_error("Could not determine users home directory\n");
             exit(EXIT_FAILURE);
         }
+    }
 
-        if (!string_ok(confdir))
-            confdir = _(DEFAULT_CONFIG_HOME);
-
-        char *pref = getenv("MEDIATOMB_DATADIR");
-        if (pref != NULL)
-            prefix = pref;
+    char* pref = getenv("MEDIATOMB_DATADIR");
+    if (pref != nullptr)
+        prefix = pref;
 
-        if (!string_ok(prefix))
-            prefix = _(PACKAGE_DATADIR);
+    if (!string_ok(prefix))
+        prefix = _(PACKAGE_DATADIR);
 
-        char *mgc = getenv("MEDIATOMB_MAGIC_FILE");
-        if (mgc != NULL)
-            magic = mgc;
+    char* mgc = getenv("MEDIATOMB_MAGIC_FILE");
+    if (mgc != nullptr)
+        magic = mgc;
 
-        if (!string_ok(magic))
-            magic = nil;
+    if (!string_ok(magic))
+        magic = nullptr;
 
-        ConfigManager::setStaticArgs(config_file, home, confdir, prefix, magic, debug_logging);
+    ConfigManager::setStaticArgs(config_file, home, confdir, prefix, magic, debug_logging, ip, interface, port);
+    try {
         ConfigManager::getInstance();
-    }
-    catch (mxml::ParseException pe)
-    {
+    } catch (const mxml::ParseException& pe) {
         log_error("Error parsing config file: %s line %d:\n%s\n",
-               pe.context->location.c_str(),
-               pe.context->line,
-               pe.getMessage().c_str());
+            pe.context->location.c_str(),
+            pe.context->line,
+            pe.getMessage().c_str());
         exit(EXIT_FAILURE);
-    }
-    catch (Exception e)
-    {
+    } catch (const Exception& e) {
         log_error("%s\n", e.getMessage().c_str());
         exit(EXIT_FAILURE);
-    }    
-    
-    // starting as daemon if applicable
-    if (daemon)
-    {
-        // The daemon startup code was taken from the Linux Daemon Writing HOWTO
-        // written by Devin Watson <dmwatson at comcast.net>
-        // The HOWTO is Copyright by Devin Watson, under the terms of the BSD License.
-        
-        /* Our process ID and Session ID */
-        pid_t pid, sid; 
-        
-
-        /* Fork off the parent process */
-        pid = fork();
-        if (pid < 0) 
-        {
-            log_error("Failed to fork: %s\n", strerror(errno));
-            exit(EXIT_FAILURE);
-        }
-        /* If we got a good PID, then
-           we can exit the parent process. */
-        if (pid > 0) 
-        {
-            exit(EXIT_SUCCESS);
-        }
-
-        /* Change the file mode mask */
-        umask(0133);
-
-        /* Open any logs here */        
-
-        /* Create a new SID for the child process */
-        sid = setsid();
-        if (sid < 0) 
-        {
-            log_error("setsid failed: %s\n", strerror(errno));
-            exit(EXIT_FAILURE);
-        }
-
-        /* Change the current working directory */
-        if ((chdir("/")) < 0) 
-        {
-            log_error("Failed to chdir to / : %s\n", strerror(errno));
-            exit(EXIT_FAILURE);
-        }
-
-        /* Close out the standard file descriptors */        
-        close(STDIN_FILENO);
-        close(STDOUT_FILENO);
-        close(STDERR_FILENO);
-
-        devnull = open("/dev/null", O_RDWR);
-        if (devnull == -1)
-        {
-            log_error("Failed to open /dev/null: %s\n", strerror(errno));
-            exit(EXIT_FAILURE);
-        }
-
-        redirect1 = dup(devnull);
-        if (redirect1 == -1)
-        {
-            log_error("Failed to redirect output: %s\n", strerror(errno));
-            close(devnull);
-            exit(EXIT_FAILURE);
-        }
-
-        redirect2 = dup(devnull);
-        if (redirect2 == -1)
-        {
-            log_error("Failed to redirect output: %s\n", strerror(errno));
-            close(devnull);
-            close(redirect1);
-            exit(EXIT_FAILURE);
-        }
-
-    }
-
-    if (pid_fd != NULL)
-    {
-        pid_t cur_pid;
-        int     size;
-
-        cur_pid = getpid();
-        String pid = String::from(cur_pid);
-
-        size = fwrite(pid.c_str(), sizeof(char), pid.length(), pid_fd);
-        fclose(pid_fd);
-
-        if (size < pid.length())
-            log_error("Error when writing pid file %s : %s\n",
-                      pid_file.c_str(), strerror(errno));
     }
 
     main_thread_id = pthread_self();
     // install signal handlers
     sigfillset(&mask_set);
-    pthread_sigmask(SIG_SETMASK, &mask_set, NULL);
+    pthread_sigmask(SIG_SETMASK, &mask_set, nullptr);
 
     memset(&action, 0, sizeof(action));
     action.sa_handler = signal_handler;
     action.sa_flags = 0;
     sigfillset(&action.sa_mask);
-    if (sigaction(SIGINT, &action, NULL) < 0)
-    {
+    if (sigaction(SIGINT, &action, nullptr) < 0) {
         log_error("Could not register SIGINT handler!\n");
     }
 
-    if (sigaction(SIGTERM, &action, NULL) < 0)
-    {
+    if (sigaction(SIGTERM, &action, nullptr) < 0) {
         log_error("Could not register SIGTERM handler!\n");
     }
 
-    if (sigaction(SIGHUP, &action, NULL) < 0)
-    {
+    if (sigaction(SIGHUP, &action, nullptr) < 0) {
         log_error("Could not register SIGHUP handler!\n");
     }
 
-    if (sigaction(SIGPIPE, &action, NULL) < 0)
-    {
+    if (sigaction(SIGPIPE, &action, nullptr) < 0) {
         log_error("Could not register SIGPIPE handler!\n");
     }
 
     Ref<SingletonManager> singletonManager = SingletonManager::getInstance();
     Ref<Server> server;
-    try
-    {
+    try {
         server = Server::getInstance();
-        server->upnp_init(interface, ip, port);
-    }
-    catch(UpnpException upnp_e)
-    {
+        server->upnp_init();
+    } catch (const UpnpException& upnp_e) {
 
         sigemptyset(&mask_set);
-        pthread_sigmask(SIG_SETMASK, &mask_set, NULL);
+        pthread_sigmask(SIG_SETMASK, &mask_set, nullptr);
 
         upnp_e.printStackTrace();
         log_error("main: upnp error %d\n", upnp_e.getErrorCode());
-        if (upnp_e.getErrorCode() == UPNP_E_SOCKET_BIND)
-        {
+        if (upnp_e.getErrorCode() == UPNP_E_SOCKET_BIND) {
             log_error("Could not bind to socket.\n");
-            log_info("Please check if another instance of MediaTomb or\n");
-            log_info("another application is running on the same port.\n");
-        }
-        else if (upnp_e.getErrorCode() == UPNP_E_SOCKET_ERROR)
-        {
+            log_info("Please check if another instance of Gerbera or\n");
+            log_info("another application is running on port %d.\n", port);
+        } else if (upnp_e.getErrorCode() == UPNP_E_SOCKET_ERROR) {
             log_error("Socket error.\n");
             log_info("Please check if your network interface was configured for multicast!\n");
             log_info("Refer to the README file for more information.\n");
         }
-        
-        try
-        {
+
+        try {
             singletonManager->shutdown(true);
-        }
-        catch (Exception e)
-        {
+        } catch (const Exception& e) {
             log_error("%s\n", e.getMessage().c_str());
             e.printStackTrace();
         }
-        if (daemon)
-        {
-            close(devnull);
-            close(redirect1);
-            close(redirect2);
-        }
         exit(EXIT_FAILURE);
-    }
-    catch (Exception e)
-    {
+    } catch (const Exception& e) {
         log_error("%s\n", e.getMessage().c_str());
         e.printStackTrace();
-        if (daemon)
-            close(devnull);
         exit(EXIT_FAILURE);
     }
 
-    if (addFile->size() > 0)
-    {
-        for (int i = 0; i < addFile->size(); i++)
-        {
-            try
-            {   
+    if (addFile->size() > 0) {
+        for (int i = 0; i < addFile->size(); i++) {
+            try {
                 // add file/directory recursively and asynchronously
                 log_info("Adding %s\n", String(addFile->get(i)).c_str());
                 ContentManager::getInstance()->addFile(String(addFile->get(i)),
-                    true, true, 
+                    true, true,
                     ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_HIDDEN_FILES));
-            }
-            catch (Exception e)
-            {
+            } catch (const Exception& e) {
                 e.printStackTrace();
-                if (daemon)
-                {
-                    close(devnull);
-                    close(redirect1);
-                    close(redirect2);
-                }
                 exit(EXIT_FAILURE);
             }
         }
     }
-    
+
     sigemptyset(&mask_set);
-    pthread_sigmask(SIG_SETMASK, &mask_set, NULL);
-    
+    pthread_sigmask(SIG_SETMASK, &mask_set, nullptr);
+
     // wait until signalled to terminate
-    while (!shutdown_flag)
-    {
-        //pause();
-        //sleep(timer->getNotifyInterval());
-        
-        if (timer == nil)
-            timer = Timer::getInstance();
-        
-        timer->triggerWait();
-        
-        if (restart_flag != 0)
-        {
-            log_info("Restarting MediaTomb!\n");
-            try
-            {
-                server = nil;
-                timer = nil;
-                
+    while (!shutdown_flag) {
+        cond.wait(lock);
+
+        if (restart_flag != 0) {
+            log_info("Restarting Gerbera!\n");
+            try {
+                server = nullptr;
+
                 singletonManager->shutdown(true);
-                singletonManager = nil;
+                singletonManager = nullptr;
                 singletonManager = SingletonManager::getInstance();
-                
-                try
-                {
-                    ConfigManager::setStaticArgs(config_file, home, confdir, 
-                                                 prefix, magic);
+
+                try {
+                    ConfigManager::setStaticArgs(config_file, home, confdir,
+                        prefix, magic);
                     ConfigManager::getInstance();
-                }
-                catch (mxml::ParseException pe)
-                {
+                } catch (const mxml::ParseException& pe) {
                     log_error("Error parsing config file: %s line %d:\n%s\n",
-                            pe.context->location.c_str(),
-                            pe.context->line,
-                            pe.getMessage().c_str());
-                    log_error("Could not restart MediaTomb\n");
+                        pe.context->location.c_str(),
+                        pe.context->line,
+                        pe.getMessage().c_str());
+                    log_error("Could not restart Gerbera\n");
                     // at this point upnp shutdown has already been called
                     // so it is safe to exit
                     exit(EXIT_FAILURE);
-                }
-                catch (Exception e)
-                {
-                    log_error("Error reloading configuration: %s\n", 
-                              e.getMessage().c_str());
+                } catch (const Exception& e) {
+                    log_error("Error reloading configuration: %s\n",
+                        e.getMessage().c_str());
                     e.printStackTrace();
-                    if (daemon)
-                    {
-                        close(devnull);
-                        close(redirect1);
-                        close(redirect2);
-                    }
                     exit(EXIT_FAILURE);
                 }
-                
+
                 ///  \todo fix this for SIGHUP
                 server = Server::getInstance();
-                server->upnp_init(interface, ip, port);
-                
+                server->upnp_init();
+
                 restart_flag = 0;
-            }
-           catch(Exception e)
-            {
+            } catch (const Exception& e) {
                 restart_flag = 0;
                 shutdown_flag = 1;
                 sigemptyset(&mask_set);
-                pthread_sigmask(SIG_SETMASK, &mask_set, NULL);
-                log_error("Could not restart MediaTomb\n");
+                pthread_sigmask(SIG_SETMASK, &mask_set, nullptr);
+                log_error("Could not restart Gerbera\n");
             }
         }
     }
 
-    // shutting down 
+    // shutting down
     int ret = EXIT_SUCCESS;
-    try
-    {
+    try {
         singletonManager->shutdown(true);
-    }
-    catch(UpnpException upnp_e)
-    {
+    } catch (const UpnpException& upnp_e) {
         log_error("main: upnp error %d\n", upnp_e.getErrorCode());
         ret = EXIT_FAILURE;
-    }
-    catch (Exception e)
-    {
+    } catch (const Exception e) {
         e.printStackTrace();
         ret = EXIT_FAILURE;
     }
 
-    log_info("Server terminating\n");
+    log_info("Gerbera exiting. Have a nice day.\n");
     log_close();
-
-    if (daemon)
-    {
-        close(devnull);
-        close(redirect1);
-        close(redirect2);
-    }
-
     exit(ret);
 }
 
 void signal_handler(int signum)
 {
-    
-    if (main_thread_id != pthread_self())
-    {
+    if (main_thread_id != pthread_self()) {
         return;
     }
-    
-    if ((signum == SIGINT) || (signum == SIGTERM))
-    {
+
+    if ((signum == SIGINT) || (signum == SIGTERM)) {
         shutdown_flag++;
         if (shutdown_flag == 1)
-            log_info("MediaTomb shutting down. Please wait...\n");
+            log_info("Gerbera shutting down. Please wait...\n");
         else if (shutdown_flag == 2)
-            log_info("Mediatomb still shutting down, signal again to kill.\n");
-        else if (shutdown_flag > 2)
-        {
-            log_error("Clean shutdown failed, killing MediaTomb!\n");
+            log_info("Gerbera still shutting down, signal again to kill.\n");
+        else if (shutdown_flag > 2) {
+            log_error("Clean shutdown failed, killing Gerbera!\n");
             exit(1);
         }
-        if (timer != nil)
-            timer->signal();
-    }
-    else if (signum == SIGHUP)
-    {
-#if defined(ENABLE_SIGHUP)
+    } else if (signum == SIGHUP) {
         restart_flag = 1;
-        if (timer != nil)
-            timer->signal();
-#else
-        log_warning("SIGHUP handling was disabled during compilation.\n");
-#endif
     }
 
+    cond.notify_one();
+
     return;
 }
diff --git a/src/mem_io_handler.cc b/src/mem_io_handler.cc
index da5113f..c398b10 100644
--- a/src/mem_io_handler.cc
+++ b/src/mem_io_handler.cc
@@ -28,19 +28,16 @@
 */
 
 /// \file mem_io_handler.cc
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
 
 
 #include "server.h"
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include "ixml.h"
-#include <time.h>
+#include <cstring>
+#include <cstdio>
+#include <upnp-1.8/ixml.h>
+#include <ctime>
 #include "common.h"
 #include "storage.h"
 #include "cds_objects.h"
@@ -52,17 +49,15 @@
 using namespace zmm;
 using namespace mxml;
 
-MemIOHandler::MemIOHandler(void *buffer, int length) : IOHandler()
+MemIOHandler::MemIOHandler(const void *buffer, int length)
+    : buffer((char *)MALLOC(length)), length(length), pos(-1)
 {
-    this->buffer = (char *)MALLOC(length);
-    this->length = length;
     memcpy(this->buffer, buffer, length);
 }
 
-MemIOHandler::MemIOHandler(String str) : IOHandler()
+MemIOHandler::MemIOHandler(String str)
+    : buffer((char *)MALLOC(str.length())), length(str.length()), pos(-1)
 {
-    this->length = str.length();
-    this->buffer = (char *)MALLOC(length);
     memcpy(this->buffer, str.c_str(), length);
 }
 
diff --git a/src/mem_io_handler.h b/src/mem_io_handler.h
index b397190..829cb05 100644
--- a/src/mem_io_handler.h
+++ b/src/mem_io_handler.h
@@ -45,18 +45,18 @@ protected:
 
     /// \brief current offset in the buffer
     off_t   pos;
-    
+
 public:
     /// \brief Initializes the internal buffer.
     /// \param buffer all operations will be done on this buffer.
-    MemIOHandler(void *buffer, int length);
+    MemIOHandler(const void *buffer, int length);
     MemIOHandler(zmm::String str);
     virtual ~MemIOHandler();
 
     /// 
     virtual void open(IN enum UpnpOpenFileMode mode);
     virtual int read(OUT char *buf, IN size_t length);
-                      
+
     virtual void seek(IN off_t offset, IN int whence);
 };
 
diff --git a/src/memory.cc b/src/memory.cc
index ed944fd..df4c8ea 100644
--- a/src/memory.cc
+++ b/src/memory.cc
@@ -29,85 +29,13 @@
 
 /// \file memory.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include <stdio.h>
-
-#include "memory.h"
-
-#ifndef HAVE_MALLOC
-void *rpl_malloc(size_t size)
-{
-    if (size == 0)
-        ++size;
-
-    return malloc(size);
-}
-#endif
-
-#ifndef HAVE_REALLOC
-void *rpl_realloc(void *p, size_t size)
-{
-    if (size == 0)
-        ++size;
-    
-    return realloc(p, size);
-}
-#endif
-
-/* calloc() function that is glibc compatible.
-   This wrapper function is required at least on Tru64 UNIX 5.1.
-   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
-
-/* written by Jim Meyering */
-
-
-/* Allocate and zero-fill an NxS-byte block of memory from the heap.
-   If N or S is zero, allocate and zero-fill a 1-byte block.  */
-
 #if defined(TOMBDEBUG) && ! defined (MEMPROF)
+#include <cstdlib>
 #include "logger.h"
 #endif
 
-#ifndef HAVE_CALLOC
-void *rpl_calloc(size_t n, size_t s)
-{
-    size_t bytes;
-
-    if (n == 0 || s == 0)
-        return calloc (1, 1);
-
-    /* Defend against buggy calloc implementations that mishandle
-       size_t overflow.  */
-    bytes = n * s;
-    if (bytes / s != n)
-        return NULL;
-
-    return calloc (n, s);
-}
-#endif
-
-
 #ifdef MEMPROF
 
-
-
 static int mallocCount = 0;
 static int freeCount = 0;
 static int totalAlloc = 0;
diff --git a/src/memory.h b/src/memory.h
index 298c16f..89b3633 100644
--- a/src/memory.h
+++ b/src/memory.h
@@ -34,28 +34,6 @@
 
 #include <stdlib.h>
 
-#if (!defined(HAVE_MALLOC)) || (!defined(HAVE_REALLOC)) 
-    #include <sys/types.h>
-#else
-    #define HAVE_CALLOC
-#endif
-
-#ifndef HAVE_MALLOC
-    #undef malloc
-    #define malloc rpl_malloc
-#endif
-
-#ifndef HAVE_REALLOC
-    #undef realloc
-    #define realloc rpl_realloc
-#endif
-
-#ifndef HAVE_CALLOC
-    #undef calloc
-    #define calloc rpl_calloc
-#endif
-
-
 #ifndef MEMPROF
 
 #ifdef TOMBDEBUG
diff --git a/src/metadata/dvd_handler.cc b/src/metadata/dvd_handler.cc
deleted file mode 100644
index 5a7271e..0000000
--- a/src/metadata/dvd_handler.cc
+++ /dev/null
@@ -1,205 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    dvd_handler.cc - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file dvd_handler.cc
-/// \brief Implementeation of the DVDHandler class.
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#ifdef HAVE_LIBDVDNAV
-
-#include "dvd_handler.h"
-#include "string_converter.h"
-#include "common.h"
-#include "tools.h"
-#include "content_manager.h"
-#include "config_manager.h"
-
-#include "dvdnav_read.h"
-
-using namespace zmm;
-
-#define DVD                         "dvd"
-#define DVD_TITLE                   DVD "t"
-#define DVD_CHAPTER                 "ch"
-#define DVD_AUDIO_TRACK             "at"
-#define DVD_DURATION                "d"
-#define DVD_REST_DURATION           "r"
-#define DVD_FORMAT                  "f"
-#define DVD_STREAM_ID               "i"
-#define DVD_COUNT                   "c"
-#define DVD_CHANNELS                "l"
-#define DVD_SAMPLE_FREQUENCY        "q"
-#define DVD_LANGUAGE                "g"
-
-#define DVD_MIMETYPE                DVD "m"
-
-DVDHandler::DVDHandler() : MetadataHandler()
-{
-}
-
-String DVDHandler::renderKey(dvd_aux_key_names_t name, int title_idx, 
-                             int chapter_idx, int audio_track_idx)
-{
-    String key;
-
-    switch (name)
-    {
-        case DVD_Title:
-            key = _(DVD_TITLE);
-            break;
-        case DVD_Chapter:
-            key = _(DVD DVD_CHAPTER);
-            break;
-        case DVD_AudioTrack:
-            key = _(DVD DVD_AUDIO_TRACK);
-            break;
-        case DVD_AudioStreamID:
-            key = _(DVD DVD_STREAM_ID);
-            break;
-        case DVD_TitleCount:
-            key = _(DVD_TITLE) + _(DVD_COUNT);
-            break;
-        case DVD_TitleDuration:
-            key = _(DVD_TITLE) + title_idx + _(DVD_DURATION);
-            break;
-        case DVD_ChapterCount:
-            key = _(DVD_TITLE) + title_idx + _(DVD_CHAPTER) + chapter_idx + 
-                  _(DVD_COUNT);
-            break;
-        case DVD_ChapterDuration:
-            key = _(DVD_TITLE) + title_idx + _(DVD_CHAPTER) + chapter_idx + 
-                  _(DVD_DURATION);
-        case DVD_ChapterRestDuration:
-            key = _(DVD_TITLE) + title_idx + _(DVD_CHAPTER) + chapter_idx +
-                  _(DVD_REST_DURATION);
-            break;
-        case DVD_AudioTrackCount:
-            key = _(DVD_TITLE) + title_idx + _(DVD_AUDIO_TRACK) + _(DVD_COUNT);
-            break;
-        case DVD_AudioTrackFormat:
-            key = _(DVD_TITLE) + title_idx + _(DVD_AUDIO_TRACK) + 
-                   audio_track_idx + _(DVD_FORMAT);
-            break;
-        case DVD_AudioTrackStreamID:
-            key = _(DVD_TITLE) + title_idx + _(DVD_AUDIO_TRACK) + 
-                   audio_track_idx + _(DVD_STREAM_ID);
-            break;
-        case DVD_AudioTrackChannels:
-            key = _(DVD_TITLE) + title_idx + _(DVD_AUDIO_TRACK) +
-                  audio_track_idx + _(DVD_CHANNELS);
-            break;
-        case DVD_AudioTrackSampleFreq:
-            key = _(DVD_TITLE) + title_idx + _(DVD_AUDIO_TRACK) +
-                  audio_track_idx + _(DVD_SAMPLE_FREQUENCY);
-            break;
-        case DVD_AudioTrackLanguage:
-            key = _(DVD_TITLE) + title_idx + _(DVD_AUDIO_TRACK) +
-                  audio_track_idx + _(DVD_LANGUAGE);
-            break;
-        default:
-            throw _Exception(_("Invalid dvd aux key name!"));
-    }
-
-    return key;
-}
-
-void DVDHandler::fillMetadata(Ref<CdsItem> item)
-{
-    try
-    {
-        Ref<DVDNavReader> dvd(new DVDNavReader(item->getLocation()));
-
-        item->setFlag(OBJECT_FLAG_DVD_IMAGE);
-
-        int titles = dvd->titleCount();
-        item->setAuxData(renderKey(DVD_TitleCount), String::from(titles));
-
-        for (int i = 0; i < titles; i++)
-        {
-            dvd->selectPGC(i, 0);
-            item->setAuxData(renderKey(DVD_ChapterCount, i), 
-                    String::from(dvd->chapterCount(i)));
-//            if (dvd->titleDuration() > 0)
-//                item->setAuxData(renderKey(DVD_TitleDuration, i), 
-//                        secondsToHMS(dvd->titleDuration()));
-            item->setAuxData(renderKey(DVD_AudioTrackCount, i), 
-                    String::from(dvd->audioTrackCount()));
-
-            for (int a = 0; a < dvd->audioTrackCount(); a++)
-            {
-                item->setAuxData(renderKey(DVD_AudioTrackFormat, i, 0, a),
-                        dvd->audioFormat(a));
-                item->setAuxData(renderKey(DVD_AudioTrackStreamID, i, 0, a),
-                        String::from(dvd->audioStreamID(a)));
-                item->setAuxData(renderKey(DVD_AudioTrackChannels, i, 0, a),
-                        String::from(dvd->audioChannels(a)));
-                item->setAuxData(renderKey(DVD_AudioTrackSampleFreq, i, 0, a),
-                        String::from(dvd->audioSampleFrequency(a)));
-                item->setAuxData(renderKey(DVD_AudioTrackLanguage, i, 0, a),
-                        dvd->audioLanguage(a));
-            }
-#if 0
-            int secs = 0;
-            for (int c = dvd->chapterCount(i)-1; c >= 0; c--)
-            {
-                int chap_secs = dvd->chapterDuration(c);
-                secs = secs + chap_secs;
-                log_debug("Chapter seconds: %d rest seconds: %d\n", chap_secs,
-                        secs);
-                if (chap_secs > 0)
-                    item->setAuxData(renderKey(DVD_ChapterDuration, i, c), 
-                            secondsToHMS(chap_secs));
-                if (secs > 0)
-                    item->setAuxData(renderKey(DVD_ChapterRestDuration, i, c), 
-                            secondsToHMS(secs));
-            }
-#endif
-        } // for titles
-
-        log_debug("DVD image %s has %d titles\n", item->getLocation().c_str(), 
-                titles);
-    }
-    catch (Exception ex)
-    {
-        log_warning("Parsing ISO image failed (not a DVD?): %s\n", ex.getMessage().c_str());
-    }
-}
-
-
-
-Ref<IOHandler> DVDHandler::serveContent(Ref<CdsItem> item, int resNum, off_t *data_size)
-{
-    *data_size = -1;
-    return nil;
-}
-
-#endif // HAVE_DVD
diff --git a/src/metadata/dvd_handler.h b/src/metadata/dvd_handler.h
deleted file mode 100644
index faac0ba..0000000
--- a/src/metadata/dvd_handler.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    dvd_handler.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file dvd_handler.h
-/// \brief Definition of the DVD class.
-
-#ifndef __METADATA_DVD_H__
-#define __METADATA_DVD_H__
-
-#include "metadata_handler.h"
-
-#define DVD_AUXDATA_TITLE_COUNT           "DVD_TITLES"
-#define DVD_AUXDATA_CHAPTERS              "DVD_CHAPTERS"
-#define DVD_AUXDATA_AUDIO_TRACKS          "DVD_AUDIO_TRACKS"
-
-
-
-typedef enum
-{
-    DVD_Title,
-    DVD_TitleDuration,
-    DVD_TitleCount,
-
-    DVD_Chapter,
-    DVD_ChapterCount,
-    DVD_ChapterDuration,
-    DVD_ChapterRestDuration,
-   
-    DVD_AudioStreamID,
-    DVD_AudioTrack,
-    DVD_AudioTrackCount,
-    DVD_AudioTrackFormat,
-    DVD_AudioTrackStreamID,
-    DVD_AudioTrackChannels,
-    DVD_AudioTrackSampleFreq,
-    DVD_AudioTrackLanguage,
-} dvd_aux_key_names_t;
-
-
-/// \brief This class is responsible for parsing DVDs and DVD ISO images
-class DVDHandler : public MetadataHandler
-{
-public:
-    DVDHandler();
-    virtual void fillMetadata(zmm::Ref<CdsItem> item);
-    virtual zmm::Ref<IOHandler> serveContent(zmm::Ref<CdsItem> item, int resNum, off_t *data_size);
-
-    /// \brief Helper function to construct the key names for DVD aux data
-    static zmm::String renderKey(dvd_aux_key_names_t name, int title_idx = 0, 
-                                 int chapter_idx = 0, int audio_track_idx = 0);
-};
-
-#endif // __METADATA_DVD_H__
diff --git a/src/metadata/exiv2_handler.cc b/src/metadata/exiv2_handler.cc
index 3fe4b6f..c9c9193 100644
--- a/src/metadata/exiv2_handler.cc
+++ b/src/metadata/exiv2_handler.cc
@@ -30,10 +30,6 @@
 /// \file exiv2_handler.cc
 /// \brief Implementeation of the Exiv2Handler class.
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_EXIV2
 #include <exiv2/image.hpp>
 #include <exiv2/exif.hpp>
@@ -136,7 +132,7 @@ void Exiv2Handler::fillMetadata(Ref<CdsItem> item)
 
 Ref<IOHandler> Exiv2Handler::serveContent(Ref<CdsItem> item, int resNum)
 {
-    return nil;
+    return nullptr;
 }
 
 #endif // HAVE_EXIV2
diff --git a/src/metadata/fanart_handler.cc b/src/metadata/fanart_handler.cc
new file mode 100644
index 0000000..a4e332c
--- /dev/null
+++ b/src/metadata/fanart_handler.cc
@@ -0,0 +1,100 @@
+/*MT*
+    
+    MediaTomb - http://www.mediatomb.cc/
+    
+    fanart_handler.cc - this file is part of MediaTomb.
+    
+    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
+                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
+    
+    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
+                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
+                            Leonhard Wimmer <leo at mediatomb.cc>
+    
+    MediaTomb is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License version 2
+    as published by the Free Software Foundation.
+    
+    MediaTomb is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+    
+    You should have received a copy of the GNU General Public License
+    version 2 along with MediaTomb; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+    
+    $Id$
+*/
+
+/// \file fanart_handler.cc
+/// \brief Implementeation of the FanArtHelper class.
+
+#include "fanart_handler.h"
+#include <sys/stat.h>
+
+#include "common.h"
+#include "tools.h"
+#include "file_io_handler.h"
+
+using namespace zmm;
+
+const int num_names = 2;
+const char* names[] = {
+    "/folder.jpg",
+    "/poster.jpg"
+};
+
+FanArtHandler::FanArtHandler() : MetadataHandler()
+{
+}
+
+inline bool path_exists(String name) {
+  struct stat buffer;   
+  return (stat (name.c_str(), &buffer) == 0); 
+}
+
+String getFolderName(Ref<CdsItem> item) {
+    String folder = item->getLocation().substring(0, item->getLocation().rindex('/'));
+    log_debug("Folder name: %s\n", folder.c_str());
+    return folder;
+}
+
+String getFanArtPath(String folder) {
+    String found;
+    for (int i = 0; i < num_names; i++) {
+        bool exists = path_exists(folder + names[i]);
+        log_debug("%s: %s\n", names[i], exists ? "found" : "missing");
+        if (!exists)
+            continue;
+        found = folder + names[i];
+        break;
+    }
+    return found;
+}
+
+void FanArtHandler::fillMetadata(Ref<CdsItem> item)
+{
+    log_debug("Running fanart handler on %s\n", item->getLocation().c_str());
+
+    String found = getFanArtPath(getFolderName(item));
+
+    if (found != nullptr) {
+        Ref<CdsResource> resource(new CdsResource(CH_FANART));
+        resource->addAttribute(MetadataHandler::getResAttrName(R_PROTOCOLINFO), renderProtocolInfo("jpg"));
+        resource->addParameter(_(RESOURCE_CONTENT_TYPE), _(ID3_ALBUM_ART));
+        item->addResource(resource);
+    }
+}
+
+Ref<IOHandler> FanArtHandler::serveContent(Ref<CdsItem> item, int resNum, off_t *data_size)
+{
+    String path = getFanArtPath(getFolderName(item));
+
+    log_debug("FanArt: Opening name: %s\n", path.c_str());
+
+    *data_size = -1;
+    Ref<IOHandler> io_handler(new FileIOHandler(path));
+    return io_handler;
+}
+
diff --git a/src/metadata/libmp4v2_handler.h b/src/metadata/fanart_handler.h
similarity index 77%
rename from src/metadata/libmp4v2_handler.h
rename to src/metadata/fanart_handler.h
index 5f8f766..fef97db 100644
--- a/src/metadata/libmp4v2_handler.h
+++ b/src/metadata/fanart_handler.h
@@ -2,7 +2,7 @@
     
     MediaTomb - http://www.mediatomb.cc/
     
-    libmp4v2_handler.h - this file is part of MediaTomb.
+    fanart_handler.h - this file is part of MediaTomb.
     
     Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
                        Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
@@ -27,21 +27,21 @@
     $Id$
 */
 
-/// \file libmp4v2_handler.h
-/// \brief Definition of the LibMP4V2 class.
+/// \file fanart_handler.h
+/// \brief Definition of the FanArt class.
 
-#ifndef __METADATA_LIBMP4V2_H__
-#define __METADATA_LIBMP4V2_H__
+#ifndef __METADATA_FANART_H__
+#define __METADATA_FANART_H__
 
 #include "metadata_handler.h"
 
-/// \brief This class is responsible for reading id3 tags metadata
-class LibMP4V2Handler : public MetadataHandler
+/// \brief This class is responsible for populating filesystem based album and fan art
+class FanArtHandler : public MetadataHandler
 {
 public:
-    LibMP4V2Handler();
+    FanArtHandler();
     virtual void fillMetadata(zmm::Ref<CdsItem> item);
     virtual zmm::Ref<IOHandler> serveContent(zmm::Ref<CdsItem> item, int resNum, off_t *data_size);
 };
 
-#endif // __METADATA_LIBMP4V2_H__
+#endif // __METADATA_FANART_H__
diff --git a/src/metadata/ffmpeg_handler.cc b/src/metadata/ffmpeg_handler.cc
index f5834cd..367a906 100644
--- a/src/metadata/ffmpeg_handler.cc
+++ b/src/metadata/ffmpeg_handler.cc
@@ -40,19 +40,18 @@
 // AVCodecContext, defined in libavcodec/avcodec.h:722
 // in the ffmpeg sources
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_FFMPEG
 
 // ffmpeg needs the following sources
 // INT64_C is not defined in ffmpeg/avformat.h but is needed
 // macro defines included via autoconfig.h
+#include <cinttypes>
+#include <errno.h>
 #include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
 
-extern "C" 
-{
+extern "C" {
 
 #include <libavformat/avformat.h>
 #include <libavutil/avutil.h>
@@ -60,80 +59,63 @@ extern "C"
 } // extern "C"
 
 #ifdef HAVE_FFMPEGTHUMBNAILER
-    #include <libffmpegthumbnailer/videothumbnailerc.h>
+#include <libffmpegthumbnailer/videothumbnailerc.h>
 #endif
 
 #include "config_manager.h"
 #include "ffmpeg_handler.h"
 #include "string_converter.h"
-#include "common.h"
-#include "tools.h"
-#include "rexp.h"
-//#include "mxml/mxml.h"
-#include "mem_io_handler.h"
 
+#ifdef HAVE_AVSTREAM_CODECPAR
+#define as_codecpar(s) s->codecpar
+#else
+#define as_codecpar(s) s->codec
+#endif
 
 using namespace zmm;
-//using namespace mxml;
 
 // Default constructor
-FfmpegHandler::FfmpegHandler() : MetadataHandler()
+FfmpegHandler::FfmpegHandler()
+    : MetadataHandler()
 {
 }
 
-static void addFfmpegMetadataFields(Ref<CdsItem> item, AVFormatContext *pFormatCtx) 
+static void addFfmpegMetadataFields(Ref<CdsItem> item, AVFormatContext* pFormatCtx)
 {
-    AVDictionaryEntry *e = NULL;
-	Ref<StringConverter> sc = StringConverter::m2i();
+    AVDictionaryEntry* e = NULL;
+    Ref<StringConverter> sc = StringConverter::m2i();
     metadata_fields_t field;
     String value;
 
-    while ((e = av_dict_get(pFormatCtx->metadata, "", e,AV_DICT_IGNORE_SUFFIX)))
-    {
+    while ((e = av_dict_get(pFormatCtx->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) {
         value = e->value;
 
-    	if (strcmp(e->key, "title") == 0) 
-        {
-    	    log_debug("Identified metadata title: %s\n", e->value);
+        if (strcmp(e->key, "title") == 0) {
+            log_debug("Identified metadata title: %s\n", e->value);
             field = M_TITLE;
-    	}
-        else if (strcmp(e->key, "artist") == 0) 
-        {
-    	    log_debug("Identified metadata artist: %s\n", e->value);
+        } else if (strcmp(e->key, "artist") == 0) {
+            log_debug("Identified metadata artist: %s\n", e->value);
             field = M_ARTIST;
-    	}
-        else if (strcmp(e->key, "album") == 0) 
-        {
-    	    log_debug("Identified metadata album: %s\n", e->value);
+        } else if (strcmp(e->key, "album") == 0) {
+            log_debug("Identified metadata album: %s\n", e->value);
             field = M_ALBUM;
-    	}
-        else if (strcmp(e->key, "date") == 0) 
-        {
-            if ((value.length() == 4) && (value.toInt() > 0))
-            {
+        } else if (strcmp(e->key, "date") == 0) {
+            if ((value.length() == 4) && (value.toInt() > 0)) {
                 value = value + _("-01-01");
-    	        log_debug("Identified metadata date: %s\n", value.c_str());
+                log_debug("Identified metadata date: %s\n", value.c_str());
             }
             /// \toto parse possible ISO8601 timestamp
             field = M_DATE;
-    	}
-        else if (strcmp(e->key, "genre") == 0) 
-        {
-    	    log_debug("Identified metadata genre: %s\n", e->value);
+        } else if (strcmp(e->key, "genre") == 0) {
+            log_debug("Identified metadata genre: %s\n", e->value);
             field = M_GENRE;
-    	}
-        else if (strcmp(e->key, "comment") == 0) 
-        {
-	        log_debug("Identified metadata comment: %s\n", e->value);
+        } else if (strcmp(e->key, "comment") == 0) {
+            log_debug("Identified metadata comment: %s\n", e->value);
             field = M_DESCRIPTION;
-    	}
-        else if (strcmp(e->key, "track") == 0) 
-        {
-	        log_debug("Identified metadata track: %d\n", e->value);
+        } else if (strcmp(e->key, "track") == 0) {
+            log_debug("Identified metadata track: %d\n", e->value);
             field = M_TRACKNUMBER;
-	    }
-        else
-        {
+        } else {
             continue;
         }
 
@@ -142,10 +124,9 @@ static void addFfmpegMetadataFields(Ref<CdsItem> item, AVFormatContext *pFormatC
 }
 
 // ffmpeg library calls
-static void addFfmpegResourceFields(Ref<CdsItem> item, AVFormatContext *pFormatCtx, int *x, int *y) 
+static void addFfmpegResourceFields(Ref<CdsItem> item, AVFormatContext* pFormatCtx, int* x, int* y)
 {
-    unsigned int i;
-    int hours, mins, secs, us;
+    int64_t hours, mins, secs, us;
     int audioch = 0, samplefreq = 0;
     bool audioset, videoset;
     String resolution;
@@ -157,99 +138,82 @@ static void addFfmpegResourceFields(Ref<CdsItem> item, AVFormatContext *pFormatC
     *x = 0;
     *y = 0;
 
-	// duration
+    // duration
     secs = pFormatCtx->duration / AV_TIME_BASE;
     us = pFormatCtx->duration % AV_TIME_BASE;
     mins = secs / 60;
     secs %= 60;
     hours = mins / 60;
     mins %= 60;
-    if ((hours + mins + secs) > 0) 
-    { 
-    	sprintf(duration, "%02d:%02d:%02d.%01d", hours, mins,
-                secs, (10 * us) / AV_TIME_BASE);
+    if ((hours + mins + secs) > 0) {
+        sprintf(duration, "%02" PRId64 ":%02" PRId64 ":%02" PRId64 ".%01" PRId64, hours, mins, secs, (10 * us) / AV_TIME_BASE);
         log_debug("Added duration: %s\n", duration);
         item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_DURATION), duration);
     }
 
-	// bitrate
-    if (pFormatCtx->bit_rate > 0)  
-    {
-        log_debug("Added overall bitrate: %d kb/s\n", 
-                  pFormatCtx->bit_rate/1000);
-        item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_BITRATE), String::from(pFormatCtx->bit_rate/1000));
+    // bitrate
+    if (pFormatCtx->bit_rate > 0) {
+        // ffmpeg's bit_rate is in bits/sec, upnp wants it in bytes/sec
+        // See http://www.upnp.org/schemas/av/didl-lite-v3.xsd
+        log_debug("Added overall bitrate: %d kb/s\n", pFormatCtx->bit_rate / 8);
+        item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_BITRATE), String::from(pFormatCtx->bit_rate / 8));
     }
 
-	// video resolution, audio sampling rate, nr of audio channels
-	audioset = false;
-	videoset = false;
-	for(i=0; i<pFormatCtx->nb_streams; i++) 
-    {
-		AVStream *st = pFormatCtx->streams[i];
-		if((st != NULL) && (videoset == false) && (st->codec->codec_type == AVMEDIA_TYPE_VIDEO))
-        {
-            if (st->codec->codec_tag > 0)
-            {
+    // video resolution, audio sampling rate, nr of audio channels
+    audioset = false;
+    videoset = false;
+    for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++) {
+        AVStream* st = pFormatCtx->streams[i];
+        if ((st != NULL) && (videoset == false) && (as_codecpar(st)->codec_type == AVMEDIA_TYPE_VIDEO)) {
+            if (as_codecpar(st)->codec_tag > 0) {
                 char fourcc[5];
-                fourcc[0] = st->codec->codec_tag;
-                fourcc[1] = st->codec->codec_tag >> 8;
-                fourcc[2] = st->codec->codec_tag >> 16;
-                fourcc[3] = st->codec->codec_tag >> 24;
+                fourcc[0] = as_codecpar(st)->codec_tag;
+                fourcc[1] = as_codecpar(st)->codec_tag >> 8;
+                fourcc[2] = as_codecpar(st)->codec_tag >> 16;
+                fourcc[3] = as_codecpar(st)->codec_tag >> 24;
                 fourcc[4] = '\0';
 
-                log_debug("FourCC: %x = %s\n", 
-                                        st->codec->codec_tag, fourcc);
+                log_debug("FourCC: %x = %s\n",
+                    as_codecpar(st)->codec_tag, fourcc);
                 String fcc = fourcc;
                 if (string_ok(fcc))
-                    item->getResource(0)->addOption(_(RESOURCE_OPTION_FOURCC), 
-                                                    fcc);
+                    item->getResource(0)->addOption(_(RESOURCE_OPTION_FOURCC),
+                        fcc);
             }
 
-			if ((st->codec->width > 0) && (st->codec->height > 0)) 
-            {
-                resolution = String::from(st->codec->width) + "x" + 
-                                    String::from(st->codec->height);
-
-				log_debug("Added resolution: %s pixel\n", resolution.c_str());
-		        item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_RESOLUTION), resolution);
-				videoset = true;
-                *x = st->codec->width;
-                *y = st->codec->height;
-			}
-		} 
-		if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) 
-        {
-			// Increase number of audiochannels
-			audioch++;
-			// Get the sample rate
-			if ((audioset == false) && (st->codec->sample_rate > 0)) 
-            {
-				samplefreq = st->codec->sample_rate;
-			    if (samplefreq > 0) 
-                {
-		    	    log_debug("Added sample frequency: %d Hz\n", samplefreq);
-		        	item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_SAMPLEFREQUENCY), String::from(samplefreq));
-					audioset = true;
-    			}
-			}
-		}
-	}
-
-    if (audioch > 0) 
-    {
-        log_debug("Added number of audio channels: %d\n", audioch);
-        item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_NRAUDIOCHANNELS), String::from(audioch));
+            if ((as_codecpar(st)->width > 0) && (as_codecpar(st)->height > 0)) {
+                resolution = String::from(as_codecpar(st)->width) + "x" + String::from(as_codecpar(st)->height);
+
+                log_debug("Added resolution: %s pixel\n", resolution.c_str());
+                item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_RESOLUTION), resolution);
+                videoset = true;
+                *x = as_codecpar(st)->width;
+                *y = as_codecpar(st)->height;
+            }
+        }
+        if ((st != NULL) && (audioset == false) && (as_codecpar(st)->codec_type == AVMEDIA_TYPE_AUDIO)) {
+            // find the first stream that has a valid sample rate
+            if (as_codecpar(st)->sample_rate > 0) {
+                samplefreq = as_codecpar(st)->sample_rate;
+                log_debug("Added sample frequency: %d Hz\n", samplefreq);
+                item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_SAMPLEFREQUENCY), String::from(samplefreq));
+                audioset = true;
+
+                audioch = as_codecpar(st)->channels;
+                if (audioch > 0) {
+                    log_debug("Added number of audio channels: %d\n", audioch);
+                    item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_NRAUDIOCHANNELS), String::from(audioch));
+                }
+            }
+        }
     }
-} // addFfmpegResourceFields
 
-/*double time_to_double(struct timeval time) {
-        return time.tv_sec + (time.tv_usec / 1000000.0);
-}*/
+}
 
 // Stub for suppressing ffmpeg error messages during matadata extraction
 void FfmpegNoOutputStub(void* ptr, int level, const char* fmt, va_list vl)
 {
-	// do nothing
+    // do nothing
 }
 
 void FfmpegHandler::fillMetadata(Ref<CdsItem> item)
@@ -259,53 +223,187 @@ void FfmpegHandler::fillMetadata(Ref<CdsItem> item)
     int x = 0;
     int y = 0;
 
-	AVFormatContext *pFormatCtx = NULL;
-	
-	// Suppress all log messages
-	av_log_set_callback(FfmpegNoOutputStub);
-	
-	// Register all formats and codecs
+    AVFormatContext* pFormatCtx = NULL;
+
+    // Suppress all log messages
+    av_log_set_callback(FfmpegNoOutputStub);
+
+    // Register all formats and codecs
     av_register_all();
 
     // Open video file
-    if (avformat_open_input(&pFormatCtx, 
-                          item->getLocation().c_str(), NULL, NULL) != 0)
+    if (avformat_open_input(&pFormatCtx,
+            item->getLocation().c_str(), NULL, NULL)
+        != 0)
         return; // Couldn't open file
 
     // Retrieve stream information
-    if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
-    {
+    if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
         avformat_close_input(&pFormatCtx);
         return; // Couldn't find stream information
-    }   
-	// Add metadata using ffmpeg library calls
-	addFfmpegMetadataFields(item, pFormatCtx);
-	// Add resources using ffmpeg library calls
-	addFfmpegResourceFields(item, pFormatCtx, &x, &y);
-	
+    }
+    // Add metadata using ffmpeg library calls
+    addFfmpegMetadataFields(item, pFormatCtx);
+    // Add resources using ffmpeg library calls
+    addFfmpegResourceFields(item, pFormatCtx, &x, &y);
+
     // Close the video file
     avformat_close_input(&pFormatCtx);
 }
 
-Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t *data_size)
+#ifdef HAVE_FFMPEGTHUMBNAILER
+
+// The ffmpegthumbnailer code (ffmpeg?) is not threading safe.
+// Add a lock around the usage to avoid crashing randomly.
+static pthread_mutex_t thumb_lock;
+
+static int _mkdir(const char* path)
+{
+    int ret = mkdir(path, 0777);
+
+    if (ret == 0) {
+        // Make sure we are +x in case of restrictive umask that strips +x.
+        struct stat st;
+        if (stat(path, &st)) {
+            log_warning("could not stat(%s): %s\n", path, strerror(errno));
+            return -1;
+        }
+        mode_t xbits = S_IXUSR | S_IXGRP | S_IXOTH;
+        if (!(st.st_mode & xbits)) {
+            if (chmod(path, st.st_mode | xbits)) {
+                log_warning("could not chmod(%s, +x): %s\n", path, strerror(errno));
+                return -1;
+            }
+        }
+    }
+
+    return ret;
+}
+
+static bool makeThumbnailCacheDir(String& path)
+{
+    char* path_temp = strdup(path.c_str());
+    char* last_slash = strrchr(path_temp, '/');
+    char* slash = last_slash;
+    bool ret = false;
+
+    if (!last_slash)
+        return ret;
+
+    // Assume most dirs exist, so scan backwards first.
+    // Avoid stat/access checks due to TOCTOU races.
+    errno = 0;
+    for (slash = last_slash; slash > path_temp; --slash) {
+        if (*slash != '/')
+            continue;
+        *slash = '\0';
+        if (_mkdir(path_temp) == 0) {
+            // Now we can forward scan.
+            while (slash < last_slash) {
+                *slash = DIR_SEPARATOR;
+                if (_mkdir(path_temp) < 0)
+                    // Allow EEXIST in case of someone else doing `mkdir`.
+                    if (errno != EEXIST)
+                        goto done;
+                slash += strlen(slash);
+            }
+            if (slash == last_slash)
+                ret = true;
+            break;
+        } else if (errno == EEXIST) {
+            ret = true;
+            break;
+        } else if (errno != ENOENT) {
+            break;
+        }
+    }
+
+done:
+    free(path_temp);
+    return ret;
+}
+
+static String getThumbnailCacheFilePath(String& movie_filename, bool create)
+{
+    Ref<ConfigManager> cfg = ConfigManager::getInstance();
+    String cache_dir = cfg->getOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR);
+
+    if (cache_dir.length() == 0) {
+        String home_dir = cfg->getOption(CFG_SERVER_HOME);
+        cache_dir = home_dir + "/cache-dir";
+    }
+
+    cache_dir = cache_dir + movie_filename + "-thumb.jpg";
+    if (create && !makeThumbnailCacheDir(cache_dir))
+        cache_dir = "";
+    return cache_dir;
+}
+
+static bool readThumbnailCacheFile(String movie_filename, uint8_t** ptr_img, size_t* size_img)
+{
+    String path = getThumbnailCacheFilePath(movie_filename, false);
+    FILE* fp = fopen(path.c_str(), "rb");
+    if (!fp)
+        return false;
+
+    size_t bytesRead;
+    uint8_t buffer[1024];
+    *ptr_img = NULL;
+    *size_img = 0;
+    while ((bytesRead = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
+        *ptr_img = (uint8_t*)realloc(*ptr_img, *size_img + bytesRead);
+        memcpy(*ptr_img + *size_img, buffer, bytesRead);
+        *size_img += bytesRead;
+    }
+    fclose(fp);
+    return true;
+}
+
+static void writeThumbnailCacheFile(String movie_filename, uint8_t* ptr_img, int size_img)
+{
+    String path = getThumbnailCacheFilePath(movie_filename, true);
+    FILE* fp = fopen(path.c_str(), "wb");
+    if (!fp)
+        return;
+    fwrite(ptr_img, sizeof(uint8_t), size_img, fp);
+    fclose(fp);
+}
+
+#endif
+
+Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t* data_size)
 {
     *data_size = -1;
 #ifdef HAVE_FFMPEGTHUMBNAILER
     Ref<ConfigManager> cfg = ConfigManager::getInstance();
 
     if (!cfg->getBoolOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_ENABLED))
-        return nil;
+        return nullptr;
+
+    if (cfg->getBoolOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED)) {
+        uint8_t* ptr_image;
+        size_t size_image;
+        if (readThumbnailCacheFile(item->getLocation(),
+                &ptr_image, &size_image)) {
+            *data_size = (off_t)size_image;
+            Ref<IOHandler> h(new MemIOHandler(ptr_image, size_image));
+            free(ptr_image);
+            log_debug("Returning cached thumbnail for file: %s\n", item->getLocation().c_str());
+            return h;
+        }
+    }
+
+    pthread_mutex_lock(&thumb_lock);
 
 #ifdef FFMPEGTHUMBNAILER_OLD_API
-    video_thumbnailer *th = create_thumbnailer();
-    image_data *img = create_image_data();
+    video_thumbnailer* th = create_thumbnailer();
+    image_data* img = create_image_data();
 #else
-    video_thumbnailer *th = video_thumbnailer_create();
-    image_data *img = video_thumbnailer_create_image_data();
+    video_thumbnailer* th = video_thumbnailer_create();
+    image_data* img = video_thumbnailer_create_image_data();
 #endif // old api
 
-
-    th->seek_percentage        = cfg->getIntOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_SEEK_PERCENTAGE);
+    th->seek_percentage = cfg->getIntOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_SEEK_PERCENTAGE);
 
     if (cfg->getBoolOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_FILMSTRIP_OVERLAY))
         th->overlay_film_strip = 1;
@@ -314,32 +412,40 @@ Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t
 
     th->thumbnail_size = cfg->getIntOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_THUMBSIZE);
     th->thumbnail_image_quality = cfg->getIntOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_IMAGE_QUALITY);
-    th->thumbnail_image_type   = Jpeg;
+    th->thumbnail_image_type = Jpeg;
 
     log_debug("Generating thumbnail for file: %s\n", item->getLocation().c_str());
 
 #ifdef FFMPEGTHUMBNAILER_OLD_API
     if (generate_thumbnail_to_buffer(th, item->getLocation().c_str(), img) != 0)
 #else
-    if (video_thumbnailer_generate_thumbnail_to_buffer(th, 
-                                         item->getLocation().c_str(), img) != 0)
+    if (video_thumbnailer_generate_thumbnail_to_buffer(th,
+            item->getLocation().c_str(), img)
+        != 0)
 #endif // old api
-        throw _Exception(_("Could not generate thumbnail for ") + 
-                item->getLocation());
+    {
+        pthread_mutex_unlock(&thumb_lock);
+        throw _Exception(_("Could not generate thumbnail for ") + item->getLocation());
+    }
+    if (cfg->getBoolOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED)) {
+        writeThumbnailCacheFile(item->getLocation(),
+            img->image_data_ptr, img->image_data_size);
+    }
 
     *data_size = (off_t)img->image_data_size;
-    Ref<IOHandler> h(new MemIOHandler((void *)img->image_data_ptr, 
-                                              img->image_data_size));
+    Ref<IOHandler> h(new MemIOHandler((void*)img->image_data_ptr,
+        img->image_data_size));
 #ifdef FFMPEGTHUMBNAILER_OLD_API
     destroy_image_data(img);
     destroy_thumbnailer(th);
 #else
     video_thumbnailer_destroy_image_data(img);
     video_thumbnailer_destroy(th);
-#endif// old api
+#endif // old api
+    pthread_mutex_unlock(&thumb_lock);
     return h;
 #else
-    return nil;
+    return nullptr;
 #endif
 }
 
@@ -351,7 +457,7 @@ String FfmpegHandler::getMimeType()
     String thumb_mimetype = mappings->get(_(CONTENT_TYPE_JPG));
     if (!string_ok(thumb_mimetype))
         thumb_mimetype = _("image/jpeg");
-    
+
     return thumb_mimetype;
 }
 #endif // HAVE_FFMPEG
diff --git a/src/metadata/flac_handler.cc b/src/metadata/flac_handler.cc
deleted file mode 100644
index ad3a08c..0000000
--- a/src/metadata/flac_handler.cc
+++ /dev/null
@@ -1,204 +0,0 @@
-/*MT*
-
-    MediaTomb - http://www.mediatomb.cc/
-
-    flac_handler.cc - this file is part of MediaTomb.
-
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-
-    Copyright (C) 2006-2009 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
-    $Id: flac_handler.cc 2032 2009-12-21 22:58:57Z lww $
-*/
-
-/// \file flac_handler.cc
-/// \brief Implementeation of the FlacHandler class.
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#ifdef HAVE_FLAC
-
-#include <FLAC/all.h>
-
-#include "flac_handler.h"
-#include "string_converter.h"
-#include "config_manager.h"
-#include "common.h"
-#include "tools.h"
-#include "mem_io_handler.h"
-
-#include "content_manager.h"
-
-using namespace zmm;
-
-FlacHandler::FlacHandler() : MetadataHandler()
-{
-}
-
-static void addField(metadata_fields_t field, const FLAC__StreamMetadata* tags, Ref<CdsItem> item)
-{
-    String value;
-    int i;
-
-    Ref<StringConverter> sc = StringConverter::i2i(); // sure is sure
-
-    switch (field)
-    {
-        case M_TITLE:
-            i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "TITLE");
-            break;
-        case M_ARTIST:
-            i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "ARTIST");
-            break;
-        case M_ALBUM:
-            i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "ALBUM");
-            break;
-        case M_DATE:
-            i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "DATE");
-            break;
-        case M_GENRE:
-            i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "GENRE");
-            break;
-        case M_DESCRIPTION:
-            i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "DESCRIPTION");
-            break;
-        case M_TRACKNUMBER:
-            i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "TRACKNUMBER");
-            break;
-        default:
-            return;
-    }
-
-    if( 0 <= i )
-        value = strchr((const char *)tags->data.vorbis_comment.comments[i].entry, '=') + 1;
-    else
-        return;
-
-    value = trim_string(value);
-
-    if (string_ok(value))
-    {
-        item->setMetadata(MT_KEYS[field].upnp, sc->convert(value));
-        log_debug("Setting metadata on item: %d, %s\n", field, sc->convert(value).c_str());
-    }
-}
-
-void FlacHandler::fillMetadata(Ref<CdsItem> item)
-{
-    FLAC__StreamMetadata* tags = NULL;
-    FLAC__StreamMetadata streaminfo;
-    Ref<StringConverter> sc = StringConverter::i2i(); // sure is sure
-
-    if (!FLAC__metadata_get_tags(item->getLocation().c_str(), &tags))
-        return;
-
-    if (FLAC__METADATA_TYPE_VORBIS_COMMENT == tags->type)
-    {
-        for (int i = 0; i < M_MAX; i++)
-            addField((metadata_fields_t) i, tags, item);
-    }
-
-    FLAC__metadata_object_delete(tags);
-    tags = NULL;
-
-    if (!FLAC__metadata_get_streaminfo(item->getLocation().c_str(), &streaminfo))
-        return;
-
-    if (FLAC__METADATA_TYPE_STREAMINFO == streaminfo.type)
-    {
-        // note: UPnP requires bytes/second
-        item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_BITRATE), String::from((unsigned)((streaminfo.data.stream_info.bits_per_sample * streaminfo.data.stream_info.sample_rate) / 8)));
-        // note: UPnP requires HMS
-        item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_DURATION), secondsToHMS((unsigned)(streaminfo.data.stream_info.total_samples / streaminfo.data.stream_info.sample_rate)));
-        item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_SAMPLEFREQUENCY), String::from(streaminfo.data.stream_info.sample_rate));
-        item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_NRAUDIOCHANNELS), String::from(streaminfo.data.stream_info.channels));
-    }
-
-    if (!FLAC__metadata_get_picture(item->getLocation().c_str(),
-                                    &tags,
-                                    FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER,
-                                    NULL,
-                                    NULL,
-                                    (unsigned)-1,
-                                    (unsigned)-1,
-                                    (unsigned)-1,
-                                    (unsigned)-1 ))
-        return;
-
-    if (FLAC__METADATA_TYPE_PICTURE == tags->type)
-    {
-        String art_mimetype = tags->data.picture.mime_type;
-        log_debug("Mime type : %s\n", sc->convert(art_mimetype).c_str());
-
-        // saw that simply "PNG" was used with some mp3's, so mimetype setting
-        // was probably invalid
-        if (!string_ok(art_mimetype) || (art_mimetype.index('/') == -1))
-        {
-#ifdef HAVE_MAGIC
-            art_mimetype =  ContentManager::getInstance()->getMimeTypeFromBuffer((void *)tags->data.picture.data, tags->data.picture.data_length);
-            if (!string_ok(art_mimetype))
-#endif
-                art_mimetype = _(MIMETYPE_DEFAULT);
-
-            log_debug("Mime type via magic: %s\n", sc->convert(art_mimetype).c_str());
-        }
-
-        // if we could not determine the mimetype, then there is no
-        // point to add the resource - it's probably garbage
-        if (art_mimetype != _(MIMETYPE_DEFAULT))
-        {
-            Ref<CdsResource> resource(new CdsResource(CH_FLAC));
-            resource->addAttribute(MetadataHandler::getResAttrName(R_PROTOCOLINFO), renderProtocolInfo(art_mimetype));
-            resource->addParameter(_(RESOURCE_CONTENT_TYPE), _(ID3_ALBUM_ART));
-            item->addResource(resource);
-        }
-    }
-
-    FLAC__metadata_object_delete(tags);
-}
-
-Ref<IOHandler> FlacHandler::serveContent(Ref<CdsItem> item, int resNum, off_t *data_size)
-{
-    FLAC__StreamMetadata* picture = NULL;
-
-    if (!FLAC__metadata_get_picture(item->getLocation().c_str(),
-                                    &picture,
-                                    FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER,
-                                    NULL,
-                                    NULL,
-                                    (unsigned)-1,
-                                    (unsigned)-1,
-                                    (unsigned)-1,
-                                    (unsigned)-1 ))
-        throw _Exception(_("FlacHandler: could not exctract cover from: ") + item->getLocation());
-
-    if ( FLAC__METADATA_TYPE_PICTURE != picture->type)
-        throw _Exception(_("TagHandler: resource has no album information"));
-
-    Ref<IOHandler> h(new MemIOHandler((void *)picture->data.picture.data, picture->data.picture.data_length));
-    *data_size = picture->data.picture.data_length;
-
-    FLAC__metadata_object_delete(picture);
-
-    return h;
-}
-
-#endif // HAVE_FLAC
diff --git a/src/metadata/flac_handler.h b/src/metadata/flac_handler.h
deleted file mode 100644
index 06432fe..0000000
--- a/src/metadata/flac_handler.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    flac_handler.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2009 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id: flac_handler.h 2010 2009-01-11 19:10:43Z lww $
-*/
-
-/// \file flac_handler.h
-/// \brief Definition of the FlacHandler class.
-
-#ifndef __METADATA_FLAC_H__
-#define __METADATA_FLAC_H__
-
-#include "metadata_handler.h"
-
-/// \brief This class is responsible for reading FLAC metadata
-class FlacHandler : public MetadataHandler
-{
-public:
-    FlacHandler();
-    virtual void fillMetadata(zmm::Ref<CdsItem> item);
-    virtual zmm::Ref<IOHandler> serveContent(zmm::Ref<CdsItem> item, int resNum,
-                                             off_t *data_size);
-};
-
-#endif // __METADATA_FLAC_H__
diff --git a/src/metadata/id3_handler.cc b/src/metadata/id3_handler.cc
deleted file mode 100644
index fcdb788..0000000
--- a/src/metadata/id3_handler.cc
+++ /dev/null
@@ -1,355 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    id3_handler.cc - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file id3_handler.cc
-/// \brief Implementeation of the Id3Handler class.
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#ifdef HAVE_ID3LIB
-
-#ifdef HAVE_CONFIG_H
-    #undef HAVE_CONFIG_H // else utils.h from the id3 library tries to import "config.h"
-
-    #include <id3/tag.h>
-    #include <id3/misc_support.h>
-    #define HAVE_CONFIG_H
-#else
-    #include <id3/tag.h>
-    #include <id3/misc_support.h>
-#endif
-
-#include "id3_handler.h"
-#include "string_converter.h"
-#include "common.h"
-#include "tools.h"
-#include "mem_io_handler.h"
-#include "content_manager.h"
-#include "config_manager.h"
-
-using namespace zmm;
-
-Id3Handler::Id3Handler() : MetadataHandler()
-{
-}
-
-char* ID3_GetFrameContent(const ID3_Tag *tag, ID3_FrameID frameID)
-{
-    char *content = NULL;
-    ID3_Frame *frame = NULL;
-    if (tag != NULL && (frame = tag->Find(frameID)) != NULL) 
-    {
-	    content = ID3_GetString(frame, ID3FN_TEXT);
-    }
-    return content;
-}
-       
-static void addID3Field(metadata_fields_t field, ID3_Tag *tag, Ref<CdsItem> item)
-{
-    String value;
-    char*  ID3_retval = NULL;
-  
-    Ref<StringConverter> sc = StringConverter::m2i();
-    size_t genre;
-#if SIZEOF_SIZE_T > 4
-    long track;
-#else
-    int track;
-#endif
-    
-    switch (field)
-    {
-        case M_TITLE:
-            ID3_retval = ID3_GetTitle(tag);
-            break;
-        case M_ARTIST:
-            ID3_retval = ID3_GetArtist(tag);          
-            break;
-        case M_ALBUM:
-            ID3_retval = ID3_GetAlbum(tag);
-            break;
-        case M_DATE:
-            ID3_retval = ID3_GetYear(tag);
-            value = ID3_retval;
-            if (string_ok(value))
-                value = value + "-01-01";
-            else
-                return;
-            break;
-        case M_GENRE:
-            genre = ID3_GetGenreNum(tag);
-            if (ID3_V1GENRE2DESCRIPTION(genre))
-                value = (char *)(ID3_V1GENRE2DESCRIPTION(genre));
-
-            if (!string_ok(value))
-            {
-                ID3_retval = ID3_GetGenre(tag); 
-                value = ID3_retval;
-            }
-            break;
-        case M_DESCRIPTION:
-            ID3_retval = ID3_GetComment(tag);
-            break;
-        case M_TRACKNUMBER:
-            track = ID3_GetTrackNum(tag);
-            if (track > 0)
-            {
-                value = String::from(track);
-                item->setTrackNumber((int)track);
-            }
-            else
-                return;
-            break;
-        case M_AUTHOR:
-            ID3_retval = ID3_GetFrameContent(tag, ID3FID_COMPOSER);
-            break;
-        case M_DIRECTOR:
-            ID3_retval = ID3_GetFrameContent(tag, ID3FID_CONDUCTOR);
-            break;
-//        case M_OPUS:
-//            ID3_retval = ID3_GetFrameContent(tag, ID3FID_CONTENTGROUP);
-//            break;
-        default:
-            return;
-    }
-
-    if ((field != M_GENRE) && (field != M_DATE) && (field != M_TRACKNUMBER))
-        value = ID3_retval;
-    
-    if (ID3_retval)
-        delete [] ID3_retval;
-
-    value = trim_string(value);
-    
-    if (string_ok(value))
-    {
-        item->setMetadata(MT_KEYS[field].upnp, sc->convert(value));
-//        log_debug("Setting metadata on item: %d, %s\n", field, sc->convert(value).c_str());
-    }
-}
-
-void Id3Handler::fillMetadata(Ref<CdsItem> item)
-{
-    ID3_Tag tag;
-    const Mp3_Headerinfo* header;
-    Ref<Array<StringBase> > aux;
-    Ref<StringConverter> sc = StringConverter::m2i();
-    
-    // the location has already been checked by the setMetadata function
-    tag.Link(item->getLocation().c_str()); 
-
-    for (int i = 0; i < M_MAX; i++)
-        addID3Field((metadata_fields_t) i, &tag, item);
-
-    Ref<ConfigManager> cm = ConfigManager::getInstance();
-    aux = cm->getStringArrayOption(CFG_IMPORT_LIBOPTS_ID3_AUXDATA_TAGS_LIST);
-    if (aux != nil)
-    {
-        const char *temp = NULL;
-        
-        for (int j = 0; j < aux->size(); j++)
-        {
-
-            String desiredFrame(aux->get(j));
-            if (string_ok(desiredFrame))
-            {
-                ID3_Tag::Iterator* frameIter = tag.CreateIterator();
-                ID3_Frame* id3Frame = NULL;
-                while (NULL != (id3Frame = frameIter->GetNext())) 
-                {
-                    String frameName(id3Frame->GetTextID());
-                    if (string_ok(frameName) && (frameName == desiredFrame)) 
-                    {
-                        ID3_Frame::Iterator* fieldIter = id3Frame->CreateIterator();
-                        ID3_Field* id3Field = NULL;
-                        while (NULL != (id3Field = fieldIter->GetNext())) 
-                        {
-                            if (id3Field->GetType() == ID3FTY_TEXTSTRING) 
-                            {
-                                temp = id3Field->GetRawText();
-
-                                if (temp != NULL)
-                                {
-                                    String value(temp);
-                                    if (string_ok(value))
-                                    {
-                                        value = sc->convert(value);
-                                        log_debug("Adding frame: %s with value %s\n", desiredFrame.c_str(), value.c_str());
-                                        item->setAuxData(desiredFrame, value);
-                                    }
-                                }
-                            }
-                        }
-                        delete fieldIter;
-                    }
-                }
-                delete frameIter;
-            }
-        }
-    }
-
-
-    header = tag.GetMp3HeaderInfo();
-    if (header)
-    {
-        int temp;
-
-        // note: UPnP requres bytes/second
-        if ((header->vbr_bitrate) > 0)
-        {
-            temp = (header->vbr_bitrate) / 8; 
-        }
-        else
-        {
-            temp = (header->bitrate) / 8;
-        }
-
-        if (temp > 0)
-        {
-            item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_BITRATE),
-                                               String::from(temp)); 
-        }
-
-        if ((header->time) > 0)
-        {
-            item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_DURATION),
-                                               secondsToHMS(header->time));
-        }
-
-        if ((header->frequency) > 0)
-        {
-            item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_SAMPLEFREQUENCY), 
-                                               String::from((int)(header->frequency)));
-        }
-
-        temp = 0;
-        switch(header->channelmode)
-        {
-            case MP3CHANNELMODE_STEREO:
-            case MP3CHANNELMODE_JOINT_STEREO:
-            case MP3CHANNELMODE_DUAL_CHANNEL:
-                temp = 2;
-                break;
-            case MP3CHANNELMODE_SINGLE_CHANNEL:
-                temp = 1;
-                break;
-            case MP3CHANNELMODE_FALSE:
-                break;
-        }
-
-        if (temp > 0)
-        {
-            item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_NRAUDIOCHANNELS),
-                                               String::from(temp));
-        }
-    }
-
-#ifdef HAVE_ID3LIB_ALBUMART
-    // get album art
-    // we have a bit of design problem here - the album art is actually not
-    // a resource, but our architecture is built that way that we can only
-    // serve resources, so we are going to bend this a little:
-    // the album art will be saved as a resource, but the CdsResourceManager
-    // will handle this special case and render the XML correctly...
-    // \todo discuss the album art approach with Leo
-    if (ID3_HasPicture(&tag))
-    {
-        ID3_Frame* frame = NULL;
-        frame = tag.Find(ID3FID_PICTURE);
-        if (frame != NULL)
-        {
-            ID3_Field* art = frame->GetField(ID3FN_DATA);
-            if (art != NULL)
-            {
-                Ref<StringConverter> sc = StringConverter::m2i(); 
-                String art_mimetype = sc->convert(ID3_GetPictureMimeType(&tag));
-                if (!string_ok(art_mimetype) || (art_mimetype.index('/') == -1))
-                {
-#ifdef HAVE_MAGIC
-                    art_mimetype = ContentManager::getInstance()->getMimeTypeFromBuffer((void *)art->GetRawBinary(), art->Size());
-                    if (!string_ok(art_mimetype))
-#endif
-                       art_mimetype = _(MIMETYPE_DEFAULT);
-                }
-
-                // if we could not determine the mimetype, then there is no
-                // point to add the resource - it's probably garbage
-                if (art_mimetype != _(MIMETYPE_DEFAULT))
-                {
-                    Ref<CdsResource> resource(new CdsResource(CH_ID3));
-                    resource->addAttribute(MetadataHandler::getResAttrName(R_PROTOCOLINFO), renderProtocolInfo(art_mimetype));
-                    resource->addParameter(_(RESOURCE_CONTENT_TYPE), _(ID3_ALBUM_ART));
-                    item->addResource(resource);
-                }
-
-            }
-        }
-    }
-#endif
-    tag.Clear();
-}
-
-Ref<IOHandler> Id3Handler::serveContent(Ref<CdsItem> item, int resNum, off_t *data_size)
-{
-    ID3_Tag tag;
-    if (tag.Link(item->getLocation().c_str()) == 0)
-    {
-        throw _Exception(_("Id3Handler: could not open file: ") + item->getLocation());
-    }
-
-    Ref<CdsResource> res = item->getResource(resNum);
-
-    String ctype = res->getParameters()->get(_(RESOURCE_CONTENT_TYPE));
-
-    if (ctype != ID3_ALBUM_ART)
-        throw _Exception(_("Id3Handler: got unknown content type: ") + ctype);
-
-    if (!ID3_HasPicture(&tag))
-        throw _Exception(_("Id3Handler: resource has no album art information"));
-
-    ID3_Frame* frame = NULL;
-    frame = tag.Find(ID3FID_PICTURE);
-
-    if (frame == NULL)
-        throw _Exception(_("Id3Handler: could not server album art - empty frame"));
-
-    ID3_Field* art = frame->GetField(ID3FN_DATA);
-    if (art == NULL)
-        throw _Exception(_("Id3Handler: could not server album art - empty field"));
-
-    Ref<IOHandler> h(new MemIOHandler((void *)art->GetRawBinary(), art->Size()));
-    *data_size = art->Size();
-    tag.Clear();
-
-    return h;
-}
-
-#endif // HAVE_ID3LIB
diff --git a/src/metadata/id3_handler.h b/src/metadata/id3_handler.h
deleted file mode 100644
index 6339f3f..0000000
--- a/src/metadata/id3_handler.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    id3_handler.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file id3_handler.h
-/// \brief Definition of the Id3Handler class.
-
-#ifndef __METADATA_ID3_H__
-#define __METADATA_ID3_H__
-
-#include "metadata_handler.h"
-
-/// \brief This class is responsible for reading id3 tags metadata
-class Id3Handler : public MetadataHandler
-{
-public:
-    Id3Handler();
-    virtual void fillMetadata(zmm::Ref<CdsItem> item);
-    virtual zmm::Ref<IOHandler> serveContent(zmm::Ref<CdsItem> item, int resNum, off_t *data_size);
-};
-
-#endif // __METADATA_ID3_H__
diff --git a/src/metadata/libexif_handler.cc b/src/metadata/libexif_handler.cc
index c3094f9..be56545 100644
--- a/src/metadata/libexif_handler.cc
+++ b/src/metadata/libexif_handler.cc
@@ -30,10 +30,6 @@
 /// \file libexif_handler.cc
 /// \brief Implementeation of the LibExifHandler class.
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_LIBEXIF
 
 #include "libexif_handler.h"
@@ -261,17 +257,9 @@ static int getTagFromString(String tag)
     return -1;
 }
 
-
-
-#ifdef EXIF_EGV_1
-    #define exif_egv(arg) exif_entry_get_value(arg)
-#endif
-
-#ifdef EXIF_EGV_3
-    #define BUFLEN  4096
-    char exif_entry_buffer[BUFLEN];
-    #define exif_egv(arg) exif_entry_get_value(arg, exif_entry_buffer, BUFLEN)
-#endif
+#define BUFLEN  4096
+char exif_entry_buffer[BUFLEN];
+#define exif_egv(arg) exif_entry_get_value(arg, exif_entry_buffer, BUFLEN)
 
 void LibExifHandler::process_ifd (ExifContent *content, Ref<CdsItem> item, Ref<StringConverter> sc, Ref<Array<StringBase> > auxtags)
 {
@@ -341,7 +329,7 @@ void LibExifHandler::process_ifd (ExifContent *content, Ref<CdsItem> item, Ref<S
         }
 
         // if there are any auxilary tags that the user wants - add them
-        if (auxtags != nil)
+        if (auxtags != nullptr)
         {
             for (int j = 0; j < auxtags->size(); j++)
             {
@@ -417,7 +405,7 @@ void LibExifHandler::fillMetadata(Ref<CdsItem> item)
             resource->addParameter(_(RESOURCE_CONTENT_TYPE), _(EXIF_THUMBNAIL));
             item->addResource(resource);
         }
-        catch (Exception e)
+        catch (const Exception & e)
         {
             e.printStackTrace();
         }
diff --git a/src/metadata/libmp4v2_handler.cc b/src/metadata/libmp4v2_handler.cc
deleted file mode 100644
index 40b0830..0000000
--- a/src/metadata/libmp4v2_handler.cc
+++ /dev/null
@@ -1,274 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    libmp4v2_handler.cc - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file libmp4v2_handler.cc
-/// \brief Implementeation of the LibMP4V2Handler class.
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#ifdef HAVE_LIBMP4V2
-
-#include "libmp4v2_handler.h"
-#include "string_converter.h"
-#include "common.h"
-#include "tools.h"
-#include "mem_io_handler.h"
-#include "content_manager.h"
-#include "config_manager.h"
-
-// why does crap like that alsways happens with some Ubuntu package?
-#undef PACKAGE
-#undef PACKAGE_BUGREPORT
-#undef PACKAGE_NAME
-#undef PACKAGE_STRING
-#undef PACKAGE_TARNAME
-#undef VERSION
-#undef TRUE
-#undef FALSE
-
-#include LIBMP4V2_INCLUDE
-
-using namespace zmm;
-
-LibMP4V2Handler::LibMP4V2Handler() : MetadataHandler()
-{
-}
-
-static void addMetaField(metadata_fields_t field, MP4FileHandle mp4, Ref<CdsItem> item)
-{
-    String value;
-    char*  mp4_retval = NULL;
-    u_int16_t track;
-    u_int16_t total_tracks;
- 
-    Ref<StringConverter> sc = StringConverter::i2i();
-    
-    switch (field)
-    {
-        case M_TITLE:
-            MP4GetMetadataName(mp4, &mp4_retval);
-            break;
-        case M_ARTIST:
-            MP4GetMetadataArtist(mp4, &mp4_retval);
-            break;
-        case M_ALBUM:
-            MP4GetMetadataAlbum(mp4, &mp4_retval);
-            break;
-        case M_DATE:
-            MP4GetMetadataYear(mp4, &mp4_retval);
-            if (mp4_retval)
-            {
-                value = mp4_retval;
-                free(mp4_retval);
-                if (string_ok(value))
-                    value = value + "-01-01";
-                else
-                    return;
-            }
-            break;
-        case M_GENRE:
-            MP4GetMetadataGenre(mp4, &mp4_retval);
-            break;
-        case M_DESCRIPTION:
-            MP4GetMetadataComment(mp4, &mp4_retval);
-            break;
-        case M_TRACKNUMBER:
-            MP4GetMetadataTrack(mp4, &track, &total_tracks);
-            if (track > 0)
-            {
-                value = String::from(track);
-                item->setTrackNumber((int)track);
-            }
-            else
-                return;
-            break;
-        default:
-            return;
-    }
-
-    if ((field != M_DATE) && (field != M_TRACKNUMBER) && 
-        (mp4_retval))
-    {
-        value = mp4_retval;
-        free(mp4_retval);
-    }
-    
-    value = trim_string(value);
-    
-    if (string_ok(value))
-    {
-        item->setMetadata(MT_KEYS[field].upnp, sc->convert(value));
-        log_debug("mp4 handler: setting metadata on item: %d, %s\n", field, sc->convert(value).c_str());
-    }
-}
-
-void LibMP4V2Handler::fillMetadata(Ref<CdsItem> item)
-{
-    MP4FileHandle mp4;
-
-    // the location has already been checked by the setMetadata function
-    mp4 = MP4Read(item->getLocation().c_str()); 
-    if (mp4 == MP4_INVALID_FILE_HANDLE)
-    {
-        log_error("Skipping metadata extraction for file %s\n", 
-                  item->getLocation().c_str());
-        return;
-    }
-
-    try
-    {
-        for (int i = 0; i < M_MAX; i++)
-            addMetaField((metadata_fields_t) i, mp4, item);
-
-        Ref<ConfigManager> cm = ConfigManager::getInstance();
-
-        //  MP4GetTimeScale returns the time scale in units of ticks per 
-        //  second for the mp4 file. Caveat: tracks may use the same time 
-        //  scale as  the  movie or may use their own time scale.
-        u_int32_t timescale = MP4GetTimeScale(mp4);
-        //  MP4GetDuration  returns the maximum duration of all the tracks in 
-        //  the specified mp4 file.
-        //
-        //  Caveat: the duration is the movie (file) time scale units.
-        MP4Duration duration = MP4GetDuration(mp4);
-
-        duration = duration / timescale;
-        if (duration > 0)
-            item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_DURATION),
-                    secondsToHMS(duration));
- 
-
-        MP4TrackId tid = MP4FindTrackId(mp4, 0, MP4_AUDIO_TRACK_TYPE);
-        if (tid != MP4_INVALID_TRACK_ID)
-        {
-#ifdef HAVE_MP4_GET_TRACK_AUDIO_CHANNELS
-            int temp = MP4GetTrackAudioChannels(mp4, tid);
-            if (temp > 0)
-            {
-                item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_NRAUDIOCHANNELS), String::from(temp));
-
-                timescale =  MP4GetTrackTimeScale(mp4, tid);
-                if (timescale > 0)
-                    item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_SAMPLEFREQUENCY), String::from((unsigned int)timescale));
-            }
-#endif
-            // note: UPnP requres bytes/second
-            timescale = MP4GetTrackBitRate(mp4, tid);
-            if (timescale > 0)
-            {
-                timescale = timescale / 8;
-                item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_BITRATE), String::from(timescale));
-            }
-        }
-
-#if defined(HAVE_MAGIC)
-        u_int8_t *art_data;
-        u_int32_t art_data_len;
-        String art_mimetype;
-#ifdef HAVE_MP4_GET_METADATA_COVER_ART_COUNT
-        if (MP4GetMetadataCoverArtCount(mp4) && 
-            MP4GetMetadataCoverArt(mp4, &art_data, &art_data_len))
-#else
-            MP4GetMetadataCoverArt(mp4, &art_data, &art_data_len);
-#endif
-        {
-            if (art_data)
-            {
-                try
-                {
-                    art_mimetype = ContentManager::getInstance()->getMimeTypeFromBuffer((void *)art_data, art_data_len);
-                    if (!string_ok(art_mimetype))
-                        art_mimetype = _(MIMETYPE_DEFAULT);
-
-                }
-                catch (Exception ex)
-                {
-                    free(art_data);
-                    throw ex;
-                }
-
-                free(art_data);
-                if (art_mimetype != _(MIMETYPE_DEFAULT))
-                {
-                    Ref<CdsResource> resource(new CdsResource(CH_MP4));
-                    resource->addAttribute(MetadataHandler::getResAttrName(R_PROTOCOLINFO), renderProtocolInfo(art_mimetype));
-                    resource->addParameter(_(RESOURCE_CONTENT_TYPE), _(ID3_ALBUM_ART));
-                    item->addResource(resource);
-                }
-            }
-        }
-#endif
-        MP4Close(mp4);
-    }
-    catch (Exception ex)
-    {
-        MP4Close(mp4);
-        throw ex;
-    }
-}
-
-Ref<IOHandler> LibMP4V2Handler::serveContent(Ref<CdsItem> item, int resNum, off_t *data_size)
-{
-    MP4FileHandle mp4 = MP4Read(item->getLocation().c_str());
-    if (mp4 == MP4_INVALID_FILE_HANDLE)
-    {
-        throw _Exception(_("LibMP4V2Handler: could not open file: ") + item->getLocation());
-    }
-
-    Ref<CdsResource> res = item->getResource(resNum);
-
-    String ctype = res->getParameters()->get(_(RESOURCE_CONTENT_TYPE));
-
-    if (ctype != ID3_ALBUM_ART)
-        throw _Exception(_("LibMP4V2Handler: got unknown content type: ") + ctype);
-#ifdef HAVE_MP4_GET_METADATA_COVER_ART_COUNT
-    if (!MP4GetMetadataCoverArtCount(mp4))
-        throw _Exception(_("LibMP4V2Handler: resource has no album art information"));
-#endif
-    u_int8_t *art_data;
-    u_int32_t art_data_len;
-    if (MP4GetMetadataCoverArt(mp4, &art_data, &art_data_len))
-    {
-        if (art_data)
-        {
-            *data_size = (off_t)art_data_len;
-            Ref<IOHandler> h(new MemIOHandler((void *)art_data, art_data_len));
-            free(art_data);
-            return h;
-        }
-    }
-        
-    throw _Exception(_("LibMP4V2Handler: could not serve album art "
-                           "for file") + item->getLocation() + 
-                           " - embedded image not found");
-}
-
-#endif // HAVE_LIBMP4V2
diff --git a/src/metadata/taglib_handler.cc b/src/metadata/taglib_handler.cc
index 976958d..3788245 100644
--- a/src/metadata/taglib_handler.cc
+++ b/src/metadata/taglib_handler.cc
@@ -30,273 +30,531 @@
 /// \file taglib_handler.cc
 /// \brief Implementeation of the TagHandler class.
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_TAGLIB
 
-#include <taglib.h>
-#include <fileref.h>
-#include <tag.h>
-#include <id3v2tag.h>
-#include <mpegfile.h>
-#include <audioproperties.h>
-#include <attachedpictureframe.h>
-#include <textidentificationframe.h>
-#include <tstring.h>
 
-#include "taglib_handler.h"
-#include "string_converter.h"
+#include <taglib/attachedpictureframe.h>
+#include <taglib/aifffile.h>
+#include <taglib/apefile.h>
+#include <taglib/asffile.h>
+#include <taglib/flacfile.h>
+#include <taglib/tfilestream.h>
+#include <taglib/tiostream.h>
+#include <taglib/id3v2tag.h>
+#include <taglib/mp4file.h>
+#include <taglib/mpegfile.h>
+#include <taglib/textidentificationframe.h>
+#include <taglib/vorbisfile.h>
+#include <taglib/wavpackfile.h>
+
 #include "config_manager.h"
-#include "common.h"
-#include "tools.h"
 #include "mem_io_handler.h"
+#include "string_converter.h"
+#include "taglib_handler.h"
 
 #include "content_manager.h"
 
 using namespace zmm;
 
-TagHandler::TagHandler() : MetadataHandler()
+TagLibHandler::TagLibHandler() : MetadataHandler()
 {
 }
-       
-static void addField(metadata_fields_t field, TagLib::Tag *tag, Ref<CdsItem> item)
+
+static void addField(metadata_fields_t field, const TagLib::Tag* tag, Ref<CdsItem> item)
 {
-    TagLib::String val;
-    String value;
-    unsigned int i;
-    
-    if (tag == NULL) 
+    if (tag == nullptr)
         return;
 
     if (tag->isEmpty())
         return;
 
     Ref<StringConverter> sc = StringConverter::i2i(); // sure is sure
-    
-    switch (field)
-    {
-        case M_TITLE:
-            val = tag->title();
-            break;
-        case M_ARTIST:
-            val = tag->artist();
-            break;
-        case M_ALBUM:
-            val = tag->album();
-            break;
-        case M_DATE:
-            i = tag->year();
-            if (i > 0)
-            {
-                value = String::from(i);
-
-                if (string_ok(value))
-                    value = value + _("-01-01");
-            }
-            else
-                return;
-            break;
-        case M_GENRE:
-            val = tag->genre();
-            break;
-        case M_DESCRIPTION:
-            val = tag->comment();
-            break;
-        case M_TRACKNUMBER:
-            i = tag->track();
-            if (i > 0)
-            {
-                value = String::from(i);
-                item->setTrackNumber((int)i);
-            }
-            else
-                return;
-            break;
-        default:
+
+    TagLib::String val;
+    String value;
+    unsigned int i;
+
+    switch (field) {
+    case M_TITLE:
+        val = tag->title();
+        break;
+    case M_ARTIST:
+        val = tag->artist();
+        break;
+    case M_ALBUM:
+        val = tag->album();
+        break;
+    case M_DATE:
+        i = tag->year();
+        if (i > 0) {
+            value = String::from(i);
+
+            if (string_ok(value))
+                value = value + _("-01-01");
+        } else
+            return;
+        break;
+    case M_GENRE:
+        val = tag->genre();
+        break;
+    case M_DESCRIPTION:
+        val = tag->comment();
+        break;
+    case M_TRACKNUMBER:
+        i = tag->track();
+        if (i > 0) {
+            value = String::from(i);
+            item->setTrackNumber((int)i);
+        } else
             return;
+        break;
+    default:
+        return;
     }
 
     if ((field != M_DATE) && (field != M_TRACKNUMBER))
         value = val.toCString(true);
 
     value = trim_string(value);
-    
-    if (string_ok(value))
-    {
+
+    if (string_ok(value)) {
         item->setMetadata(MT_KEYS[field].upnp, sc->convert(value));
-//        log_debug("Setting metadata on item: %d, %s\n", field, sc->convert(value).c_str());
+        //        log_debug("Setting metadata on item: %d, %s\n", field, sc->convert(value).c_str());
     }
 }
 
-void TagHandler::fillMetadata(Ref<CdsItem> item)
+void TagLibHandler::populateGenericTags(Ref<CdsItem> item, const TagLib::File& file) const
 {
-    Ref<Array<StringBase> > aux;
-    Ref<StringConverter> sc = StringConverter::i2i();
-
-    TagLib::FileRef f(item->getLocation().c_str());
-
-    if (f.isNull() || (!f.tag()))
+    if (!file.tag())
         return;
 
-
-    TagLib::Tag *tag = f.tag();
+    const TagLib::Tag* tag = file.tag();
 
     for (int i = 0; i < M_MAX; i++)
-        addField((metadata_fields_t) i, tag, item);
+        addField((metadata_fields_t)i, tag, item);
 
     int temp;
-    
-    TagLib::AudioProperties *audioProps = f.audioProperties();
-    
-    if (audioProps == NULL) 
+
+    const TagLib::AudioProperties* audioProps = file.audioProperties();
+
+    if (!audioProps)
         return;
-    
+
     // note: UPnP requres bytes/second
     temp = audioProps->bitrate() * 1024 / 8;
 
-    if (temp > 0)
-    {
-        item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_BITRATE),
-                                           String::from(temp)); 
+    Ref<CdsResource> res = item->getResource(0);
+
+    if (temp > 0) {
+        res->addAttribute(MetadataHandler::getResAttrName(R_BITRATE),
+            String::from(temp));
     }
 
     temp = audioProps->length();
-    if (temp > 0)
-    {
-        item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_DURATION),
-                                           secondsToHMS(temp));
+    if (temp > 0) {
+        res->addAttribute(MetadataHandler::getResAttrName(R_DURATION),
+            secondsToHMS(temp));
     }
 
     temp = audioProps->sampleRate();
-    if (temp > 0)
-    {
-        item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_SAMPLEFREQUENCY), 
-                                           String::from(temp));
+    if (temp > 0) {
+        res->addAttribute(MetadataHandler::getResAttrName(R_SAMPLEFREQUENCY),
+            String::from(temp));
     }
 
     temp = audioProps->channels();
+    if (temp > 0) {
+        res->addAttribute(MetadataHandler::getResAttrName(R_NRAUDIOCHANNELS),
+            String::from(temp));
+    }
+}
+
+void TagLibHandler::fillMetadata(Ref<CdsItem> item)
+{
+    Ref<Dictionary> mappings = ConfigManager::getInstance()->getDictionaryOption(CFG_IMPORT_MAPPINGS_MIMETYPE_TO_CONTENTTYPE_LIST);
+    String content_type = mappings->get(item->getMimeType());
 
-    if (temp > 0)
-    {
-        item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_NRAUDIOCHANNELS),
-                                           String::from(temp));
+    TagLib::FileStream fs(item->getLocation().c_str(), true); // true = Read only
+
+    if (content_type == CONTENT_TYPE_MP3) {
+        extractMP3(&fs, item);
+    } else if (content_type == CONTENT_TYPE_FLAC) {
+       extractFLAC(&fs, item);
+    } else if (content_type == CONTENT_TYPE_MP4) {
+        extractMP4(&fs, item);
+    } else if (content_type == CONTENT_TYPE_OGG) {
+        extractOgg(&fs, item);
+    } else if (content_type == CONTENT_TYPE_APE) {
+        extractAPE(&fs, item);
+    } else if (content_type == CONTENT_TYPE_WMA) {
+        extractASF(&fs, item);
+    } else if (content_type == CONTENT_TYPE_WAVPACK) {
+        extractWavPack(&fs, item);
+    } else if (content_type == CONTENT_TYPE_AIFF) {
+        extractAiff(&fs, item);
+    } else {
+        log_warning("TagLibHandler does not handle the %s content type\n", content_type.c_str());
     }
+    log_debug("TagLib handler done.\n");
+}
+
+bool TagLibHandler::isValidArtworkContentType(zmm::String art_mimetype)
+{
+    // saw that simply "PNG" was used with some mp3's, so mimetype setting
+    // was probably invalid
+    return (string_ok(art_mimetype) && (art_mimetype.index('/') != -1));
+}
 
+String TagLibHandler::getContentTypeFromByteVector(const TagLib::ByteVector& data) const
+{
+    String art_mimetype = _(MIMETYPE_DEFAULT);
+#ifdef HAVE_MAGIC
+    art_mimetype = ContentManager::getInstance()->getMimeTypeFromBuffer(data.data(), data.size());
+    if (!string_ok(art_mimetype))
+        return _(MIMETYPE_DEFAULT);
+#endif
+    return art_mimetype;
+}
+
+void TagLibHandler::addArtworkResource(Ref<CdsItem> item, String art_mimetype)
+{
+    // if we could not determine the mimetype, then there is no
+    // point to add the resource - it's probably garbage
+    log_debug("Found artwork of type %s in file %s\n", art_mimetype.c_str(), item->getLocation().c_str());
+
+    if (art_mimetype != _(MIMETYPE_DEFAULT)) {
+        Ref<CdsResource> resource(new CdsResource(CH_ID3));
+        resource->addAttribute(MetadataHandler::getResAttrName(
+                                   R_PROTOCOLINFO),
+            renderProtocolInfo(art_mimetype));
+        resource->addParameter(_(RESOURCE_CONTENT_TYPE),
+            _(ID3_ALBUM_ART));
+        item->addResource(resource);
+    }
+}
+
+Ref<IOHandler> TagLibHandler::serveContent(IN Ref<CdsItem> item, IN int resNum, OUT off_t* data_size)
+{
     Ref<Dictionary> mappings = ConfigManager::getInstance()->getDictionaryOption(CFG_IMPORT_MAPPINGS_MIMETYPE_TO_CONTENTTYPE_LIST);
     String content_type = mappings->get(item->getMimeType());
-    // we are done here, album art can only be retrieved from id3v2
-    if (content_type != CONTENT_TYPE_MP3)
-        return;
 
-    // did not yet found a way on how to get to the picture from the file
-    // reference that we already have
-    TagLib::MPEG::File mp(item->getLocation().c_str());
+    TagLib::FileStream roStream(item->getLocation().c_str(), true); // Open read only
+
+    if (content_type == CONTENT_TYPE_MP3) {
+
+        TagLib::MPEG::File f(&roStream, TagLib::ID3v2::FrameFactory::instance());
+
+        if (!f.isValid())
+            throw _Exception(_("TagLibHandler: could not open file: ") + item->getLocation());
+
+        if (!f.ID3v2Tag())
+            throw _Exception(_("TagLibHandler: resource has no album information"));
+
+        TagLib::ID3v2::FrameList list = f.ID3v2Tag()->frameList("APIC");
+        if (list.isEmpty())
+            throw _Exception(_("TagLibHandler: resource has no album information"));
+
+        auto* art = static_cast<TagLib::ID3v2::AttachedPictureFrame*>(list.front());
+
+        Ref<IOHandler> h(new MemIOHandler((void*)art->picture().data(),
+            art->picture().size()));
+
+        *data_size = art->picture().size();
+        return h;
+
+    } else if (content_type == CONTENT_TYPE_FLAC) {
+        TagLib::FLAC::File f(&roStream, TagLib::ID3v2::FrameFactory::instance());
+
+        if (!f.isValid())
+            throw _Exception(_("TagLibHandler: could not open flac file: ") + item->getLocation());
+
+        if (f.pictureList().isEmpty())
+            throw _Exception(_("TagLibHandler: flac resource has no picture information"));
+
+        TagLib::FLAC::Picture* pic = f.pictureList().front();
+        const TagLib::ByteVector& data = pic->data();
+
+        Ref<IOHandler> h(new MemIOHandler(data.data(), data.size()));
+
+        *data_size = data.size();
+        return h;
+
+    } else if (content_type == CONTENT_TYPE_MP4) {
+        TagLib::MP4::File f(&roStream);
+
+        if (!f.isValid()) {
+            throw _Exception(_("TagLibHandler: could not open mp4 file: ") + item->getLocation());
+        }
+
+        if (!f.hasMP4Tag()) {
+            throw _Exception(_("TagLibHandler: mp4 resource has no tag information"));
+        }
+
+        String art_mimetype;
+
+        const TagLib::MP4::ItemListMap& itemsListMap = f.tag()->itemListMap();
+        const TagLib::MP4::Item& coverItem = itemsListMap["covr"];
+        const TagLib::MP4::CoverArtList& coverArtList = coverItem.toCoverArtList();
+        if (coverArtList.isEmpty()) {
+            throw _Exception(_("TagLibHandler: mp4 resource has no picture information"));
+        }
+
+        const TagLib::MP4::CoverArt& coverArt = coverArtList.front();
+        const TagLib::ByteVector& data = coverArt.data();
+
+        Ref<IOHandler> h(new MemIOHandler(data.data(), data.size()));
+
+        *data_size = data.size();
+        return h;
+    } else if (content_type == CONTENT_TYPE_WMA) {
+        TagLib::ASF::File f(&roStream);
+
+        if (!f.isValid())
+            throw _Exception(_("TagLibHandler: could not open flac file: ") + item->getLocation());
 
-    if (!mp.isValid() || !mp.ID3v2Tag())
+        const TagLib::ASF::AttributeListMap& attrListMap = f.tag()->attributeListMap();
+        if (!attrListMap.contains("WM/Picture"))
+            throw _Exception(_("TagLibHandler: wma file has no picture information"));
+
+        const TagLib::ASF::AttributeList& attrList = attrListMap["WM/Picture"];
+        if (attrList.isEmpty())
+            throw _Exception(_("TagLibHandler: wma list has no picture information"));
+
+        const TagLib::ASF::Picture& wmpic = attrList[0].toPicture();
+        if (!wmpic.isValid())
+            throw _Exception(_("TagLibHandler: wma pic not valid"));
+
+        const TagLib::ByteVector& data = wmpic.picture();
+
+        Ref<IOHandler> h(new MemIOHandler(data.data(), data.size()));
+        *data_size = data.size();
+        return h;
+    } else if (content_type == CONTENT_TYPE_OGG) {
+        TagLib::Ogg::Vorbis::File f(&roStream);
+
+        if (!f.isValid() || !f.tag())
+            throw _Exception(_("TagLibHandler: could not open vorbis file: ") + item->getLocation());
+
+        const TagLib::List<TagLib::FLAC::Picture *> picList = f.tag()->pictureList();
+        if (picList.isEmpty())
+            throw _Exception(_("TagLibHandler: vorbis file has no picture information"));
+
+        const TagLib::FLAC::Picture *pic = picList.front();
+        const TagLib::ByteVector& data = pic->data();
+
+        Ref<IOHandler> h(new MemIOHandler(data.data(), data.size()));
+        *data_size = data.size();
+        return h;
+    }
+
+    throw _Exception(_("TagLibHandler: Unsupported content_type: ") + content_type);
+}
+
+void TagLibHandler::extractMP3(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item) {
+    TagLib::MPEG::File mp3(roStream, TagLib::ID3v2::FrameFactory::instance());
+
+    if (!mp3.isValid() || !mp3.hasID3v2Tag()) {
+        log_debug("TagLibHandler: could not open mp3 file: %s\n",
+                  item->getLocation().c_str());
         return;
+    }
+    populateGenericTags(item, mp3);
+
+    Ref<StringConverter> sc = StringConverter::i2i();
 
-    //log_debug("Tag contains %i frame(s)\n", mp.ID3v2Tag()->frameListMap().size());
-    Ref<ConfigManager> cm = ConfigManager::getInstance();
-    aux = cm->getStringArrayOption(CFG_IMPORT_LIBOPTS_ID3_AUXDATA_TAGS_LIST);
-    if (aux != nil) 
-    {
-        for (int j = 0; j < aux->size(); j++) 
-        {
-            String desiredFrame = aux->get(j);
-            if (string_ok(desiredFrame)) 
-            {
-                const TagLib::ID3v2::FrameList& allFrames = mp.ID3v2Tag()->frameList();
-                if (!allFrames.isEmpty()) 
-                {
-                    TagLib::ID3v2::FrameList::ConstIterator it = allFrames.begin();
-                    for (; it != allFrames.end(); it++) 
-                    {
-                        TagLib::String frameID((*it)->frameID(), TagLib::String::Latin1);
-                        //log_debug("Found frame: %s\n", frameID.toCString(true));
-
-                        TagLib::ID3v2::TextIdentificationFrame *textFrame =
-                            dynamic_cast<TagLib::ID3v2::TextIdentificationFrame *>(*it);
-
-                        if (textFrame) 
-                        {
-                            //log_debug("We have a TextIdentificationFrame\n");
-
-                            if (frameID == desiredFrame.c_str()) 
-                            {
-                                TagLib::String frameContents = textFrame->toString();
-                                //log_debug("We have a match!!!!: %s\n", frameContents.toCString(true));
-                                String value(frameContents.toCString(true), frameContents.size());
-                                value = sc->convert(value);
-                                log_debug("Adding frame: %s with value %s\n", desiredFrame.c_str(), value.c_str());
-                                item->setAuxData(desiredFrame, value);
-                            }
-                        }
-                    }
-                }
+    Ref<Array<StringBase> > aux_tags_list = ConfigManager::getInstance()->getStringArrayOption(CFG_IMPORT_LIBOPTS_ID3_AUXDATA_TAGS_LIST);
+    if (aux_tags_list != nullptr) {
+        for (int j = 0; j < aux_tags_list->size(); j++) {
+
+            String desiredFrame = aux_tags_list->get(j);
+            if (!string_ok(desiredFrame)) {
+                continue;
+            }
+
+            auto frameListMap = mp3.ID3v2Tag()->frameListMap();
+
+            if (frameListMap.contains(desiredFrame.c_str())) {
+                const auto frameList = frameListMap[desiredFrame.c_str()];
+                if (frameList.isEmpty())
+                    continue;
+
+                const TagLib::ID3v2::Frame *frame = frameList.front();
+                const auto textFrame = static_cast<const TagLib::ID3v2::TextIdentificationFrame*>(frame);
+
+                const TagLib::String frameContents = textFrame->toString();
+                String value(frameContents.toCString(true), frameContents.size());
+                value = sc->convert(value);
+                log_debug(
+                    "Adding frame: %s with value %s\n", desiredFrame.c_str(),
+                    value.c_str());
+                item->setAuxData(desiredFrame, value);
             }
         }
     }
 
-    TagLib::ID3v2::FrameList list = mp.ID3v2Tag()->frameList("APIC");
-    if (!list.isEmpty())
-    {
-        TagLib::ID3v2::AttachedPictureFrame *art =
-               static_cast<TagLib::ID3v2::AttachedPictureFrame *>(list.front());
-
-        if (art->picture().size() < 1)
-            return;
+    const TagLib::ID3v2::FrameList apicFrameList = mp3.ID3v2Tag()->frameList("APIC");
+    if (!apicFrameList.isEmpty()) {
+        auto art = static_cast<const TagLib::ID3v2::AttachedPictureFrame*>(apicFrameList.front());
 
+        const TagLib::ByteVector pic = art->picture();
         String art_mimetype = sc->convert(art->mimeType().toCString(true));
-        // saw that simply "PNG" was used with some mp3's, so mimetype setting
-        // was probably invalid
-        if (!string_ok(art_mimetype) || (art_mimetype.index('/') == -1))
-        {
-#ifdef HAVE_MAGIC
-            art_mimetype =  ContentManager::getInstance()->getMimeTypeFromBuffer((void *)art->picture().data(), art->picture().size());
-            if (!string_ok(art_mimetype))
-#endif
-            art_mimetype = _(MIMETYPE_DEFAULT);
+        if (!isValidArtworkContentType(art_mimetype)) {
+            art_mimetype = getContentTypeFromByteVector(pic);
         }
 
-        // if we could not determine the mimetype, then there is no
-        // point to add the resource - it's probably garbage
-        if (art_mimetype != _(MIMETYPE_DEFAULT))
-        {
-            Ref<CdsResource> resource(new CdsResource(CH_ID3));
-            resource->addAttribute(MetadataHandler::getResAttrName(R_PROTOCOLINFO), renderProtocolInfo(art_mimetype));
-            resource->addParameter(_(RESOURCE_CONTENT_TYPE), _(ID3_ALBUM_ART));
-            item->addResource(resource);
+        addArtworkResource(item, art_mimetype);
+    }
+}
+
+void TagLibHandler::extractOgg(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item) {
+    TagLib::Ogg::Vorbis::File vorbis(item->getLocation().c_str());
+
+    if (!vorbis.isValid()) {
+        log_debug("TagLibHandler: could not open ogg file: %s\n",
+                  item->getLocation().c_str());
+        return;
+    }
+    populateGenericTags(item, vorbis);
+
+    if (!vorbis.tag())
+        return;
+
+    // Vorbis uses the FLAC binary picture structure...
+    // https://wiki.xiph.org/VorbisComment#Cover_art
+    // The unofficial COVERART field is not supported.
+    const TagLib::List<TagLib::FLAC::Picture *> picList = vorbis.tag()->pictureList();
+    if (picList.isEmpty())
+        return;
+
+    const TagLib::FLAC::Picture *pic = picList.front();
+    const TagLib::ByteVector& data = pic->data();
+
+    Ref<StringConverter> sc = StringConverter::i2i();
+    String art_mimetype = sc->convert(pic->mimeType().toCString(true));
+    if (!isValidArtworkContentType(art_mimetype)) {
+        art_mimetype = getContentTypeFromByteVector(data);
+    }
+    addArtworkResource(item, art_mimetype);
+}
+
+void TagLibHandler::extractASF(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item) {
+    TagLib::ASF::File asf(roStream);
+
+    if (!asf.isValid()) {
+        log_debug("TagLibHandler: could not open asf/wma file: %s\n",
+                  item->getLocation().c_str());
+        return;
+    }
+    populateGenericTags(item, asf);
+
+    const TagLib::ASF::AttributeListMap& attrListMap = asf.tag()->attributeListMap();
+    if (attrListMap.contains("WM/Picture")) {
+        const TagLib::ASF::AttributeList& attrList = attrListMap["WM/Picture"];
+        if (attrList.isEmpty())
+            return;
+
+        const TagLib::ASF::Picture& wmpic = attrList[0].toPicture();
+        if (!wmpic.isValid())
+            return;
+
+        Ref<StringConverter> sc = StringConverter::i2i();
+        String art_mimetype = sc->convert(wmpic.mimeType().toCString(true));
+        if (!isValidArtworkContentType(art_mimetype)) {
+            art_mimetype = getContentTypeFromByteVector(wmpic.picture());
         }
+        addArtworkResource(item, art_mimetype);
     }
 }
 
-Ref<IOHandler> TagHandler::serveContent(Ref<CdsItem> item, int resNum, off_t *data_size)
-{
-    // we should only get mp3 files here
-    TagLib::MPEG::File f(item->getLocation().c_str());
+void TagLibHandler::extractFLAC(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item) {
+    TagLib::FLAC::File flac(roStream, TagLib::ID3v2::FrameFactory::instance());
 
-    if (!f.isValid())
-        throw _Exception(_("TagHandler: could not open file: ") + 
-                item->getLocation());
+    if (!flac.isValid()) {
+        log_debug("TagLibHandler: could not open flac file: %s\n",
+                  item->getLocation().c_str());
+        return;
+    }
+    populateGenericTags(item, flac);
 
+    if (flac.pictureList().isEmpty()) {
+        log_debug("TagLibHandler: flac resource has no picture information\n");
+        return;
+    }
+    const TagLib::FLAC::Picture *pic = flac.pictureList().front();
+    const TagLib::ByteVector& data = pic->data();
 
-    if (!f.ID3v2Tag())
-        throw _Exception(_("TagHandler: resource has no album information"));
+    Ref<StringConverter> sc = StringConverter::i2i();
+    String art_mimetype = sc->convert(pic->mimeType().toCString(true));
+    if (!isValidArtworkContentType(art_mimetype)) {
+        art_mimetype = getContentTypeFromByteVector(data);
+    }
+    addArtworkResource(item, art_mimetype);
+}
 
-    TagLib::ID3v2::FrameList list = f.ID3v2Tag()->frameList("APIC");
-    if (list.isEmpty())
-        throw _Exception(_("TagHandler: resource has no album information"));
+void TagLibHandler::extractAPE(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item) {
+    TagLib::APE::File ape(roStream);
 
-    TagLib::ID3v2::AttachedPictureFrame *art =
-        static_cast<TagLib::ID3v2::AttachedPictureFrame *>(list.front());
+    if (!ape.isValid()) {
+        log_debug("TagLibHandler: could not open APE file: %s\n",
+                  item->getLocation().c_str());
+        return;
+    }
+    populateGenericTags(item, ape);
+}
 
-    Ref<IOHandler> h(new MemIOHandler((void *)art->picture().data(), 
-                art->picture().size()));
+void TagLibHandler::extractWavPack(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item) {
+    TagLib::WavPack::File wavpack(roStream);
 
-    *data_size = art->picture().size();
-    return h;
+    if (!wavpack.isValid()) {
+        log_debug("TagLibHandler: could not open WavPack file: %s\n",
+                  item->getLocation().c_str());
+        return;
+    }
+    populateGenericTags(item, wavpack);
+}
+
+void TagLibHandler::extractMP4(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item) {
+    TagLib::MP4::File mp4(roStream);
+    populateGenericTags(item, mp4);
+
+    if (!mp4.isValid()) {
+        log_debug("TagLibHandler: could not open mp4 file: %s\n",
+                  item->getLocation().c_str());
+        return;
+    }
+
+    if (!mp4.hasMP4Tag()) {
+        log_debug("TagLibHandler: mp4 file has no tag information\n");
+        return;
+    }
+
+    String art_mimetype;
+
+    TagLib::MP4::ItemListMap itemsListMap = mp4.tag()->itemListMap();
+    TagLib::MP4::Item coverItem = itemsListMap["covr"];
+    TagLib::MP4::CoverArtList coverArtList = coverItem.toCoverArtList();
+    if (coverArtList.isEmpty()) {
+        log_debug("TagLibHandler: mp4 file has no coverart");
+        return;
+    }
+
+    TagLib::MP4::CoverArt coverArt = coverArtList.front();
+    TagLib::ByteVector data = coverArt.data();
+    art_mimetype = getContentTypeFromByteVector(data);
+
+    if (string_ok(art_mimetype))
+        addArtworkResource(item, art_mimetype);
+}
+
+void TagLibHandler::extractAiff(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item) {
+    TagLib::RIFF::AIFF::File aiff(roStream);
+
+    if (!aiff.isValid()) {
+        log_debug("TagLibHandler: could not open AIFF file: %s\n",
+                  item->getLocation().c_str());
+        return;
+    }
+    populateGenericTags(item, aiff);
 }
 
 #endif // HAVE_TAGLIB
diff --git a/src/metadata/taglib_handler.h b/src/metadata/taglib_handler.h
index 3e3fd97..ea520c5 100644
--- a/src/metadata/taglib_handler.h
+++ b/src/metadata/taglib_handler.h
@@ -33,15 +33,36 @@
 #ifndef __METADATA_TAGLIB_H__
 #define __METADATA_TAGLIB_H__
 
+#ifdef HAVE_TAGLIB
+
+#include <taglib/tbytevector.h>
+#include <taglib/tfile.h>
+#include <taglib/tiostream.h>
+
 #include "metadata_handler.h"
 
 /// \brief This class is responsible for reading id3 or ogg tags metadata
-class TagHandler : public MetadataHandler
+class TagLibHandler : public MetadataHandler
 {
 public:
-    TagHandler();
+    TagLibHandler();
     virtual void fillMetadata(zmm::Ref<CdsItem> item);
     virtual zmm::Ref<IOHandler> serveContent(zmm::Ref<CdsItem> item, int resNum, off_t *data_size);
+private:
+    void populateGenericTags(zmm::Ref<CdsItem> item, const TagLib::File& file) const;
+    bool isValidArtworkContentType(zmm::String content_type);
+    zmm::String getContentTypeFromByteVector(const TagLib::ByteVector& data) const;
+    void addArtworkResource(zmm::Ref<CdsItem> item, zmm::String content_type);
+    void extractMP3(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item);
+    void extractOgg(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item);
+    void extractASF(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item);
+    void extractFLAC(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item);
+    void extractAPE(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item);
+    void extractWavPack(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item);
+    void extractMP4(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item);
+    void extractAiff(TagLib::IOStream *roStream, zmm::Ref<CdsItem> item);
 };
 
+#endif
+
 #endif // __METADATA_TAGLIB_H__
diff --git a/src/metadata_handler.cc b/src/metadata_handler.cc
index ff75095..e8a0a10 100644
--- a/src/metadata_handler.cc
+++ b/src/metadata_handler.cc
@@ -30,12 +30,7 @@
 /// \file metadata_handler.cc
 /// \brief Implementeation of the MetadataHandler class.
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "metadata_handler.h"
-#include "string_converter.h"
 #include "tools.h"
 #include "config_manager.h"
 
@@ -45,20 +40,8 @@
 
 #ifdef HAVE_TAGLIB
 #include "metadata/taglib_handler.h"
-#else
-#ifdef HAVE_ID3LIB // we only want ID3 if taglib was not found
-#include "metadata/id3_handler.h"
-#endif // HAVE_ID3LIB
 #endif // HAVE_TAGLIB
 
-#ifdef HAVE_FLAC
-#include "metadata/flac_handler.h"
-#endif
-
-#ifdef HAVE_LIBMP4V2
-#include "metadata/libmp4v2_handler.h"
-#endif
-
 #ifdef HAVE_FFMPEG
 #include "metadata/ffmpeg_handler.h"
 #endif
@@ -67,9 +50,7 @@
 #include "metadata/libexif_handler.h"
 #endif
 
-#ifdef HAVE_LIBDVDNAV
-#include "metadata/dvd_handler.h"
-#endif
+#include "metadata/fanart_handler.h"
 
 using namespace zmm;
 
@@ -119,119 +100,72 @@ void MetadataHandler::setMetadata(Ref<CdsItem> item)
     String mimetype = item->getMimeType();
 
     Ref<CdsResource> resource(new CdsResource(CH_DEFAULT));
-    resource->addAttribute(getResAttrName(R_PROTOCOLINFO),
-                           renderProtocolInfo(mimetype));
-    resource->addAttribute(getResAttrName(R_SIZE),
-            String::from(filesize));
+    resource->addAttribute(getResAttrName(R_PROTOCOLINFO), renderProtocolInfo(mimetype));
+    resource->addAttribute(getResAttrName(R_SIZE), String::from(filesize));
     
     item->addResource(resource);
 
-    Ref<MetadataHandler> handler;
     Ref<Dictionary> mappings = ConfigManager::getInstance()->getDictionaryOption(CFG_IMPORT_MAPPINGS_MIMETYPE_TO_CONTENTTYPE_LIST);
-
     String content_type = mappings->get(mimetype);
    
     if ((content_type == CONTENT_TYPE_OGG) && (isTheora(item->getLocation())))
             item->setFlag(OBJECT_FLAG_OGG_THEORA);
 
-    do
-    {
 #ifdef HAVE_TAGLIB
-        if ((content_type == CONTENT_TYPE_MP3) || 
-           ((content_type == CONTENT_TYPE_OGG) && 
-            (!item->getFlag(OBJECT_FLAG_OGG_THEORA))) ||
-            (content_type == CONTENT_TYPE_WMA) ||
-            (content_type == CONTENT_TYPE_WAVPACK))
-        {
-            handler = Ref<MetadataHandler>(new TagHandler());
-            break;
-        }
-#else
-#ifdef HAVE_ID3LIB
-        if (content_type == CONTENT_TYPE_MP3)
-        {
-            handler = Ref<MetadataHandler>(new Id3Handler());
-            break;
-        }
-#endif // HAVE_ID3LIB
+    if ((content_type == CONTENT_TYPE_MP3) || 
+        ((content_type == CONTENT_TYPE_OGG) && (!item->getFlag(OBJECT_FLAG_OGG_THEORA))) ||
+        (content_type == CONTENT_TYPE_WMA) ||
+        (content_type == CONTENT_TYPE_WAVPACK) ||
+        (content_type == CONTENT_TYPE_FLAC) ||
+        (content_type == CONTENT_TYPE_PCM) ||
+        (content_type == CONTENT_TYPE_AIFF) ||
+        (content_type == CONTENT_TYPE_APE) ||
+        (content_type == CONTENT_TYPE_MP4))
+    {
+        TagLibHandler().fillMetadata(item);
+    }
 #endif // HAVE_TAGLIB
 
-#ifdef HAVE_FLAC
-        if (content_type == CONTENT_TYPE_FLAC)
-        {
-            handler = Ref<MetadataHandler>(new FlacHandler());
-            break;
-        }
-
-#endif
-
 #ifdef HAVE_EXIV2
 /*        
-          if (content_type == CONTENT_TYPE_JPG)
-          {
-          handler = Ref<MetadataHandler>(new Exiv2Handler());
-          break;
-          } 
+    if (content_type == CONTENT_TYPE_JPG)
+    {
+        handlers->append(Ref<MetadataHandler>(new Exiv2Handler()));
+    } 
 */
 #endif
 
 #ifdef HAVE_LIBEXIF
-        if (content_type == CONTENT_TYPE_JPG)
-        {
-            handler = Ref<MetadataHandler>(new LibExifHandler());
-            break;
-        }
+    if (content_type == CONTENT_TYPE_JPG)
+    {
+        LibExifHandler().fillMetadata(item);
+    }
 #endif // HAVE_LIBEXIF
 
-#if defined(HAVE_LIBMP4V2)
-#if !defined(HAVE_FFMPEG)
-        if (content_type == CONTENT_TYPE_MP4)
-#else // FFMPEG available 
-        if ((content_type == CONTENT_TYPE_MP4) && 
-            (!item->getMimeType().startsWith(_("video"))))
-#endif // !defined(HAVE_FFMPEG)            
-        {
-            handler = Ref<MetadataHandler>(new LibMP4V2Handler());
-            break;
-        }
-#endif // defined(HAVE_LIBMP4V2)
-
 #ifdef HAVE_FFMPEG
-        if (content_type != CONTENT_TYPE_PLAYLIST &&
-            ((content_type == CONTENT_TYPE_OGG &&
-             item->getFlag(OBJECT_FLAG_OGG_THEORA)) ||
-            item->getMimeType().startsWith(_("video")) ||
-            item->getMimeType().startsWith(_("audio"))))
-        {
-            handler = Ref<MetadataHandler>(new FfmpegHandler());
-            break;
-        }
+    if (content_type != CONTENT_TYPE_PLAYLIST &&
+        ((content_type == CONTENT_TYPE_OGG &&
+         item->getFlag(OBJECT_FLAG_OGG_THEORA)) ||
+        item->getMimeType().startsWith(_("video")) ||
+        item->getMimeType().startsWith(_("audio"))))
+    {
+        FfmpegHandler().fillMetadata(item);
+    }
 #else
-        if (content_type == CONTENT_TYPE_AVI)
+    if (content_type == CONTENT_TYPE_AVI)
+    {
+        String fourcc = getAVIFourCC(item->getLocation());
+        if (string_ok(fourcc))
         {
-            String fourcc = getAVIFourCC(item->getLocation());
-            if (string_ok(fourcc))
-            {
-                item->getResource(0)->addOption(_(RESOURCE_OPTION_FOURCC),
-                                                fourcc);
-            }
+            item->getResource(0)->addOption(_(RESOURCE_OPTION_FOURCC),
+                                            fourcc);
         }
+    }
 
 #endif // HAVE_FFMPEG
 
-#ifdef HAVE_LIBDVDNAV
-        if (content_type == CONTENT_TYPE_DVD)
-        {
-            handler = Ref<MetadataHandler>(new DVDHandler());
-            break;
-        }
-#endif
-    }
-    while (false);
-
-    if (handler == nil)
-        return;
-    handler->fillMetadata(item);
+    // Fanart for all things!
+    FanArtHandler().fillMetadata(item);
 }
 
 String MetadataHandler::getMetaFieldName(metadata_fields_t field)
@@ -252,25 +186,16 @@ Ref<MetadataHandler> MetadataHandler::createHandler(int handlerType)
         case CH_LIBEXIF:
             return Ref<MetadataHandler>(new LibExifHandler());
 #endif
-#ifdef HAVE_ID3LIB
-        case CH_ID3:
-            return Ref<MetadataHandler>(new Id3Handler());
-#elif HAVE_TAGLIB
+#ifdef HAVE_TAGLIB
         case CH_ID3:
-            return Ref<MetadataHandler>(new TagHandler());
-#endif
-#ifdef HAVE_LIBMP4V2
-        case CH_MP4:
-            return Ref<MetadataHandler>(new LibMP4V2Handler());
+            return Ref<MetadataHandler>(new TagLibHandler());
 #endif
 #if defined(HAVE_FFMPEG) && defined(HAVE_FFMPEGTHUMBNAILER)
         case CH_FFTH:
             return Ref<MetadataHandler>(new FfmpegHandler());
 #endif
-#ifdef HAVE_FLAC
-        case CH_FLAC:
-            return Ref<MetadataHandler>(new FlacHandler());
-#endif
+        case CH_FANART:
+            return Ref<MetadataHandler>(new FanArtHandler());
         default:
             throw _Exception(_("unknown content handler ID: ") + handlerType);
     }
diff --git a/src/metadata_handler.h b/src/metadata_handler.h
index 2031ac8..7c9e4ee 100644
--- a/src/metadata_handler.h
+++ b/src/metadata_handler.h
@@ -46,20 +46,24 @@
 #define CH_MP4       5
 #define CH_FFTH      6
 #define CH_FLAC      7
+#define CH_FANART    8
 
 #define CONTENT_TYPE_MP3        "mp3"
 #define CONTENT_TYPE_OGG        "ogg"
 #define CONTENT_TYPE_FLAC       "flac"
 #define CONTENT_TYPE_WMA        "wma"
 #define CONTENT_TYPE_WAVPACK    "wv"
+#define CONTENT_TYPE_APE        "ape"
 #define CONTENT_TYPE_JPG        "jpg"
 #define CONTENT_TYPE_PLAYLIST   "playlist"
 #define CONTENT_TYPE_MP4        "mp4"
 #define CONTENT_TYPE_PCM        "pcm"
 #define CONTENT_TYPE_AVI        "avi"
 #define CONTENT_TYPE_MPEG       "mpeg"
-#define CONTENT_TYPE_DVD        "dvd"
 #define CONTENT_TYPE_QUICKTIME  "quicktime"
+#define CONTENT_TYPE_MKV        "mkv"
+#define CONTENT_TYPE_MKA        "mka"
+#define CONTENT_TYPE_AIFF       "aiff"
 
 #define OGG_THEORA              "t"
 
diff --git a/src/mpegdemux/buffer.c b/src/mpegdemux/buffer.c
deleted file mode 100644
index edfe4d9..0000000
--- a/src/mpegdemux/buffer.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*****************************************************************************
- * mpegdemux                                                                 *
- *****************************************************************************/
-
-/*****************************************************************************
- * File name:     buffer.c                                                   *
- * Created:       2003-04-08 by Hampa Hug <hampa at hampa.ch>                   *
- * Last modified: 2003-04-08 by Hampa Hug <hampa at hampa.ch>                   *
- * Copyright:     (C) 2003 by Hampa Hug <hampa at hampa.ch>                     *
- *****************************************************************************/
-
-/*****************************************************************************
- * This program is free software. You can redistribute it and / or modify it *
- * under the terms of the GNU General Public License version 2 as  published *
- * by the Free Software Foundation.                                          *
- *                                                                           *
- * This program is distributed in the hope  that  it  will  be  useful,  but *
- * WITHOUT  ANY   WARRANTY,   without   even   the   implied   warranty   of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  General *
- * Public License for more details.                                          *
- *****************************************************************************/
-
-/* $Id: buffer.c 67 2004-01-02 18:20:15Z hampa $ */
-
-// The code has been modified to use file descriptors instead of FILE streams.
-// Only functionality needed in MediaTomb remains, all extra features are
-// stripped out.
-
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#ifdef HAVE_LIBDVDNAV
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "buffer.h"
-
-
-void mpeg_buf_init (mpeg_buffer_t *buf)
-{
-  buf->buf = NULL;
-  buf->max = 0;
-  buf->cnt = 0;
-}
-
-void mpeg_buf_free (mpeg_buffer_t *buf)
-{
-  free (buf->buf);
-
-  buf->buf = NULL;
-  buf->cnt = 0;
-  buf->max = 0;
-}
-
-void mpeg_buf_clear (mpeg_buffer_t *buf)
-{
-  buf->cnt = 0;
-}
-
-int mpeg_buf_set_max (mpeg_buffer_t *buf, unsigned max)
-{
-  if (buf->max == max) {
-    return (0);
-  }
-
-  if (max == 0) {
-    free (buf->buf);
-    buf->max = 0;
-    buf->cnt = 0;
-    return (0);
-  }
-
-  buf->buf = (unsigned char *) realloc (buf->buf, max);
-  if (buf->buf == NULL) {
-    buf->max = 0;
-    buf->cnt = 0;
-    return (1);
-  }
-
-  buf->max = max;
-
-  if (buf->cnt > max) {
-    buf->cnt = max;
-  }
-
-  return (0);
-}
-
-int mpeg_buf_set_cnt (mpeg_buffer_t *buf, unsigned cnt)
-{
-  if (cnt > buf->max) {
-    if (mpeg_buf_set_max (buf, cnt)) {
-      return (1);
-    }
-  }
-
-  buf->cnt = cnt;
-
-  return (0);
-}
-
-int mpeg_buf_read (mpeg_buffer_t *buf, mpeg_demux_t *mpeg, unsigned cnt)
-{
-  if (mpeg_buf_set_cnt (buf, cnt)) {
-    return (1);
-  }
-
-  buf->cnt = mpegd_read (mpeg, buf->buf, cnt);
-
-  if (buf->cnt != cnt) {
-    return (1);
-  }
-
-  return (0);
-}
-
-int mpeg_buf_write (mpeg_buffer_t *buf, int fd)
-{
-  if (buf->cnt > 0) {
-    if (write (fd, buf->buf, buf->cnt) != buf->cnt) {
-      return (1);
-    }
-  }
-
-  return (0);
-}
-
-int mpeg_buf_write_clear (mpeg_buffer_t *buf, int fd)
-{
-  if (buf->cnt > 0) {
-    if (write (fd, buf->buf, buf->cnt) != buf->cnt) {
-      buf->cnt = 0;
-      return (1);
-    }
-  }
-
-  buf->cnt = 0;
-
-  return (0);
-}
-
-#endif//HAVE_LIBDVDNAV
diff --git a/src/mpegdemux/buffer.h b/src/mpegdemux/buffer.h
deleted file mode 100644
index 78951a5..0000000
--- a/src/mpegdemux/buffer.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*****************************************************************************
- * mpegdemux                                                                 *
- *****************************************************************************/
-
-/*****************************************************************************
- * File name:     buffer.h                                                   *
- * Created:       2003-04-08 by Hampa Hug <hampa at hampa.ch>                   *
- * Last modified: 2003-04-08 by Hampa Hug <hampa at hampa.ch>                   *
- * Copyright:     (C) 2003 by Hampa Hug <hampa at hampa.ch>                     *
- *****************************************************************************/
-
-/*****************************************************************************
- * This program is free software. You can redistribute it and / or modify it *
- * under the terms of the GNU General Public License version 2 as  published *
- * by the Free Software Foundation.                                          *
- *                                                                           *
- * This program is distributed in the hope  that  it  will  be  useful,  but *
- * WITHOUT  ANY   WARRANTY,   without   even   the   implied   warranty   of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  General *
- * Public License for more details.                                          *
- *****************************************************************************/
-
-/* $Id: buffer.h 67 2004-01-02 18:20:15Z hampa $ */
-
-// The code has been modified to use file descriptors instead of FILE streams.
-// Only functionality needed in MediaTomb remains, all extra features are
-// stripped out.
-
-#ifndef MPEGDEMUX_BUFFER_H
-#define MPEGDEMUX_BUFFER_H 1
-
-
-#include "mpeg_parse.h"
-
-
-typedef struct {
-  unsigned char *buf;
-  unsigned      cnt;
-  unsigned      max;
-} mpeg_buffer_t;
-
-
-
-void mpeg_buf_init (mpeg_buffer_t *buf);
-void mpeg_buf_free (mpeg_buffer_t *buf);
-void mpeg_buf_clear (mpeg_buffer_t *buf);
-int mpeg_buf_set_max (mpeg_buffer_t *buf, unsigned max);
-int mpeg_buf_set_cnt (mpeg_buffer_t *buf, unsigned cnt);
-int mpeg_buf_read (mpeg_buffer_t *buf, mpeg_demux_t *mpeg, unsigned cnt);
-int mpeg_buf_write (mpeg_buffer_t *buf, int fd);
-int mpeg_buf_write_clear (mpeg_buffer_t *buf, int fd);
-
-
-#endif
diff --git a/src/mpegdemux/mpeg_parse.c b/src/mpegdemux/mpeg_parse.c
deleted file mode 100644
index c7774fc..0000000
--- a/src/mpegdemux/mpeg_parse.c
+++ /dev/null
@@ -1,645 +0,0 @@
-/*****************************************************************************
- * mpegdemux                                                                 *
- *****************************************************************************/
-
-/*****************************************************************************
- * File name:     mpeg_parse.c                                               *
- * Created:       2003-02-01 by Hampa Hug <hampa at hampa.ch>                   *
- * Last modified: 2003-09-10 by Hampa Hug <hampa at hampa.ch>                   *
- * Copyright:     (C) 2003 by Hampa Hug <hampa at hampa.ch>                     *
- *****************************************************************************/
-
-/*****************************************************************************
- * This program is free software. You can redistribute it and / or modify it *
- * under the terms of the GNU General Public License version 2 as  published *
- * by the Free Software Foundation.                                          *
- *                                                                           *
- * This program is distributed in the hope  that  it  will  be  useful,  but *
- * WITHOUT  ANY   WARRANTY,   without   even   the   implied   warranty   of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  General *
- * Public License for more details.                                          *
- *****************************************************************************/
-
-/* $Id: mpeg_parse.c 67 2004-01-02 18:20:15Z hampa $ */
-
-// The code has been modified to use file descriptors instead of FILE streams.
-// Only functionality needed in MediaTomb remains, all extra features are
-// stripped out.
-
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#ifdef HAVE_LIBDVDNAV
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "mpeg_parse.h"
-
-
-mpeg_demux_t *mpegd_open_fd (mpeg_demux_t *mpeg, int fd, int close_file)
-{
-  if (mpeg == NULL) {
-    mpeg = (mpeg_demux_t *) malloc (sizeof (mpeg_demux_t));
-    if (mpeg == NULL) {
-      return (NULL);
-    }
-    mpeg->free = 1;
-  }
-  else {
-    mpeg->free = 0;
-  }
-
-  mpeg->fd = fd;
-  mpeg->close = close_file;
-
-  mpeg->ofs = 0;
-
-  mpeg->buf_i = 0;
-  mpeg->buf_n = 0;
-
-  mpeg->ext = -1;
-
-  mpeg->mpeg_skip = NULL;
-  mpeg->mpeg_system_header = NULL;
-  mpeg->mpeg_packet = NULL;
-  mpeg->mpeg_packet_check = NULL;
-  mpeg->mpeg_pack = NULL;
-  mpeg->mpeg_end = NULL;
-
-  mpegd_reset_stats (mpeg);
-
-  return (mpeg);
-}
-
-mpeg_demux_t *mpegd_open (mpeg_demux_t *mpeg, const char *fname)
-{
-  int fd;
-
-  fd = open (fname, O_RDONLY);
-  if (fd == -1) {
-    return (NULL);
-  }
-
-  mpeg = mpegd_open_fd (mpeg, fd, 1);
-
-  return (mpeg);
-}
-
-void mpegd_close (mpeg_demux_t *mpeg)
-{
-  if (mpeg->close) {
-    close (mpeg->fd);
-  }
-
-  if (mpeg->free) {
-    free (mpeg);
-  }
-}
-
-void mpegd_reset_stats (mpeg_demux_t *mpeg)
-{
-  unsigned i;
-
-  mpeg->shdr_cnt = 0;
-  mpeg->pack_cnt = 0;
-  mpeg->packet_cnt = 0;
-  mpeg->end_cnt = 0;
-  mpeg->skip_cnt = 0;
-
-  for (i = 0; i < 256; i++) {
-    mpeg->streams[i].packet_cnt = 0;
-    mpeg->streams[i].size = 0;
-    mpeg->substreams[i].packet_cnt = 0;
-    mpeg->substreams[i].size = 0;
-  }
-}
-
-static
-int mpegd_buffer_fill (mpeg_demux_t *mpeg)
-{
-  unsigned i, n;
-  size_t   r;
-
-  if ((mpeg->buf_i > 0) && (mpeg->buf_n > 0)) {
-    for (i = 0; i < mpeg->buf_n; i++) {
-      mpeg->buf[i] = mpeg->buf[mpeg->buf_i + i];
-    }
-  }
-
-  mpeg->buf_i = 0;
-
-  n = MPEG_DEMUX_BUFFER - mpeg->buf_n;
-
-  if (n > 0) {
-    r = read (mpeg->fd, mpeg->buf + mpeg->buf_n, n);
-    if (r < 0) {
-      return (1);
-    }
-
-    mpeg->buf_n += (unsigned) r;
-  }
-
-  return (0);
-}
-
-static
-int mpegd_need_bits (mpeg_demux_t *mpeg, unsigned n)
-{
-  n = (n + 7) / 8;
-
-  if (n > mpeg->buf_n) {
-    mpegd_buffer_fill (mpeg);
-  }
-
-  if (n > mpeg->buf_n) {
-    return (1);
-  }
-
-  return (0);
-}
-
-unsigned long mpegd_get_bits (mpeg_demux_t *mpeg, unsigned i, unsigned n)
-{
-  unsigned long r;
-  unsigned long v, m;
-  unsigned      b_i, b_n;
-  unsigned char *buf;
-
-  if (mpegd_need_bits (mpeg, i + n)) {
-    return (0);
-  }
-
-  buf = mpeg->buf + mpeg->buf_i;
-
-  r = 0;
-
-  /* aligned bytes */
-  if (((i | n) & 7) == 0) {
-    i = i / 8;
-    n = n / 8;
-    while (n > 0) {
-      r = (r << 8) | buf[i];
-      i += 1;
-      n -= 1;
-    }
-    return (r);
-  }
-
-
-  while (n > 0) {
-    b_n = 8 - (i & 7);
-    if (b_n > n) {
-      b_n = n;
-    }
-
-    b_i = 8 - (i & 7) - b_n;
-
-    m = (1 << b_n) - 1;
-    v = (buf[i >> 3] >> b_i) & m;
-
-    r = (r << b_n) | v;
-
-    i += b_n;
-    n -= b_n;
-  }
-
-  return (r);
-}
-
-int mpegd_skip (mpeg_demux_t *mpeg, unsigned n)
-{
-  size_t r;
-
-  mpeg->ofs += n;
-
-  if (n <= mpeg->buf_n) {
-    mpeg->buf_i += n;
-    mpeg->buf_n -= n;
-    return (0);
-  }
-
-  n -= mpeg->buf_n;
-  mpeg->buf_i = 0;
-  mpeg->buf_n = 0;
-
-  while (n > 0) {
-    if (n <= MPEG_DEMUX_BUFFER) {
-      r = read (mpeg->fd ,mpeg->buf, n);
-    }
-    else {
-      r = read (mpeg->fd, mpeg->buf, MPEG_DEMUX_BUFFER);
-    }
-
-    if (r <= 0) {
-      return (1);
-    }
-
-    n -= (unsigned) r;
-  }
-
-  return (0);
-}
-
-unsigned mpegd_read (mpeg_demux_t *mpeg, void *buf, unsigned n)
-{
-  unsigned      ret;
-  unsigned      i;
-  unsigned char *tmp;
-
-  tmp = (unsigned char *) buf;
-
-  i = (n < mpeg->buf_n) ? n : mpeg->buf_n;
-
-  ret = i;
-
-  if (i > 0) {
-    memcpy (tmp, &mpeg->buf[mpeg->buf_i], i);
-
-    tmp += i;
-    mpeg->buf_i += i;
-    mpeg->buf_n -= i;
-    n -= i;
-  }
-
-  if (n > 0) {
-    ret += read (mpeg->fd, tmp, n);
-  }
-
-  mpeg->ofs += ret;
-
-  return (ret);
-}
-
-int mpegd_set_offset (mpeg_demux_t *mpeg, unsigned long long ofs)
-{
-  if (ofs == mpeg->ofs) {
-    return (0);
-  }
-
-  if (ofs > mpeg->ofs) {
-    return (mpegd_skip (mpeg, (unsigned long) (ofs - mpeg->ofs)));
-  }
-
-  return (1);
-}
-
-static
-int mpegd_seek_header (mpeg_demux_t *mpeg)
-{
-  unsigned long long ofs;
-
-  while (mpegd_get_bits (mpeg, 0, 24) != 1) {
-    ofs = mpeg->ofs + 1;
-
-    if (mpeg->mpeg_skip != NULL) {
-      if (mpeg->mpeg_skip (mpeg)) {
-        return (1);
-      }
-    }
-
-    if (mpegd_set_offset (mpeg, ofs)) {
-      return (1);
-    }
-
-    mpeg->skip_cnt += 1;
-  }
-
-  return (0);
-}
-
-static
-int mpegd_parse_system_header (mpeg_demux_t *mpeg)
-{
-  unsigned long long ofs;
-
-  mpeg->shdr.size = mpegd_get_bits (mpeg, 32, 16) + 6;
-
-  mpeg->shdr.fixed = mpegd_get_bits (mpeg, 78, 1);
-  mpeg->shdr.csps = mpegd_get_bits (mpeg, 79, 1);
-
-  mpeg->shdr_cnt += 1;
-
-  ofs = mpeg->ofs + mpeg->shdr.size;
-
-  if (mpeg->mpeg_system_header != NULL) {
-    if (mpeg->mpeg_system_header (mpeg)) {
-      return (1);
-    }
-  }
-
-  mpegd_set_offset (mpeg, ofs);
-
-  return (0);
-}
-
-static
-int mpegd_parse_packet1 (mpeg_demux_t *mpeg, unsigned i)
-{
-  unsigned           val;
-  unsigned long long tmp;
-
-  mpeg->packet.type = 1;
-
-  if (mpegd_get_bits (mpeg, i, 2) == 0x01) {
-    i += 16;
-  }
-
-  val = mpegd_get_bits (mpeg, i, 8);
-
-  if ((val & 0xf0) == 0x20) {
-    tmp = mpegd_get_bits (mpeg, i + 4, 3);
-    tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 8, 15);
-    tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 24, 15);
-
-    mpeg->packet.have_pts = 1;
-    mpeg->packet.pts = tmp;
-
-    i += 40;
-  }
-  else if ((val & 0xf0) == 0x30) {
-    tmp = mpegd_get_bits (mpeg, i + 4, 3);
-    tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 8, 15);
-    tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 24, 15);
-
-    mpeg->packet.have_pts = 1;
-    mpeg->packet.pts = tmp;
-
-    tmp = mpegd_get_bits (mpeg, i + 44, 3);
-    tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 48, 15);
-    tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 64, 15);
-
-    mpeg->packet.have_dts = 1;
-    mpeg->packet.dts = tmp;
-
-    i += 80;
-  }
-  else if (val == 0x0f) {
-    i += 8;
-  }
-
-  mpeg->packet.offset = i / 8;
-
-  return (0);
-}
-
-static
-int mpegd_parse_packet2 (mpeg_demux_t *mpeg, unsigned i)
-{
-  unsigned           pts_dts_flag;
-  unsigned           cnt;
-  unsigned long long tmp;
-
-  mpeg->packet.type = 2;
-
-  pts_dts_flag = mpegd_get_bits (mpeg, i + 8, 2);
-  cnt = mpegd_get_bits (mpeg, i + 16, 8);
-
-  if (pts_dts_flag == 0x02) {
-    if (mpegd_get_bits (mpeg, i + 24, 4) == 0x02) {
-      tmp = mpegd_get_bits (mpeg, i + 28, 3);
-      tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 32, 15);
-      tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 48, 15);
-
-      mpeg->packet.have_pts = 1;
-      mpeg->packet.pts = tmp;
-    }
-  }
-  else if ((pts_dts_flag & 0x03) == 0x03) {
-    if (mpegd_get_bits (mpeg, i + 24, 4) == 0x03) {
-      tmp = mpegd_get_bits (mpeg, i + 28, 3);
-      tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 32, 15);
-      tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 48, 15);
-
-      mpeg->packet.have_pts = 1;
-      mpeg->packet.pts = tmp;
-    }
-
-    if (mpegd_get_bits (mpeg, i + 64, 4) == 0x01) {
-      tmp = mpegd_get_bits (mpeg, i + 68, 3);
-      tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 72, 15);
-      tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 88, 15);
-
-      mpeg->packet.have_dts = 1;
-      mpeg->packet.dts = tmp;
-    }
-  }
-
-  i += 8 * (cnt + 3);
-
-  mpeg->packet.offset = i / 8;
-
-  return (0);
-}
-
-static
-int mpegd_parse_packet (mpeg_demux_t *mpeg)
-{
-  unsigned           i;
-  unsigned           sid, ssid;
-  unsigned long long ofs;
-
-  mpeg->packet.type = 0;
-
-  sid = mpegd_get_bits (mpeg, 24, 8);
-  ssid = 0;
-
-  mpeg->packet.sid = sid;
-  mpeg->packet.ssid = ssid;
-
-  mpeg->packet.size = mpegd_get_bits (mpeg, 32, 16) + 6;
-  mpeg->packet.offset = 6;
-
-  mpeg->packet.have_pts = 0;
-  mpeg->packet.pts = 0;
-
-  mpeg->packet.have_dts = 0;
-  mpeg->packet.dts = 0;
-
-  i = 48;
-
-  if (((sid >= 0xc0) && (sid < 0xf0)) || (sid == 0xbd)) {
-    while (mpegd_get_bits (mpeg, i, 8) == 0xff) {
-      if (i > (48 + 16 * 8)) {
-        break;
-      }
-      i += 8;
-    }
-
-    if (mpegd_get_bits (mpeg, i, 2) == 0x02) {
-      if (mpegd_parse_packet2 (mpeg, i)) {
-        return (1);
-      }
-    }
-    else {
-      if (mpegd_parse_packet1 (mpeg, i)) {
-        return (1);
-      }
-    }
-  }
-  else if (sid == 0xbe) {
-    mpeg->packet.type = 1;
-  }
-
-  if (sid == 0xbd) {
-    ssid = mpegd_get_bits (mpeg, 8 * mpeg->packet.offset, 8);
-    mpeg->packet.ssid = ssid;
-  }
-
-  if ((mpeg->mpeg_packet_check != NULL) && mpeg->mpeg_packet_check (mpeg)) {
-    if (mpegd_skip (mpeg, 1)) {
-      return (1);
-    }
-  }
-  else {
-    mpeg->packet_cnt += 1;
-    mpeg->streams[sid].packet_cnt += 1;
-    mpeg->streams[sid].size += mpeg->packet.size - mpeg->packet.offset;
-
-    if (sid == 0xbd) {
-      mpeg->substreams[ssid].packet_cnt += 1;
-      mpeg->substreams[ssid].size += mpeg->packet.size - mpeg->packet.offset;
-    }
-
-    ofs = mpeg->ofs + mpeg->packet.size;
-
-    if (mpeg->mpeg_packet != NULL) {
-      if (mpeg->mpeg_packet (mpeg)) {
-        return (1);
-      }
-    }
-
-    mpegd_set_offset (mpeg, ofs);
-  }
-
-  return (0);
-}
-
-static
-int mpegd_parse_pack (mpeg_demux_t *mpeg)
-{
-  unsigned           sid;
-  unsigned long long ofs;
-
-  if (mpegd_get_bits (mpeg, 32, 4) == 0x02) {
-    mpeg->pack.type = 1;
-    mpeg->pack.scr = mpegd_get_bits (mpeg, 36, 3);
-    mpeg->pack.scr = (mpeg->pack.scr << 15) | mpegd_get_bits (mpeg, 40, 15);
-    mpeg->pack.scr = (mpeg->pack.scr << 15) | mpegd_get_bits (mpeg, 56, 15);
-    mpeg->pack.mux_rate = mpegd_get_bits (mpeg, 73, 22);
-    mpeg->pack.stuff = 0;
-    mpeg->pack.size = 12;
-  }
-  else if (mpegd_get_bits (mpeg, 32, 2) == 0x01) {
-    mpeg->pack.type = 2;
-    mpeg->pack.scr = mpegd_get_bits (mpeg, 34, 3);
-    mpeg->pack.scr = (mpeg->pack.scr << 15) | mpegd_get_bits (mpeg, 38, 15);
-    mpeg->pack.scr = (mpeg->pack.scr << 15) | mpegd_get_bits (mpeg, 54, 15);
-    mpeg->pack.mux_rate = mpegd_get_bits (mpeg, 80, 22);
-    mpeg->pack.stuff = mpegd_get_bits (mpeg, 109, 3);
-    mpeg->pack.size = 14 + mpeg->pack.stuff;
-  }
-  else {
-    mpeg->pack.type = 0;
-    mpeg->pack.scr = 0;
-    mpeg->pack.mux_rate = 0;
-    mpeg->pack.size = 4;
-  }
-
-  ofs = mpeg->ofs + mpeg->pack.size;
-
-  mpeg->pack_cnt += 1;
-
-  if (mpeg->mpeg_pack != NULL) {
-    if (mpeg->mpeg_pack (mpeg)) {
-      return (1);
-    }
-  }
-
-  mpegd_set_offset (mpeg, ofs);
-
-  mpegd_seek_header (mpeg);
-
-  if (mpegd_get_bits (mpeg, 0, 32) == MPEG_SYSTEM_HEADER) {
-    if (mpegd_parse_system_header (mpeg)) {
-      return (1);
-    }
-
-    mpegd_seek_header (mpeg);
-  }
-
-  while (mpegd_get_bits (mpeg, 0, 24) == MPEG_PACKET_START) {
-    sid = mpegd_get_bits (mpeg, 24, 8);
-
-    if ((sid == 0xba) || (sid == 0xb9) || (sid == 0xbb)) {
-      break;
-    }
-    else {
-      mpegd_parse_packet (mpeg);
-    }
-
-    mpegd_seek_header (mpeg);
-  }
-
-  return (0);
-}
-
-int mpegd_parse (mpeg_demux_t *mpeg)
-{
-  unsigned long long ofs;
-
-  while (1) {
-    if (mpegd_seek_header (mpeg)) {
-      return (0);
-    }
-
-    switch (mpegd_get_bits (mpeg, 0, 32)) {
-      case MPEG_PACK_START:
-        if (mpegd_parse_pack (mpeg)) {
-          return (1);
-        }
-        break;
-
-      case MPEG_END_CODE:
-        mpeg->end_cnt += 1;
-
-        ofs = mpeg->ofs + 4;
-
-        if (mpeg->mpeg_end != NULL) {
-          if (mpeg->mpeg_end (mpeg)) {
-            return (1);
-          }
-        }
-
-        if (mpegd_set_offset (mpeg, ofs)) {
-          return (1);
-        }
-        break;
-
-      default:
-        ofs = mpeg->ofs + 1;
-
-        if (mpeg->mpeg_skip != NULL) {
-          if (mpeg->mpeg_skip (mpeg)) {
-            return (1);
-          }
-        }
-
-        if (mpegd_set_offset (mpeg, ofs)) {
-          return (0);
-        }
-
-        break;
-    }
-  }
-
-  return (0);
-}
-
-#endif//HAVE_LIBDVDNAV
diff --git a/src/mpegdemux/mpeg_parse.h b/src/mpegdemux/mpeg_parse.h
deleted file mode 100644
index 1279c01..0000000
--- a/src/mpegdemux/mpeg_parse.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*****************************************************************************
- * mpegdemux                                                                 *
- *****************************************************************************/
-
-/*****************************************************************************
- * File name:     mpeg_parse.h                                               *
- * Created:       2003-02-01 by Hampa Hug <hampa at hampa.ch>                   *
- * Last modified: 2003-09-10 by Hampa Hug <hampa at hampa.ch>                   *
- * Copyright:     (C) 2003 by Hampa Hug <hampa at hampa.ch>                     *
- *****************************************************************************/
-
-/*****************************************************************************
- * This program is free software. You can redistribute it and / or modify it *
- * under the terms of the GNU General Public License version 2 as  published *
- * by the Free Software Foundation.                                          *
- *                                                                           *
- * This program is distributed in the hope  that  it  will  be  useful,  but *
- * WITHOUT  ANY   WARRANTY,   without   even   the   implied   warranty   of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  General *
- * Public License for more details.                                          *
- *****************************************************************************/
-
-/* $Id: mpeg_parse.h 67 2004-01-02 18:20:15Z hampa $ */
-
-// The code has been modified to use file descriptors instead of FILE streams.
-// Only functionality needed in MediaTomb remains, all extra features are
-// stripped out.
-
-#ifndef MPEG_PARSE_H
-#define MPEG_PARSE_H 1
-
-#include <stdio.h>
-
-
-#define MPEG_DEMUX_BUFFER 4096
-
-#define MPEG_END_CODE      0x01b9
-#define MPEG_PACK_START    0x01ba
-#define MPEG_SYSTEM_HEADER 0x01bb
-#define MPEG_PACKET_START  0x0001
-
-
-typedef struct {
-  unsigned long      packet_cnt;
-  unsigned long long size;
-} mpeg_stream_info_t;
-
-typedef struct {
-  unsigned size;
-  int      fixed;
-  int      csps;
-} mpeg_shdr_t;
-
-typedef struct {
-  unsigned           type;
-  unsigned           sid;
-  unsigned           ssid;
-  unsigned           size;
-  unsigned           offset;
-
-  char               have_pts;
-  unsigned long long pts;
-
-  char               have_dts;
-  unsigned long long dts;
-} mpeg_packet_t;
-
-typedef struct {
-  unsigned           size;
-  unsigned           type;
-  unsigned long long scr;
-  unsigned long      mux_rate;
-  unsigned           stuff;
-} mpeg_pack_t;
-
-typedef struct mpeg_demux_t {
-  int                close;
-  int                free;
-
-  int                fd;
-
-  unsigned long long ofs;
-
-  unsigned           buf_i;
-  unsigned           buf_n;
-  unsigned char      buf[MPEG_DEMUX_BUFFER];
-
-  mpeg_shdr_t        shdr;
-  mpeg_packet_t      packet;
-  mpeg_pack_t        pack;
-
-  unsigned long      shdr_cnt;
-  unsigned long      pack_cnt;
-  unsigned long      packet_cnt;
-  unsigned long      end_cnt;
-  unsigned long      skip_cnt;
-  mpeg_stream_info_t streams[256];
-  mpeg_stream_info_t substreams[256];
-
-//  void               *ext;
-  int                ext;
-
-  int (*mpeg_skip) (struct mpeg_demux_t *mpeg);
-  int (*mpeg_pack) (struct mpeg_demux_t *mpeg);
-  int (*mpeg_system_header) (struct mpeg_demux_t *mpeg);
-  int (*mpeg_packet) (struct mpeg_demux_t *mpeg);
-  int (*mpeg_packet_check) (struct mpeg_demux_t *mpeg);
-  int (*mpeg_end) (struct mpeg_demux_t *mpeg);
-} mpeg_demux_t;
-
-
-mpeg_demux_t *mpegd_open_fd (mpeg_demux_t *mpeg, int fd, int close_file);
-mpeg_demux_t *mpegd_open (mpeg_demux_t *mpeg, const char *fname);
-void mpegd_close (mpeg_demux_t *mpeg);
-void mpegd_reset_stats (mpeg_demux_t *mpeg);
-unsigned long mpegd_get_bits (mpeg_demux_t *mpeg, unsigned i, unsigned n);
-int mpegd_skip (mpeg_demux_t *mpeg, unsigned n);
-
-/*!***************************************************************************
- * @short  Read from the mpeg stream
- * @return The number of bytes read
- *****************************************************************************/
-unsigned mpegd_read (mpeg_demux_t *mpeg, void *buf, unsigned n);
-
-int mpegd_set_offset (mpeg_demux_t *mpeg, unsigned long long ofs);
-int mpegd_parse (mpeg_demux_t *mpeg);
-
-
-#endif
diff --git a/src/mpegdemux/mpeg_remux.c b/src/mpegdemux/mpeg_remux.c
deleted file mode 100644
index d957d95..0000000
--- a/src/mpegdemux/mpeg_remux.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*****************************************************************************
- * mpegdemux                                                                 *
- *****************************************************************************/
-
-/*****************************************************************************
- * File name:     mpeg_remux.c                                               *
- * Created:       2003-02-02 by Hampa Hug <hampa at hampa.ch>                   *
- * Last modified: 2003-09-10 by Hampa Hug <hampa at hampa.ch>                   *
- * Copyright:     (C) 2003 by Hampa Hug <hampa at hampa.ch>                     *
- *****************************************************************************/
-
-/*****************************************************************************
- * This program is free software. You can redistribute it and / or modify it *
- * under the terms of the GNU General Public License version 2 as  published *
- * by the Free Software Foundation.                                          *
- *                                                                           *
- * This program is distributed in the hope  that  it  will  be  useful,  but *
- * WITHOUT  ANY   WARRANTY,   without   even   the   implied   warranty   of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  General *
- * Public License for more details.                                          *
- *****************************************************************************/
-
-/* $Id: mpeg_remux.c 67 2004-01-02 18:20:15Z hampa $ */
-
-// The code has been modified to use file descriptors instead of FILE streams.
-// Only functionality needed in MediaTomb remains, all extra features are
-// stripped out.
-
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#ifdef HAVE_LIBDVDNAV
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "buffer.h"
-#include "mpeg_parse.h"
-#include "mpeg_remux.h"
-#include "mpegdemux_internal.h"
-
-
-static mpeg_buffer_t shdr = { NULL, 0, 0 };
-static mpeg_buffer_t pack = { NULL, 0, 0 };
-static mpeg_buffer_t packet = { NULL, 0, 0 };
-
-static
-int mpeg_remux_system_header (mpeg_demux_t *mpeg)
-{
-  if (mpeg_buf_write_clear (&pack, mpeg->ext)) {
-    return (1);
-  }
-
-  if (mpeg_buf_read (&shdr, mpeg, mpeg->shdr.size)) {
-    return (1);
-  }
-
-  if (mpeg_buf_write_clear (&shdr, mpeg->ext)) {
-    return (1);
-  }
-
-  return (0);
-}
-
-static
-int mpeg_remux_packet (mpeg_demux_t *mpeg)
-{
-  int      r;
-  unsigned sid, ssid;
-
-  sid = mpeg->packet.sid;
-  ssid = mpeg->packet.ssid;
-
-  if (mpeg_stream_excl (sid, ssid)) {
-    return (0);
-  }
-
-  r = 0;
-
-  if (mpeg_buf_read (&packet, mpeg, mpeg->packet.size)) {
-    fprintf(stderr, "remux: incomplete packet (sid=%02x size=%u/%u)\n",
-      sid, packet.cnt, mpeg->packet.size
-    );
-
-    if (par_drop) {
-      mpeg_buf_clear (&packet);
-      return (1);
-    }
-
-    r = 1;
-  }
-
-  if (mpeg_buf_write_clear (&pack, mpeg->ext)) {
-    return (1);
-  }
-
-  if (mpeg_buf_write_clear (&packet, mpeg->ext)) {
-    return (1);
-  }
-
-  return (r);
-}
-
-static
-int mpeg_remux_pack (mpeg_demux_t *mpeg)
-{
-  if (mpeg_buf_read (&pack, mpeg, mpeg->pack.size)) {
-    return (1);
-  }
-
-  if (par_empty_pack) {
-    if (mpeg_buf_write_clear (&pack, mpeg->ext)) {
-      return (1);
-    }
-  }
-
-  return (0);
-}
-
-static
-int mpeg_remux_end (mpeg_demux_t *mpeg)
-{
-  if (mpeg_copy (mpeg, mpeg->ext, 4)) {
-    return (1);
-  }
-
-  return (0);
-}
-
-int mpeg_remux (int inp, int out)
-{
-  int          r;
-  mpeg_demux_t *mpeg;
-
-  mpeg = mpegd_open_fd (NULL, inp, 0);
-  if (mpeg == NULL) {
-    return (1);
-  }
-
-  mpeg->ext = out;
-  mpeg->mpeg_system_header = &mpeg_remux_system_header;
-  mpeg->mpeg_pack = &mpeg_remux_pack;
-  mpeg->mpeg_packet = &mpeg_remux_packet;
-  mpeg->mpeg_packet_check = &mpeg_packet_check;
-  mpeg->mpeg_end = &mpeg_remux_end;
-
-  mpeg_buf_init (&shdr);
-  mpeg_buf_init (&pack);
-  mpeg_buf_init (&packet);
-
-  r = mpegd_parse (mpeg);
-
-  mpegd_close (mpeg);
-
-  mpeg_buf_free (&shdr);
-  mpeg_buf_free (&pack);
-  mpeg_buf_free (&packet);
-
-  return (r);
-}
-
-#endif//HAVE_LIBDVDNAV
diff --git a/src/mpegdemux/mpeg_remux.h b/src/mpegdemux/mpeg_remux.h
deleted file mode 100644
index cf624f2..0000000
--- a/src/mpegdemux/mpeg_remux.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*****************************************************************************
- * mpegdemux                                                                 *
- *****************************************************************************/
-
-/*****************************************************************************
- * File name:     mpeg_remux.h                                               *
- * Created:       2003-02-02 by Hampa Hug <hampa at hampa.ch>                   *
- * Last modified: 2003-03-02 by Hampa Hug <hampa at hampa.ch>                   *
- * Copyright:     (C) 2003 by Hampa Hug <hampa at hampa.ch>                     *
- *****************************************************************************/
-
-/*****************************************************************************
- * This program is free software. You can redistribute it and / or modify it *
- * under the terms of the GNU General Public License version 2 as  published *
- * by the Free Software Foundation.                                          *
- *                                                                           *
- * This program is distributed in the hope  that  it  will  be  useful,  but *
- * WITHOUT  ANY   WARRANTY,   without   even   the   implied   warranty   of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  General *
- * Public License for more details.                                          *
- *****************************************************************************/
-
-/* $Id: mpeg_remux.h 67 2004-01-02 18:20:15Z hampa $ */
-
-// The code has been modified to use file descriptors instead of FILE streams.
-// Only functionality needed in MediaTomb remains, all extra features are
-// stripped out.
-
-
-#ifndef MPEGDEMUX_MPEG_REMUX_H
-#define MPEGDEMUX_MPEG_REMUX_H 1
-
-
-int mpeg_remux (int inp, int out);
-
-
-#endif
diff --git a/src/mpegdemux/mpegdemux.c b/src/mpegdemux/mpegdemux.c
deleted file mode 100644
index 2f600d5..0000000
--- a/src/mpegdemux/mpegdemux.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*****************************************************************************
- * mpegdemux                                                                 *
- *****************************************************************************/
-
-/*****************************************************************************
- * File name:     mpegdemux.c                                                *
- * Created:       2003-02-01 by Hampa Hug <hampa at hampa.ch>                   *
- * Last modified: 2004-04-08 by Hampa Hug <hampa at hampa.ch>                   *
- * Copyright:     (C) 2003-2004 Hampa Hug <hampa at hampa.ch>                   *
- *****************************************************************************/
-
-/*****************************************************************************
- * This program is free software. You can redistribute it and / or modify it *
- * under the terms of the GNU General Public License version 2 as  published *
- * by the Free Software Foundation.                                          *
- *                                                                           *
- * This program is distributed in the hope  that  it  will  be  useful,  but *
- * WITHOUT  ANY   WARRANTY,   without   even   the   implied   warranty   of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  General *
- * Public License for more details.                                          *
- *****************************************************************************/
-
-/* $Id: mpegdemux.c 78 2004-04-08 18:57:31Z hampa $ */
-
-// The code has been modified to use file descriptors instead of FILE streams.
-// Only functionality needed in MediaTomb remains, all extra features are
-// stripped out.
-
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#ifdef HAVE_LIBDVDNAV
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "mpeg_parse.h"
-#include "mpeg_remux.h"
-#include "mpegdemux_internal.h"
-
-// thanks to mru for the following defines
-#define ISVIDEO(id)     ((id & 0xf0) == 0xe0)
-#define ISMPEGAUDIO(id) ((id & 0xe0) == 0xc0)
-#define ISAC3(id)       ((id & 0xf8) == 0x80)
-#define ISDTS(id)       ((id & 0xf8) == 0x88)
-#define ISPCM(id)       ((id & 0xf8) == 0xa0)
-#define ISSPU(id)       ((id & 0xe0) == 0x20)
-
-#define STREAM_ID_PRIVATE      0xbd
-
-static int     par_inp = -1;
-static int     par_out = -1;
-
-unsigned char   par_stream[256];
-unsigned char   par_substream[256];
-unsigned char   par_invalid[256];
-
-int             par_empty_pack = 0;
-int             par_drop = 1;
-int             par_dvdac3 = 0;
-
-
-
-
-int mpeg_stream_excl (unsigned char sid, unsigned char ssid)
-{
-  if (par_stream[sid] & PAR_STREAM_EXCLUDE) {
-    return (1);
-  }
-
-  if (sid == 0xbd) {
-    if (par_substream[ssid] & PAR_STREAM_EXCLUDE) {
-      return (1);
-    }
-  }
-
-  return (0);
-}
-
-/* check if packet is valid. returns 0 if it is. */
-int mpeg_packet_check (mpeg_demux_t *mpeg)
-{
-  return ((par_invalid[mpeg->packet.sid] & PAR_STREAM_EXCLUDE) == 0);
-}
-
-int mpeg_copy (mpeg_demux_t *mpeg, int fd, unsigned n)
-{
-  unsigned char buf[4096];
-  unsigned      i, j;
-
-  while (n > 0) {
-    i = (n < 4096) ? n : 4096;
-
-    j = mpegd_read (mpeg, buf, i);
-
-    if (j > 0) {
-      if (write (fd, buf, j) != j) {
-        return (1);
-      }
-    }
-
-    if (i != j) {
-      return (1);
-    }
-
-    n -= i;
-  }
-
-  return (0);
-}
-
-int remux_mpeg(int fd_in, int fd_out, unsigned char keep_video_id, unsigned char keep_audio_id)
-{
-  unsigned i;
-  int      r;
-
-  if (!ISVIDEO(keep_video_id))
-      return 1;
-
-  for (i = 0; i < 256; i++) {
-    par_stream[i] = PAR_STREAM_EXCLUDE;
-    par_substream[i] = PAR_STREAM_EXCLUDE;
-    par_invalid[i] = PAR_STREAM_EXCLUDE;
-  }
-
-  par_stream[keep_video_id] &= ~PAR_STREAM_EXCLUDE;
-
-  if (ISAC3(keep_audio_id) || ISDTS(keep_audio_id) || ISPCM(keep_audio_id))
-  {
-      par_stream[STREAM_ID_PRIVATE] &= ~PAR_STREAM_EXCLUDE;
-      par_substream[keep_audio_id] &= ~PAR_STREAM_EXCLUDE; 
-      par_dvdac3 = 1;
-  }
-  else
-  {
-      par_stream[keep_audio_id] &= ~PAR_STREAM_EXCLUDE;
-  }
-
- 
-  par_inp = fd_in;
-  par_out = fd_out;
-
-  if ((par_inp == -1) || (par_out == -1))
-  {
-      return 1;
-  }
-
-  r = mpeg_remux (par_inp, par_out);
-
-  if (r) {
-    return (1);
-  }
-
-  return (0);
-}
-
-#endif//HAVE_LIBDVDNAV
diff --git a/src/mpegdemux/mpegdemux.h b/src/mpegdemux/mpegdemux.h
deleted file mode 100644
index 0dcee3f..0000000
--- a/src/mpegdemux/mpegdemux.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* 
- * MT 
- * 
- * */
-
-
-#ifndef __MPEGDEMUX_H__
-#define __MPEGDEMUX_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/// \brief Remuxes an MPEG2 stream and keeps only the video and audio streams
-/// that are given by the ID.
-//
-/// \param fd_in Already opened file descriptor for reading the input stream.
-/// \param fd_out Already opeend file descriptor for writing the remuxed data.
-/// \param keep_video_id id of the video that should be kept.
-/// \param keep_audio_id id of the audio stream taht should be kept.
-/// \return 0 on success.
-
-int remux_mpeg(int fd_in, int fd_out, 
-               unsigned char keep_video_id, 
-               unsigned char keep_audio_id);
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-
-#endif
diff --git a/src/mpegdemux/mpegdemux_internal.h b/src/mpegdemux/mpegdemux_internal.h
deleted file mode 100644
index c509c4c..0000000
--- a/src/mpegdemux/mpegdemux_internal.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*****************************************************************************
- * mpegdemux                                                                 *
- *****************************************************************************/
-
-/*****************************************************************************
- * File name:     mpegdemux.h                                                *
- * Created:       2003-02-01 by Hampa Hug <hampa at hampa.ch>                   *
- * Last modified: 2004-04-08 by Hampa Hug <hampa at hampa.ch>                   *
- * Copyright:     (C) 2003-2004 Hampa Hug <hampa at hampa.ch>                   *
- *****************************************************************************/
-
-/*****************************************************************************
- * This program is free software. You can redistribute it and / or modify it *
- * under the terms of the GNU General Public License version 2 as  published *
- * by the Free Software Foundation.                                          *
- *                                                                           *
- * This program is distributed in the hope  that  it  will  be  useful,  but *
- * WITHOUT  ANY   WARRANTY,   without   even   the   implied   warranty   of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  General *
- * Public License for more details.                                          *
- *****************************************************************************/
-
-/* $Id: mpegdemux.h 78 2004-04-08 18:57:31Z hampa $ */
-
-// The code has been modified to use file descriptors instead of FILE streams.
-// Only functionality needed in MediaTomb remains, all extra features are
-// stripped out.
-
-
-#ifndef MPEGDEMUX_INTERNAL_H
-#define MPEGDEMUX_INTERNAL_H 1
-
-
-#define PAR_STREAM_EXCLUDE 1
-
-#define PAR_MODE_SCAN  0
-#define PAR_MODE_LIST  1
-#define PAR_MODE_REMUX 2
-#define PAR_MODE_DEMUX 3
-
-
-extern unsigned char par_stream[256];
-extern unsigned char par_substream[256];
-extern unsigned char par_invalid[256];
-extern int           par_empty_pack;
-extern int           par_drop;
-extern int           par_dvdac3;
-
-char *mpeg_get_name (const char *base, unsigned sid);
-int mpeg_stream_excl (unsigned char sid, unsigned char ssid);
-int mpeg_packet_check (mpeg_demux_t *mpeg);
-int mpeg_copy (mpeg_demux_t *mpeg, int fd, unsigned n);
-
-
-#endif
diff --git a/src/mpegremux_processor.cc b/src/mpegremux_processor.cc
index 54bb7b8..016637a 100644
--- a/src/mpegremux_processor.cc
+++ b/src/mpegremux_processor.cc
@@ -29,37 +29,3 @@
 
 /// \file mpegremux_processor.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#ifdef HAVE_LIBDVDNAV
-
-#include "mpegremux_processor.h"
-#include "mpegdemux/mpegdemux.h"
-
-using namespace zmm;
-
-MPEGRemuxProcessor::MPEGRemuxProcessor(int in_fd, int out_fd, unsigned char keep_audio_id) : ThreadExecutor()
-{
-    if (in_fd < 0)
-        throw _Exception(_("Got invalid input fd!"));
-
-    if (out_fd < 0)
-        throw _Exception(_("Got invalid input fd!"));
-
-    this->in_fd = in_fd;
-    this->out_fd = out_fd;
-    this->keep_audio_id = keep_audio_id;
-    startThread();
-}
-
-void MPEGRemuxProcessor::threadProc()
-{
-    log_debug("Starting remux thread...\n");
-    status = remux_mpeg(in_fd, out_fd, 0xe0, keep_audio_id);
-    threadRunning = false;
-    log_debug("Done remuxing\n");
-}
-
-#endif//HAVE_LIBDVDNAV
diff --git a/src/mt_inotify.cc b/src/mt_inotify.cc
index 22387ac..29fb8bb 100644
--- a/src/mt_inotify.cc
+++ b/src/mt_inotify.cc
@@ -36,20 +36,12 @@
 
 /// \file mt_inotify.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_INOTIFY
 
 #include <sys/ioctl.h>
 #include <unistd.h>
-#include <errno.h>
-#include <assert.h>
-
-#ifdef HAVE_SYS_UTSNAME_H
-    #include <sys/utsname.h>
-#endif
+#include <cerrno>
+#include <cassert>
 
 #include "mt_inotify.h"
 #include "tools.h"
@@ -80,24 +72,6 @@ Inotify::~Inotify()
 
 bool Inotify::supported()
 {
-#if defined(HAVE_UNAME) && defined(HAVE_SYS_UTSNAME_H)
-    struct utsname info;
-
-    if (uname(&info) == 0)
-    {
-        // 2.6.13 is the first kernel version that has inotify support
-        Ref<Array<StringBase> > kversion = split_string(_(info.release), '.');
-        if (kversion->size() >= 3)
-        {
-            int major = _(kversion->get(0)->data).toInt();
-            int minor = _(kversion->get(1)->data).toInt();
-            int patch = _(kversion->get(2)->data).toInt();
-
-            if ((major < 2) && (minor < 6) && (patch < 13))
-                return false;
-        }
-    }
-#endif   
     int test_fd = inotify_init();
     if (test_fd < 0)
         return false;
@@ -196,13 +170,13 @@ struct inotify_event *Inotify::nextEvent()
         fd_max = stop_fd_read;
 
     rc = select(fd_max + 1, &read_fds,
-            NULL, NULL, NULL);
+            nullptr, nullptr, nullptr);
     if ( rc < 0 ) {
-        return NULL;
+        return nullptr;
     }
     else if ( rc == 0 ) {
         // timeout
-        return NULL;
+        return nullptr;
     }
 
     if (FD_ISSET(stop_fd_read, &read_fds))
@@ -225,18 +199,18 @@ struct inotify_event *Inotify::nextEvent()
                 bytes_to_read < sizeof(struct inotify_event));
 
         if ( rc == -1 ) {
-            return NULL;
+            return nullptr;
         }
 
         this_bytes = read(inotify_fd, &event[0] + bytes,
                 sizeof(struct inotify_event)*MAX_EVENTS - bytes);
         if ( this_bytes < 0 ) {
-            return NULL;
+            return nullptr;
         }
         if ( this_bytes == 0 ) {
             log_error("Inotify reported end-of-file.  Possibly too many "
                     "events occurred at once.\n");
-            return NULL;
+            return nullptr;
         }
         bytes += this_bytes;
 
@@ -251,7 +225,7 @@ struct inotify_event *Inotify::nextEvent()
         return ret;
     }
 
-    return NULL;
+    return nullptr;
 }
 
 
diff --git a/src/mt_inotify.h b/src/mt_inotify.h
index b4dffd7..f758ad8 100644
--- a/src/mt_inotify.h
+++ b/src/mt_inotify.h
@@ -32,13 +32,11 @@
 #ifndef __MT_INOTIFY_H__
 #define __MT_INOTIFY_H__
 
-#include "zmmf/zmmf.h"
+#ifdef HAVE_INOTIFY
 
-#ifdef SYS_INOTIFY_H_OK
-    #include <sys/inotify.h>
-#else
-    #include "inotify-nosys.h"
-#endif
+#include <sys/inotify.h>
+
+#include "zmm/zmmf.h"
 
 /// \brief Inotify interface.
 class Inotify : public zmm::Object
@@ -77,4 +75,6 @@ private:
     int stop_fd_write;
 };
 
+#endif
+
 #endif // __INOTIFY_H__
diff --git a/src/mxml/attribute.cc b/src/mxml/attribute.cc
index 8471e4a..b6eebbf 100644
--- a/src/mxml/attribute.cc
+++ b/src/mxml/attribute.cc
@@ -29,10 +29,6 @@
 
 /// \file attribute.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "mxml.h"
 #include "attribute.h"
 
diff --git a/src/mxml/attribute.h b/src/mxml/attribute.h
index 1cec054..be97eb0 100644
--- a/src/mxml/attribute.h
+++ b/src/mxml/attribute.h
@@ -32,7 +32,7 @@
 #ifndef __MXML_ATTRIBUTE_H__
 #define __MXML_ATTRIBUTE_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 #include "mxml.h"
 
 namespace mxml
diff --git a/src/mxml/comment.cc b/src/mxml/comment.cc
index 763da5a..be89b3a 100644
--- a/src/mxml/comment.cc
+++ b/src/mxml/comment.cc
@@ -29,10 +29,6 @@
 
 /// \file comment.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "mxml.h"
 #include "comment.h"
 
diff --git a/src/mxml/comment.h b/src/mxml/comment.h
index e84982b..76fedf6 100644
--- a/src/mxml/comment.h
+++ b/src/mxml/comment.h
@@ -32,7 +32,7 @@
 #ifndef __MXML_COMMENT_H__
 #define __MXML_COMMENT_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 
 #include "mxml.h"
 
diff --git a/src/mxml/context.cc b/src/mxml/context.cc
index 1000248..7112f24 100644
--- a/src/mxml/context.cc
+++ b/src/mxml/context.cc
@@ -29,10 +29,6 @@
 
 /// \file context.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "context.h"
 
 using namespace zmm;
@@ -46,6 +42,8 @@ Context::Context(String location) : Object()
 }
 Context::Context()
 {
+    line = 1;
+    col = 1;
 }
 
 Ref<Context> Context::clone()
diff --git a/src/mxml/context.h b/src/mxml/context.h
index bd513d8..8f9475b 100644
--- a/src/mxml/context.h
+++ b/src/mxml/context.h
@@ -32,7 +32,7 @@
 #ifndef __MXML_CONTEXT_H__
 #define __MXML_CONTEXT_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 
 namespace mxml
 {
diff --git a/src/mxml/document.cc b/src/mxml/document.cc
index 3c80137..a992865 100644
--- a/src/mxml/document.cc
+++ b/src/mxml/document.cc
@@ -29,10 +29,6 @@
 
 /// \file document.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "mxml.h"
 #include "document.h"
 
@@ -42,7 +38,7 @@ using namespace mxml;
 Document::Document() : Node()
 {
     type = mxml_node_document;
-    root = nil;
+    root = nullptr;
 }
 
 void Document::setRoot(Ref<Element> root)
@@ -58,14 +54,14 @@ Ref<Element> Document::getRoot()
 
 void Document::appendChild(Ref<Node> child)
 {
-    if(children == nil)
+    if(children == nullptr)
         children = Ref<Array<Node> >(new Array<Node>());
     children->append(child);
 }
 
 void Document::print_internal(Ref<StringBuffer> buf, int indent)
 {
-    if (children != nil && children->size())
+    if (children != nullptr && children->size())
     {
         for(int i = 0; i < children->size(); i++)
         {
diff --git a/src/mxml/document.h b/src/mxml/document.h
index 2535c85..f0a24d4 100644
--- a/src/mxml/document.h
+++ b/src/mxml/document.h
@@ -32,7 +32,7 @@
 #ifndef __MXML_DOCUMENT_H__
 #define __MXML_DOCUMENT_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 
 #include "mxml.h"
 
diff --git a/src/mxml/element.cc b/src/mxml/element.cc
index 2ad3ba7..38b3fd5 100644
--- a/src/mxml/element.cc
+++ b/src/mxml/element.cc
@@ -29,15 +29,11 @@
 
 /// \file element.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
+#include <cassert>
 
 #include "element.h"
 #include "tools.h"
 
-#include <string.h>
-
 using namespace zmm;
 using namespace mxml;
 
@@ -46,8 +42,8 @@ Element::Element(String name) : Node()
     type = mxml_node_element;
     this->name = name;
     arrayType = false;
-    arrayName = nil;
-    textKey = nil;
+    arrayName = nullptr;
+    textKey = nullptr;
 }
 Element::Element(String name, Ref<Context> context) : Node()
 {
@@ -55,13 +51,13 @@ Element::Element(String name, Ref<Context> context) : Node()
     this->name = name;
     this->context = context;
     arrayType = false;
-    arrayName = nil;
-    textKey = nil;
+    arrayName = nullptr;
+    textKey = nullptr;
 }
 String Element::getAttribute(String name)
 {
-    if(attributes == nil)
-        return nil;
+    if(attributes == nullptr)
+        return nullptr;
     int len = attributes->size();
     for(int i = 0; i < len; i++)
     {
@@ -69,7 +65,7 @@ String Element::getAttribute(String name)
         if(attr->name == name)
             return attr->value;
     }
-    return nil;
+    return nullptr;
 }
 void Element::addAttribute(String name, String value, enum mxml_value_type type)
 {
@@ -79,14 +75,14 @@ void Element::addAttribute(String name, String value, enum mxml_value_type type)
 
 void Element::addAttribute(Ref<Attribute> attr)
 {
-    if (attributes == nil)
+    if (attributes == nullptr)
         attributes = Ref<Array<Attribute> >(new Array<Attribute>());
     attributes->append(attr);
 }
 
 void Element::setAttribute(String name, String value, enum mxml_value_type type)
 {
-    if (attributes == nil)
+    if (attributes == nullptr)
         attributes = Ref<Array<Attribute> >(new Array<Attribute>());
     int len = attributes->size();
     for(int i = 0; i < len; i++)
@@ -104,7 +100,7 @@ void Element::setAttribute(String name, String value, enum mxml_value_type type)
 
 int Element::childCount(enum mxml_node_types type)
 {
-    if (children == nil)
+    if (children == nullptr)
         return 0;
     
     if (type == mxml_node_all)
@@ -124,14 +120,14 @@ int Element::childCount(enum mxml_node_types type)
 
 Ref<Node> Element::getChild(int index, enum mxml_node_types type, bool remove)
 {
-    if (children == nil)
-        return nil;
+    if (children == nullptr)
+        return nullptr;
     int countElements = 0;
     
     if (type == mxml_node_all)
     {
         if (index >= children->size())
-            return nil;
+            return nullptr;
         else
         {
             Ref<Node> node = children->get(index);
@@ -154,7 +150,7 @@ Ref<Node> Element::getChild(int index, enum mxml_node_types type, bool remove)
             }
         }
     }
-    return nil;
+    return nullptr;
 }
 
 bool Element::removeElementChild(String name, bool removeAll)
@@ -163,7 +159,7 @@ bool Element::removeElementChild(String name, bool removeAll)
     if (id < 0)
         return false;
     Ref<Node> child = getChild(id, mxml_node_all, true);
-    if (child == nil)
+    if (child == nullptr)
         return false;
     if (! removeAll)
         return true;
@@ -173,14 +169,14 @@ bool Element::removeElementChild(String name, bool removeAll)
 
 void Element::appendChild(Ref<Node> child)
 {
-    if(children == nil)
+    if(children == nullptr)
         children = Ref<Array<Node> >(new Array<Node>());
     children->append(child);
 }
 
 void Element::insertChild(int index, Ref<Node> child)
 {
-    if (children == nil)
+    if (children == nullptr)
         children = Ref<Array<Node> >(new Array<Node>());
     children->insert(index, child);
 }
@@ -288,7 +284,7 @@ String Element::getText()
     Ref<Text> text;
     int i = 0;
     bool someText = false;
-    while ((text = RefCast(getChild(i++, mxml_node_text), Text)) != nil)
+    while ((text = RefCast(getChild(i++, mxml_node_text), Text)) != nullptr)
     {
         someText = true;
         *buf << text->getText();
@@ -296,7 +292,7 @@ String Element::getText()
     if (someText)
         return buf->toString();
     else
-        return nil;
+        return nullptr;
 }
 
 enum mxml_value_type Element::getVTypeText()
@@ -305,7 +301,7 @@ enum mxml_value_type Element::getVTypeText()
     int i = 0;
     bool someText = false;
     enum mxml_value_type vtype = mxml_string_type;
-    while ((text = RefCast(getChild(i++, mxml_node_text), Text)) != nil)
+    while ((text = RefCast(getChild(i++, mxml_node_text), Text)) != nullptr)
     {
         if (! someText)
         {
@@ -323,17 +319,17 @@ enum mxml_value_type Element::getVTypeText()
 
 int Element::attributeCount()
 {
-    if (attributes == nil)
+    if (attributes == nullptr)
         return 0;
     return attributes->size();
 }
 
 Ref<Attribute> Element::getAttribute(int index)
 {
-    if (attributes == nil)
-        return nil;
+    if (attributes == nullptr)
+        return nullptr;
     if (index >= attributes->size())
-        return nil;
+        return nullptr;
     return attributes->get(index);
 }
 
@@ -345,7 +341,7 @@ void Element::setText(String str, enum mxml_value_type type)
     if (childCount() == 1)
     {
         Ref<Node> child = getChild(0);
-        if (child == nil || child->getType() != mxml_node_text)
+        if (child == nullptr || child->getType() != mxml_node_text)
             throw _Exception(_("Element::setText() cannot be called on an element which has a non-text child"));
         Ref<Text> text = RefCast(child, Text);
         text->setText(str);
@@ -368,7 +364,7 @@ void Element::appendTextChild(String name, String text, enum mxml_value_type typ
 
 int Element::getChildIdByName(String name)
 {
-    if(children == nil)
+    if(children == nullptr)
         return -1;
     for(int i = 0; i < children->size(); i++)
     {
@@ -376,7 +372,7 @@ int Element::getChildIdByName(String name)
         if (nd->getType() == mxml_node_element)
         {
             Ref<Element> el = RefCast(nd, Element);
-            if (name == nil || el->name == name)
+            if (name == nullptr || el->name == name)
                 return i;
         }
     }
@@ -387,15 +383,15 @@ Ref<Element> Element::getChildByName(String name)
 {
     int id = getChildIdByName(name);
     if (id < 0)
-        return nil;
+        return nullptr;
     return RefCast(getChild(id), Element);
 }
 
 String Element::getChildText(String name)
 {
     Ref<Element> el = getChildByName(name);
-    if(el == nil)
-        return nil;
+    if(el == nullptr)
+        return nullptr;
     return el->getText();
 }
 
@@ -411,7 +407,7 @@ void Element::print_internal(Ref<StringBuffer> buf, int indent)
     int i;
     
     *buf << "<" << name;
-    if (attributes != nil)
+    if (attributes != nullptr)
     {
         for(i = 0; i < attributes->size(); i++)
         {
@@ -421,7 +417,7 @@ void Element::print_internal(Ref<StringBuffer> buf, int indent)
         }
     }
     
-    if (children != nil && children->size())
+    if (children != nullptr && children->size())
     {
         *buf << ">";
         
diff --git a/src/mxml/element.h b/src/mxml/element.h
index 43e6021..aab8379 100644
--- a/src/mxml/element.h
+++ b/src/mxml/element.h
@@ -32,7 +32,7 @@
 #ifndef __MXML_ELEMENT_H__
 #define __MXML_ELEMENT_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 
 #include "mxml.h"
 
diff --git a/src/mxml/mxml.h b/src/mxml/mxml.h
index fafc195..c14e843 100644
--- a/src/mxml/mxml.h
+++ b/src/mxml/mxml.h
@@ -32,7 +32,7 @@
 #ifndef __MXML_H__
 #define __MXML_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 
 namespace mxml
 {
diff --git a/src/mxml/node.cc b/src/mxml/node.cc
index 0f00061..a6ab624 100644
--- a/src/mxml/node.cc
+++ b/src/mxml/node.cc
@@ -29,13 +29,9 @@
 
 /// \file node.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "mxml.h"
 
-#include <string.h>
+#include <cstring>
 
 using namespace zmm;
 using namespace mxml;
@@ -50,7 +46,7 @@ String Node::print()
 String Node::escape(String str)
 {
     Ref<StringBuffer> buf(new StringBuffer(str.length()));
-    signed char *ptr = (signed char *)str.c_str();
+    auto *ptr = (signed char *)str.c_str();
     while (ptr && *ptr)
     {
         switch (*ptr)
diff --git a/src/mxml/node.h b/src/mxml/node.h
index 3657d42..5403e87 100644
--- a/src/mxml/node.h
+++ b/src/mxml/node.h
@@ -32,7 +32,7 @@
 #ifndef __MXML_NODE_H__
 #define __MXML_NODE_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 
 #include "mxml.h"
 
diff --git a/src/mxml/parseexception.cc b/src/mxml/parseexception.cc
index 8443a9b..f637703 100644
--- a/src/mxml/parseexception.cc
+++ b/src/mxml/parseexception.cc
@@ -29,10 +29,6 @@
 
 /// \file parseexception.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "parseexception.h"
 
 #include "context.h"
diff --git a/src/mxml/parseexception.h b/src/mxml/parseexception.h
index 5f17725..a04c9f5 100644
--- a/src/mxml/parseexception.h
+++ b/src/mxml/parseexception.h
@@ -32,7 +32,7 @@
 #ifndef __MXML_PARSEEXCEPTION_H__
 #define __MXML_PARSEEXCEPTION_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 
 namespace mxml
 {
diff --git a/src/mxml/parser.h b/src/mxml/parser.h
index 7634509..4ab8f9d 100644
--- a/src/mxml/parser.h
+++ b/src/mxml/parser.h
@@ -32,14 +32,10 @@
 #ifndef __MXML_PARSER_H__
 #define __MXML_PARSER_H__
 
-#include "zmmf/zmmf.h"
-
-#ifndef HAVE_EXPAT
-    #error Expat is needed to compile MediaTomb!
-#endif
-
 #include <expat.h>
-#include "zmmf/object_stack.h"
+
+#include "zmm/zmmf.h"
+#include "zmm/object_stack.h"
 
 namespace mxml
 {
diff --git a/src/mxml/parser_expat.cc b/src/mxml/parser_expat.cc
index 9f3117e..58ba943 100644
--- a/src/mxml/parser_expat.cc
+++ b/src/mxml/parser_expat.cc
@@ -29,12 +29,6 @@
 
 /// \file parser_expat.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#ifdef HAVE_EXPAT
-
 #include "parser.h"
 
 using namespace zmm;
@@ -45,19 +39,19 @@ using namespace mxml;
 
 void XMLCALL Parser::element_start(void *userdata, const char *name, const char **attrs)
 {
-    Parser *parser = (Parser *)userdata;
+    auto *parser = (Parser *)userdata;
     Ref<Element> el(new Element(name));
     for (int i = 0; attrs[i]; i += 2) 
     {
         el->addAttribute(attrs[i], attrs[i + 1]);
     }
 
-    if (parser->document->getRoot() == nil)
+    if (parser->document->getRoot() == nullptr)
     {
         parser->document->setRoot(el);
         parser->curEl = el;
     }
-    else if (parser->curEl != nil)
+    else if (parser->curEl != nullptr)
     {
         parser->curEl->appendElementChild(el);
         parser->elements->push(parser->curEl);
@@ -72,19 +66,19 @@ void XMLCALL Parser::element_start(void *userdata, const char *name, const char
 
 void XMLCALL Parser::element_end(void *userdata, const char *name)
 {
-    Parser *parser = (Parser *)userdata;
+    auto *parser = (Parser *)userdata;
     parser->curEl = parser->elements->pop();
 }
 
 void XMLCALL Parser::character_data(void *userdata, const XML_Char *s, int len)
 {
-    Parser *parser = (Parser *)userdata;
+    auto *parser = (Parser *)userdata;
     String text = String(s, len);
     
-    if (text != nil)
+    if (text != nullptr)
     {
         Ref<Text> textEl(new Text(text));
-        if (parser->curEl == nil)
+        if (parser->curEl == nullptr)
             parser->document->appendChild(RefCast(textEl, Node));
         else
             parser->curEl->appendChild(RefCast(textEl, Node));
@@ -93,12 +87,12 @@ void XMLCALL Parser::character_data(void *userdata, const XML_Char *s, int len)
 
 void XMLCALL Parser::comment_callback(void *userdata, const XML_Char *s)
 {
-    Parser *parser = (Parser *)userdata;
+    auto *parser = (Parser *)userdata;
     String text = s;
-    if (text != nil)
+    if (text != nullptr)
     {
         Ref<Comment> cm(new Comment(text));
-        if (parser->curEl == nil)
+        if (parser->curEl == nullptr)
             parser->document->appendChild(RefCast(cm, Node));
         else
             parser->curEl->appendChild(RefCast(cm, Node));
@@ -107,7 +101,7 @@ void XMLCALL Parser::comment_callback(void *userdata, const XML_Char *s)
 
 void XMLCALL Parser::default_callback(void *userdata, const XML_Char *s, int len)
 {
-    Parser *parser = (Parser *)userdata;
+    auto *parser = (Parser *)userdata;
     String text = String(s, len);
     
     if (text.charAt(0) == '<')
@@ -146,7 +140,7 @@ Ref<Document> Parser::parseString(String str)
 
 Ref<Document> Parser::parse(Ref<Context> ctx, String input)
 {
-    XML_Parser parser = XML_ParserCreate(NULL);
+    XML_Parser parser = XML_ParserCreate(nullptr);
     if (!parser)
         throw Exception(_("Unable to allocate XML parser"));
 
@@ -171,5 +165,3 @@ Ref<Document> Parser::parse(Ref<Context> ctx, String input)
     XML_ParserFree(parser);
     return document;
 }
-
-#endif
diff --git a/src/mxml/xml_text.cc b/src/mxml/xml_text.cc
index c42dcc5..66a0bac 100644
--- a/src/mxml/xml_text.cc
+++ b/src/mxml/xml_text.cc
@@ -29,10 +29,6 @@
 
 /// \file xml_text.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "mxml.h"
 #include "xml_text.h"
 
diff --git a/src/mxml/xml_text.h b/src/mxml/xml_text.h
index b9e5989..46edc16 100644
--- a/src/mxml/xml_text.h
+++ b/src/mxml/xml_text.h
@@ -32,7 +32,7 @@
 #ifndef __MXML_XML_TEXT_H__
 #define __MXML_XML_TEXT_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 
 #include "mxml.h"
 
diff --git a/src/mxml/xml_to_json.cc b/src/mxml/xml_to_json.cc
index af4418c..726fd0a 100644
--- a/src/mxml/xml_to_json.cc
+++ b/src/mxml/xml_to_json.cc
@@ -29,9 +29,7 @@
 
 /// \file xml_to_json.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
+#include <cassert>
 
 #include "xml_to_json.h"
 #include "tools.h"
@@ -67,7 +65,7 @@ void XML2JSON::handleElement(Ref<StringBuffer> buf, Ref<Element> el)
     }
     
     bool array = el->isArrayType();
-    String nodeName = nil;
+    String nodeName = nullptr;
     
     if (array)
     {
@@ -192,5 +190,5 @@ String XML2JSON::getValue(String text, enum mxml_value_type type)
         /// \todo should we check if really int?
         return text;
     }
-    return nil;
+    return nullptr;
 }
diff --git a/src/mxml/xml_to_json.h b/src/mxml/xml_to_json.h
index 8ff3d06..44a8e3b 100644
--- a/src/mxml/xml_to_json.h
+++ b/src/mxml/xml_to_json.h
@@ -32,7 +32,7 @@
 #ifndef __MXML_XML_TO_JSON_H__
 #define __MXML_XML_TO_JSON_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 
 #include "mxml.h"
 
diff --git a/src/object_dictionary.h b/src/object_dictionary.h
index b1c0a88..6338917 100644
--- a/src/object_dictionary.h
+++ b/src/object_dictionary.h
@@ -32,7 +32,7 @@
 #ifndef __OBJECT_DICTIONARY_H__
 #define __OBJECT_DICTIONARY_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 
 
 template <class T>
@@ -103,7 +103,7 @@ public:
                 return el->getValue();
             }
         }
-        return nil;
+        return nullptr;
     }
     
     /// \brief Returns the number of elements in the dictinary.
diff --git a/src/online_service.cc b/src/online_service.cc
index 3412378..517ad4c 100644
--- a/src/online_service.cc
+++ b/src/online_service.cc
@@ -29,10 +29,6 @@
 
 /// \file online_service.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef ONLINE_SERVICES
 
 #include "online_service.h"
@@ -52,7 +48,7 @@ OnlineServiceList::OnlineServiceList()
 
 void OnlineServiceList::registerService(Ref<OnlineService> service)
 {
-    if (service == nil)
+    if (service == nullptr)
         return;
 
     if (service->getServiceType() >= OS_Max)
@@ -66,7 +62,7 @@ void OnlineServiceList::registerService(Ref<OnlineService> service)
 Ref<OnlineService> OnlineServiceList::getService(service_type_t service)
 {
     if ((service > OS_Max) || (service < 0))
-        return nil;
+        return nullptr;
 
     return service_list->get(service);
 }
@@ -98,9 +94,9 @@ String OnlineService::getCheckAttr(Ref<Element> xml, String attrname)
         return temp;
     else
         throw _Exception(getServiceName() + _(": Tag <") + xml->getName() +
-                _("> is missing the requred \"") + attrname +
+                _("> is missing the required \"") + attrname +
                 _("\" attribute!"));
-    return nil;
+    return nullptr;
 }
 
 int OnlineService::getCheckPosIntAttr(Ref<Element> xml, String attrname)
@@ -111,7 +107,7 @@ int OnlineService::getCheckPosIntAttr(Ref<Element> xml, String attrname)
         itmp = temp.toInt();
     else
         throw _Exception(getServiceName() + _(": Tag <") + xml->getName() +
-                _("> is missing the requred \"") + attrname +
+                _("> is missing the required \"") + attrname +
                 _("\" attribute!"));
 
     if (itmp < 1)
diff --git a/src/online_service.h b/src/online_service.h
index 268419c..082841e 100644
--- a/src/online_service.h
+++ b/src/online_service.h
@@ -35,10 +35,12 @@
 #ifndef __ONLINE_SERVICE_H__
 #define __ONLINE_SERVICE_H__
 
+
 #include "zmm/zmm.h"
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 #include "mxml/mxml.h"
 #include "layout/layout.h"
+#include "timer.h"
 
 #define ONLINE_SERVICE_AUX_ID "ols"
 #define ONLINE_SERVICE_LAST_UPDATE "lu"
@@ -49,7 +51,7 @@ typedef enum
     OS_None         = 0,
     OS_YouTube      = 1,
     OS_SopCast      = 2,
-    OS_Weborama     = 3,
+
     OS_ATrailers    = 4,
     OS_Max
 } service_type_t;
@@ -108,10 +110,10 @@ public:
     void setTaskCount(int taskCount) { this->taskCount = taskCount; }
 
     /// Parameter that can be used by timerNotify
-    void setTimerParameter(zmm::Ref<zmm::Object> param) 
+    void setTimerParameter(zmm::Ref<Timer::Parameter> param)
                            { timer_parameter = param; }
 
-    zmm::Ref<Object> getTimerParameter() { return timer_parameter; }
+    zmm::Ref<Timer::Parameter> getTimerParameter() { return timer_parameter; }
 
     /// \brief Sets the service refresh interval in seconds
     void setRefreshInterval(int interval) {refresh_interval = interval; }
@@ -129,7 +131,7 @@ protected:
     int taskCount;
     int refresh_interval;
     int purge_interval;
-    zmm::Ref<zmm::Object> timer_parameter;
+    zmm::Ref<Timer::Parameter> timer_parameter;
 
     /// \brief retrieves a required attribute given by the name
     zmm::String getCheckAttr(zmm::Ref<mxml::Element> xml, zmm::String attrname);
diff --git a/src/online_service_helper.cc b/src/online_service_helper.cc
index cee9cac..b6800b5 100644
--- a/src/online_service_helper.cc
+++ b/src/online_service_helper.cc
@@ -30,14 +30,10 @@
 /// \file online_service_helper.cc
 /// \brief Definition of the OnlineServiceHelper class.
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef ONLINE_SERVICES
 
 #include "zmm/zmm.h"
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 #include "mxml/mxml.h"
 #include "online_service.h"
 #include "online_service_helper.h"
@@ -92,11 +88,6 @@ String OnlineServiceHelper::resolveURL(Ref<CdsItemExternalURL> item)
             url = item->getLocation();
             break;
 #endif
-#ifdef WEBORAMA
-        case OS_Weborama:
-            url = item->getLocation();
-            break;
-#endif
 #ifdef ATRAILERS
         case OS_ATrailers:
             url = item->getLocation();
diff --git a/src/online_service_helper.h b/src/online_service_helper.h
index 91b9646..1a378a5 100644
--- a/src/online_service_helper.h
+++ b/src/online_service_helper.h
@@ -36,7 +36,7 @@
 #define __ONLINE_SERVICE_HELPER_H__
 
 #include "zmm/zmm.h"
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 #include "cds_objects.h"
 
 /// \brief This class will handle things that are specific to various services
diff --git a/src/play_hook.cc b/src/play_hook.cc
index 4a19046..fc9aeef 100644
--- a/src/play_hook.cc
+++ b/src/play_hook.cc
@@ -32,10 +32,6 @@
 //
 // \todo this should be solved via an observer model 
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "play_hook.h"
 #include "config_manager.h"
 #include "content_manager.h"
@@ -46,8 +42,6 @@
 
 using namespace zmm;
 
-SINGLETON_MUTEX(PlayHook, false);
-
 void PlayHook::trigger(zmm::Ref<CdsObject> obj)
 {
     Ref<ConfigManager> cfg = ConfigManager::getInstance();
diff --git a/src/play_hook.h b/src/play_hook.h
index ad757d2..0a435bb 100644
--- a/src/play_hook.h
+++ b/src/play_hook.h
@@ -39,7 +39,7 @@
 #include "common.h"
 #include "cds_objects.h"
 
-class PlayHook : public Singleton<PlayHook>
+class PlayHook : public Singleton<PlayHook, std::mutex>
 {
 public:
     void trigger(zmm::Ref<CdsObject> obj);
diff --git a/src/process.cc b/src/process.cc
index ef08b5f..008d9da 100644
--- a/src/process.cc
+++ b/src/process.cc
@@ -29,22 +29,18 @@
 
 /// \file process.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "process.h"
 
-#include <stdio.h>
+#include <cstdio>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <signal.h>
+#include <csignal>
 #include <sys/wait.h>
 
-#include <string.h>
-#include <errno.h>
+#include <cstring>
+#include <cerrno>
 
 #include "config_manager.h"
 
@@ -118,7 +114,7 @@ String run_simple_process(String prog, String param, String input)
 
     int bytesRead;
     char buf[BUF_SIZE];
-    while (1)
+    while (true)
     {
         bytesRead = fread(buf, 1, BUF_SIZE, file);
         if(bytesRead > 0)
diff --git a/src/process.h b/src/process.h
index e2fefae..c689d85 100644
--- a/src/process.h
+++ b/src/process.h
@@ -32,7 +32,7 @@
 #ifndef __PROCESS_H__
 #define __PROCESS_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 
 void init_process();
 zmm::String run_simple_process(zmm::String prog, zmm::String param, zmm::String input);
diff --git a/src/process_executor.cc b/src/process_executor.cc
index f5772b3..c770663 100644
--- a/src/process_executor.cc
+++ b/src/process_executor.cc
@@ -29,21 +29,17 @@
 
 /// \file process_executor.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "process_executor.h"
 #include "process.h"
 #include <pthread.h>
-#include <signal.h>
+#include <csignal>
 
 using namespace zmm;
 
 ProcessExecutor::ProcessExecutor(String command, Ref<Array<StringBase> > arglist)
 {
 #define MAX_ARGS 255
-    char *argv[MAX_ARGS];
+    const char *argv[MAX_ARGS];
     
     argv[0] = command.c_str();
     int apos = 0;
@@ -54,7 +50,7 @@ ProcessExecutor::ProcessExecutor(String command, Ref<Array<StringBase> > arglist
         if (apos >= MAX_ARGS-1)
             break;
     }
-    argv[++apos] = NULL;
+    argv[++apos] = nullptr;
 
     exit_status = 0;
 
@@ -67,9 +63,9 @@ ProcessExecutor::ProcessExecutor(String command, Ref<Array<StringBase> > arglist
         
         case 0:
             sigset_t mask_set;
-            pthread_sigmask(SIG_SETMASK, &mask_set, NULL);
+            pthread_sigmask(SIG_SETMASK, &mask_set, nullptr);
             log_debug("Launching process: %s\n", command.c_str());
-            execvp(command.c_str(), argv);
+            execvp(command.c_str(), const_cast<char **const>(argv));
         default:
             break;
     }
diff --git a/src/process_io_handler.cc b/src/process_io_handler.cc
index aaa248d..c683308 100644
--- a/src/process_io_handler.cc
+++ b/src/process_io_handler.cc
@@ -29,16 +29,12 @@
 
 /// \file process_io_handler.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef EXTERNAL_TRANSCODING
 
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <signal.h>
+#include <csignal>
 #include <unistd.h>
 #include "common.h"
 #include "process_io_handler.h"
@@ -73,13 +69,13 @@ bool ProcessIOHandler::abort()
 {
     bool abort = false;
 
-    if (proclist == nil)
+    if (proclist == nullptr)
         return abort; 
 
     for (int i = 0; i < proclist->size(); i++)
     {
         Ref<Executor> exec = proclist->get(i)->getExecutor();
-        if ((exec != nil) && (!exec->isAlive()))
+        if ((exec != nullptr) && (!exec->isAlive()))
         {
             if (proclist->get(i)->abortOnDeath())
                 abort = true;
@@ -92,45 +88,45 @@ bool ProcessIOHandler::abort()
 
 void ProcessIOHandler::killall()
 {
-    if (proclist == nil)
+    if (proclist == nullptr)
         return;
 
     for (int i = 0; i < proclist->size(); i++)
     {
         Ref<Executor> exec = proclist->get(i)->getExecutor();
-        if (exec != nil)
+        if (exec != nullptr)
             exec->kill();
     }
 }
 
 void ProcessIOHandler::registerAll()
 {
-    if (main_proc != nil)
+    if (main_proc != nullptr)
         ContentManager::getInstance()->registerExecutor(main_proc);
 
-    if (proclist == nil)
+    if (proclist == nullptr)
         return;
 
     for (int i = 0; i < proclist->size(); i++)
     {
         Ref<Executor> exec = proclist->get(i)->getExecutor();
-        if (exec != nil)
+        if (exec != nullptr)
             ContentManager::getInstance()->registerExecutor(exec);
     }
 }
 
 void ProcessIOHandler::unregisterAll()
 {
-    if (main_proc != nil)
+    if (main_proc != nullptr)
         ContentManager::getInstance()->unregisterExecutor(main_proc);
 
-    if (proclist == nil)
+    if (proclist == nullptr)
         return;
 
     for (int i = 0; i < proclist->size(); i++)
     {
         Ref<Executor> exec = proclist->get(i)->getExecutor();
-        if (exec != nil)
+        if (exec != nullptr)
             ContentManager::getInstance()->unregisterExecutor(exec);
     }
 }
@@ -145,7 +141,7 @@ ProcessIOHandler::ProcessIOHandler(String filename,
     this->main_proc = main_proc;
     this->ignore_seek = ignoreSeek;
 
-    if ((main_proc != nil) && ((!main_proc->isAlive() || abort())))
+    if ((main_proc != nullptr) && ((!main_proc->isAlive() || abort())))
     {
         killall();
         throw _Exception(_("process terminated early"));
@@ -155,7 +151,7 @@ ProcessIOHandler::ProcessIOHandler(String filename,
     {
         log_error("Failed to create fifo: %s\n", strerror(errno));
         killall();
-        if (main_proc != nil)
+        if (main_proc != nullptr)
             main_proc->kill();
 
         throw _Exception(_("Could not create reader fifo!\n"));
@@ -166,7 +162,7 @@ ProcessIOHandler::ProcessIOHandler(String filename,
 
 void ProcessIOHandler::open(IN enum UpnpOpenFileMode mode)
 {
-    if ((main_proc != nil) && ((!main_proc->isAlive() || abort())))
+    if ((main_proc != nullptr) && ((!main_proc->isAlive() || abort())))
     {
         killall();
         throw _Exception(_("process terminated early"));
@@ -187,7 +183,7 @@ void ProcessIOHandler::open(IN enum UpnpOpenFileMode mode)
         }
 
         killall();
-        if (main_proc != nil)
+        if (main_proc != nullptr)
             main_proc->kill();
         unlink(filename.c_str());
         throw _Exception(_("open: failed to open: ") + filename.c_str());
@@ -213,7 +209,7 @@ int ProcessIOHandler::read(OUT char *buf, IN size_t length)
         timeout.tv_sec = FIFO_READ_TIMEOUT;
         timeout.tv_usec = 0;
 
-        ret = select(fd + 1, &readSet, NULL, NULL, &timeout);
+        ret = select(fd + 1, &readSet, nullptr, nullptr, &timeout);
         if (ret == -1)
         {
             if (errno == EINTR)
@@ -223,7 +219,7 @@ int ProcessIOHandler::read(OUT char *buf, IN size_t length)
         // timeout
         if (ret == 0)
         {
-            if (main_proc != nil)
+            if (main_proc != nullptr)
             {
                 bool main_ok = main_proc->isAlive();
                 if (!main_ok || abort())
@@ -289,7 +285,7 @@ int ProcessIOHandler::read(OUT char *buf, IN size_t length)
         // actually that will depend on the ret code of the process
         ret = -1;
 
-        if (main_proc != nil)
+        if (main_proc != nullptr)
         {
             if (!main_proc->isAlive())
             {
@@ -330,7 +326,7 @@ int ProcessIOHandler::write(IN char *buf, IN size_t length)
         timeout.tv_sec = FIFO_WRITE_TIMEOUT;
         timeout.tv_usec = 0;
 
-        ret = select(fd + 1, NULL, &writeSet, NULL, &timeout);
+        ret = select(fd + 1, nullptr, &writeSet, nullptr, &timeout);
         if (ret == -1)
         {
             if (errno == EINTR)
@@ -342,7 +338,7 @@ int ProcessIOHandler::write(IN char *buf, IN size_t length)
         // timeout
         if (ret == 0)
         {
-            if (main_proc != nil)
+            if (main_proc != nullptr)
             {
                 bool main_ok = main_proc->isAlive();
                 if (!main_ok || abort())
@@ -399,7 +395,7 @@ int ProcessIOHandler::write(IN char *buf, IN size_t length)
         // actually that will depend on the ret code of the process
         ret = -1;
 
-        if (main_proc != nil)
+        if (main_proc != nullptr)
         {
             if (!main_proc->isAlive())
             {
@@ -438,7 +434,7 @@ void ProcessIOHandler::close()
     log_debug("terminating process, closing %s\n", this->filename.c_str());
     unregisterAll();
 
-    if (main_proc != nil)
+    if (main_proc != nullptr)
     {
         ret = main_proc->kill();
     }
@@ -461,7 +457,7 @@ ProcessIOHandler::~ProcessIOHandler()
     {
         close();
     }
-    catch (Exception ex) {}
+    catch (const Exception & ex) {}
 }
 
 #endif // EXTERNAL_TRANSCODING
diff --git a/src/process_io_handler.h b/src/process_io_handler.h
index bc5966c..1601943 100644
--- a/src/process_io_handler.h
+++ b/src/process_io_handler.h
@@ -60,7 +60,7 @@ public:
     /// \param proclist associated processes that will be terminated once
     /// they are no longer needed
     ProcessIOHandler(zmm::String filename, zmm::Ref<Executor> main_proc,
-                     zmm::Ref<zmm::Array<ProcListItem> > proclist = nil, 
+                     zmm::Ref<zmm::Array<ProcListItem> > proclist = nullptr,
                      bool ignoreSeek = false);
     
     /// \brief Opens file for reading (writing is not supported)
diff --git a/src/reentrant_array.h b/src/reentrant_array.h
index 23e6784..d985cf7 100644
--- a/src/reentrant_array.h
+++ b/src/reentrant_array.h
@@ -32,8 +32,8 @@
 #ifndef __REENTRANT_ARRAY_H__
 #define __REENTRANT_ARRAY_H__
 
-#include "zmmf/zmmf.h"
-#include "sync.h"
+#include <mutex>
+#include "zmm/zmmf.h"
 
 /// \brief Reentrant version of the object array
 template <class T>
@@ -41,73 +41,57 @@ class ReentrantArray : public zmm::Array<T>
 {
 public:
     ReentrantArray() : zmm::Array<T>()
-    {
-        mutex = zmm::Ref<Mutex>(new Mutex());
-    }
+    { }
     ReentrantArray(int capacity) : zmm::Array<T>(capacity)
-    {
-        mutex = zmm::Ref<Mutex>(new Mutex());
-    }
+    { }
     inline void append(zmm::Ref<T> el)
     {
-        mutex->lock();
+        AutoLock lock(mutex);
         zmm::Array<T>::append(el);
-        mutex->unlock();
     }
     inline void set(zmm::Ref<T> el, int index)
     {
-        mutex->lock();
+        AutoLock lock(mutex);
         zmm::Array<T>::set(el, index);
-        mutex->unlock();
     }
     inline zmm::Ref<T> get(int index)
     {
-        zmm::Ref<T> ret;
-        mutex->lock();
-        ret = zmm::Array<T>::get(index);
-        mutex->unlock();
-        return ret;
+        AutoLock lock(mutex);
+        return zmm::Array<T>::get(index);
     }
     inline void remove(int index, int count=1)
     {
-        mutex->lock();
+        AutoLock lock(mutex);
         zmm::Array<T>::set(index, count);
-        mutex->unlock();
     }
     inline void removeUnordered(int index)
     {
-        mutex->lock();
+        AutoLock lock(mutex);
         zmm::Array<T>::removeUnordered(index);
-        mutex->unlock();
     }
     inline void insert(int index, zmm::Ref<T> el)
     {
-        mutex->lock();
+        AutoLock lock(mutex);
         zmm::Array<T>::insert(index, el);
-        mutex->unlock();
     }
     inline int size()
     {
-        int size;
-        mutex->lock();
-        size = zmm::Array<T>::size();
-        mutex->unlock();
-        return size;
+        AutoLock lock(mutex);
+        return zmm::Array<T>::size();
     }
     inline void clear()
     {
-        mutex->lock();
+        AutoLock lock(mutex);
         zmm::Array<T>::clear();
-        mutex->unlock();
     }
     inline void optimize()
     {
-        mutex->lock();
+        AutoLock lock(mutex);
         zmm::Array<T>::optimize();
-        mutex->unlock();
     }
 protected:
-    zmm::Ref<Mutex> mutex;
+    std::mutex mutex;
+    using AutoLock = std::lock_guard<decltype(mutex)>;
 };
 
 
diff --git a/src/request_handler.cc b/src/request_handler.cc
index 7dbbfbb..fb3006e 100644
--- a/src/request_handler.cc
+++ b/src/request_handler.cc
@@ -29,10 +29,6 @@
 
 /// \file request_handler.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "request_handler.h"
 #include "tools.h"
 
@@ -49,7 +45,7 @@ void RequestHandler::split_url(const char *url, char separator, String &path, St
     else if (separator == '?')
         i1 = url_s.index(separator);
     else
-        throw _Exception(_("Forbidden separator: " + separator));
+        throw _Exception(String("Forbidden separator: ") + separator);
 
     if (i1 < 0)
     {
diff --git a/src/request_handler.h b/src/request_handler.h
index ff448ef..461eea5 100644
--- a/src/request_handler.h
+++ b/src/request_handler.h
@@ -40,9 +40,8 @@ class RequestHandler : public zmm::Object
 {
 public:
     virtual void get_info(IN const char *filename, 
-                          OUT struct File_Info *info) = 0;
-    virtual zmm::Ref<IOHandler> open(IN const char *filename, 
-                                     OUT struct File_Info *info, 
+                          OUT UpnpFileInfo *info) = 0;
+    virtual zmm::Ref<IOHandler> open(IN const char *filename,
                                      IN enum UpnpOpenFileMode mode,
                                      IN zmm::String range) = 0;
 
diff --git a/src/rexp.cc b/src/rexp.cc
index 496fad3..75982fb 100644
--- a/src/rexp.cc
+++ b/src/rexp.cc
@@ -29,19 +29,15 @@
 
 /// \file rexp.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "rexp.h"
 
 using namespace zmm;
 
 static String error_string(int code, regex_t *regex)
 {
-    int size = regerror(code, regex, NULL, 0);
+    int size = regerror(code, regex, nullptr, 0);
     String buf = String::allocate(size);
-    regerror(code, regex, buf.c_str(), size);
+    regerror(code, regex, const_cast<char *>(buf.c_str()), size);
     buf.setLength(size - 1);
     return buf;
 }
@@ -75,7 +71,7 @@ void RExp::compile(String pattern, int flags)
 void RExp::compile(zmm::String pattern, const char *sflags)
 {
     int flags = 0;
-    char *p = (char *)sflags;
+    auto *p = (char *)sflags;
     char c;
     while ((c = *p) != 0)
     {
@@ -100,7 +96,7 @@ Ref<Matcher> RExp::match(String text, int nmatch)
     if (m->next())
         return m;
     else
-        return nil;
+        return nullptr;
 }
 
 bool RExp::matches(String text)
@@ -113,12 +109,12 @@ Matcher::Matcher(zmm::Ref<RExp> rexp, String text, int nmatch)
 {
     this->rexp = rexp;
     this->text = text;
-    this->ptr = NULL;
+    this->ptr = nullptr;
     this->nmatch = nmatch++; 
     if (this->nmatch)
         this->pmatch = (regmatch_t *)MALLOC(this->nmatch * sizeof(regmatch_t));
     else
-        this->pmatch = NULL;
+        this->pmatch = nullptr;
 }
 Matcher::~Matcher()
 {
@@ -131,15 +127,15 @@ String Matcher::group(int i)
     if (m->rm_so >= 0)
         return String(ptr + m->rm_so, m->rm_eo - m->rm_so);
     else
-        return nil;
+        return nullptr;
 }
 bool Matcher::next()
 {
     int ret;
 
-    if (ptr == NULL) // first match
+    if (ptr == nullptr) // first match
     {
-        ptr = text.c_str();
+        ptr = const_cast<char *>(text.c_str());
     }
     else
     {
diff --git a/src/scripting/dvd_image_import_script.cc b/src/scripting/dvd_image_import_script.cc
deleted file mode 100644
index 8fc2c10..0000000
--- a/src/scripting/dvd_image_import_script.cc
+++ /dev/null
@@ -1,316 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    dvd_image_import_script.cc - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file dvd_image_import_script.cc
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#if defined(HAVE_JS) && defined(HAVE_LIBDVDNAV)
-
-#include "dvd_image_import_script.h"
-#include "config_manager.h"
-#include "js_functions.h"
-#include "metadata/dvd_handler.h"
-using namespace zmm;
-
-extern "C" {
- 
-// object, dvd title, chapter, audio track, container chain, container class
-static JSBool js_addDVDObject(JSContext *cx, JSObject *obj, uintN argc, 
-                            jsval *argv, jsval *rval)
-{
-    try
-    {
-        jsval arg;
-        JSObject *js_cds_obj;
-        Ref<CdsObject> cds_obj;
-        Ref<CdsObject> processed;
-        int title;
-        int chapter;
-        int audio_track;
-        String chain;
-        String containerclass;
-        JSString *str;
-
-
-        DVDImportScript *self = (DVDImportScript *)JS_GetPrivate(cx, obj);
-
-        if (self->whoami() != S_DVD)
-        {
-            log_error("Function must be called from the DVD import script!\n");
-            return JS_TRUE;
-        }
-
-        arg = JS_ARGV(cx, argv)[0];
-        if (!JSVAL_IS_OBJECT(arg))
-        {
-            log_error("Invalid argument!");
-            return JS_TRUE;
-        }
-
-        if (!JS_ValueToObject(cx, arg, &js_cds_obj))
-        {
-            log_error("Could not convert object!");
-            return JS_TRUE;
-        }
-
-        // root it
-        JS_ARGV(cx, argv)[0] = OBJECT_TO_JSVAL(js_cds_obj);
-
-        if (!JS_ValueToInt32(cx, JS_ARGV(cx, argv)[1], &title))
-        {
-            log_error("addDVDObject: Invalid DVD title number given!\n");
-            return JS_TRUE;
-        }
-
-        if (!JS_ValueToInt32(cx, JS_ARGV(cx, argv)[2], &chapter))
-        {
-            log_error("addDVDObject: Invalid DVD chapter number given!\n");
-            return JS_TRUE;
-        }
-
-        if (!JS_ValueToInt32(cx, JS_ARGV(cx, argv)[3], &audio_track))
-        {
-            log_error("addDVDObject: Invalid DVD audio track number given!\n");
-            return JS_TRUE;
-        }
-
-        str = JS_ValueToString(cx, JS_ARGV(cx, argv)[4]);
-        if (!str)
-        {
-            log_error("addDVDObject: Invalid DVD container chain given!\n");
-            return JS_TRUE;
-        }
-
-        chain = JS_GetStringBytes(str);
-        if (!string_ok(chain) || chain == "undefined")
-        {
-            log_error("addDVDObject: Invalid DVD container chain given!\n");
-            return JS_TRUE;
-        }
-
-        JSString *cont = JS_ValueToString(cx, JS_ARGV(cx, argv)[5]);
-        if (cont)
-        {
-            containerclass = JS_GetStringBytes(cont);
-            if (!string_ok(containerclass) || containerclass == "undefined")
-                containerclass = nil;
-        }
-       
-        processed = self->getProcessedObject();
-        if (processed == nil)
-        {
-            log_error("addDVDObject: could not retrieve original object!\n");
-            return JS_TRUE;
-        }
-
-
-        // convert incoming object
-        cds_obj = self->jsObject2cdsObject(js_cds_obj, processed);
-        if (cds_obj == nil)
-        {
-            log_error("addDVDObject: could not convert js object!\n");
-            return JS_TRUE;
-        }
-
-        self->addDVDObject(cds_obj, title, chapter, audio_track, chain, 
-                           containerclass);
-
-    }
-    catch (ServerShutdownException se)
-    {
-        log_warning("Aborting script execution due to server shutdown.\n");
-        return JS_FALSE;
-    }
-    catch (Exception ex)
-    {
-        log_error("%s\n", ex.getMessage().c_str());
-        ex.printStackTrace();
-    }
-
-    return JS_TRUE;
-}
-
-} // extern "C" 
-
-void DVDImportScript::addDVDObject(Ref<CdsObject> obj, int title, 
-                                  int chapter, int audio_track, String chain, 
-                                  String containerclass)
-{
-
-    if (processed == nil)
-        throw _Exception(_("Invalid original object!"));
-
-    if (processed->getID() == INVALID_OBJECT_ID)
-        throw _Exception(_("Original object not yet in database!"));
-
-    obj->setRefID(processed->getID());
-    obj->setID(INVALID_OBJECT_ID);
-    obj->setVirtual(1);
-    obj->clearFlag(OBJECT_FLAG_USE_RESOURCE_REF);
-
-    Ref<ContentManager> cm = ContentManager::getInstance();
-
-    int id = cm->addContainerChain(chain, containerclass, processed->getID());
-    obj->setParentID(id);
-
-    RefCast(obj, CdsItem)->setMimeType(mimetype);
-    obj->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_PROTOCOLINFO), renderProtocolInfo(mimetype));
-    
-    /// \todo this has to be changed once we add seeking
-    obj->getResource(0)->removeAttribute(MetadataHandler::getResAttrName(R_SIZE));
-    obj->getResource(0)->addParameter(DVDHandler::renderKey(DVD_AudioStreamID), processed->getAuxData(DVDHandler::renderKey(DVD_AudioTrackStreamID, title, 0, 
-                    audio_track)));
-
-    String tmp = processed->getAuxData(DVDHandler::renderKey(DVD_AudioTrackChannels, title, 0, audio_track));
-    if (string_ok(tmp))
-    {
-        obj->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_NRAUDIOCHANNELS), tmp);
-        log_debug("Setting Audio Channels, object %s -  num: %s\n",
-                obj->getLocation().c_str(), tmp.c_str());
-    }
-
-    tmp = processed->getAuxData(DVDHandler::renderKey(DVD_AudioTrackSampleFreq, title, 0, audio_track));
-    if (string_ok(tmp))
-        obj->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_SAMPLEFREQUENCY), tmp);
-
-    obj->getResource(0)->addParameter(DVDHandler::renderKey(DVD_Chapter),
-            String::from(chapter));
-
-//    tmp = processed->getAuxData(DVDHandler::renderKey(DVD_ChapterRestDuration,
-//                title, chapter));
-//    if (string_ok(tmp))
-//        obj->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_DURATION), tmp);
-
-    obj->getResource(0)->addParameter(DVDHandler::renderKey(DVD_Title),
-            String::from(title));
-
-    cm->addObject(obj);
-}
-
-DVDImportScript::DVDImportScript(Ref<Runtime> runtime) : Script(runtime)
-{
-
-#ifdef JS_THREADSAFE
-    JS_SetContextThread(cx);
-    JS_BeginRequest(cx);
-#endif
-
-    try 
-    {
-        defineFunction(_("addDVDObject"), js_addDVDObject, 7);
-    
-        setProperty(glob, _("DVD"), _("DVD"));
-
-        String scriptPath = ConfigManager::getInstance()->getOption(CFG_IMPORT_SCRIPTING_DVD_SCRIPT); 
-        load(scriptPath);
-        root = JS_NewScriptObject(cx, script);
-        JS_AddNamedRoot(cx, &root, "DVDImportScript");
-        log_info("Loaded %s\n", scriptPath.c_str());
-
-         Ref<Dictionary> mappings =
-                         ConfigManager::getInstance()->getDictionaryOption(
-                              CFG_IMPORT_MAPPINGS_MIMETYPE_TO_CONTENTTYPE_LIST);
-
-         mimetype = mappings->get(_(CONTENT_TYPE_MPEG));
-         if (!string_ok(mimetype))
-             mimetype = _("video/mpeg");
-    }
-    catch (Exception ex)
-    {
-#ifdef JS_THREADSAFE
-        JS_EndRequest(cx);
-        JS_ClearContextThread(cx);
-#endif
-        throw ex;
-    }
-#ifdef JS_THREADSAFE
-        JS_EndRequest(cx);
-        JS_ClearContextThread(cx);
-#endif
-}
-
-void DVDImportScript::processDVDObject(Ref<CdsObject> obj)
-{
-#ifdef JS_THREADSAFE
-    JS_SetContextThread(cx);
-    JS_BeginRequest(cx);
-#endif
-    processed = obj;
-    try 
-    {
-        JSObject *orig = JS_NewObject(cx, NULL, NULL, glob);
-        setObjectProperty(glob, _("dvd"), orig);
-        cdsObject2jsObject(obj, orig);
-        execute();
-    }
-    catch (Exception ex)
-    {
-        processed = nil;
-#ifdef JS_THREADSAFE
-        JS_EndRequest(cx);
-        JS_ClearContextThread(cx);
-#endif
-        throw ex;
-    }
-
-    processed = nil;
-
-    gc_counter++;
-    if (gc_counter > JS_CALL_GC_AFTER_NUM)
-    {
-        JS_MaybeGC(cx);
-        gc_counter = 0;
-    }
-#ifdef JS_THREADSAFE
-    JS_EndRequest(cx);
-    JS_ClearContextThread(cx);
-#endif
-}
-
-DVDImportScript::~DVDImportScript()
-{
-#ifdef JS_THREADSAFE
-    JS_SetContextThread(cx);
-    JS_BeginRequest(cx);
-#endif
-    
-    if (root)
-        JS_RemoveRoot(cx, &root);
-
-#ifdef JS_THREADSAFE
-    JS_EndRequest(cx);
-    JS_ClearContextThread(cx);
-#endif
-
-}
-
-#endif // HAVE_JS
diff --git a/src/scripting/dvd_image_import_script.h b/src/scripting/dvd_image_import_script.h
deleted file mode 100644
index 443a9e4..0000000
--- a/src/scripting/dvd_image_import_script.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    dvd_image_import_script.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file dvd_image_import_script.h
-
-#ifndef __SCRIPTING_DVD_IMAGE_IMPORT_SCRIPT_H__
-#define __SCRIPTING_DVD_IMAGE_IMPORT_SCRIPT_H__
-
-#include "common.h"
-#include "script.h"
-#include "cds_objects.h"
-#include "content_manager.h"
-
-class DVDImportScript : public Script
-{
-public:
-    DVDImportScript(zmm::Ref<Runtime> runtime);
-    ~DVDImportScript();
-    /// \brief Adds a DVD object to the database
-    /// 
-    /// \param title DVD title number
-    /// \param chapter DVD chapter 
-    /// \param audio track DVD audio track
-    void addDVDObject(zmm::Ref<CdsObject> obj, int title, int chapter, 
-                      int audio_track, zmm::String chain, 
-                      zmm::String containerclass);
-    void processDVDObject(zmm::Ref<CdsObject> obj);
-    virtual script_class_t whoami() { return S_DVD; }
-
-private:
-    int currentObjectID;
-    zmm::Ref<CMTask> currentTask;
-    JSObject *root;
-    zmm::String mimetype;
-
-};
-
-#endif // __SCRIPTING_DVD_IMAGE_IMPORT_SCRIPT_H__
diff --git a/src/scripting/import_script.cc b/src/scripting/import_script.cc
index 1eade0a..a65be1a 100644
--- a/src/scripting/import_script.cc
+++ b/src/scripting/import_script.cc
@@ -29,10 +29,6 @@
 
 /// \file import_script.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_JS
 
 #include "import_script.h"
@@ -41,88 +37,56 @@
 
 using namespace zmm;
 
-ImportScript::ImportScript(Ref<Runtime> runtime) : Script(runtime)
+ImportScript::ImportScript(Ref<Runtime> runtime) : Script(runtime, "import")
 {
     String scriptPath = ConfigManager::getInstance()->getOption(CFG_IMPORT_SCRIPTING_IMPORT_SCRIPT); 
 
-#ifdef JS_THREADSAFE
-    JS_SetContextThread(cx);
-    JS_BeginRequest(cx);
-#endif
-
     try 
     {
         load(scriptPath);
-        JS_AddNamedObjectRoot(cx, &script, "ImportScript");
     }
-    catch (Exception ex)
+    catch (const Exception & ex)
     {
-#ifdef JS_THREADSAFE
-        JS_EndRequest(cx);
-        JS_ClearContextThread(cx);
-#endif
         throw ex;
     }
-#ifdef JS_THREADSAFE
-        JS_EndRequest(cx);
-        JS_ClearContextThread(cx);
-#endif
 }
 
 void ImportScript::processCdsObject(Ref<CdsObject> obj, String scriptpath)
 {
-#ifdef JS_THREADSAFE
-    JS_SetContextThread(cx);
-    JS_BeginRequest(cx);
-#endif
     processed = obj;
     try 
     {
-        JSObject *orig = JS_NewObject(cx, NULL, NULL, glob);
-        setObjectProperty(glob, _("orig"), orig);
-        cdsObject2jsObject(obj, orig);
-        setProperty(glob, _("object_script_path"), scriptpath);
+        cdsObject2dukObject(obj);
+        duk_put_global_string(ctx, "orig");
+        duk_push_string(ctx, scriptpath.c_str());
+        duk_put_global_string(ctx, "object_script_path");
         execute();
+        duk_push_global_object(ctx);
+        duk_del_prop_string(ctx, -1, "orig");
+        duk_del_prop_string(ctx, -1, "object_script_path");
+        duk_pop(ctx);
     }
-    catch (Exception ex)
+    catch (const Exception & ex)
     {
-        processed = nil;
-#ifdef JS_THREADSAFE
-        JS_EndRequest(cx);
-        JS_ClearContextThread(cx);
-#endif
+        duk_push_global_object(ctx);
+        duk_del_prop_string(ctx, -1, "orig");
+        duk_del_prop_string(ctx, -1, "object_script_path");
+        processed = nullptr;
         throw ex;
     }
 
-    processed = nil;
+    processed = nullptr;
 
     gc_counter++;
     if (gc_counter > JS_CALL_GC_AFTER_NUM)
     {
-        JS_MaybeGC(cx);
+        duk_gc(ctx, 0);
         gc_counter = 0;
     }
-#ifdef JS_THREADSAFE
-    JS_EndRequest(cx);
-    JS_ClearContextThread(cx);
-#endif
 }
 
 ImportScript::~ImportScript()
 {
-#ifdef JS_THREADSAFE
-    JS_SetContextThread(cx);
-    JS_BeginRequest(cx);
-#endif
-    
-    if (script)
-        JS_RemoveObjectRoot(cx, &script);
-
-#ifdef JS_THREADSAFE
-    JS_EndRequest(cx);
-    JS_ClearContextThread(cx);
-#endif
-
 }
 
 #endif // HAVE_JS
diff --git a/src/scripting/import_script.h b/src/scripting/import_script.h
index 260d7ee..0343327 100644
--- a/src/scripting/import_script.h
+++ b/src/scripting/import_script.h
@@ -43,9 +43,7 @@ public:
     ImportScript(zmm::Ref<Runtime> runtime);
     ~ImportScript();
     void processCdsObject(zmm::Ref<CdsObject> obj, zmm::String rootpath);
-    virtual script_class_t whoami() { return S_IMPORT; }
-private:
-    JSObject *root;
+    virtual script_class_t whoami() override { return S_IMPORT; }
 };
 
 #endif // __SCRIPTING_IMPORT_SCRIPT_H__
diff --git a/src/scripting/js_functions.cc b/src/scripting/js_functions.cc
index b34643e..3dda0ca 100644
--- a/src/scripting/js_functions.cc
+++ b/src/scripting/js_functions.cc
@@ -29,10 +29,6 @@
 
 /// \file js_functions.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_JS
 
 #include "js_functions.h"
@@ -48,109 +44,55 @@ using namespace zmm;
 
 //extern "C" {
 
-JSBool 
-js_print(JSContext *cx, uintN argc, jsval *argv)
+duk_ret_t js_print(duk_context *ctx)
 {
-    uintN i;
-    JSString *str;
-
-    if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, argv), "*"))
-    {
-        return JS_FALSE;
-    }
-
-    Ref<StringBuffer> buf(new StringBuffer());
-    for (i = 0; i < argc; i++) 
-    {
-        str = JS_ValueToString(cx, JS_ARGV(cx, argv)[i]);
-        if (!str)
-        {
-            return JS_FALSE;
-        }
-        JS_ARGV(cx, argv)[i] = STRING_TO_JSVAL(str);
-        char *temp = JS_EncodeString(cx, str);
-        if (temp)
-        {
-            *buf << temp;
-            free(temp);
-        }
-    }
-    log_js("%s\n", buf->toString().c_str());
-    JS_SET_RVAL(cx, argv, JSVAL_VOID);
-    return JS_TRUE;
+    duk_push_string(ctx, " ");
+    duk_insert(ctx, 0);
+    duk_join(ctx, duk_get_top(ctx)-1);
+    log_js("%s\n", duk_get_string(ctx, 0));
+    return 0;
 }
 
-JSBool
-js_copyObject(JSContext *cx, uintN argc, jsval *argv)
+duk_ret_t js_copyObject(duk_context *ctx)
 {
-    jsval arg;
-    JSObject *js_cds_obj;
-    JSObject *js_cds_clone_obj;
-
-    Script *self = (Script *)JS_GetContextPrivate(cx);
-
-    try
-    {
-        arg = JS_ARGV(cx, argv)[0];
-        if (!JSVAL_IS_OBJECT(arg))
-            return JS_TRUE;
-
-        if (!JS_ValueToObject(cx, arg, &js_cds_obj))
-            return JS_TRUE;
-
-        JS_ARGV(cx, argv)[0] = OBJECT_TO_JSVAL(js_cds_obj);
-
-        Ref<CdsObject> cds_obj = self->jsObject2cdsObject(js_cds_obj, nil);
-        js_cds_clone_obj = JS_NewObject(cx, NULL, NULL, NULL);
-        JS_ARGV(cx, argv)[1] = OBJECT_TO_JSVAL(js_cds_clone_obj);
-
-        self->cdsObject2jsObject(cds_obj, js_cds_clone_obj);
-
-        JS_SET_RVAL(cx, argv, OBJECT_TO_JSVAL(js_cds_clone_obj));
-        return JS_TRUE;
+    auto *self = Script::getContextScript(ctx);
+    if (!duk_is_object(ctx, 0))
+        return duk_error(ctx, DUK_ERR_TYPE_ERROR, "copyObject argument is not an object");
+    Ref<CdsObject> cds_obj = self->dukObject2cdsObject(nullptr);
+    self->cdsObject2dukObject(cds_obj);
+    return 1;
+}
 
-    }
-    catch (ServerShutdownException se)
-    {
-        log_warning("Aborting script execution due to server shutdown.\n");
-        JS_SET_RVAL(cx, argv, JSVAL_VOID);
-        return JS_FALSE;
-    }
-    catch (Exception e)
+duk_ret_t
+js_addCdsObject(duk_context *ctx)
+{
+    auto *self = Script::getContextScript(ctx);
+
+    if (!duk_is_object(ctx, 0))
+        return 0;
+    duk_to_object(ctx, 0);
+    //stack: js_cds_obj
+    const char *ts = duk_to_string(ctx, 1);
+    if (!ts)
+        ts = "/";
+    String path = ts;
+    //stack: js_cds_obj path
+    String containerclass = nullptr;
+    if (!duk_is_null_or_undefined(ctx, 2))
     {
-        log_error("%s\n", e.getMessage().c_str());
-        e.printStackTrace();
+        containerclass = duk_to_string(ctx, 2);
+        if (!string_ok(containerclass))
+            containerclass = nullptr;
     }
-    JS_SET_RVAL(cx, argv, JSVAL_VOID);
-    return JS_TRUE;
-}
+    //stack: js_cds_obj path containerclass
 
-JSBool
-js_addCdsObject(JSContext *cx, uintN argc, jsval *argv)
-{
     try
     {
-        jsval arg;
-        JSString *str;
-        String path;
-        String containerclass;
-        char *ts;
-
-        JSObject *js_cds_obj;
-        JSObject *js_orig_obj = NULL;
         Ref<CdsObject> orig_object;
 
         Ref<StringConverter> p2i;
         Ref<StringConverter> i2i;
 
-        Script *self = (Script *)JS_GetContextPrivate(cx);
-
-        if (self == NULL)
-        {
-            log_debug("Could not retrieve class instance from global object\n");
-            return JS_FALSE;
-        }
-
         if (self->whoami() == S_PLAYLIST)
         {
             p2i = StringConverter::p2i();
@@ -159,116 +101,66 @@ js_addCdsObject(JSContext *cx, uintN argc, jsval *argv)
         {
             i2i = StringConverter::i2i();
         }
- 
-        arg = JS_ARGV(cx, argv)[0];
-        if (!JSVAL_IS_OBJECT(arg))
-        {
-            JS_SET_RVAL(cx, argv, JSVAL_VOID);
-            return JS_TRUE;
-        }
-        if (!JS_ValueToObject(cx, arg, &js_cds_obj))
-        {
-            JS_SET_RVAL(cx, argv, JSVAL_VOID);
-            return JS_TRUE;
-        }
-
-        // root it
-        JS_ARGV(cx, argv)[0] = OBJECT_TO_JSVAL(js_cds_obj);
 
-        str = JS_ValueToString(cx, JS_ARGV(cx, argv)[1]);
-        if (!str)
-        {
-            path = _("/");
-        }
-        else
-        {
-            ts = JS_EncodeString(cx, str);
-            if (ts)
-            {
-                path = ts;
-                JS_free(cx, ts);
-            }
-        }
-
-        JSString *cont = JS_ValueToString(cx, JS_ARGV(cx, argv)[2]);
-        if (cont)
-        {
-            ts = JS_EncodeString(cx, cont);
-            if (ts)
-            {
-                containerclass = ts;
-                JS_free(cx, ts);
-            }
-            containerclass = ts;
-            if (!string_ok(containerclass) || containerclass == "undefined")
-                containerclass = nil;
-        }
-
-        JSObject *obj = JS_THIS_OBJECT(cx, argv);
         if (self->whoami() == S_PLAYLIST)
-            js_orig_obj = self->getObjectProperty(obj, _("playlist"));
+            duk_get_global_string(ctx, "playlist");
         else if (self->whoami() == S_IMPORT)
-            js_orig_obj = self->getObjectProperty(obj, _("orig"));
-        
-        if (js_orig_obj == NULL)
+            duk_get_global_string(ctx, "orig");
+        else
+            duk_push_undefined(ctx);
+        //stack: js_cds_obj path containerclass js_orig_obj
+
+        if (duk_is_undefined(ctx, -1))
         {
             log_debug("Could not retrieve orig/playlist object\n");
-            JS_SET_RVAL(cx, argv, JSVAL_VOID);
-            return JS_TRUE;
+            return 0;
         }
 
-        // root it
-        JS_ARGV(cx, argv)[1] = OBJECT_TO_JSVAL(js_orig_obj);
-
-        orig_object = self->jsObject2cdsObject(js_orig_obj, self->getProcessedObject());
-        if (orig_object == nil)
-        {
-            JS_SET_RVAL(cx, argv, JSVAL_VOID);
-            return JS_TRUE;
-        }
+        orig_object = self->dukObject2cdsObject(self->getProcessedObject());
+        if (orig_object == nullptr)
+            return 0;
 
         Ref<CdsObject> cds_obj;
         Ref<ContentManager> cm = ContentManager::getInstance();
         int pcd_id = INVALID_OBJECT_ID;
 
+        duk_swap_top(ctx, 0);
+        //stack: js_orig_obj path containerclass js_cds_obj
         if (self->whoami() == S_PLAYLIST)
-        {  
-            int otype = self->getIntProperty(js_cds_obj, _("objectType"), -1);
+        {
+            int otype = self->getIntProperty(_("objectType"), -1);
             if (otype == -1)
             {
                 log_error("missing objectType property\n");
-                JS_SET_RVAL(cx, argv, JSVAL_VOID);
-                return JS_TRUE;
+                return 0;
             }
 
             if (!IS_CDS_ITEM_EXTERNAL_URL(otype) &&
                 !IS_CDS_ITEM_INTERNAL_URL(otype))
-            { 
-                String loc = self->getProperty(js_cds_obj, _("location"));
-                if (string_ok(loc) && 
+            {
+                String loc = self->getProperty(_("location"));
+                if (string_ok(loc) &&
                    (IS_CDS_PURE_ITEM(otype) || IS_CDS_ACTIVE_ITEM(otype)))
                     loc = normalizePath(loc);
 
                 pcd_id = cm->addFile(loc, false, false, true);
                 if (pcd_id == INVALID_OBJECT_ID)
                 {
-                    JS_SET_RVAL(cx, argv, JSVAL_VOID);
-                    return JS_TRUE;
+                    return 0;
                 }
 
                 Ref<CdsObject> mainObj = Storage::getInstance()->loadObject(pcd_id);
-                cds_obj = self->jsObject2cdsObject(js_cds_obj, mainObj);
+                cds_obj = self->dukObject2cdsObject(mainObj);
             }
             else
-                cds_obj = self->jsObject2cdsObject(js_cds_obj, self->getProcessedObject());
+                cds_obj = self->dukObject2cdsObject(self->getProcessedObject());
         }
         else
-            cds_obj = self->jsObject2cdsObject(js_cds_obj, orig_object);
-        
-        if (cds_obj == nil)
+            cds_obj = self->dukObject2cdsObject(orig_object);
+
+        if (cds_obj == nullptr)
         {
-            JS_SET_RVAL(cx, argv, JSVAL_VOID);
-            return JS_TRUE;
+            return 0;
         }
 
         int id;
@@ -278,7 +170,7 @@ js_addCdsObject(JSContext *cx, uintN argc, jsval *argv)
              getBoolOption(CFG_IMPORT_SCRIPTING_PLAYLIST_SCRIPT_LINK_OBJECTS)))
         {
             path = p2i->convert(path);
-            id = cm->addContainerChain(path, containerclass, 
+            id = cm->addContainerChain(path, containerclass,
                     orig_object->getID());
         }
         else
@@ -287,7 +179,7 @@ js_addCdsObject(JSContext *cx, uintN argc, jsval *argv)
                 path = p2i->convert(path);
             else
                 path = i2i->convert(path);
-            
+
             id = cm->addContainerChain(path, containerclass);
         }
 
@@ -303,8 +195,7 @@ js_addCdsObject(JSContext *cx, uintN argc, jsval *argv)
             {
                 if (pcd_id == INVALID_OBJECT_ID)
                 {
-                    JS_SET_RVAL(cx, argv, JSVAL_VOID);
-                    return JS_TRUE;
+                    return 0;
                 }
 
                 /// \todo check why this if is needed?
@@ -317,7 +208,7 @@ js_addCdsObject(JSContext *cx, uintN argc, jsval *argv)
 
             cds_obj->setFlag(OBJECT_FLAG_USE_RESOURCE_REF);
         }
-        else if (IS_CDS_ITEM_EXTERNAL_URL(cds_obj->getObjectType()) || 
+        else if (IS_CDS_ITEM_EXTERNAL_URL(cds_obj->getObjectType()) ||
                  IS_CDS_ITEM_INTERNAL_URL(cds_obj->getObjectType()))
         {
             if ((self->whoami() == S_PLAYLIST) &&
@@ -334,109 +225,70 @@ js_addCdsObject(JSContext *cx, uintN argc, jsval *argv)
 
         /* setting object ID as return value */
         String tmp = String::from(id);
-
-        JSString *str2 = JS_NewStringCopyN(cx, tmp.c_str(), tmp.length());
-        if (!str2)
-        {
-            JS_SET_RVAL(cx, argv, JSVAL_VOID);
-            return JS_TRUE;
-        }
-        
-        JS_SET_RVAL(cx, argv, STRING_TO_JSVAL(str2));
-        return JS_TRUE;
+        duk_push_string(ctx, tmp.c_str());
+        return 1;
     }
-    catch (ServerShutdownException se)
+    catch (const ServerShutdownException & se)
     {
         log_warning("Aborting script execution due to server shutdown.\n");
-        JS_SET_RVAL(cx, argv, JSVAL_VOID);
-        return JS_FALSE;
+        return duk_error(ctx, DUK_ERR_ERROR, "Aborting script execution due to server shutdown.\n");
     }
-    catch (Exception e)
+    catch (const Exception & e)
     {
         log_error("%s\n", e.getMessage().c_str());
         e.printStackTrace();
     }
-    JS_SET_RVAL(cx, argv, JSVAL_VOID);
-    return JS_TRUE;
+    return 0;
 }
 
-static JSBool convert_charset_generic(JSContext *cx, uintN argc, jsval *argv, charset_convert_t chr)
+static duk_ret_t convert_charset_generic(duk_context *ctx, charset_convert_t chr)
 {
+    auto *self = Script::getContextScript(ctx);
+    if (duk_get_top(ctx) != 1)
+        return DUK_RET_SYNTAX_ERROR;
+    if (!duk_is_string(ctx, 0))
+        return DUK_RET_TYPE_ERROR;
+    const char *ts = duk_to_string(ctx, 0);
+    duk_pop(ctx);
+
     try
     {
-        JSString *str;
-        String result;
-
-        Script *self = (Script *)JS_GetContextPrivate(cx);
-
-        if (self == NULL)
-        {
-            log_debug("Could not retrieve class instance from global object\n");
-            JS_SET_RVAL(cx, argv, JSVAL_VOID);
-            return JS_FALSE;
-        }
-
-        if (JSVAL_IS_STRING(JS_ARGV(cx, argv)[0]))
-        {
-            str = JS_ValueToString(cx, JS_ARGV(cx, argv)[0]);
-            if (str)
-            {
-                 
-                char *ts = JS_EncodeString(cx, str);
-                if (ts)
-                {
-                    result = ts;
-                    JS_free(cx, ts);
-                }
-            }
-        }
-
-        if (result != nil)
-        {
-            result = self->convertToCharset(result, chr);
-            JSString *str2 = JS_NewStringCopyN(cx, result.c_str(), result.length());
-            if (!str2)
-            {
-                JS_SET_RVAL(cx, argv, JSVAL_VOID);
-                return JS_TRUE;
-            }
-            JS_SET_RVAL(cx, argv, STRING_TO_JSVAL(str2));
-        }
+        String result = self->convertToCharset(_(ts), chr);
+        duk_push_lstring(ctx, result.c_str(), result.length());
+        return 1;
     }
-    catch (ServerShutdownException se)
+    catch (const ServerShutdownException & se)
     {
         log_warning("Aborting script execution due to server shutdown.\n");
-        JS_SET_RVAL(cx, argv, JSVAL_VOID);
-        return JS_FALSE;
+        return DUK_RET_ERROR;
     }
-    catch (Exception e)
+    catch (const Exception & e)
     {
         log_error("%s\n", e.getMessage().c_str());
         e.printStackTrace();
     }
-    JS_SET_RVAL(cx, argv, JSVAL_VOID);
-    return JS_TRUE;
+    return 0;
 }
 
 
-JSBool js_f2i(JSContext *cx, uintN argc, jsval *argv)
+duk_ret_t js_f2i(duk_context *ctx)
 {
-     return convert_charset_generic(cx, argc, argv, F2I);
+    return convert_charset_generic(ctx, F2I);
 }
 
-JSBool js_m2i(JSContext *cx, uintN argc, jsval *argv)
+duk_ret_t js_m2i(duk_context *ctx)
 {
-     return convert_charset_generic(cx, argc, argv, M2I);
+    return convert_charset_generic(ctx, M2I);
 }
 
-JSBool js_p2i(JSContext *cx, uintN argc, jsval *argv)
+duk_ret_t js_p2i(duk_context *ctx)
 {
-     return convert_charset_generic(cx, argc, argv, P2I);
+    return convert_charset_generic(ctx, P2I);
 }
 
-JSBool js_j2i(JSContext *cx, uintN argc, jsval *argv)
+duk_ret_t js_j2i(duk_context *ctx)
 {
-     return convert_charset_generic(cx, argc, argv, J2I);
+    return convert_charset_generic(ctx, J2I);
 }
 
 //} // extern "C"
diff --git a/src/scripting/js_functions.h b/src/scripting/js_functions.h
index 57368f4..749064b 100644
--- a/src/scripting/js_functions.h
+++ b/src/scripting/js_functions.h
@@ -33,24 +33,29 @@
 #ifndef __SCRIPTING_JS_FUNCTIONS_H__
 #define __SCRIPTING_JS_FUNCTIONS_H__
 
-#include <jsapi.h>
+#include <duktape.h>
 
 extern "C" {
 
 /// \brief Log output.
-JSBool js_print(JSContext *cx, uintN argc, jsval *argv);
+duk_ret_t js_print(duk_context *ctx);
 
 /// \brief Adds an object to the database.
-JSBool js_addCdsObject(JSContext *cx, uintN argc, jsval *argv);
+duk_ret_t js_addCdsObject(duk_context *ctx);
 
 /// \brief Makes a copy of an CDS object.
-JSBool js_copyObject(JSContext *cx, uintN argc, jsval *argv);
-
-JSBool js_f2i(JSContext *cx, uintN argc, jsval *argv);
-JSBool js_m2i(JSContext *cx, uintN argc, jsval *argv);
-JSBool js_p2i(JSContext *cx, uintN argc, jsval *argv);
-JSBool js_j2i(JSContext *cx, uintN argc, jsval *argv);
-
+duk_ret_t js_copyObject(duk_context *ctx);
+
+/// filesystem charset to internal
+duk_ret_t js_f2i(duk_context *ctx);
+/// metadata charset to internal
+duk_ret_t js_m2i(duk_context *ctx);
+/// playlist charset to internal
+duk_ret_t js_p2i(duk_context *ctx);
+/// js charset to internal
+duk_ret_t js_j2i(duk_context *ctx);
+
+#define log_debug_stack(ctx) do{duk_push_context_dump(ctx);log_debug("%s\n", duk_safe_to_string(ctx, -1));duk_pop(ctx);}while(0)
 } // extern "C"
 
 #endif//__SCRIPTING_JS_FUNCTIONS_H__
diff --git a/src/scripting/playlist_parser_script.cc b/src/scripting/playlist_parser_script.cc
index 8846327..203cc77 100644
--- a/src/scripting/playlist_parser_script.cc
+++ b/src/scripting/playlist_parser_script.cc
@@ -29,14 +29,11 @@
 
 /// \file playlist_parser_script.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_JS
 
 #include "playlist_parser_script.h"
 #include "config_manager.h"
+#include "content_manager.h"
 #include "js_functions.h"
 
 #define ONE_TEXTLINE_BYTES  1024
@@ -45,10 +42,10 @@ using namespace zmm;
 
 extern "C" {
 
-static JSBool
-js_readln(JSContext *cx, uintN argc, jsval *vp)
+static duk_ret_t
+js_readln(duk_context *ctx)
 {
-    PlaylistParserScript *self = (PlaylistParserScript *)JS_GetContextPrivate(cx);
+    auto *self = (PlaylistParserScript *)Script::getContextScript(ctx);
 
     String line;
     
@@ -56,58 +53,69 @@ js_readln(JSContext *cx, uintN argc, jsval *vp)
     {
         line = self->readln();
     }
-    catch (ServerShutdownException se)
+    catch (const ServerShutdownException & se)
     {
         log_warning("Aborting script execution due to server shutdown.\n");
-        return JS_FALSE;
+        return duk_error(ctx, DUK_ERR_ERROR, "Aborting script execution due to server shutdown.");
     }
-    catch (Exception e)
+    catch (const Exception & e)
     {
         e.printStackTrace();
-        return JS_TRUE;
+        return 0;
     }
 
-    JSString *jsline = JS_NewStringCopyZ(cx, line.c_str());
+    duk_push_string(ctx, line.c_str());
+    return 1;
+}
+
+static duk_ret_t
+js_getCdsObject(duk_context *ctx)
+{
+    auto *self = (PlaylistParserScript *)Script::getContextScript(ctx);
+
+    if (!duk_is_string(ctx, 0))
+        return 0;
+
+    String path = duk_to_string(ctx, 0);
+    duk_pop(ctx);
 
-    JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(jsline));
-  
-    return JS_TRUE;
+    if (!string_ok(path))
+        return 0;
+
+    Ref<Storage> storage = Storage::getInstance();
+    Ref<CdsObject> obj = storage->findObjectByPath(path);
+    if (obj == nullptr) {
+        Ref<ContentManager> cm = ContentManager::getInstance();
+        obj = cm->createObjectFromFile(path);
+        if (obj == nullptr) // object ignored
+            return 0;
+    }
+    self->cdsObject2dukObject(obj);
+    return 1;
 }
-    
+
 } // extern "C"
 
-PlaylistParserScript::PlaylistParserScript(Ref<Runtime> runtime) : Script(runtime)
+PlaylistParserScript::PlaylistParserScript(Ref<Runtime> runtime) : Script(runtime, "playlist")
 {
-    currentHandle = NULL;
+    currentHandle = nullptr;
     currentObjectID = INVALID_OBJECT_ID;
-    currentLine = NULL;
+    currentLine = nullptr;
  
-#ifdef JS_THREADSAFE
-    JS_SetContextThread(cx);
-    JS_BeginRequest(cx);
-#endif
-  
     try
     {
+        AutoLock lock(runtime->getMutex());
         defineFunction(_("readln"), js_readln, 0);
+        defineFunction(_("getCdsObject"), js_getCdsObject, 1);
 
         String scriptPath = ConfigManager::getInstance()->getOption(CFG_IMPORT_SCRIPTING_PLAYLIST_SCRIPT); 
         load(scriptPath);
-        JS_AddNamedObjectRoot(cx, &script, "PlaylistScript");
     }
-    catch (Exception ex)
+    catch (const Exception & ex)
     {
-#ifdef JS_THREADSAFE
-        JS_EndRequest(cx);
-        JS_ClearContextThread(cx);
-#endif
         throw ex;
     }
     
-#ifdef JS_THREADSAFE
-        JS_EndRequest(cx);
-        JS_ClearContextThread(cx);
-#endif
 }
 
 String PlaylistParserScript::readln()
@@ -116,13 +124,13 @@ String PlaylistParserScript::readln()
     if (!currentHandle)
         throw _Exception(_("Readline not yet setup for use"));
 
-    if ((currentTask != nil) && (!currentTask->isValid()))
-        return nil;
+    if ((currentTask != nullptr) && (!currentTask->isValid()))
+        return nullptr;
 
     while (true)
     {
-        if(fgets(currentLine, ONE_TEXTLINE_BYTES, currentHandle) == NULL)
-            return nil;
+        if(fgets(currentLine, ONE_TEXTLINE_BYTES, currentHandle) == nullptr)
+            return nullptr;
 
         ret = trim_string(currentLine);
         if (string_ok(ret))
@@ -132,26 +140,14 @@ String PlaylistParserScript::readln()
 
 void PlaylistParserScript::processPlaylistObject(zmm::Ref<CdsObject> obj, Ref<GenericTask> task)
 {
-#ifdef JS_THREADSAFE
-    JS_SetContextThread(cx);
-    JS_BeginRequest(cx);
-#endif
-    if ((currentObjectID != INVALID_OBJECT_ID) || (currentHandle != NULL) ||
-            (currentLine != NULL))
+    if ((currentObjectID != INVALID_OBJECT_ID) || (currentHandle != nullptr) ||
+            (currentLine != nullptr))
     {
-#ifdef JS_THREADSAFE
-        JS_EndRequest(cx);
-        JS_ClearContextThread(cx);
-#endif
         throw _Exception(_("recursion not allowed!"));
     }
 
     if (!IS_CDS_PURE_ITEM(obj->getObjectType()))
     {
-#ifdef JS_THREADSAFE
-        JS_EndRequest(cx);
-        JS_ClearContextThread(cx);
-#endif
         throw _Exception(_("only allowed for pure items"));
     }
 
@@ -161,11 +157,7 @@ void PlaylistParserScript::processPlaylistObject(zmm::Ref<CdsObject> obj, Ref<Ge
     if (!currentLine)
     {
         currentObjectID = INVALID_OBJECT_ID;
-        currentTask = nil;
-#ifdef JS_THREADSAFE
-        JS_EndRequest(cx);
-        JS_ClearContextThread(cx);
-#endif
+        currentTask = nullptr;
         throw _Exception(_("failed to allocate memory for playlist parsing!"));
     }
 
@@ -175,81 +167,63 @@ void PlaylistParserScript::processPlaylistObject(zmm::Ref<CdsObject> obj, Ref<Ge
     if (!currentHandle)
     {
         currentObjectID = INVALID_OBJECT_ID;
-        currentTask = nil;
+        currentTask = nullptr;
         FREE(currentLine);
-#ifdef JS_THREADSAFE
-        JS_EndRequest(cx);
-        JS_ClearContextThread(cx);
-#endif
         throw _Exception(_("failed to open file: ") + obj->getLocation());
     }
 
-    JSObject *playlist = JS_NewObject(cx, NULL, NULL, glob);
+    AutoLock lock(runtime->getMutex());
 
     try
     {
-        setObjectProperty(glob, _("playlist"), playlist);
-        cdsObject2jsObject(obj, playlist);
+        cdsObject2dukObject(obj);
+        duk_put_global_string(ctx, "playlist");
 
         execute();
+
+        duk_push_global_object(ctx);
+        duk_del_prop_string(ctx, -1, "playlist");
+        duk_pop(ctx);
     }
 
-    catch (Exception e)
+    catch (const Exception & e)
     {
+        duk_push_global_object(ctx);
+        duk_del_prop_string(ctx, -1, "playlist");
+        duk_pop(ctx);
+
         fclose(currentHandle);
-        currentHandle = NULL;
+        currentHandle = nullptr;
 
         FREE(currentLine);
-        currentLine = NULL;
+        currentLine = nullptr;
 
         currentObjectID = INVALID_OBJECT_ID;
-        currentTask = nil;
+        currentTask = nullptr;
 
-#ifdef JS_THREADSAFE
-        JS_EndRequest(cx);
-        JS_ClearContextThread(cx);
-#endif
         throw e;
     }
 
     fclose(currentHandle);
-    currentHandle = NULL;
+    currentHandle = nullptr;
 
     FREE(currentLine);
-    currentLine = NULL;
+    currentLine = nullptr;
 
     currentObjectID = INVALID_OBJECT_ID;
-    currentTask = nil;
+    currentTask = nullptr;
 
     gc_counter++;
     if (gc_counter > JS_CALL_GC_AFTER_NUM)
     {
-        JS_MaybeGC(cx);
+        duk_gc(ctx, 0);
         gc_counter = 0;
     }
 
-#ifdef JS_THREADSAFE
-    JS_EndRequest(cx);
-    JS_ClearContextThread(cx);
-#endif
-
 }
 
 
 PlaylistParserScript::~PlaylistParserScript()
 {
-#ifdef JS_THREADSAFE
-    JS_SetContextThread(cx);
-    JS_BeginRequest(cx);
-#endif
-
-    if (script)
-        JS_RemoveObjectRoot(cx, &script);
-
-#ifdef JS_THREADSAFE
-    JS_EndRequest(cx);
-    JS_ClearContextThread(cx);
-#endif
-
 }
 #endif // HAVE_JS
diff --git a/src/scripting/runtime.cc b/src/scripting/runtime.cc
index 6819de8..b666a1d 100644
--- a/src/scripting/runtime.cc
+++ b/src/scripting/runtime.cc
@@ -29,31 +29,42 @@
 
 /// \file runtime.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_JS
 
 #include "runtime.h"
 
 using namespace zmm;
+using namespace std;
 
-SINGLETON_MUTEX(Runtime, true);
-
-Runtime::Runtime() : Singleton<Runtime>()
+static void fatal_handler(void *udata, const char *msg)
 {
-    /* initialize the JS run time, and return result in rt */
-    rt = JS_NewRuntime(8L * 1024L * 1024L);
-    if (!rt)
-        throw Exception(_("Scripting: could not initialize js runtime"));
+    log_error("Fatal Duktape error: %s\n", msg ? msg : "no message");
+    abort();
+}
+
+Runtime::Runtime() {
+    ctx = duk_create_heap(nullptr, nullptr, nullptr, nullptr, fatal_handler);
 }
 Runtime::~Runtime()
 {
-    if (rt)
-        JS_DestroyRuntime(rt);
-    rt = NULL;
-    JS_ShutDown();
+    duk_destroy_heap(ctx);
+}
+
+duk_context *Runtime::createContext(std::string name)
+{
+    duk_push_heap_stash(ctx);
+    duk_idx_t thread_idx = duk_push_thread_new_globalenv(ctx);
+    duk_context *newctx = duk_get_context(ctx, thread_idx);
+    duk_put_prop_string(ctx, -2, name.c_str());
+    duk_pop(ctx);
+    return newctx;
+}
+
+void Runtime::destroyContext(std::string name)
+{
+    duk_push_heap_stash(ctx);
+    duk_del_prop_string(ctx, -1, name.c_str());
+    duk_pop(ctx);
 }
 
 #endif // HAVE_JS
diff --git a/src/scripting/runtime.h b/src/scripting/runtime.h
index 5090bb3..eb3e3ce 100644
--- a/src/scripting/runtime.h
+++ b/src/scripting/runtime.h
@@ -32,26 +32,25 @@
 #ifndef __SCRIPTING_RUNTIME_H__
 #define __SCRIPTING_RUNTIME_H__
 
-#define XP_UNIX 1
-
-#include <jsapi.h>
+#include "duktape.h"
 #include <pthread.h>
 #include "common.h"
-#include "sync.h"
 #include "singleton.h"
 
 /// \brief Runtime class definition.
-class Runtime : public Singleton<Runtime>
+class Runtime : public Singleton<Runtime, std::recursive_mutex>
 {
 protected:
-    JSRuntime *rt;
+    duk_context *ctx;
 
 public:
     Runtime();
     virtual ~Runtime();
     
-    /// \brief Returns the runtime for script execution.
-    JSRuntime *getRT() { return rt; }
+    /// \brief Returns a new (sub)context. !!! Not thread-safe !!!
+    duk_context *createContext(std::string name);
+    void destroyContext(std::string name);
+    std::recursive_mutex& getMutex() { return mutex; }
 };
 
 #endif // __SCRIPTING_RUNTIME_H__
diff --git a/src/scripting/script.cc b/src/scripting/script.cc
index 85ceebc..a433fb8 100644
--- a/src/scripting/script.cc
+++ b/src/scripting/script.cc
@@ -29,10 +29,6 @@
 
 /// \file script.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_JS
 
 #include "script.h"
@@ -49,362 +45,171 @@
     #include "youtube_content_handler.h"
 #endif
 
-#ifdef WEBORAMA
-    #include "weborama_content_handler.h"
-#endif
-
 #ifdef ATRAILERS
     #include "atrailers_content_handler.h"
 #endif
 
-#ifdef HAVE_LIBDVDNAV
-    #include "metadata/dvd_handler.h"
-#endif
-
 using namespace zmm;
 
-static JSFunctionSpec js_global_functions[] =
+static duk_function_list_entry js_global_functions[] =
 {
-    JS_FS("print",          js_print,          1, 0),
-    JS_FS("addCdsObject",   js_addCdsObject,   3, 0),
-    JS_FS("copyObject",     js_copyObject,     2, 0),
-    JS_FS("f2i",            js_f2i,            1, 0),
-    JS_FS("m2i",            js_m2i,            1, 0),
-    JS_FS("p2i",            js_m2i,            1, 0),
-    JS_FS("j2i",            js_m2i,            1, 0),
-    JS_FS_END 
+    { "print",          js_print,        DUK_VARARGS },
+    { "addCdsObject",   js_addCdsObject, 3 },
+    { "copyObject",     js_copyObject,   1 },
+    { "f2i",            js_f2i,          1 },
+    { "m2i",            js_m2i,          1 },
+    { "p2i",            js_p2i,          1 },
+    { "j2i",            js_j2i,          1 },
+    { nullptr,          nullptr,         0 },
 };
 
-String Script::getProperty(JSObject *obj, String name)
+String Script::getProperty(String name)
 {
-    jsval val;
-    JSString *str;
     String ret;
-    if (!JS_GetProperty(cx, obj, name.c_str(), &val))
-        return nil;
-    if (val == JSVAL_VOID)
-        return nil;
-    str = JS_ValueToString(cx, val);
-    if (!str)
-        return nil;
-
-    char *ts = JS_EncodeString(cx, str);
-    if (!ts)
+    if (!duk_is_object_coercible(ctx, -1))
+        return nullptr;
+    duk_get_prop_string(ctx, -1, name.c_str());
+    if (duk_is_null_or_undefined(ctx, -1) || !duk_to_string(ctx, -1))
     {
-        return nil;
+        duk_pop(ctx);
+        return nullptr;
     }
-    ret = ts;
-    JS_free(cx, ts);
+    ret = duk_get_string(ctx, -1);
+    duk_pop(ctx);
     return ret;
 }
 
-int Script::getBoolProperty(JSObject *obj, String name)
+int Script::getBoolProperty(String name)
 {
-    jsval val;
-    JSBool boolVal;
-
-    if (!JS_GetProperty(cx, obj, name.c_str(), &val))
-        return -1;
-    if (val == JSVAL_VOID)
+    int ret;
+    if (!duk_is_object_coercible(ctx, -1))
         return -1;
-    if (!JS_ValueToBoolean(cx, val, &boolVal))
+    duk_get_prop_string(ctx, -1, name.c_str());
+    if (duk_is_null_or_undefined(ctx, -1))
+    {
+        duk_pop(ctx);
         return -1;
-    return (boolVal ? 1 : 0);
+    }
+    ret = duk_to_boolean(ctx, -1);
+    duk_pop(ctx);
+    return ret;
 }
 
-int Script::getIntProperty(JSObject *obj, String name, int def)
+int Script::getIntProperty(String name, int def)
 {
-    jsval val;
-    int intVal;
-
-    if (!JS_GetProperty(cx, obj, name.c_str(), &val))
+    int ret;
+    if (!duk_is_object_coercible(ctx, -1))
         return def;
-    if (val == JSVAL_VOID)
-        return def;
-    if (!JS_ValueToInt32(cx, val, &intVal))
+    duk_get_prop_string(ctx, -1, name.c_str());
+    if (duk_is_null_or_undefined(ctx, -1))
+    {
+        duk_pop(ctx);
         return def;
-    return intVal;
-}
-
-JSObject *Script::getObjectProperty(JSObject *obj, String name)
-{
-    jsval val;
-    JSObject *js_obj;
-
-    if (!JS_GetProperty(cx, obj, name.c_str(), &val))
-        return NULL;
-    if (val == JSVAL_VOID)
-        return NULL;
-    if (!JS_ValueToObject(cx, val, &js_obj))
-        return NULL;
-    return js_obj;
-}
-
-void Script::setProperty(JSObject *obj, String name, String value)
-{
-    jsval val;
-    JSString *str = JS_NewStringCopyN(cx, value.c_str(), value.length());
-    if (!str)
-        return;
-    val = STRING_TO_JSVAL(str);
-    if (!JS_SetProperty(cx, obj, name.c_str(), &val))
-        return;
-}
-
-void Script::setIntProperty(JSObject *obj, String name, int value)
-{
-    jsval val;
-    if (!JS_NewNumberValue(cx, (jsdouble)value, &val))
-        return;
-    if (!JS_SetProperty(cx, obj, name.c_str(), &val))
-        return;
-}
-
-void Script::setObjectProperty(JSObject *parent, String name, JSObject *obj)
-{
-    jsval val;
-    val = OBJECT_TO_JSVAL(obj);
-    if (!JS_SetProperty(cx, parent, name.c_str(), &val)) {
-        log_error("Failed to set object property %s\n", name.c_str());
     }
+    ret = duk_to_int32(ctx, -1);
+    duk_pop(ctx);
+    return ret;
 }
 
-void Script::deleteProperty(JSObject *obj, String name)
+void Script::setProperty(String name, String value)
 {
-    JS_DeleteProperty(cx, obj, name.c_str());
+    duk_push_string(ctx, value.c_str());
+    duk_put_prop_string(ctx, -2, name.c_str());
 }
 
-static void
-js_error_reporter(JSContext *cx, const char *message, JSErrorReport *report)
+void Script::setIntProperty(String name, int value)
 {
-    int n;
-    const char *ctmp;
-
-    int reportWarnings = 1; // TODO move to object field
-
-    Ref<StringBuffer> buf(new StringBuffer());
-
-    do
-    {
-        if (!report)
-        {
-            *buf << (char *)message;
-            break;
-        }
-
-        // Conditionally ignore reported warnings.
-        if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings)
-            return;
-
-        String prefix;
-        Ref<StringBuffer> prefix_buf(new StringBuffer());
-
-        if (report->filename)
-            *prefix_buf << (char *)report->filename << ":";
-
-        if (report->lineno)
-        {
-            *prefix_buf << (int)report->lineno << ": ";
-        }
-        if (JSREPORT_IS_WARNING(report->flags))
-        {
-            if (JSREPORT_IS_STRICT(report->flags))
-                *prefix_buf << "(STRICT WARN)";
-            else
-                *prefix_buf << "(WARN)";
-        }
-
-        prefix = prefix_buf->toString();
-
-        // embedded newlines
-        while ((ctmp = strchr(message, '\n')) != 0)
-        {
-            ctmp++;
-            if (prefix.length())
-                *buf << prefix;
-            *buf << String((char *)message, ctmp - message);
-            message = ctmp;
-        }
-
-        // If there were no filename or lineno, the prefix might be empty
-        if (prefix.length())
-            *buf << prefix;
-        *buf << (char *)message << "\n";
-
-        if (report->linebuf)
-        {
-            // report->linebuf usually ends with a newline.
-            n = strlen(report->linebuf);
-            *buf << prefix << (char *)report->linebuf;
-            *buf << (char *)((n > 0 && report->linebuf[n-1] == '\n') ? "" : "\n");
-            *buf << prefix;
-            /*
-            n = PTRDIFF(report->tokenptr, report->linebuf, char);
-            for (i = j = 0; i < n; i++)
-            {
-                if (report->linebuf[i] == '\t')
-                {
-                    for (k = (j + 8) & ~7; j < k; j++)
-                    {
-                        fputc('.', gErrFile);
-                    }
-                    continue;
-                }
-                fputc('.', stdout);
-                j++;
-            }
-            fputs("^\n", stdout);
-            */
-        }
-    }
-    while (0);
-
-    String err = buf->toString();
-    log_js("%s\n", err.c_str());
+    duk_push_int(ctx, value);
+    duk_put_prop_string(ctx, -2, name.c_str());
 }
 
 /* **************** */
 
-Script::Script(Ref<Runtime> runtime) : Object()
+Script::Script(Ref<Runtime> runtime, std::string name) : Object(), name(name)
 {
     gc_counter = 0;
 
     this->runtime = runtime;
-    rt = runtime->getRT();
 
     /* create a context and associate it with the JS run time */
-    cx = JS_NewContext(rt, 8192);
-    if (! cx)
+    AutoLock lock(runtime->getMutex());
+    ctx = runtime->createContext(name);
+    if (!ctx)
         throw _Exception(_("Scripting: could not initialize js context"));
 
-#ifdef JS_THREADSAFE
-    JS_SetContextThread(cx);
-    JS_BeginRequest(cx);
-#endif
-//    JS_SetGCZeal(cx, 2);
-
-    glob = NULL;
-    script = NULL;
-
     _p2i = StringConverter::p2i();
     _j2i = StringConverter::j2i();
     _m2i = StringConverter::m2i();
     _f2i = StringConverter::f2i();
     _i2i = StringConverter::i2i();
 
-    JS_SetErrorReporter(cx, js_error_reporter);
-    initGlobalObject();
-
-    JS_SetContextPrivate(cx, this);
+    duk_push_thread_stash(ctx, ctx);
+    duk_push_pointer(ctx, this);
+    duk_put_prop_string(ctx, -2, "this");
+    duk_pop(ctx);
 
     /* initialize contstants */
-    setIntProperty(glob, _("OBJECT_TYPE_CONTAINER"),
-            OBJECT_TYPE_CONTAINER);
-    setIntProperty(glob, _("OBJECT_TYPE_ITEM"),
-            OBJECT_TYPE_ITEM);
-    setIntProperty(glob, _("OBJECT_TYPE_ACTIVE_ITEM"),
-            OBJECT_TYPE_ACTIVE_ITEM);
-    setIntProperty(glob, _("OBJECT_TYPE_ITEM_EXTERNAL_URL"),
-            OBJECT_TYPE_ITEM_EXTERNAL_URL);
-    setIntProperty(glob, _("OBJECT_TYPE_ITEM_INTERNAL_URL"),
-            OBJECT_TYPE_ITEM_INTERNAL_URL);
+    duk_push_int(ctx, OBJECT_TYPE_CONTAINER); duk_put_global_string(ctx, "OBJECT_TYPE_CONTAINER");
+    duk_push_int(ctx, OBJECT_TYPE_ITEM); duk_put_global_string(ctx, "OBJECT_TYPE_ITEM");
+    duk_push_int(ctx, OBJECT_TYPE_ACTIVE_ITEM); duk_put_global_string(ctx, "OBJECT_TYPE_ACTIVE_ITEM");
+    duk_push_int(ctx, OBJECT_TYPE_ITEM_EXTERNAL_URL); duk_put_global_string(ctx, "OBJECT_TYPE_ITEM_EXTERNAL_URL");
+    duk_push_int(ctx, OBJECT_TYPE_ITEM_INTERNAL_URL); duk_put_global_string(ctx, "OBJECT_TYPE_ITEM_INTERNAL_URL");
 #ifdef ONLINE_SERVICES 
-    setIntProperty(glob, _("ONLINE_SERVICE_NONE"), (int)OS_None);
+    duk_push_int(ctx, (int)OS_None); duk_put_global_string(ctx, "ONLINE_SERVICE_NONE");
 #ifdef YOUTUBE
-    setIntProperty(glob, _("ONLINE_SERVICE_YOUTUBE"), (int)OS_YouTube);
-
-    setProperty(glob, _("YOUTUBE_AUXDATA_KEYWORDS"), 
-            _(YOUTUBE_AUXDATA_KEYWORDS));
-    setProperty(glob, _("YOUTUBE_AUXDATA_AVG_RATING"), 
-            _(YOUTUBE_AUXDATA_AVG_RATING));
-    setProperty(glob, _("YOUTUBE_AUXDATA_AUTHOR"), 
-            _(YOUTUBE_AUXDATA_AUTHOR));
-    setProperty(glob, _("YOUTUBE_AUXDATA_FEED"), 
-            _(YOUTUBE_AUXDATA_FEED));
-    setProperty(glob, _("YOUTUBE_AUXDATA_VIEW_COUNT"), 
-            _(YOUTUBE_AUXDATA_VIEW_COUNT));
-    setProperty(glob, _("YOUTUBE_AUXDATA_FAVORITE_COUNT"), 
-            _(YOUTUBE_AUXDATA_FAVORITE_COUNT));
-    setProperty(glob, _("YOUTUBE_AUXDATA_RATING_COUNT"), 
-            _(YOUTUBE_AUXDATA_RATING_COUNT));
-    setProperty(glob, _("YOUTUBE_AUXDATA_CATEGORY"), 
-            _(YOUTUBE_AUXDATA_CATEGORY));
-    setProperty(glob, _("YOUTUBE_AUXDATA_SUBREQUEST_NAME"), 
-            _(YOUTUBE_AUXDATA_SUBREQUEST_NAME));
-    setProperty(glob, _("YOUTUBE_AUXDATA_REQUEST"), 
-            _(YOUTUBE_AUXDATA_REQUEST));
-    setProperty(glob, _("YOUTUBE_AUXDATA_REGION"),
-            _(YOUTUBE_AUXDATA_REGION));
-
-    setIntProperty(glob, _("YOUTUBE_REQUEST_NONE"), (int)YT_request_none);
-    setIntProperty(glob, _("YOUTUBE_REQUEST_VIDEO_SEARCH"), 
-                  (int)YT_request_video_search);
-    setIntProperty(glob, _("YOUTUBE_REQUEST_STANDARD_FEED"), 
-                  (int)YT_request_stdfeed);
-    setIntProperty(glob, _("YOUTUBE_REQUEST_USER_FAVORITES"), 
-                  (int)YT_request_user_favorites);
-    setIntProperty(glob, _("YOUTUBE_REQUEST_USER_PLAYLISTS"), 
-                  (int)YT_request_user_playlists);
-    setIntProperty(glob, _("YOUTUBE_REQUEST_USER_SUBSCRIPTIONS"), 
-                   (int)YT_request_user_subscriptions);
-    setIntProperty(glob, _("YOUTUBE_REQUEST_USER_UPLOADS"), 
-                   (int)YT_request_user_uploads);
+    duk_push_int(ctx, (int)OS_YouTube); duk_put_global_string(ctx, "ONLINE_SERVICE_YOUTUBE");
+
+    duk_push_string(ctx, YOUTUBE_AUXDATA_KEYWORDS); duk_put_global_string(ctx, "YOUTUBE_AUXDATA_KEYWORDS");
+    duk_push_string(ctx, YOUTUBE_AUXDATA_AVG_RATING); duk_put_global_string(ctx, "YOUTUBE_AUXDATA_AVG_RATING");
+    duk_push_string(ctx, YOUTUBE_AUXDATA_AUTHOR); duk_put_global_string(ctx, "YOUTUBE_AUXDATA_AUTHOR");
+    duk_push_string(ctx, YOUTUBE_AUXDATA_FEED); duk_put_global_string(ctx, "YOUTUBE_AUXDATA_FEED");
+    duk_push_string(ctx, YOUTUBE_AUXDATA_VIEW_COUNT); duk_put_global_string(ctx, "YOUTUBE_AUXDATA_VIEW_COUNT");
+    duk_push_string(ctx, YOUTUBE_AUXDATA_FAVORITE_COUNT); duk_put_global_string(ctx, "YOUTUBE_AUXDATA_FAVORITE_COUNT");
+    duk_push_string(ctx, YOUTUBE_AUXDATA_RATING_COUNT); duk_put_global_string(ctx, "YOUTUBE_AUXDATA_RATING_COUNT");
+    duk_push_string(ctx, YOUTUBE_AUXDATA_CATEGORY); duk_put_global_string(ctx, "YOUTUBE_AUXDATA_CATEGORY");
+    duk_push_string(ctx, YOUTUBE_AUXDATA_SUBREQUEST_NAME); duk_put_global_string(ctx, "YOUTUBE_AUXDATA_SUBREQUEST_NAME");
+    duk_push_string(ctx, YOUTUBE_AUXDATA_REQUEST); duk_put_global_string(ctx, "YOUTUBE_AUXDATA_REQUEST");
+    duk_push_string(ctx, YOUTUBE_AUXDATA_REGION); duk_put_global_string(ctx, "YOUTUBE_AUXDATA_REGION");
+
+    duk_push_int(ctx, (int)YT_request_user_uploads); duk_put_global_string(ctx, "YOUTUBE_REQUEST_USER_UPLOADS");
 #else
-    setIntProperty(glob, _("ONLINE_SERVICE_YOUTUBE"), -1);
+    duk_push_int(ctx, -1); duk_put_global_string(ctx, "ONLINE_SERVICE_YOUTUBE");
 #endif//YOUTUBE
 
-#ifdef WEBORAMA
-    setIntProperty(glob, _("ONLINE_SERVICE_WEBORAMA"), (int)OS_Weborama);
-    setProperty(glob, _("WEBORAMA_AUXDATA_REQUEST_NAME"),
-                      _(WEBORAMA_AUXDATA_REQUEST_NAME));
-#else
-    setIntProperty(glob, _("ONLINE_SERVICE_WEBORAMA"), -1);
-#endif//WEBORAMAa
-
 #ifdef ATRAILERS
-    setIntProperty(glob, _("ONLINE_SERVICE_APPLE_TRAILERS"), (int)OS_ATrailers);
-    setProperty(glob, _("APPLE_TRAILERS_AUXDATA_POST_DATE"),
-                      _(ATRAILERS_AUXDATA_POST_DATE));
+    duk_push_int(ctx, (int)OS_ATrailers); duk_put_global_string(ctx, "ONLINE_SERVICE_APPLE_TRAILERS");
+    duk_push_string(ctx, ATRAILERS_AUXDATA_POST_DATE); duk_put_global_string(ctx, "APPLE_TRAILERS_AUXDATA_POST_DATE");
 #else
-    setIntProperty(glob, _("ONLINE_SERVICE_APPLE_TRAILERS"), -1);
+    duk_push_int(ctx, -1); duk_put_global_string(ctx, "ONLINE_SERVICE_APPLE_TRAILERS");
 #endif//ATRAILERS
 
 #ifdef SOPCAST
-    setIntProperty(glob, _("ONLINE_SERVICE_SOPCAST"), (int)OS_SopCast);
+    duk_push_int(ctx, (int)OS_SopCast); duk_put_global_string(ctx, "ONLINE_SERVICE_SOPCAST");
 #else
-    setIntProperty(glob, _("ONLINE_SERVICE_SOPCAST"), -1);
+    duk_push_int(ctx, -1); duk_put_global_string(ctx, "ONLINE_SERVICE_SOPCAST");
 #endif//SOPCAST
 
 #else // ONLINE SERVICES
-    setIntProperty(glob, _("ONLINE_SERVICE_NONE"), 0);
-    setIntProperty(glob, _("ONLINE_SERVICE_YOUTUBE"), -1);
-    setIntProperty(glob, _("ONLINE_SERVICE_WEBORAMA"), -1);
-    setIntProperty(glob, _("ONLINE_SERVICE_SOPCAST"), -1);
-    setIntProperty(glob, _("ONLINE_SERVICE_APPLE_TRAILERS"), -1);
+    duk_push_int(ctx, 0); duk_put_global_string(ctx, "ONLINE_SERVICE_NONE");
+    duk_push_int(ctx, -1); duk_put_global_string(ctx, "ONLINE_SERVICE_YOUTUBE");
+    duk_push_int(ctx, -1); duk_put_global_string(ctx, "ONLINE_SERVICE_APPLE_TRAILERS");
+    duk_push_int(ctx, -1); duk_put_global_string(ctx, "ONLINE_SERVICE_SOPCAST");
 #endif//ONLINE_SERVICES
 
     for (int i = 0; i < M_MAX; i++)
     {
-        setProperty(glob, _(MT_KEYS[i].sym), _(MT_KEYS[i].upnp));
+        duk_push_string(ctx, MT_KEYS[i].upnp); duk_put_global_string(ctx, MT_KEYS[i].sym);
     }
  
-    setProperty(glob, _("UPNP_CLASS_CONTAINER_MUSIC_ALBUM"),
-            _(UPNP_DEFAULT_CLASS_MUSIC_ALBUM));
-    setProperty(glob, _("UPNP_CLASS_CONTAINER_MUSIC_ARTIST"),
-            _(UPNP_DEFAULT_CLASS_MUSIC_ARTIST));
-    setProperty(glob, _("UPNP_CLASS_CONTAINER_MUSIC_GENRE"),
-            _(UPNP_DEFAULT_CLASS_MUSIC_GENRE));
-    setProperty(glob, _("UPNP_CLASS_CONTAINER"),
-            _(UPNP_DEFAULT_CLASS_CONTAINER));
-    setProperty(glob, _("UPNP_CLASS_ITEM"), _(UPNP_DEFAULT_CLASS_ITEM));
-    setProperty(glob, _("UPNP_CLASS_ITEM_MUSIC_TRACK"),
-            _(UPNP_DEFAULT_CLASS_MUSIC_TRACK));
-    setProperty(glob, _("UPNP_CLASS_ITEM_VIDEO"),
-            _(UPNP_DEFAULT_CLASS_VIDEO_ITEM));
-    setProperty(glob, _("UPNP_CLASS_ITEM_IMAGE"), 
-            _(UPNP_DEFAULT_CLASS_IMAGE_ITEM));
-    setProperty(glob, _("UPNP_CLASS_PLAYLIST_CONTAINER"),
-            _(UPNP_DEFAULT_CLASS_PLAYLIST_CONTAINER));
+    duk_push_string(ctx, UPNP_DEFAULT_CLASS_MUSIC_ALBUM); duk_put_global_string(ctx, "UPNP_CLASS_CONTAINER_MUSIC_ALBUM");
+    duk_push_string(ctx, UPNP_DEFAULT_CLASS_MUSIC_ARTIST); duk_put_global_string(ctx, "UPNP_CLASS_CONTAINER_MUSIC_ARTIST");
+    duk_push_string(ctx, UPNP_DEFAULT_CLASS_MUSIC_GENRE); duk_put_global_string(ctx, "UPNP_CLASS_CONTAINER_MUSIC_GENRE");
+    duk_push_string(ctx, UPNP_DEFAULT_CLASS_CONTAINER); duk_put_global_string(ctx, "UPNP_CLASS_CONTAINER");
+    duk_push_string(ctx, UPNP_DEFAULT_CLASS_ITEM); duk_put_global_string(ctx, "UPNP_CLASS_ITEM");
+    duk_push_string(ctx, UPNP_DEFAULT_CLASS_MUSIC_TRACK); duk_put_global_string(ctx, "UPNP_CLASS_ITEM_MUSIC_TRACK");
+    duk_push_string(ctx, UPNP_DEFAULT_CLASS_VIDEO_ITEM); duk_put_global_string(ctx, "UPNP_CLASS_CONTAINER_ITEM_VIDEO");
+    duk_push_string(ctx, UPNP_DEFAULT_CLASS_IMAGE_ITEM); duk_put_global_string(ctx, "UPNP_CLASS_CONTAINER_ITEM_IMAGE");
+    duk_push_string(ctx, UPNP_DEFAULT_CLASS_PLAYLIST_CONTAINER); duk_put_global_string(ctx, "UPNP_CLASS_PLAYLIST_CONTAINER");
 
     defineFunctions(js_global_functions);
 
@@ -416,127 +221,51 @@ Script::Script(Ref<Runtime> runtime) : Object()
     {
         try
         {
-            common_script = _load(common_scr_path);
-            JS_AddNamedObjectRoot(cx, &common_script, "common-script");
-            _execute(common_script);
+            _load(common_scr_path);
+            _execute();
         }
-        catch (Exception e)
+        catch (const Exception & e)
         {
-            if (common_script)
-            {
-                JS_RemoveObjectRoot(cx, &common_script);
-            }
-
             log_js("Unable to load %s: %s\n", common_scr_path.c_str(), 
                     e.getMessage().c_str());
         }
     }
-#ifdef JS_THREADSAFE
-    JS_EndRequest(cx);
-    JS_ClearContextThread(cx);
-#endif
-}
-
-/*
-static intN map(void *rp, const char *name, void *data)
-{
-    return JS_MAP_GCROOT_NEXT;
 }
-*/
 
 Script::~Script()
 {
-#ifdef JS_THREADSAFE
-    JS_SetContextThread(cx);
-    JS_BeginRequest(cx);
-#endif
-    if (common_script)
-        JS_RemoveObjectRoot(cx, &common_script);
-
-/*
- * scripts are unrooted and will be cleaned up by GC
-    if (common_script)
-        JS_DestroyScript(cx, common_script);
-
-    if (script)
-        JS_DestroyScript(cx, script);
-*/       
-//    JS_MapGCRoots(rt, &map, NULL); // debug stuff
-#ifdef JS_THREADSAFE
-    JS_EndRequest(cx);
-//    JS_ClearContextThread(cx);
-#endif
-    if (cx)
-    {
-        JS_DestroyContext(cx);
-        cx = NULL;
-    }
-}
-
-void Script::setGlobalObject(JSObject *glob)
-{
-    this->glob = glob;
-    JS_SetGlobalObject(cx, glob);
+    runtime->destroyContext(name);
 }
 
-JSObject *Script::getGlobalObject()
+Script *Script::getContextScript(duk_context *ctx)
 {
-    return glob;
-}
-
-JSContext *Script::getContext()
-{
-    return cx;
-}
-
-void Script::initGlobalObject()
-{
-    /* define characteristics of the global class */
-    static JSClass global_class =
+    duk_push_thread_stash(ctx, ctx);
+    duk_get_prop_string(ctx, -1, "this");
+    auto *self = (Script *)duk_get_pointer(ctx, -1);
+    duk_pop_2(ctx);
+    if (self == nullptr)
     {
-        "global",                                   /* name */
-        JSCLASS_HAS_PRIVATE | JSCLASS_GLOBAL_FLAGS, /* flags */
-        JS_PropertyStub,                            /* add property */
-        JS_PropertyStub,                            /* del property */
-        JS_PropertyStub,                            /* get property */
-        JS_StrictPropertyStub,                      /* set property */
-        JS_EnumerateStandardClasses,                /* enumerate */
-        JS_ResolveStub,                             /* resolve */
-        JS_ConvertStub,                             /* convert */
-        JS_FinalizeStub,                            /* finalize */
-        JSCLASS_NO_OPTIONAL_MEMBERS
-    };
-
-    /* create the global object here */
-    glob = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
-    if (! glob)
-        throw _Exception(_("Scripting: could not initialize glboal class"));
-
-    /* initialize the built-in JS objects and the global object */
-    if (! JS_InitStandardClasses(cx, glob))
-        throw _Exception(_("Scripting: JS_InitStandardClasses failed"));
-
+        log_debug("Could not retrieve class instance from global object\n");
+        duk_error(ctx, DUK_ERR_ERROR, "Could not retrieve current script from stash");
+    }
+    return self;
 }
 
-void Script::defineFunction(String name, JSNative function, int numParams)
+void Script::defineFunction(String name, duk_c_function function, uint32_t numParams)
 {
-    if (! JS_DefineFunction(cx, glob, name.c_str(), function, numParams, 0))
-        throw _Exception(_("Scripting: JS_DefineFunction failed"));
+    duk_push_c_function(ctx, function, numParams);
+    duk_put_global_string(ctx, name.c_str());
 }
 
-void Script::defineFunctions(JSFunctionSpec *functions)
+void Script::defineFunctions(duk_function_list_entry *functions)
 {
-    if (! JS_DefineFunctions(cx, glob, functions))
-        throw _Exception(_("Scripting: JS_DefineFunctions failed"));
+    duk_push_global_object(ctx);
+    duk_put_function_list(ctx, -1, functions);
+    duk_pop(ctx);
 }
 
-JSObject *Script::_load(zmm::String scriptPath)
+void Script::_load(zmm::String scriptPath)
 {
-    if (glob == NULL)
-        initGlobalObject();
-
-    JSObject *scr;
-
     String scriptText = read_text_file(scriptPath);
 
     if (!string_ok(scriptText))
@@ -547,39 +276,46 @@ JSObject *Script::_load(zmm::String scriptPath)
     {
         scriptText = j2i->convert(scriptText, true);
     }
-    catch (Exception e)
+    catch (const Exception & e)
     {
         throw _Exception(_("Failed to convert import script:") + e.getMessage().c_str());
     }
 
-    scr = JS_CompileScript(cx, glob, scriptText.c_str(), scriptText.length(),
-            scriptPath.c_str(), 1);
-    if (! scr)
+    duk_push_string(ctx, scriptPath.c_str());
+    if (duk_pcompile_lstring_filename(ctx, 0, scriptText.c_str(), scriptText.length()) != 0)
         throw _Exception(_("Scripting: failed to compile ") + scriptPath);
-
-    return scr;
 }
 
 void Script::load(zmm::String scriptPath)
 {
-    script = _load((scriptPath));
+    AutoLock lock(runtime->getMutex());
+    duk_push_thread_stash(ctx, ctx);
+    _load(scriptPath);
+    duk_put_prop_string(ctx, -2, "script");
+    duk_pop(ctx);
 }
 
 
-void Script::_execute(JSObject *scr)
+void Script::_execute()
 {
-    jsval ret_val;
-
-    if (!JS_ExecuteScript(cx, glob, scr, &ret_val))
+    if (duk_pcall(ctx, 0) != DUK_EXEC_SUCCESS)
+    {
+        log_debug("Failed to execute script: %s\n", duk_safe_to_string(ctx, -1));
         throw _Exception(_("Script: failed to execute script"));
+    }
+    duk_pop(ctx);
 }
 
 void Script::execute()
 {
-    _execute(script);
+    AutoLock lock(runtime->getMutex());
+    duk_push_thread_stash(ctx, ctx);
+    duk_get_prop_string(ctx, -1, "script");
+    duk_remove(ctx, -2);
+    _execute();
 }
 
-Ref<CdsObject> Script::jsObject2cdsObject(JSObject *js, zmm::Ref<CdsObject> pcd)
+Ref<CdsObject> Script::dukObject2cdsObject(zmm::Ref<CdsObject> pcd)
 {
     String val;
     int objectType;
@@ -594,11 +330,11 @@ Ref<CdsObject> Script::jsObject2cdsObject(JSObject *js, zmm::Ref<CdsObject> pcd)
     else
         sc = StringConverter::i2i();
 
-    objectType = getIntProperty(js, _("objectType"), -1);
+    objectType = getIntProperty(_("objectType"), -1);
     if (objectType == -1)
     {
         log_error("missing objectType property\n");
-        return nil;
+        return nullptr;
     }
 
     Ref<CdsObject> obj = CdsObject::createObject(objectType);
@@ -607,55 +343,55 @@ Ref<CdsObject> Script::jsObject2cdsObject(JSObject *js, zmm::Ref<CdsObject> pcd)
     // by the create function
 
     // CdsObject
-    obj->setVirtual(1); // JS creates only virtual objects
+    obj->setVirtual(true); // JS creates only virtual objects
 
-    i = getIntProperty(js, _("id"), INVALID_OBJECT_ID);
+    i = getIntProperty(_("id"), INVALID_OBJECT_ID);
     if (i != INVALID_OBJECT_ID)
         obj->setID(i);
-    i = getIntProperty(js, _("refID"), INVALID_OBJECT_ID);
+    i = getIntProperty(_("refID"), INVALID_OBJECT_ID);
     if (i != INVALID_OBJECT_ID)
         obj->setRefID(i);
-    i = getIntProperty(js, _("parentID"), INVALID_OBJECT_ID);
+    i = getIntProperty(_("parentID"), INVALID_OBJECT_ID);
     if (i != INVALID_OBJECT_ID)
         obj->setParentID(i);
 
-    val = getProperty(js, _("title"));
-    if (val != nil)
+    val = getProperty(_("title"));
+    if (val != nullptr)
     {
         val = sc->convert(val);
         obj->setTitle(val);
     }
     else
     {
-        if (pcd != nil)
+        if (pcd != nullptr)
             obj->setTitle(pcd->getTitle());
     }
 
-    val = getProperty(js, _("upnpclass"));
-    if (val != nil)
+    val = getProperty(_("upnpclass"));
+    if (val != nullptr)
     {
         val = sc->convert(val);
         obj->setClass(val);
     }
     else
     {
-        if (pcd != nil)
+        if (pcd != nullptr)
             obj->setClass(pcd->getClass());
     }
 
-    b = getBoolProperty(js, _("restricted"));
+    b = getBoolProperty(_("restricted"));
     if (b >= 0)
         obj->setRestricted(b);
-   
-    JSObject *js_meta = getObjectProperty(js, _("meta"));
-    if (js_meta)
+
+    duk_get_prop_string(ctx, -1, "meta");
+    if (duk_is_object(ctx, -1))
     {
-        JS_AddNamedObjectRoot(cx, &js_meta, "meta");
+        duk_to_object(ctx, -1);
         /// \todo: only metadata enumerated in MT_KEYS is taken
         for (int i = 0; i < M_MAX; i++)
         {
-            val = getProperty(js_meta, _(MT_KEYS[i].upnp));
-            if (val != nil)
+            val = getProperty(_(MT_KEYS[i].upnp));
+            if (val != nullptr)
             {
                 if (i == M_TRACKNUMBER)
                 {
@@ -675,11 +411,11 @@ Ref<CdsObject> Script::jsObject2cdsObject(JSObject *js, zmm::Ref<CdsObject> pcd)
                 }
             }
         }
-        JS_RemoveObjectRoot(cx, &js_meta);
     }
-    
+    duk_pop(ctx);
+
     // stuff that has not been exported to js
-    if (pcd != nil)
+    if (pcd != nullptr)
     {
         obj->setFlags(pcd->getFlags());
         obj->setResources(pcd->getResources());
@@ -692,23 +428,23 @@ Ref<CdsObject> Script::jsObject2cdsObject(JSObject *js, zmm::Ref<CdsObject> pcd)
         Ref<CdsItem> item = RefCast(obj, CdsItem);
         Ref<CdsItem> pcd_item;
 
-        if (pcd != nil)
+        if (pcd != nullptr)
             pcd_item = RefCast(pcd, CdsItem);
 
-        val = getProperty(js, _("mimetype"));
-        if (val != nil)
+        val = getProperty(_("mimetype"));
+        if (val != nullptr)
         {
             val = sc->convert(val);
             item->setMimeType(val);
         }
         else
         {
-            if (pcd != nil)
+            if (pcd != nullptr)
                 item->setMimeType(pcd_item->getMimeType());
         }
 
-        val = getProperty(js, _("serviceID"));
-        if (val != nil)
+        val = getProperty(_("serviceID"));
+        if (val != nullptr)
         {
             val = sc->convert(val);
             item->setServiceID(val);
@@ -716,33 +452,33 @@ Ref<CdsObject> Script::jsObject2cdsObject(JSObject *js, zmm::Ref<CdsObject> pcd)
 
         /// \todo check what this is doing here, wasn't it already handled
         /// in the MT_KEYS loop?
-        val = getProperty(js, _("description"));
-        if (val != nil)
+        val = getProperty(_("description"));
+        if (val != nullptr)
         {
             val = sc->convert(val);
             item->setMetadata(MetadataHandler::getMetaFieldName(M_DESCRIPTION), val);
         }
         else
         {
-            if (pcd != nil)
+            if (pcd != nullptr)
                 item->setMetadata(MetadataHandler::getMetaFieldName(M_DESCRIPTION),
                     pcd_item->getMetadata(MetadataHandler::getMetaFieldName(M_DESCRIPTION)));
         }
         if (this->whoami() == S_PLAYLIST)
         {
-            item->setTrackNumber(getIntProperty(js, _("playlistOrder"), 0));
+            item->setTrackNumber(getIntProperty(_("playlistOrder"), 0));
         }
 
         // location must not be touched by character conversion!
-        val = getProperty(js, _("location"));
-        if ((val != nil) && (IS_CDS_PURE_ITEM(objectType) || IS_CDS_ACTIVE_ITEM(objectType)))
+        val = getProperty(_("location"));
+        if ((val != nullptr) && (IS_CDS_PURE_ITEM(objectType) || IS_CDS_ACTIVE_ITEM(objectType)))
             val = normalizePath(val);
-        
+
         if (string_ok(val))
             obj->setLocation(val);
         else
         {
-            if (pcd != nil)
+            if (pcd != nullptr)
                 obj->setLocation(pcd->getLocation());
         }
 
@@ -750,24 +486,24 @@ Ref<CdsObject> Script::jsObject2cdsObject(JSObject *js, zmm::Ref<CdsObject> pcd)
         {
             Ref<CdsActiveItem> aitem = RefCast(obj, CdsActiveItem);
             Ref<CdsActiveItem> pcd_aitem;
-            if (pcd != nil)
+            if (pcd != nullptr)
                 pcd_aitem = RefCast(pcd, CdsActiveItem);
           /// \todo what about character conversion for action and state fields?
-            val = getProperty(js, _("action"));
-            if (val != nil)
+            val = getProperty(_("action"));
+            if (val != nullptr)
                 aitem->setAction(val);
             else
             {
-                if (pcd != nil)
+                if (pcd != nullptr)
                     aitem->setAction(pcd_aitem->getAction());
             }
 
-            val = getProperty(js, _("state"));
-            if (val != nil)
+            val = getProperty(_("state"));
+            if (val != nullptr)
                 aitem->setState(val);
             else
             {
-                if (pcd != nil)
+                if (pcd != nullptr)
                     aitem->setState(pcd_aitem->getState());
             }
         }
@@ -778,8 +514,8 @@ Ref<CdsObject> Script::jsObject2cdsObject(JSObject *js, zmm::Ref<CdsObject> pcd)
 
             obj->setRestricted(true);
             Ref<CdsItemExternalURL> item = RefCast(obj, CdsItemExternalURL);
-            val = getProperty(js, _("protocol"));
-            if (val != nil)
+            val = getProperty(_("protocol"));
+            if (val != nullptr)
             {
                 val = sc->convert(val);
                 protocolInfo = renderProtocolInfo(item->getMimeType(), val);
@@ -804,11 +540,11 @@ Ref<CdsObject> Script::jsObject2cdsObject(JSObject *js, zmm::Ref<CdsObject> pcd)
     if (IS_CDS_CONTAINER(objectType))
     {
         Ref<CdsContainer> cont = RefCast(obj, CdsContainer);
-        i = getIntProperty(js, _("updateID"), -1);
+        i = getIntProperty(_("updateID"), -1);
         if (i >= 0)
             cont->setUpdateID(i);
 
-        b = getBoolProperty(js, _("searchable"));
+        b = getBoolProperty(_("searchable"));
         if (b >= 0)
             cont->setSearchable(b);
     }
@@ -816,142 +552,89 @@ Ref<CdsObject> Script::jsObject2cdsObject(JSObject *js, zmm::Ref<CdsObject> pcd)
     return obj;
 }
 
-void Script::cdsObject2jsObject(Ref<CdsObject> obj, JSObject *js)
+void Script::cdsObject2dukObject(Ref<CdsObject> obj)
 {
     String val;
     int i;
 
+    duk_push_object(ctx);
+
     int objectType = obj->getObjectType();
 
     // CdsObject
-    setIntProperty(js, _("objectType"), objectType);
+    setIntProperty(_("objectType"), objectType);
 
     i = obj->getID();
 
     if (i != INVALID_OBJECT_ID)
-        setIntProperty(js, _("id"), i);
+        setIntProperty(_("id"), i);
 
     i = obj->getParentID();
     if (i != INVALID_OBJECT_ID)
-        setIntProperty(js, _("parentID"), i);
+        setIntProperty(_("parentID"), i);
 
     val = obj->getTitle();
-    if (val != nil)
-        setProperty(js, _("title"), val);
+    if (val != nullptr)
+        setProperty(_("title"), val);
 
     val = obj->getClass();
-    if (val != nil)
-        setProperty(js, _("upnpclass"), val);
+    if (val != nullptr)
+        setProperty(_("upnpclass"), val);
 
     val = obj->getLocation();
-    if (val != nil)
-        setProperty(js, _("location"), val);
+    if (val != nullptr)
+        setProperty(_("location"), val);
 
+    setIntProperty(_("mtime"), (int)obj->getMTime());
+    setIntProperty(_("sizeOnDisk"), (int)obj->getSizeOnDisk());
 
     // TODO: boolean type
     i = obj->isRestricted();
-    setIntProperty(js, _("restricted"), i);
+    setIntProperty(_("restricted"), i);
 
     if (obj->getFlag(OBJECT_FLAG_OGG_THEORA))
-        setIntProperty(js, _("theora"), 1);
+        setIntProperty(_("theora"), 1);
     else
-        setIntProperty(js, _("theora"), 0);
+        setIntProperty(_("theora"), 0);
 
 #ifdef ONLINE_SERVICES
     if (obj->getFlag(OBJECT_FLAG_ONLINE_SERVICE))
     {
          service_type_t service = (service_type_t)(obj->getAuxData(_(ONLINE_SERVICE_AUX_ID)).toInt());
-        setIntProperty(js, _("onlineservice"), (int)service);
+        setIntProperty(_("onlineservice"), (int)service);
     }
     else
 #endif
-        setIntProperty(js, _("onlineservice"), 0);
+        setIntProperty(_("onlineservice"), 0);
 
     // setting metadata
     {
-        JSObject *meta_js = JS_NewObject(cx, NULL, NULL, js);
-        setObjectProperty(js, _("meta"), meta_js);
+        duk_push_object(ctx);
+        // stack: js meta_js
+
         Ref<Dictionary> meta = obj->getMetadata();
         Ref<Array<DictionaryElement> > elements = meta->getElements();
         int len = elements->size();
         for (int i = 0; i < len; i++)
         {
             Ref<DictionaryElement> el = elements->get(i);
-            setProperty(meta_js, el->getKey(), el->getValue());
+            setProperty(el->getKey(), el->getValue());
         }
 
         if (RefCast(obj, CdsItem)->getTrackNumber() > 0)
-            setProperty(meta_js, MetadataHandler::getMetaFieldName(M_TRACKNUMBER), String::from(RefCast(obj, CdsItem)->getTrackNumber())); 
+            setProperty(MetadataHandler::getMetaFieldName(M_TRACKNUMBER), String::from(RefCast(obj, CdsItem)->getTrackNumber()));
+
+        duk_put_prop_string(ctx, -2, "meta");
+        // stack: js
     }
 
     // setting auxdata
     {
-        JSObject *aux_js = JS_NewObject(cx, NULL, NULL, js);
-        setObjectProperty(js, _("aux"), aux_js);
-        Ref<Dictionary> aux = obj->getAuxData();
-
-#ifdef HAVE_LIBDVDNAV
-        if (obj->getFlag(OBJECT_FLAG_DVD_IMAGE))
-        {
-            JSObject *aux_dvd = JS_NewObject(cx, NULL, NULL, js);
-            setObjectProperty(aux_js, _("DVD"), aux_dvd);
-
-            int title_count = obj->getAuxData(
-                                DVDHandler::renderKey(DVD_TitleCount)).toInt();
-
-            JSObject *titles = JS_NewArrayObject(cx, 0, NULL);
-            setObjectProperty(aux_dvd, _("titles"), titles);
-
-            for (int t = 0; t < title_count; t++)
-            {
-                JSObject *title = JS_NewObject(cx, NULL, NULL, js);
-                jsval val = OBJECT_TO_JSVAL(title);
-                JS_SetElement(cx, titles, t, &val);
-
-                setProperty(title, _("duration"), 
-                        obj->getAuxData(DVDHandler::renderKey(DVD_TitleDuration,
-                                        t)));
-
-                JSObject *audio_tracks = JS_NewArrayObject(cx, 0, NULL);
-                setObjectProperty(title, _("audio_tracks"), audio_tracks);
-
-                int audio_track_count = obj->getAuxData(
-                        DVDHandler::renderKey(DVD_AudioTrackCount, t)).toInt();
+        duk_push_object(ctx);
+        // stack: js aux_js
 
-                for (int a = 0; a < audio_track_count; a++)
-                {
-                    JSObject *track = JS_NewObject(cx, NULL, NULL, js);
-                    jsval val = OBJECT_TO_JSVAL(track);
-                    JS_SetElement(cx, audio_tracks, a, &val);
-
-                    setProperty(track, _("language"), obj->getAuxData(
-                                DVDHandler::renderKey(DVD_AudioTrackLanguage,
-                                    t, 0, a)));
-
-                    setProperty(track, _("format"), obj->getAuxData(
-                                DVDHandler::renderKey(DVD_AudioTrackFormat, 
-                                    t, 0, a)));
-                }
-
-                JSObject *chapters = JS_NewArrayObject(cx, 0, NULL);
-                setObjectProperty(title, _("chapters"), chapters);
-
-                int chapter_count = obj->getAuxData(DVDHandler::renderKey(DVD_ChapterCount, t)).toInt();
-
-                for (int c = 0; c < chapter_count; c++)
-                {
-                    JSObject *chapter = JS_NewObject(cx, NULL, NULL, js);
-                    jsval val = OBJECT_TO_JSVAL(chapter);
-                    JS_SetElement(cx, chapters, c, &val);
-
-                    setProperty(chapter, _("duration"), obj->getAuxData(
-                                DVDHandler::renderKey(DVD_ChapterRestDuration,
-                                    t, c)));
-                }
-            }
-        }
+        Ref<Dictionary> aux = obj->getAuxData();
 
-#endif
 #ifdef YOUTUBE
         // put in meaningful names for YouTube specific enum values
         String tmp = obj->getAuxData(_(YOUTUBE_AUXDATA_AVG_RATING));
@@ -993,7 +676,7 @@ void Script::cdsObject2jsObject(Ref<CdsObject> obj, JSObject *js)
         tmp = obj->getAuxData(_(YOUTUBE_AUXDATA_REQUEST));
         if (string_ok(tmp))
         {
-            yt_requests_t req = (yt_requests_t)tmp.toInt();
+            auto req = (yt_requests_t)tmp.toInt();
 
             // since subrequests do not actually produce any items they
             // should not be visible to js
@@ -1002,7 +685,9 @@ void Script::cdsObject2jsObject(Ref<CdsObject> obj, JSObject *js)
             else if (req == YT_subrequest_subscriptions)
                 req = YT_request_user_subscriptions;
 
-            setIntProperty(js, _("yt_request"), (int)req);
+            duk_swap_top(ctx, -2);
+            setIntProperty(_("yt_request"), (int)req);
+            duk_swap_top(ctx, -2);
             tmp = YouTubeService::getRequestName(req);
             if (string_ok(tmp))
                 aux->put(_(YOUTUBE_AUXDATA_REQUEST), tmp);
@@ -1011,7 +696,7 @@ void Script::cdsObject2jsObject(Ref<CdsObject> obj, JSObject *js)
         tmp = obj->getAuxData(_(YOUTUBE_AUXDATA_REGION));
         if (string_ok(tmp))
         {
-            yt_regions_t reg = (yt_regions_t)tmp.toInt();
+            auto reg = (yt_regions_t)tmp.toInt();
             if (reg != YT_region_none)
             {
                 tmp = YouTubeService::getRegionName(reg);
@@ -1020,7 +705,7 @@ void Script::cdsObject2jsObject(Ref<CdsObject> obj, JSObject *js)
             }
         }
 #endif // YouTube
-#ifdef HAVE_ATRAILERSSSS
+#ifdef HAVE_ATRAILERS
         tmp = obj->getAuxData(_(ATRAILERS_AUXDATA_POST_DATE));
         if (string_ok(tmp))
             aux->put(_(ATRAILERS_AUXDATA_POST_DATE), tmp);
@@ -1031,8 +716,11 @@ void Script::cdsObject2jsObject(Ref<CdsObject> obj, JSObject *js)
         for (int i = 0; i < len; i++)
         {
             Ref<DictionaryElement> el = elements->get(i);
-            setProperty(aux_js, el->getKey(), el->getValue());
+            setProperty(el->getKey(), el->getValue());
         }
+
+        duk_put_prop_string(ctx, -2, "aux");
+        // stack: js
     }
 
 
@@ -1043,22 +731,22 @@ void Script::cdsObject2jsObject(Ref<CdsObject> obj, JSObject *js)
     {
         Ref<CdsItem> item = RefCast(obj, CdsItem);
         val = item->getMimeType();
-        if (val != nil)
-            setProperty(js, _("mimetype"), val);
+        if (val != nullptr)
+            setProperty(_("mimetype"), val);
 
         val = item->getServiceID();
-        if (val != nil)
-            setProperty(js, _("serviceID"), val);
+        if (val != nullptr)
+            setProperty(_("serviceID"), val);
 
         if (IS_CDS_ACTIVE_ITEM(objectType))
         {
             Ref<CdsActiveItem> aitem = RefCast(obj, CdsActiveItem);
             val = aitem->getAction();
-            if (val != nil)
-                setProperty(js, _("action"), val);
+            if (val != nullptr)
+                setProperty(_("action"), val);
             val = aitem->getState();
-            if (val != nil)
-                setProperty(js, _("state"), val);
+            if (val != nullptr)
+                setProperty(_("state"), val);
         }
     }
 
@@ -1068,10 +756,10 @@ void Script::cdsObject2jsObject(Ref<CdsObject> obj, JSObject *js)
         Ref<CdsContainer> cont = RefCast(obj, CdsContainer);
         // TODO: boolean type, hide updateID
         i = cont->getUpdateID();
-        setIntProperty(js, _("updateID"), i);
+        setIntProperty(_("updateID"), i);
 
         i = cont->isSearchable();
-        setIntProperty(js, _("searchable"), i);
+        setIntProperty(_("searchable"), i);
     }
 }
 
@@ -1091,7 +779,7 @@ String Script::convertToCharset(String str, charset_convert_t chr)
             return _i2i->convert(str);
     }
 
-    return nil;
+    return nullptr;
 }
 
 Ref<CdsObject> Script::getProcessedObject()
diff --git a/src/scripting/script.h b/src/scripting/script.h
index 0423241..202cdd3 100644
--- a/src/scripting/script.h
+++ b/src/scripting/script.h
@@ -32,9 +32,8 @@
 #ifndef __SCRIPTING_SCRIPT_H__
 #define __SCRIPTING_SCRIPT_H__
 
-#define XP_UNIX 1
-
-#include <jsapi.h>
+#include <mutex>
+#include "duktape.h"
 #include "common.h"
 #include "runtime.h"
 #include "cds_objects.h"
@@ -46,8 +45,7 @@
 typedef enum
 {
     S_IMPORT = 0,
-    S_PLAYLIST,
-    S_DVD
+    S_PLAYLIST
 } script_class_t;
 
 typedef enum
@@ -63,39 +61,24 @@ class Script : public zmm::Object
 {
 public:
     zmm::Ref<Runtime> runtime;
-    JSRuntime *rt;
-    JSContext *cx;
-    JSObject  *glob;
-    JSObject *script;
-    JSObject *common_script;
     
 public:
-    Script(zmm::Ref<Runtime> runtime);
     virtual ~Script();
     
-    zmm::String getProperty(JSObject *obj, zmm::String name);
-    int getBoolProperty(JSObject *obj, zmm::String name);
-    int getIntProperty(JSObject *obj, zmm::String name, int def);
-    JSObject *getObjectProperty(JSObject *obj, zmm::String name);
-    
-    void setProperty(JSObject *obj, zmm::String name, zmm::String value);
-    void setIntProperty(JSObject *obj, zmm::String name, int value);
-    void setObjectProperty(JSObject *parent, zmm::String name, JSObject *obj);
-    
-    void deleteProperty(JSObject *obj, zmm::String name);
-    
-    JSObject *getGlobalObject();
-    void setGlobalObject(JSObject *glob);
+    zmm::String getProperty(zmm::String name);
+    int getBoolProperty(zmm::String name);
+    int getIntProperty(zmm::String name, int def);
     
-    JSContext *getContext();
+    void setProperty(zmm::String name, zmm::String value);
+    void setIntProperty(zmm::String name, int value);
     
-    void defineFunction(zmm::String name, JSNative function, int numParams);
-    void defineFunctions(JSFunctionSpec *functions);
+    void defineFunction(zmm::String name, duk_c_function function, uint32_t numParams);
+    void defineFunctions(duk_function_list_entry *functions);
     void load(zmm::String scriptPath);
     void load(zmm::String scriptText, zmm::String scriptPath);
     
-    zmm::Ref<CdsObject> jsObject2cdsObject(JSObject *js, zmm::Ref<CdsObject> pcd);
-    void cdsObject2jsObject(zmm::Ref<CdsObject> obj, JSObject *js);
+    zmm::Ref<CdsObject> dukObject2cdsObject(zmm::Ref<CdsObject> pcd);
+    void cdsObject2dukObject(zmm::Ref<CdsObject> obj);
     
     virtual script_class_t whoami() = 0;
 
@@ -103,7 +86,10 @@ public:
 
     zmm::String convertToCharset(zmm::String str, charset_convert_t chr);
     
+    static Script *getContextScript(duk_context *ctx);
+
 protected:
+    Script(zmm::Ref<Runtime> runtime, std::string name);
     void execute();
     int gc_counter;
 
@@ -111,12 +97,13 @@ protected:
     // script)
     zmm::Ref<CdsObject> processed;
     
-private:
-    JSObject *common_root;
+    using AutoLock = std::lock_guard<std::recursive_mutex>;
+    duk_context *ctx;
 
-    void initGlobalObject();
-    JSObject *_load(zmm::String scriptPath);
-    void _execute(JSObject *scr);
+private:
+    std::string name;
+    void _load(zmm::String scriptPath);
+    void _execute();
     zmm::Ref<StringConverter> _p2i;
     zmm::Ref<StringConverter> _j2i;
     zmm::Ref<StringConverter> _f2i;
diff --git a/src/serve_request_handler.cc b/src/serve_request_handler.cc
index b1b3604..b1d1a27 100644
--- a/src/serve_request_handler.cc
+++ b/src/serve_request_handler.cc
@@ -29,26 +29,11 @@
 
 /// \file serve_request_handler.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
+#include <sys/stat.h>
 
 #include "server.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include "common.h"
-#include "storage.h"
-#include "cds_objects.h"
-#include "process.h"
-#include "update_manager.h"
-#include "ixml.h"
 #include "file_io_handler.h"
-#include "dictionary.h"
 #include "serve_request_handler.h"
-#include "tools.h"
 
 
 using namespace zmm;
@@ -59,7 +44,7 @@ ServeRequestHandler::ServeRequestHandler() : RequestHandler()
 }
 
 /// \todo clean up the fix for internal items
-void ServeRequestHandler::get_info(IN const char *filename, OUT struct File_Info *info)
+void ServeRequestHandler::get_info(IN const char *filename, OUT UpnpFileInfo *info)
 {
     struct stat statbuf;
     int ret = 0;
@@ -97,15 +82,15 @@ void ServeRequestHandler::get_info(IN const char *filename, OUT struct File_Info
     {
         String mimetype = _(MIMETYPE_DEFAULT);
 #ifdef HAVE_MAGIC
-        magic_set *ms = NULL;
+        magic_set *ms = nullptr;
         ms = magic_open(MAGIC_MIME);
-        if (ms != NULL)
+        if (ms != nullptr)
         {
-            if (magic_load(ms, NULL) == -1)
+            if (magic_load(ms, nullptr) == -1)
             {
                 log_warning("magic_load: %s\n", magic_error(ms));
                 magic_close(ms);
-                ms = NULL;
+                ms = nullptr;
             } 
             else
             {
@@ -123,20 +108,24 @@ void ServeRequestHandler::get_info(IN const char *filename, OUT struct File_Info
         }
 #endif // HAVE_MAGIC
 
-        info->file_length = statbuf.st_size;
-        info->last_modified = statbuf.st_mtime;
-        info->is_directory = S_ISDIR(statbuf.st_mode);
+        UpnpFileInfo_set_FileLength(info, statbuf.st_size);
+#ifdef UPNP_OLD_SNAPSHOT
+        UpnpFileInfo_set_LastModified(info, &(statbuf.st_mtime));
+#else
+        UpnpFileInfo_set_LastModified(info, statbuf.st_mtime);
+#endif
+        UpnpFileInfo_set_IsDirectory(info, S_ISDIR(statbuf.st_mode));
 
         if (access(path.c_str(), R_OK) == 0)
         {
-            info->is_readable = 1;
+            UpnpFileInfo_set_IsReadable(info, 1);
         }
         else
         {
-            info->is_readable = 0;
+            UpnpFileInfo_set_IsReadable(info, 0);
         }
 
-        info->content_type = ixmlCloneDOMString(mimetype.c_str());
+        UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString(mimetype.c_str()));
     }
     else
     {
@@ -145,7 +134,6 @@ void ServeRequestHandler::get_info(IN const char *filename, OUT struct File_Info
 }
 
 Ref<IOHandler> ServeRequestHandler::open(IN const char *filename,
-                                         OUT struct File_Info *info,
                                          IN enum UpnpOpenFileMode mode,
                                          IN zmm::String range)
 {
@@ -187,15 +175,15 @@ Ref<IOHandler> ServeRequestHandler::open(IN const char *filename,
     {
         String mimetype = _(MIMETYPE_DEFAULT);
 #ifdef HAVE_MAGIC
-        magic_set *ms = NULL;
+        magic_set *ms = nullptr;
         ms = magic_open(MAGIC_MIME);
-        if (ms != NULL)
+        if (ms != nullptr)
         {
-            if (magic_load(ms, NULL) == -1)
+            if (magic_load(ms, nullptr) == -1)
             {
                 log_warning("magic_load: %s\n", magic_error(ms));
                 magic_close(ms);
-                ms = NULL;
+                ms = nullptr;
             }
             else
             {
@@ -213,6 +201,8 @@ Ref<IOHandler> ServeRequestHandler::open(IN const char *filename,
         }
 #endif // HAVE_MAGIC
 
+		// FIXME upstream headers
+		/*
         info->file_length = statbuf.st_size;
         info->last_modified = statbuf.st_mtime;
         info->is_directory = S_ISDIR(statbuf.st_mode);
@@ -226,7 +216,9 @@ Ref<IOHandler> ServeRequestHandler::open(IN const char *filename,
             info->is_readable = 0;
         }
 
+
         info->content_type = ixmlCloneDOMString(mimetype.c_str());
+        */
     }
     else
     {
diff --git a/src/serve_request_handler.h b/src/serve_request_handler.h
index af39314..fb79315 100644
--- a/src/serve_request_handler.h
+++ b/src/serve_request_handler.h
@@ -40,9 +40,8 @@ class ServeRequestHandler : public RequestHandler
 {
 public:
     ServeRequestHandler();
-    virtual void get_info(IN const char *filename, OUT struct File_Info *info);
+    virtual void get_info(IN const char *filename, OUT UpnpFileInfo *info);
     virtual zmm::Ref<IOHandler> open(IN const char *filename,
-                                     OUT struct File_Info *info,
                                      IN enum UpnpOpenFileMode mode,
                                      IN zmm::String range);
 };
diff --git a/src/server.cc b/src/server.cc
index b7c9018..9c12d2c 100644
--- a/src/server.cc
+++ b/src/server.cc
@@ -29,75 +29,68 @@
 
 /// \file server.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_CURL
-    #include <curl/curl.h>
+#include <curl/curl.h>
 #endif
 
 #ifdef HAVE_LASTFMLIB
-    #include "lastfm_scrobbler.h"
+#include "lastfm_scrobbler.h"
 #endif
 
-#include "server.h"
-#include "web_callbacks.h"
 #include "content_manager.h"
+#include "server.h"
 #include "update_manager.h"
-#include "dictionary.h"
-#include "upnp_xml.h"
-#include "tools.h"
+#include "web_callbacks.h"
 
 using namespace zmm;
 using namespace mxml;
 
-Ref<Storage> Server::storage = nil;
+Ref<Storage> Server::storage = nullptr;
 
-SINGLETON_MUTEX(Server, false);
-
-static int static_upnp_callback(Upnp_EventType eventtype, void *event, void *cookie)
+#ifdef UPNP_OLD_SNAPSHOT
+static int static_upnp_callback(Upnp_EventType eventtype, void* event, void* cookie)
+#else
+static int static_upnp_callback(Upnp_EventType eventtype, const void* event, void* cookie)
+#endif
 {
     return Server::getInstance()->upnp_callback(eventtype, event, cookie);
 }
 
 void Server::static_cleanup_callback()
 {
-    if (storage != nil)
-    {
-        try
-        {
+    if (storage != nullptr) {
+        try {
             storage->threadCleanup();
+        } catch (const Exception& ex) {
         }
-        catch (Exception ex) {}
     }
 }
 
-Server::Server() : Singleton<Server>()
+Server::Server()
 {
     server_shutdown_flag = false;
 }
 
 void Server::init()
 {
-    virtual_directory = _(SERVER_VIRTUAL_DIR); 
-    
+    virtual_directory = _(SERVER_VIRTUAL_DIR);
+
     ContentDirectoryService::setStaticArgs(_(DESC_CDS_SERVICE_TYPE),
-                                           _(DESC_CDS_SERVICE_ID));
+        _(DESC_CDS_SERVICE_ID));
     cds = ContentDirectoryService::getInstance();
-                                                 
+
     ConnectionManagerService::setStaticArgs(_(DESC_CM_SERVICE_TYPE),
-                                            _(DESC_CM_SERVICE_ID));
+        _(DESC_CM_SERVICE_ID));
     cmgr = ConnectionManagerService::getInstance();
 
-#if defined(ENABLE_MRREG)                                                    
+#if defined(ENABLE_MRREG)
     MRRegistrarService::setStaticArgs(_(DESC_MRREG_SERVICE_TYPE),
-                                      _(DESC_MRREG_SERVICE_ID));
+        _(DESC_MRREG_SERVICE_ID));
     mrreg = MRRegistrarService::getInstance();
 #endif
 
     Ref<ConfigManager> config = ConfigManager::getInstance();
-    
+
     serverUDN = config->getOption(CFG_SERVER_UDN);
     alive_advertisement = config->getIntOption(CFG_SERVER_ALIVE_INTERVAL);
 
@@ -110,75 +103,42 @@ void Server::init()
 #endif
 }
 
-void Server::upnp_init(String iface, String ip_address, int port)
+void Server::upnp_init()
 {
-    int ret = 0;        // general purpose error code
-    String ip;
-
+    int ret = 0; // general purpose error code
     log_debug("start\n");
 
     Ref<ConfigManager> config = ConfigManager::getInstance();
 
-    if (!string_ok(iface))
-        iface = config->getOption(CFG_SERVER_NETWORK_INTERFACE);
-
-    if (!string_ok(ip_address))
-        ip = config->getOption(CFG_SERVER_IP);
-    else
-        ip = ip_address;
+    String iface = config->getOption(CFG_SERVER_NETWORK_INTERFACE);
+    String ip = config->getOption(CFG_SERVER_IP);
 
     if (string_ok(ip) && string_ok(iface))
         throw _Exception(_("You can not specify interface and IP at the same time!"));
 
+    if (!string_ok(iface))
+        iface = ipToInterface(ip);
 
-    if (!string_ok(ip))
-        ip = interfaceToIP(iface);
-
-    if (string_ok(iface) && !string_ok(ip))
-        throw _Exception(_("Could not find interface: ") + iface);
-/*
-    // without this lod_debug coredumped on Solaris...
-    if (iface == nil)
-        iface = _("");
-
-    if (ip == nil)
-        ip = _("");
-    
-    log_debug("interface: %s ip: %s\n", iface.c_str(), ip.c_str());
-
-    if (ip == "")
-        ip = nil;
-*/
-    if (port < 0)
-    {
-        port = config->getIntOption(CFG_SERVER_PORT);
-    }
-
-    if (port < 0)
-        port = 0;
+    if (string_ok(ip) && !string_ok(iface))
+        throw _Exception(_("Could not find ip: ") + ip);
 
+    int port = config->getIntOption(CFG_SERVER_PORT);
 
-    void *cb = NULL;
     // this is important, so the storage lives a little longer when
     // shutdown is initiated
+    // FIMXE: why?
     storage = Storage::getInstance();
 
-    if (storage->threadCleanupRequired())
-        cb = (void *)static_cleanup_callback;
-
-    ret = UpnpInit(ip.c_str(), port, 0, cb);
-
-    if (ret != UPNP_E_SUCCESS)
-    {
+    log_debug("Initialising libupnp with interface: %s, port: %d\n", iface.c_str(), port);
+    ret = UpnpInit2(iface.c_str(), port);
+    if (ret != UPNP_E_SUCCESS) {
         throw _UpnpException(ret, _("upnp_init: UpnpInit failed"));
     }
 
     port = UpnpGetServerPort();
-
     log_info("Initialized port: %d\n", port);
 
-    if (!string_ok(ip))
-    {
+    if (!string_ok(ip)) {
         ip = UpnpGetServerIpAddress();
     }
 
@@ -189,125 +149,90 @@ void Server::upnp_init(String iface, String ip_address, int port)
     // next set webroot directory
     String web_root = config->getOption(CFG_SERVER_WEBROOT);
 
-    if (!string_ok(web_root))
-    {
+    if (!string_ok(web_root)) {
         throw _Exception(_("invalid web server root directory"));
     }
-    
+
     ret = UpnpSetWebServerRootDir(web_root.c_str());
-    if (ret != UPNP_E_SUCCESS)
-    {
+    if (ret != UPNP_E_SUCCESS) {
         throw _UpnpException(ret, _("upnp_init: UpnpSetWebServerRootDir failed"));
     }
 
-    log_debug("webroot: %s\n", web_root.c_str()); 
-
-        Ref<Array<StringBase> > arr = config->getStringArrayOption(CFG_SERVER_CUSTOM_HTTP_HEADERS);
-
-        if (arr != nil)
-        {
-            String tmp;
-            for (int i = 0; i < arr->size(); i++)
-            {
-                tmp = arr->get(i);
-                if (string_ok(tmp))
-                {
-                    log_info("Adding HTTP header \"%s\"\n", tmp.c_str());
-                    ret = UpnpAddCustomHTTPHeader(tmp.c_str());
-                    if (ret != UPNP_E_SUCCESS)
-                    {
-                        throw _UpnpException(ret, _("upnp_init: UpnpAddCustomHTTPHeader failed"));
-                    }
-                }
+    log_debug("webroot: %s\n", web_root.c_str());
+
+    Ref<Array<StringBase> > arr = config->getStringArrayOption(CFG_SERVER_CUSTOM_HTTP_HEADERS);
+
+    if (arr != nullptr) {
+        String tmp;
+        for (int i = 0; i < arr->size(); i++) {
+            tmp = arr->get(i);
+            if (string_ok(tmp)) {
+                log_info("(NOT) Adding HTTP header \"%s\"\n", tmp.c_str());
+                // FIXME upstream upnp
+                //ret = UpnpAddCustomHTTPHeader(tmp.c_str());
+                //if (ret != UPNP_E_SUCCESS)
+                //{
+                //    throw _UpnpException(ret, _("upnp_init: UpnpAddCustomHTTPHeader failed"));
+                //}
             }
         }
+    }
 
+    log_debug("Setting virtual dir to: %s\n", virtual_directory.c_str());
     ret = UpnpAddVirtualDir(virtual_directory.c_str());
-    if (ret != UPNP_E_SUCCESS)
-    {
+    if (ret != UPNP_E_SUCCESS) {
         throw _UpnpException(ret, _("upnp_init: UpnpAddVirtualDir failed"));
     }
 
     ret = register_web_callbacks();
-    if (ret != UPNP_E_SUCCESS)
-    {
+    if (ret != UPNP_E_SUCCESS) {
         throw _UpnpException(ret, _("upnp_init: UpnpSetVirtualDirCallbacks failed"));
     }
 
-    String presentationURL =  config->getOption(CFG_SERVER_PRESENTATION_URL);
-    if (!string_ok(presentationURL))
-    {
+    String presentationURL = config->getOption(CFG_SERVER_PRESENTATION_URL);
+    if (!string_ok(presentationURL)) {
         presentationURL = _("http://") + ip + ":" + port + "/";
-    }
-    else
-    {
-        String appendto = 
-           config->getOption(CFG_SERVER_APPEND_PRESENTATION_URL_TO);
-        if (appendto == "ip")
-        {
+    } else {
+        String appendto = config->getOption(CFG_SERVER_APPEND_PRESENTATION_URL_TO);
+        if (appendto == "ip") {
             presentationURL = _("http://") + ip + ":" + presentationURL;
-        }
-        else if (appendto == "port")
-        {
-            presentationURL = _("http://") + ip + ":" + port + "/" + 
-                              presentationURL;
+        } else if (appendto == "port") {
+            presentationURL = _("http://") + ip + ":" + port + "/" + presentationURL;
         } // else appendto is none and we take the URL as it entered by user
     }
 
     // register root device with the library
-    String device_description = 
-        _("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
-         UpnpXML_RenderDeviceDescription(presentationURL)->print();
-         
-    //log_debug("DEVICE DESCRIPTION: \n%s\n", device_description.c_str());
-
-    // register root device with the library
-    ret = UpnpRegisterRootDevice2(UPNPREG_BUF_DESC, device_description.c_str(), 
-                                  device_description.length() + 1, true,
-                                  static_upnp_callback,
-                                  &device_handle,
-                                  &device_handle);
-    if (ret != UPNP_E_SUCCESS)
-    {
-        throw _UpnpException(ret, _("upnp_init: UpnpRegisterRootDevice failed"));
-    }
-
-    // now unregister in order to cleanup previous instances
-    // that might still be there due to crash/unclean shutdown/network interruptions
-    ret = UpnpUnRegisterRootDevice(device_handle);
-    if (ret != UPNP_E_SUCCESS) {   
-        throw _UpnpException(ret, _("upnp_init: unregistering failed"));
-    }
-    
-    // and register again, we should be clean now
-    ret = UpnpRegisterRootDevice2(UPNPREG_BUF_DESC, device_description.c_str(), 
-                                  device_description.length() + 1, true,
-                                  static_upnp_callback,
-                                  &device_handle,
-                                  &device_handle);
-    if (ret != UPNP_E_SUCCESS)
-    {
+    String device_description = _("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + UpnpXML_RenderDeviceDescription(presentationURL)->print();
+
+    //log_debug("Device Description: \n%s\n", device_description.c_str());
+
+    log_debug("Registering with UPnP...\n");
+    ret = UpnpRegisterRootDevice2(UPNPREG_BUF_DESC,
+        device_description.c_str(),
+        device_description.length() + 1,
+        true,
+        static_upnp_callback,
+        &device_handle,
+        &device_handle);
+    if (ret != UPNP_E_SUCCESS) {
         throw _UpnpException(ret, _("upnp_init: UpnpRegisterRootDevice failed"));
     }
 
-
-    // send advertisements every 180secs
+    log_debug("Sending UPnP Alive advertisment\n");
     ret = UpnpSendAdvertisement(device_handle, alive_advertisement);
-    if (ret != UPNP_E_SUCCESS)
-    {
+    if (ret != UPNP_E_SUCCESS) {
         throw _UpnpException(ret, _("upnp_init: UpnpSendAdvertisement failed"));
     }
-       
+
     // initializing UpdateManager
     UpdateManager::getInstance();
-    
+
     // initializing ContentManager
     ContentManager::getInstance();
-    
+
     config->writeBookmark(ip, String::from(port));
-    log_info("MediaTomb Web UI can be reached by following this link:\n");
-    log_info("http://%s:%d/\n", ip.c_str(), port);
-    
+    log_info("The Web UI can be reached by following this link: http://%s:%d/\n", ip.c_str(), port);
+
     log_debug("end\n");
 }
 
@@ -319,22 +244,19 @@ bool Server::getShutdownStatus()
 void Server::shutdown()
 {
     int ret = 0; // return code
-    
+
     /*
     ContentManager::getInstance()->shutdown();
     UpdateManager::getInstance()->shutdown();
     Storage::getInstance()->shutdown();
     */
-    
+
     server_shutdown_flag = true;
-    
-    log_debug("start\n");
-    
-    // unregister device
-    
+
+    log_debug("Server shutting down\n");
+
     ret = UpnpUnRegisterRootDevice(device_handle);
-    if (ret != UPNP_E_SUCCESS) 
-    {   
+    if (ret != UPNP_E_SUCCESS) {
         throw _UpnpException(ret, _("upnp_cleanup: UpnpUnRegisterRootDevice failed"));
     }
 
@@ -344,9 +266,10 @@ void Server::shutdown()
 
     log_debug("now calling upnp finish\n");
     UpnpFinish();
-    storage = nil;
-
-    log_debug("end\n");
+    if (storage != nullptr && storage->threadCleanupRequired()) {
+        static_cleanup_callback();
+    }
+    storage = nullptr;
 }
 
 String Server::getVirtualURL()
@@ -354,79 +277,71 @@ String Server::getVirtualURL()
     return virtual_url;
 }
 
-
-int Server::upnp_callback(Upnp_EventType eventtype, void *event, void *cookie)
+int Server::upnp_callback(Upnp_EventType eventtype, const void* event, void* cookie)
 {
     int ret = UPNP_E_SUCCESS; // general purpose return code
 
     log_debug("start\n");
 
     // check parameters
-    if (event == NULL) {
+    if (event == nullptr) {
         log_debug("upnp_callback: NULL event structure\n");
         return UPNP_E_BAD_REQUEST;
     }
 
-//    log_info("event is ok\n");
+    //log_info("event is ok\n");
     // get device wide mutex (have to figure out what the hell that is)
-    AUTOLOCK(mutex);
-
-//    log_info("got device mutex\n");
+    AutoLock lock(mutex);
 
     // dispatch event based on event type
     switch (eventtype) {
 
-        case UPNP_CONTROL_ACTION_REQUEST:
-            // a CP is invoking an action
-//            log_info("UPNP_CONTROL_ACTION_REQUEST\n");
-            try
-            {
-                Ref<ActionRequest> request(new ActionRequest((struct Upnp_Action_Request *)event));
-                upnp_actions(request);
-                request->update();
-               // set in update() ((struct Upnp_Action_Request *)event)->ErrCode = ret;
-            }
-            catch(UpnpException upnp_e)
-            {
-                ret = upnp_e.getErrorCode();
-                ((struct Upnp_Action_Request *)event)->ErrCode = ret;
-            }
-            catch(Exception e)
-            {
-                log_info("Exception: %s\n", e.getMessage().c_str());
-            }
-            
-            break;
-            
-        case UPNP_EVENT_SUBSCRIPTION_REQUEST:
-            // a cp wants a subscription
-//            log_info("UPNP_EVENT_SUBSCRIPTION_REQUEST\n");
-            try
-            {
-                Ref<SubscriptionRequest> request(new SubscriptionRequest((struct Upnp_Subscription_Request *)event));
-                upnp_subscriptions(request);
-            }
-            catch(UpnpException upnp_e)
-            {
-                ret = upnp_e.getErrorCode();
-            }
-            
-            break;
-            
-        default:
-            // unhandled event type
-            log_warning("unsupported event type: %d\n", eventtype);
-            ret = UPNP_E_BAD_REQUEST;
-            break;
+    case UPNP_CONTROL_ACTION_REQUEST:
+        // a CP is invoking an action
+        //log_info("UPNP_CONTROL_ACTION_REQUEST\n");
+        try {
+            // https://github.com/mrjimenez/pupnp/blob/master/upnp/sample/common/tv_device.c
+
+            Ref<ActionRequest> request(new ActionRequest((UpnpActionRequest*)event));
+            upnp_actions(request);
+            request->update();
+            // set in update() ((struct Upnp_Action_Request *)event)->ErrCode = ret;
+        } catch (const UpnpException& upnp_e) {
+            ret = upnp_e.getErrorCode();
+            UpnpActionRequest_set_ErrCode((UpnpActionRequest*)event, ret);
+        } catch (const Exception& e) {
+            log_info("Exception: %s\n", e.getMessage().c_str());
+        }
+
+        break;
+
+    case UPNP_EVENT_SUBSCRIPTION_REQUEST:
+        // a cp wants a subscription
+        //log_info("UPNP_EVENT_SUBSCRIPTION_REQUEST\n");
+        try {
+            Ref<SubscriptionRequest> request(new SubscriptionRequest((UpnpSubscriptionRequest*)event));
+            upnp_subscriptions(request);
+        } catch (const UpnpException& upnp_e) {
+            log_warning("Subscription exception: %s\n", upnp_e.getMessage().c_str());
+            ret = upnp_e.getErrorCode();
+        }
+
+        break;
+
+    default:
+        // unhandled event type
+        log_warning("unsupported event type: %d\n", eventtype);
+        ret = UPNP_E_BAD_REQUEST;
+        break;
     }
-    
+
     log_debug("returning %d\n", ret);
     return ret;
 }
 
 UpnpDevice_Handle Server::getDeviceHandle()
 {
-    return device_handle; 
+    return device_handle;
 }
 
 zmm::String Server::getIP()
@@ -444,78 +359,66 @@ void Server::upnp_actions(Ref<ActionRequest> request)
     log_debug("start\n");
 
     // make sure the request is for our device
-    if (request->getUDN() != serverUDN)
-    {
+    if (request->getUDN() != serverUDN) {
         // not for us
-        throw _UpnpException(UPNP_E_BAD_REQUEST, 
-                            _("upnp_actions: request not for this device"));
+        throw _UpnpException(UPNP_E_BAD_REQUEST,
+            _("upnp_actions: request not for this device"));
     }
 
     // we need to match the serviceID to one of our services
-    if (request->getServiceID() == DESC_CM_SERVICE_ID)
-    {
+    if (request->getServiceID() == DESC_CM_SERVICE_ID) {
         // this call is for the lifetime stats service
-//        log_debug("request for connection manager service\n");
+        // log_debug("request for connection manager service\n");
         cmgr->process_action_request(request);
-    } 
-    else if (request->getServiceID() == DESC_CDS_SERVICE_ID) 
-    {
+    } else if (request->getServiceID() == DESC_CDS_SERVICE_ID) {
         // this call is for the toaster control service
-//        log_debug("upnp_actions: request for content directory service\n");
+        //log_debug("upnp_actions: request for content directory service\n");
         cds->process_action_request(request);
-    } 
+    }
 #if defined(ENABLE_MRREG)
-    else if (request->getServiceID() == DESC_MRREG_SERVICE_ID)
-    {
+    else if (request->getServiceID() == DESC_MRREG_SERVICE_ID) {
         mrreg->process_action_request(request);
     }
 #endif
-    else 
-    {
+    else {
         // cp is asking for a nonexistent service, or for a service
         // that does not support any actions
-        throw _UpnpException(UPNP_E_BAD_REQUEST, 
-                            _("Service does not exist or action not supported"));
+        throw _UpnpException(UPNP_E_BAD_REQUEST,
+            _("Service does not exist or action not supported"));
     }
 }
 
-
 void Server::upnp_subscriptions(Ref<SubscriptionRequest> request)
 {
     // make sure that the request is for our device
-    if (request->getUDN() != serverUDN)
-    {
+    if (request->getUDN() != serverUDN) {
         // not for us
-//        log_debug("upnp_subscriptions: request not for this device\n");
+        log_debug("upnp_subscriptions: request not for this device: %s vs %s\n",
+            request->getUDN().c_str(), serverUDN.c_str());
         throw _UpnpException(UPNP_E_BAD_REQUEST,
-                            _("upnp_actions: request not for this device"));
+            _("upnp_actions: request not for this device"));
     }
-                                                             
+
     // we need to match the serviceID to one of our services
 
-    if (request->getServiceID() == DESC_CDS_SERVICE_ID)
-    {
+    if (request->getServiceID() == DESC_CDS_SERVICE_ID) {
         // this call is for the content directory service
-//        log_debug("upnp_subscriptions: request for content directory service\n");
+        //log_debug("upnp_subscriptions: request for content directory service\n");
         cds->process_subscription_request(request);
-    }
-    else if (request->getServiceID() == DESC_CM_SERVICE_ID)
-    {
+    } else if (request->getServiceID() == DESC_CM_SERVICE_ID) {
         // this call is for the connection manager service
-//        log_debug("upnp_subscriptions: request for connection manager service\n");
+        //log_debug("upnp_subscriptions: request for connection manager service\n");
         cmgr->process_subscription_request(request);
     }
 #if defined(ENABLE_MRREG)
-    else if (request->getServiceID() == DESC_MRREG_SERVICE_ID)
-    {
+    else if (request->getServiceID() == DESC_MRREG_SERVICE_ID) {
         mrreg->process_subscription_request(request);
     }
 #endif
-    else 
-    {
+    else {
         // cp asks for a nonexistent service or for a service that
         // does not support subscriptions
-        throw _UpnpException(UPNP_E_BAD_REQUEST, 
-                            _("Service does not exist or subscriptions not supported"));
+        throw _UpnpException(UPNP_E_BAD_REQUEST,
+            _("Service does not exist or subscriptions not supported"));
     }
 }
diff --git a/src/server.h b/src/server.h
index 5d8950d..e176260 100644
--- a/src/server.h
+++ b/src/server.h
@@ -40,7 +40,6 @@
 #include "upnp_cm.h"
 #include "upnp_mrreg.h"
 #include "config_manager.h"
-#include "sync.h"
 #include "storage.h"
 
 /// \brief Provides methods to initialize and shutdown
@@ -59,15 +58,12 @@ public:
     
     
     /// \brief Initializes UPnP portion, only ip or interface can be given
-    /// \param interface to bind to
-    /// \param ip address to bind to
-    /// \param port Port where the server will be listening for requests.
     ///
     /// Reads information from the config and creates a 
     /// device description document. Initializes the UPnP SDK,
     /// sets up the virutal web server directories and registers
     /// web callbacks. Starts the update manager task.
-    void upnp_init(zmm::String interface, zmm::String ip_address, int port);
+    void upnp_init();
     
     /// \brief Cleanup routine to shutdown the server.
     ///
@@ -94,7 +90,7 @@ public:
     /// data structures (ActionRequest or SubscriptionRequest) and is then
     /// passed on to the appropriate request handler - to upnp_actions() or
     /// upnp_subscriptions()
-    int upnp_callback(Upnp_EventType eventtype, void *event, void *cookie);
+    int upnp_callback(Upnp_EventType eventtype, const void *event, void *cookie);
   
     /// \brief Returns the device handle.
     ///
diff --git a/src/session_manager.cc b/src/session_manager.cc
index 182e1cd..74a98ef 100644
--- a/src/session_manager.cc
+++ b/src/session_manager.cc
@@ -29,9 +29,8 @@
 
 /// \file session_manager.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
+#include <memory>
+#include <unordered_set>
 
 #include "session_manager.h"
 #include "config_manager.h"
@@ -44,15 +43,15 @@
 
 using namespace zmm;
 using namespace mxml;
-
-SINGLETON_MUTEX(SessionManager, false);
+using namespace std;
 
 Session::Session(long timeout) : Dictionary_r()
 {
     this->timeout = timeout;
     loggedIn = false;
-    sessionID = nil;
-    uiUpdateIDs = Ref<DBRHash<int> >(new DBRHash<int>(UI_UPDATE_ID_HASH_SIZE, MAX_UI_UPDATE_IDS + 5, INVALID_OBJECT_ID, INVALID_OBJECT_ID_2));
+    sessionID = nullptr;
+    uiUpdateIDs = make_shared<unordered_set<int>>();
+        //(new DBRHash<int>(UI_UPDATE_ID_HASH_SIZE, MAX_UI_UPDATE_IDS + 5, INVALID_OBJECT_ID, INVALID_OBJECT_ID_2));
     updateAll = false;
     access();
 }
@@ -63,7 +62,7 @@ void Session::containerChangedUI(int objectID)
         return;
     if (! updateAll)
     {
-        AUTOLOCK(mutex);
+        AutoLock lock(mutex);
         if (! updateAll)
         {
             if (uiUpdateIDs->size() >= MAX_UI_UPDATE_IDS)
@@ -72,7 +71,7 @@ void Session::containerChangedUI(int objectID)
                 uiUpdateIDs->clear();
             }
             else
-                uiUpdateIDs->put(objectID);
+                uiUpdateIDs->insert(objectID);
         }
     }
 }
@@ -81,10 +80,10 @@ void Session::containerChangedUI(Ref<IntArray> objectIDs)
 {
     if (updateAll)
         return;
-    if (objectIDs == nil)
+    if (objectIDs == nullptr)
         return;
     int arSize = objectIDs->size();
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     if (updateAll)
         return;
     if (uiUpdateIDs->size() + arSize >= MAX_UI_UPDATE_IDS)
@@ -95,24 +94,22 @@ void Session::containerChangedUI(Ref<IntArray> objectIDs)
     }
     for (int i = 0; i < arSize; i++)
     {
-        uiUpdateIDs->put(objectIDs->get(i));
+        uiUpdateIDs->insert(objectIDs->get(i));
     }
 }
 
 String Session::getUIUpdateIDs()
 {
     if (! hasUIUpdateIDs())
-        return nil;
-    AUTOLOCK(mutex);
+        return nullptr;
+    AutoLock lock(mutex);
     if (updateAll)
     {
         updateAll = false;
         return _("all");
     }
-    hash_data_array_t<int> hash_data_array;
-    uiUpdateIDs->getAll(&hash_data_array);
-    String ret = intArrayToCSV(hash_data_array.data, hash_data_array.size);
-    if (ret != nil)
+    String ret = toCSV(uiUpdateIDs);
+    if (ret != nullptr)
         uiUpdateIDs->clear();
     return ret;
 }
@@ -121,19 +118,19 @@ bool Session::hasUIUpdateIDs()
 {
     if (updateAll)
         return true;
-    // AUTOLOCK(mutex); only accessing an int - shouldn't be necessary
+    // AutoLock lock(mutex); only accessing an int - shouldn't be necessary
     return (uiUpdateIDs->size() > 0);
 }
 
 void Session::clearUpdateIDs()
 {
     log_debug("clearing UI updateIDs\n");
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     uiUpdateIDs->clear();
     updateAll = false;
 }
 
-SessionManager::SessionManager() : TimerSubscriberSingleton<SessionManager>()
+SessionManager::SessionManager()
 {
     Ref<ConfigManager> configManager = ConfigManager::getInstance();
 
@@ -145,7 +142,7 @@ SessionManager::SessionManager() : TimerSubscriberSingleton<SessionManager>()
 Ref<Session> SessionManager::createSession(long timeout)
 {
     Ref<Session> newSession(new Session(timeout));
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     
     int count=0;
     String sessionID;
@@ -155,7 +152,7 @@ Ref<Session> SessionManager::createSession(long timeout)
         if (count++ > 100)
             throw _Exception(_("There seems to be something wrong with the random numbers. I tried to get a unique id 100 times and failed. last sessionID: ") + sessionID);
     }
-    while(getSession(sessionID, false) != nil); // for the rare case, where we get a random id, that is already taken
+    while(getSession(sessionID, false) != nullptr); // for the rare case, where we get a random id, that is already taken
     
     newSession->setID(sessionID);
     sessions->append(newSession);
@@ -165,21 +162,21 @@ Ref<Session> SessionManager::createSession(long timeout)
 
 Ref<Session> SessionManager::getSession(String sessionID, bool doLock)
 {
-    AUTOLOCK_NOLOCK(mutex)
+    unique_lock<decltype(mutex)> lock(mutex, std::defer_lock);
     if (doLock)
-        AUTORELOCK();
+        lock.lock();
     for (int i = 0; i < sessions->size(); i++)
     {
         Ref<Session> s = sessions->get(i);
         if (s->getID() == sessionID)
             return s;
     }
-    return nil;
+    return nullptr;
 }
 
 void SessionManager::removeSession(String sessionID)
 {
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     for (int i = 0; i < sessions->size(); i++)
     {
         Ref<Session> s = sessions->get(i);
@@ -195,9 +192,9 @@ void SessionManager::removeSession(String sessionID)
 
 String SessionManager::getUserPassword(String user)
 {
-    if (accounts == nil)
+    if (accounts == nullptr)
     {
-        return nil;
+        return nullptr;
     }
     return accounts->get(user);
 }
@@ -206,7 +203,7 @@ void SessionManager::containerChangedUI(int objectID)
 {
     if (sessions->size() <= 0)
         return;
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     int sesSize = sessions->size();
     for (int i = 0; i < sesSize; i++)
     {
@@ -220,7 +217,7 @@ void SessionManager::containerChangedUI(Ref<IntArray> objectIDs)
 {
     if (sessions->size() <= 0)
         return;
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     int sesSize = sessions->size();
     for (int i = 0; i < sesSize; i++)
     {
@@ -234,20 +231,20 @@ void SessionManager::checkTimer()
 {
     if (sessions->size() > 0 && ! timerAdded)
     {
-        Timer::getInstance()->addTimerSubscriber(AS_TIMER_SUBSCRIBER_SINGLETON(this), SESSION_TIMEOUT_CHECK_INTERVAL);
+        Timer::getInstance()->addTimerSubscriber(this, SESSION_TIMEOUT_CHECK_INTERVAL);
         timerAdded = true;
     }
     else if (sessions->size() <= 0 && timerAdded)
     {
-        Timer::getInstance()->removeTimerSubscriber(AS_TIMER_SUBSCRIBER_SINGLETON(this));
+        Timer::getInstance()->removeTimerSubscriber(this);
         timerAdded = false;
     }
 }
 
-void SessionManager::timerNotify(Ref<Object> parameter)
+void SessionManager::timerNotify(Ref<Timer::Parameter> parameter)
 {
     log_debug("notified... %d sessions.\n", sessions->size());
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     struct timespec now;
     getTimespecNow(&now);
     for (int i = 0; i < sessions->size(); i++)
diff --git a/src/session_manager.h b/src/session_manager.h
index dbb0f54..c9c123a 100644
--- a/src/session_manager.h
+++ b/src/session_manager.h
@@ -32,10 +32,11 @@
 #ifndef __SESSION_MANAGER_H__
 #define __SESSION_MANAGER_H__
 
+#include <memory>
+#include <unordered_set>
+
 #include "singleton.h"
 #include "dictionary.h"
-#include "sync.h"
-#include "hash.h"
 #include "timer.h"
 
 /// \brief One UI session.
@@ -95,7 +96,7 @@ protected:
     /// the UI shall update every container
     bool updateAll;
     
-    zmm::Ref<DBRHash<int> > uiUpdateIDs;
+    std::shared_ptr<std::unordered_set<int> > uiUpdateIDs;
     
     /// \brief maximum time the session can be idle (starting from last_access)
     long timeout;
@@ -112,7 +113,7 @@ protected:
 };
 
 /// \brief This class offers ways to create new sessoins, stores all available sessions and provides access to them.
-class SessionManager : public TimerSubscriberSingleton<SessionManager>
+class SessionManager : public Timer::Subscriber, public Singleton<SessionManager>
 {
 protected:
     /// \brief This array is holding available sessions.
@@ -135,7 +136,7 @@ public:
     
     /// \brief Returns the instance to a Session with a given sessionID
     /// \param ID of the Session.
-    /// \return intance of the Session with a given ID or nil if no session with that ID was found.
+    /// \return intance of the Session with a given ID or nullptr if no session with that ID was found.
     zmm::Ref<Session> getSession(zmm::String sessionID, bool doLock = true);
     
     /// \brief Removes a session
@@ -151,7 +152,7 @@ public:
     
     void containerChangedUI(zmm::Ref<zmm::IntArray> objectIDs);
     
-    virtual void timerNotify(zmm::Ref<zmm::Object> parameter);
+    virtual void timerNotify(zmm::Ref<Timer::Parameter> parameter);
 };
 
 #endif //  __SESSION_MANAGER_H__
diff --git a/src/singleton.cc b/src/singleton.cc
index 10c4fcd..f579540 100644
--- a/src/singleton.cc
+++ b/src/singleton.cc
@@ -29,23 +29,19 @@
 
 /// \file singleton.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "singleton.h"
 
 using namespace zmm;
 
-Ref<SingletonManager> SingletonManager::instance = nil;
-Ref<Mutex> SingletonManager::mutex = Ref<Mutex>(new Mutex());
+Ref<SingletonManager> SingletonManager::instance = nullptr;
+std::mutex SingletonManager::mutex{};
 
 Ref<SingletonManager> SingletonManager::getInstance()
 {
-    if (instance == nil)
+    if (instance == nullptr)
     {
-        AUTOLOCK(mutex);
-        if (instance == nil) // check again, because there is a very small chance
+        AutoLock lock(mutex);
+        if (instance == nullptr) // check again, because there is a very small chance
                              // that 2 threads tried to lock() concurrently
         {
             instance = zmm::Ref<SingletonManager>(new SingletonManager());
@@ -61,7 +57,7 @@ SingletonManager::SingletonManager() : Object()
 
 void SingletonManager::registerSingleton(Ref<Singleton<Object> > object)
 {
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
 #ifdef TOMBDEBUG
     if (singletonStack->size() >= SINGLETON_CUR_MAX)
     {
@@ -77,12 +73,12 @@ void SingletonManager::registerSingleton(Ref<Singleton<Object> > object)
 void SingletonManager::shutdown(bool complete)
 {
     log_debug("start (%d objects)\n", singletonStack->size());
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     
     Ref<ObjectStack<Singleton<Object> > > singletonStackReactivate(new ObjectStack<Singleton<Object> >(SINGLETON_CUR_MAX));
     
     Ref<Singleton<Object> > object;
-    while((object = singletonStack->pop()) != nil)
+    while((object = singletonStack->pop()) != nullptr)
     {
         //log_debug("destoying... \n");
         //_print_backtrace(stdout);
@@ -91,9 +87,9 @@ void SingletonManager::shutdown(bool complete)
         singletonStackReactivate->push(object);
         //object->destroyMutex();
     }
-    while((object = singletonStackReactivate->pop()) != nil)
+    while((object = singletonStackReactivate->pop()) != nullptr)
         object->reactivateSingleton();
-    if (complete && instance != nil)
-        instance = nil;
+    if (complete && instance != nullptr)
+        instance = nullptr;
     log_debug("end\n");
 }
diff --git a/src/singleton.h b/src/singleton.h
index 3a57cbe..03c5b76 100644
--- a/src/singleton.h
+++ b/src/singleton.h
@@ -32,12 +32,13 @@
 #ifndef __SINGLETON_H__
 #define __SINGLETON_H__
 
-#include "sync.h"
-#include "zmmf/zmmf.h"
+#include <mutex>
+#include "zmm/zmmf.h"
+#include "exceptions.h"
 
 #define SINGLETON_CUR_MAX 15
 
-template <class T> class Singleton;
+template <class T, class MutexT = std::mutex> class Singleton;
 
 class SingletonManager : public zmm::Object
 {
@@ -50,25 +51,28 @@ public:
     
 protected:
     static zmm::Ref<SingletonManager> instance;
-    static zmm::Ref<Mutex> mutex;
+    static std::mutex mutex;
+    using AutoLock = std::lock_guard<std::mutex>;
     
     zmm::Ref<zmm::ObjectStack<Singleton<zmm::Object> > > singletonStack;
 };
 
-template <class T>
+template <class T, class MutexT>
 class Singleton : public zmm::Object
 {
 public:
+    typedef MutexT mutex_type;
+
     static zmm::Ref<T> getInstance()
     {
         if (! singletonActive)
             throw _ServerShutdownException(_("singleton is currently inactive!"));
-        if (instance == nil)
+        if (instance == nullptr)
         {
-            AUTOLOCK(mutex);
+            AutoLock lock(mutex);
             if (! singletonActive)
                 throw _ServerShutdownException(_("singleton is currently inactive!"));
-            if (instance == nil) // check again, because there is a very small chance
+            if (instance == nullptr) // check again, because there is a very small chance
                                  // that 2 threads tried to lock() concurrently
             {
                 zmm::Ref<T> tmpInstance = zmm::Ref<T>(new T());
@@ -87,7 +91,9 @@ protected:
     virtual void init() { }
     virtual void shutdown() { }
     
-    static zmm::Ref<Mutex> mutex;
+    static MutexT mutex;
+    using AutoLock = std::lock_guard<MutexT>;
+
     static zmm::Ref<T> instance;
     static bool singletonActive;
     
@@ -102,16 +108,16 @@ private:
     {
         //log_debug("%d %d\n", singletonActive, instance.getPtr());
         singletonActive = false;
-        instance = nil;
+        instance = nullptr;
     }
     virtual void reactivateSingleton() { singletonActive = true; }
     
     friend class SingletonManager;
 };
 
-#define SINGLETON_MUTEX(klass, recursive) template <> zmm::Ref<Mutex> Singleton<klass>::mutex = zmm::Ref<Mutex>(new Mutex(recursive))
-//template <class T> zmm::Ref<Mutex> Singleton<T>::mutex = zmm::Ref<Mutex>(new Mutex());
-template <class T> zmm::Ref<T> Singleton<T>::instance = nil;
-template <class T> bool Singleton<T>::singletonActive = true;
+template <class T, class MutexT> zmm::Ref<T> Singleton<T, MutexT>::instance = nullptr;
+template <class T, class MutexT> bool Singleton<T, MutexT>::singletonActive = true;
+// Without the {} it's a declaration, not a definition.
+template <class T, class MutexT> MutexT Singleton<T, MutexT>::mutex{};
 
 #endif // __SINGLETON_H__
diff --git a/src/sopcast_content_handler.cc b/src/sopcast_content_handler.cc
index 8a1c3ef..2122f94 100644
--- a/src/sopcast_content_handler.cc
+++ b/src/sopcast_content_handler.cc
@@ -30,10 +30,6 @@
 /// \file sopcast_content_handler.cc
 /// \brief Implementation of the SopCastContentHandler class.
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #if defined(SOPCAST)
 
 #include "sopcast_content_handler.h"
@@ -62,7 +58,7 @@ bool SopCastContentHandler::setServiceContent(zmm::Ref<mxml::Element> service)
     current_group_node_index = 0;
     current_channel_index = 0;
     channel_count = 0;
-    current_group = nil;
+    current_group = nullptr;
 
     extension_mimetype_map =
         ConfigManager::getInstance()->getDictionaryOption(CFG_IMPORT_MAPPINGS_EXTENSION_TO_MIMETYPE_LIST);
@@ -78,12 +74,12 @@ Ref<CdsObject> SopCastContentHandler::getNextObject()
 
     while (current_group_node_index < group_count)
     {
-        if (current_group == nil)
+        if (current_group == nullptr)
         {
             Ref<Node> n = channels->getChild(current_group_node_index);
             current_group_node_index++;
 
-            if (n == nil)
+            if (n == nullptr)
                 continue;
 
             if (n->getType() != mxml_node_element)
@@ -95,8 +91,8 @@ Ref<CdsObject> SopCastContentHandler::getNextObject()
             if ((current_group->getName() != "group") ||
                 (channel_count < 1))
             {
-                current_group = nil;
-                current_group_name = nil;
+                current_group = nullptr;
+                current_group_name = nullptr;
                 continue;
             }
             else
@@ -115,7 +111,7 @@ Ref<CdsObject> SopCastContentHandler::getNextObject()
 
         if (current_channel_index >= channel_count)
         {
-            current_group = nil;
+            current_group = nullptr;
             continue;
         }
 
@@ -124,7 +120,7 @@ Ref<CdsObject> SopCastContentHandler::getNextObject()
             Ref<Node> n = current_group->getChild(current_channel_index);
             current_channel_index++;
 
-            if ((n == nil) || (n->getType() != mxml_node_element))
+            if ((n == nullptr) || (n->getType() != mxml_node_element))
                 continue;
 
             Ref<Element> channel = RefCast(n, Element);
@@ -181,7 +177,7 @@ Ref<CdsObject> SopCastContentHandler::getNextObject()
             item->setMimeType(mt);
            
             Ref<Element> tmp_el = channel->getChildByName(_("sop_address"));
-            if (tmp_el == nil)
+            if (tmp_el == nullptr)
             {
                 log_warning("Failed to retrieve SopCast channel URL\n");
                 continue;
@@ -196,7 +192,7 @@ Ref<CdsObject> SopCastContentHandler::getNextObject()
             item->setURL(temp);
 
             tmp_el = channel->getChildByName(_("name"));
-            if (tmp_el == nil)
+            if (tmp_el == nullptr)
             {
                 log_warning("Failed to retrieve SopCast channel name\n");
                 continue;
@@ -209,7 +205,7 @@ Ref<CdsObject> SopCastContentHandler::getNextObject()
                 item->setTitle(_("Unknown"));
 
             tmp_el = channel->getChildByName(_("region"));
-            if (tmp_el != nil)
+            if (tmp_el != nullptr)
             {
                 temp = tmp_el->getAttribute(_("en"));
                 if (string_ok(temp))
@@ -236,7 +232,7 @@ Ref<CdsObject> SopCastContentHandler::getNextObject()
                 item->validate();
                 return RefCast(item, CdsObject);
             }
-            catch (Exception ex)
+            catch (const Exception & ex)
             {
                 log_warning("Failed to validate newly created SopCast item: %s\n",
                         ex.getMessage().c_str());
@@ -245,7 +241,7 @@ Ref<CdsObject> SopCastContentHandler::getNextObject()
         }
     }
 
-    return nil;
+    return nullptr;
 }
 
 #endif//SOPCAST
diff --git a/src/sopcast_content_handler.h b/src/sopcast_content_handler.h
index b57b317..6491c82 100644
--- a/src/sopcast_content_handler.h
+++ b/src/sopcast_content_handler.h
@@ -61,9 +61,9 @@ public:
     ///
     /// Each invokation of this funtion will return a new object,
     /// when the whole service XML is parsed and no more objects are left,
-    /// this function will return nil.
+    /// this function will return nullptr.
     ///
-    /// \return CdsObject or nil if there are no more objects to parse.
+    /// \return CdsObject or nullptr if there are no more objects to parse.
     zmm::Ref<CdsObject> getNextObject();
 
 
diff --git a/src/sopcast_service.cc b/src/sopcast_service.cc
index b7b4488..fe7a5d5 100644
--- a/src/sopcast_service.cc
+++ b/src/sopcast_service.cc
@@ -29,10 +29,6 @@
 
 /// \file sopcast_service.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef SOPCAST 
 
 #include "zmm/zmm.h"
@@ -75,7 +71,7 @@ String SopCastService::getServiceName()
 
 Ref<Object> SopCastService::defineServiceTask(Ref<Element> xmlopt, Ref<Object> params)
 {
-    return nil;
+    return nullptr;
 }
 
 Ref<Element> SopCastService::getData()
@@ -92,18 +88,18 @@ Ref<Element> SopCastService::getData()
                                curl_handle, false, true, true);
     
     }
-    catch (Exception ex)
+    catch (const Exception & ex)
     {
         log_error("Failed to download SopCast XML data: %s\n", 
                   ex.getMessage().c_str());
-        return nil;
+        return nullptr;
     }
 
-    if (buffer == nil)
-        return nil;
+    if (buffer == nullptr)
+        return nullptr;
 
     if (retcode != 200)
-        return nil;
+        return nullptr;
 
     log_debug("GOT BUFFER\n%s\n", buffer->toString().c_str()); 
     Ref<Parser> parser(new Parser());
@@ -111,21 +107,21 @@ Ref<Element> SopCastService::getData()
     {
         return parser->parseString(sc->convert(buffer->toString()))->getRoot();
     }
-    catch (ParseException pe)
+    catch (const ParseException & pe)
     {
         log_error("Error parsing SopCast XML %s line %d:\n%s\n",
                pe.context->location.c_str(),
                pe.context->line,
                pe.getMessage().c_str());
-        return nil;
+        return nullptr;
     }
-    catch (Exception ex)
+    catch (const Exception & ex)
     {
         log_error("Error parsing SopCast XML %s\n", ex.getMessage().c_str());
-        return nil;
+        return nullptr;
     }
     
-    return nil;
+    return nullptr;
 }
 
 bool SopCastService::refreshServiceData(Ref<Layout> layout)
@@ -147,7 +143,7 @@ bool SopCastService::refreshServiceData(Ref<Layout> layout)
     Ref<Element> reply = getData();
 
     Ref<SopCastContentHandler> sc(new SopCastContentHandler());
-    if (reply != nil)
+    if (reply != nullptr)
         sc->setServiceContent(reply);
     else
     {
@@ -161,18 +157,18 @@ bool SopCastService::refreshServiceData(Ref<Layout> layout)
         /// \todo add try/catch here and a possibility do find out if we
         /// may request more stuff or if we are at the end of the list
         obj = sc->getNextObject();
-        if (obj == nil)
+        if (obj == nullptr)
             break;
 
        obj->setVirtual(true);
 
         Ref<CdsObject> old = Storage::getInstance()->loadObjectByServiceID(RefCast(obj, CdsItem)->getServiceID());
-        if (old == nil)
+        if (old == nullptr)
         {
             log_debug("Adding new SopCast object\n");
             
-            if (layout != nil)
-                layout->processCdsObject(obj, nil);
+            if (layout != nullptr)
+                layout->processCdsObject(obj, nullptr);
         }
         else
         {
@@ -191,7 +187,7 @@ bool SopCastService::refreshServiceData(Ref<Layout> layout)
             return false;
 
     }
-    while (obj != nil);
+    while (obj != nullptr);
 
     return false;
 }
diff --git a/src/storage.cc b/src/storage.cc
index e128c9c..bb5f773 100644
--- a/src/storage.cc
+++ b/src/storage.cc
@@ -29,10 +29,6 @@
 
 /// \file storage.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "config_manager.h"
 
 #if ! defined(HAVE_MYSQL) && ! defined(HAVE_SQLITE3)
@@ -46,18 +42,16 @@
 
 using namespace zmm;
 
-SINGLETON_MUTEX(Storage, false);
-
 Ref<Storage> Storage::getInstance()
 {
     if (! instance->singletonActive)
             throw _Exception(_("singleton is currently inactive!"));
-    if(instance == nil)
+    if(instance == nullptr)
     {
-        AUTOLOCK(mutex);
+        AutoLock lock(mutex);
         if (! instance->singletonActive)
                 throw _Exception(_("singleton is currently inactive!"));
-        if (instance == nil)
+        if (instance == nullptr)
         {
             Ref<Storage> tmpInstance = createInstance();
             tmpInstance->init();
diff --git a/src/storage.h b/src/storage.h
index 61fab1c..b5bfb4f 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -32,12 +32,13 @@
 #ifndef __STORAGE_H__
 #define __STORAGE_H__
 
-#include "zmmf/zmmf.h"
+#include <memory>
+#include <unordered_set>
+
+#include "zmm/zmmf.h"
 #include "singleton.h"
 #include "cds_objects.h"
 #include "dictionary.h"
-#include "sync.h"
-#include "hash.h"
 #include "autoscan.h"
 
 #define BROWSE_DIRECT_CHILDREN      0x00000001
@@ -98,7 +99,7 @@ public:
     
 };
 
-class Storage : public Singleton<Storage>
+class Storage : public Singleton<Storage, std::mutex>
 {
 public:
     static zmm::Ref<Storage> getInstance();
@@ -122,8 +123,8 @@ public:
     /// the object ID of the container that is last in the path. The
     /// updateID will hold the objectID of the container that was changed,
     /// in case new containers were created during the operation.
-    virtual void addContainerChain(zmm::String path, zmm::String lastClass,
-            int lastRefID, int *containerID, int *updateID) = 0;
+    virtual void addContainerChain(zmm::String path, zmm::String lastClass, int lastRefID, int *containerID,
+                                   int *updateID, zmm::Ref<Dictionary> lastMetadata) = 0;
     
     /// \brief Builds the container path. Fetches the path of the
     /// parent and adds the title
@@ -160,11 +161,14 @@ public:
     /// \param size number of entries in the given array
     /// \return a String for UPnP: a CSV list; for every existing object:
     ///  "id,update_id"
-    virtual zmm::String incrementUpdateIDs(int *ids, int size) = 0;
+    virtual zmm::String incrementUpdateIDs(std::shared_ptr<std::unordered_set<int> > ids) = 0;
     
     /* utility methods */
     virtual zmm::Ref<CdsObject> loadObject(int objectID) = 0;
     virtual int getChildCount(int contId, bool containers = true, bool items = true, bool hideFsRoot = false) = 0;
+
+    virtual zmm::String findFolderImage(int id, zmm::String trackArtBase) = 0;
+
     
     class ChangedContainers : public Object
     {
@@ -193,14 +197,14 @@ public:
     /// \brief Get all objects under the given parentID.
     /// \param parentID parent container
     /// \param withoutContainer if false: all children are returned; if true: only items are returned
-    /// \return DBHash containing the objectID's - nil if there are none! 
-    virtual zmm::Ref<DBRHash<int> > getObjects(int parentID, bool withoutContainer) = 0;
+    /// \return DBHash containing the objectID's - nullptr if there are none!
+    virtual std::shared_ptr<std::unordered_set<int> > getObjects(int parentID, bool withoutContainer) = 0;
     
     /// \brief Remove all objects found in list
     /// \param list a DBHash containing objectIDs that have to be removed
     /// \param all if true and the object to be removed is a reference
     /// \return changed container ids
-    virtual zmm::Ref<ChangedContainers> removeObjects(zmm::Ref<DBRHash<int> > list, bool all = false) = 0;
+    virtual zmm::Ref<ChangedContainers> removeObjects(std::shared_ptr<std::unordered_set<int> > list, bool all = false) = 0;
     
     /// \brief Loads an object given by the online service ID.
     virtual zmm::Ref<CdsObject> loadObjectByServiceID(zmm::String serviceID) = 0;
@@ -218,8 +222,8 @@ public:
     virtual void storeInternalSetting(zmm::String key, zmm::String value) = 0;
     
     /* autoscan methods */
-    virtual void updateAutoscanPersistentList(scan_mode_t scanmode, zmm::Ref<AutoscanList> list) = 0;
-    virtual zmm::Ref<AutoscanList> getAutoscanList(scan_mode_t scanmode) = 0;
+    virtual void updateAutoscanPersistentList(ScanMode scanmode, zmm::Ref<AutoscanList> list) = 0;
+    virtual zmm::Ref<AutoscanList> getAutoscanList(ScanMode scanode) = 0;
     virtual void addAutoscanDirectory(zmm::Ref<AutoscanDirectory> adir) = 0;
     virtual void updateAutoscanDirectory(zmm::Ref<AutoscanDirectory> adir) = 0;
     virtual void removeAutoscanDirectoryByObjectID(int objectID) = 0;
@@ -241,10 +245,10 @@ public:
     /// \return 0 if the given id is no autoscan start point, 1 if it is a non-recursive one, 2 if it is a recursive on
     virtual int isAutoscanDirectoryRecursive(int objectId) = 0;
     
-    /// \brief returns the AutoscanDirectory for the given objectID or nil if
+    /// \brief returns the AutoscanDirectory for the given objectID or nullptr if
     /// it's not an autoscan start point - scan id will be invalid
     /// \param objectID the object id to get the AutoscanDirectory for
-    /// \return nil if the given id is no autoscan start point,
+    /// \return nullptr if the given id is no autoscan start point,
     /// or the matching AutoscanDirectory
     virtual zmm::Ref<AutoscanDirectory> getAutoscanDirectory(int objectID) = 0;
     
diff --git a/src/storage/cache_object.cc b/src/storage/cache_object.cc
index 901fd71..27241d1 100644
--- a/src/storage/cache_object.cc
+++ b/src/storage/cache_object.cc
@@ -29,11 +29,7 @@
 
 /// \file cache_object.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include "common.h"
+#include "../common.h"
 #include "cache_object.h"
 
 using namespace zmm;
@@ -43,7 +39,7 @@ CacheObject::CacheObject()
     parentID = INVALID_OBJECT_ID;
     refID = INVALID_OBJECT_ID;
     knowRefID = false;
-    obj = nil;
+    obj = nullptr;
     numChildren = 0;
     knowNumChildren = false;
     objectType = 0;
diff --git a/src/storage/cache_object.h b/src/storage/cache_object.h
index bef162e..3e882f4 100644
--- a/src/storage/cache_object.h
+++ b/src/storage/cache_object.h
@@ -32,7 +32,7 @@
 #ifndef __CACHE_OBJECT_H__
 #define __CACHE_OBJECT_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 #include "common.h"
 #include "cds_objects.h"
 
@@ -53,7 +53,7 @@ public:
     
     void setObject(zmm::Ref<CdsObject> obj);
     zmm::Ref<CdsObject> getObject() { return obj; }
-    bool knowsObject() { return obj != nil; }
+    bool knowsObject() { return obj != nullptr; }
     
     void setNumChildren(int numChildren) { this->numChildren = numChildren; knowNumChildren = true; }
     int getNumChildren() { return numChildren; }
@@ -65,7 +65,7 @@ public:
     
     void setLocation(zmm::String location) { this->location = location; }
     zmm::String getLocation() { return location; }
-    bool knowsLocation() { return location != nil; }
+    bool knowsLocation() { return location != nullptr; }
     
     void setVirtual(bool virtualObj) { this->virtualObj = virtualObj; knowVirtualObj = true; }
     bool getVirtual() { return virtualObj; }
diff --git a/src/storage/mysql/mysql_storage.cc b/src/storage/mysql/mysql_storage.cc
index 24185b2..2a19b2e 100644
--- a/src/storage/mysql/mysql_storage.cc
+++ b/src/storage/mysql/mysql_storage.cc
@@ -29,10 +29,6 @@
 
 /// \file mysql_storage.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_MYSQL
 
 //#define MYSQL_SET_NAMES "/*!40101 SET NAMES utf8 */"
@@ -44,8 +40,8 @@
 #include "config_manager.h"
 
 #ifdef AUTO_CREATE_DATABASE
-    #include "mysql_create_sql.h"
-    #include <zlib.h>
+#include "mysql_create_sql.h"
+#include <zlib.h>
 #endif
 
 // updates 1->2
@@ -67,26 +63,25 @@
 #define MYSQL_UPDATE_3_4_2 "ALTER TABLE `mt_cds_object` ADD KEY `cds_object_service_id` (`service_id`)"
 #define MYSQL_UPDATE_3_4_3 "UPDATE `mt_internal_setting` SET `value`='4' WHERE `key`='db_version' AND `value`='3'"
 
-
 using namespace zmm;
 using namespace mxml;
+using namespace std;
 
-MysqlStorage::MysqlStorage() : SQLStorage()
+MysqlStorage::MysqlStorage()
+    : SQLStorage()
 {
     mysql_init_key_initialized = false;
     mysql_connection = false;
-    mysqlMutex = Ref<Mutex> (new Mutex(true));
     table_quote_begin = '`';
     table_quote_end = '`';
-    insertBuffer = nil;
+    insertBuffer = nullptr;
 }
 MysqlStorage::~MysqlStorage()
 {
-    AUTOLOCK(mysqlMutex);    // just to ensure, that we don't close while another thread 
-                    // is executing a query
-    
-    if(mysql_connection)
-    {
+    AutoLock lock(mysqlMutex); // just to ensure, that we don't close while another thread
+    // is executing a query
+
+    if (mysql_connection) {
         mysql_close(&db);
         mysql_connection = false;
     }
@@ -97,22 +92,22 @@ MysqlStorage::~MysqlStorage()
 
 void MysqlStorage::checkMysqlThreadInit()
 {
-    if (! mysql_connection)
+    if (!mysql_connection)
         throw _Exception(_("mysql connection is not open or already closed"));
     //log_debug("checkMysqlThreadInit; thread_id=%d\n", pthread_self());
-    if (pthread_getspecific(mysql_init_key) == NULL)
-    {
+    if (pthread_getspecific(mysql_init_key) == nullptr) {
         log_debug("running mysql_thread_init(); thread_id=%d\n", pthread_self());
-        if (mysql_thread_init()) throw _Exception(_("error while calling mysql_thread_init()"));
-        if (pthread_setspecific(mysql_init_key, (void *) 1)) throw _Exception(_("error while calling pthread_setspecific()"));
+        if (mysql_thread_init())
+            throw _Exception(_("error while calling mysql_thread_init()"));
+        if (pthread_setspecific(mysql_init_key, (void*)1))
+            throw _Exception(_("error while calling pthread_setspecific()"));
     }
 }
 
 void MysqlStorage::threadCleanup()
 {
     log_debug("thread cleanup; thread_id=%d\n", pthread_self());
-    if (pthread_getspecific(mysql_init_key) != NULL)
-    {
+    if (pthread_getspecific(mysql_init_key) != nullptr) {
         mysql_thread_end();
     }
 }
@@ -121,87 +116,76 @@ void MysqlStorage::init()
 {
     log_debug("start\n");
     SQLStorage::init();
-    
-    AUTOLOCK(mysqlMutex);
+
+    unique_lock<decltype(mysqlMutex)> lock(mysqlMutex);
     int ret;
-    
-    if (! mysql_thread_safe())
-    {
+
+    if (!mysql_thread_safe()) {
         throw _Exception(_("mysql library is not thread safe!"));
     }
-    
+
     /// \todo write destructor function
-    ret = pthread_key_create(&mysql_init_key, NULL);
-    if (ret)
-    {
+    ret = pthread_key_create(&mysql_init_key, nullptr);
+    if (ret) {
         throw _Exception(_("could not create pthread_key"));
     }
-    mysql_server_init(0, NULL, NULL);
-    pthread_setspecific(mysql_init_key, (void *) 1);
-    
+    mysql_server_init(0, nullptr, nullptr);
+    pthread_setspecific(mysql_init_key, (void*)1);
+
     Ref<ConfigManager> config = ConfigManager::getInstance();
-    
+
     String dbHost = config->getOption(CFG_SERVER_STORAGE_MYSQL_HOST);
     String dbName = config->getOption(CFG_SERVER_STORAGE_MYSQL_DATABASE);
     String dbUser = config->getOption(CFG_SERVER_STORAGE_MYSQL_USERNAME);
     int dbPort = config->getIntOption(CFG_SERVER_STORAGE_MYSQL_PORT);
     String dbPass = config->getOption(CFG_SERVER_STORAGE_MYSQL_PASSWORD);
     String dbSock = config->getOption(CFG_SERVER_STORAGE_MYSQL_SOCKET);
-    
-    MYSQL *res_mysql;
-    
+
+    MYSQL* res_mysql;
+
     res_mysql = mysql_init(&db);
-    if(! res_mysql)
-    {
+    if (!res_mysql) {
         throw _Exception(_("mysql_init failed"));
     }
-    
+
     mysql_init_key_initialized = true;
-    
+
     mysql_options(&db, MYSQL_SET_CHARSET_NAME, "utf8");
-    
-    #ifdef HAVE_MYSQL_OPT_RECONNECT
-        my_bool my_bool_var = true;
-        mysql_options(&db, MYSQL_OPT_RECONNECT, &my_bool_var);
-    #endif
-    
+
+    my_bool my_bool_var = true;
+    mysql_options(&db, MYSQL_OPT_RECONNECT, &my_bool_var);
+
     res_mysql = mysql_real_connect(&db,
         dbHost.c_str(),
         dbUser.c_str(),
-        (dbPass == nil ? NULL : dbPass.c_str()),
+        (dbPass == nullptr ? nullptr : dbPass.c_str()),
         dbName.c_str(),
         dbPort, // port
-        (dbSock == nil ? NULL : dbSock.c_str()), // socket
+        (dbSock == nullptr ? nullptr : dbSock.c_str()), // socket
         0 // flags
-    );
-    if(! res_mysql)
-    {
+        );
+    if (!res_mysql) {
         throw _Exception(_("The connection to the MySQL database has failed: ") + getError(&db));
     }
-    
+
     /*
     int res = mysql_real_query(&db, MYSQL_SET_NAMES, strlen(MYSQL_SET_NAMES));
     if(res)
     {
         String myError = getError(&db);
-        throw _StorageException(nil, _("MySQL query 'SET NAMES' failed!"));
+        throw _StorageException(nullptr, _("MySQL query 'SET NAMES' failed!"));
     }
     */
-    
-    
+
     mysql_connection = true;
-    
-    String dbVersion = nil;
-    try
-    {
+
+    String dbVersion = nullptr;
+    try {
         dbVersion = getInternalSetting(_("db_version"));
+    } catch (Exception) {
     }
-    catch (Exception)
-    {
-    }
-    
-    if (dbVersion == nil)
-    {
+
+    if (dbVersion == nullptr) {
 #ifdef AUTO_CREATE_DATABASE
         log_info("database doesn't seem to exist. automatically creating database...\n");
         unsigned char buf[MS_CREATE_SQL_INFLATED_SIZE + 1]; // + 1 for '\0' at the end of the string
@@ -210,31 +194,26 @@ void MysqlStorage::init()
         if (ret != Z_OK || uncompressed_size != MS_CREATE_SQL_INFLATED_SIZE)
             throw _Exception(_("Error while uncompressing mysql create sql. returned: ") + ret);
         buf[MS_CREATE_SQL_INFLATED_SIZE] = '\0';
-        
-        char *sql_start = (char *)buf;
-        char *sql_end = strchr(sql_start, ';');
-        if (sql_end == NULL)
-        {
+
+        auto* sql_start = (char*)buf;
+        char* sql_end = strchr(sql_start, ';');
+        if (sql_end == nullptr) {
             throw _Exception(_("';' not found in mysql create sql"));
         }
-        do
-        {
+        do {
             ret = mysql_real_query(&db, sql_start, sql_end - sql_start);
-            if (ret)
-            {
+            if (ret) {
                 String myError = getError(&db);
                 throw _StorageException(myError, _("Mysql: error while creating db: ") + myError);
             }
             sql_start = sql_end + 1; // skip ';'
-            if (*sql_start == '\n')  // skip newline
+            if (*sql_start == '\n') // skip newline
                 sql_start++;
-            
+
             sql_end = strchr(sql_start, ';');
-        }
-        while(sql_end != NULL);
+        } while (sql_end != nullptr);
         dbVersion = getInternalSetting(_("db_version"));
-        if (dbVersion == nil)
-        {
+        if (dbVersion == nullptr) {
             shutdown();
             throw _Exception(_("error while creating database"));
         }
@@ -243,13 +222,11 @@ void MysqlStorage::init()
         shutdown();
         throw _Exception(_("database doesn't seem to exist yet and autocreation wasn't compiled in"));
 #endif
-        
     }
     log_debug("db_version: %s\n", dbVersion.c_str());
-    
+
     /* --- database upgrades --- */
-    if (dbVersion == "1")
-    {
+    if (dbVersion == "1") {
         log_info("Doing an automatic database upgrade from database version 1 to version 2...\n");
         _exec(MYSQL_UPDATE_1_2_1);
         _exec(MYSQL_UPDATE_1_2_2);
@@ -260,9 +237,8 @@ void MysqlStorage::init()
         log_info("database upgrade successful.\n");
         dbVersion = _("2");
     }
-    
-    if (dbVersion == "2")
-    {
+
+    if (dbVersion == "2") {
         log_info("Doing an automatic database upgrade from database version 2 to version 3...\n");
         _exec(MYSQL_UPDATE_2_3_1);
         _exec(MYSQL_UPDATE_2_3_2);
@@ -271,9 +247,8 @@ void MysqlStorage::init()
         log_info("database upgrade successful.\n");
         dbVersion = _("3");
     }
-    
-    if (dbVersion == "3")
-    {
+
+    if (dbVersion == "3") {
         log_info("Doing an automatic database upgrade from database version 3 to version 4...\n");
         _exec(MYSQL_UPDATE_3_4_1);
         _exec(MYSQL_UPDATE_3_4_2);
@@ -281,16 +256,16 @@ void MysqlStorage::init()
         log_info("database upgrade successful.\n");
         dbVersion = _("4");
     }
-    
+
     /* --- --- ---*/
-    
-    if (! string_ok(dbVersion) || dbVersion != "4")
+
+    if (!string_ok(dbVersion) || dbVersion != "4")
         throw _Exception(_("The database seems to be from a newer version (database version ") + dbVersion + ")!");
-    
-    AUTOUNLOCK();
-    
+
+    lock.unlock();
+
     log_debug("end\n");
-    
+
     dbReady();
 }
 
@@ -301,7 +276,7 @@ String MysqlStorage::quote(String value)
      * the \0; then the string won't be null-terminated, but that doesn't matter,
      * because we give the correct length to String()
      */
-    char *q = (char *)MALLOC(value.length() * 2 + 2);
+    auto* q = (char*)MALLOC(value.length() * 2 + 2);
     *q = '\'';
     long size = mysql_real_escape_string(&db, q + 1, value.c_str(), value.length());
     q[size + 1] = '\'';
@@ -310,7 +285,7 @@ String MysqlStorage::quote(String value)
     return ret;
 }
 
-String MysqlStorage::getError(MYSQL *db)
+String MysqlStorage::getError(MYSQL* db)
 {
     Ref<StringBuffer> err_buf(new StringBuffer());
     *err_buf << "mysql_error (" << String::from(mysql_errno(db));
@@ -319,35 +294,33 @@ String MysqlStorage::getError(MYSQL *db)
     return err_buf->toString();
 }
 
-Ref<SQLResult> MysqlStorage::select(const char *query, int length)
+Ref<SQLResult> MysqlStorage::select(const char* query, int length)
 {
 #ifdef MYSQL_SELECT_DEBUG
     log_debug("%s\n", query);
     print_backtrace();
 #endif
-    
+
     int res;
-    
+
     checkMysqlThreadInit();
-    AUTOLOCK(mysqlMutex);
+    AutoLock lock(mysqlMutex);
     res = mysql_real_query(&db, query, length);
-    if (res)
-    {
+    if (res) {
         String myError = getError(&db);
         throw _StorageException(myError, _("Mysql: mysql_real_query() failed: ") + myError + "; query: " + query);
     }
-    
-    MYSQL_RES *mysql_res;
+
+    MYSQL_RES* mysql_res;
     mysql_res = mysql_store_result(&db);
-    if(! mysql_res)
-    {
+    if (!mysql_res) {
         String myError = getError(&db);
         throw _StorageException(myError, _("Mysql: mysql_store_result() failed: ") + myError + "; query: " + query);
     }
-    return Ref<SQLResult> (new MysqlResult(mysql_res));
+    return Ref<SQLResult>(new MysqlResult(mysql_res));
 }
 
-int MysqlStorage::exec(const char *query, int length, bool getLastInsertId)
+int MysqlStorage::exec(const char* query, int length, bool getLastInsertId)
 {
 #ifdef MYSQL_EXEC_DEBUG
     log_debug("%s\n", query);
@@ -355,19 +328,18 @@ int MysqlStorage::exec(const char *query, int length, bool getLastInsertId)
 #endif
 
     int res;
-    
+
     checkMysqlThreadInit();
-    AUTOLOCK(mysqlMutex);
+    AutoLock lock(mysqlMutex);
     res = mysql_real_query(&db, query, length);
-    if(res)
-    {
+    if (res) {
         String myError = getError(&db);
         throw _StorageException(myError, _("Mysql: mysql_real_query() failed: ") + myError + "; query: " + query);
     }
-    int insert_id=-1;
-    if (getLastInsertId) insert_id = mysql_insert_id(&db);
+    int insert_id = -1;
+    if (getLastInsertId)
+        insert_id = mysql_insert_id(&db);
     return insert_id;
-    
 }
 
 void MysqlStorage::shutdownDriver()
@@ -379,15 +351,16 @@ void MysqlStorage::storeInternalSetting(String key, String value)
     String quotedValue = quote(value);
     Ref<StringBuffer> q(new StringBuffer());
     *q << "INSERT INTO " << QTB << INTERNAL_SETTINGS_TABLE << QTE << " (`key`, `value`) "
-    "VALUES (" << quote(key) << ", "<< quotedValue << ") "
-    "ON DUPLICATE KEY UPDATE `value` = " << quotedValue;
+                                                                     "VALUES ("
+       << quote(key) << ", " << quotedValue << ") "
+                                               "ON DUPLICATE KEY UPDATE `value` = "
+       << quotedValue;
     SQLStorage::exec(q);
 }
 
-void MysqlStorage::_exec(const char *query, int length)
+void MysqlStorage::_exec(const char* query, int length)
 {
-    if (mysql_real_query(&db, query, (length > 0 ? length : strlen(query))))
-    {
+    if (mysql_real_query(&db, query, (length > 0 ? length : strlen(query)))) {
         String myError = getError(&db);
         throw _StorageException(myError, _("Mysql: error while updating db: ") + myError);
     }
@@ -395,36 +368,34 @@ void MysqlStorage::_exec(const char *query, int length)
 
 void MysqlStorage::_addToInsertBuffer(Ref<StringBuffer> query)
 {
-    if (insertBuffer == nil)
-    {
-        insertBuffer = Ref<Array<StringBase> >(new Array<StringBase>());
+    if (insertBuffer == nullptr) {
+        insertBuffer = Ref<Array<StringBase>>(new Array<StringBase>());
         insertBuffer->append(_("BEGIN"));
     }
-    Ref<StringBase> sb (new StringBase(query->c_str()));
+    Ref<StringBase> sb(new StringBase(query->c_str()));
     insertBuffer->append(sb);
 }
 
 void MysqlStorage::_flushInsertBuffer()
 {
-    if (insertBuffer == nil)
+    if (insertBuffer == nullptr)
         return;
     insertBuffer->append(_("COMMIT"));
-    
+
     checkMysqlThreadInit();
-    AUTOLOCK(mysqlMutex);
-    for (int i=0; i < insertBuffer->size(); i++)
-    {
+    unique_lock<decltype(mysqlMutex)> lock(mysqlMutex);
+    for (int i = 0; i < insertBuffer->size(); i++) {
         _exec(insertBuffer->get(i)->data, insertBuffer->get(i)->len);
     }
-    AUTOUNLOCK();
+    lock.unlock();
     insertBuffer->clear();
     insertBuffer->append(_("BEGIN"));
 }
 
-
 /* MysqlResult */
 
-MysqlResult::MysqlResult(MYSQL_RES *mysql_res) : SQLResult()
+MysqlResult::MysqlResult(MYSQL_RES* mysql_res)
+    : SQLResult()
 {
     this->mysql_res = mysql_res;
     nullRead = false;
@@ -432,35 +403,34 @@ MysqlResult::MysqlResult(MYSQL_RES *mysql_res) : SQLResult()
 
 MysqlResult::~MysqlResult()
 {
-    if(mysql_res)
-    {
-        if (! nullRead)
-        {
+    if (mysql_res) {
+        if (!nullRead) {
             MYSQL_ROW mysql_row;
-            while((mysql_row = mysql_fetch_row(mysql_res)) != NULL); // read out data
+            while ((mysql_row = mysql_fetch_row(mysql_res)) != nullptr)
+                ; // read out data
         }
         mysql_free_result(mysql_res);
-        mysql_res = NULL;
+        mysql_res = nullptr;
     }
 }
 
 Ref<SQLRow> MysqlResult::nextRow()
-{   
+{
     MYSQL_ROW mysql_row;
     mysql_row = mysql_fetch_row(mysql_res);
-    if(mysql_row)
-    {
+    if (mysql_row) {
         return Ref<SQLRow>(new MysqlRow(mysql_row, Ref<SQLResult>(this)));
     }
     nullRead = true;
     mysql_free_result(mysql_res);
-    mysql_res = NULL;
-    return nil;
+    mysql_res = nullptr;
+    return nullptr;
 }
 
 /* MysqlRow */
 
-MysqlRow::MysqlRow(MYSQL_ROW mysql_row, Ref<SQLResult> sqlResult) : SQLRow(sqlResult)
+MysqlRow::MysqlRow(MYSQL_ROW mysql_row, Ref<SQLResult> sqlResult)
+    : SQLRow(sqlResult)
 {
     this->mysql_row = mysql_row;
 }
diff --git a/src/storage/mysql/mysql_storage.h b/src/storage/mysql/mysql_storage.h
index c377d76..3e79739 100644
--- a/src/storage/mysql/mysql_storage.h
+++ b/src/storage/mysql/mysql_storage.h
@@ -34,9 +34,9 @@
 #ifndef __MYSQL_STORAGE_H__
 #define __MYSQL_STORAGE_H__
 
+#include <mutex>
 #include "common.h"
 #include "storage/sql_storage.h"
-#include "sync.h"
 #include <mysql.h>
 
 class MysqlStorage : private SQLStorage
@@ -55,6 +55,7 @@ private:
     virtual inline zmm::String quote(unsigned long val) { return zmm::String::from(val); }
     virtual inline zmm::String quote(bool val) { return zmm::String(val ? '1' : '0'); }
     virtual inline zmm::String quote(char val) { return quote(zmm::String(val)); }
+    virtual inline zmm::String quote(long long val) { return zmm::String::from(val); }
     virtual zmm::Ref<SQLResult> select(const char *query, int length);
     virtual int exec(const char *query, int length, bool getLastInsertId = false);
     virtual void storeInternalSetting(zmm::String key, zmm::String value);
@@ -67,7 +68,8 @@ private:
     
     zmm::String getError(MYSQL *db);
     
-    zmm::Ref<Mutex> mysqlMutex;
+    std::recursive_mutex mysqlMutex;
+    using AutoLock = std::lock_guard<decltype(mysqlMutex)>;
     
     virtual void threadCleanup();
     virtual bool threadCleanupRequired() { return true; }
diff --git a/src/storage/sql_storage.cc b/src/storage/sql_storage.cc
index d247127..ca580df 100644
--- a/src/storage/sql_storage.cc
+++ b/src/storage/sql_storage.cc
@@ -29,29 +29,25 @@
 
 /// \file sql_storage.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include <limits.h>
 #include "sql_storage.h"
-#include "tools.h"
-#include "update_manager.h"
-#include "string_converter.h"
 #include "config_manager.h"
 #include "filesystem.h"
+#include "string_converter.h"
+#include "tools.h"
+#include "update_manager.h"
+#include <climits>
 
 using namespace zmm;
+using namespace std;
 
-#define MAX_REMOVE_SIZE     10000
+#define MAX_REMOVE_SIZE 10000
 #define MAX_REMOVE_RECURSION 500
 
-#define SQL_NULL             "NULL"
+#define SQL_NULL "NULL"
 
 #define RESOURCE_SEP '|'
 
-enum
-{
+enum {
     _id = 0,
     _ref_id,
     _parent_id,
@@ -79,12 +75,12 @@ enum
 };
 
 /* table quote */
-#define TQ(data)        QTB << data << QTE
+#define TQ(data) QTB << data << QTE
 /* table quote with dot */
-#define TQD(data1, data2)        TQ(data1) << '.' << TQ(data2)
+#define TQD(data1, data2) TQ(data1) << '.' << TQ(data2)
 
-#define SEL_F_QUOTED        << TQ('f') <<
-#define SEL_RF_QUOTED       << TQ("rf") <<
+#define SEL_F_QUOTED << TQ('f') <<
+#define SEL_RF_QUOTED << TQ("rf") <<
 
 // end quote, space, f quoted, dot, begin quote
 #define SEL_EQ_SP_FQ_DT_BQ  << QTE << ',' << TQ('f') << '.' << QTB <<
@@ -115,18 +111,20 @@ enum
     SEL_EQ_SP_RFQ_DT_BQ "mime_type" \
     SEL_EQ_SP_RFQ_DT_BQ "service_id" << QTE \
     << ',' << TQD("as","persistent")
-    
+
 #define SQL_QUERY_FOR_STRINGBUFFER "SELECT " << SELECT_DATA_FOR_STRINGBUFFER << \
     " FROM " << TQ(CDS_OBJECT_TABLE) << ' ' << TQ('f') << " LEFT JOIN " \
     << TQ(CDS_OBJECT_TABLE) << ' ' << TQ("rf") << " ON " << TQD('f',"ref_id") \
     << '=' << TQD("rf","id") << " LEFT JOIN " << TQ(AUTOSCAN_TABLE) << ' ' \
     << TQ("as") << " ON " << TQD("as","obj_id") << '=' << TQD('f',"id") << ' '
-    
+
 #define SQL_QUERY       sql_query
+#define SQL_QUERY sql_query
 
 /* enum for createObjectFromRow's mode parameter */
 
-SQLStorage::SQLStorage() : Storage()
+SQLStorage::SQLStorage()
+    : Storage()
 {
     table_quote_begin = '\0';
     table_quote_end = '\0';
@@ -136,42 +134,38 @@ SQLStorage::SQLStorage() : Storage()
 void SQLStorage::init()
 {
     if (table_quote_begin == '\0' || table_quote_end == '\0')
-        throw _Exception(_("quote vars need to be overriden!"));
-    
+        throw _Exception(_("quote vars need to be overridden!"));
+
     Ref<StringBuffer> buf(new StringBuffer());
     *buf << SQL_QUERY_FOR_STRINGBUFFER;
     this->sql_query = buf->toString();
-   
-    if (ConfigManager::getInstance()->getBoolOption(CFG_SERVER_STORAGE_CACHING_ENABLED))
-    {
+
+    if (ConfigManager::getInstance()->getBoolOption(CFG_SERVER_STORAGE_CACHING_ENABLED)) {
         cache = Ref<StorageCache>(new StorageCache());
         insertBufferOn = true;
-    }
-    else
-    {
-        cache = nil;
+    } else {
+        cache = nullptr;
         insertBufferOn = false;
     }
-    
+
     insertBufferEmpty = true;
-    insertBufferMutex = Ref<Mutex>(new Mutex());
     insertBufferStatementCount = 0;
     insertBufferByteCount = 0;
-    
+
     //log_debug("using SQL: %s\n", this->sql_query.c_str());
-    
+
     //objectTitleCache = Ref<DSOHash<CdsObject> >(new DSOHash<CdsObject>(OBJECT_CACHE_CAPACITY));
     //objectIDCache = Ref<DBOHash<int, CdsObject> >(new DBOHash<int, CdsObject>(OBJECT_CACHE_CAPACITY, -100));
-   
-/*    
+
+    /*
     Ref<SQLResult> res = select(_("SELECT MAX(id) + 1 FROM cds_objects"));
     Ref<SQLRow> row = res->nextRow();
     nextObjectID = row->col(0).toInt();
-    
+
     log_debug(("PRELOADING OBJECTS...\n"));
     res = select(getSelectQuery(SELECT_FULL));
     Ref<Array<CdsObject> > arr(new Array<CdsObject>());
-    while((row = res->nextRow()) != nil)
+    while((row = res->nextRow()) != nullptr)
     {
         Ref<CdsObject> obj = createObjectFromRow(row, SELECT_FULL);
         obj->optimize();
@@ -184,7 +178,6 @@ void SQLStorage::init()
 
 void SQLStorage::dbReady()
 {
-    nextIDMutex = Ref<Mutex>(new Mutex());;
     loadLastID();
 }
 
@@ -202,123 +195,105 @@ SQLStorage::~SQLStorage()
 
 Ref<CdsObject> SQLStorage::checkRefID(Ref<CdsObject> obj)
 {
-    if (! obj->isVirtual()) throw _Exception(_("checkRefID called for a non-virtual object"));
+    if (!obj->isVirtual())
+        throw _Exception(_("checkRefID called for a non-virtual object"));
+
     int refID = obj->getRefID();
     String location = obj->getLocation();
-    if (! string_ok(location))
+
+    if (!string_ok(location))
         throw _Exception(_("tried to check refID without a location set"));
-    if (refID > 0)
-    {
-        try
-        {
-            Ref<CdsObject> refObj;
-            refObj = loadObject(refID);
-            if (refObj != nil && refObj->getLocation() == location)
+
+    if (refID > 0) {
+        try {
+            Ref<CdsObject> refObj = loadObject(refID);
+            if (refObj != nullptr && refObj->getLocation() == location)
                 return refObj;
-        }
-        catch (Exception e)
-        {
-            // this should never happen - but fail softly if compiled without debugging
-            assert(0);
+        } catch (const Exception& e) {
             throw _Exception(_("illegal refID was set"));
         }
     }
-    
-    // this should never happen - but fail softly if compiled without debugging
-    // we do this assert to find code while debugging, that doesn't set the
-    // refID correctly
-    assert(0);
-    
+
+    // This should never happen - but fail softly
+    // It means that something doesn't set the refID correctly
+    log_warning("Failed to loadObject with refid: %d\n", refID);
+
     return findObjectByPath(location);
 }
 
-Ref<Array<SQLStorage::AddUpdateTable> > SQLStorage::_addUpdateObject(Ref<CdsObject> obj, bool isUpdate, int *changedContainer)
+Ref<Array<SQLStorage::AddUpdateTable>> SQLStorage::_addUpdateObject(Ref<CdsObject> obj, bool isUpdate, int* changedContainer)
 {
     int objectType = obj->getObjectType();
-    Ref<CdsObject> refObj = nil;
+    Ref<CdsObject> refObj = nullptr;
     bool hasReference = false;
     bool playlistRef = obj->getFlag(OBJECT_FLAG_PLAYLIST_REF);
-    if (playlistRef)
-    {
+    if (playlistRef) {
         if (IS_CDS_PURE_ITEM(objectType))
             throw _Exception(_("tried to add pure item with PLAYLIST_REF flag set"));
         if (obj->getRefID() <= 0)
             throw _Exception(_("PLAYLIST_REF flag set but refId is <=0"));
         refObj = loadObject(obj->getRefID());
-        if (refObj == nil)
+        if (refObj == nullptr)
             throw _Exception(_("PLAYLIST_REF flag set but refId doesn't point to an existing object"));
-    }
-    else if (obj->isVirtual() && IS_CDS_PURE_ITEM(objectType))
-    {
+    } else if (obj->isVirtual() && IS_CDS_PURE_ITEM(objectType)) {
         hasReference = true;
         refObj = checkRefID(obj);
-        if (refObj == nil)
+        if (refObj == nullptr)
             throw _Exception(_("tried to add or update a virtual object with illegal reference id and an illegal location"));
-    }
-    else if (obj->getRefID() > 0)
-    {
-        if (obj->getFlag(OBJECT_FLAG_ONLINE_SERVICE))
-        {
+    } else if (obj->getRefID() > 0) {
+        if (obj->getFlag(OBJECT_FLAG_ONLINE_SERVICE)) {
             hasReference = true;
             refObj = loadObject(obj->getRefID());
-            if (refObj == nil)
+            if (refObj == nullptr)
                 throw _Exception(_("OBJECT_FLAG_ONLINE_SERVICE and refID set but refID doesn't point to an existing object"));
-        }
-        else if (IS_CDS_CONTAINER(objectType))
-        {
+        } else if (IS_CDS_CONTAINER(objectType)) {
             // in this case it's a playlist-container. that's ok
             // we don't need to do anything
-        }
-        else
+        } else
             throw _Exception(_("refId set, but it makes no sense"));
     }
-    
-    Ref<Array<AddUpdateTable> > returnVal(new Array<AddUpdateTable>(2));
+
+    Ref<Array<AddUpdateTable>> returnVal(new Array<AddUpdateTable>(2));
     Ref<Dictionary> cdsObjectSql(new Dictionary());
-    returnVal->append(Ref<AddUpdateTable> (new AddUpdateTable(_(CDS_OBJECT_TABLE), cdsObjectSql)));
-    
+    returnVal->append(Ref<AddUpdateTable>(new AddUpdateTable(_(CDS_OBJECT_TABLE), cdsObjectSql)));
+
     cdsObjectSql->put(_("object_type"), quote(objectType));
-    
+
     if (hasReference || playlistRef)
         cdsObjectSql->put(_("ref_id"), quote(refObj->getID()));
     else if (isUpdate)
         cdsObjectSql->put(_("ref_id"), _(SQL_NULL));
-    
-    if (! hasReference || refObj->getClass() != obj->getClass())
+
+    if (!hasReference || refObj->getClass() != obj->getClass())
         cdsObjectSql->put(_("upnp_class"), quote(obj->getClass()));
     else if (isUpdate)
         cdsObjectSql->put(_("upnp_class"), _(SQL_NULL));
-    
+
     //if (!hasReference || refObj->getTitle() != obj->getTitle())
     cdsObjectSql->put(_("dc_title"), quote(obj->getTitle()));
     //else if (isUpdate)
     //    cdsObjectSql->put(_("dc_title"), _(SQL_NULL));
-    
+
     if (isUpdate)
         cdsObjectSql->put(_("metadata"), _(SQL_NULL));
     Ref<Dictionary> dict = obj->getMetadata();
-    if (dict->size() > 0)
-    {
-        if (! hasReference || ! refObj->getMetadata()->equals(obj->getMetadata()))
-        {
+    if (dict->size() > 0) {
+        if (!hasReference || !refObj->getMetadata()->equals(obj->getMetadata())) {
             cdsObjectSql->put(_("metadata"), quote(dict->encode()));
         }
     }
-    
+
     if (isUpdate)
         cdsObjectSql->put(_("auxdata"), _(SQL_NULL));
     dict = obj->getAuxData();
-    if (dict->size() > 0 && (! hasReference || ! refObj->getAuxData()->equals(obj->getAuxData())))
-    {
+    if (dict->size() > 0 && (!hasReference || !refObj->getAuxData()->equals(obj->getAuxData()))) {
         cdsObjectSql->put(_("auxdata"), quote(obj->getAuxData()->encode()));
     }
-    
-    if (! hasReference || (! obj->getFlag(OBJECT_FLAG_USE_RESOURCE_REF) && ! refObj->resourcesEqual(obj)))
-    {
+
+    if (!hasReference || (!obj->getFlag(OBJECT_FLAG_USE_RESOURCE_REF) && !refObj->resourcesEqual(obj))) {
         // encode resources
         Ref<StringBuffer> resBuf(new StringBuffer());
-        for (int i = 0; i < obj->getResourceCount(); i++)
-        {
+        for (int i = 0; i < obj->getResourceCount(); i++) {
             if (i > 0)
                 *resBuf << RESOURCE_SEP;
             *resBuf << obj->getResource(i)->encode();
@@ -328,171 +303,146 @@ Ref<Array<SQLStorage::AddUpdateTable> > SQLStorage::_addUpdateObject(Ref<CdsObje
             cdsObjectSql->put(_("resources"), quote(resStr));
         else
             cdsObjectSql->put(_("resources"), _(SQL_NULL));
-    }
-    else if (isUpdate)
+    } else if (isUpdate)
         cdsObjectSql->put(_("resources"), _(SQL_NULL));
-    
+
     obj->clearFlag(OBJECT_FLAG_USE_RESOURCE_REF);
-    
+
     cdsObjectSql->put(_("flags"), quote(obj->getFlags()));
-    
-    if (IS_CDS_CONTAINER(objectType))
-    {
-        if (! (isUpdate && obj->isVirtual()) )
+
+    if (IS_CDS_CONTAINER(objectType)) {
+        if (!(isUpdate && obj->isVirtual()))
             throw _Exception(_("tried to add a container or tried to update a non-virtual container via _addUpdateObject; is this correct?"));
         String dbLocation = addLocationPrefix(LOC_VIRT_PREFIX, obj->getLocation());
         cdsObjectSql->put(_("location"), quote(dbLocation));
         cdsObjectSql->put(_("location_hash"), quote(stringHash(dbLocation)));
     }
-    
-    if (IS_CDS_ITEM(objectType))
-    {
+
+    if (IS_CDS_ITEM(objectType)) {
         Ref<CdsItem> item = RefCast(obj, CdsItem);
-        
-        if (! hasReference)
-        {
+
+        if (!hasReference) {
             String loc = item->getLocation();
-            if (!string_ok(loc)) throw _Exception(_("tried to create or update a non-referenced item without a location set"));
-            if (IS_CDS_PURE_ITEM(objectType))
-            {
-                Ref<Array<StringBase> > pathAr = split_path(loc);
+            if (!string_ok(loc))
+                throw _Exception(_("tried to create or update a non-referenced item without a location set"));
+            if (IS_CDS_PURE_ITEM(objectType)) {
+                Ref<Array<StringBase>> pathAr = split_path(loc);
                 String path = pathAr->get(0);
                 int parentID = ensurePathExistence(path, changedContainer);
                 item->setParentID(parentID);
                 String dbLocation = addLocationPrefix(LOC_FILE_PREFIX, loc);
                 cdsObjectSql->put(_("location"), quote(dbLocation));
                 cdsObjectSql->put(_("location_hash"), quote(stringHash(dbLocation)));
-            }
-            else 
-            {
+            } else {
                 // URLs and active items
                 cdsObjectSql->put(_("location"), quote(loc));
                 cdsObjectSql->put(_("location_hash"), _(SQL_NULL));
             }
-        }
-        else 
-        {
-            if (isUpdate)
-            {
+        } else {
+            if (isUpdate) {
                 cdsObjectSql->put(_("location"), _(SQL_NULL));
                 cdsObjectSql->put(_("location_hash"), _(SQL_NULL));
             }
         }
-        
-        if (item->getTrackNumber() > 0)
-        {
+
+        if (item->getTrackNumber() > 0) {
             cdsObjectSql->put(_("track_number"), quote(item->getTrackNumber()));
-        }
-        else
-        {
+        } else {
             if (isUpdate)
                 cdsObjectSql->put(_("track_number"), _(SQL_NULL));
         }
-        
-        if (string_ok(item->getServiceID()))
-        {
-            if (! hasReference || RefCast(refObj,CdsItem)->getServiceID() != item->getServiceID())
+
+        if (string_ok(item->getServiceID())) {
+            if (!hasReference || RefCast(refObj, CdsItem)->getServiceID() != item->getServiceID())
                 cdsObjectSql->put(_("service_id"), quote(item->getServiceID()));
             else
                 cdsObjectSql->put(_("service_id"), _(SQL_NULL));
-        }
-        else
-        {
+        } else {
             if (isUpdate)
                 cdsObjectSql->put(_("service_id"), _(SQL_NULL));
         }
-        
+
         cdsObjectSql->put(_("mime_type"), quote(item->getMimeType()));
     }
-    if (IS_CDS_ACTIVE_ITEM(objectType))
-    {
+    if (IS_CDS_ACTIVE_ITEM(objectType)) {
         Ref<Dictionary> cdsActiveItemSql(new Dictionary());
-        returnVal->append(Ref<AddUpdateTable> (new AddUpdateTable(_(CDS_ACTIVE_ITEM_TABLE), cdsActiveItemSql)));
+        returnVal->append(Ref<AddUpdateTable>(new AddUpdateTable(_(CDS_ACTIVE_ITEM_TABLE), cdsActiveItemSql)));
         Ref<CdsActiveItem> aitem = RefCast(obj, CdsActiveItem);
-        
+
         cdsActiveItemSql->put(_("id"), String::from(aitem->getID()));
         cdsActiveItemSql->put(_("action"), quote(aitem->getAction()));
         cdsActiveItemSql->put(_("state"), quote(aitem->getState()));
     }
-    
-    
+
     // check for a duplicate (virtual) object
-    if (hasReference && ! isUpdate)
-    {
+    if (hasReference && !isUpdate) {
         Ref<StringBuffer> qb(new StringBuffer());
-        *qb << "SELECT " << TQ("id") 
+        *qb << "SELECT " << TQ("id")
             << " FROM " << TQ(CDS_OBJECT_TABLE)
-            << " WHERE " << TQ("parent_id") 
+            << " WHERE " << TQ("parent_id")
             << '=' << quote(obj->getParentID())
-            << " AND " << TQ("ref_id") 
+            << " AND " << TQ("ref_id")
             << '=' << quote(refObj->getID())
             << " AND " << TQ("dc_title")
             << '=' << quote(obj->getTitle())
             << " LIMIT 1";
         Ref<SQLResult> res = select(qb);
         // if duplicate items is found - ignore
-        if (res != nil && (res->nextRow() != nil))
-            return nil;
+        if (res != nullptr && (res->nextRow() != nullptr))
+            return nullptr;
     }
-    
+
     if (obj->getParentID() == INVALID_OBJECT_ID)
         throw _Exception(_("tried to create or update an object with an illegal parent id"));
     cdsObjectSql->put(_("parent_id"), String::from(obj->getParentID()));
-    
+
     return returnVal;
 }
 
-void SQLStorage::addObject(Ref<CdsObject> obj, int *changedContainer)
+void SQLStorage::addObject(Ref<CdsObject> obj, int* changedContainer)
 {
     if (obj->getID() != INVALID_OBJECT_ID)
         throw _Exception(_("tried to add an object with an object ID set"));
     //obj->setID(INVALID_OBJECT_ID);
-    Ref<Array<AddUpdateTable> > data = _addUpdateObject(obj, false, changedContainer);
-    if (data == nil)
+    Ref<Array<AddUpdateTable>> data = _addUpdateObject(obj, false, changedContainer);
+    if (data == nullptr)
         return;
     int lastInsertID = INVALID_OBJECT_ID;
-    for (int i = 0; i < data->size(); i++)
-    {
+    for (int i = 0; i < data->size(); i++) {
         Ref<AddUpdateTable> addUpdateTable = data->get(i);
         String tableName = addUpdateTable->getTable();
-        Ref<Array<DictionaryElement> > dataElements = addUpdateTable->getDict()->getElements();
-        
+        Ref<Array<DictionaryElement>> dataElements = addUpdateTable->getDict()->getElements();
+
         Ref<StringBuffer> fields(new StringBuffer(128));
         Ref<StringBuffer> values(new StringBuffer(128));
-        
-        for (int j = 0; j < dataElements->size(); j++)
-        {
+
+        for (int j = 0; j < dataElements->size(); j++) {
             Ref<DictionaryElement> element = dataElements->get(j);
-            if (j != 0)
-            {
+            if (j != 0) {
                 *fields << ',';
                 *values << ',';
             }
             *fields << TQ(element->getKey());
-            if (lastInsertID != INVALID_OBJECT_ID &&
-                element->getKey() == "id" &&
-                element->getValue().toInt() == INVALID_OBJECT_ID )
+            if (lastInsertID != INVALID_OBJECT_ID && element->getKey() == "id" && element->getValue().toInt() == INVALID_OBJECT_ID)
                 *values << lastInsertID;
             else
-            *values << element->getValue();
+                *values << element->getValue();
         }
-        
+
         /* manually generate ID */
-        if (lastInsertID == INVALID_OBJECT_ID && tableName == _(CDS_OBJECT_TABLE))
-        {
+        if (lastInsertID == INVALID_OBJECT_ID && tableName == _(CDS_OBJECT_TABLE)) {
             lastInsertID = getNextID();
             obj->setID(lastInsertID);
             *fields << ',' << TQ("id");
             *values << ',' << quote(lastInsertID);
         }
         /* -------------------- */
-        
+
         Ref<StringBuffer> qb(new StringBuffer(256));
-        *qb << "INSERT INTO " << TQ(tableName) << " (" << fields->toString() <<
-                ") VALUES (" << values->toString() << ')';
-                
+        *qb << "INSERT INTO " << TQ(tableName) << " (" << fields->toString() << ") VALUES (" << values->toString() << ')';
+
         log_debug("insert_query: %s\n", qb->toString().c_str());
-        
+
         /*
         if (lastInsertID == INVALID_OBJECT_ID && tableName == _(CDS_OBJECT_TABLE))
         {
@@ -502,17 +452,16 @@ void SQLStorage::addObject(Ref<CdsObject> obj, int *changedContainer)
         else
             exec(qb);
         */
-        
-        if (! doInsertBuffering())
+
+        if (!doInsertBuffering())
             exec(qb);
         else
             addToInsertBuffer(qb);
     }
-    
+
     /* add to cache */
-    if (cacheOn())
-    {
-        AUTOLOCK(cache->getMutex());
+    if (cacheOn()) {
+        AutoLock lock(cache->getMutex());
         cache->addChild(obj->getParentID());
         if (cache->flushed())
             flushInsertBuffer();
@@ -521,52 +470,46 @@ void SQLStorage::addObject(Ref<CdsObject> obj, int *changedContainer)
     /* ------------ */
 }
 
-void SQLStorage::updateObject(zmm::Ref<CdsObject> obj, int *changedContainer)
+void SQLStorage::updateObject(zmm::Ref<CdsObject> obj, int* changedContainer)
 {
     flushInsertBuffer();
-    
-    Ref<Array<AddUpdateTable> > data;
-    if (obj->getID() == CDS_ID_FS_ROOT)
-    {
-        data = Ref<Array<AddUpdateTable> >(new Array<AddUpdateTable>(1));
+
+    Ref<Array<AddUpdateTable>> data;
+    if (obj->getID() == CDS_ID_FS_ROOT) {
+        data = Ref<Array<AddUpdateTable>>(new Array<AddUpdateTable>(1));
         Ref<Dictionary> cdsObjectSql(new Dictionary());
-        data->append(Ref<AddUpdateTable> (new AddUpdateTable(_(CDS_OBJECT_TABLE), cdsObjectSql)));
+        data->append(Ref<AddUpdateTable>(new AddUpdateTable(_(CDS_OBJECT_TABLE), cdsObjectSql)));
         cdsObjectSql->put(_("dc_title"), quote(obj->getTitle()));
         setFsRootName(obj->getTitle());
         cdsObjectSql->put(_("upnp_class"), quote(obj->getClass()));
-    }
-    else
-    {
+    } else {
         if (IS_FORBIDDEN_CDS_ID(obj->getID()))
-            throw _Exception(_("tried to update an object with a forbidden ID (")+obj->getID()+")!");
+            throw _Exception(_("tried to update an object with a forbidden ID (") + obj->getID() + ")!");
         data = _addUpdateObject(obj, true, changedContainer);
-        if (data == nil)
+        if (data == nullptr)
             return;
     }
-    for (int i = 0; i < data->size(); i++)
-    {
+    for (int i = 0; i < data->size(); i++) {
         Ref<AddUpdateTable> addUpdateTable = data->get(i);
         String tableName = addUpdateTable->getTable();
-        Ref<Array<DictionaryElement> > dataElements = addUpdateTable->getDict()->getElements();
-        
+        Ref<Array<DictionaryElement>> dataElements = addUpdateTable->getDict()->getElements();
+
         Ref<StringBuffer> qb(new StringBuffer(256));
         *qb << "UPDATE " << TQ(tableName) << " SET ";
-        
-        for (int j = 0; j < dataElements->size(); j++)
-        {
+
+        for (int j = 0; j < dataElements->size(); j++) {
             Ref<DictionaryElement> element = dataElements->get(j);
-            if (j != 0)
-            {
+            if (j != 0) {
                 *qb << ',';
             }
             *qb << TQ(element->getKey()) << '='
                 << element->getValue();
         }
-        
+
         *qb << " WHERE id = " << obj->getID();
-        
+
         log_debug("upd_query: %s\n", qb->toString().c_str());
-        
+
         exec(qb);
     }
     /* add to cache */
@@ -576,36 +519,33 @@ void SQLStorage::updateObject(zmm::Ref<CdsObject> obj, int *changedContainer)
 
 Ref<CdsObject> SQLStorage::loadObject(int objectID)
 {
-    
+
     /* check cache */
-    if (cacheOn())
-    {
-        AUTOLOCK(cache->getMutex());
+    if (cacheOn()) {
+        AutoLock lock(cache->getMutex());
         Ref<CacheObject> cObj = cache->getObject(objectID);
-        if (cObj != nil)
-        {
+        if (cObj != nullptr) {
             if (cObj->knowsObject())
                 return cObj->getObject();
         }
     }
     /* ----------- */
-    
-/*
+
+    /*
     Ref<CdsObject> obj = objectIDCache->get(objectID);
-    if (obj != nil)
+    if (obj != nullptr)
         return obj;
     throw _Exception(_("Object not found: ") + objectID);
 */
     Ref<StringBuffer> qb(new StringBuffer());
-    
+
     //log_debug("sql_query = %s\n",sql_query.c_str());
-    
-    *qb << SQL_QUERY << " WHERE " << TQD('f',"id") << '=' << objectID;
+
+    *qb << SQL_QUERY << " WHERE " << TQD('f', "id") << '=' << objectID;
 
     Ref<SQLResult> res = select(qb);
     Ref<SQLRow> row;
-    if (res != nil && (row = res->nextRow()) != nil)
-    {
+    if (res != nullptr && (row = res->nextRow()) != nullptr) {
         return createObjectFromRow(row);
     }
     throw _ObjectNotFoundException(_("Object not found: ") + objectID);
@@ -614,280 +554,248 @@ Ref<CdsObject> SQLStorage::loadObject(int objectID)
 Ref<CdsObject> SQLStorage::loadObjectByServiceID(String serviceID)
 {
     flushInsertBuffer();
-    
+
     Ref<StringBuffer> qb(new StringBuffer());
-    *qb << SQL_QUERY << " WHERE " << TQD('f',"service_id") << '=' << quote(serviceID);
+    *qb << SQL_QUERY << " WHERE " << TQD('f', "service_id") << '=' << quote(serviceID);
     Ref<SQLResult> res = select(qb);
     Ref<SQLRow> row;
-    if (res != nil && (row = res->nextRow()) != nil)
-    {
+    if (res != nullptr && (row = res->nextRow()) != nullptr) {
         return createObjectFromRow(row);
     }
-    
-    return nil;
+
+    return nullptr;
 }
 
 Ref<IntArray> SQLStorage::getServiceObjectIDs(char servicePrefix)
 {
     flushInsertBuffer();
-    
+
     Ref<IntArray> objectIDs(new IntArray());
     Ref<StringBuffer> qb(new StringBuffer());
     *qb << "SELECT " << TQ("id")
         << " FROM " << TQ(CDS_OBJECT_TABLE)
         << " WHERE " << TQ("service_id")
-        << " LIKE " << quote(String(servicePrefix)+'%');
+        << " LIKE " << quote(String(servicePrefix) + '%');
 
     Ref<SQLResult> res = select(qb);
-    if (res == nil)
+    if (res == nullptr)
         throw _Exception(_("db error"));
-    
+
     Ref<SQLRow> row;
-    while((row = res->nextRow()) != nil)
-    {
+    while ((row = res->nextRow()) != nullptr) {
         objectIDs->append(row->col(0).toInt());
     }
-    
+
     return objectIDs;
 }
 
-Ref<Array<CdsObject> > SQLStorage::browse(Ref<BrowseParam> param)
+Ref<Array<CdsObject>> SQLStorage::browse(Ref<BrowseParam> param)
 {
     flushInsertBuffer();
-    
+
     int objectID;
     int objectType = 0;
-    
+
     bool getContainers = param->getFlag(BROWSE_CONTAINERS);
     bool getItems = param->getFlag(BROWSE_ITEMS);
-    
+
     objectID = param->getObjectID();
-    
+
     Ref<SQLResult> res;
     Ref<SQLRow> row;
-    
+
     bool haveObjectType = false;
-    
+
     /* check cache */
-    if (cacheOn())
-    {
-        AUTOLOCK(cache->getMutex());
+    if (cacheOn()) {
+        AutoLock lock(cache->getMutex());
         Ref<CacheObject> cObj = cache->getObject(objectID);
-        if (cObj != nil && cObj->knowsObjectType())
-        {
+        if (cObj != nullptr && cObj->knowsObjectType()) {
             objectType = cObj->getObjectType();
             haveObjectType = true;
         }
     }
     /* ----------- */
-    
+
     Ref<StringBuffer> qb(new StringBuffer());
-    if (! haveObjectType)
-    {
+    if (!haveObjectType) {
         *qb << "SELECT " << TQ("object_type")
             << " FROM " << TQ(CDS_OBJECT_TABLE)
             << " WHERE " << TQ("id") << '=' << objectID;
         res = select(qb);
-        if(res != nil && (row = res->nextRow()) != nil)
-        {
+        if (res != nullptr && (row = res->nextRow()) != nullptr) {
             objectType = row->col(0).toInt();
             haveObjectType = true;
-            
+
             /* add to cache */
-            if (cacheOn())
-            {
-                AUTOLOCK(cache->getMutex());
+            if (cacheOn()) {
+                AutoLock lock(cache->getMutex());
                 cache->getObjectDefinitely(objectID)->setObjectType(objectType);
                 if (cache->flushed())
                     flushInsertBuffer();
             }
             /* ------------ */
-        }
-        else
-        {
+        } else {
             throw _ObjectNotFoundException(_("Object not found: ") + objectID);
         }
-        
-        row = nil;
-        res = nil;
+
+        row = nullptr;
+        res = nullptr;
     }
-    
-    
+
     bool hideFsRoot = param->getFlag(BROWSE_HIDE_FS_ROOT);
-    
-    if(param->getFlag(BROWSE_DIRECT_CHILDREN) && IS_CDS_CONTAINER(objectType))
-    {
+
+    if (param->getFlag(BROWSE_DIRECT_CHILDREN) && IS_CDS_CONTAINER(objectType)) {
         param->setTotalMatches(getChildCount(objectID, getContainers, getItems, hideFsRoot));
-    }
-    else
-    {
+    } else {
         param->setTotalMatches(1);
     }
-    
+
     // order by code..
     qb->clear();
     if (param->getFlag(BROWSE_TRACK_SORT))
-        *qb << TQD('f',"track_number") << ',';
-    *qb << TQD('f',"dc_title");
+        *qb << TQD('f', "track_number") << ',';
+    *qb << TQD('f', "dc_title");
     String orderByCode = qb->toString();
-    
+
     qb->clear();
     *qb << SQL_QUERY << " WHERE ";
-    
-    if(param->getFlag(BROWSE_DIRECT_CHILDREN) && IS_CDS_CONTAINER(objectType))
-    {
+
+    if (param->getFlag(BROWSE_DIRECT_CHILDREN) && IS_CDS_CONTAINER(objectType)) {
         int count = param->getRequestedCount();
         bool doLimit = true;
-        if (! count)
-        {
+        if (!count) {
             if (param->getStartingIndex())
                 count = INT_MAX;
             else
                 doLimit = false;
         }
-        
-        *qb << TQD('f',"parent_id") << '=' << objectID;
-        
+
+        *qb << TQD('f', "parent_id") << '=' << objectID;
+
         if (objectID == CDS_ID_ROOT && hideFsRoot)
-            *qb << " AND " << TQD('f',"id") << "!="
-                << quote (CDS_ID_FS_ROOT);
-        
-        if (! getContainers && ! getItems)
-        {
+            *qb << " AND " << TQD('f', "id") << "!="
+                << quote(CDS_ID_FS_ROOT);
+
+        if (!getContainers && !getItems) {
             *qb << " AND 0=1";
-        }
-        else if (getContainers && ! getItems)
-        {
-            *qb << " AND " << TQD('f',"object_type") << '='
+        } else if (getContainers && !getItems) {
+            *qb << " AND " << TQD('f', "object_type") << '='
                 << quote(OBJECT_TYPE_CONTAINER)
                 << " ORDER BY " << orderByCode;
-        }
-        else if (! getContainers && getItems)
-        {
-            *qb << " AND (" << TQD('f',"object_type") << " & "
-                << quote(OBJECT_TYPE_ITEM) << ") = " 
+        } else if (!getContainers && getItems) {
+            *qb << " AND (" << TQD('f', "object_type") << " & "
+                << quote(OBJECT_TYPE_ITEM) << ") = "
                 << quote(OBJECT_TYPE_ITEM)
                 << " ORDER BY " << orderByCode;
-        }
-        else
-        {
+        } else {
             *qb << " ORDER BY ("
-            << TQD('f',"object_type") << '=' << quote(OBJECT_TYPE_CONTAINER)
-            << ") DESC, " << orderByCode;
+                << TQD('f', "object_type") << '=' << quote(OBJECT_TYPE_CONTAINER)
+                << ") DESC, " << orderByCode;
         }
         if (doLimit)
             *qb << " LIMIT " << count << " OFFSET " << param->getStartingIndex();
-    }
-    else // metadata
+    } else // metadata
     {
-        *qb << TQD('f',"id") << '=' << objectID << " LIMIT 1";
+        *qb << TQD('f', "id") << '=' << objectID << " LIMIT 1";
     }
     log_debug("QUERY: %s\n", qb->toString().c_str());
     res = select(qb);
-    
-    Ref<Array<CdsObject> > arr(new Array<CdsObject>());
-    
-    while((row = res->nextRow()) != nil)
-    {
+
+    Ref<Array<CdsObject>> arr(new Array<CdsObject>());
+
+    while ((row = res->nextRow()) != nullptr) {
         Ref<CdsObject> obj = createObjectFromRow(row);
         arr->append(obj);
-        row = nil;
+        row = nullptr;
     }
-    
-    row = nil;
-    res = nil;
-    
+
+    row = nullptr;
+    res = nullptr;
+
     // update childCount fields
-    for (int i = 0; i < arr->size(); i++)
-    {
+    for (int i = 0; i < arr->size(); i++) {
         Ref<CdsObject> obj = arr->get(i);
-        if (IS_CDS_CONTAINER(obj->getObjectType()))
-        {
+        if (IS_CDS_CONTAINER(obj->getObjectType())) {
             Ref<CdsContainer> cont = RefCast(obj, CdsContainer);
             cont->setChildCount(getChildCount(cont->getID(), getContainers, getItems, hideFsRoot));
         }
     }
-    
+
     return arr;
 }
 
 int SQLStorage::getChildCount(int contId, bool containers, bool items, bool hideFsRoot)
 {
-    if (! containers && ! items)
+    if (!containers && !items)
         return 0;
-    
+
     /* check cache */
-    if (cacheOn() && containers && items && ! (contId == CDS_ID_ROOT && hideFsRoot))
-    {
-        AUTOLOCK(cache->getMutex());
+    if (cacheOn() && containers && items && !(contId == CDS_ID_ROOT && hideFsRoot)) {
+        AutoLock lock(cache->getMutex());
         Ref<CacheObject> cObj = cache->getObject(contId);
-        if (cObj != nil)
-        {
+        if (cObj != nullptr) {
             if (cObj->knowsNumChildren())
                 return cObj->getNumChildren();
             //cObj->debug();
         }
     }
     /* ----------- */
-    
+
     flushInsertBuffer();
-    
+
     Ref<SQLRow> row;
     Ref<SQLResult> res;
     Ref<StringBuffer> qb(new StringBuffer());
     *qb << "SELECT COUNT(*) FROM " << TQ(CDS_OBJECT_TABLE)
         << " WHERE " << TQ("parent_id") << '=' << contId;
-    if (containers && ! items)
+    if (containers && !items)
         *qb << " AND " << TQ("object_type") << '=' << OBJECT_TYPE_CONTAINER;
-    else if (items && ! containers)
+    else if (items && !containers)
         *qb << " AND (" << TQ("object_type") << " & " << OBJECT_TYPE_ITEM
             << ") = " << OBJECT_TYPE_ITEM;
-    if (contId == CDS_ID_ROOT && hideFsRoot)
-    {
-        *qb << " AND " << TQ("id") << "!=" << quote (CDS_ID_FS_ROOT);
+    if (contId == CDS_ID_ROOT && hideFsRoot) {
+        *qb << " AND " << TQ("id") << "!=" << quote(CDS_ID_FS_ROOT);
     }
     res = select(qb);
-    if (res != nil && (row = res->nextRow()) != nil)
-    {
+    if (res != nullptr && (row = res->nextRow()) != nullptr) {
         int childCount = row->col(0).toInt();
-        
+
         /* add to cache */
-        if (cacheOn() && containers && items && ! (contId == CDS_ID_ROOT && hideFsRoot))
-        {
-            AUTOLOCK(cache->getMutex());
+        if (cacheOn() && containers && items && !(contId == CDS_ID_ROOT && hideFsRoot)) {
+            AutoLock lock(cache->getMutex());
             cache->getObjectDefinitely(contId)->setNumChildren(childCount);
             if (cache->flushed())
                 flushInsertBuffer();
         }
         /* ------------ */
-        
+
         return childCount;
     }
     return 0;
 }
 
-Ref<Array<StringBase> > SQLStorage::getMimeTypes()
+Ref<Array<StringBase>> SQLStorage::getMimeTypes()
 {
     flushInsertBuffer();
-    
-    Ref<Array<StringBase> > arr(new Array<StringBase>());
-    
+
+    Ref<Array<StringBase>> arr(new Array<StringBase>());
+
     Ref<StringBuffer> qb(new StringBuffer());
     *qb << "SELECT DISTINCT " << TQ("mime_type")
         << " FROM " << TQ(CDS_OBJECT_TABLE)
         << " WHERE " << TQ("mime_type") << " IS NOT NULL ORDER BY "
         << TQ("mime_type");
     Ref<SQLResult> res = select(qb);
-    if (res == nil)
+    if (res == nullptr)
         throw _Exception(_("db error"));
-    
+
     Ref<SQLRow> row;
-    
-    while ((row = res->nextRow()) != nil)
-    {
+
+    while ((row = res->nextRow()) != nullptr) {
         arr->append(String(row->col(0)));
     }
-    
+
     return arr;
 }
 
@@ -896,31 +804,25 @@ Ref<CdsObject> SQLStorage::_findObjectByPath(String fullpath)
     //log_debug("fullpath: %s\n", fullpath.c_str());
     fullpath = fullpath.reduce(DIR_SEPARATOR);
     //log_debug("fullpath after reduce: %s\n", fullpath.c_str());
-    Ref<Array<StringBase> > pathAr = split_path(fullpath);
+    Ref<Array<StringBase>> pathAr = split_path(fullpath);
     String path = pathAr->get(0);
     String filename = pathAr->get(1);
-    
+
     bool file = string_ok(filename);
-    
+
     String dbLocation;
-    if (file)
-    {
+    if (file) {
         //flushInsertBuffer(); - not needed if correctly in cache (see below)
         dbLocation = addLocationPrefix(LOC_FILE_PREFIX, fullpath);
-    }
-    else
+    } else
         dbLocation = addLocationPrefix(LOC_DIR_PREFIX, path);
-    
-    
+
     /* check cache */
-    if (cacheOn())
-    {
-        AUTOLOCK(cache->getMutex());
-        Ref<Array<CacheObject> > objects = cache->getObjects(dbLocation);
-        if (objects != nil)
-        {
-            for (int i = 0; i < objects->size(); i++)
-            {
+    if (cacheOn()) {
+        AutoLock lock(cache->getMutex());
+        Ref<Array<CacheObject>> objects = cache->getObjects(dbLocation);
+        if (objects != nullptr) {
+            for (int i = 0; i < objects->size(); i++) {
                 Ref<CacheObject> cObj = objects->get(i);
                 if (cObj->knowsObject() && cObj->knowsVirtual() && !cObj->getVirtual())
                     return cObj->getObject();
@@ -928,22 +830,21 @@ Ref<CdsObject> SQLStorage::_findObjectByPath(String fullpath)
         }
     }
     /* ----------- */
-    
+
     Ref<StringBuffer> qb(new StringBuffer());
     *qb << SQL_QUERY
-            << " WHERE " << TQD('f',"location_hash") << '=' << quote(stringHash(dbLocation))
-            << " AND " << TQD('f',"location") << '=' << quote(dbLocation)
-            << " AND " << TQD('f',"ref_id") << " IS NULL "
-            "LIMIT 1";
-    
+        << " WHERE " << TQD('f', "location_hash") << '=' << quote(stringHash(dbLocation))
+        << " AND " << TQD('f', "location") << '=' << quote(dbLocation)
+        << " AND " << TQD('f', "ref_id") << " IS NULL "
+                                            "LIMIT 1";
+
     Ref<SQLResult> res = select(qb);
-    if (res == nil)
+    if (res == nullptr)
         throw _Exception(_("error while doing select: ") + qb->toString());
-    
-    
+
     Ref<SQLRow> row = res->nextRow();
-    if (row == nil)
-        return nil;
+    if (row == nullptr)
+        return nullptr;
     return createObjectFromRow(row);
 }
 
@@ -955,55 +856,68 @@ Ref<CdsObject> SQLStorage::findObjectByPath(String fullpath)
 int SQLStorage::findObjectIDByPath(String fullpath)
 {
     Ref<CdsObject> obj = _findObjectByPath(fullpath);
-    if (obj == nil)
+    if (obj == nullptr)
         return INVALID_OBJECT_ID;
     return obj->getID();
 }
 
-int SQLStorage::ensurePathExistence(String path, int *changedContainer)
+int SQLStorage::ensurePathExistence(String path, int* changedContainer)
 {
     *changedContainer = INVALID_OBJECT_ID;
     String cleanPath = path.reduce(DIR_SEPARATOR);
     if (cleanPath == DIR_SEPARATOR)
         return CDS_ID_FS_ROOT;
+
     if (cleanPath.charAt(cleanPath.length() - 1) == DIR_SEPARATOR) // cut off trailing slash
         cleanPath = cleanPath.substring(0, cleanPath.length() - 1);
+
     return _ensurePathExistence(cleanPath, changedContainer);
 }
 
-int SQLStorage::_ensurePathExistence(String path, int *changedContainer)
+int SQLStorage::_ensurePathExistence(String path, int* changedContainer)
 {
     if (path == DIR_SEPARATOR)
         return CDS_ID_FS_ROOT;
+
     Ref<CdsObject> obj = findObjectByPath(path + DIR_SEPARATOR);
-    if (obj != nil)
+    if (obj != nullptr)
         return obj->getID();
-    Ref<Array<StringBase> > pathAr = split_path(path);
+
+    Ref<Array<StringBase>> pathAr = split_path(path);
     String parent = pathAr->get(0);
     String folder = pathAr->get(1);
-    int parentID;
-    parentID = ensurePathExistence(parent, changedContainer);
-    
+
+    int parentID = ensurePathExistence(parent, changedContainer);
+
     Ref<StringConverter> f2i = StringConverter::f2i();
-    if (changedContainer != NULL && *changedContainer == INVALID_OBJECT_ID)
+    if (changedContainer != nullptr && *changedContainer == INVALID_OBJECT_ID)
         *changedContainer = parentID;
-    return createContainer(parentID, f2i->convert(folder), path, false, nil, INVALID_OBJECT_ID);
+
+    return createContainer(parentID, f2i->convert(folder), path, false, nullptr, INVALID_OBJECT_ID, nullptr);
 }
 
-int SQLStorage::createContainer(int parentID, String name, String path, bool isVirtual, String upnpClass, int refID)
+int SQLStorage::createContainer(int parentID, String name, String path, bool isVirtual, String upnpClass, int refID, Ref<Dictionary> itemMetadata)
 {
-    if (refID > 0)
-    {
+    if (refID > 0) {
         Ref<CdsObject> refObj = loadObject(refID);
-        if (refObj == nil)
+        if (refObj == nullptr)
             throw _Exception(_("tried to create container with refID set, but refID doesn't point to an existing object"));
     }
     String dbLocation = addLocationPrefix((isVirtual ? LOC_VIRT_PREFIX : LOC_DIR_PREFIX), path);
-    
+
+    Ref<Dictionary> metadata = NULL;
+    if (itemMetadata != nullptr) {
+        if (upnpClass == UPNP_DEFAULT_CLASS_MUSIC_ALBUM) {
+            Ref<Dictionary> metadata(new Dictionary());
+            metadata->put("artist", itemMetadata->get("artist"));
+            metadata->put("date", itemMetadata->get("date"));
+        }
+    }
+
     int newID = getNextID();
-    
+
     Ref<StringBuffer> qb(new StringBuffer());
-    *qb << "INSERT INTO " 
+    *qb << "INSERT INTO "
         << TQ(CDS_OBJECT_TABLE)
         << " ("
         << TQ("id") << ','
@@ -1013,23 +927,24 @@ int SQLStorage::createContainer(int parentID, String name, String path, bool isV
         << TQ("dc_title") << ','
         << TQ("location") << ','
         << TQ("location_hash") << ','
+        << TQ("metadata") << ','
         << TQ("ref_id") << ") VALUES ("
         << newID << ','
         << parentID << ','
         << OBJECT_TYPE_CONTAINER << ','
-        << (string_ok(upnpClass) ? quote(upnpClass) : quote(_(UPNP_DEFAULT_CLASS_CONTAINER))) << ',' 
+        << (string_ok(upnpClass) ? quote(upnpClass) : quote(_(UPNP_DEFAULT_CLASS_CONTAINER))) << ','
         << quote(name) << ','
         << quote(dbLocation) << ','
         << quote(stringHash(dbLocation)) << ','
+        << (metadata == nullptr ? _(SQL_NULL) : metadata->encode()) << ','
         << (refID > 0 ? quote(refID) : _(SQL_NULL))
         << ')';
-        
+
     exec(qb);
-    
+
     /* inform cache */
-    if (cacheOn())
-    {
-        AUTOLOCK(cache->getMutex());
+    if (cacheOn()) {
+        AutoLock lock(cache->getMutex());
         cache->addChild(parentID);
         if (cache->flushed())
             flushInsertBuffer();
@@ -1042,11 +957,10 @@ int SQLStorage::createContainer(int parentID, String name, String path, bool isV
         cObj->setLocation(path);
     }
     /* ------------ */
-    
+
     return newID;
-    
+
     //return exec(qb, true);
-    
 }
 
 String SQLStorage::buildContainerPath(int parentID, String title)
@@ -1054,54 +968,58 @@ String SQLStorage::buildContainerPath(int parentID, String title)
     //title = escape(title, xxx);
     if (parentID == CDS_ID_ROOT)
         return String(VIRTUAL_CONTAINER_SEPARATOR) + title;
+
     Ref<StringBuffer> qb(new StringBuffer());
-    *qb << "SELECT " << TQ("location") << " FROM " << TQ(CDS_OBJECT_TABLE) <<
-        " WHERE " << TQ("id") << '=' << parentID << " LIMIT 1";
-     Ref<SQLResult> res = select(qb);
-    if (res == nil)
-        return nil;
+    *qb << "SELECT " << TQ("location") << " FROM " << TQ(CDS_OBJECT_TABLE) << " WHERE " << TQ("id") << '=' << parentID << " LIMIT 1";
+
+    Ref<SQLResult> res = select(qb);
+    if (res == nullptr)
+        return nullptr;
+
     Ref<SQLRow> row = res->nextRow();
-    if (row == nil)
-        return nil;
+    if (row == nullptr)
+        return nullptr;
+
     char prefix;
     String path = stripLocationPrefix(&prefix, row->col(0)) + VIRTUAL_CONTAINER_SEPARATOR + title;
     if (prefix != LOC_VIRT_PREFIX)
         throw _Exception(_("tried to build a virtual container path with an non-virtual parentID"));
+
     return path;
 }
 
-void SQLStorage::addContainerChain(String path, String lastClass, int lastRefID, int *containerID, int *updateID)
+void SQLStorage::addContainerChain(String path, String lastClass, int lastRefID, int* containerID, int* updateID, Ref<Dictionary> lastMetadata)
 {
     path = path.reduce(VIRTUAL_CONTAINER_SEPARATOR);
-    if (path == VIRTUAL_CONTAINER_SEPARATOR)
-    {
+    if (path == VIRTUAL_CONTAINER_SEPARATOR) {
         *containerID = CDS_ID_ROOT;
         return;
     }
     Ref<StringBuffer> qb(new StringBuffer());
     String dbLocation = addLocationPrefix(LOC_VIRT_PREFIX, path);
     *qb << "SELECT " << TQ("id") << " FROM " << TQ(CDS_OBJECT_TABLE)
-            << " WHERE " << TQ("location_hash") << '=' << quote(stringHash(dbLocation))
-            << " AND " << TQ("location") << '=' << quote(dbLocation)
-            << " LIMIT 1";
+        << " WHERE " << TQ("location_hash") << '=' << quote(stringHash(dbLocation))
+        << " AND " << TQ("location") << '=' << quote(dbLocation)
+        << " LIMIT 1";
+
     Ref<SQLResult> res = select(qb);
-    if (res != nil)
-    {
+    if (res != nullptr) {
         Ref<SQLRow> row = res->nextRow();
-        if (row != nil)
-        {
-            if (containerID != NULL)
+        if (row != nullptr) {
+            if (containerID != nullptr)
                 *containerID = row->col(0).toInt();
             return;
         }
     }
+
     int parentContainerID;
     String newpath, container;
     stripAndUnescapeVirtualContainerFromPath(path, newpath, container);
-    addContainerChain(newpath, nil, INVALID_OBJECT_ID, &parentContainerID, updateID);
-    if (updateID != NULL && *updateID == INVALID_OBJECT_ID)
+
+    addContainerChain(newpath, nullptr, INVALID_OBJECT_ID, &parentContainerID, updateID, nullptr);
+    if (updateID != nullptr && *updateID == INVALID_OBJECT_ID)
         *updateID = parentContainerID;
-    *containerID = createContainer(parentContainerID, container, path, true, lastClass, lastRefID);
+    *containerID = createContainer(parentContainerID, container, path, true, lastClass, lastRefID, lastMetadata);
 }
 
 String SQLStorage::addLocationPrefix(char prefix, String path)
@@ -1111,10 +1029,9 @@ String SQLStorage::addLocationPrefix(char prefix, String path)
 
 String SQLStorage::stripLocationPrefix(char* prefix, String path)
 {
-    if (path == nil)
-    {
+    if (path == nullptr) {
         *prefix = LOC_ILLEGAL_PREFIX;
-        return nil;
+        return nullptr;
     }
     *prefix = path.charAt(0);
     return path.substring(1);
@@ -1122,8 +1039,8 @@ String SQLStorage::stripLocationPrefix(char* prefix, String path)
 
 String SQLStorage::stripLocationPrefix(String path)
 {
-    if (path == nil)
-        return nil;
+    if (path == nullptr)
+        return nullptr;
     return path.substring(1);
 }
 
@@ -1135,121 +1052,108 @@ Ref<CdsObject> SQLStorage::createObjectFromRow(Ref<SQLRow> row)
     /* set common properties */
     obj->setID(row->col(_id).toInt());
     obj->setRefID(row->col(_ref_id).toInt());
-    
+
     obj->setParentID(row->col(_parent_id).toInt());
     obj->setTitle(row->col(_dc_title));
     obj->setClass(fallbackString(row->col(_upnp_class), row->col(_ref_upnp_class)));
     obj->setFlags(row->col(_flags).toUInt());
-    
+
     String metadataStr = fallbackString(row->col(_metadata), row->col(_ref_metadata));
     Ref<Dictionary> meta(new Dictionary());
     meta->decode(metadataStr);
     obj->setMetadata(meta);
-    
+
     String auxdataStr = fallbackString(row->col(_auxdata), row->col(_ref_auxdata));
     Ref<Dictionary> aux(new Dictionary());
     aux->decode(auxdataStr);
     obj->setAuxData(aux);
-    
+
     String resources_str = fallbackString(row->col(_resources), row->col(_ref_resources));
     bool resource_zero_ok = false;
-    if (string_ok(resources_str))
-    {
-        Ref<Array<StringBase> > resources = split_string(resources_str,
-                                                    RESOURCE_SEP);
-        for (int i = 0; i < resources->size(); i++)
-        {
+    if (string_ok(resources_str)) {
+        Ref<Array<StringBase>> resources = split_string(resources_str,
+            RESOURCE_SEP);
+        for (int i = 0; i < resources->size(); i++) {
             if (i == 0)
                 resource_zero_ok = true;
             obj->addResource(CdsResource::decode(resources->get(i)));
         }
     }
-    
-    if ( (obj->getRefID() && IS_CDS_PURE_ITEM(objectType)) ||
-        (IS_CDS_ITEM(objectType) && ! IS_CDS_PURE_ITEM(objectType)) )
+
+    if ((obj->getRefID() && IS_CDS_PURE_ITEM(objectType)) || (IS_CDS_ITEM(objectType) && !IS_CDS_PURE_ITEM(objectType)))
         obj->setVirtual(true);
     else
         obj->setVirtual(false); // gets set to true for virtual containers below
-    
+
     int matched_types = 0;
-    
-    if (IS_CDS_CONTAINER(objectType))
-    {
+
+    if (IS_CDS_CONTAINER(objectType)) {
         Ref<CdsContainer> cont = RefCast(obj, CdsContainer);
         cont->setUpdateID(row->col(_update_id).toInt());
         char locationPrefix;
         cont->setLocation(stripLocationPrefix(&locationPrefix, row->col(_location)));
         if (locationPrefix == LOC_VIRT_PREFIX)
             cont->setVirtual(true);
-        
+
         String autoscanPersistent = row->col(_as_persistent);
-        if (string_ok(autoscanPersistent))
-        {
+        if (string_ok(autoscanPersistent)) {
             if (remapBool(autoscanPersistent))
                 cont->setAutoscanType(OBJECT_AUTOSCAN_CFG);
             else
                 cont->setAutoscanType(OBJECT_AUTOSCAN_UI);
-        }
-        else
+        } else
             cont->setAutoscanType(OBJECT_AUTOSCAN_NONE);
         matched_types++;
     }
-    
-    if (IS_CDS_ITEM(objectType))
-    {
-        if (! resource_zero_ok)
+
+    if (IS_CDS_ITEM(objectType)) {
+        if (!resource_zero_ok)
             throw _Exception(_("tried to create object without at least one resource"));
-        
+
         Ref<CdsItem> item = RefCast(obj, CdsItem);
         item->setMimeType(fallbackString(row->col(_mime_type), row->col(_ref_mime_type)));
-        if (IS_CDS_PURE_ITEM(objectType))
-        {
-            if (! obj->isVirtual())
-            item->setLocation(stripLocationPrefix(row->col(_location)));
-                else
-            item->setLocation(stripLocationPrefix(row->col(_ref_location)));
-        }
-        else // URLs and active items
+        if (IS_CDS_PURE_ITEM(objectType)) {
+            if (!obj->isVirtual())
+                item->setLocation(stripLocationPrefix(row->col(_location)));
+            else
+                item->setLocation(stripLocationPrefix(row->col(_ref_location)));
+        } else // URLs and active items
         {
             item->setLocation(fallbackString(row->col(_location), row->col(_ref_location)));
         }
-        
+
         item->setTrackNumber(row->col(_track_number).toInt());
-        
+
         if (string_ok(row->col(_ref_service_id)))
             item->setServiceID(row->col(_ref_service_id));
         else
             item->setServiceID(row->col(_service_id));
-        
+
         matched_types++;
     }
-    
-    if (IS_CDS_ACTIVE_ITEM(objectType))
-    {
+
+    if (IS_CDS_ACTIVE_ITEM(objectType)) {
         Ref<CdsActiveItem> aitem = RefCast(obj, CdsActiveItem);
-        
+
         Ref<StringBuffer> query(new StringBuffer());
         *query << "SELECT " << TQ("id") << ',' << TQ("action") << ','
-            << TQ("state") << " FROM " << TQ(CDS_ACTIVE_ITEM_TABLE)
-            << " WHERE " << TQ("id") << '=' << quote(aitem->getID());
+               << TQ("state") << " FROM " << TQ(CDS_ACTIVE_ITEM_TABLE)
+               << " WHERE " << TQ("id") << '=' << quote(aitem->getID());
         Ref<SQLResult> resAI = select(query);
         Ref<SQLRow> rowAI;
-        if (resAI != nil && (rowAI = resAI->nextRow()) != nil)
-        {
+        if (resAI != nullptr && (rowAI = resAI->nextRow()) != nullptr) {
             aitem->setAction(rowAI->col(1));
             aitem->setState(rowAI->col(2));
-        }
-        else
+        } else
             throw _Exception(_("Active Item in cds_objects, but not in cds_active_item"));
-        
+
         matched_types++;
     }
 
-    if(! matched_types)
-    {
-        throw _StorageException(nil, _("unknown object type: ")+ objectType);
+    if (!matched_types) {
+        throw _StorageException(nullptr, _("unknown object type: ") + objectType);
     }
-    
+
     addObjectToCache(obj);
     return obj;
 }
@@ -1257,50 +1161,97 @@ Ref<CdsObject> SQLStorage::createObjectFromRow(Ref<SQLRow> row)
 int SQLStorage::getTotalFiles()
 {
     flushInsertBuffer();
-    
+
     Ref<StringBuffer> query(new StringBuffer());
     *query << "SELECT COUNT(*) FROM " << TQ(CDS_OBJECT_TABLE) << " WHERE "
            << TQ("object_type") << " != " << quote(OBJECT_TYPE_CONTAINER);
-           //<< " AND is_virtual = 0";
+    //<< " AND is_virtual = 0";
     Ref<SQLResult> res = select(query);
     Ref<SQLRow> row;
-    if (res != nil && (row = res->nextRow()) != nil)
-    {
+    if (res != nullptr && (row = res->nextRow()) != nullptr) {
         return row->col(0).toInt();
     }
     return 0;
 }
 
-String SQLStorage::incrementUpdateIDs(int *ids, int size)
+String SQLStorage::incrementUpdateIDs(shared_ptr<unordered_set<int>> ids)
 {
-    if (size <= 0)
-        return nil;
+    if (ids->empty())
+        return nullptr;
     Ref<StringBuffer> inBuf(new StringBuffer()); // ??? what was that: size * sizeof(int)));
-    *inBuf << "IN (" << ids[0];
-    for (int i = 1; i < size; i++)
-        *inBuf << ',' << ids[i];
+
+    bool first = true;
+    for (const auto& id : *ids) {
+        if (first) {
+            *inBuf << "IN (" << id;
+            first = false;
+        } else {
+            *inBuf << ',' << id;
+        }
+    }
     *inBuf << ')';
-    
+
     Ref<StringBuffer> buf(new StringBuffer());
     *buf << "UPDATE " << TQ(CDS_OBJECT_TABLE) << " SET " << TQ("update_id") << '=' << TQ("update_id") << " + 1 WHERE " << TQ("id") << ' ';
     *buf << inBuf;
     exec(buf);
-    
+
     buf->clear();
     *buf << "SELECT " << TQ("id") << ',' << TQ("update_id") << " FROM " << TQ(CDS_OBJECT_TABLE) << " WHERE " << TQ("id") << ' ';
     *buf << inBuf;
     Ref<SQLResult> res = select(buf);
-    if (res == nil)
+    if (res == nullptr)
         throw _Exception(_("Error while fetching update ids"));
     Ref<SQLRow> row;
     buf->clear();
-    while((row = res->nextRow()) != nil)
+    while ((row = res->nextRow()) != nullptr)
         *buf << ',' << row->col(0) << ',' << row->col(1);
     if (buf->length() <= 0)
-        return nil;
+        return nullptr;
     return buf->toString(1);
 }
 
+// id is the parent_id for cover media to find, and if set, trackArtBase is the case-folded
+// name of the track to try as artwork
+String SQLStorage::findFolderImage(int id, String trackArtBase)
+{
+    Ref<StringBuffer> q(new StringBuffer());
+    // folder.jpg or cover.jpg [and variants]
+    // note - "_" is regexp "." and "%" is regexp ".*" in sql LIKE land
+    *q << "SELECT " << TQ("id") << " FROM " << TQ(CDS_OBJECT_TABLE) << " WHERE ";
+    *q << "( ";
+    if (trackArtBase.length() > 0) {
+        *q << "lower(" << TQ("dc_title") << ") "
+           << "LIKE " << quote(trackArtBase + _(".jp%")) << " OR ";
+    }
+    *q << "lower(" << TQ("dc_title") << ") "
+       << "LIKE " << quote(_("cover.jp%")) << " OR ";
+    *q << "lower(" << TQ("dc_title") << ") "
+       << "LIKE " << quote(_("albumart%.jp%")) << " OR ";
+    *q << "lower(" << TQ("dc_title") << ") "
+       << "LIKE " << quote(_("album.jp%")) << " OR ";
+    *q << "lower(" << TQ("dc_title") << ") "
+       << "LIKE " << quote(_("front.jp%")) << " OR ";
+    *q << "lower(" << TQ("dc_title") << ") "
+       << "LIKE " << quote(_("folder.jp%"));
+    *q << " ) AND ";
+    *q << TQ("upnp_class") << '=' << quote(_(UPNP_DEFAULT_CLASS_IMAGE_ITEM)) << " AND ";
+    *q << TQ("parent_id") << '=' << quote(String::from(id));
+    *q << " ORDER BY " << TQ("dc_title") << " DESC";
+
+    //log_debug("findFolderImage %d, %s\n", id, q->c_str());
+    Ref<SQLResult> res = select(q);
+    if (res == nullptr)
+        throw _Exception(_("db error"));
+    Ref<SQLRow> row;
+    if ((row = res->nextRow()) != nullptr) // we only care about the first result
+    {
+        log_debug("findFolderImage result: %s\n", row->col(0).c_str());
+        return row->col(0);
+    }
+    return nullptr;
+}
+
 /*
 Ref<Array<CdsObject> > SQLStorage::selectObjects(Ref<SelectParam> param)
 {
@@ -1331,7 +1282,7 @@ Ref<Array<CdsObject> > SQLStorage::selectObjects(Ref<SelectParam> param)
     Ref<SQLRow> row;
     Ref<Array<CdsObject> > arr(new Array<CdsObject>());
 
-    while((row = res->nextRow()) != nil)
+    while((row = res->nextRow()) != nullptr)
     {
         Ref<CdsObject> obj = createObjectFromRow(row);
         arr->append(obj);
@@ -1340,10 +1291,10 @@ Ref<Array<CdsObject> > SQLStorage::selectObjects(Ref<SelectParam> param)
 }
 */
 
-Ref<DBRHash<int> > SQLStorage::getObjects(int parentID, bool withoutContainer)
+shared_ptr<unordered_set<int>> SQLStorage::getObjects(int parentID, bool withoutContainer)
 {
     flushInsertBuffer();
-    
+
     Ref<StringBuffer> q(new StringBuffer());
     *q << "SELECT " << TQ("id") << " FROM " << TQ(CDS_OBJECT_TABLE) << " WHERE ";
     if (withoutContainer)
@@ -1351,44 +1302,40 @@ Ref<DBRHash<int> > SQLStorage::getObjects(int parentID, bool withoutContainer)
     *q << TQ("parent_id") << '=';
     *q << parentID;
     Ref<SQLResult> res = select(q);
-    if (res == nil)
+    if (res == nullptr)
         throw _Exception(_("db error"));
     Ref<SQLRow> row;
-    
+
     if (res->getNumRows() <= 0)
-        return nil;
-    int capacity = res->getNumRows() * 5 + 1;
+        return nullptr;
+
+    unsigned long long capacity = res->getNumRows() * 5 + 1;
     if (capacity < 521)
         capacity = 521;
-    
-    Ref<DBRHash<int> > ret(new DBRHash<int>(capacity, res->getNumRows(), INVALID_OBJECT_ID, INVALID_OBJECT_ID_2));
-    
-    while ((row = res->nextRow()) != nil)
-    {
-        ret->put(row->col(0).toInt());
+
+    shared_ptr<unordered_set<int>> ret = make_shared<unordered_set<int>>();
+
+    while ((row = res->nextRow()) != nullptr) {
+        ret->insert(row->col(0).toInt());
     }
     return ret;
 }
 
-Ref<Storage::ChangedContainers> SQLStorage::removeObjects(zmm::Ref<DBRHash<int> > list, bool all)
+Ref<Storage::ChangedContainers> SQLStorage::removeObjects(shared_ptr<unordered_set<int>> list, bool all)
 {
     flushInsertBuffer();
-    
-    hash_data_array_t<int> hash_data_array;
-    list->getAll(&hash_data_array);
-    int count = hash_data_array.size;
-    int *array = hash_data_array.data;
+
+    int count = list->size();
     if (count <= 0)
-        return nil;
-    
+        return nullptr;
+
     Ref<StringBuffer> idsBuf(new StringBuffer());
     *idsBuf << "SELECT " << TQ("id") << ',' << TQ("object_type")
-        << " FROM " << TQ(CDS_OBJECT_TABLE)
-        << " WHERE " << TQ("id") << " IN (";
+            << " FROM " << TQ(CDS_OBJECT_TABLE)
+            << " WHERE " << TQ("id") << " IN (";
     int firstComma = idsBuf->length();
-    for (int i = 0; i < count; i++)
-    {
-        int id = array[i];
+
+    for (const auto& id : *list) {
         if (IS_FORBIDDEN_CDS_ID(id))
             throw _Exception(_("tried to delete a forbidden ID (") + id + ")!");
         *idsBuf << ',' << id;
@@ -1396,15 +1343,14 @@ Ref<Storage::ChangedContainers> SQLStorage::removeObjects(zmm::Ref<DBRHash<int>
     idsBuf->setCharAt(firstComma, ' ');
     *idsBuf << ')';
     Ref<SQLResult> res = select(idsBuf);
-    idsBuf = nil;
-    if (res == nil)
+    idsBuf = nullptr;
+    if (res == nullptr)
         throw _Exception(_("sql error"));
-    
+
     Ref<StringBuffer> items(new StringBuffer());
     Ref<StringBuffer> containers(new StringBuffer());
     Ref<SQLRow> row;
-    while ((row = res->nextRow()) != nil)
-    {
+    while ((row = res->nextRow()) != nullptr) {
         int objectType = row->col(1).toInt();
         if (IS_CDS_CONTAINER(objectType))
             *containers << ',' << row->col_c_str(0);
@@ -1417,61 +1363,58 @@ Ref<Storage::ChangedContainers> SQLStorage::removeObjects(zmm::Ref<DBRHash<int>
 void SQLStorage::_removeObjects(Ref<StringBuffer> objectIDs, int offset)
 {
     Ref<StringBuffer> q(new StringBuffer());
-    *q << "SELECT " << TQD('a',"id") << ',' << TQD('a',"persistent")
-        << ',' << TQD('o',"location")
-        << " FROM " << TQ(AUTOSCAN_TABLE) << " a"
-        " JOIN "  << TQ(CDS_OBJECT_TABLE) << " o"
-        " ON " << TQD('o',"id") << '=' << TQD('a',"obj_id")
-        << " WHERE " << TQD('o',"id") << " IN (";
+    *q << "SELECT " << TQD('a', "id") << ',' << TQD('a', "persistent")
+       << ',' << TQD('o', "location")
+       << " FROM " << TQ(AUTOSCAN_TABLE) << " a"
+                                            " JOIN "
+       << TQ(CDS_OBJECT_TABLE) << " o"
+                                  " ON "
+       << TQD('o', "id") << '=' << TQD('a', "obj_id")
+       << " WHERE " << TQD('o', "id") << " IN (";
     q->concat(objectIDs, offset);
     *q << ')';
-    
+
     log_debug("%s\n", q->c_str());
-    
+
     Ref<SQLResult> res = select(q);
-    if (res != nil)
-    {
+    if (res != nullptr) {
         log_debug("relevant autoscans!\n");
         Ref<StringBuffer> delete_as(new StringBuffer());
         Ref<SQLRow> row;
-        while((row = res->nextRow()) != nil)
-        {
+        while ((row = res->nextRow()) != nullptr) {
             bool persistent = remapBool(row->col(1));
-            if (persistent)
-            {
+            if (persistent) {
                 String location = stripLocationPrefix(row->col(2));
                 *q << "UPDATE " << TQ(AUTOSCAN_TABLE)
-                    << " SET " << TQ("obj_id") << "=" SQL_NULL
-                    << ',' << TQ("location") << '=' << quote(location)
-                    << " WHERE " << TQ("id") << '=' << quote(row->col(0));
-            }
-            else
+                   << " SET " << TQ("obj_id") << "=" SQL_NULL
+                   << ',' << TQ("location") << '=' << quote(location)
+                   << " WHERE " << TQ("id") << '=' << quote(row->col(0));
+            } else
                 *delete_as << ',' << row->col_c_str(0);
             log_debug("relevant autoscan: %d; persistent: %d\n", row->col_c_str(0), persistent);
         }
-        
-        if (delete_as->length() > 0)
-        {
+
+        if (delete_as->length() > 0) {
             q->clear();
             *q << "DELETE FROM " << TQ(AUTOSCAN_TABLE)
-                << " WHERE " << TQ("id") << " IN (";
+               << " WHERE " << TQ("id") << " IN (";
             q->concat(delete_as, 1);
             *q << ')';
             exec(q);
             log_debug("deleting autoscans: %s\n", delete_as->c_str());
         }
     }
-    
+
     q->clear();
     *q << "DELETE FROM " << TQ(CDS_ACTIVE_ITEM_TABLE)
-        << " WHERE " << TQ("id") << " IN (";
+       << " WHERE " << TQ("id") << " IN (";
     q->concat(objectIDs, offset);
     *q << ')';
     exec(q);
-    
+
     q->clear();
     *q << "DELETE FROM " << TQ(CDS_OBJECT_TABLE)
-        << " WHERE " << TQ("id") << " IN (";
+       << " WHERE " << TQ("id") << " IN (";
     q->concat(objectIDs, offset);
     *q << ')';
     exec(q);
@@ -1480,28 +1423,26 @@ void SQLStorage::_removeObjects(Ref<StringBuffer> objectIDs, int offset)
 Ref<Storage::ChangedContainers> SQLStorage::removeObject(int objectID, bool all)
 {
     flushInsertBuffer();
-    
+
     Ref<StringBuffer> q(new StringBuffer());
     *q << "SELECT " << TQ("object_type") << ',' << TQ("ref_id")
-        << " FROM " << TQ(CDS_OBJECT_TABLE)
-        << " WHERE " << TQ("id") << '=' << quote(objectID) << " LIMIT 1";
+       << " FROM " << TQ(CDS_OBJECT_TABLE)
+       << " WHERE " << TQ("id") << '=' << quote(objectID) << " LIMIT 1";
     Ref<SQLResult> res = select(q);
-    if (res == nil)
-        return nil;
+    if (res == nullptr)
+        return nullptr;
     Ref<SQLRow> row = res->nextRow();
-    if (row == nil)
-        return nil;
-    
+    if (row == nullptr)
+        return nullptr;
+
     int objectType = row->col(0).toInt();
     bool isContainer = IS_CDS_CONTAINER(objectType);
-    if (all && ! isContainer)
-    {
+    if (all && !isContainer) {
         String ref_id_str = row->col(1);
         int ref_id;
-        if (string_ok(ref_id_str))
-        {
+        if (string_ok(ref_id_str)) {
             ref_id = ref_id_str.toInt();
-            if (! IS_FORBIDDEN_CDS_ID(ref_id))
+            if (!IS_FORBIDDEN_CDS_ID(ref_id))
                 objectID = ref_id;
         }
     }
@@ -1509,11 +1450,11 @@ Ref<Storage::ChangedContainers> SQLStorage::removeObject(int objectID, bool all)
         throw _Exception(_("tried to delete a forbidden ID (") + objectID + ")!");
     Ref<StringBuffer> idsBuf(new StringBuffer());
     *idsBuf << ',' << objectID;
-    Ref<ChangedContainersStr> changedContainers = nil;
+    Ref<ChangedContainersStr> changedContainers = nullptr;
     if (isContainer)
-        changedContainers = _recursiveRemove(nil, idsBuf, all);
+        changedContainers = _recursiveRemove(nullptr, idsBuf, all);
     else
-        changedContainers = _recursiveRemove(idsBuf, nil, all);
+        changedContainers = _recursiveRemove(idsBuf, nullptr, all);
     return _purgeEmptyContainers(changedContainers);
 }
 
@@ -1522,127 +1463,108 @@ Ref<SQLStorage::ChangedContainersStr> SQLStorage::_recursiveRemove(Ref<StringBuf
     log_debug("start\n");
     Ref<StringBuffer> recurseItems(new StringBuffer());
     *recurseItems << "SELECT DISTINCT " << TQ("id") << ',' << TQ("parent_id")
-        << " FROM " << TQ(CDS_OBJECT_TABLE) <<
-            " WHERE " << TQ("ref_id") << " IN (";
+                  << " FROM " << TQ(CDS_OBJECT_TABLE) << " WHERE " << TQ("ref_id") << " IN (";
     int recurseItemsLen = recurseItems->length();
-    
+
     Ref<StringBuffer> recurseContainers(new StringBuffer());
-    *recurseContainers << "SELECT DISTINCT " << TQ("id") 
-        << ',' << TQ("object_type");
+    *recurseContainers << "SELECT DISTINCT " << TQ("id")
+                       << ',' << TQ("object_type");
     if (all)
         *recurseContainers << ',' << TQ("ref_id");
-    *recurseContainers << " FROM " << TQ(CDS_OBJECT_TABLE) <<
-            " WHERE " << TQ("parent_id") << " IN (";
+    *recurseContainers << " FROM " << TQ(CDS_OBJECT_TABLE) << " WHERE " << TQ("parent_id") << " IN (";
     int recurseContainersLen = recurseContainers->length();
-    
+
     Ref<StringBuffer> removeAddParents(new StringBuffer());
     *removeAddParents << "SELECT DISTINCT " << TQ("parent_id")
-        << " FROM " << TQ(CDS_OBJECT_TABLE)
-        << " WHERE " << TQ("id") << " IN (";
+                      << " FROM " << TQ(CDS_OBJECT_TABLE)
+                      << " WHERE " << TQ("id") << " IN (";
     int removeAddParentsLen = removeAddParents->length();
-    
+
     Ref<StringBuffer> remove(new StringBuffer());
     Ref<ChangedContainersStr> changedContainers(new ChangedContainersStr());
-    
+
     Ref<SQLResult> res;
     Ref<SQLRow> row;
-    
-    if (items != nil && items->length() > 1)
-    {
+
+    if (items != nullptr && items->length() > 1) {
         *recurseItems << items;
         *removeAddParents << items;
     }
-    
-    if (containers != nil && containers->length() > 1)
-    {
+
+    if (containers != nullptr && containers->length() > 1) {
         *recurseContainers << containers;
-        
+
         *remove << containers;
         *removeAddParents << containers;
         removeAddParents->setCharAt(removeAddParentsLen, ' ');
         *removeAddParents << ')';
         res = select(removeAddParents);
-        if (res == nil)
-            throw _StorageException(nil, _("sql error"));
+        if (res == nullptr)
+            throw _StorageException(nullptr, _("sql error"));
         removeAddParents->setLength(removeAddParentsLen);
-        while ((row = res->nextRow()) != nil)
+        while ((row = res->nextRow()) != nullptr)
             *changedContainers->ui << ',' << row->col_c_str(0);
     }
-    
+
     int count = 0;
-    while(recurseItems->length() > recurseItemsLen 
+    while (recurseItems->length() > recurseItemsLen
         || removeAddParents->length() > removeAddParentsLen
-        || recurseContainers->length() > recurseContainersLen)
-    {
-        if (removeAddParents->length() > removeAddParentsLen)
-        {
+        || recurseContainers->length() > recurseContainersLen) {
+        if (removeAddParents->length() > removeAddParentsLen) {
             // add ids to remove
             *remove << removeAddParents->c_str(removeAddParentsLen);
             // get rid of first ','
             removeAddParents->setCharAt(removeAddParentsLen, ' ');
             *removeAddParents << ')';
             res = select(removeAddParents);
-            if (res == nil)
-                throw _StorageException(nil, _("sql error"));
+            if (res == nullptr)
+                throw _StorageException(nullptr, _("sql error"));
             // reset length
             removeAddParents->setLength(removeAddParentsLen);
-            while ((row = res->nextRow()) != nil)
+            while ((row = res->nextRow()) != nullptr)
                 *changedContainers->upnp << ',' << row->col_c_str(0);
         }
-        
-        if (recurseItems->length() > recurseItemsLen)
-        {
+
+        if (recurseItems->length() > recurseItemsLen) {
             recurseItems->setCharAt(recurseItemsLen, ' ');
             *recurseItems << ')';
             res = select(recurseItems);
-            if (res == nil)
-                throw _StorageException(nil, _("sql error"));
+            if (res == nullptr)
+                throw _StorageException(nullptr, _("sql error"));
             recurseItems->setLength(recurseItemsLen);
-            while ((row = res->nextRow()) != nil)
-            {
+            while ((row = res->nextRow()) != nullptr) {
                 *remove << ',' << row->col_c_str(0);
                 *changedContainers->upnp << ',' << row->col_c_str(1);
                 //log_debug("refs-add id: %s; parent_id: %s\n", id.c_str(), parentId.c_str());
             }
         }
-        
-        if (recurseContainers->length() > recurseContainersLen)
-        {
+
+        if (recurseContainers->length() > recurseContainersLen) {
             recurseContainers->setCharAt(recurseContainersLen, ' ');
             *recurseContainers << ')';
             res = select(recurseContainers);
-            if (res == nil)
-                throw _StorageException(nil, _("sql error"));
+            if (res == nullptr)
+                throw _StorageException(nullptr, _("sql error"));
             recurseContainers->setLength(recurseContainersLen);
-            while ((row = res->nextRow()) != nil)
-            {
+            while ((row = res->nextRow()) != nullptr) {
                 //containers->append(row->col(1).toInt());
-                
+
                 int objectType = row->col(1).toInt();
-                if (IS_CDS_CONTAINER(objectType))
-                {
+                if (IS_CDS_CONTAINER(objectType)) {
                     *recurseContainers << ',' << row->col_c_str(0);
                     *remove << ',' << row->col_c_str(0);
-                }
-                else
-                {
-                    if (all)
-                    {
+                } else {
+                    if (all) {
                         String refId = row->col(2);
-                        if (string_ok(refId))
-                        {
+                        if (string_ok(refId)) {
                             *removeAddParents << ',' << refId;
                             *recurseItems << ',' << refId;
                             //*remove << ',' << refId;
-                        }
-                        else
-                        {
+                        } else {
                             *remove << ',' << row->col_c_str(0);
                             *recurseItems << ',' << row->col_c_str(0);
                         }
-                    }
-                    else
-                    {
+                    } else {
                         *remove << ',' << row->col_c_str(0);
                         *recurseItems << ',' << row->col_c_str(0);
                     }
@@ -1650,17 +1572,17 @@ Ref<SQLStorage::ChangedContainersStr> SQLStorage::_recursiveRemove(Ref<StringBuf
                 //log_debug("id: %s; parent_id: %s\n", id.c_str(), parentId.c_str());
             }
         }
-        
+
         if (remove->length() > MAX_REMOVE_SIZE) // remove->length() > 0) // )
         {
             _removeObjects(remove, 1);
             remove->clear();
         }
-        
+
         if (count++ > MAX_REMOVE_RECURSION)
             throw _Exception(_("there seems to be an infinite loop..."));
     }
-    
+
     if (remove->length() > 0)
         _removeObjects(remove, 1);
     log_debug("end\n");
@@ -1671,96 +1593,82 @@ Ref<Storage::ChangedContainers> SQLStorage::_purgeEmptyContainers(Ref<ChangedCon
 {
     log_debug("start upnp: %s; ui: %s\n", changedContainersStr->upnp->c_str(), changedContainersStr->ui->c_str());
     Ref<ChangedContainers> changedContainers(new ChangedContainers());
-    if (! string_ok(changedContainersStr->upnp) && ! string_ok(changedContainersStr->ui))
+    if (!string_ok(changedContainersStr->upnp) && !string_ok(changedContainersStr->ui))
         return changedContainers;
-    
+
     Ref<StringBuffer> bufSelUI(new StringBuffer());
-    *bufSelUI << "SELECT " << TQD('a',"id")
-        << ", COUNT(" << TQD('b',"parent_id") 
-        << ")," << TQD('a',"parent_id") << ',' << TQD('a',"flags")
-        << " FROM " << TQ(CDS_OBJECT_TABLE) << ' ' << TQ('a')
-        << " LEFT JOIN " << TQ(CDS_OBJECT_TABLE) << ' ' << TQ('b')
-        << " ON " << TQD('a',"id") << '=' << TQD('b',"parent_id") 
-        << " WHERE " << TQD('a',"object_type") << '=' << quote(1)
-        << " AND " << TQD('a',"id") << " IN (";  //(a.flags & " << OBJECT_FLAG_PERSISTENT_CONTAINER << ") = 0 AND
+    *bufSelUI << "SELECT " << TQD('a', "id")
+              << ", COUNT(" << TQD('b', "parent_id")
+              << ")," << TQD('a', "parent_id") << ',' << TQD('a', "flags")
+              << " FROM " << TQ(CDS_OBJECT_TABLE) << ' ' << TQ('a')
+              << " LEFT JOIN " << TQ(CDS_OBJECT_TABLE) << ' ' << TQ('b')
+              << " ON " << TQD('a', "id") << '=' << TQD('b', "parent_id")
+              << " WHERE " << TQD('a', "object_type") << '=' << quote(1)
+              << " AND " << TQD('a', "id") << " IN ("; //(a.flags & " << OBJECT_FLAG_PERSISTENT_CONTAINER << ") = 0 AND
     int bufSelLen = bufSelUI->length();
     String strSel2 = _(") GROUP BY a.id"); // HAVING COUNT(b.parent_id)=0");
-    
+
     Ref<StringBuffer> bufSelUpnp(new StringBuffer());
     *bufSelUpnp << bufSelUI;
-    
+
     Ref<StringBuffer> bufDel(new StringBuffer());
-    
+
     Ref<SQLResult> res;
     Ref<SQLRow> row;
-    
+
     *bufSelUI << changedContainersStr->ui;
     *bufSelUpnp << changedContainersStr->upnp;
-    
+
     bool again;
     int count = 0;
-    do
-    {
+    do {
         again = false;
-        
-        if (bufSelUpnp->length() > bufSelLen)
-        {
+
+        if (bufSelUpnp->length() > bufSelLen) {
             bufSelUpnp->setCharAt(bufSelLen, ' ');
             *bufSelUpnp << strSel2;
             log_debug("upnp-sql: %s\n", bufSelUpnp->c_str());
             res = select(bufSelUpnp);
             bufSelUpnp->setLength(bufSelLen);
-            if (res == nil)
+            if (res == nullptr)
                 throw _Exception(_("db error"));
-            while ((row = res->nextRow()) != nil)
-            {
+            while ((row = res->nextRow()) != nullptr) {
                 int flags = row->col(3).toInt();
                 if (flags & OBJECT_FLAG_PERSISTENT_CONTAINER)
                     changedContainers->upnp->append(row->col(0).toInt());
-                else if (row->col(1) == "0")
-                {
+                else if (row->col(1) == "0") {
                     *bufDel << ',' << row->col_c_str(0);
                     *bufSelUI << ',' << row->col_c_str(2);
-                }
-                else
-                {
+                } else {
                     *bufSelUpnp << ',' << row->col_c_str(0);
                 }
             }
         }
-        
-        if (bufSelUI->length() > bufSelLen)
-        {
+
+        if (bufSelUI->length() > bufSelLen) {
             bufSelUI->setCharAt(bufSelLen, ' ');
             *bufSelUI << strSel2;
             log_debug("ui-sql: %s\n", bufSelUI->c_str());
             res = select(bufSelUI);
             bufSelUI->setLength(bufSelLen);
-            if (res == nil)
+            if (res == nullptr)
                 throw _Exception(_("db error"));
-            while ((row = res->nextRow()) != nil)
-            {
+            while ((row = res->nextRow()) != nullptr) {
                 int flags = row->col(3).toInt();
-                if (flags & OBJECT_FLAG_PERSISTENT_CONTAINER)
-                {
+                if (flags & OBJECT_FLAG_PERSISTENT_CONTAINER) {
                     changedContainers->ui->append(row->col(0).toInt());
                     changedContainers->upnp->append(row->col(0).toInt());
-                }
-                else if (row->col(1) == "0")
-                {
+                } else if (row->col(1) == "0") {
                     *bufDel << ',' << row->col_c_str(0);
                     *bufSelUI << ',' << row->col_c_str(2);
-                }
-                else
-                {
+                } else {
                     *bufSelUI << ',' << row->col_c_str(0);
                 }
             }
         }
-        
+
         //log_debug("selecting: %s; removing: %s\n", bufSel->c_str(), bufDel->c_str());
-        if (bufDel->length() > 0)
-        {
+        if (bufDel->length() > 0) {
             _removeObjects(bufDel, 1);
             bufDel->clear();
             if (bufSelUI->length() > bufSelLen || bufSelUpnp->length() > bufSelLen)
@@ -1768,26 +1676,23 @@ Ref<Storage::ChangedContainers> SQLStorage::_purgeEmptyContainers(Ref<ChangedCon
         }
         if (count++ >= MAX_REMOVE_RECURSION)
             throw _Exception(_("there seems to be an infinite loop..."));
-    }
-    while (again);
-    
-    if (bufSelUI->length() > bufSelLen)
-    {
+    } while (again);
+
+    if (bufSelUI->length() > bufSelLen) {
         changedContainers->ui->addCSV(bufSelUI->toString(bufSelLen + 1));
         changedContainers->upnp->addCSV(bufSelUI->toString(bufSelLen + 1));
     }
-    if (bufSelUpnp->length() > bufSelLen)
-    {
+    if (bufSelUpnp->length() > bufSelLen) {
         changedContainers->upnp->addCSV(bufSelUpnp->toString(bufSelLen + 1));
     }
     log_debug("end; changedContainers (upnp): %s\n", changedContainers->upnp->toCSV().c_str());
     log_debug("end; changedContainers (ui): %s\n", changedContainers->ui->toCSV().c_str());
-    
+
     /* clear cache (for now) */
     if (cacheOn())
         cache->clear();
     /* --------------------- */
-    
+
     return changedContainers;
 }
 
@@ -1795,13 +1700,13 @@ String SQLStorage::getInternalSetting(String key)
 {
     Ref<StringBuffer> q(new StringBuffer());
     *q << "SELECT " << TQ("value") << " FROM " << TQ(INTERNAL_SETTINGS_TABLE) << " WHERE " << TQ("key") << '='
-        << quote(key) << " LIMIT 1";
+       << quote(key) << " LIMIT 1";
     Ref<SQLResult> res = select(q);
-    if (res == nil)
-        return nil;
+    if (res == nullptr)
+        return nullptr;
     Ref<SQLRow> row = res->nextRow();
-    if (row == nil)
-        return nil;
+    if (row == nullptr)
+        return nullptr;
     return row->col(0);
 }
 /*
@@ -1809,40 +1714,39 @@ void SQLStorage::storeInternalSetting(String key, String value)
 overwritten due to different SQL syntax for MySQL and SQLite3
 */
 
-void SQLStorage::updateAutoscanPersistentList(scan_mode_t scanmode, Ref<AutoscanList> list)
+void SQLStorage::updateAutoscanPersistentList(ScanMode scanmode, Ref<AutoscanList> list)
 {
-    
+
     log_debug("setting persistent autoscans untouched - scanmode: %s;\n", AutoscanDirectory::mapScanmode(scanmode).c_str());
     Ref<StringBuffer> q(new StringBuffer());
     *q << "UPDATE " << TQ(AUTOSCAN_TABLE)
-        << " SET " << TQ("touched") << '=' << mapBool(false)
-        << " WHERE "
-        << TQ("persistent") << '=' << mapBool(true)
-        << " AND " << TQ("scan_mode") << '='
-        << quote(AutoscanDirectory::mapScanmode(scanmode));
+       << " SET " << TQ("touched") << '=' << mapBool(false)
+       << " WHERE "
+       << TQ("persistent") << '=' << mapBool(true)
+       << " AND " << TQ("scan_mode") << '='
+       << quote(AutoscanDirectory::mapScanmode(scanmode));
     exec(q);
-    
+
     int listSize = list->size();
     log_debug("updating/adding persistent autoscans (count: %d)\n", listSize);
-    for (int i = 0; i < listSize; i++)
-    {
+    for (int i = 0; i < listSize; i++) {
         log_debug("getting ad %d from list..\n", i);
         Ref<AutoscanDirectory> ad = list->get(i);
-        if (ad == nil)
+        if (ad == nullptr)
             continue;
-        
+
         // only persistent asD should be given to getAutoscanList
         assert(ad->persistent());
         // the scanmode should match the given parameter
         assert(ad->getScanMode() == scanmode);
-        
+
         String location = ad->getLocation();
-        if (! string_ok(location))
+        if (!string_ok(location))
             throw _Exception(_("AutoscanDirectoy with illegal location given to SQLStorage::updateAutoscanPersistentList"));
-        
+
         q->clear();
         *q << "SELECT " << TQ("id") << " FROM " << TQ(AUTOSCAN_TABLE)
-            << " WHERE ";
+           << " WHERE ";
         int objectID = findObjectIDByPath(location + '/');
         log_debug("objectID = %d\n", objectID);
         if (objectID == INVALID_OBJECT_ID)
@@ -1851,47 +1755,41 @@ void SQLStorage::updateAutoscanPersistentList(scan_mode_t scanmode, Ref<Autoscan
             *q << TQ("obj_id") << '=' << quote(objectID);
         *q << " LIMIT 1";
         Ref<SQLResult> res = select(q);
-        if (res == nil)
-            throw _StorageException(nil, _("query error while selecting from autoscan list"));
+        if (res == nullptr)
+            throw _StorageException(nullptr, _("query error while selecting from autoscan list"));
         Ref<SQLRow> row;
-        if ((row = res->nextRow()) != nil)
-        {
+        if ((row = res->nextRow()) != nullptr) {
             ad->setStorageID(row->col(0).toInt());
             updateAutoscanDirectory(ad);
-        }
-        else
+        } else
             addAutoscanDirectory(ad);
     }
-    
+
     q->clear();
     *q << "DELETE FROM " << TQ(AUTOSCAN_TABLE)
-        << " WHERE " << TQ("touched") << '=' << mapBool(false)
-        << " AND " << TQ("scan_mode") << '='
-        << quote(AutoscanDirectory::mapScanmode(scanmode));
+       << " WHERE " << TQ("touched") << '=' << mapBool(false)
+       << " AND " << TQ("scan_mode") << '='
+       << quote(AutoscanDirectory::mapScanmode(scanmode));
     exec(q);
 }
 
-Ref<AutoscanList> SQLStorage::getAutoscanList(scan_mode_t scanmode)
+Ref<AutoscanList> SQLStorage::getAutoscanList(ScanMode scanmode)
 {
-    #define FLD(field) << TQD('a',field) <<
+#define FLD(field) << TQD('a', field) <<
     Ref<StringBuffer> q(new StringBuffer());
-    *q << "SELECT " FLD("id") ',' FLD("obj_id") ',' FLD("scan_level") ','
-       FLD("scan_mode") ',' FLD("recursive") ',' FLD("hidden") ','
-       FLD("interval") ',' FLD("last_modified") ',' FLD("persistent") ','
-       FLD("location") ',' << TQD('t',"location")
+    *q << "SELECT " FLD("id") ',' FLD("obj_id") ',' FLD("scan_level") ',' FLD("scan_mode") ',' FLD("recursive") ',' FLD("hidden") ',' FLD("interval") ',' FLD("last_modified") ',' FLD("persistent") ',' FLD("location") ',' << TQD('t', "location")
        << " FROM " << TQ(AUTOSCAN_TABLE) << ' ' << TQ('a')
        << " LEFT JOIN " << TQ(CDS_OBJECT_TABLE) << ' ' << TQ('t')
-       << " ON " FLD("obj_id") '=' << TQD('t',"id")
+       << " ON " FLD("obj_id") '=' << TQD('t', "id")
        << " WHERE " FLD("scan_mode") '=' << quote(AutoscanDirectory::mapScanmode(scanmode));
     Ref<SQLResult> res = select(q);
-    if (res == nil)
-        throw _StorageException(nil, _("query error while fetching autoscan list"));
+    if (res == nullptr)
+        throw _StorageException(nullptr, _("query error while fetching autoscan list"));
     Ref<AutoscanList> ret(new AutoscanList());
     Ref<SQLRow> row;
-    while((row = res->nextRow()) != nil)
-    {
+    while ((row = res->nextRow()) != nullptr) {
         Ref<AutoscanDirectory> dir = _fillAutoscanDirectory(row);
-        if (dir == nil)
+        if (dir == nullptr)
             removeAutoscanDirectory(row->col(0).toInt());
         else
             ret->add(dir);
@@ -1901,23 +1799,20 @@ Ref<AutoscanList> SQLStorage::getAutoscanList(scan_mode_t scanmode)
 
 Ref<AutoscanDirectory> SQLStorage::getAutoscanDirectory(int objectID)
 {
-    #define FLD(field) << TQD('a',field) <<
+#define FLD(field) << TQD('a', field) <<
     Ref<StringBuffer> q(new StringBuffer());
-    *q << "SELECT " FLD("id") ',' FLD("obj_id") ',' FLD("scan_level") ','
-       FLD("scan_mode") ',' FLD("recursive") ',' FLD("hidden") ','
-       FLD("interval") ',' FLD("last_modified") ',' FLD("persistent") ','
-       FLD("location") ',' << TQD('t',"location")
+    *q << "SELECT " FLD("id") ',' FLD("obj_id") ',' FLD("scan_level") ',' FLD("scan_mode") ',' FLD("recursive") ',' FLD("hidden") ',' FLD("interval") ',' FLD("last_modified") ',' FLD("persistent") ',' FLD("location") ',' << TQD('t', "location")
        << " FROM " << TQ(AUTOSCAN_TABLE) << ' ' << TQ('a')
        << " LEFT JOIN " << TQ(CDS_OBJECT_TABLE) << ' ' << TQ('t')
-       << " ON " FLD("obj_id") '=' << TQD('t',"id")
-       << " WHERE " << TQD('t',"id") << '=' << quote(objectID);
+       << " ON " FLD("obj_id") '=' << TQD('t', "id")
+       << " WHERE " << TQD('t', "id") << '=' << quote(objectID);
     Ref<SQLResult> res = select(q);
-    if (res == nil)
-        throw _StorageException(nil, _("query error while fetching autoscan"));
+    if (res == nullptr)
+        throw _StorageException(nullptr, _("query error while fetching autoscan"));
     Ref<AutoscanList> ret(new AutoscanList());
     Ref<SQLRow> row = res->nextRow();
-    if (row == nil)
-        return nil;
+    if (row == nullptr)
+        return nullptr;
     else
         return _fillAutoscanDirectory(row);
 }
@@ -1929,30 +1824,29 @@ Ref<AutoscanDirectory> SQLStorage::_fillAutoscanDirectory(Ref<SQLRow> row)
     if (string_ok(objectIDstr))
         objectID = objectIDstr.toInt();
     int storageID = row->col(0).toInt();
-    
+
     String location;
-    if (objectID == INVALID_OBJECT_ID)
+    if (objectID == INVALID_OBJECT_ID) {
         location = row->col(9);
-    else
-    {
+    } else {
         char prefix;
         location = stripLocationPrefix(&prefix, row->col(10));
         if (prefix != LOC_DIR_PREFIX)
-            return nil;
+            return nullptr;
     }
-    
-    scan_level_t level = AutoscanDirectory::remapScanlevel(row->col(2));
-    scan_mode_t mode = AutoscanDirectory::remapScanmode(row->col(3));
+
+    ScanLevel level = AutoscanDirectory::remapScanlevel(row->col(2));
+    ScanMode mode = AutoscanDirectory::remapScanmode(row->col(3));
     bool recursive = remapBool(row->col(4));
     bool hidden = remapBool(row->col(5));
     bool persistent = remapBool(row->col(8));
     int interval = 0;
-    if (mode == TimedScanMode)
+    if (mode == ScanMode::Timed)
         interval = row->col(6).toInt();
     time_t last_modified = row->col(7).toLong();
-    
+
     //log_debug("adding autoscan location: %s; recursive: %d\n", location.c_str(), recursive);
-    
+
     Ref<AutoscanDirectory> dir(new AutoscanDirectory(location, mode, level, recursive, persistent, INVALID_SCAN_ID, interval, hidden));
     dir->setObjectID(objectID);
     dir->setStorageID(storageID);
@@ -1963,8 +1857,8 @@ Ref<AutoscanDirectory> SQLStorage::_fillAutoscanDirectory(Ref<SQLRow> row)
 
 void SQLStorage::addAutoscanDirectory(Ref<AutoscanDirectory> adir)
 {
-    if (adir == nil)
-        throw _Exception(_("addAutoscanDirectory called with adir==nil"));
+    if (adir == nullptr)
+        throw _Exception(_("addAutoscanDirectory called with adir==nullptr"));
     if (adir->getStorageID() >= 0)
         throw _Exception(_("tried to add autoscan directory with a storage id set"));
     int objectID;
@@ -1972,73 +1866,72 @@ void SQLStorage::addAutoscanDirectory(Ref<AutoscanDirectory> adir)
         objectID = CDS_ID_FS_ROOT;
     else
         objectID = findObjectIDByPath(adir->getLocation() + DIR_SEPARATOR);
-    if (! adir->persistent() && objectID < 0)
+    if (!adir->persistent() && objectID < 0)
         throw _Exception(_("tried to add non-persistent autoscan directory with an illegal objectID or location"));
-    
+
     Ref<IntArray> pathIds = _checkOverlappingAutoscans(adir);
-    
+
     _autoscanChangePersistentFlag(objectID, true);
-    
+
     Ref<StringBuffer> q(new StringBuffer());
     *q << "INSERT INTO " << TQ(AUTOSCAN_TABLE)
-        << " (" << TQ("obj_id") << ','
-        << TQ("scan_level") << ','
-        << TQ("scan_mode") << ','
-        << TQ("recursive") << ','
-        << TQ("hidden") << ','
-        << TQ("interval") << ','
-        << TQ("last_modified") << ','
-        << TQ("persistent") << ','
-        << TQ("location") << ','
-        << TQ("path_ids")
-        << ") VALUES ("
-        << (objectID >= 0 ? quote(objectID) : _(SQL_NULL)) << ','
-        << quote(AutoscanDirectory::mapScanlevel(adir->getScanLevel())) << ','
-        << quote(AutoscanDirectory::mapScanmode(adir->getScanMode())) << ','
-        << mapBool(adir->getRecursive()) << ','
-        << mapBool(adir->getHidden()) << ','
-        << quote(adir->getInterval()) << ','
-        << quote(adir->getPreviousLMT()) << ','
-        << mapBool(adir->persistent()) << ','
-        << (objectID >= 0 ? _(SQL_NULL) : quote(adir->getLocation())) << ','
-        << (pathIds == nil ? _(SQL_NULL) : quote(_(",") + pathIds->toCSV() + ','))
-        << ')';
+       << " (" << TQ("obj_id") << ','
+       << TQ("scan_level") << ','
+       << TQ("scan_mode") << ','
+       << TQ("recursive") << ','
+       << TQ("hidden") << ','
+       << TQ("interval") << ','
+       << TQ("last_modified") << ','
+       << TQ("persistent") << ','
+       << TQ("location") << ','
+       << TQ("path_ids")
+       << ") VALUES ("
+       << (objectID >= 0 ? quote(objectID) : _(SQL_NULL)) << ','
+       << quote(AutoscanDirectory::mapScanlevel(adir->getScanLevel())) << ','
+       << quote(AutoscanDirectory::mapScanmode(adir->getScanMode())) << ','
+       << mapBool(adir->getRecursive()) << ','
+       << mapBool(adir->getHidden()) << ','
+       << quote(adir->getInterval()) << ','
+       << quote(adir->getPreviousLMT()) << ','
+       << mapBool(adir->persistent()) << ','
+       << (objectID >= 0 ? _(SQL_NULL) : quote(adir->getLocation())) << ','
+       << (pathIds == nullptr ? _(SQL_NULL) : quote(_(",") + pathIds->toCSV() + ','))
+       << ')';
     adir->setStorageID(exec(q, true));
 }
 
 void SQLStorage::updateAutoscanDirectory(Ref<AutoscanDirectory> adir)
 {
     log_debug("id: %d, obj_id: %d\n", adir->getStorageID(), adir->getObjectID());
-    
-    if (adir == nil)
-        throw _Exception(_("updateAutoscanDirectory called with adir==nil"));
-    
+
+    if (adir == nullptr)
+        throw _Exception(_("updateAutoscanDirectory called with adir==nullptr"));
+
     Ref<IntArray> pathIds = _checkOverlappingAutoscans(adir);
-    
+
     int objectID = adir->getObjectID();
     int objectIDold = _getAutoscanObjectID(adir->getStorageID());
-    if (objectIDold != objectID)
-    {
+    if (objectIDold != objectID) {
         _autoscanChangePersistentFlag(objectIDold, false);
         _autoscanChangePersistentFlag(objectID, true);
     }
     Ref<StringBuffer> q(new StringBuffer());
     *q << "UPDATE " << TQ(AUTOSCAN_TABLE)
-        << " SET " << TQ("obj_id") << '=' << (objectID >= 0 ? quote(objectID) : _(SQL_NULL))
-        << ',' << TQ("scan_level") << '='
-        << quote(AutoscanDirectory::mapScanlevel(adir->getScanLevel()))
-        << ',' << TQ("scan_mode") << '='
-        << quote(AutoscanDirectory::mapScanmode(adir->getScanMode()))
-        << ',' << TQ("recursive") << '=' << mapBool(adir->getRecursive())
-        << ',' << TQ("hidden") << '=' << mapBool(adir->getHidden())
-        << ',' << TQ("interval") << '=' << quote(adir->getInterval());
+       << " SET " << TQ("obj_id") << '=' << (objectID >= 0 ? quote(objectID) : _(SQL_NULL))
+       << ',' << TQ("scan_level") << '='
+       << quote(AutoscanDirectory::mapScanlevel(adir->getScanLevel()))
+       << ',' << TQ("scan_mode") << '='
+       << quote(AutoscanDirectory::mapScanmode(adir->getScanMode()))
+       << ',' << TQ("recursive") << '=' << mapBool(adir->getRecursive())
+       << ',' << TQ("hidden") << '=' << mapBool(adir->getHidden())
+       << ',' << TQ("interval") << '=' << quote(adir->getInterval());
     if (adir->getPreviousLMT() > 0)
         *q << ',' << TQ("last_modified") << '=' << quote(adir->getPreviousLMT());
     *q << ',' << TQ("persistent") << '=' << mapBool(adir->persistent())
-        << ',' << TQ("location") << '=' << (objectID >= 0 ? _(SQL_NULL) : quote(adir->getLocation()))
-        << ',' << TQ("path_ids") << '=' << (pathIds == nil ? _(SQL_NULL) : quote(_(",") + pathIds->toCSV() + ','))
-        << ',' << TQ("touched") << '=' << mapBool(true)
-        << " WHERE " << TQ("id") << '=' << quote(adir->getStorageID());
+       << ',' << TQ("location") << '=' << (objectID >= 0 ? _(SQL_NULL) : quote(adir->getLocation()))
+       << ',' << TQ("path_ids") << '=' << (pathIds == nullptr ? _(SQL_NULL) : quote(_(",") + pathIds->toCSV() + ','))
+       << ',' << TQ("touched") << '=' << mapBool(true)
+       << " WHERE " << TQ("id") << '=' << quote(adir->getStorageID());
     exec(q);
 }
 
@@ -2048,9 +1941,9 @@ void SQLStorage::removeAutoscanDirectoryByObjectID(int objectID)
         return;
     Ref<StringBuffer> q(new StringBuffer());
     *q << "DELETE FROM " << TQ(AUTOSCAN_TABLE)
-        << " WHERE " << TQ("obj_id") << '=' << quote(objectID);
+       << " WHERE " << TQ("obj_id") << '=' << quote(objectID);
     exec(q);
-    
+
     _autoscanChangePersistentFlag(objectID, false);
 }
 
@@ -2061,7 +1954,7 @@ void SQLStorage::removeAutoscanDirectory(int autoscanID)
     int objectID = _getAutoscanObjectID(autoscanID);
     Ref<StringBuffer> q(new StringBuffer());
     *q << "DELETE FROM " << TQ(AUTOSCAN_TABLE)
-        << " WHERE " << TQ("id") << '=' << quote(autoscanID);
+       << " WHERE " << TQ("id") << '=' << quote(autoscanID);
     exec(q);
     if (objectID != INVALID_OBJECT_ID)
         _autoscanChangePersistentFlag(objectID, false);
@@ -2083,12 +1976,12 @@ int SQLStorage::_getAutoscanDirectoryInfo(int objectID, String field)
         return 0;
     Ref<StringBuffer> q(new StringBuffer());
     *q << "SELECT " << TQ(field) << " FROM " << TQ(AUTOSCAN_TABLE)
-        << " WHERE " << TQ("obj_id") << '=' << quote(objectID);
+       << " WHERE " << TQ("obj_id") << '=' << quote(objectID);
     Ref<SQLResult> res = select(q);
     Ref<SQLRow> row;
-    if (res == nil || (row = res->nextRow()) == nil)
+    if (res == nullptr || (row = res->nextRow()) == nullptr)
         return 0;
-    if (! remapBool(row->col(0)))
+    if (!remapBool(row->col(0)))
         return 1;
     else
         return 2;
@@ -2098,27 +1991,28 @@ int SQLStorage::_getAutoscanObjectID(int autoscanID)
 {
     Ref<StringBuffer> q(new StringBuffer());
     *q << "SELECT " << TQ("obj_id") << " FROM " << TQ(AUTOSCAN_TABLE)
-        << " WHERE " << TQ("id") << '=' << quote(autoscanID)
-        << " LIMIT 1";
+       << " WHERE " << TQ("id") << '=' << quote(autoscanID)
+       << " LIMIT 1";
     Ref<SQLResult> res = select(q);
-    if (res == nil)
-        throw _StorageException(nil, _("error while doing select on "));
+    if (res == nullptr)
+        throw _StorageException(nullptr, _("error while doing select on "));
     Ref<SQLRow> row;
-    if ((row = res->nextRow()) != nil && string_ok(row->col(0)))
+    if ((row = res->nextRow()) != nullptr && string_ok(row->col(0)))
         return row->col(0).toInt();
     return INVALID_OBJECT_ID;
 }
 
 void SQLStorage::_autoscanChangePersistentFlag(int objectID, bool persistent)
 {
-    if (objectID == INVALID_OBJECT_ID && objectID == INVALID_OBJECT_ID_2)
+    if (objectID == INVALID_OBJECT_ID || objectID == INVALID_OBJECT_ID_2)
         return;
+
     Ref<StringBuffer> q(new StringBuffer());
     *q << "UPDATE " << TQ(CDS_OBJECT_TABLE)
-        << " SET " << TQ("flags") << " = (" << TQ("flags")
-        << (persistent ? _(" | ") : _(" & ~"))
-        << OBJECT_FLAG_PERSISTENT_CONTAINER
-        << ") WHERE " << TQ("id") << '=' << quote(objectID);
+       << " SET " << TQ("flags") << " = (" << TQ("flags")
+       << (persistent ? _(" | ") : _(" & ~"))
+       << OBJECT_FLAG_PERSISTENT_CONTAINER
+       << ") WHERE " << TQ("id") << '=' << quote(objectID);
     exec(q);
 }
 
@@ -2136,18 +2030,17 @@ void SQLStorage::autoscanUpdateLM(Ref<AutoscanDirectory> adir)
     log_debug("id: %d; last_modified: %d\n", adir->getStorageID(), adir->getPreviousLMT());
     Ref<StringBuffer> q(new StringBuffer());
     *q << "UPDATE " << TQ(AUTOSCAN_TABLE)
-        << " SET " << TQ("last_modified") << '=' << quote(adir->getPreviousLMT())
-        << " WHERE " << TQ("id") << '=' << quote(adir->getStorageID());
+       << " SET " << TQ("last_modified") << '=' << quote(adir->getPreviousLMT())
+       << " WHERE " << TQ("id") << '=' << quote(adir->getStorageID());
     exec(q);
 }
 
 int SQLStorage::isAutoscanChild(int objectID)
 {
     Ref<IntArray> pathIDs = getPathIDs(objectID);
-    if (pathIDs == nil)
+    if (pathIDs == nullptr)
         return INVALID_OBJECT_ID;
-    for (int i = 0; i < pathIDs->size(); i++)
-    {
+    for (int i = 0; i < pathIDs->size(); i++) {
         int recursive = isAutoscanDirectoryRecursive(pathIDs->get(i));
         if (recursive == 2)
             return pathIDs->get(i);
@@ -2162,89 +2055,85 @@ void SQLStorage::checkOverlappingAutoscans(Ref<AutoscanDirectory> adir)
 
 Ref<IntArray> SQLStorage::_checkOverlappingAutoscans(Ref<AutoscanDirectory> adir)
 {
-    if (adir == nil)
-        throw _Exception(_("_checkOverlappingAutoscans called with adir==nil"));
+    if (adir == nullptr)
+        throw _Exception(_("_checkOverlappingAutoscans called with adir==nullptr"));
     int checkObjectID = adir->getObjectID();
     if (checkObjectID == INVALID_OBJECT_ID)
-        return nil;
+        return nullptr;
     int storageID = adir->getStorageID();
-    
+
     Ref<SQLResult> res;
     Ref<SQLRow> row;
-    
+
     Ref<StringBuffer> q(new StringBuffer());
-    
+
     *q << "SELECT " << TQ("id")
-        << " FROM " << TQ(AUTOSCAN_TABLE)
-        << " WHERE " << TQ("obj_id") << " = "
-        << quote(checkObjectID);
+       << " FROM " << TQ(AUTOSCAN_TABLE)
+       << " WHERE " << TQ("obj_id") << " = "
+       << quote(checkObjectID);
     if (storageID >= 0)
         *q << " AND " << TQ("id") << " != " << quote(storageID);
-    
+
     res = select(q);
-    if (res == nil)
+    if (res == nullptr)
         throw _Exception(_("SQL error"));
-    
-    if ((row = res->nextRow()) != nil)
-    {
+
+    if ((row = res->nextRow()) != nullptr) {
         Ref<CdsObject> obj = loadObject(checkObjectID);
-        if (obj == nil)
+        if (obj == nullptr)
             throw _Exception(_("Referenced object (by Autoscan) not found."));
         log_error("There is already an Autoscan set on %s\n", obj->getLocation().c_str());
         throw _Exception(_("There is already an Autoscan set on ") + obj->getLocation());
     }
-    
-    if (adir->getRecursive())
-    {
+
+    if (adir->getRecursive()) {
         q->clear();
         *q << "SELECT " << TQ("obj_id")
-            << " FROM " << TQ(AUTOSCAN_TABLE)
-            << " WHERE " << TQ("path_ids") << " LIKE "
-            << quote(_("%,") + checkObjectID + ",%");
+           << " FROM " << TQ(AUTOSCAN_TABLE)
+           << " WHERE " << TQ("path_ids") << " LIKE "
+           << quote(_("%,") + checkObjectID + ",%");
         if (storageID >= 0)
             *q << " AND " << TQ("id") << " != " << quote(storageID);
         *q << " LIMIT 1";
-        
+
         log_debug("------------ %s\n", q->c_str());
-        
+
         res = select(q);
-        if (res == nil)
+        if (res == nullptr)
             throw _Exception(_("SQL error"));
-        if ((row = res->nextRow()) != nil)
-        {
+        if ((row = res->nextRow()) != nullptr) {
             int objectID = row->col(0).toInt();
             log_debug("-------------- %d\n", objectID);
             Ref<CdsObject> obj = loadObject(objectID);
-            if (obj == nil)
+            if (obj == nullptr)
                 throw _Exception(_("Referenced object (by Autoscan) not found."));
             log_error("Overlapping Autoscans are not allowed. There is already an Autoscan set on %s\n", obj->getLocation().c_str());
             throw _Exception(_("Overlapping Autoscans are not allowed. There is already an Autoscan set on ") + obj->getLocation());
         }
     }
-    
+
     Ref<IntArray> pathIDs = getPathIDs(checkObjectID);
-    if (pathIDs == nil)
-        throw _Exception(_("getPathIDs returned nil"));
+    if (pathIDs == nullptr)
+        throw _Exception(_("getPathIDs returned nullptr"));
     q->clear();
     *q << "SELECT " << TQ("obj_id")
-        << " FROM " << TQ(AUTOSCAN_TABLE)
-        << " WHERE " << TQ("obj_id") << " IN ("
-        << pathIDs->toCSV()
-        << ") AND " << TQ("recursive") << '=' << mapBool(true);
+       << " FROM " << TQ(AUTOSCAN_TABLE)
+       << " WHERE " << TQ("obj_id") << " IN ("
+       << pathIDs->toCSV()
+       << ") AND " << TQ("recursive") << '=' << mapBool(true);
     if (storageID >= 0)
         *q << " AND " << TQ("id") << " != " << quote(storageID);
     *q << " LIMIT 1";
-    
+
     res = select(q);
-    if (res == nil)
+    if (res == nullptr)
         throw _Exception(_("SQL error"));
-    if ((row = res->nextRow()) == nil)
+    if ((row = res->nextRow()) == nullptr)
         return pathIDs;
-    else
-    {
+    else {
         int objectID = row->col(0).toInt();
         Ref<CdsObject> obj = loadObject(objectID);
-        if (obj == nil)
+        if (obj == nullptr)
             throw _Exception(_("Referenced object (by Autoscan) not found."));
         log_error("Overlapping Autoscans are not allowed. There is already a recursive Autoscan set on %s\n", obj->getLocation().c_str());
         throw _Exception(_("Overlapping Autoscans are not allowed. There is already a recursive Autoscan set on ") + obj->getLocation());
@@ -2254,9 +2143,9 @@ Ref<IntArray> SQLStorage::_checkOverlappingAutoscans(Ref<AutoscanDirectory> adir
 Ref<IntArray> SQLStorage::getPathIDs(int objectID)
 {
     flushInsertBuffer();
-    
+
     if (objectID == INVALID_OBJECT_ID)
-        return nil;
+        return nullptr;
     Ref<IntArray> pathIDs(new IntArray());
     Ref<StringBuffer> q(new StringBuffer());
     *q << "SELECT " << TQ("parent_id") << " FROM " << TQ(CDS_OBJECT_TABLE) << " WHERE ";
@@ -2264,13 +2153,12 @@ Ref<IntArray> SQLStorage::getPathIDs(int objectID)
     int selBufLen = q->length();
     Ref<SQLResult> res;
     Ref<SQLRow> row;
-    while (objectID != CDS_ID_ROOT)
-    {
+    while (objectID != CDS_ID_ROOT) {
         pathIDs->append(objectID);
         q->setLength(selBufLen);
         *q << quote(objectID) << " LIMIT 1";
         res = select(q);
-        if (res == nil || (row = res->nextRow()) == nil)
+        if (res == nullptr || (row = res->nextRow()) == nullptr)
             break;
         objectID = row->col(0).toInt();
     }
@@ -2287,12 +2175,9 @@ String SQLStorage::getFsRootName()
 
 void SQLStorage::setFsRootName(String rootName)
 {
-    if (string_ok(rootName))
-    {
+    if (string_ok(rootName)) {
         fsRootName = rootName;
-    }
-    else
-    {
+    } else {
         Ref<CdsObject> fsRootObj = loadObject(CDS_ID_FS_ROOT);
         fsRootName = fsRootObj->getTitle();
     }
@@ -2302,25 +2187,26 @@ int SQLStorage::getNextID()
 {
     if (lastID < CDS_ID_FS_ROOT)
         throw _Exception(_("SQLStorage::getNextID() called, but lastID hasn't been loaded correctly yet"));
-    AUTOLOCK(nextIDMutex);
+    AutoLock lock(nextIDMutex);
     return ++lastID;
 }
 
 void SQLStorage::loadLastID()
 {
+    AutoLock lock(nextIDMutex);
+
     // we don't rely on automatic db generated ids, because of our caching
-    
     Ref<StringBuffer> qb(new StringBuffer());
     *qb << "SELECT MAX(" << TQ("id") << ')'
         << " FROM " << TQ(CDS_OBJECT_TABLE);
     Ref<SQLResult> res = select(qb);
-    if (res == nil)
-        throw _Exception(_("could not load lastID (res==nil)"));
-    
+    if (res == nullptr)
+        throw _Exception(_("could not load lastID (res==nullptr)"));
+
     Ref<SQLRow> row = res->nextRow();
-    if (row == nil)
-        throw _Exception(_("could not load lastID (row==nil)"));
-    
+    if (row == nullptr)
+        throw _Exception(_("could not load lastID (row==nullptr)"));
+
     lastID = row->col(0).toInt();
     if (lastID < CDS_ID_FS_ROOT)
         throw _Exception(_("could not load correct lastID (db not initialized?)"));
@@ -2328,11 +2214,10 @@ void SQLStorage::loadLastID()
 
 void SQLStorage::addObjectToCache(Ref<CdsObject> object, bool dontLock)
 {
-    if (cacheOn() && object != nil)
-    {
-        AUTOLOCK_DEFINE_ONLY();
-        if (! dontLock)
-            AUTOLOCK_NO_DEFINE(cache->getMutex());
+    if (cacheOn() && object != nullptr) {
+        unique_lock<std::mutex> lock(cache->getMutex(), std::defer_lock);
+        if (!dontLock)
+            lock.lock();
         Ref<CacheObject> cObj = cache->getObjectDefinitely(object->getID());
         if (cache->flushed())
             flushInsertBuffer();
@@ -2344,26 +2229,26 @@ void SQLStorage::addObjectToCache(Ref<CdsObject> object, bool dontLock)
 void SQLStorage::addToInsertBuffer(Ref<StringBuffer> query)
 {
     assert(doInsertBuffering());
-    
+
+    AutoLock lock(mutex);
     _addToInsertBuffer(query);
-    
-    AUTOLOCK(mutex);
+
     insertBufferEmpty = false;
     insertBufferStatementCount++;
     insertBufferByteCount += query->length();
-    
+
     if (insertBufferByteCount > 102400)
         flushInsertBuffer(true);
 }
 
 void SQLStorage::flushInsertBuffer(bool dontLock)
 {
-    if (! doInsertBuffering())
+    if (!doInsertBuffering())
         return;
     //print_backtrace();
-    AUTOLOCK_DEFINE_ONLY();
-    if (! dontLock)
-        AUTOLOCK_NO_DEFINE(mutex);
+    unique_lock<decltype(mutex)> lock(mutex, std::defer_lock);
+    if (!dontLock)
+        lock.lock();
     if (insertBufferEmpty)
         return;
     _flushInsertBuffer();
diff --git a/src/storage/sql_storage.h b/src/storage/sql_storage.h
index 09414ed..4526350 100644
--- a/src/storage/sql_storage.h
+++ b/src/storage/sql_storage.h
@@ -32,14 +32,15 @@
 #ifndef __SQL_STORAGE_H__
 #define __SQL_STORAGE_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 #include "cds_objects.h"
 #include "dictionary.h"
 #include "storage.h"
-#include "hash.h"
-#include "sync.h"
 #include "storage_cache.h"
 
+#include <unordered_set>
+#include <mutex>
+
 #define QTB                 table_quote_begin
 #define QTE                 table_quote_end
 
@@ -81,6 +82,7 @@ public:
     virtual zmm::String quote(unsigned long val) = 0;
     virtual zmm::String quote(bool val) = 0;
     virtual zmm::String quote(char val) = 0;
+    virtual zmm::String quote(long long val) = 0;
     virtual zmm::Ref<SQLResult> select(const char *query, int length) = 0;
     virtual int exec(const char *query, int length, bool getLastInsertId = false) = 0;
     
@@ -92,67 +94,68 @@ public:
     int exec(zmm::Ref<zmm::StringBuffer> buf, bool getLastInsertId = false)
         { return exec(buf->c_str(), buf->length(), getLastInsertId); }
     
-    virtual void addObject(zmm::Ref<CdsObject> object, int *changedContainer);
-    virtual void updateObject(zmm::Ref<CdsObject> object, int *changedContainer);
+    virtual void addObject(zmm::Ref<CdsObject> object, int *changedContainer) override;
+    virtual void updateObject(zmm::Ref<CdsObject> object, int *changedContainer) override;
     
-    virtual zmm::Ref<CdsObject> loadObject(int objectID);
-    virtual int getChildCount(int contId, bool containers, bool items, bool hideFsRoot);
+    virtual zmm::Ref<CdsObject> loadObject(int objectID) override;
+    virtual int getChildCount(int contId, bool containers, bool items, bool hideFsRoot) override;
     
     //virtual zmm::Ref<zmm::Array<CdsObject> > selectObjects(zmm::Ref<SelectParam> param);
     
-    virtual zmm::Ref<DBRHash<int> > getObjects(int parentID, bool withoutContainer);
+    virtual std::shared_ptr<std::unordered_set<int> > getObjects(int parentID, bool withoutContainer) override;
     
-    virtual zmm::Ref<ChangedContainers> removeObject(int objectID, bool all);
-    virtual zmm::Ref<ChangedContainers> removeObjects(zmm::Ref<DBRHash<int> > list, bool all = false);
+    virtual zmm::Ref<ChangedContainers> removeObject(int objectID, bool all) override;
+    virtual zmm::Ref<ChangedContainers> removeObjects(std::shared_ptr<std::unordered_set<int> > list, bool all = false) override;
     
-    virtual zmm::Ref<CdsObject> loadObjectByServiceID(zmm::String serviceID);
-    virtual zmm::Ref<zmm::IntArray> getServiceObjectIDs(char servicePrefix);
+    virtual zmm::Ref<CdsObject> loadObjectByServiceID(zmm::String serviceID) override;
+    virtual zmm::Ref<zmm::IntArray> getServiceObjectIDs(char servicePrefix) override;
+
+    virtual zmm::String findFolderImage(int id, zmm::String trackArtBase) override;
     
     /* accounting methods */
-    virtual int getTotalFiles();
+    virtual int getTotalFiles() override;
     
-    virtual zmm::Ref<zmm::Array<CdsObject> > browse(zmm::Ref<BrowseParam> param);
-    virtual zmm::Ref<zmm::Array<zmm::StringBase> > getMimeTypes();
+    virtual zmm::Ref<zmm::Array<CdsObject> > browse(zmm::Ref<BrowseParam> param) override;
+    virtual zmm::Ref<zmm::Array<zmm::StringBase> > getMimeTypes() override;
     
     //virtual zmm::Ref<CdsObject> findObjectByTitle(zmm::String title, int parentID);
-    virtual zmm::Ref<CdsObject> findObjectByPath(zmm::String fullpath);
-    virtual int findObjectIDByPath(zmm::String fullpath);
-    virtual zmm::String incrementUpdateIDs(int *ids, int size);
-    
-    virtual zmm::String buildContainerPath(int parentID, zmm::String title);
-    virtual void addContainerChain(zmm::String path, zmm::String lastClass,
-            int lastRefID, int *containerID, int *updateID);
-    virtual zmm::String getInternalSetting(zmm::String key);
-    virtual void storeInternalSetting(zmm::String key, zmm::String value) = 0;
-    
-    virtual void updateAutoscanPersistentList(scan_mode_t scanmode, zmm::Ref<AutoscanList> list);
-    virtual zmm::Ref<AutoscanList> getAutoscanList(scan_mode_t scanmode);
-    virtual void addAutoscanDirectory(zmm::Ref<AutoscanDirectory> adir);
-    virtual void updateAutoscanDirectory(zmm::Ref<AutoscanDirectory> adir);
-    virtual void removeAutoscanDirectoryByObjectID(int objectID);
-    virtual void removeAutoscanDirectory(int autoscanID);
-    virtual int getAutoscanDirectoryType(int objectId);
-    virtual int isAutoscanDirectoryRecursive(int objectId);
-    virtual void autoscanUpdateLM(zmm::Ref<AutoscanDirectory> adir);
-    virtual zmm::Ref<AutoscanDirectory> getAutoscanDirectory(int objectID);
-    virtual int isAutoscanChild(int objectID);
-    virtual void checkOverlappingAutoscans(zmm::Ref<AutoscanDirectory> adir);
-    
-    virtual zmm::Ref<zmm::IntArray> getPathIDs(int objectID);
-    
-    virtual void shutdown();
+    virtual zmm::Ref<CdsObject> findObjectByPath(zmm::String fullpath) override;
+    virtual int findObjectIDByPath(zmm::String fullpath) override;
+    virtual zmm::String incrementUpdateIDs(std::shared_ptr<std::unordered_set<int> > ids) override;
+    
+    virtual zmm::String buildContainerPath(int parentID, zmm::String title) override;
+    virtual void addContainerChain(zmm::String path, zmm::String lastClass, int lastRefID, int *containerID, int *updateID, zmm::Ref<Dictionary> lastMetadata) override;
+    virtual zmm::String getInternalSetting(zmm::String key) override;
+    virtual void storeInternalSetting(zmm::String key, zmm::String value) override = 0;
+    
+    virtual void updateAutoscanPersistentList(ScanMode scanmode, zmm::Ref<AutoscanList> list) override;
+    virtual zmm::Ref<AutoscanList> getAutoscanList(ScanMode scanmode) override;
+    virtual void addAutoscanDirectory(zmm::Ref<AutoscanDirectory> adir) override;
+    virtual void updateAutoscanDirectory(zmm::Ref<AutoscanDirectory> adir) override;
+    virtual void removeAutoscanDirectoryByObjectID(int objectID) override;
+    virtual void removeAutoscanDirectory(int autoscanID) override;
+    virtual int getAutoscanDirectoryType(int objectId) override;
+    virtual int isAutoscanDirectoryRecursive(int objectId) override;
+    virtual void autoscanUpdateLM(zmm::Ref<AutoscanDirectory> adir) override;
+    virtual zmm::Ref<AutoscanDirectory> getAutoscanDirectory(int objectID) override;
+    virtual int isAutoscanChild(int objectID) override;
+    virtual void checkOverlappingAutoscans(zmm::Ref<AutoscanDirectory> adir) override;
+    
+    virtual zmm::Ref<zmm::IntArray> getPathIDs(int objectID) override;
+    
+    virtual void shutdown() override;
     virtual void shutdownDriver() = 0;
     
-    virtual int ensurePathExistence(zmm::String path, int *changedContainer);
+    virtual int ensurePathExistence(zmm::String path, int *changedContainer) override;
     
-    virtual zmm::String getFsRootName();
+    virtual zmm::String getFsRootName() override;
     
-    virtual void clearFlagInDB(int flag);
+    virtual void clearFlagInDB(int flag) override;
 
 protected:
     SQLStorage();
     //virtual ~SQLStorage();
-    virtual void init();
+    virtual void init() override;
     
     char table_quote_begin;
     char table_quote_end;
@@ -219,12 +222,12 @@ private:
     zmm::String stripLocationPrefix(zmm::String path);
     
     zmm::Ref<CdsObject> checkRefID(zmm::Ref<CdsObject> obj);
-    int createContainer(int parentID, zmm::String name, zmm::String path, bool isVirtual, zmm::String upnpClass, int refID);
-    
+    int createContainer(int parentID, zmm::String name, zmm::String path, bool isVirtual, zmm::String upnpClass, int refID, zmm::Ref<Dictionary> lastMetadata);
+
     zmm::String mapBool(bool val) { return quote((val ? 1 : 0)); }
     bool remapBool(zmm::String field) { return (string_ok(field) && field == "1"); }
     
-    void setFsRootName(zmm::String rootName = nil);
+    void setFsRootName(zmm::String rootName = nullptr);
     
     zmm::String fsRootName;
     
@@ -232,17 +235,17 @@ private:
     
     int getNextID();
     void loadLastID();
-    zmm::Ref<Mutex> nextIDMutex;
+    std::mutex nextIDMutex;
     
     zmm::Ref<StorageCache> cache;
-    inline bool cacheOn() { return cache != nil; }
+    inline bool cacheOn() { return cache != nullptr; }
     void addObjectToCache(zmm::Ref<CdsObject> object, bool dontLock = false);
     
     inline bool doInsertBuffering() { return insertBufferOn; }
     void addToInsertBuffer(zmm::Ref<zmm::StringBuffer> query);
     void flushInsertBuffer(bool dontLock = false);
     
-    /* insert buffer functions to be overriden by implementing classes */
+    /* insert buffer functions to be overridden by implementing classes */
     virtual void _addToInsertBuffer(zmm::Ref<zmm::StringBuffer> query) = 0;
     virtual void _flushInsertBuffer() = 0;
     
@@ -250,7 +253,7 @@ private:
     bool insertBufferEmpty;
     int insertBufferStatementCount;
     int insertBufferByteCount;
-    zmm::Ref<Mutex> insertBufferMutex;
+    using AutoLock = std::lock_guard<std::mutex>;
 };
 
 #endif // __SQL_STORAGE_H__
diff --git a/src/storage/sqlite3/sqlite3_storage.cc b/src/storage/sqlite3/sqlite3_storage.cc
index 621b1cd..ad40560 100644
--- a/src/storage/sqlite3/sqlite3_storage.cc
+++ b/src/storage/sqlite3/sqlite3_storage.cc
@@ -60,16 +60,15 @@
 
 using namespace zmm;
 using namespace mxml;
+using namespace std;
 
 Sqlite3Storage::Sqlite3Storage() : SQLStorage()
 {
     shutdownFlag = false;
     table_quote_begin = '"';
     table_quote_end = '"';
-    startupError = nil;
-    sqliteMutex = Ref<Mutex>(new Mutex());
-    cond = Ref<Cond>(new Cond(sqliteMutex));
-    insertBuffer = nil;
+    startupError = nullptr;
+    insertBuffer = nullptr;
     dirty = false;
 }
 
@@ -79,7 +78,7 @@ void Sqlite3Storage::init()
     
     int ret;
     
-    AUTOLOCK(sqliteMutex);
+    AutoLockU lock(sqliteMutex);
     /*
     pthread_attr_t attr;
     pthread_attr_init(&attr);
@@ -90,7 +89,7 @@ void Sqlite3Storage::init()
     
     // check for db-file
     if (access(dbFilePath.c_str(), R_OK | W_OK) != 0 && errno != ENOENT)
-        throw _StorageException(nil, _("Error while accessing sqlite database file (") + dbFilePath +"): " + mt_strerror(errno));
+        throw _StorageException(nullptr, _("Error while accessing sqlite database file (") + dbFilePath +"): " + mt_strerror(errno));
     
     
     
@@ -99,25 +98,25 @@ void Sqlite3Storage::init()
     
     ret = pthread_create(
         &sqliteThread,
-        NULL, //&attr,
+        nullptr, //&attr,
         Sqlite3Storage::staticThreadProc,
         this
     );
 
     if (ret != 0)
     {
-        throw _StorageException(nil, _("Could not start sqlite thread: ") +
+        throw _StorageException(nullptr, _("Could not start sqlite thread: ") +
                     mt_strerror(errno));
     }
     
     // wait for sqlite3 thread to become ready
-    cond->wait();
-    AUTOUNLOCK();
-    if (startupError != nil)
-        throw _StorageException(nil, startupError);
+    cond.wait(lock);
+    lock.unlock();
+    if (startupError != nullptr)
+        throw _StorageException(nullptr, startupError);
     
     
-    String dbVersion = nil;
+    String dbVersion = nullptr;
     try
     {
         dbVersion = getInternalSetting(_("db_version"));
@@ -147,7 +146,7 @@ void Sqlite3Storage::init()
                 }
             }
             
-            if (dbVersion == nil)
+            if (dbVersion == nullptr)
             {
 #ifdef AUTO_CREATE_DATABASE
                 log_info("no sqlite3 backup is available or backup is corrupt. automatically creating database...\n");
@@ -158,7 +157,7 @@ void Sqlite3Storage::init()
                     ptask->waitForTask();
                     dbVersion = getInternalSetting(_("db_version"));
                 }
-                catch (Exception e)
+                catch (const Exception & e)
                 {
                     shutdown();
                     throw _Exception(_("error while creating database: ") + e.getMessage());
@@ -178,7 +177,7 @@ void Sqlite3Storage::init()
         }
     }
     
-    if (dbVersion == nil)
+    if (dbVersion == nullptr)
     {
         shutdown();
         throw _Exception(_("sqlite3 database seems to be corrupt and restoring from backup failed"));
@@ -228,8 +227,7 @@ void Sqlite3Storage::init()
     if (ConfigManager::getInstance()->getBoolOption(CFG_SERVER_STORAGE_SQLITE_BACKUP_ENABLED))
     {
         int backupInterval = ConfigManager::getInstance()->getIntOption(CFG_SERVER_STORAGE_SQLITE_BACKUP_INTERVAL);
-        Ref<TimerSubscriberObject> backupTimerSubscriber(new Sqlite3BackupTimerSubscriber());
-        Timer::getInstance()->addTimerSubscriber(backupTimerSubscriber, backupInterval, Ref<Object>(this));
+        Timer::getInstance()->addTimerSubscriber(this, backupInterval, nullptr);
         
         // do a backup now
         Ref<SLBackupTask> btask (new SLBackupTask(false));
@@ -248,7 +246,7 @@ void Sqlite3Storage::_exec(const char *query)
 String Sqlite3Storage::quote(String value)
 {
     char *q = sqlite3_mprintf("'%q'",
-        (value == nil ? "" : value.c_str()));
+        (value == nullptr ? "" : value.c_str()));
     String ret = q;
     sqlite3_free(q);
     return ret;
@@ -257,7 +255,7 @@ String Sqlite3Storage::quote(String value)
 String Sqlite3Storage::getError(String query, String error, sqlite3 *db)
 {
     return _("SQLITE3: (") + sqlite3_errcode(db) + ") " 
-        + sqlite3_errmsg(db) +"\nQuery:" + (query == nil ? _("unknown") : query) + "\nerror: " + (error == nil ? _("unknown") : error);
+        + sqlite3_errmsg(db) +"\nQuery:" + (query == nullptr ? _("unknown") : query) + "\nerror: " + (error == nullptr ? _("unknown") : error);
 }
 
 Ref<SQLResult> Sqlite3Storage::select(const char *query, int length)
@@ -283,11 +281,11 @@ int Sqlite3Storage::exec(const char *query, int length, bool getLastInsertId)
 
 void *Sqlite3Storage::staticThreadProc(void *arg)
 {
-    Sqlite3Storage *inst = (Sqlite3Storage *)arg;
+    auto *inst = (Sqlite3Storage *)arg;
     inst->threadProc();
     log_debug("Sqlite3Storage::staticThreadProc - exiting thread\n");
-    pthread_exit(NULL);
-    return NULL;
+    pthread_exit(nullptr);
+    return nullptr;
 }
 
 void Sqlite3Storage::threadProc()
@@ -305,19 +303,19 @@ void Sqlite3Storage::threadProc()
             dbFilePath;
         return;
     }
-    AUTOLOCK(sqliteMutex);
+    AutoLockU lock(sqliteMutex);
     // tell init() that we are ready
-    cond->signal();
+    cond.notify_one();
     
     while(! shutdownFlag)
     {
-        if((task = taskQueue->dequeue()) == nil)
+        if((task = taskQueue->dequeue()) == nullptr)
         {
             /* if nothing to do, sleep until awakened */
-            cond->wait();
+            cond.wait(lock);
             continue;
         }
-        AUTOUNLOCK();
+        lock.unlock();
         try
         {
             task->run(&db, this);
@@ -327,15 +325,15 @@ void Sqlite3Storage::threadProc()
                 dirty = false;
             task->sendSignal();
         }
-        catch (Exception e)
+        catch (const Exception & e)
         {
             task->sendSignal(e.getMessage());
         }
-        AUTORELOCK();
+        lock.lock();
     }
     
     taskQueueOpen = false;
-    while((task = taskQueue->dequeue()) != nil)
+    while((task = taskQueue->dequeue()) != nullptr)
     {
         task->sendSignal(_("Sorry, sqlite3 thread is shutting down"));
     }
@@ -347,7 +345,7 @@ void Sqlite3Storage::addTask(zmm::Ref<SLTask> task, bool onlyIfDirty)
 {
     if (! taskQueueOpen)
         throw _Exception(_("sqlite3 task queue is already closed"));
-    AUTOLOCK(sqliteMutex);
+    AutoLock lock(sqliteMutex);
     if (! taskQueueOpen)
     {
         throw _Exception(_("sqlite3 task queue is already closed"));
@@ -355,21 +353,24 @@ void Sqlite3Storage::addTask(zmm::Ref<SLTask> task, bool onlyIfDirty)
     if (! onlyIfDirty || dirty)
     {
         taskQueue->enqueue(task);
-        signal();
+        cond.notify_one();
     }
 }
 
 void Sqlite3Storage::shutdownDriver()
 {
     log_debug("start\n");
-    AUTOLOCK(sqliteMutex);
+    AutoLockU lock(sqliteMutex);
     shutdownFlag = true;
+    if (ConfigManager::getInstance()->getBoolOption(CFG_SERVER_STORAGE_SQLITE_BACKUP_ENABLED)) {
+        Timer::getInstance()->removeTimerSubscriber(this, nullptr);
+    }
     log_debug("signalling...\n");
-    signal();
-    AUTOUNLOCK();
+    cond.notify_one();
+    lock.unlock();
     log_debug("waiting for thread\n");
     if (sqliteThread)
-        pthread_join(sqliteThread, NULL);
+        pthread_join(sqliteThread, nullptr);
     sqliteThread = 0;
     log_debug("end\n");
 }
@@ -384,7 +385,7 @@ void Sqlite3Storage::storeInternalSetting(String key, String value)
 
 void Sqlite3Storage::_addToInsertBuffer(Ref<StringBuffer> query)
 {
-    if (insertBuffer == nil)
+    if (insertBuffer == nullptr)
     {
         insertBuffer = Ref<StringBuffer>(new StringBuffer());
         *insertBuffer << "BEGIN TRANSACTION;";
@@ -395,7 +396,7 @@ void Sqlite3Storage::_addToInsertBuffer(Ref<StringBuffer> query)
 
 void Sqlite3Storage::_flushInsertBuffer()
 {
-    if (insertBuffer == nil)
+    if (insertBuffer == nullptr)
         return;
     *insertBuffer << "COMMIT;";
     SQLStorage::exec(insertBuffer);
@@ -408,9 +409,7 @@ void Sqlite3Storage::_flushInsertBuffer()
 SLTask::SLTask() : Object()
 {
     running = true;
-    mutex = Ref<Mutex>(new Mutex());
-    cond = Ref<Cond>(new Cond(mutex));
-    error = nil;
+    error = nullptr;
     contamination = false;
     decontamination = false;
 }
@@ -421,9 +420,9 @@ bool SLTask::is_running()
 
 void SLTask::sendSignal()
 {
-    AUTOLOCK(mutex);
+    lock_guard<decltype(mutex)> lock(mutex);
     running=false;
-    cond->signal();
+    cond.notify_one();
 }
 
 void SLTask::sendSignal(String error)
@@ -436,14 +435,14 @@ void SLTask::waitForTask()
 {
     if (is_running())
     { // we check before we lock first, because there is no need to lock then
-        AUTOLOCK(mutex);
+        unique_lock<decltype(mutex)> lock(mutex);
         if (is_running())
         { // we check it a second time after locking to ensure we didn't miss the pthread_cond_signal 
-            cond->wait(); // waiting for the task to complete
+            cond.wait(lock); // waiting for the task to complete
         }
     }
     
-    if (getError() != nil)
+    if (getError() != nullptr)
     {
         log_debug("%s\n", getError().c_str());
         throw _Exception(getError());
@@ -460,36 +459,36 @@ void SLInitTask::run(sqlite3 **db, Sqlite3Storage *sl)
     sqlite3_close(*db);
     
     if (unlink(dbFilePath.c_str()) != 0)
-        throw _StorageException(nil, _("error while autocreating sqlite3 database: could not unlink old database file: ") + mt_strerror(errno));
+        throw _StorageException(nullptr, _("error while autocreating sqlite3 database: could not unlink old database file: ") + mt_strerror(errno));
     
     int res = sqlite3_open(dbFilePath.c_str(), db);
     if (res != SQLITE_OK)
-        throw _StorageException(nil, _("error while autocreating sqlite3 database: could not create new database"));
+        throw _StorageException(nullptr, _("error while autocreating sqlite3 database: could not create new database"));
     
     unsigned char buf[SL3_CREATE_SQL_INFLATED_SIZE + 1]; // +1 for '\0' at the end of the string
     unsigned long uncompressed_size = SL3_CREATE_SQL_INFLATED_SIZE;
     int ret = uncompress(buf, &uncompressed_size, sqlite3_create_sql, SL3_CREATE_SQL_DEFLATED_SIZE);
     if (ret != Z_OK || uncompressed_size != SL3_CREATE_SQL_INFLATED_SIZE)
-        throw _StorageException(nil, _("Error while uncompressing sqlite3 create sql. returned: ") + ret);
+        throw _StorageException(nullptr, _("Error while uncompressing sqlite3 create sql. returned: ") + ret);
     buf[SL3_CREATE_SQL_INFLATED_SIZE] = '\0';
     
-    char *err = NULL;
+    char *err = nullptr;
     ret = sqlite3_exec(
         *db,
         (const char *)buf,
-        NULL,
-        NULL,
+        nullptr,
+        nullptr,
         &err
     );
-    String error = nil;
-    if (err != NULL)
+    String error = nullptr;
+    if (err != nullptr)
     {
         error = err;
         sqlite3_free(err);
     }
     if(ret != SQLITE_OK)
     {
-        throw _StorageException(nil, sl->getError((const char*)buf, error, *db));
+        throw _StorageException(nullptr, sl->getError((const char*)buf, error, *db));
     }
     contamination = true;
 }
@@ -517,15 +516,15 @@ void SLSelectTask::run(sqlite3 **db, Sqlite3Storage *sl)
         &pres->ncolumn,
         &err
     );
-    String error = nil;
-    if (err != NULL)
+    String error = nullptr;
+    if (err != nullptr)
     {
         error = err;
         sqlite3_free(err);
     }
     if(ret != SQLITE_OK)
     {
-        throw _StorageException(nil, sl->getError(query, error, *db));
+        throw _StorageException(nullptr, sl->getError(query, error, *db));
     }
     
     pres->row = pres->table;
@@ -547,19 +546,19 @@ void SLExecTask::run(sqlite3 **db, Sqlite3Storage *sl)
     int res = sqlite3_exec(
         *db,
         query,
-        NULL,
-        NULL,
+        nullptr,
+        nullptr,
         &err
     );
-    String error = nil;
-    if (err != NULL)
+    String error = nullptr;
+    if (err != nullptr)
     {
         error = err;
         sqlite3_free(err);
     }
     if(res != SQLITE_OK)
     {
-        throw _StorageException(nil, sl->getError(query, error, *db));
+        throw _StorageException(nullptr, sl->getError(query, error, *db));
     }
     if (getLastInsertIdFlag)
         lastInsertId = sqlite3_last_insert_rowid(*db);
@@ -584,7 +583,7 @@ void SLBackupTask::run(sqlite3 **db, Sqlite3Storage *sl)
             log_debug("sqlite3 backup successful\n");
             decontamination = true;
         }
-        catch (Exception e)
+        catch (const Exception & e)
         {
             log_error("error while making sqlite3 backup: %s\n", e.getMessage().c_str());
         }
@@ -601,14 +600,14 @@ void SLBackupTask::run(sqlite3 **db, Sqlite3Storage *sl)
             );
             
         }
-        catch (Exception e)
+        catch (const Exception & e)
         {
-            throw _StorageException(nil, _("error while restoring sqlite3 backup: ") + e.getMessage());
+            throw _StorageException(nullptr, _("error while restoring sqlite3 backup: ") + e.getMessage());
         }
         int res = sqlite3_open(dbFilePath.c_str(), db);
         if (res != SQLITE_OK)
         {
-            throw _StorageException(nil, _("error while restoring sqlite3 backup: could not reopen sqlite3 database after restore"));
+            throw _StorageException(nullptr, _("error while restoring sqlite3 backup: could not reopen sqlite3 database after restore"));
         }
         log_info("sqlite3 database successfully restored from backup.\n");   
     }
@@ -620,14 +619,14 @@ void SLBackupTask::run(sqlite3 **db, Sqlite3Storage *sl)
 
 Sqlite3Result::Sqlite3Result() : SQLResult()
 {
-    table = NULL;
+    table = nullptr;
 }
 Sqlite3Result::~Sqlite3Result()
 {
     if(table)
     {
         sqlite3_free_table(table);
-        table = NULL;
+        table = nullptr;
     }
 }
 Ref<SQLRow> Sqlite3Result::nextRow()
@@ -643,9 +642,9 @@ Ref<SQLRow> Sqlite3Result::nextRow()
             return RefCast(p, SQLRow);
         }
         else
-            return nil;
+            return nullptr;
     }
-    return nil;
+    return nullptr;
 
 }
 
@@ -658,12 +657,10 @@ Sqlite3Row::Sqlite3Row(char **row, Ref<SQLResult> sqlResult) : SQLRow(sqlResult)
 
 /* Sqlite3BackupTimerSubscriber */
 
-void Sqlite3BackupTimerSubscriber::timerNotify(Ref<Object> sqlite3storage)
+void Sqlite3Storage::timerNotify(Ref<Timer::Parameter> param)
 {
-    Sqlite3Storage *storage = (Sqlite3Storage*)(sqlite3storage.getPtr());
-    
     Ref<SLBackupTask> btask (new SLBackupTask(false));
-    storage->addTask(RefCast(btask, SLTask), true);
+    this->addTask(RefCast(btask, SLTask), true);
 }
 
 #endif // HAVE_SQLITE3
diff --git a/src/storage/sqlite3/sqlite3_storage.h b/src/storage/sqlite3/sqlite3_storage.h
index d825bd4..836d547 100644
--- a/src/storage/sqlite3/sqlite3_storage.h
+++ b/src/storage/sqlite3/sqlite3_storage.h
@@ -35,10 +35,11 @@
 #ifndef __SQLITE3_STORAGE_H__
 #define __SQLITE3_STORAGE_H__
 
+#include <mutex>
+#include <condition_variable>
 #include <sqlite3.h>
 
 #include "storage/sql_storage.h"
-#include "sync.h"
 #include "timer.h"
 
 class Sqlite3Storage;
@@ -83,8 +84,9 @@ protected:
     /// \brief true if this task has backuped the db
     bool decontamination;
     
-    zmm::Ref<Cond> cond;
-    zmm::Ref<Mutex> mutex;
+    std::condition_variable cond;
+    std::mutex mutex;
+
     zmm::String error;
 };
 
@@ -145,25 +147,28 @@ protected:
 };
 
 /// \brief The Storage class for using SQLite3
-class Sqlite3Storage : private SQLStorage
+class Sqlite3Storage : public Timer::Subscriber, private SQLStorage
 {
+public:
+    virtual void timerNotify(zmm::Ref<Timer::Parameter> sqlite3storage);
 private:
     Sqlite3Storage();
     friend zmm::Ref<Storage> Storage::createInstance();
-    virtual void init();
-    virtual void shutdownDriver();
-    
-    virtual zmm::String quote(zmm::String str);
-    virtual inline zmm::String quote(int val) { return zmm::String::from(val); }
-    virtual inline zmm::String quote(unsigned int val) { return zmm::String::from(val); }
-    virtual inline zmm::String quote(long val) { return zmm::String::from(val); }
-    virtual inline zmm::String quote(unsigned long val) { return zmm::String::from(val); }
-    virtual inline zmm::String quote(bool val) { return zmm::String(val ? '1' : '0'); }
-    virtual inline zmm::String quote(char val) { return quote(zmm::String(val)); }
-    virtual zmm::Ref<SQLResult> select(const char *query, int length);
-    virtual int exec(const char *query, int length, bool getLastInsertId = false);
-    virtual void storeInternalSetting(zmm::String key, zmm::String value);
-    
+    virtual void init() override;
+    virtual void shutdownDriver() override;
+    
+    virtual zmm::String quote(zmm::String str) override;
+    virtual inline zmm::String quote(int val) override { return zmm::String::from(val); }
+    virtual inline zmm::String quote(unsigned int val) override { return zmm::String::from(val); }
+    virtual inline zmm::String quote(long val) override { return zmm::String::from(val); }
+    virtual inline zmm::String quote(unsigned long val) override { return zmm::String::from(val); }
+    virtual inline zmm::String quote(bool val) override { return zmm::String(val ? '1' : '0'); }
+    virtual inline zmm::String quote(char val) override { return quote(zmm::String(val)); }
+    virtual inline zmm::String quote(long long val) override { return zmm::String::from(val); }
+    virtual zmm::Ref<SQLResult> select(const char *query, int length) override;
+    virtual int exec(const char *query, int length, bool getLastInsertId = false) override;
+    virtual void storeInternalSetting(zmm::String key, zmm::String value) override;
+
     void _exec(const char *query);
     
     zmm::String startupError;
@@ -176,8 +181,10 @@ private:
     void addTask(zmm::Ref<SLTask> task, bool onlyIfDirty = false);
     
     pthread_t sqliteThread;
-    zmm::Ref<Cond> cond;
-    zmm::Ref<Mutex> sqliteMutex;
+    std::condition_variable cond;
+    std::mutex sqliteMutex;
+    using AutoLock = std::lock_guard<decltype(sqliteMutex)>;
+    using AutoLockU = std::unique_lock<decltype(sqliteMutex)>;
     
     /// \brief is set to true by shutdown() if the sqlite3 thread should terminate
     bool shutdownFlag;
@@ -186,17 +193,15 @@ private:
     zmm::Ref<zmm::ObjectQueue<SLTask> > taskQueue;
     bool taskQueueOpen;
     
-    virtual void threadCleanup() {}
-    virtual bool threadCleanupRequired() { return false; }
-    
-    inline void signal() { cond->signal(); }
+    virtual void threadCleanup() override {}
+    virtual bool threadCleanupRequired() override { return false; }
     
     zmm::Ref<zmm::StringBuffer> insertBuffer;
-    virtual void _addToInsertBuffer(zmm::Ref<zmm::StringBuffer> query);
-    virtual void _flushInsertBuffer();
+    virtual void _addToInsertBuffer(zmm::Ref<zmm::StringBuffer> query) override;
+    virtual void _flushInsertBuffer() override;
     
     bool dirty;
-    
+
     friend class SLSelectTask;
     friend class SLExecTask;
     friend class SLInitTask;
@@ -209,8 +214,8 @@ class Sqlite3Result : public SQLResult
 private:
     Sqlite3Result();
     virtual ~Sqlite3Result();
-    virtual zmm::Ref<SQLRow> nextRow();
-    virtual unsigned long long getNumRows() { return nrow; }
+    virtual zmm::Ref<SQLRow> nextRow() override;
+    virtual unsigned long long getNumRows() override { return nrow; }
     
     char **table;
     char **row;
@@ -237,12 +242,6 @@ private:
     friend class Sqlite3Result;
 };
 
-class Sqlite3BackupTimerSubscriber : public TimerSubscriberObject
-{
-    /// \brief for making backups in regulary intervals - see TimerSubscriber
-    virtual void timerNotify(zmm::Ref<zmm::Object> sqlite3storage);
-};
-
 #endif // __SQLITE3_STORAGE_H__
 
 #endif // HAVE_SQLITE3
diff --git a/src/storage/storage_cache.cc b/src/storage/storage_cache.cc
index 23cdef7..80d5179 100644
--- a/src/storage/storage_cache.cc
+++ b/src/storage/storage_cache.cc
@@ -29,27 +29,25 @@
 
 /// \file storage_cache.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
+#include <cassert>
 
 #include "storage_cache.h"
 
 using namespace zmm;
+using namespace std;
 
 StorageCache::StorageCache()
 {
     capacity = STORAGE_CACHE_CAPACITY;
     maxfill = STORAGE_CACHE_MAXFILL;
-    idHash = Ref<DBOHash<int,CacheObject> >(new DBOHash<int,CacheObject>(capacity, INVALID_OBJECT_ID, INVALID_OBJECT_ID_2));
-    locationHash = Ref<DSOHash<Array<CacheObject> > >(new DSOHash<Array<CacheObject> >(capacity));
+    idHash = make_shared<unordered_map<int,Ref<CacheObject> > >();
+    locationHash = make_shared<unordered_map<zmm::String, Ref<Array<CacheObject> > > >();
     hasBeenFlushed = false;
-    mutex = Ref<Mutex> (new Mutex());
 }
 
 void StorageCache::clear()
 {
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     idHash->clear();
     locationHash->clear();
 }
@@ -57,22 +55,27 @@ void StorageCache::clear()
 Ref<CacheObject> StorageCache::getObject(int id)
 {
 #ifdef TOMBDEBUG
-    assert(mutex->isLocked());
+    //assert(mutex->isLocked());
 #endif
-    return idHash->get(id);
+    try {
+        return idHash->at(id);
+    } catch(out_of_range& nope) {
+        return nullptr;
+    }
 }
 
 Ref<CacheObject> StorageCache::getObjectDefinitely(int id)
 {
 #ifdef TOMBDEBUG
-    assert(mutex->isLocked());
+    //assert(mutex->isLocked());
 #endif
-    Ref<CacheObject> obj = idHash->get(id);
-    if (obj == nil)
-    {
+    Ref<CacheObject> obj = nullptr;
+    try {
+        obj = idHash->at(id);
+    } catch (const out_of_range& ex) {
         ensureFillLevelOk();
         obj = Ref<CacheObject>(new CacheObject());
-        idHash->put(id, obj);
+        idHash->emplace(id, obj);
     }
     return obj;
 }
@@ -80,55 +83,58 @@ Ref<CacheObject> StorageCache::getObjectDefinitely(int id)
 void StorageCache::addChild(int id)
 {
 #ifdef TOMBDEBUG
-    assert(mutex->isLocked());
+    //assert(mutex->isLocked());
 #endif
-    Ref<CacheObject> obj = idHash->get(id);
-    if (obj != nil && obj->knowsNumChildren())
-    {
-        obj->setNumChildren(obj->getNumChildren() + 1);
-    }
+    Ref<CacheObject> obj = nullptr;
+    try {
+        obj = idHash->at(id);
+        if (obj->knowsNumChildren())
+            obj->setNumChildren(obj->getNumChildren() + 1);
+    } catch(const out_of_range& ex) {} // id not found
 }
 
 bool StorageCache::removeObject(int id)
 {
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     Ref<CacheObject> obj = getObject(id);
-    if (obj == nil)
+    if (obj == nullptr)
         return false;
     if (obj->knowsLocation())
-        locationHash->remove(obj->getLocation());
-    return idHash->remove(id);
+        locationHash->erase(obj->getLocation());
+    return idHash->erase(id);
 }
 
 Ref<Array<CacheObject> > StorageCache::getObjects(String location)
 {
 #ifdef TOMBDEBUG
-    assert(mutex->isLocked());
+    //assert(mutex->isLocked());
 #endif
-    return locationHash->get(location);
+    try {
+        return locationHash->at(location);
+    } catch (const out_of_range& ex) {
+        return nullptr;
+    }
 }
 
 void StorageCache::checkLocation(Ref<CacheObject> obj)
 {
 #ifdef TOMBDEBUG
-    assert(mutex->isLocked());
+    //assert(mutex->isLocked());
 #endif
     if (! obj->knowsLocation())
         return;
     String location = obj->getLocation();
-    Ref<Array<CacheObject> > objects = locationHash->get(location);
-    if (objects == nil)
-    {
-        objects = Ref<Array<CacheObject> >(new Array<CacheObject>());
-        locationHash->put(location, objects);
-    }
-    else
-    {
+    Ref<Array<CacheObject> > objects = nullptr;
+    try {
+        objects = locationHash->at(location);
         for (int i=0;i<objects->size();i++)
         {
             if (objects->get(i) == obj)
                 return;
         }
+    } catch (const out_of_range& ex) {
+        objects = Ref<Array<CacheObject> >(new Array<CacheObject>());
+        locationHash->emplace(location, objects);
     }
     objects->append(obj);
 }
@@ -146,7 +152,7 @@ bool StorageCache::flushed()
 void StorageCache::ensureFillLevelOk()
 {
 #ifdef TOMBDEBUG
-    assert(mutex->isLocked());
+    //assert(mutex->isLocked());
 #endif
     // TODO - much better...
     // for now just clear cache if it gets too full
diff --git a/src/storage/storage_cache.h b/src/storage/storage_cache.h
index ac50b22..289d89f 100644
--- a/src/storage/storage_cache.h
+++ b/src/storage/storage_cache.h
@@ -32,14 +32,16 @@
 #ifndef __STORAGE_CACHE_H__
 #define __STORAGE_CACHE_H__
 
-#include "zmmf/zmmf.h"
+#include <memory>
+#include <unordered_map>
+#include <mutex>
+
+#include "zmm/zmmf.h"
 #include "common.h"
-#include "hash.h"
-#include "sync.h"
 #include "cache_object.h"
 
-#define STORAGE_CACHE_CAPACITY 29989
-#define STORAGE_CACHE_MAXFILL 9973
+#define STORAGE_CACHE_CAPACITY 29989u
+#define STORAGE_CACHE_MAXFILL 9973u
 
 class StorageCache : public zmm::Object
 {
@@ -60,19 +62,20 @@ public:
     
     bool flushed();
     
-    zmm::Ref<Mutex> getMutex() { return mutex; }
+    std::mutex & getMutex() { return mutex; }
     
 private:
     
     int capacity;
-    int maxfill;
+    unsigned int maxfill;
     bool hasBeenFlushed;
     
     void ensureFillLevelOk();
     
-    zmm::Ref<DBOHash<int,CacheObject> > idHash;
-    zmm::Ref<DSOHash<zmm::Array<CacheObject> > > locationHash;
-    zmm::Ref<Mutex> mutex;
+    std::shared_ptr<std::unordered_map<int,zmm::Ref<CacheObject> > > idHash;
+    std::shared_ptr<std::unordered_map<zmm::String, zmm::Ref<zmm::Array<CacheObject> > > > locationHash;
+    std::mutex mutex;
+    using AutoLock = std::lock_guard<std::mutex>;
 };
 
 #endif // __STORAGE_CACHE_H__
diff --git a/src/string_converter.cc b/src/string_converter.cc
index 6c61c64..b0b1f20 100644
--- a/src/string_converter.cc
+++ b/src/string_converter.cc
@@ -29,10 +29,6 @@
 
 /// \file string_converter.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "string_converter.h"
 #include "config_manager.h"
 
@@ -45,14 +41,14 @@ StringConverter::StringConverter(String from, String to) : Object()
     cd = iconv_open(to.c_str(), from.c_str());
     if (cd == (iconv_t)(-1))
     {
-        cd = (iconv_t)(0);
+        cd = (iconv_t)nullptr;
         throw _Exception(_("iconv: ") + strerror(errno));
     }
 }
 
 StringConverter::~StringConverter()
 {
-    if (cd != (iconv_t)(0))
+    if (cd != (iconv_t)nullptr)
         iconv_close(cd);
 }
 
@@ -89,7 +85,7 @@ bool StringConverter::validate(String str)
         _convert(str, true);
         return true;
     }
-    catch (Exception e)
+    catch (const Exception & e)
     {
         return false;
     }
@@ -102,39 +98,39 @@ zmm::String StringConverter::_convert(String str, bool validate,
 
     int buf_size = str.length() * 4;
 
-    char *input = str.c_str();
-    char *output = (char *)MALLOC(buf_size);
+    const char *input = str.c_str();
+    auto *output = (char *)MALLOC(buf_size);
     if (!output)
     {
         log_debug("Could not allocate memory for string conversion!\n");
         throw _Exception(_("Could not allocate memory for string conversion!"));
     }
 
-    char *input_copy = input;
+    const char *input_copy = input;
     char *output_copy = output;
     
-    char **input_ptr = &input_copy;
+    const char **input_ptr = &input_copy;
     char **output_ptr = &output_copy;
    
-    size_t input_bytes = (size_t)str.length();
-    size_t output_bytes = (size_t)buf_size;
+    auto input_bytes = (size_t)str.length();
+    auto output_bytes = (size_t)buf_size;
 
     int ret;
   
     // reset to initial state
     if (dirty)
     {
-        iconv(cd, NULL, 0, NULL, 0);
+        iconv(cd, nullptr, nullptr, nullptr, nullptr);
         dirty = false;
     }
     
     //log_debug(("iconv: BEFORE: input bytes left: %d  output bytes left: %d\n",
     //       input_bytes, output_bytes));
 #if defined(ICONV_CONST) || defined(SOLARIS)
-    ret = iconv(cd, (const char**)input_ptr, &input_bytes,
+    ret = iconv(cd, input_ptr, &input_bytes,
             output_ptr, &output_bytes);
 #else
-    ret = iconv(cd, input_ptr, &input_bytes,
+    ret = iconv(cd, (char**)input_ptr, &input_bytes,
             output_ptr, &output_bytes);
 #endif
 
diff --git a/src/subscription_request.cc b/src/subscription_request.cc
index f1af81f..7f55998 100644
--- a/src/subscription_request.cc
+++ b/src/subscription_request.cc
@@ -29,23 +29,19 @@
 
 /// \file subscription_request.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "mxml/mxml.h"
 #include "subscription_request.h"
 
 using namespace zmm;
 using namespace mxml;
 
-SubscriptionRequest::SubscriptionRequest(Upnp_Subscription_Request *upnp_request) : Object()
+SubscriptionRequest::SubscriptionRequest(UpnpSubscriptionRequest *upnp_request) : Object()
 {
     this->upnp_request = upnp_request;
 
-    serviceID = upnp_request->ServiceId;
-    UDN = upnp_request->UDN;
-    sID = upnp_request->Sid;
+    serviceID = UpnpSubscriptionRequest_get_ServiceId_cstr(upnp_request);
+    UDN = UpnpSubscriptionRequest_get_UDN_cstr(upnp_request);
+    sID = UpnpSubscriptionRequest_get_SID_cstr(upnp_request);
 }
 
 String SubscriptionRequest::getServiceID()
diff --git a/src/subscription_request.h b/src/subscription_request.h
index e9aefbe..e956d54 100644
--- a/src/subscription_request.h
+++ b/src/subscription_request.h
@@ -33,8 +33,10 @@
 #ifndef __SUBSCRIPTION_REQUEST_H__
 #define __SUBSCRIPTION_REQUEST_H__
 
+#include <upnp-1.8/upnp.h>
+
 #include "common.h"
-#include "upnp.h"
+
 
 /// \brief This class represents the Upnp_Subscription_Request type from the SDK.
 ///
@@ -45,7 +47,7 @@ class SubscriptionRequest : public zmm::Object
 {
 protected:
     /// \brief Upnp_Subscription_Request that comes from the SDK.
-    Upnp_Subscription_Request *upnp_request;
+    UpnpSubscriptionRequest *upnp_request;
 
     /// \brief ID of the service.
     ///
@@ -65,7 +67,7 @@ protected:
 public:
     /// \brief The Constructor takes the values from the upnp_request and fills in internal variables.
     /// \param *upnp_request Pointer to the Upnp_Subscription_Request structure.
-    SubscriptionRequest(Upnp_Subscription_Request *upnp_request);
+    SubscriptionRequest(UpnpSubscriptionRequest *upnp_request);
 
     /// \brief Returns the service ID (should be one of the services that we support).
     zmm::String getServiceID();
diff --git a/src/sync.cc b/src/sync.cc
deleted file mode 100644
index ff8e137..0000000
--- a/src/sync.cc
+++ /dev/null
@@ -1,217 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    sync.cc - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file sync.cc
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include "sync.h"
-
-using namespace zmm;
-
-/* Mutex */
-
-Mutex::Mutex(bool recursive) : Object()
-{
-#ifdef TOMBDEBUG
-    this->recursive = recursive;
-    lock_level = 0;
-    
-    pthread_mutexattr_t mutex_attr;
-    pthread_mutexattr_init(&mutex_attr);
-    pthread_mutexattr_settype(&mutex_attr, (recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_ERRORCHECK));
-    pthread_mutex_init(&mutex_struct, &mutex_attr);
-    pthread_mutexattr_destroy(&mutex_attr);
-#else
-    if (recursive)
-    {
-        pthread_mutexattr_t mutex_attr;
-        pthread_mutexattr_init(&mutex_attr);
-        pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE);
-        pthread_mutex_init(&mutex_struct, &mutex_attr);
-        pthread_mutexattr_destroy(&mutex_attr);
-    }
-    else
-        pthread_mutex_init(&mutex_struct, NULL);
-#endif
-}
-
-Mutex::~Mutex()
-{
-    pthread_mutex_destroy(&mutex_struct);
-}
-
-#ifdef TOMBDEBUG
-void Mutex::lock()
-{
-    pthread_mutex_lock(&mutex_struct);
-    pthread_t this_thread = pthread_self();
-    if (lock_level && ! recursive && this_thread == locking_thread)
-        errorExit(_("same thread tried to lock non-recursive mutex twice"));
-    doLock(false);
-    autolock = false;
-}
-
-void Mutex::unlock(bool autolock)
-{
-    if (! recursive && autolock != this->autolock)
-    {
-        if (autolock)
-            errorExit(_("unlock() called by autolock, but not locked by getAutolock()?? - seems to be an error in sync.cc..."));
-        else
-            errorExit(_("unlock() called, but locked by an getAutolock()!"));
-    }
-    pthread_t this_thread = pthread_self();
-    if (lock_level <= 0)
-     errorExit(_("tried to unlock not locked mutex"));
-    if (this_thread != locking_thread)
-     errorExit(_("a different thread tried to unlock the locked mutex"));
-    doUnlock(false);
-    pthread_mutex_unlock(&mutex_struct);
-}
-
-
-void Mutex::errorExit(String error)
-{
-    printf("%s\n", error.c_str());
-    print_backtrace();
-    abort();
-}
-
-void Mutex::unlockAutolock()
-{
-    unlock(true);
-}
-
-void Mutex::doLock(bool cond)
-{
-    lock_level++;
-    if (! recursive && lock_level > 1)
-        errorExit(_("managed to lock a non-recursive thread twice? cond: ") + cond);
-    locking_thread = pthread_self();
-}
-
-void Mutex::doUnlock(bool cond)
-{
-    if (cond && recursive && lock_level != 1)
-        errorExit(_("tried to unlock a recursive mutex via a cond->wait() or cond->timedwait() call, which is locked more than once - is this correct?"));
-    if (--lock_level < 0)
-        errorExit(_("unlocked a thread somehow, but it wasn't locked. cond: ") + cond);
-}
-
-#endif // TOMBDEBUG
-
-/* Cond */
-
-Cond::Cond(Ref<Mutex> mutex) : Object()
-{
-    this->mutex = mutex;
-    pthread_cond_init(&cond_struct, NULL);
-}
-
-Cond::~Cond()
-{
-    pthread_cond_destroy(&cond_struct);
-}
-
-#ifdef TOMBDEBUG
-void Cond::wait()
-{
-    bool autolock_save = mutex->autolock;
-    mutex->doUnlock(true);
-    pthread_cond_wait(&cond_struct, mutex->getMutex());
-    mutex->doLock(true);
-    mutex->autolock = autolock_save;
-}
-
-int Cond::timedwait(struct timespec *timeout)
-{
-    mutex->doUnlock(true);
-    int ret = pthread_cond_timedwait(&cond_struct, mutex->getMutex(), timeout);
-    mutex->doLock(true);
-    return ret;
-}
-
-/*
-void Cond::checkwait()
-{
-    if (! mutex->isLocked())
-        mutex->errorExit(_("tried to do a cond_wait with an unlocked mutex"));
-    if (mutex->lock_level > 1)
-        mutex->errorExit(_("pthread_cond(timed)wait called for a (recursive) mutex, that is locked more than once!"));
-    pthread_t this_thread = pthread_self();
-    pthread_t mutex_thread = mutex->getLockingThread();
-    if (this_thread != mutex_thread)
-        mutex->errorExit(_("tried to do a cond_wait with a mutex locked by another thread"));
-}
-*/
-#endif // TOMBDEBUG
-
-
-MutexAutolock::MutexAutolock(Ref<Mutex> mutex, bool unlocked)
-{
-    this->mutex = mutex;
-#ifdef TOMBDEBUG
-    if (! unlocked)
-        mutex->lockAutolock();
-#else
-    pmutex = mutex->getMutex();
-    if (! unlocked)
-        pthread_mutex_lock(pmutex);
-#endif
-    locked = ! unlocked;
-}
-
-#ifdef TOMBDEBUG
-MutexAutolock::~MutexAutolock()
-{
-    if (locked)
-        mutex->unlockAutolock();
-}
-
-void MutexAutolock::unlock()
-{
-    if (locked)
-        mutex->unlockAutolock();
-    else
-        mutex->errorExit(_("tried to unlock a not-locked autolock"));
-    locked = false;
-}
-
-void MutexAutolock::relock()
-{
-    if (! locked)
-        mutex->lockAutolock();
-    else
-        mutex->errorExit(_("tried to relock a locked autolock"));
-    locked = true;
-}
-#endif
diff --git a/src/sync.h b/src/sync.h
deleted file mode 100644
index 02691ad..0000000
--- a/src/sync.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    sync.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file sync.h
-
-#ifndef __SYNC_H__
-#define __SYNC_H__
-
-#include "common.h"
-#include <pthread.h>
-
-#define AUTOLOCK_DEFINE_ONLY() zmm::Ref<MutexAutolock> mutex_autolock;
-#define AUTOLOCK_NOLOCK(mutex) zmm::Ref<MutexAutolock> mutex_autolock = mutex->getAutolock(true);
-#define AUTOLOCK(mutex) zmm::Ref<MutexAutolock> mutex_autolock = mutex->getAutolock();
-#define AUTOLOCK_NO_DEFINE(mutex) mutex_autolock = mutex->getAutolock();
-#define AUTOUNLOCK() mutex_autolock->unlock();
-#define AUTORELOCK() mutex_autolock->relock();
-#define LOCK(mutex) mutex->lock();
-#define UNLOCK(mutex) mutex->unlock();
-
-class Mutex;
-
-class MutexAutolock : public zmm::Object
-{
-public:
-    
-#ifndef TOMBDEBUG
-    inline ~MutexAutolock() { if (locked) pthread_mutex_unlock(pmutex); }
-    inline void unlock() { pthread_mutex_unlock(pmutex); locked = false; }
-    inline void relock() { pthread_mutex_lock(pmutex); locked = true; }
-#else
-    ~MutexAutolock();
-    void unlock();
-    void relock();
-#endif
-protected:
-    MutexAutolock(zmm::Ref<Mutex> mutex, bool unlocked = false);
-    zmm::Ref<Mutex> mutex;
-    bool locked;
-#ifndef TOMBDEBUG
-    pthread_mutex_t *pmutex;
-#endif
-    
-    friend class Mutex;
-};
-
-class Mutex : public zmm::Object
-{
-public:
-    Mutex(bool recursive = false);
-    virtual ~Mutex();
-#ifndef TOMBDEBUG
-    inline void lock() { pthread_mutex_lock(&mutex_struct); }
-    inline void unlock() { pthread_mutex_unlock(&mutex_struct); }
-#else
-    void lock();
-    void unlock(bool autolock = false);
-#endif
-    inline zmm::Ref<MutexAutolock> getAutolock(bool unlocked = false) { return zmm::Ref<MutexAutolock>(new MutexAutolock(zmm::Ref<Mutex>(this), unlocked)); }
-protected:
-    pthread_mutex_t mutex_struct;
-    inline pthread_mutex_t* getMutex() { return &mutex_struct; }
-    
-#ifdef TOMBDEBUG
-    void errorExit(zmm::String error);
-    inline pthread_t getLockingThread() { return locking_thread; }
-    void doLock(bool cond);
-    void doUnlock(bool cond);
-public:
-    inline bool isLocked() { return lock_level > 0; }
-protected:
-    inline void lockAutolock() { lock(); autolock = true; }
-    void unlockAutolock();
-    int lock_level;
-    bool recursive;
-    bool autolock;
-    pthread_t locking_thread;
-#endif
-    
-    friend class MutexAutolock;
-    friend class Cond;
-};
-
-class Cond : public zmm::Object
-{
-public:
-    Cond(zmm::Ref<Mutex> mutex);
-    virtual ~Cond();
-    inline void signal() { pthread_cond_signal(&cond_struct); }
-    inline void broadcast() { pthread_cond_broadcast(&cond_struct); }
-#ifndef TOMBDEBUG
-    inline void wait() { pthread_cond_wait(&cond_struct, mutex->getMutex()); }
-    inline int timedwait(struct timespec *timeout) { return pthread_cond_timedwait(&cond_struct, mutex->getMutex(), timeout); }
-#else
-    void wait();
-    int timedwait(struct timespec *timeout);
-    //void checkwait();
-#endif
-protected:
-    pthread_cond_t cond_struct;
-    zmm::Ref<Mutex> mutex;
-};
-
-#endif // __SYNC_H__
diff --git a/src/task_processor.cc b/src/task_processor.cc
index a8dc619..01720ff 100644
--- a/src/task_processor.cc
+++ b/src/task_processor.cc
@@ -1,10 +1,6 @@
 /*MT*
 */
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef ONLINE_SERVICES
 
 #include "task_processor.h"
@@ -14,16 +10,11 @@
 #define TP_INITIAL_QUEUE_SIZE 4
 
 using namespace zmm;
+using namespace std;
 
-SINGLETON_MUTEX(TaskProcessor, false);
-
-TaskProcessor::TaskProcessor() : Singleton<TaskProcessor>()
+TaskProcessor::TaskProcessor() : Singleton<TaskProcessor>(),
+    taskThread(0), shutdownFlag(false), working(false), taskID(1)
 {
-    cond = Ref<Cond>(new Cond(mutex));
-    taskID = 1;
-    working = false;
-    shutdownFlag = false;
-
     taskQueue = Ref<ObjectQueue<GenericTask> >(new ObjectQueue<GenericTask>(TP_INITIAL_QUEUE_SIZE));
 }
 
@@ -31,7 +22,7 @@ void TaskProcessor::init()
 {
     int ret;
 
-    ret = pthread_create(&taskThread, NULL, TaskProcessor::staticThreadProc,
+    ret = pthread_create(&taskThread, nullptr, TaskProcessor::staticThreadProc,
           this);
 
     if (ret != 0)
@@ -44,34 +35,33 @@ void TaskProcessor::shutdown()
 {
     log_debug("Shutting down TaskProcessor\n");
     shutdownFlag = true;
-    cond->signal();
+    cond.notify_one();
     if (taskThread)
-        pthread_join(taskThread, NULL);
+        pthread_join(taskThread, nullptr);
     taskThread = 0;
 }
 
 void *TaskProcessor::staticThreadProc(void *arg)
 {
-    TaskProcessor *inst = (TaskProcessor *)arg;
+    auto *inst = (TaskProcessor *)arg;
     inst->threadProc();
-    pthread_exit(NULL);
-    return NULL;
+    pthread_exit(nullptr);
+    return nullptr;
 }
 
 void TaskProcessor::threadProc()
 {
     Ref<GenericTask> task;
-    //Ref<TaskProcessor> this_ref(this);
-    AUTOLOCK(mutex);
+    unique_lock<mutex_type> lock(mutex);
     working = true;
 
     while (!shutdownFlag)
     {
-        currentTask = nil;
-        if ((task = taskQueue->dequeue()) == nil)
+        currentTask = nullptr;
+        if ((task = taskQueue->dequeue()) == nullptr)
         {
             working = false;
-            cond->wait();
+            cond.wait(lock);
             working = true;
             continue;
         }
@@ -79,18 +69,18 @@ void TaskProcessor::threadProc()
         {
             currentTask = task;
         }
-        AUTOUNLOCK();
+        lock.unlock();
 
         try
         {
             if (task->isValid())
                 task->run();
         }
-        catch (ServerShutdownException se)
+        catch (const ServerShutdownException & se)
         {
             shutdownFlag = true;
         }
-        catch (Exception e)
+        catch (const Exception & e)
         {
             log_error("Exception caught: %s\n", e.getMessage().c_str());
             e.printStackTrace();
@@ -98,25 +88,25 @@ void TaskProcessor::threadProc()
 
         if (!shutdownFlag)
         {
-            AUTORELOCK();
+            lock.lock();
         }
     }
 }
 
 void TaskProcessor::addTask(Ref<GenericTask> task)
 {
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
 
     task->setID(taskID++);
 
     taskQueue->enqueue(task);
-    cond->signal();
+    cond.notify_one();
 }
 
 Ref<GenericTask> TaskProcessor::getCurrentTask()
 {
     Ref<GenericTask> task;
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     task = currentTask;
     return task;
 }
@@ -125,9 +115,9 @@ void TaskProcessor::invalidateTask(unsigned int taskID)
 {
     int i;
 
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     Ref<GenericTask> t = getCurrentTask();
-    if (t != nil)
+    if (t != nullptr)
     {
         if ((t->getID() == taskID) || (t->getParentID() == taskID))
         {
@@ -150,15 +140,15 @@ void TaskProcessor::invalidateTask(unsigned int taskID)
 Ref<Array<GenericTask> > TaskProcessor::getTasklist()
 {
     int i;
-    Ref<Array<GenericTask> > taskList = nil;
+    Ref<Array<GenericTask> > taskList = nullptr;
 
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     Ref<GenericTask> t = getCurrentTask();
 
     // if there is no current task, then the queues are empty
     // and we do not have to allocate the array
-    if (t == nil)
-        return nil;
+    if (t == nullptr)
+        return nullptr;
 
     taskList = Ref<Array<GenericTask> >(new Array<GenericTask>());
     taskList->append(t);
@@ -192,7 +182,7 @@ TPFetchOnlineContentTask::TPFetchOnlineContentTask(Ref<OnlineService> service,
 
 void TPFetchOnlineContentTask::run()
 {
-    if (this->service == nil)
+    if (this->service == nullptr)
     {
         log_debug("No service specified\n");
         return;
@@ -217,7 +207,7 @@ void TPFetchOnlineContentTask::run()
             ContentManager::getInstance()->cleanupOnlineServiceObjects(service);
         }
     }
-    catch (Exception ex)
+    catch (const Exception & ex)
     {
         log_error("%s\n", ex.getMessage().c_str());
     }
@@ -226,7 +216,8 @@ void TPFetchOnlineContentTask::run()
     {
         if ((service->getRefreshInterval() > 0) && !unscheduled_refresh)
         {
-            Timer::getInstance()->addTimerSubscriber(AS_TIMER_SUBSCRIBER_SINGLETON_FROM_REF(ContentManager::getInstance()),
+            Timer::getInstance()->addTimerSubscriber(
+                    ContentManager::getInstance().getPtr(),
                     service->getRefreshInterval(),
                     service->getTimerParameter(), true);
         }
diff --git a/src/task_processor.h b/src/task_processor.h
index edc4c3f..af254d4 100644
--- a/src/task_processor.h
+++ b/src/task_processor.h
@@ -4,8 +4,8 @@
 #ifndef __TASK_PROCESSOR_H__
 #define __TASK_PROCESSOR_H__
 
+#include <condition_variable>
 #include "common.h"
-#include "sync.h"
 #include "online_service.h"
 #include "singleton.h"
 #include "generic_task.h"
@@ -13,7 +13,7 @@
 class TPFetchOnlineContentTask : public GenericTask
 {
 public:
-    TPFetchOnlineContentTask(zmm::Ref<OnlineService> service, 
+    TPFetchOnlineContentTask(zmm::Ref<OnlineService> service,
                              zmm::Ref<Layout> layout, bool cancellable,
                              bool unscheduled_refresh);
     virtual void run();
@@ -27,7 +27,7 @@ protected:
 
 class TaskProcessor : public Singleton<TaskProcessor>
 {
-public:    
+public:
     TaskProcessor();
     virtual ~TaskProcessor();
     void addTask(zmm::Ref<GenericTask> task);
@@ -39,7 +39,7 @@ public:
 
 protected:
     pthread_t taskThread;
-    zmm::Ref<Cond> cond;
+    std::condition_variable cond;
     bool shutdownFlag;
     bool working;
     unsigned int taskID;
diff --git a/src/thread_executor.cc b/src/thread_executor.cc
index 4cdc643..61a6edc 100644
--- a/src/thread_executor.cc
+++ b/src/thread_executor.cc
@@ -29,20 +29,13 @@
 
 /// \file thread_executor.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "thread_executor.h"
 
 using namespace zmm;
+using namespace std;
 
-ThreadExecutor::ThreadExecutor()
+ThreadExecutor::ThreadExecutor() : threadShutdown(false), thread(0)
 {
-    mutex = Ref<Mutex>(new Mutex());
-    cond = Ref<Cond>(new Cond(mutex));
-    
-    threadShutdown = false;
 }
 
 ThreadExecutor::~ThreadExecutor()
@@ -55,7 +48,7 @@ void ThreadExecutor::startThread()
     threadRunning = true;
     pthread_create(
         &thread,
-        NULL, // attr
+        nullptr, // attr
         ThreadExecutor::staticThreadProc,
         this
     );
@@ -65,22 +58,24 @@ bool ThreadExecutor::kill()
 {
     if (! threadRunning)
         return true;
-    AUTOLOCK(mutex);
+
+    unique_lock<std::mutex> lock(mutex);
     threadShutdown = true;
-    cond->signal();
-    AUTOUNLOCK();
+    cond.notify_one();
+    lock.unlock();
+
     if (thread)
     {
         threadRunning = false;
-        pthread_join(thread, NULL);
+        pthread_join(thread, nullptr);
     }
     return true;
 }
 
 void *ThreadExecutor::staticThreadProc(void *arg)
 {
-    ThreadExecutor *inst = (ThreadExecutor *)arg;
+    auto *inst = (ThreadExecutor *)arg;
     inst->threadProc();
-    pthread_exit(NULL);
-    return NULL;
+    pthread_exit(nullptr);
+    return nullptr;
 }
diff --git a/src/thread_executor.h b/src/thread_executor.h
index 06127ba..d85efe4 100644
--- a/src/thread_executor.h
+++ b/src/thread_executor.h
@@ -33,10 +33,11 @@
 #define __THREAD_EXECUTOR_H__
 
 #include <pthread.h>
+#include <mutex>
+#include <condition_variable>
 
 #include "common.h"
 #include "executor.h"
-#include "sync.h"
 
 /// \brief an executor which runs a thread
 class ThreadExecutor : public Executor
@@ -59,8 +60,8 @@ protected:
     /// \brief if the thread is currently running
     bool threadRunning;
 
-    zmm::Ref<Cond> cond;
-    zmm::Ref<Mutex> mutex;
+    std::condition_variable cond;
+    std::mutex mutex;
     
     /// \brief abstract thread method, which needs to be overridden
     virtual void threadProc() = 0;
diff --git a/src/timer.cc b/src/timer.cc
index dd7fa52..b920c2a 100644
--- a/src/timer.cc
+++ b/src/timer.cc
@@ -29,93 +29,140 @@
 
 /// \file timer.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
+#include "singleton.h"
 #include "timer.h"
 
 using namespace zmm;
+using namespace std;
+
+void Timer::init() {
+    log_debug("Starting Timer thread...\n");
+    int ret = pthread_create(
+        &thread,
+        nullptr,
+        Timer::staticThreadProc,
+        this
+    );
 
-SINGLETON_MUTEX(Timer, true);
+    if (ret)
+        throw _Exception(_("failed to start timer thread: ") + ret);
+}
 
-template <>
-Ref<Array<Timer::TimerSubscriberElement<TimerSubscriberSingleton<Object> > > > Timer::getAppropriateSubscribers<TimerSubscriberSingleton<Object> >()
+void *Timer::staticThreadProc(void *arg)
 {
-    if (subscribersSingleton == nil)
-        throw _Exception(_("timer already inactive!"));
-    return subscribersSingleton;
+    log_debug("Started Timer thread.\n");
+    auto *inst = (Timer *)arg;
+    inst->threadProc();
+    log_debug("Exiting Timer thread...\n");
+    pthread_exit(nullptr);
+}
+
+void Timer::threadProc() {
+    triggerWait();
 }
 
-template <>
-Ref<Array<Timer::TimerSubscriberElement<TimerSubscriberObject> > > Timer::getAppropriateSubscribers<TimerSubscriberObject>()
+void Timer::addTimerSubscriber(Subscriber* timerSubscriber, unsigned int notifyInterval, zmm::Ref<Parameter> parameter, bool once)
 {
-    if (subscribersObject == nil)
-        throw _Exception(_("timer already inactive!"));
-    return subscribersObject;
+    log_debug("Adding subscriber... interval: %d once: %d \n", notifyInterval, once);
+    if (notifyInterval == 0)
+        throw zmm::Exception(_("Tried to add timer with illegal notifyInterval: ") + notifyInterval);
+
+    AutoLock lock(mutex);
+    TimerSubscriberElement element(timerSubscriber, notifyInterval, parameter, once);
+    for (auto& subscriber : subscribers) {
+        if (subscriber == element) {
+            throw zmm::Exception(_("Tried to add same timer twice"));
+        }
+    }
+    subscribers.push_back(element);
+    signal();
 }
 
-Timer::Timer() : Singleton<Timer>()
+void Timer::removeTimerSubscriber(Subscriber* timerSubscriber, zmm::Ref<Parameter> parameter, bool dontFail)
 {
-    subscribersSingleton = Ref<Array<TimerSubscriberElement<TimerSubscriberSingleton<Object> > > >(new Array<TimerSubscriberElement<TimerSubscriberSingleton<Object> > >);
-    subscribersObject = Ref<Array<TimerSubscriberElement<TimerSubscriberObject> > >(new Array<TimerSubscriberElement<TimerSubscriberObject> >);
-    cond = Ref<Cond>(new Cond(mutex));
+    log_debug("Removing subscriber...\n");
+    AutoLock lock(mutex);
+    TimerSubscriberElement element(timerSubscriber, 0, parameter);
+    auto it = std::find(subscribers.cbegin(), subscribers.cend(), element);
+    if (it != subscribers.cend()) {
+        subscribers.erase(it);
+        signal();
+    } else if (!dontFail) {
+        throw zmm::Exception(_("Tried to remove nonexistent timer"));
+    }
 }
 
 void Timer::triggerWait()
 {
-    log_debug("triggerWait. - %d subscriber(s)\n", subscribersSingleton->size());
-    
-    AUTOLOCK(mutex);
-    if (subscribersSingleton->size() > 0 || subscribersObject->size() > 0)
-    {
+    unique_lock<std::mutex> lock(waitMutex);
+
+    while(!shutdownFlag) {
+        log_debug("triggerWait. - %d subscriber(s)\n", subscribers.size());
+
+        if (subscribers.empty()) {
+            log_debug("Nothing to do, sleeping...\n");
+            cond.wait(lock);
+        }
+
         struct timespec *timeout = getNextNotifyTime();
         struct timespec now;
         getTimespecNow(&now);
-        if (compareTimespecs(timeout, &now) < 0)
-        {
-            log_debug("sleeping...\n");
-            int ret = cond->timedwait(timeout);
-            if (ret != 0 && ret != ETIMEDOUT)
-            {
-                log_debug("pthread_cond_timedwait returned errorcode %d\n", ret);
-                throw _Exception(_("pthread_cond_timedwait returned errorcode ") + ret);
-            }
-            if (ret == ETIMEDOUT)
-            {
-                notify<TimerSubscriberSingleton<Object> >();
-                notify<TimerSubscriberObject>();
+
+        long wait = getDeltaMillis(&now, timeout);
+        if (wait > 0) {
+            cv_status ret = cond.wait_for(lock, chrono::milliseconds(wait));
+            if (ret != cv_status::timeout) {
+                /*
+                 * Some rude thread woke us!
+                 * Now we have to wait all over again...
+                 */
+                continue;
             }
         }
-        else
-        {
-            notify<TimerSubscriberSingleton<Object> >();
-            notify<TimerSubscriberObject>();
-        }
-    }
-    else
-    {
-        log_debug("nothing to do, sleeping...\n");
-        cond->wait();
+        notify();
     }
 }
 
-struct timespec * Timer::getNextNotifyTime()
+void  Timer::notify()
 {
-    struct timespec *nextTime = NULL;
-    for(int i = 0; i < subscribersSingleton->size(); i++)
-    {
-        struct timespec *nextNotify = subscribersSingleton->get(i)->getNextNotify();
-        if (nextTime == NULL || compareTimespecs(nextNotify, nextTime) > 0)
-        {
-            nextTime = nextNotify;
+    AutoLock lock(mutex);
+
+    std::list<TimerSubscriberElement> toNotify;
+
+    for (auto it = subscribers.begin(); it != subscribers.end(); ) {
+        TimerSubscriberElement& element = *it;
+
+        struct timespec now;
+        getTimespecNow(&now);
+        long wait = getDeltaMillis(&now, element.getNextNotify());
+
+        if (wait <= 0) {
+            toNotify.push_back(element);
+            if(element.isOnce()){
+                it = subscribers.erase(it);
+            } else {
+                element.updateNextNotify();
+                ++it;
+            }
+        } else {
+            ++it;
         }
     }
-    for(int i = 0; i < subscribersObject->size(); i++)
-    {
-        struct timespec *nextNotify = subscribersObject->get(i)->getNextNotify();
-        if (nextTime == NULL || compareTimespecs(nextNotify, nextTime) > 0)
-        {
+
+    mutex.unlock();
+
+    for(auto& element : toNotify){
+        element.notify();
+    }
+}
+
+struct timespec* Timer::getNextNotifyTime()
+{
+    AutoLock lock(mutex);
+    struct timespec *nextTime = nullptr;
+    for (auto & subscriber : subscribers) {
+        struct timespec *nextNotify = subscriber.getNextNotify();
+        if (nextTime == nullptr || getDeltaMillis(nextTime, nextNotify) < 0) {
             nextTime = nextNotify;
         }
     }
@@ -124,7 +171,5 @@ struct timespec * Timer::getNextNotifyTime()
 
 void Timer::shutdown()
 {
-    subscribersSingleton = nil;
-    subscribersObject = nil;
-    log_debug("finished.\n");
+    shutdownFlag = true;
 }
diff --git a/src/timer.h b/src/timer.h
index 2ce3017..5677ec8 100644
--- a/src/timer.h
+++ b/src/timer.h
@@ -32,165 +32,119 @@
 #ifndef __TIMER_H__
 #define __TIMER_H__
 
-#include "zmm/zmm.h"
-#include "zmmf/zmmf.h"
 #include "singleton.h"
-#include "sync.h"
 #include "tools.h"
+#include "zmm/ref.h"
+#include "zmm/zmm.h"
+#include "zmm/zmmf.h"
+#include <algorithm>
+#include <condition_variable>
+#include <list>
 
-//#define AS_TIMER_SUBSCRIBER(klass, object) RefCast(Ref<TimerSubscriber<Singleton<klass> > >(object), TimerSubscriber<Object>)
-#define AS_TIMER_SUBSCRIBER_SINGLETON(obj) zmm::Ref<TimerSubscriberSingleton<Object> >((TimerSubscriberSingleton<Object>*)obj)
-#define AS_TIMER_SUBSCRIBER_SINGLETON_FROM_REF(obj) RefCast(obj, TimerSubscriberSingleton<Object>)
+class Timer : public Singleton<Timer, std::mutex> {
+public:
+    /// \brief This is the parameter class for timerNotify
+    class Parameter : public zmm::Object {
+    public:
+        enum timer_param_t {
+            IDAutoscan,
+#ifdef ONLINE_SERVICES
+            IDOnlineContent,
+#ifdef YOUTUBE
+            IDURLCache
+#endif
+#endif
+        };
 
-/// \todo Leo: please add doxygen documentation!
+        Parameter(timer_param_t param, int id)
+        {
+            this->param = param;
+            this->id = id;
+        }
 
-class TimerSubscriber
-{
-public:
-    virtual ~TimerSubscriber() { log_debug("TS destroyed\n"); }
-    virtual void timerNotify(zmm::Ref<zmm::Object> parameter) = 0;
-//    void addTimerSubscriber(unsigned int notifyInterval, int id = 0, bool once = false);
-//    void removeTimerSubscriber(int id = 0, bool dontFail = false);
-};
+        timer_param_t whoami() { return param; }
+        void setID(int id) { this->id = id; }
+        int getID() { return id; }
 
+    protected:
+        timer_param_t param;
+        int id;
+    };
 
-template <class T>
-class TimerSubscriberSingleton : public TimerSubscriber, public Singleton<T>
-{
-};
+    class Subscriber {
+    public:
+        virtual ~Subscriber() { log_debug("Subscriber destroyed\n"); }
+        virtual void timerNotify(zmm::Ref<Parameter> parameter) = 0;
+    };
 
-class TimerSubscriberObject : public TimerSubscriber, public zmm::Object
-{
-};
+    ~Timer() { log_debug("Timer destroyed!\n"); }
+    void init() override;
+    void shutdown() override;
 
+    /// \brief Add a subscriber
+    ///
+    /// @param timerSubscriber Caller must ensure that before this pointer is
+    /// freed the subscriber is removed by calling removeTimerSubscriber() with
+    /// the same parameter argument, unless the subscription is for a one-shot
+    /// timer and the subscriber has already been notified (and removed from the
+    /// subscribers list).
+    void addTimerSubscriber(Subscriber* timerSubscriber, unsigned int notifyInterval, zmm::Ref<Parameter> parameter = nullptr, bool once = false);
+    void removeTimerSubscriber(Subscriber* timerSubscriber, zmm::Ref<Parameter> parameter = nullptr, bool dontFail = false);
+    void triggerWait();
+    inline void signal() { cond.notify_one(); }
 
-class Timer : public Singleton<Timer>
-{
-public:
-    Timer();
-    virtual ~Timer() { log_debug("Timer destroyed!\n"); }
-    //static zmm::Ref<Timer> getInstance();
-    
-    virtual void shutdown();
-    
-    template <class T>
-    void addTimerSubscriber(zmm::Ref<T> timerSubscriber, unsigned int notifyInterval, zmm::Ref<zmm::Object> parameter = nil, bool once = false)
-    {
-        log_debug("adding subscriber...\n");
-        if (notifyInterval <= 0)
-            throw zmm::Exception(_("tried to add timer with illegal notifyInterval: ") + notifyInterval);
-        AUTOLOCK(mutex);
-        //timerSubscriber->timerNotify(id);
-        zmm::Ref<TimerSubscriberElement<T> > element(new TimerSubscriberElement<T>(timerSubscriber, notifyInterval, parameter, once));
-        for(int i = 0; i < getAppropriateSubscribers<T>()->size(); i++)
+protected:
+    class TimerSubscriberElement {
+    public:
+        TimerSubscriberElement(Subscriber* subscriber, unsigned int notifyInterval, zmm::Ref<Parameter> parameter, bool once = false)
+            : subscriber(subscriber)
+            , notifyInterval(notifyInterval)
+            , parameter(parameter)
+            , once(once)
         {
-            if (getAppropriateSubscribers<T>()->get(i)->equals(element))
-            {
-                throw zmm::Exception(_("tried to add same timer twice"));
-            }
+            updateNextNotify();
         }
-        getAppropriateSubscribers<T>()->append(element);
-        signal();
-    }
-    
-    template <class T>
-    void removeTimerSubscriber(zmm::Ref<T> timerSubscriber, zmm::Ref<zmm::Object> parameter = nil, bool dontFail = false)
-    {
-        log_debug("removing subscriber...\n");
-        AUTOLOCK(mutex);
-        zmm::Ref<TimerSubscriberElement<T> > element(new TimerSubscriberElement<T>(timerSubscriber, 0, parameter));
-        bool removed = false;
-        for(int i = 0; i < getAppropriateSubscribers<T>()->size(); i++)
+        void notify()
         {
-            if (getAppropriateSubscribers<T>()->get(i)->equals(element))
-            {
-                getAppropriateSubscribers<T>()->removeUnordered(i);
-                removed = true;
-                break;
+            try {
+                subscriber->timerNotify(parameter);
+            } catch (const zmm::Exception& e) {
+                log_debug("timer caught exception!\n");
+                e.printStackTrace();
             }
         }
-        if (! removed && ! dontFail)
+        inline void updateNextNotify()
         {
-            throw zmm::Exception(_("tried to remove nonexistent timer"));
+            getTimespecAfterMillis(notifyInterval * 1000, &nextNotify);
         }
-        signal();
-    }
-    
-    void triggerWait();
-    
-    inline void signal() { cond->signal(); }
-    
-protected:
-    template <class T>
-    class TimerSubscriberElement : public zmm::Object
-    {
-    public:
-        TimerSubscriberElement(zmm::Ref<T> subscriber, unsigned int notifyInterval, zmm::Ref<zmm::Object> parameter, bool once = false)
+        inline struct timespec* getNextNotify() { return &nextNotify; }
+        inline zmm::Ref<Parameter> getParameter() { return parameter; }
+        bool operator==(const TimerSubscriberElement& other) const
         {
-            this->subscriber = subscriber;
-            this->notifyInterval = notifyInterval;
-            this->parameter = parameter;
-            this->once = once;
-            notified();
+            return subscriber == other.subscriber && parameter == other.parameter;
         }
-        inline unsigned int getNotifyInterval() { return notifyInterval; }
-        inline zmm::Ref<T> getSubscriber() { return subscriber; }
-        inline void notified() { getTimespecAfterMillis(notifyInterval * 1000, &nextNotify); }
-        inline struct timespec *getNextNotify() { return &nextNotify; }
-        inline zmm::Ref<zmm::Object> getParameter() { return parameter; }
-        bool equals(zmm::Ref<TimerSubscriberElement> other) { return (subscriber == other->subscriber && parameter == other->parameter); }
-        bool isOnce() { return once; }
+        bool isOnce() const { return once; }
+
     protected:
-        zmm::Ref<T> subscriber;
+        Subscriber* subscriber;
         unsigned int notifyInterval;
-        zmm::Ref<zmm::Object> parameter;
+        zmm::Ref<Parameter> parameter;
         struct timespec nextNotify;
         bool once;
     };
-    
-    
-    //static zmm::Ref<Timer> instance;
-    //static zmm::Ref<Mutex> mutex;
-    zmm::Ref<Cond> cond;
-    
-    zmm::Ref<zmm::Array<TimerSubscriberElement<TimerSubscriberSingleton<Object> > > > subscribersSingleton;
-    zmm::Ref<zmm::Array<TimerSubscriberElement<TimerSubscriberObject> > > subscribersObject;
-    
-    template <class T>
-    zmm::Ref<zmm::Array<TimerSubscriberElement<T> > > getAppropriateSubscribers();
-    
-    template <class T>
-    void notify()
-    {
-        struct timespec now;
-        getTimespecNow(&now);
-        log_debug("notifying. - %d subscribers\n", getAppropriateSubscribers<T>()->size());
-        for(int i = 0; i < getAppropriateSubscribers<T>()->size(); i++)
-        {
-            zmm::Ref<TimerSubscriberElement<T> > element = getAppropriateSubscribers<T>()->get(i);
-            if (compareTimespecs(element->getNextNotify(), &now) >= 0)
-            {
-                log_debug("notifying %d\n", i);
-                zmm::Ref<T> subscriber = element->getSubscriber();
-                try
-                {
-                    subscriber->timerNotify(element->getParameter());
-                }
-                catch (zmm::Exception e)
-                {
-                    log_debug("timer caught exception!\n");
-                    e.printStackTrace();
-                }
-                element->notified();
-                if (element->isOnce())
-                {
-                    getAppropriateSubscribers<T>()->removeUnordered(i--);
-                }
-            }
-        }
-    }
-    
-    struct timespec *getNextNotifyTime();
+
+    std::mutex waitMutex;
+    std::condition_variable cond;
+    std::list<TimerSubscriberElement> subscribers;
+    std::atomic_bool shutdownFlag;
+
+    void notify();
+    struct timespec* getNextNotifyTime();
+
+private:
+    static void *staticThreadProc(void *arg);
+    void threadProc();
+    pthread_t thread;
 };
 
 #endif // __TIMER_H__
diff --git a/src/tools.cc b/src/tools.cc
index 22fbd6b..32136d7 100644
--- a/src/tools.cc
+++ b/src/tools.cc
@@ -29,22 +29,19 @@
 
 /// \file tools.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
 
-#include "tools.h"
 #include <sys/stat.h>
-#include <errno.h>
+#include <cerrno>
 #include <unistd.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include <limits.h>
+#include <climits>
 #include <netdb.h>
-#include <string.h>
-#include "config_manager.h"
+#include <cstring>
+
+#include <ifaddrs.h>
 
 #ifndef SOLARIS
     #include <net/if.h>
@@ -57,22 +54,25 @@
 #include "md5/md5.h"
 #include "file_io_handler.h"
 #include "metadata_handler.h"
+#include "config_manager.h"
+#include "tools.h"
 
 #define WHITE_SPACE " \t\r\n"
 
 using namespace zmm;
+using namespace std;
 
 static const char *HEX_CHARS = "0123456789abcdef";
 
 Ref<Array<StringBase> > split_string(String str, char sep, bool empty)
 {
     Ref<Array<StringBase> > ret(new Array<StringBase>());
-    char *data = str.c_str();
-    char *end = data + str.length();
+    const char *data = str.c_str();
+    const char *end = data + str.length();
     while (data < end)
     {
-        char *pos = strchr(data, sep);
-        if (pos == NULL)
+        const char *pos = strchr(data, sep);
+        if (pos == nullptr)
         {
             String part = data;
             ret->append(part);
@@ -124,14 +124,14 @@ Ref<Array<StringBase> > split_path(String str)
 
 String trim_string(String str)
 {
-    if (str == nil)
-        return nil;
+    if (str == nullptr)
+        return nullptr;
     int i;
     int start = 0;
     int end = 0;
     int len = str.length();
 
-    char *buf = str.c_str();
+    const char *buf = str.c_str();
 
     for (i = 0; i < len; i++)
     {
@@ -174,7 +174,7 @@ time_t check_path_ex(String path, bool needDir, bool existenceUnneeded,
     int ret = 0;
     struct stat statbuf;
 
-    if (filesize != NULL)
+    if (filesize != nullptr)
         *filesize = 0;
 
     ret = stat(path.c_str(), &statbuf);
@@ -182,8 +182,8 @@ time_t check_path_ex(String path, bool needDir, bool existenceUnneeded,
     {
         if (existenceUnneeded && (errno == ENOENT))
             return 0;
-        
-        throw _Exception(path + " : " + errno + (int)existenceUnneeded+ " x " + mt_strerror(errno));
+        throw _Exception(mt_strerror(errno) + ": " +  path + " (errno: " +
+            errno + (int)existenceUnneeded + ")") ;
     }
 
     if (needDir && (!S_ISDIR(statbuf.st_mode)))
@@ -192,7 +192,7 @@ time_t check_path_ex(String path, bool needDir, bool existenceUnneeded,
     if (!needDir && (S_ISDIR(statbuf.st_mode)))
         throw _Exception(_("Not a file: ") + path);
 
-    if ((filesize != NULL) && S_ISREG(statbuf.st_mode))
+    if ((filesize != nullptr) && S_ISREG(statbuf.st_mode))
         *filesize = statbuf.st_size;
 
     return statbuf.st_mtime;
@@ -201,7 +201,7 @@ time_t check_path_ex(String path, bool needDir, bool existenceUnneeded,
 bool is_executable(String path, int *err)
 {
     int ret = access(path.c_str(), R_OK | X_OK);
-    if (err != NULL)
+    if (err != nullptr)
         *err = errno;
 
     if (ret == 0)
@@ -214,44 +214,44 @@ String find_in_path(String exec)
 {
     String PATH = getenv("PATH");
     if (!string_ok(PATH))
-        return nil;
+        return nullptr;
 
     Ref<StringTokenizer> st(new StringTokenizer(PATH));
-    String path = nil;
+    String path = nullptr;
     String next;
     do
     {
-        if (path == nil)
+        if (path == nullptr)
             path = st->nextToken(_(":"));
         next = st->nextToken(_(":"));
 
-        if (path == nil)
+        if (path == nullptr)
             break;
 
-        if ((next != nil) && !next.startsWith(_("/")))
+        if ((next != nullptr) && !next.startsWith(_("/")))
         {
             path = path + _(":") + next;
-            next = nil;
+            next = nullptr;
         }
 
         String check = path + _("/") + exec;
         if (check_path(check))
             return check;
 
-        if (next != nil)
+        if (next != nullptr)
             path = next;
         else
-            path = nil;
+            path = nullptr;
 
 
-    } while (path != nil);
+    } while (path != nullptr);
 
-    return nil;
+    return nullptr;
 }
 
 bool string_ok(String str)
 {
-    if ((str == nil) || (str == ""))
+    if ((str == nullptr) || (str == ""))
         return false;
     return true;
 }
@@ -259,7 +259,7 @@ bool string_ok(String str)
 bool string_ok(Ref<StringBuffer> str)
 {
     
-    if ((str == nil) || (str->length()<=0))
+    if ((str == nullptr) || (str->length()<=0))
         return false;
     else
         return true;
@@ -267,7 +267,7 @@ bool string_ok(Ref<StringBuffer> str)
 
 void string_ok_ex(String str)
 {
-    if ((str == nil) || (str == ""))
+    if ((str == nullptr) || (str == ""))
         throw _Exception(_("Empty string"));
 }
 
@@ -276,9 +276,9 @@ String http_redirect_to(String ip, String port, String page)
     return _("<html><head><meta http-equiv=\"Refresh\" content=\"0;URL=http://") + ip + ":" + port + "/" + page + "\"></head><body bgcolor=\"#dddddd\"></body></html>";
 }
 
-String hex_encode(void *data, int len)
+String hex_encode(const void *data, int len)
 {
-    unsigned char *chars;
+    const unsigned char *chars;
     int i;
     unsigned char hi, lo;
 
@@ -298,14 +298,14 @@ String hex_encode(void *data, int len)
 
 String hex_decode_string(String encoded)
 {
-    char *ptr = encoded.c_str();
+    auto *ptr = const_cast<char *>(encoded.c_str());
     int len = encoded.length();
     
     Ref<StringBuffer> buf(new StringBuffer(len / 2));
     for (int i = 0; i < len; i += 2)
     {
-        const char *chi = strchr(HEX_CHARS, ptr[i]);
-        const char *clo = strchr(HEX_CHARS, ptr[i + 1]);
+        const char *chi = strchr(const_cast<char *>(HEX_CHARS), ptr[i]);
+        const char *clo = strchr(const_cast<char *>(HEX_CHARS), ptr[i + 1]);
         int hi, lo;
         
         if (chi)
@@ -317,7 +317,7 @@ String hex_decode_string(String encoded)
             lo = clo - HEX_CHARS;
         else
             lo = 0;
-        char ch = (char)(hi << 4 | lo);
+        auto ch = (char)(hi << 4 | lo);
         *buf << ch;
     }
     return buf->toString();
@@ -328,7 +328,7 @@ struct randomizer
     struct timeval tv;
     int salt;
 };
-String hex_md5(void *data, int length)
+String hex_md5(const void *data, int length)
 {
     char md5buf[16];
 
@@ -346,7 +346,7 @@ String hex_string_md5(String str)
 String generate_random_id()
 {
     struct randomizer st;
-    gettimeofday(&st.tv, NULL);
+    gettimeofday(&st.tv, nullptr);
     st.salt = rand();
     return hex_md5(&st, sizeof(st));
 }
@@ -356,12 +356,12 @@ static const char *hex = "0123456789ABCDEF";
 
 String url_escape(String str)
 {
-    char *data = str.c_str();
+    const char *data = str.c_str();
     int len = str.length();
     Ref<StringBuffer> buf(new StringBuffer(len));
     for (int i = 0; i < len; i++)
     {
-        unsigned char c = (unsigned char)data[i];
+        auto c = (unsigned char)data[i];
         if ((c >= '0' && c <= '9') ||
             (c >= 'A' && c <= 'Z') ||
             (c >= 'a' && c <= 'z') ||
@@ -382,7 +382,7 @@ String url_escape(String str)
 
 String url_unescape(String str)
 {
-    char *data = str.c_str();
+    auto *data = const_cast<char *>(str.c_str());
     int len = str.length();
     Ref<StringBuffer> buf(new StringBuffer(len));
 
@@ -400,13 +400,13 @@ String url_unescape(String str)
 
             const char *pos;
 
-            pos = strchr(hex, chi);
+            pos = strchr(const_cast<char *>(hex), chi);
             if (!pos)
                 hi = 0;
             else
                 hi = pos - hex;
 
-            pos = strchr(hex, clo);
+            pos = strchr(const_cast<char *>(hex), clo);
             if (!pos)
                 lo = 0;
             else
@@ -473,7 +473,7 @@ String read_text_file(String path)
                         path + " : " + mt_strerror(errno));
     }
     Ref<StringBuffer> buf(new StringBuffer()); 
-    char *buffer = (char *)MALLOC(1024);
+    auto *buffer = (char *)MALLOC(1024);
     size_t bytesRead;    
     while((bytesRead = fread(buffer, 1, 1024, f)) > 0)
     {
@@ -522,7 +522,7 @@ void copy_file(String from, String to)
         throw _Exception(_("copy_file: could not open ") +
                         to + " for write: " + mt_strerror(errno));
     }
-    char *buffer = (char *)MALLOC(1024);
+    auto *buffer = (char *)MALLOC(1024);
     size_t bytesRead = 0;
     size_t bytesWritten = 0;
     while(bytesRead == bytesWritten && ! feof(f) && ! ferror(f) && ! ferror(t)
@@ -639,7 +639,7 @@ String getMTFromProtocolInfo(String protocol)
     if (parts->size() > 2)
         return parts->get(2);
     else
-        return nil;
+        return nullptr;
 }
 
 String getProtocol(String protocolInfo)
@@ -669,7 +669,7 @@ String secondsToHMS(int seconds)
     if (h > 999)
         h = 999;
 
-    char *str = (char *)malloc(10);
+    auto *str = (char *)malloc(10);
     sprintf(str, "%02d:%02d:%02d", h, m, s);
     return String::take(str);
 }
@@ -693,14 +693,14 @@ int HMSToSeconds(String time)
 #ifdef HAVE_MAGIC
 String get_mime_type(magic_set *ms, Ref<RExp> reMimetype, String file)
 {
-    if (ms == NULL)
-        return nil;
+    if (ms == nullptr)
+        return nullptr;
 
-    char *mt = (char *)magic_file(ms, file.c_str());
-    if (mt == NULL)
+    auto *mt = (char *)magic_file(ms, file.c_str());
+    if (mt == nullptr)
     {
         log_error("magic_file: %s\n", magic_error(ms));
-        return nil;
+        return nullptr;
     }
 
     String mime_type = mt;
@@ -711,20 +711,20 @@ String get_mime_type(magic_set *ms, Ref<RExp> reMimetype, String file)
 
     log_warning("filemagic returned invalid mimetype for %s\n%s\n",
                 file.c_str(), mt);
-    return nil;
+    return nullptr;
 }
 
 String get_mime_type_from_buffer(magic_set *ms, Ref<RExp> reMimetype, 
-                                 void *buffer, size_t length)
+                                 const void *buffer, size_t length)
 {
-    if (ms == NULL)
-        return nil;
+    if (ms == nullptr)
+        return nullptr;
 
-    char *mt = (char *)magic_buffer(ms, buffer, length);
-    if (mt == NULL)
+    auto *mt = (char *)magic_buffer(ms, buffer, length);
+    if (mt == nullptr)
     {
         log_error("magic_file: %s\n", magic_error(ms));
-        return nil;
+        return nullptr;
     }
 
     String mime_type = mt;
@@ -733,9 +733,8 @@ String get_mime_type_from_buffer(magic_set *ms, Ref<RExp> reMimetype,
     if (matcher->next())
         return matcher->group(1);
 
-    log_warning("filemagic returned invalid mimetype for the given buffer%s\n",
-                mt);
-    return nil;
+    log_warning("filemagic returned invalid mimetype for the given buffer%s\n", mt);
+    return nullptr;
 }
 #endif 
 
@@ -752,7 +751,7 @@ void set_jpeg_resolution_resource(Ref<CdsItem> item, int res_num)
             
         item->getResource(res_num)->addAttribute(MetadataHandler::getResAttrName(R_RESOLUTION), resolution);
     }
-    catch (Exception e)
+    catch (const Exception & e)
     {
         e.printStackTrace();
     }
@@ -760,10 +759,10 @@ void set_jpeg_resolution_resource(Ref<CdsItem> item, int res_num)
 
 bool check_resolution(String resolution, int *x, int *y)
 {
-    if (x != NULL)
+    if (x != nullptr)
         *x = 0;
 
-    if (y != NULL)
+    if (y != nullptr)
         *y = 0;
 
     Ref<Array<StringBase> > parts = split_string(resolution, 'x');
@@ -778,10 +777,10 @@ bool check_resolution(String resolution, int *x, int *y)
 
             if ((_x > 0) && (_y > 0))
             {
-                if (x != NULL)
+                if (x != nullptr)
                     *x = _x;
 
-                if (y != NULL)
+                if (y != nullptr)
                     *y = _y;
 
                 return true;
@@ -934,8 +933,8 @@ String xml_unescape(String string)
 
 String unescape_amp(String string)
 {
-    if (string == nil)
-        return nil;
+    if (string == nullptr)
+        return nullptr;
     Ref<StringBase> stringBase(new StringBase(string.length()));
     char *str = stringBase->data;
     int len = string.length();
@@ -975,7 +974,7 @@ String unescape_amp(String string)
 
 String fallbackString(String first, String fallback)
 {
-    if (first==nil)
+    if (first==nullptr)
         return fallback;
     return first;
 }
@@ -983,27 +982,28 @@ String fallbackString(String first, String fallback)
 unsigned int stringHash(String str)
 {
     unsigned int hash = 5381;
-    unsigned char *data = (unsigned char *)str.c_str();
+    auto *data = (unsigned char *)str.c_str();
     int c;
     while ((c = *data++))
         hash = ((hash << 5) + hash) ^ c; /* (hash * 33) ^ c */
     return hash;
 }
 
-String intArrayToCSV(int *array, int size)
+String toCSV(shared_ptr<unordered_set<int> > array)
 {
-    if (size <= 0)
-        return nil;
+    if (array->empty())
+        return nullptr;
     Ref<StringBuffer> buf(new StringBuffer());
-    for (int i = 0; i < size; i++)
-        *buf << ',' << array[i];
+    for (const auto &i: *array) {
+        *buf << ',' << i;
+    }
     return buf->toString(1);
 }
 
 void getTimespecNow(struct timespec *ts)
 {
     struct timeval tv;
-    int ret = gettimeofday(&tv, NULL);
+    int ret = gettimeofday(&tv, nullptr);
     if (ret != 0)
         throw _Exception(_("gettimeofday failed: ") + mt_strerror(errno));
     
@@ -1026,7 +1026,7 @@ long getDeltaMillis(struct timespec *first, struct timespec *second)
 void getTimespecAfterMillis(long delta, struct timespec *ret, struct timespec *start)
 {
     struct timespec now;
-    if (start == NULL)
+    if (start == nullptr)
     {
         getTimespecNow(&now);
         start = &now;
@@ -1039,20 +1039,7 @@ void getTimespecAfterMillis(long delta, struct timespec *ret, struct timespec *s
         ret->tv_nsec -= 1000000000;
     }
     
-    //log_debug("timespec: sec: %ld, nsec: %ld\n", ret->tv_sec, ret->tv_nsec);
-}
-
-int compareTimespecs(struct timespec *a,  struct timespec *b)
-{
-    if (a->tv_sec < b->tv_sec)
-        return 1;
-    if (a->tv_sec > b->tv_sec)
-        return -1;
-    if (a->tv_nsec < b->tv_nsec)
-        return 1;
-    if (a->tv_nsec > b->tv_nsec)
-        return -1;
-    return 0;
+    // log_debug("timespec: sec: %ld, nsec: %ld\n", ret->tv_sec, ret->tv_nsec);
 }
 
 String normalizePath(String path)
@@ -1070,15 +1057,7 @@ String normalizePath(String path)
     char *str = result->data;
     //int len = string.length();
 
-#ifndef __CYGWIN__
     if (path.charAt(0) != DIR_SEPARATOR)
-#else
-    #error !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! this function is not finished for Cygwin
-    for (int i = 0; i < 20; i++)
-        print_backtrace();
-    /// \todo this doesn't seem to be correct...
-    if ((!path.length() > 1) && (path.charAt(1) != ':'))
-#endif
         throw _Exception(_("Relative paths are not allowed!\n"));
     
     int next = 1;
@@ -1131,49 +1110,31 @@ String normalizePath(String path)
 
 String interfaceToIP(String interface)
 {
-#if defined(__CYGWIN__)
-    struct hostent *h=NULL;
-    struct sockaddr_in LocalAddr;
-    char *hostname = (char *)MALLOC(256);
-    if (!hostname)
-        return nil;
-
-    gethostname(hostname, 255);
-    hostname[255] = '\0';
-    h=gethostbyname(hostname);
-    free(hostname);
-    if (h != NULL)
-    {
-        memcpy(&LocalAddr.sin_addr, h->h_addr_list[0],4);
-        return String(inet_ntoa(LocalAddr.sin_addr));
-    }
-    return nil;
-#else
 
-    struct if_nameindex *iflist = NULL;
-    struct if_nameindex *iflist_free = NULL;
+    struct if_nameindex *iflist = nullptr;
+    struct if_nameindex *iflist_free = nullptr;
     struct ifreq if_request;
     struct sockaddr_in local_address;
     int local_socket;
 
     if (!string_ok(interface))
-            return nil;
+            return nullptr;
 
     local_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
     if (local_socket < 0)
     {
         log_error("Could not create local socket: %s\n", 
                   mt_strerror(errno).c_str());
-        return nil;
+        return nullptr;
     }
 
     iflist = iflist_free = if_nameindex();
-    if (iflist == NULL)
+    if (iflist == nullptr)
     {
         log_error("Could not get interface list: %s\n", 
                   mt_strerror(errno).c_str());
         close(local_socket);
-        return nil;
+        return nullptr;
     }
 
     while (iflist->if_index || iflist->if_name)
@@ -1187,7 +1148,7 @@ String interfaceToIP(String interface)
                           mt_strerror(errno).c_str());
                 close(local_socket);
                 if_freenameindex(iflist_free);
-                return nil;
+                return nullptr;
             }
 
             memcpy(&local_address, &if_request.ifr_addr, sizeof(if_request.ifr_addr));
@@ -1201,8 +1162,52 @@ String interfaceToIP(String interface)
 
     close(local_socket);
     if_freenameindex(iflist_free);
-    return nil;
-#endif
+    return nullptr;
+}
+
+String ipToInterface(String ip) {
+    if (!string_ok(ip)) {
+        log_warning("IP is null\n");
+        return nullptr;
+    } else {
+        log_debug("Looking for '%s'\n", ip.c_str());
+    }
+
+    struct ifaddrs *ifaddr, *ifa;
+    int family, s, n;
+    char host[NI_MAXHOST];
+
+    if (getifaddrs(&ifaddr) == -1) {
+        log_error("Could not getifaddrs: %s\n", mt_strerror(errno).c_str());
+    }
+
+    for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
+        if (ifa->ifa_addr == NULL)
+            continue;
+
+        family = ifa->ifa_addr->sa_family;
+        String name = String::copy(ifa->ifa_name);
+
+        if (family == AF_INET || family == AF_INET6) {
+            s = getnameinfo(ifa->ifa_addr,
+                    (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6),
+                    host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+            if (s != 0) {
+                log_error("getnameinfo() failed: %s\n", gai_strerror(s));
+                return nullptr;
+            }
+
+            String ipaddr = String::copy(host);
+            // IPv6 link locals come back as fe80::351d:d7f4:6b17:3396%eth0
+            if (ipaddr.startsWith(ip)) {
+                return name;
+            }
+        }
+    }
+
+    freeifaddrs(ifaddr);
+    log_warning("Failed to find interface for IP: %s\n", ip.c_str());
+    return nullptr;
 }
 
 bool validateYesNo(String value)
@@ -1217,7 +1222,7 @@ Ref<Array<StringBase> > parseCommandLine(String line, String in, String out,
                                          String range)
 {
     Ref<Array<StringBase> > params = split_string(line, ' ');
-    if ((in == nil) && (out == nil))
+    if ((in == nullptr) && (out == nullptr))
         return params;
 
     for (int i = 0; i < params->size(); i++)
@@ -1225,7 +1230,7 @@ Ref<Array<StringBase> > parseCommandLine(String line, String in, String out,
         String param = params->get(i);
         String newParam = param.replace(_("%in"), in);
         newParam = newParam.replace(_("%out"), out);
-        if (range != nil)
+        if (range != nullptr)
         {
             newParam = newParam.replace(_("%range"), range);
         }
@@ -1282,11 +1287,11 @@ String tempName(String leadPath, char *tmpl)
 
     if (!XXXXXX || strncmp (XXXXXX, "XXXXXX", 6))
     {
-        return nil;
+        return nullptr;
     }
 
     /* Get some more or less random data.  */
-    gettimeofday(&tv, NULL);
+    gettimeofday(&tv, nullptr);
     value = (tv.tv_usec ^ tv.tv_sec) + counter++;
 
     for (count = 0; count < 100; value += 7777, ++count)
@@ -1314,12 +1319,12 @@ String tempName(String leadPath, char *tmpl)
                     (errno == ENOTDIR))
                 return check;
             else
-                return nil;
+                return nullptr;
         }
     }
 
     /* We got out of the loop because we ran out of combinations to try.  */
-    return nil;
+    return nullptr;
 }
 
 bool isTheora(String ogg_filename)
@@ -1385,12 +1390,12 @@ String get_last_path(String location)
 }
 
 
-ssize_t getValidUTF8CutPosition(zmm::String str, size_t cutpos)
+ssize_t getValidUTF8CutPosition(zmm::String str, ssize_t cutpos)
 {
     ssize_t pos = -1;
     size_t len = str.length();
 
-    if ((len == 0) || (cutpos > len))
+    if ((len == 0) || (cutpos > (ssize_t)len))
         return pos;
 
     printf("Character at cut position: %0x\n", (char)str.charAt(cutpos));
@@ -1459,7 +1464,7 @@ String getAVIFourCC(zmm::String avi_filename)
                           mt_strerror(errno));
 
     buffer = (char *)MALLOC(FCC_OFFSET+6);
-    if (buffer == NULL)
+    if (buffer == nullptr)
     {
         fclose(f);
         throw _Exception(_("Out of memory when allocating buffer for file ") +
@@ -1480,13 +1485,13 @@ String getAVIFourCC(zmm::String avi_filename)
     if (strncmp(buffer, "RIFF", 4) != 0)
     {
         free(buffer);
-        return nil;
+        return nullptr;
     }
 
     if (strncmp(buffer+8, "AVI ", 4) != 0)
     {
         free(buffer);
-        return nil;
+        return nullptr;
     }
 
     String fourcc = String(buffer+FCC_OFFSET, 4);
@@ -1495,7 +1500,7 @@ String getAVIFourCC(zmm::String avi_filename)
     if (string_ok(fourcc))
         return fourcc;
     else
-        return nil;
+        return nullptr;
 }
 #endif
 
diff --git a/src/tools.h b/src/tools.h
index 793c043..f33b593 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -31,11 +31,15 @@
 #ifndef __TOOLS_H__
 #define __TOOLS_H__
 
+#include <memory>
+#include <unordered_set>
+
+#include <sys/time.h>
+
 #include "common.h"
 #include "rexp.h"
 #include "io_handler.h"
 #include "cds_objects.h"
-#include <sys/time.h>
 
 #ifdef HAVE_MAGIC
 // for older versions of filemagic
@@ -91,15 +95,15 @@ bool is_executable(zmm::String path, int *err = NULL);
 
 /// \brief Checks if the given executable exists in $PATH
 /// \param exec filename of the executable that needs to be checked
-/// \return aboslute path to the given executable or nil of it was not found
+/// \return aboslute path to the given executable or nullptr of it was not found
 zmm::String find_in_path(zmm::String exec);
 
 /// \brief Checks if the string contains any data.
 /// \param str String to be checked.
 /// \return true if ok
-/// \return false if string was either nil or empty
+/// \return false if string was either nullptr or empty
 /// 
-/// Checks if str is nil or ""
+/// Checks if str is nullptr or ""
 bool string_ok(zmm::String str);
 
 bool string_ok(zmm::Ref<zmm::StringBuffer> str);
@@ -107,7 +111,7 @@ bool string_ok(zmm::Ref<zmm::StringBuffer> str);
 /// \brief Checks if the string contains any data.
 /// \param str String to be checked.
 /// 
-/// Checks if str is nil or "" and throws an exception if that is the case.
+/// Checks if str is nullptr or "" and throws an exception if that is the case.
 void string_ok_ex(zmm::String str);
 
 /// \brief Render HTML that is doing a redirect to the given ip, port and html page.
@@ -121,7 +125,7 @@ zmm::String http_redirect_to(zmm::String ip, zmm::String port, zmm::String page
 /// \param data Buffer that is holding the data
 /// \param len Length of the buffer.
 /// \return string of the data in hex representation.
-zmm::String hex_encode(void *data, int len);
+zmm::String hex_encode(const void *data, int len);
 
 /// \brief Decodes hex encoded string.
 /// \param encoded hex-encoded string.
@@ -134,7 +138,7 @@ zmm::String hex_decode_string(zmm::String encoded);
 zmm::String generate_random_id();
 
 /// \brief Generates hex md5 sum of the given data.
-zmm::String hex_md5(void *data, int length);
+zmm::String hex_md5(const void *data, int length);
 
 /// \brief Generates hex md5 sum of the given string.
 zmm::String hex_string_md5(zmm::String str);
@@ -181,7 +185,7 @@ void quicksort(COMPARABLE *arr, int size, COMPARATOR comparator);
 /// \param mimetype the mimetype that should be inserted
 /// \param protocol the protocol which should be inserted (default: "http-get")
 /// \return The rendered protocolInfo String
-zmm::String renderProtocolInfo(zmm::String mimetype, zmm::String protocol = _(PROTOCOL), zmm::String extend = nil);
+zmm::String renderProtocolInfo(zmm::String mimetype, zmm::String protocol = _(PROTOCOL), zmm::String extend = nullptr);
 
 /// \brief Extracts mimetype from the protocol info string.
 /// \param protocol info string as used in the protocolInfo attribute
@@ -206,7 +210,7 @@ int HMSToSeconds(zmm::String time);
 zmm::String get_mime_type(magic_set *ms, zmm::Ref<RExp> reMimetype, zmm::String file);
 /// \brief Extracts mimetype from a buffer using filemagic
 zmm::String get_mime_type_from_buffer(magic_set *ms, zmm::Ref<RExp> reMimetype,
-                                         void *buffer, size_t length);
+                                         const void *buffer, size_t length);
 
 #endif // HAVE_MAGIC
 
@@ -249,10 +253,10 @@ zmm::String xml_unescape(zmm::String string);
 /// \return the unescaped string
 zmm::String unescape_amp(zmm::String string);
 
-/// \brief Returns the first string if it isn't "nil", otherwise the fallback string.
-/// \param first the string to return if it isn't nil
-/// \param fallback fallback string to return if first is nil
-/// \return return first if it isn't nil, otherwise fallback
+/// \brief Returns the first string if it isn't "nullptr", otherwise the fallback string.
+/// \param first the string to return if it isn't nullptr
+/// \param fallback fallback string to return if first is nullptr
+/// \return return first if it isn't nullptr, otherwise fallback
 zmm::String fallbackString(zmm::String first, zmm::String fallback);
 
 /// \brief computes an (unsigned int) hash for the given string
@@ -260,7 +264,7 @@ zmm::String fallbackString(zmm::String first, zmm::String fallback);
 /// \return return the (unsigned int) hash value
 unsigned int stringHash(zmm::String str);
 
-zmm::String intArrayToCSV(int *array, int size);
+zmm::String toCSV(std::shared_ptr<std::unordered_set<int> > array);
 
 //inline void getTimeval(struct timeval *now) { gettimeofday(now, NULL); }
 
@@ -270,13 +274,6 @@ long getDeltaMillis(struct timespec *first);
 long getDeltaMillis(struct timespec *first, struct timespec *second);
 
 void getTimespecAfterMillis(long delta, struct timespec *ret, struct timespec *start = NULL);
-int compareTimespecs(struct timespec *a,  struct timespec *b);
-/*
-/// \bried Returns the current milliseconds since the "epoch" or since startMillis (which are counted since the epoch).
-long getMillis(long startMillis = 0);
-
-void millisToTimespec(long millis, struct timespec *spec);
-*/
 
 /// \brief This function makes sure that there are no trailing slashes, no 
 /// consecutive slashes. If /../ or /..\0 is encountered an exception is 
@@ -285,9 +282,15 @@ zmm::String normalizePath(zmm::String path);
 
 /// \brief Finds the IP address of the specified network interface.
 /// \param interface i.e. eth0, lo, etc.
-/// \return IP address or nil if interface was not found.
+/// \return IP address or nullptr if interface was not found.
 zmm::String interfaceToIP(zmm::String interface);
 
+/// \brief Finds the Interface with the specified IP address.
+/// \param ip i.e. 192.168.4.56.
+/// \return Interface name or nullptr if IP was not found.
+zmm::String ipToInterface(zmm::String interface);
+
+
 /// \brief Returns true if the given string is eitehr "yes" or "no", otherwise
 /// returns false.
 bool validateYesNo(zmm::String value);
@@ -322,7 +325,7 @@ zmm::String get_last_path(zmm::String location);
 
 /// \brief Calculates a position where it is safe to cut an UTF-8 string.
 /// \return Caclulated position or -1 in case of an error.
-ssize_t getValidUTF8CutPosition(zmm::String str, size_t cutpos);
+ssize_t getValidUTF8CutPosition(zmm::String str, ssize_t cutpos);
 
 #ifdef EXTEND_PROTOCOLINFO
 zmm::String getDLNAtransferHeader(zmm::String mimeType, zmm::String header);
diff --git a/src/transcoding/transcode_dispatcher.cc b/src/transcoding/transcode_dispatcher.cc
index ed8fb76..4a37cdc 100644
--- a/src/transcoding/transcode_dispatcher.cc
+++ b/src/transcoding/transcode_dispatcher.cc
@@ -29,10 +29,6 @@
 
 /// \file transcode_dispatcher.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef EXTERNAL_TRANSCODING
 
 #include "common.h"
@@ -50,11 +46,10 @@ TranscodeDispatcher::TranscodeDispatcher() : TranscodeHandler()
 
 Ref<IOHandler> TranscodeDispatcher::open(Ref<TranscodingProfile> profile, 
                                          String location, 
-                                         Ref<CdsObject> obj, 
-                                         struct File_Info *info,
+                                         Ref<CdsObject> obj,
                                          String range)
 {
-    if (profile == nil)
+    if (profile == nullptr)
         throw _Exception(_("Transcoding of file ") + location +
                            "requested but no profile given ");
    
@@ -63,7 +58,7 @@ Ref<IOHandler> TranscodeDispatcher::open(Ref<TranscodingProfile> profile,
     if (profile->getType() == TR_External)
     {
         Ref<TranscodeExternalHandler> tr_ext(new TranscodeExternalHandler());
-        return tr_ext->open(profile, location, obj, info, range);
+        return tr_ext->open(profile, location, obj, range);
     }
     else
         throw _Exception(_("Unknown transcoding type for profile ") + 
diff --git a/src/transcoding/transcode_dispatcher.h b/src/transcoding/transcode_dispatcher.h
index 3f9fb65..3c27658 100644
--- a/src/transcoding/transcode_dispatcher.h
+++ b/src/transcoding/transcode_dispatcher.h
@@ -41,8 +41,7 @@ public:
     TranscodeDispatcher();
     virtual zmm::Ref<IOHandler> open(zmm::Ref<TranscodingProfile> profile, 
                                      zmm::String location,
-                                     zmm::Ref<CdsObject> obj, 
-                                     struct File_Info *info,
+                                     zmm::Ref<CdsObject> obj,
                                      zmm::String range);
 };
 
diff --git a/src/transcoding/transcode_ext_handler.cc b/src/transcoding/transcode_ext_handler.cc
index 01703a3..1900a39 100644
--- a/src/transcoding/transcode_ext_handler.cc
+++ b/src/transcoding/transcode_ext_handler.cc
@@ -29,10 +29,6 @@
 
 /// \file transcode_ext_handler.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef EXTERNAL_TRANSCODING
 
 #include "transcode_ext_handler.h"
@@ -40,18 +36,18 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <upnp-1.8/ixml.h>
 #include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <signal.h>
-#include <limits.h>
+#include <cstring>
+#include <cstdio>
+#include <csignal>
+#include <climits>
 #include "common.h"
 #include "storage.h"
 #include "cds_objects.h"
 #include "process.h"
 #include "update_manager.h"
 #include "session_manager.h"
-#include "ixml.h"
 #include "process_io_handler.h"
 #include "buffered_io_handler.h"
 #include "dictionary.h"
@@ -66,13 +62,6 @@
     #include "curl_io_handler.h"
 #endif
 
-#ifdef HAVE_LIBDVDNAV
-    #include "dvd_io_handler.h"
-    #include "metadata/dvd_handler.h"
-    #include "fd_io_handler.h"
-    #include "mpegremux_processor.h"
-#endif
-
 using namespace zmm;
 
 TranscodeExternalHandler::TranscodeExternalHandler() : TranscodeHandler()
@@ -81,17 +70,16 @@ TranscodeExternalHandler::TranscodeExternalHandler() : TranscodeHandler()
 
 Ref<IOHandler> TranscodeExternalHandler::open(Ref<TranscodingProfile> profile, 
                                               String location, 
-                                              Ref<CdsObject> obj, 
-                                              struct File_Info *info,
+                                              Ref<CdsObject> obj,
                                               String range)
 {
     bool isURL = false;
 //    bool is_srt = false;
 
-    log_debug("start\n");
+    log_debug("start transcoding file: %s\n", location.c_str());
     char fifo_template[]="mt_transcode_XXXXXX";
 
-    if (profile == nil)
+    if (profile == nullptr)
         throw _Exception(_("Transcoding of file ") + location +
                            "requested but no profile given");
     
@@ -118,7 +106,7 @@ Ref<IOHandler> TranscodeExternalHandler::open(Ref<TranscodingProfile> profile,
         }
     }
 
-    info->content_type = ixmlCloneDOMString(mimeType.c_str());
+    //info->content_type = ixmlCloneDOMString(mimeType.c_str());
 #ifdef EXTEND_PROTOCOLINFO
     String header;
     header = header + _("TimeSeekRange.dlna.org: npt=") + range;
@@ -129,8 +117,8 @@ Ref<IOHandler> TranscodeExternalHandler::open(Ref<TranscodingProfile> profile,
         info->http_header = ixmlCloneDOMString(header.c_str());
 #endif
    
-    info->file_length = UNKNOWN_CONTENT_LENGTH;
-    info->force_chunked = (int)profile->getChunked();
+    //info->file_length = UNKNOWN_CONTENT_LENGTH;
+    //info->force_chunked = (int)profile->getChunked();
 
     Ref<ConfigManager> cfg = ConfigManager::getInstance();
    
@@ -140,7 +128,7 @@ Ref<IOHandler> TranscodeExternalHandler::open(Ref<TranscodingProfile> profile,
     String temp;
     String command;
     Ref<Array<StringBase> > arglist;
-    Ref<Array<ProcListItem> > proc_list = nil; 
+    Ref<Array<ProcListItem> > proc_list = nullptr;
 
 #ifdef SOPCAST
     service_type_t service = OS_None;
@@ -155,7 +143,7 @@ Ref<IOHandler> TranscodeExternalHandler::open(Ref<TranscodingProfile> profile,
         int p1 = find_local_port(45000,65500);
         int p2 = find_local_port(45000,65500);
         sop_args = parseCommandLine(location + " " + String::from(p1) + " " +
-                   String::from(p2), nil, nil);
+                   String::from(p2), nullptr, nullptr);
         Ref<ProcessExecutor> spsc(new ProcessExecutor(_("sp-sc-auth"), 
                                                       sop_args));
         proc_list = Ref<Array<ProcListItem> >(new Array<ProcListItem>(1));
@@ -187,17 +175,17 @@ Ref<IOHandler> TranscodeExternalHandler::open(Ref<TranscodingProfile> profile,
             {
                 chmod(location.c_str(), S_IWUSR | S_IRUSR);
 
-                Ref<IOHandler> c_ioh(new CurlIOHandler(url, NULL, 
+                Ref<IOHandler> c_ioh(new CurlIOHandler(url, nullptr, 
                    cfg->getIntOption(CFG_EXTERNAL_TRANSCODING_CURL_BUFFER_SIZE),
                    cfg->getIntOption(CFG_EXTERNAL_TRANSCODING_CURL_FILL_SIZE)));
 
-                Ref<IOHandler> p_ioh(new ProcessIOHandler(location, nil));
+                Ref<IOHandler> p_ioh(new ProcessIOHandler(location, nullptr));
                 Ref<Executor> ch(new IOHandlerChainer(c_ioh, p_ioh, 16384));
                 proc_list = Ref<Array<ProcListItem> >(new Array<ProcListItem>(1));
                 Ref<ProcListItem> pr_item(new ProcListItem(ch));
                 proc_list->append(pr_item);
             }
-            catch (Exception ex)
+            catch (const Exception & ex)
             {
                 unlink(location.c_str());
                 throw ex;
@@ -212,92 +200,6 @@ Ref<IOHandler> TranscodeExternalHandler::open(Ref<TranscodingProfile> profile,
     }
 #endif
 
-#ifdef HAVE_LIBDVDNAV
-    if (obj->getFlag(OBJECT_FLAG_DVD_IMAGE))
-    {
-        strcpy(fifo_template, "mt_transcode_XXXXXX");
-        location = normalizePath(tempName(cfg->getOption(CFG_SERVER_TMPDIR), fifo_template));
-        log_debug("creating reader fifo: %s\n", location.c_str());
-        if (mkfifo(location.c_str(), O_RDWR) == -1)
-        {
-            log_error("Failed to create fifo for the DVD image "
-                    "reading thread: %s\n", strerror(errno));
-            throw _Exception(_("Could not create reader fifo!\n"));
-        }
-
-       
-        try
-        {
-            String tmp = obj->getResource(0)->getParameter(DVDHandler::renderKey(DVD_Title));
-            if (!string_ok(tmp))
-                throw _Exception(_("DVD Image requested but title parameter is missing!"));
-            int title = tmp.toInt();
-            if (title < 0)
-                throw _Exception(_("DVD Image - requested invalid title!"));
-
-            tmp = obj->getResource(0)->getParameter(DVDHandler::renderKey(DVD_Chapter));
-            if (!string_ok(tmp))
-                throw _Exception(_("DVD Image requested but chapter parameter is missing!"));
-            int chapter = tmp.toInt();
-            if (chapter < 0)
-                throw _Exception(_("DVD Image - requested invalid chapter!"));
-
-            // actually we are retrieving the audio stream id here
-            tmp = obj->getResource(0)->getParameter(DVDHandler::renderKey(DVD_AudioStreamID));
-            if (!string_ok(tmp))
-                throw _Exception(_("DVD Image requested but audio track parameter is missing!"));
-            int audio_track = tmp.toInt();
-            if (audio_track < 0)
-                throw _Exception(_("DVD Image - requested invalid audio stream ID!"));
-
-            chmod(location.c_str(), S_IWUSR | S_IRUSR);
-            
-            Ref<IOHandler> dvd_ioh(new DVDIOHandler(obj->getLocation(), title, chapter, audio_track));
-
-            int from_dvd_fd[2];
-            if (pipe(from_dvd_fd) == -1)
-                throw _Exception(_("Failed to create DVD input pipe!"));
-
-            int from_remux_fd[2];
-            if (pipe(from_remux_fd) == -1)
-            {
-                close(from_dvd_fd[0]);
-                close(from_dvd_fd[1]);
-                throw _Exception(_("Failed to create remux output pipe!"));
-            }
-
-            Ref<IOHandler> fd_writer(new FDIOHandler(from_dvd_fd[1]));
-            Ref<Executor> from_dvd(new IOHandlerChainer(dvd_ioh,
-                                                        fd_writer, 16384));
-
-            Ref<IOHandler> fd_reader(new FDIOHandler(from_remux_fd[0]));
-
-            Ref<MPEGRemuxProcessor> remux(new MPEGRemuxProcessor(from_dvd_fd[0],
-                                          from_remux_fd[1],
-                                          (unsigned char)audio_track));
-
-            RefCast(fd_reader, FDIOHandler)->addReference(RefCast(remux, Object));
-            RefCast(fd_reader, FDIOHandler)->addReference(RefCast(from_dvd, Object));
-            RefCast(fd_reader, FDIOHandler)->addReference(RefCast(fd_writer, Object));
-            RefCast(fd_reader, FDIOHandler)->closeOther(fd_writer);
-            
-
-            Ref<IOHandler> p_ioh(new ProcessIOHandler(location, nil));
-            Ref<Executor> ch(new IOHandlerChainer(fd_reader, p_ioh, 16384));
-            proc_list = Ref<Array<ProcListItem> >(new Array<ProcListItem>(2));
-            Ref<ProcListItem> pr_item(new ProcListItem(ch));
-            proc_list->append(pr_item);
-            Ref<ProcListItem> pr2_item(new ProcListItem(from_dvd));
-            proc_list->append(pr2_item);
-        }
-        catch (Exception ex)
-        {
-            unlink(location.c_str());
-            throw ex;
-        }
-    }
-#endif
-
     String check;
     if (profile->getCommand().startsWith(_(_DIR_SEPARATOR)))
     {
@@ -333,19 +235,14 @@ Ref<IOHandler> TranscodeExternalHandler::open(Ref<TranscodingProfile> profile,
    
     arglist = parseCommandLine(profile->getArguments(), location, fifo_name, range);
 
-    log_info("Arguments: %s\n", profile->getArguments().c_str());
+    log_debug("Command: %s\n", profile->getCommand().c_str());
+    log_debug("Arguments: %s\n", profile->getArguments().c_str());
     Ref<TranscodingProcessExecutor> main_proc(new TranscodingProcessExecutor(profile->getCommand(), arglist));
     main_proc->removeFile(fifo_name);
     if (isURL && (!profile->acceptURL()))
     {
         main_proc->removeFile(location);
     }
-#ifdef HAVE_LIBDVDNAV
-    if (obj->getFlag(OBJECT_FLAG_DVD_IMAGE))
-    {
-        main_proc->removeFile(location);
-    }
-#endif    
     Ref<IOHandler> io_handler(new BufferedIOHandler(Ref<IOHandler> (new ProcessIOHandler(fifo_name, RefCast(main_proc, Executor), proc_list)), profile->getBufferSize(), profile->getBufferChunkSize(), profile->getBufferInitialFillSize()));
 
     io_handler->open(UPNP_READ);
diff --git a/src/transcoding/transcode_ext_handler.h b/src/transcoding/transcode_ext_handler.h
index 2ae26cf..ac7d14f 100644
--- a/src/transcoding/transcode_ext_handler.h
+++ b/src/transcoding/transcode_ext_handler.h
@@ -32,9 +32,11 @@
 #ifndef __TRANSCODE_EXTERNAL_HANDLER_H__
 #define __TRANSCODE_EXTERNAL_HANDLER_H__
 
+#include <upnp-1.8/upnp.h>
+
 #include "common.h"
 #include "transcode_handler.h"
-#include "upnp.h"
+
 
 class TranscodeExternalHandler : public TranscodeHandler 
 {
@@ -42,8 +44,7 @@ public:
     TranscodeExternalHandler();
     virtual zmm::Ref<IOHandler> open(zmm::Ref<TranscodingProfile> profile, 
                                      zmm::String location,
-                                     zmm::Ref<CdsObject> obj, 
-                                     struct File_Info *info,
+                                     zmm::Ref<CdsObject> obj,
                                      zmm::String range);
 };
 
diff --git a/src/transcoding/transcode_handler.h b/src/transcoding/transcode_handler.h
index 4b9d47c..40001b0 100644
--- a/src/transcoding/transcode_handler.h
+++ b/src/transcoding/transcode_handler.h
@@ -32,10 +32,12 @@
 #ifndef __TRANSCODE_HANDLER_H__
 #define __TRANSCODE_HANDLER_H__
 
+#include <upnp-1.8/upnp.h>
+
 #include "common.h"
 #include "io_handler.h"
 #include "transcoding.h"
-#include "upnp.h"
+
 #include "cds_objects.h"
 
 class TranscodeHandler : public zmm::Object
@@ -44,8 +46,7 @@ public:
 //    TranscodeHandler();
     virtual zmm::Ref<IOHandler> open(zmm::Ref<TranscodingProfile> profile, 
                                      zmm::String location,
-                                     zmm::Ref<CdsObject> obj, 
-                                     struct File_Info *info,
+                                     zmm::Ref<CdsObject> obj,
                                      zmm::String range) = 0;
 protected:
     enum { UNKNOWN_CONTENT_LENGTH = -1 };
diff --git a/src/transcoding/transcoding.cc b/src/transcoding/transcoding.cc
index cdd3a69..2c82a0d 100644
--- a/src/transcoding/transcoding.cc
+++ b/src/transcoding/transcoding.cc
@@ -30,10 +30,6 @@
 /// \file transcoding.cc
 /// \brief Definitions of the Transcoding classes. 
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef EXTERNAL_TRANSCODING
 
 #include "transcoding.h"
@@ -50,7 +46,6 @@ TranscodingProfile::TranscodingProfile()
     tr_type = TR_None;
     theora = false;
     accept_url = true;
-    dvd_only = false;
     force_chunked = true;
     hide_orig_res = false;
     thumbnail = false;
@@ -68,7 +63,6 @@ TranscodingProfile::TranscodingProfile(transcoding_type_t tr_type, String name)
     theora = false;
     first_resource = false;
     accept_url = true;
-    dvd_only = false;
     force_chunked = true;
     hide_orig_res = false;
     thumbnail = false;
@@ -123,7 +117,7 @@ void TranscodingProfileList::add(zmm::String sourceMimeType, zmm::Ref<Transcodin
 {
     Ref<ObjectDictionary<TranscodingProfile> > inner = list->get(sourceMimeType);
 
-    if (inner == nil)
+    if (inner == nullptr)
         inner = Ref<ObjectDictionary<TranscodingProfile> >(new ObjectDictionary<TranscodingProfile>());
 
     inner->put(prof->getName(), prof);
@@ -142,14 +136,14 @@ Ref<TranscodingProfile> TranscodingProfileList::getByName(zmm::String name)
     for (int i = 0; i < mt_list->size(); i++)
     {
         Ref<ObjectDictionary<TranscodingProfile> > names = mt_list->get(i)->getValue();
-        if (names != nil)
+        if (names != nullptr)
         {
             Ref<TranscodingProfile> tp = names->get(name);
-            if (tp != nil)
+            if (tp != nullptr)
                 return tp;
         }
     }
-    return nil;
+    return nullptr;
 }
 
 #endif//EXTERNAL_TRANSCODING
diff --git a/src/transcoding/transcoding.h b/src/transcoding/transcoding.h
index ca04496..50f1356 100644
--- a/src/transcoding/transcoding.h
+++ b/src/transcoding/transcoding.h
@@ -35,7 +35,7 @@
 #ifndef __TRANSCODING_H__
 #define __TRANSCODING_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 #include "dictionary.h"
 #include "object_dictionary.h"
 
@@ -179,10 +179,6 @@ public:
     void setNumChannels(int chans) { number_of_channels = chans; }
     int getNumChannels() { return number_of_channels; }
 
-    /// \brief transcode or ignore streams extracted from a DVD image
-    void setOnlyDVD(bool accept) { dvd_only = accept; }
-    bool onlyDVD() { return dvd_only; }
-
 protected:
     zmm::String name;
     zmm::String tm;
@@ -191,7 +187,6 @@ protected:
     bool first_resource;
     bool theora;
     bool accept_url;
-    bool dvd_only;
     bool hide_orig_res;
     bool thumbnail;
     bool force_chunked;
diff --git a/src/transcoding/transcoding_process_executor.cc b/src/transcoding/transcoding_process_executor.cc
index 0923b48..2f6e970 100644
--- a/src/transcoding/transcoding_process_executor.cc
+++ b/src/transcoding/transcoding_process_executor.cc
@@ -29,10 +29,6 @@
 
 /// \file transcoding_process_executor.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef EXTERNAL_TRANSCODING
 
 #include <unistd.h>
@@ -47,7 +43,7 @@ TranscodingProcessExecutor::TranscodingProcessExecutor(String command, Ref<Array
 
 void TranscodingProcessExecutor::removeFile(String filename)
 {
-    if (file_list == nil)
+    if (file_list == nullptr)
         file_list = Ref<Array<StringBase> >(new Array<StringBase>(2));
 
     file_list->append(filename);
@@ -57,7 +53,7 @@ TranscodingProcessExecutor::~TranscodingProcessExecutor()
 {
     kill();
 
-    if (file_list != nil)
+    if (file_list != nullptr)
     {
         for (int i = 0; i < file_list->size(); i++)
         {
diff --git a/src/update_manager.cc b/src/update_manager.cc
index 968a908..7ca8b7a 100644
--- a/src/update_manager.cc
+++ b/src/update_manager.cc
@@ -29,17 +29,14 @@
 
 /// \file update_manager.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "update_manager.h"
 
 #include "upnp_cds.h"
 #include "storage.h"
 #include "tools.h"
 #include <sys/types.h>
-#include <signal.h>
+#include <csignal>
+#include <chrono>
 
 /* following constants in milliseconds */
 #define SPEC_INTERVAL 2000
@@ -50,16 +47,13 @@
 #define OBJECT_ID_HASH_CAPACITY 3109
 
 using namespace zmm;
+using namespace std;
 
-SINGLETON_MUTEX(UpdateManager, false);
-
-UpdateManager::UpdateManager() : Singleton<UpdateManager>()
+UpdateManager::UpdateManager() : Singleton<UpdateManager>(),
+    objectIDHash(make_shared<unordered_set<int>>()),
+    shutdownFlag(false), flushPolicy(FLUSH_SPEC),
+    lastContainerChanged(INVALID_OBJECT_ID)
 {
-    objectIDHash = Ref<DBRHash<int> >(new DBRHash<int>(OBJECT_ID_HASH_CAPACITY, MAX_OBJECT_IDS + 2 * MAX_OBJECT_IDS_OVERLOAD, INVALID_OBJECT_ID, INVALID_OBJECT_ID_2));
-    shutdownFlag = false;
-    flushPolicy = FLUSH_SPEC;
-    lastContainerChanged = INVALID_OBJECT_ID;
-    cond = Ref<Cond>(new Cond(mutex));
 }
 
 void UpdateManager::init()
@@ -72,7 +66,7 @@ void UpdateManager::init()
     
     pthread_create(
         &updateThread,
-        NULL, // &attr, // attr
+        nullptr, // &attr, // attr
         UpdateManager::staticThreadProc,
         this
     );
@@ -84,23 +78,23 @@ void UpdateManager::init()
 void UpdateManager::shutdown()
 {
     log_debug("start\n");
-    AUTOLOCK(mutex);
+    unique_lock<mutex_type> lock(mutex);
     shutdownFlag = true;
     log_debug("signalling...\n");
-    cond->signal();
-    AUTOUNLOCK();
+    cond.notify_one();
+    lock.unlock();
     log_debug("waiting for thread\n");
     if (updateThread)
-        pthread_join(updateThread, NULL);
+        pthread_join(updateThread, nullptr);
     updateThread = 0;
     log_debug("end\n");
 }
 
 void UpdateManager::containersChanged(Ref<IntArray> objectIDs, int flushPolicy)
 {
-    if (objectIDs == nil)
+    if (objectIDs == nullptr)
         return;
-    AUTOLOCK(mutex);
+    unique_lock<mutex_type> lock(mutex);
     // signalling thread if it could have been idle, because 
     // there were no unprocessed updates
     bool signal = (! haveUpdates());
@@ -120,15 +114,15 @@ void UpdateManager::containersChanged(Ref<IntArray> objectIDs, int flushPolicy)
         if (objectID != lastContainerChanged)
         {
             //log_debug("containerChanged. id: %d, signal: %d\n", objectID, signal);
-            objectIDHash->put(objectID);
+            objectIDHash->insert(objectID);
             if (split && objectIDHash->size() > MAX_OBJECT_IDS)
             {
                 while(objectIDHash->size() > MAX_OBJECT_IDS)
                 {
                     log_debug("in-between signalling...\n");
-                    cond->signal();
-                    AUTOUNLOCK();
-                    AUTORELOCK();
+                    cond.notify_one();
+                    lock.unlock();
+                    lock.lock();
                 }
             }
         }
@@ -138,7 +132,7 @@ void UpdateManager::containersChanged(Ref<IntArray> objectIDs, int flushPolicy)
     if (signal)
     {
         log_debug("signalling...\n");
-        cond->signal();
+        cond.notify_one();
     }
 }
 
@@ -146,14 +140,14 @@ void UpdateManager::containerChanged(int objectID, int flushPolicy)
 {
     if (objectID == INVALID_OBJECT_ID)
         return;
-    AUTOLOCK(mutex);
+    AutoLock lock(mutex);
     if (objectID != lastContainerChanged || flushPolicy > this->flushPolicy)
     {
         // signalling thread if it could have been idle, because 
         // there were no unprocessed updates
         bool signal = (! haveUpdates());
         log_debug("containerChanged. id: %d, signal: %d\n", objectID, signal);
-        objectIDHash->put(objectID);
+        objectIDHash->insert(objectID);
         
         // signalling if the hash gets too full
         if (objectIDHash->size() >= MAX_OBJECT_IDS)
@@ -172,7 +166,7 @@ void UpdateManager::containerChanged(int objectID, int flushPolicy)
         if (signal)
         {
             log_debug("signalling...\n");
-            cond->signal();
+            cond.notify_one();
         }
     }
     else
@@ -188,8 +182,8 @@ void UpdateManager::threadProc()
     struct timespec lastUpdate;
     getTimespecNow(&lastUpdate);
     
-    AUTOLOCK(mutex);
-    //cond->signal();
+    unique_lock<mutex_type> lock(mutex);
+    //cond.notify_one();
     while (! shutdownFlag)
     {
         if (haveUpdates())
@@ -214,18 +208,11 @@ void UpdateManager::threadProc()
                 getTimespecAfterMillis(sleepMillis, &timeout, &now);
                 log_debug("threadProc: sleeping for %ld millis\n", sleepMillis);
                 
-                int ret = cond->timedwait(&timeout);
+                cv_status ret = cond.wait_for(lock, chrono::milliseconds(sleepMillis));
                 
                 if (! shutdownFlag)
                 {
-                    if (ret != 0 && ret != ETIMEDOUT)
-                    {
-                        log_error("Fatal error: pthread_cond_timedwait returned errorcode %d\n", ret);
-                        log_error("Forcing MediaTomb shutdown.\n");
-                        print_backtrace();
-                        kill(0, SIGINT);
-                    }
-                    if (ret == ETIMEDOUT)
+                    if (ret == cv_status::timeout)
                         sendUpdates = false;
                 }
                 else
@@ -241,21 +228,17 @@ void UpdateManager::threadProc()
 
                 try
                 {
-                    hash_data_array_t<int> hash_data_array;
-                    // hash_data_array points to the array inside objectIDHash, so
-                    // we may only call clear() after we don't need the array anymore
-                    objectIDHash->getAll(&hash_data_array);
-                    updateString = Storage::getInstance()->incrementUpdateIDs(hash_data_array.data,hash_data_array.size);
+                    updateString = Storage::getInstance()->incrementUpdateIDs(objectIDHash);
                     objectIDHash->clear(); // hash_data_array will be invalid after clear()
                 }
-                catch (Exception e)
+                catch (const Exception & e)
                 {
                     e.printStackTrace();
                     log_error("Fatal error when sending updates: %s\n", e.getMessage().c_str());
                     log_error("Forcing MediaTomb shutdown.\n");
                     kill(0, SIGINT);
                 }
-                AUTOUNLOCK(); // we don't need to hold the lock during the sending of the updates
+                lock.unlock(); // we don't need to hold the lock during the sending of the updates
                 if (string_ok(updateString))
                 {
                     try
@@ -264,7 +247,7 @@ void UpdateManager::threadProc()
                     log_debug("updates sent.\n");
                     getTimespecNow(&lastUpdate);
                     }
-                    catch (Exception e)
+                    catch (const Exception & e)
                     {
                         log_error("Fatal error when sending updates: %s\n", e.getMessage().c_str());
                         log_error("Forcing MediaTomb shutdown.\n");
@@ -275,13 +258,13 @@ void UpdateManager::threadProc()
                 {
                     log_debug("NOT sending updates (string empty or invalid).\n");
                 }
-                AUTORELOCK();
+                lock.lock();
             }
         }
         else
         {
             //nothing to do
-            cond->wait();
+            cond.wait(lock);
         }
     }
 }
@@ -289,11 +272,11 @@ void UpdateManager::threadProc()
 void *UpdateManager::staticThreadProc(void *arg)
 {
     log_debug("starting update thread... thread: %d\n", pthread_self());
-    UpdateManager *inst = (UpdateManager *)arg;
+    auto *inst = (UpdateManager *)arg;
     inst->threadProc();
     Storage::getInstance()->threadCleanup();
     
     log_debug("update thread shut down. thread: %d\n", pthread_self());
-    pthread_exit(NULL);
-    return NULL;
+    pthread_exit(nullptr);
+    return nullptr;
 }
diff --git a/src/update_manager.h b/src/update_manager.h
index 0eec697..55d5ee4 100644
--- a/src/update_manager.h
+++ b/src/update_manager.h
@@ -1,29 +1,29 @@
 /*MT*
-    
+
     MediaTomb - http://www.mediatomb.cc/
-    
+
     update_manager.h - this file is part of MediaTomb.
-    
+
     Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
                        Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
+
     Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
                             Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
                             Leonhard Wimmer <leo at mediatomb.cc>
-    
+
     MediaTomb is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2
     as published by the Free Software Foundation.
-    
+
     MediaTomb is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-    
+
     You should have received a copy of the GNU General Public License
     version 2 along with MediaTomb; if not, write to the Free Software
     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
+
     $Id$
 */
 
@@ -32,10 +32,12 @@
 #ifndef __UPDATE_MANAGER_H__
 #define __UPDATE_MANAGER_H__
 
+#include <memory>
+#include <unordered_set>
+#include <condition_variable>
+
 #include "common.h"
 #include "singleton.h"
-#include "hash.h"
-#include "sync.h"
 
 #define FLUSH_ASAP 2
 #define FLUSH_SPEC 1
@@ -46,25 +48,25 @@ public:
     UpdateManager();
     virtual void shutdown();
     virtual void init();
-    
+
     void containerChanged(int objectID, int flushPolicy = FLUSH_SPEC);
     void containersChanged(zmm::Ref<zmm::IntArray> objectIDs, int flushPolicy = FLUSH_SPEC);
-    
+
 protected:
-    
+
     pthread_t updateThread;
-    zmm::Ref<Cond> cond;
-    
-    zmm::Ref<DBRHash<int> > objectIDHash;
-    
+    std::condition_variable cond;
+
+    std::shared_ptr<std::unordered_set<int> > objectIDHash;
+
     bool shutdownFlag;
     int flushPolicy;
-    
+
     int lastContainerChanged;
-    
+
     static void *staticThreadProc(void *arg);
     void threadProc();
-    
+
     inline bool haveUpdates() { return (objectIDHash->size() > 0); }
 };
 
diff --git a/src/upnp_cds.cc b/src/upnp_cds.cc
index 3f92428..3319c07 100644
--- a/src/upnp_cds.cc
+++ b/src/upnp_cds.cc
@@ -1,61 +1,54 @@
 /*MT*
-    
+
     MediaTomb - http://www.mediatomb.cc/
-    
+
     upnp_cds.cc - this file is part of MediaTomb.
-    
+
     Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
                        Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
+
     Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
                             Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
                             Leonhard Wimmer <leo at mediatomb.cc>
-    
+
     MediaTomb is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2
     as published by the Free Software Foundation.
-    
+
     MediaTomb is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-    
+
     You should have received a copy of the GNU General Public License
     version 2 along with MediaTomb; if not, write to the Free Software
     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
+
     $Id$
 */
 
 /// \file upnp_cds.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "upnp_cds.h"
 #include "config_manager.h"
 
 using namespace zmm;
 
-SINGLETON_MUTEX(ContentDirectoryService, false);
+String ContentDirectoryService::serviceType = nullptr;
+String ContentDirectoryService::serviceID = nullptr;
 
-String ContentDirectoryService::serviceType = nil;
-String ContentDirectoryService::serviceID = nil;
-
-ContentDirectoryService::ContentDirectoryService() : Singleton<ContentDirectoryService>()
+ContentDirectoryService::ContentDirectoryService() : Singleton<ContentDirectoryService>(),
+    systemUpdateID(0),
+    stringLimit(ConfigManager::getInstance()->getIntOption(CFG_SERVER_UPNP_TITLE_AND_DESC_STRING_LIMIT))
 {
-    if (serviceType == nil || serviceID == nil)
+    if (serviceType == nullptr || serviceID == nullptr)
         throw _Exception(_("serviceType or serviceID not set!"));
-    systemUpdateID = 0;
-
-    stringLimit = ConfigManager::getInstance()->getIntOption(CFG_SERVER_UPNP_TITLE_AND_DESC_STRING_LIMIT);
 }
 
 ContentDirectoryService::~ContentDirectoryService()
 {
-    serviceType = nil;
-    serviceID = nil;
+    serviceType = nullptr;
+    serviceID = nullptr;
 }
 
 void ContentDirectoryService::setStaticArgs(String _serviceType, String _serviceID)
diff --git a/src/upnp_cds.h b/src/upnp_cds.h
index 51a74ff..d3fdf08 100644
--- a/src/upnp_cds.h
+++ b/src/upnp_cds.h
@@ -1,29 +1,29 @@
 /*MT*
-    
+
     MediaTomb - http://www.mediatomb.cc/
-    
+
     upnp_cds.h - this file is part of MediaTomb.
-    
+
     Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
                        Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
+
     Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
                             Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
                             Leonhard Wimmer <leo at mediatomb.cc>
-    
+
     MediaTomb is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2
     as published by the Free Software Foundation.
-    
+
     MediaTomb is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-    
+
     You should have received a copy of the GNU General Public License
     version 2 along with MediaTomb; if not, write to the Free Software
     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
+
     $Id$
 */
 
@@ -58,8 +58,8 @@ protected:
     /// \brief UPnP standard defined action: Browse()
     /// \param request Incoming ActionRequest.
     ///
-    /// Browse(string ObjectID, string BrowseFlag, string Filter, ui4 StartingIndex, 
-    /// ui4 RequestedCount, string SortCriteria, string Result, ui4 NumberReturned, 
+    /// Browse(string ObjectID, string BrowseFlag, string Filter, ui4 StartingIndex,
+    /// ui4 RequestedCount, string SortCriteria, string Result, ui4 NumberReturned,
     /// ui4 TotalMatches, ui4 UpdateID)
     void upnp_action_Browse(zmm::Ref<ActionRequest> request);
 
@@ -69,7 +69,7 @@ protected:
     /// GetSearchCapabilities(string SearchCaps)
     void upnp_action_GetSearchCapabilities(zmm::Ref<ActionRequest> request);
 
-    /// \brief UPnP standard defined action: GetSortCapabilities() 
+    /// \brief UPnP standard defined action: GetSortCapabilities()
     /// \param request Incoming ActionRequest.
     ///
     /// GetSortCapabilities(string SortCaps)
@@ -80,39 +80,39 @@ protected:
     ///
     /// GetSystemUpdateID(ui4 Id)
     void upnp_action_GetSystemUpdateID(zmm::Ref<ActionRequest> request);
-    
+
     /// \brief UPnP standard defined service type
     /// \todo Check if it makes sense to use it as it is done now...why not define constants here?
     static zmm::String serviceType;
     /// \brief ID of the service.
     static zmm::String serviceID;
-    
+
 public:
     /// \brief Constructor for the CDS, saves the service type and service id
     /// in internal variables.
     /// \todo Check if it makes sense to use it as it is done now...why not define them as constants?
     ContentDirectoryService();
     virtual ~ContentDirectoryService();
-    
+
     static void setStaticArgs(zmm::String serviceType, zmm::String serviceID);
-    
+
     /// \brief Dispatches the ActionRequest between the available actions.
     /// \param request ActionRequest to be processed by the function.
     ///
     /// This function looks at the incoming ActionRequest and passes it on
     /// to the appropriate action for processing.
     void process_action_request(zmm::Ref<ActionRequest> request);
-    
+
     /// \brief Processes an incoming SubscriptionRequest.
     /// \param request SubscriptionRequest to be processed by the function.
     ///
     /// Looks at the incoming SubscriptionRequest and accepts the subscription
     /// if everything is ok.
     void process_subscription_request(zmm::Ref<SubscriptionRequest> request);
-    
+
     /// \brief Sends out an event to all subscribed devices.
     /// \param containerUpdateIDs_CSV Comma Separated Value list of container update ID's (as defined in the UPnP CDS specs)
-    /// 
+    ///
     /// When something in the content directory chagnes, we will send out
     /// an event to all subscribed devices. Container updates are supported,
     /// and of course the mimimum required - systemUpdateID.
diff --git a/src/upnp_cds_actions.cc b/src/upnp_cds_actions.cc
index 4dac58c..1920024 100644
--- a/src/upnp_cds_actions.cc
+++ b/src/upnp_cds_actions.cc
@@ -29,10 +29,6 @@
 
 /// \file upnp_cds_actions.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "upnp_cds.h"
 #include "server.h"
 #include "storage.h"
@@ -59,7 +55,7 @@ void ContentDirectoryService::upnp_action_Browse(Ref<ActionRequest> request)
 //            ObjectID.c_str(), BrowseFlag.c_str(), StartingIndex.c_str(), RequestedCount.c_str());
    
 
-    if (objID == nil)
+    if (objID == nullptr)
         throw UpnpException(UPNP_E_NO_SUCH_ID, _("empty object id"));
     else
         objectID = objID.toInt();
@@ -91,7 +87,7 @@ void ContentDirectoryService::upnp_action_Browse(Ref<ActionRequest> request)
     {
         arr = storage->browse(param);
     }
-    catch (Exception e)
+    catch (const Exception & e)
     {
         throw UpnpException(UPNP_E_NO_SUCH_ID, _("no such object"));
     }
diff --git a/src/upnp_cds_subscriptions.cc b/src/upnp_cds_subscriptions.cc
index f736364..0ab36ec 100644
--- a/src/upnp_cds_subscriptions.cc
+++ b/src/upnp_cds_subscriptions.cc
@@ -29,15 +29,9 @@
 
 /// \file upnp_cds_subscriptions.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "upnp_cds.h"
 #include "upnp_xml.h"
-#include "ixml.h"
 #include "server.h"
-#include "storage.h"
 
 using namespace zmm;
 using namespace mxml;
@@ -45,7 +39,7 @@ using namespace mxml;
 void ContentDirectoryService::process_subscription_request(zmm::Ref<SubscriptionRequest> request)
 {
     int err;
-    IXML_Document *event = NULL;
+    IXML_Document *event = nullptr;
 
     Ref<Element> propset, property;
    
@@ -75,7 +69,7 @@ void ContentDirectoryService::process_subscription_request(zmm::Ref<Subscription
 void ContentDirectoryService::subscription_update(String containerUpdateIDs_CSV)
 {
     int err;
-    IXML_Document *event = NULL;
+    IXML_Document *event = nullptr;
 
     Ref<Element> propset, property;
     
diff --git a/src/upnp_cm.cc b/src/upnp_cm.cc
index 92211d4..7867826 100644
--- a/src/upnp_cm.cc
+++ b/src/upnp_cm.cc
@@ -29,30 +29,25 @@
 
 /// \file upnp_cm.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "upnp_cm.h"
 
 using namespace zmm;
 using namespace mxml;
 
-SINGLETON_MUTEX(ConnectionManagerService, false);
 
-String ConnectionManagerService::serviceType = nil;
-String ConnectionManagerService::serviceID = nil;
+String ConnectionManagerService::serviceType = nullptr;
+String ConnectionManagerService::serviceID = nullptr;
 
-ConnectionManagerService::ConnectionManagerService() : Singleton<ConnectionManagerService>()
+ConnectionManagerService::ConnectionManagerService()
 {
-    if (serviceType == nil || serviceID == nil)
+    if (serviceType == nullptr || serviceID == nullptr)
         throw _Exception(_("serviceType or serviceID not set!"));
 }
 
 ConnectionManagerService::~ConnectionManagerService()
 {
-    serviceType = nil;
-    serviceID = nil;
+    serviceType = nullptr;
+    serviceID = nullptr;
 }
 
 void ConnectionManagerService::setStaticArgs(String _serviceType, String _serviceID)
diff --git a/src/upnp_cm_actions.cc b/src/upnp_cm_actions.cc
index 6961926..d53c366 100644
--- a/src/upnp_cm_actions.cc
+++ b/src/upnp_cm_actions.cc
@@ -29,10 +29,6 @@
 
 /// \file upnp_cm_actions.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "tools.h"
 #include "upnp_cm.h"
 #include "storage.h"
diff --git a/src/upnp_cm_subscriptions.cc b/src/upnp_cm_subscriptions.cc
index db476fa..425eda7 100644
--- a/src/upnp_cm_subscriptions.cc
+++ b/src/upnp_cm_subscriptions.cc
@@ -29,16 +29,9 @@
 
 /// \file upnp_cm_subscriptions.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "tools.h"
 #include "upnp_cm.h"
 #include "server.h"
-#include "upnp_xml.h"
-#include "ixml.h"
-#include "storage.h"
 
 using namespace zmm;
 using namespace mxml;
@@ -46,7 +39,7 @@ using namespace mxml;
 void ConnectionManagerService::process_subscription_request(zmm::Ref<SubscriptionRequest> request)
 {
     int err;
-    IXML_Document *event = NULL;
+    IXML_Document *event = nullptr;
 
     Ref<Element> propset, property;
 
@@ -77,7 +70,7 @@ void ConnectionManagerService::process_subscription_request(zmm::Ref<Subscriptio
 void ConnectionManagerService::subscription_update(String sourceProtocol_CSV)
 {
     int err;
-    IXML_Document *event = NULL;
+    IXML_Document *event = nullptr;
 
     Ref<Element> propset, property;
 
diff --git a/src/upnp_mrreg.cc b/src/upnp_mrreg.cc
index b026d21..58bc252 100644
--- a/src/upnp_mrreg.cc
+++ b/src/upnp_mrreg.cc
@@ -29,10 +29,6 @@
 
 /// \file upnp_mrreg.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #if defined(ENABLE_MRREG)
 
 #include "upnp_mrreg.h"
@@ -40,21 +36,20 @@
 using namespace zmm;
 using namespace mxml;
 
-SINGLETON_MUTEX(MRRegistrarService, false);
 
-String MRRegistrarService::serviceType = nil;
-String MRRegistrarService::serviceID = nil;
+String MRRegistrarService::serviceType = nullptr;
+String MRRegistrarService::serviceID = nullptr;
 
 MRRegistrarService::MRRegistrarService() : Singleton<MRRegistrarService>()
 {
-    if (serviceType == nil || serviceID == nil)
+    if (serviceType == nullptr || serviceID == nullptr)
         throw _Exception(_("serviceType or serviceID not set!"));
 }
 
 MRRegistrarService::~MRRegistrarService()
 {
-    serviceType = nil;
-    serviceID = nil;
+    serviceType = nullptr;
+    serviceID = nullptr;
 }
 
 void MRRegistrarService::setStaticArgs(String _serviceType, String _serviceID)
diff --git a/src/upnp_mrreg_actions.cc b/src/upnp_mrreg_actions.cc
index f126faa..82ba79d 100644
--- a/src/upnp_mrreg_actions.cc
+++ b/src/upnp_mrreg_actions.cc
@@ -29,10 +29,6 @@
 
 /// \file upnp_mrreg_actions.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #if defined(ENABLE_MRREG)
 
 #include "tools.h"
diff --git a/src/upnp_mrreg_subscriptions.cc b/src/upnp_mrreg_subscriptions.cc
index 9b8a266..25e2bb5 100644
--- a/src/upnp_mrreg_subscriptions.cc
+++ b/src/upnp_mrreg_subscriptions.cc
@@ -29,10 +29,6 @@
 
 /// \file upnp_mrreg_subscriptions.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #if defined(ENABLE_MRREG)
 
 #include "tools.h"
diff --git a/src/upnp_xml.cc b/src/upnp_xml.cc
index 61f7beb..c95b76a 100644
--- a/src/upnp_xml.cc
+++ b/src/upnp_xml.cc
@@ -29,10 +29,6 @@
 
 /// \file upnp_xml.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "upnp_xml.h"
 #include "server.h"
 #include "cds_resource_manager.h"
@@ -109,12 +105,36 @@ Ref<Element> UpnpXML_DIDLRenderObject(Ref<CdsObject> obj, bool renderActions, in
                      (upnp_class == UPNP_DEFAULT_CLASS_MUSIC_TRACK)))
                 result->appendTextChild(key, el->getValue());
         }
-        
-//        log_debug("ITEM HAS FOLLOWING METADATA: %s\n", item->getMetadata()->encode().c_str());
-        
-        
+
         CdsResourceManager::addResources(item, result);
         
+        if (upnp_class == UPNP_DEFAULT_CLASS_MUSIC_TRACK) {
+            Ref<Storage> storage = Storage::getInstance();
+            // extract extension-less, lowercase track name to search for corresponding
+            // image as cover alternative
+            String dctl = item->getTitle().toLower();
+            String trackArtBase = String();
+            int doti = dctl.rindex('.');
+            if (doti>=0) {
+                trackArtBase = dctl.substring(0, doti);
+            } 
+            String aa_id = storage->findFolderImage(item->getParentID(), trackArtBase);
+            if (aa_id != nullptr) {
+                String url;
+                Ref<Dictionary> dict(new Dictionary());
+                dict->put(_(URL_OBJECT_ID), aa_id);
+
+                url = Server::getInstance()->getVirtualURL() +
+                        _(_URL_PARAM_SEPARATOR) +
+                        CONTENT_MEDIA_HANDLER + _(_URL_PARAM_SEPARATOR) +
+                        dict->encodeSimple() + _(_URL_PARAM_SEPARATOR) +
+                        _(URL_RESOURCE_ID) + _(_URL_PARAM_SEPARATOR) + "0";
+                log_debug("UpnpXML_DIDLRenderObject: url: %s\n", url.c_str());
+                Ref<Element> aa(new Element(MetadataHandler::getMetaFieldName(M_ALBUMARTURI)));
+                aa->setText(url);
+                result->appendElementChild(aa);
+            }
+        }
         result->setName(_("item"));
     }
     else if (IS_CDS_CONTAINER(objectType))
@@ -125,6 +145,86 @@ Ref<Element> UpnpXML_DIDLRenderObject(Ref<CdsObject> obj, bool renderActions, in
         int childCount = cont->getChildCount();
         if (childCount >= 0)
             result->setAttribute(_("childCount"), String::from(childCount));
+
+        String upnp_class = obj->getClass();
+        log_debug("container is class: %s\n", upnp_class.c_str());
+        if (upnp_class == UPNP_DEFAULT_CLASS_MUSIC_ALBUM) {
+            Ref<Dictionary> meta = obj->getMetadata();
+            Ref<Array<DictionaryElement> > elements = meta->getElements();
+            int len = elements->size();
+            String key;
+
+            //log_debug("Album has %d metadata(s)\n", len);
+
+            for (int i = 0; i < len; i++)
+            {
+                Ref<DictionaryElement> el = elements->get(i);
+                key = el->getKey();
+                //log_debug("Container %s\n", key.c_str());
+
+                if (key == MetadataHandler::getMetaFieldName(M_ARTIST)) {
+                    result->appendElementChild(UpnpXML_DIDLRenderCreator(el->getValue()));
+                }
+            }
+        }
+        if (upnp_class == UPNP_DEFAULT_CLASS_MUSIC_ALBUM || upnp_class == UPNP_DEFAULT_CLASS_CONTAINER) {
+            Ref<Storage> storage = Storage::getInstance();
+            String aa_id = storage->findFolderImage(cont->getID(), String());
+
+            if (aa_id != nullptr) {
+                log_debug("Using folder image as artwork for container\n");
+
+                String url;
+                Ref<Dictionary> dict(new Dictionary());
+                dict->put(_(URL_OBJECT_ID), aa_id);
+
+                url = Server::getInstance()->getVirtualURL() +
+                    _(_URL_PARAM_SEPARATOR) +
+                    CONTENT_MEDIA_HANDLER + _(_URL_PARAM_SEPARATOR) +
+                    dict->encodeSimple() + _(_URL_PARAM_SEPARATOR) +
+                    _(URL_RESOURCE_ID) + _(_URL_PARAM_SEPARATOR) + "0";
+
+                result->appendElementChild(UpnpXML_DIDLRenderAlbumArtURI(url));
+
+            } else if (upnp_class == UPNP_DEFAULT_CLASS_MUSIC_ALBUM) {
+                // try to find the first track and use its artwork
+                auto items = storage->getObjects(cont->getID(), true);
+                if (items != nullptr) {
+
+                    bool artAdded = false;
+                    for (const auto &id : *items) {
+                        if (artAdded)
+                            break;
+
+                        Ref<CdsObject> obj = storage->loadObject(id);
+                        if (obj->getClass() != UPNP_DEFAULT_CLASS_MUSIC_TRACK)
+                            continue;
+
+                        Ref<CdsItem> item = RefCast(obj, CdsItem);
+
+                        auto resources = item->getResources();
+
+                        for (int i = 1; i < resources->size(); i++) {
+                            auto res = resources->get(i);
+                            // only add upnp:AlbumArtURI if we have an AA, skip the resource
+                            if ((res->getHandlerType() == CH_ID3) ||
+                                (res->getHandlerType() == CH_MP4) ||
+                                (res->getHandlerType() == CH_FLAC) ||
+                                (res->getHandlerType() == CH_FANART) ||
+                                (res->getHandlerType() == CH_EXTURL)) {
+
+                                String url = CdsResourceManager::getArtworkUrl(item);
+                                result->appendElementChild(UpnpXML_DIDLRenderAlbumArtURI(url));
+
+                                artAdded = true;
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
         
     }
     
@@ -137,7 +237,7 @@ Ref<Element> UpnpXML_DIDLRenderObject(Ref<CdsObject> obj, bool renderActions, in
         result->appendTextChild(_("mime-type"), aitem->getMimeType());
     }
    
-//    log_debug("renderen DIDL: \n%s\n", result->print().c_str());
+    // log_debug("Rendered DIDL: \n%s\n", result->print().c_str());
 
     return result;
 }
@@ -153,30 +253,30 @@ void UpnpXML_DIDLUpdateObject(Ref<CdsObject> obj, String text)
         Ref<CdsActiveItem> aitem = RefCast(obj, CdsActiveItem);
 
         String title = root->getChildText(_("dc:title"));
-        if (title != nil && title != "")
+        if (title != nullptr && title != "")
             aitem->setTitle(title);
 
         /// \todo description should be taken from the dictionary      
         String description = root->getChildText(_("dc:description"));
-        if (description == nil)
+        if (description == nullptr)
             description = _("");
         aitem->setMetadata(MetadataHandler::getMetaFieldName(M_DESCRIPTION),
                     description);
 
         String location = root->getChildText(_("location"));
-        if (location != nil && location != "")
+        if (location != nullptr && location != "")
             aitem->setLocation(location);
     
         String mimeType = root->getChildText(_("mime-type"));
-        if (mimeType != nil && mimeType != "")
+        if (mimeType != nullptr && mimeType != "")
             aitem->setMimeType(mimeType);
 
         String action = root->getChildText(_("action"));
-        if (action != nil && action != "")
+        if (action != nullptr && action != "")
             aitem->setAction(action);
 
         String state = root->getChildText(_("state"));
-        if (state == nil)
+        if (state == nullptr)
             state = _("");
         aitem->setState(state);
     }
@@ -398,3 +498,17 @@ Ref<Element> UpnpXML_DIDLRenderCaptionInfo(String URL) {
 
     return cap;
 }
+
+Ref<Element> UpnpXML_DIDLRenderCreator(String creator) {
+    Ref<Element> out(new Element(_("dc:creator")));
+
+    out->setText(creator);
+
+    return out;
+}
+
+Ref<Element> UpnpXML_DIDLRenderAlbumArtURI(String uri) {
+    Ref<Element> out(new Element(_("upnp:albumArtURI")));
+    out->setText(uri);
+    return out;
+}
diff --git a/src/upnp_xml.h b/src/upnp_xml.h
index f8d29ff..69acb8b 100644
--- a/src/upnp_xml.h
+++ b/src/upnp_xml.h
@@ -70,7 +70,7 @@ zmm::Ref<mxml::Element> UpnpXML_CreateEventPropertySet();
 ///
 /// Some elements are statically defined in common.h, others are loaded
 /// from the config with the help of the ConfigManager.
-zmm::Ref<mxml::Element> UpnpXML_RenderDeviceDescription(zmm::String presentationUTL = nil);
+zmm::Ref<mxml::Element> UpnpXML_RenderDeviceDescription(zmm::String presentationUTL = nullptr);
 
 /// \brief Renders a resource tag (part of DIDL-Lite XML)
 /// \param URL download location of the item (will be child element of the <res> tag)
@@ -80,4 +80,8 @@ zmm::Ref<mxml::Element> UpnpXML_DIDLRenderResource(zmm::String URL, zmm::Ref<Dic
 /// \brief Renders a subtitle resource tag (Samsung proprietary extension)
 /// \param URL download location of the video item
 zmm::Ref<mxml::Element> UpnpXML_DIDLRenderCaptionInfo(zmm::String URL);
+
+zmm::Ref<mxml::Element> UpnpXML_DIDLRenderCreator(zmm::String creator);
+
+zmm::Ref<mxml::Element> UpnpXML_DIDLRenderAlbumArtURI(zmm::String uri);
 #endif // __UPNP_XML_H__
diff --git a/src/url.cc b/src/url.cc
index c139342..01d00e3 100644
--- a/src/url.cc
+++ b/src/url.cc
@@ -29,10 +29,6 @@
 
 /// \file url.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_CURL
 
 #include <pthread.h>
@@ -44,9 +40,8 @@
 
 using namespace zmm;
 
-URL::URL(size_t buffer_hint)
+URL::URL(size_t buffer_hint) : buffer_hint(buffer_hint)
 {
-    this->buffer_hint = buffer_hint;
 }
 
 Ref<StringBuffer> URL::download(String URL, long *HTTP_retcode, 
@@ -57,11 +52,11 @@ Ref<StringBuffer> URL::download(String URL, long *HTTP_retcode,
     bool cleanup = false;
     char error_buffer[CURL_ERROR_SIZE] = {'\0'};
 
-    if (curl_handle == NULL)
+    if (curl_handle == nullptr)
     {
         curl_handle = curl_easy_init();
         cleanup = true;
-        if (curl_handle == NULL)
+        if (curl_handle == nullptr)
             throw _Exception(_("Invalid curl handle!\n"));
     }
 
@@ -146,11 +141,11 @@ Ref<URL::Stat> URL::getInfo(String URL, CURL *curl_handle)
     String mt;
     String used_url;
 
-    if (curl_handle == NULL)
+    if (curl_handle == nullptr)
     {
         curl_handle = curl_easy_init();
         cleanup = true;
-        if (curl_handle == NULL)
+        if (curl_handle == nullptr)
             throw _Exception(_("Invalid curl handle!\n"));
     }
 
@@ -170,7 +165,7 @@ Ref<URL::Stat> URL::getInfo(String URL, CURL *curl_handle)
     {
         getMT->compile(_("\nContent-Type: ([^\n]+)\n"), REG_ICASE);
     }
-    catch (Exception ex)
+    catch (const Exception & ex)
     {
         if (cleanup)
             curl_easy_cleanup(curl_handle);
@@ -193,7 +188,7 @@ Ref<URL::Stat> URL::getInfo(String URL, CURL *curl_handle)
     {
         getCL->compile(_("\nContent-Length: ([^\n]+)\n"), REG_ICASE);
     }
-    catch (Exception ex)
+    catch (const Exception & ex)
     {
         if (cleanup)
             curl_easy_cleanup(curl_handle);
@@ -226,7 +221,7 @@ Ref<URL::Stat> URL::getInfo(String URL, CURL *curl_handle)
         throw _Exception(error_buffer);
     }
 
-    if (ct == NULL)
+    if (ct == nullptr)
         mt = _(MIMETYPE_DEFAULT);
     else
         mt = ct;
@@ -242,7 +237,7 @@ Ref<URL::Stat> URL::getInfo(String URL, CURL *curl_handle)
         throw _Exception(error_buffer);
     }
 
-    if (c_url == NULL)
+    if (c_url == nullptr)
         used_url = URL;
     else
         used_url = c_url;
@@ -258,8 +253,8 @@ Ref<URL::Stat> URL::getInfo(String URL, CURL *curl_handle)
 
 size_t URL::dl(void *buf, size_t size, size_t nmemb, void *data)
 {
-    StringBuffer *buffer = (StringBuffer *)data;
-    if (buffer == NULL)
+    auto *buffer = (StringBuffer *)data;
+    if (buffer == nullptr)
         return 0;
 
     size_t s = size * nmemb;
diff --git a/src/url.h b/src/url.h
index 8d92e49..6847cfc 100644
--- a/src/url.h
+++ b/src/url.h
@@ -36,7 +36,8 @@
 #define __URL_H__
 
 #include <curl/curl.h>
-#include "zmmf/zmmf.h"
+
+#include "zmm/zmmf.h"
 #include "zmm/zmm.h"
 
 class URL : public zmm::Object
diff --git a/src/url_request_handler.cc b/src/url_request_handler.cc
index a31bf24..93e818d 100644
--- a/src/url_request_handler.cc
+++ b/src/url_request_handler.cc
@@ -29,16 +29,14 @@
 
 /// \file url_request_handler.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef HAVE_CURL
 
+#include <upnp-1.8/ixml.h>
+
 #include "server.h"
 #include "common.h"
 #include "storage.h"
-#include "ixml.h"
+
 #include "buffered_io_handler.h"
 #include "dictionary.h"
 #include "url_request_handler.h"
@@ -61,7 +59,7 @@ URLRequestHandler::URLRequestHandler() : RequestHandler()
 {
 }
 
-void URLRequestHandler::get_info(IN const char *filename, OUT struct File_Info *info)
+void URLRequestHandler::get_info(IN const char *filename, OUT UpnpFileInfo *info)
 {
     log_debug("start\n");
         
@@ -82,7 +80,7 @@ void URLRequestHandler::get_info(IN const char *filename, OUT struct File_Info *
                filename, parameters.c_str());
     
     String objID = dict->get(_("object_id"));
-    if (objID == nil)
+    if (objID == nullptr)
     {
         //log_error("object_id not found in url\n");
         throw _Exception(_("get_info: object_id not found"));
@@ -110,12 +108,12 @@ void URLRequestHandler::get_info(IN const char *filename, OUT struct File_Info *
     {
         Ref<TranscodingProfile> tp = ConfigManager::getInstance()->getTranscodingProfileListOption(CFG_TRANSCODING_PROFILE_LIST)->getByName(tr_profile);
 
-        if (tp == nil)
+        if (tp == nullptr)
             throw _Exception(_("Transcoding requested but no profile "
                                "matching the name ") + tr_profile + " found");
 
         mimeType = tp->getTargetMimeType();
-        info->file_length = -1;
+        UpnpFileInfo_set_FileLength(info, -1);
     }
     else
 #endif
@@ -142,36 +140,35 @@ void URLRequestHandler::get_info(IN const char *filename, OUT struct File_Info *
         try
         { 
             st = u->getInfo(url);
-            info->file_length = st->getSize();
+            UpnpFileInfo_set_FileLength(info, st->getSize());
             header = _("Accept-Ranges: bytes");
             log_debug("URL used for request: %s\n", st->getURL().c_str());
         }
-        catch (Exception ex)
+        catch (const Exception & ex)
         {
             log_warning("%s\n", ex.getMessage().c_str());
-            info->file_length = -1;
+            UpnpFileInfo_set_FileLength(info, -1);
         }
 
         mimeType = item->getMimeType();
     }
 
-    info->is_readable = 1;
-    info->last_modified = 0;
-    info->is_directory = 0;
+    UpnpFileInfo_set_IsReadable(info, 1);
+    UpnpFileInfo_set_LastModified(info, 0);
+    UpnpFileInfo_set_IsDirectory(info, 0);
 
-    if (string_ok(header))
-        info->http_header = ixmlCloneDOMString(header.c_str());
-    else
-        info->http_header = NULL;
+    if (string_ok(header)) {
+        UpnpFileInfo_set_ExtraHeaders(info,
+                                      ixmlCloneDOMString(header.c_str()));
+    }
 
-    info->content_type = ixmlCloneDOMString(mimeType.c_str());
+    UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString(mimeType.c_str()));
     log_debug("web_get_info(): end\n");
 
     /// \todo transcoding for get_info
 }
 
 Ref<IOHandler> URLRequestHandler::open(IN const char *filename,
-                                       OUT struct File_Info *info,
                                        IN enum UpnpOpenFileMode mode,
                                        IN String range)
 {
@@ -198,7 +195,7 @@ Ref<IOHandler> URLRequestHandler::open(IN const char *filename,
                filename, parameters.c_str());
 
     String objID = dict->get(_("object_id"));
-    if (objID == nil)
+    if (objID == nullptr)
     {
         throw _Exception(_("object_id not found"));
     }
@@ -233,10 +230,10 @@ Ref<IOHandler> URLRequestHandler::open(IN const char *filename,
 
     log_debug("Online content url: %s\n", url.c_str());
 
-    info->is_readable = 1;
-    info->last_modified = 0;
-    info->is_directory = 0;
-    info->http_header = NULL;
+    //info->is_readable = 1;
+    //info->last_modified = 0;
+    //info->is_directory = 0;
+    //info->http_header = NULL;
 
 #ifdef EXTERNAL_TRANSCODING
     tr_profile = dict->get(_(URL_PARAM_TRANSCODE_PROFILE_NAME));
@@ -245,13 +242,13 @@ Ref<IOHandler> URLRequestHandler::open(IN const char *filename,
     {
         Ref<TranscodingProfile> tp = ConfigManager::getInstance()->getTranscodingProfileListOption(CFG_TRANSCODING_PROFILE_LIST)->getByName(tr_profile);
 
-        if (tp == nil)
+        if (tp == nullptr)
             throw _Exception(_("Transcoding of file ") + url +
                     " but no profile matching the name " +
                     tr_profile + " found");
 
         Ref<TranscodeDispatcher> tr_d(new TranscodeDispatcher());
-        return tr_d->open(tp, url, RefCast(item, CdsObject), info, range);
+        return tr_d->open(tp, url, RefCast(item, CdsObject), range);
     }
     else
 #endif
@@ -261,24 +258,26 @@ Ref<IOHandler> URLRequestHandler::open(IN const char *filename,
         try
         {
             st = u->getInfo(url);
-            info->file_length = st->getSize();
+           // info->file_length = st->getSize();
             header = _("Accept-Ranges: bytes");
             log_debug("URL used for request: %s\n", st->getURL().c_str());
         }
-        catch (Exception ex)
+        catch (const Exception & ex)
         {
             log_warning("%s\n", ex.getMessage().c_str());
-            info->file_length = -1;
+            //info->file_length = -1;
         }
         mimeType = item->getMimeType();
-        info->content_type = ixmlCloneDOMString(mimeType.c_str());
+       // info->content_type = ixmlCloneDOMString(mimeType.c_str());
     }
 
+    /* FIXME headers
     if (string_ok(header))
         info->http_header = ixmlCloneDOMString(header.c_str());
+    */
 
     ///\todo make curl io handler configurable for url request handler
-    Ref<IOHandler> io_handler(new CurlIOHandler(url, NULL, 1024*1024, 0));
+    Ref<IOHandler> io_handler(new CurlIOHandler(url, nullptr, 1024*1024, 0));
 
     io_handler->open(mode);
     
diff --git a/src/url_request_handler.h b/src/url_request_handler.h
index ac43c1c..a453081 100644
--- a/src/url_request_handler.h
+++ b/src/url_request_handler.h
@@ -40,9 +40,8 @@ class URLRequestHandler : public RequestHandler
 {
 public:
     URLRequestHandler();
-    virtual void get_info(IN const char *filename, OUT struct File_Info *info);
-    virtual zmm::Ref<IOHandler> open(IN const char *filename, 
-                                     OUT struct File_Info *info, 
+    virtual void get_info(IN const char *filename, OUT UpnpFileInfo *info);
+    virtual zmm::Ref<IOHandler> open(IN const char *filename,
                                      IN enum UpnpOpenFileMode mode,
                                      IN zmm::String range);
 };
diff --git a/src/uuid/COPYING b/src/uuid/COPYING
deleted file mode 100644
index 50cf486..0000000
--- a/src/uuid/COPYING
+++ /dev/null
@@ -1,851 +0,0 @@
-This package, the EXT2 filesystem utilities, are made available under
-the GNU Public License.
-
-However, I request that if the version string in the file version.h
-contains the string "pre-", or "WIP" that this version of e2fsprogs be
-distributed in source form only.  Please feel free to give a copy of
-the e2fsck binary to help a friend recover his or her filesystem, as
-the need arises.  However, "pre" or "WIP" indicates that this release
-is under development, and available for ALPHA testing.  So for your
-protection as much as mine, I'd prefer that it not appear in a some
-distribution --- especially not a CD-ROM distribution!
-
-The most recent officially distributed version can be found at
-http://e2fsprogs.sourceforge.net.  If you need to make a distribution,
-that's the one you should use.  If there is some reason why you'd like
-a more recent version that is still in ALPHA testing for your
-distribution, please contact me (tytso at mit.edu), and we will very
-likely be able to work out something that will work for all concerned.
-The release schedules for this package are flexible, if you give me
-enough lead time.
-
-
-					Theodore Ts'o
-					15-Mar-2003
-
-----------------------------------------------------------------------
-
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year  name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
-
-----------------------------------------------------------------------
-
-		  GNU LIBRARY GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1991 Free Software Foundation, Inc.
-    		    59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the library GPL.  It is
- numbered 2 because it goes with version 2 of the ordinary GPL.]
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Library General Public License, applies to some
-specially designated Free Software Foundation software, and to any
-other libraries whose authors decide to use it.  You can use it for
-your libraries, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if
-you distribute copies of the library, or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link a program with the library, you must provide
-complete object files to the recipients so that they can relink them
-with the library, after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  Our method of protecting your rights has two steps: (1) copyright
-the library, and (2) offer you this license which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  Also, for each distributor's protection, we want to make certain
-that everyone understands that there is no warranty for this free
-library.  If the library is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original
-version, so that any problems introduced by others will not reflect on
-the original authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that companies distributing free
-software will individually obtain patent licenses, thus in effect
-transforming the program into proprietary software.  To prevent this,
-we have made it clear that any patent must be licensed for everyone's
-free use or not licensed at all.
-
-  Most GNU software, including some libraries, is covered by the ordinary
-GNU General Public License, which was designed for utility programs.  This
-license, the GNU Library General Public License, applies to certain
-designated libraries.  This license is quite different from the ordinary
-one; be sure to read it in full, and don't assume that anything in it is
-the same as in the ordinary license.
-
-  The reason we have a separate public license for some libraries is that
-they blur the distinction we usually make between modifying or adding to a
-program and simply using it.  Linking a program with a library, without
-changing the library, is in some sense simply using the library, and is
-analogous to running a utility program or application program.  However, in
-a textual and legal sense, the linked executable is a combined work, a
-derivative of the original library, and the ordinary General Public License
-treats it as such.
-
-  Because of this blurred distinction, using the ordinary General
-Public License for libraries did not effectively promote software
-sharing, because most developers did not use the libraries.  We
-concluded that weaker conditions might promote sharing better.
-
-  However, unrestricted linking of non-free programs would deprive the
-users of those programs of all benefit from the free status of the
-libraries themselves.  This Library General Public License is intended to
-permit developers of non-free programs to use free libraries, while
-preserving your freedom as a user of such programs to change the free
-libraries that are incorporated in them.  (We have not seen how to achieve
-this as regards changes in header files, but we have achieved it as regards
-changes in the actual functions of the Library.)  The hope is that this
-will lead to faster development of free libraries.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, while the latter only
-works together with the library.
-
-  Note that it is possible for a library to be covered by the ordinary
-General Public License rather than by this special one.
-
-		  GNU LIBRARY GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library which
-contains a notice placed by the copyright holder or other authorized
-party saying it may be distributed under the terms of this Library
-General Public License (also called "this License").  Each licensee is
-addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
-  6. As an exception to the Sections above, you may also compile or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    c) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    d) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the source code distributed need not include anything that is normally
-distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Library General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-			    NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-           How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
diff --git a/src/uuid/clear.c b/src/uuid/clear.c
deleted file mode 100644
index 65d0105..0000000
--- a/src/uuid/clear.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * clear.c -- Clear a UUID
- * 
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU 
- * Library General Public License.
- * %End-Header%
- */
-
-#include "string.h"
-
-#include "uuidP.h"
-
-void uuid_clear(uuid_t uu)
-{
-	memset(uu, 0, 16);
-}
diff --git a/src/uuid/compare.c b/src/uuid/compare.c
deleted file mode 100644
index 3099589..0000000
--- a/src/uuid/compare.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * compare.c --- compare whether or not two UUID's are the same
- *
- * Returns 0 if the two UUID's are different, and 1 if they are the same.
- * 
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU 
- * Library General Public License.
- * %End-Header%
- */
-
-#include "uuidP.h"
-#include <string.h>
-
-#define UUCMP(u1,u2) if (u1 != u2) return((u1 < u2) ? -1 : 1);
-
-int uuid_compare(const uuid_t uu1, const uuid_t uu2)
-{
-	struct uuid	uuid1, uuid2;
-
-	uuid_unpack2(uu1, &uuid1);
-	uuid_unpack2(uu2, &uuid2);
-
-	UUCMP(uuid1.time_low, uuid2.time_low);
-	UUCMP(uuid1.time_mid, uuid2.time_mid);
-	UUCMP(uuid1.time_hi_and_version, uuid2.time_hi_and_version);
-	UUCMP(uuid1.clock_seq, uuid2.clock_seq);
-	return memcmp(uuid1.node, uuid2.node, 6);
-}
diff --git a/src/uuid/copy.c b/src/uuid/copy.c
deleted file mode 100644
index b9a34da..0000000
--- a/src/uuid/copy.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * copy.c --- copy UUIDs
- * 
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU 
- * Library General Public License.
- * %End-Header%
- */
-
-#include "uuidP.h"
-
-void uuid_copy(uuid_t dst, const uuid_t src)
-{
-	unsigned char		*cp1;
-	const unsigned char	*cp2;
-	int			i;
-
-	for (i=0, cp1 = dst, cp2 = src; i < 16; i++)
-		*cp1++ = *cp2++;
-}
diff --git a/src/uuid/gen_uuid.c b/src/uuid/gen_uuid.c
deleted file mode 100644
index d27a93c..0000000
--- a/src/uuid/gen_uuid.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * gen_uuid.c --- generate a DCE-compatible uuid
- *
- * Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU 
- * Library General Public License.
- * %End-Header%
- */
-
-/*
- * Force inclusion of SVID stuff since we need it if we're compiling in
- * gcc-wall wall mode
- */
-#define _SVID_SOURCE
-
-#include "autoconfig.h"
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>
-#endif
-#ifdef HAVE_NET_IF_H
-#include <net/if.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
-#include "uuidP.h"
-
-#ifdef HAVE_SRANDOM
-#define srand(x) 	srandom(x)
-#define rand() 		random()
-#endif
-
-static int get_random_fd(void)
-{
-	struct timeval	tv;
-	static int	fd = -2;
-	int		i;
-
-	if (fd == -2) {
-		gettimeofday(&tv, 0);
-		fd = open("/dev/urandom", O_RDONLY);
-		if (fd == -1)
-			fd = open("/dev/random", O_RDONLY);
-			//fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
-		srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
-	}
-	/* Crank the random number generator a few times */
-	gettimeofday(&tv, 0);
-	for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
-		rand();
-	return fd;
-}
-
-
-/*
- * Generate a series of random bytes.  Use /dev/urandom if possible,
- * and if not, use srandom/random.
- */
-static void get_random_bytes(void *buf, int nbytes)
-{
-	int i, n = nbytes, fd = get_random_fd();
-	int lose_counter = 0;
-	unsigned char *cp = (unsigned char *) buf;
-
-	if (fd >= 0) {
-		while (n > 0) {
-			i = read(fd, cp, n);
-			if (i <= 0) {
-				if (lose_counter++ > 16)
-					break;
-				continue;
-			}
-			n -= i;
-			cp += i;
-			lose_counter = 0;
-		}
-	}
-	
-	/*
-	 * We do this all the time, but this is the only source of
-	 * randomness if /dev/random/urandom is out to lunch.
-	 */
-	for (cp = buf, i = 0; i < nbytes; i++)
-		*cp++ ^= (rand() >> 7) & 0xFF;
-	return;
-}
-
-/*
- * Get the ethernet hardware address, if we can find it...
- */
-static int get_node_id(unsigned char *node_id)
-{
-#ifdef HAVE_NET_IF_H
-	int 		sd;
-	struct ifreq 	ifr, *ifrp;
-	struct ifconf 	ifc;
-	char buf[1024];
-	int		n, i;
-	unsigned char 	*a;
-	
-/*
- * BSD 4.4 defines the size of an ifreq to be
- * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
- * However, under earlier systems, sa_len isn't present, so the size is 
- * just sizeof(struct ifreq)
- */
-#ifdef HAVE_SA_LEN
-#ifndef max
-#define max(a,b) ((a) > (b) ? (a) : (b))
-#endif
-#define ifreq_size(i) max(sizeof(struct ifreq),\
-     sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
-#else
-#define ifreq_size(i) sizeof(struct ifreq)
-#endif /* HAVE_SA_LEN*/
-
-	sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
-	if (sd < 0) {
-		return -1;
-	}
-	memset(buf, 0, sizeof(buf));
-	ifc.ifc_len = sizeof(buf);
-	ifc.ifc_buf = buf;
-	if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
-		close(sd);
-		return -1;
-	}
-	n = ifc.ifc_len;
-	for (i = 0; i < n; i+= ifreq_size(*ifr) ) {
-		ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);
-		strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
-#ifdef SIOCGIFHWADDR
-		if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
-			continue;
-		a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
-#else
-#ifdef SIOCGENADDR
-		if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
-			continue;
-		a = (unsigned char *) ifr.ifr_enaddr;
-#else
-		/*
-		 * XXX we don't have a way of getting the hardware
-		 * address
-		 */
-		close(sd);
-		return 0;
-#endif /* SIOCGENADDR */
-#endif /* SIOCGIFHWADDR */
-		if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
-			continue;
-		if (node_id) {
-			memcpy(node_id, a, 6);
-			close(sd);
-			return 1;
-		}
-	}
-	close(sd);
-#endif
-	return 0;
-}
-
-/* Assume that the gettimeofday() has microsecond granularity */
-#define MAX_ADJUSTMENT 10
-
-static int get_clock(__u32 *clock_high, __u32 *clock_low, __u16 *ret_clock_seq)
-{
-	static int			adjustment = 0;
-	static struct timeval		last = {0, 0};
-	static __u16			clock_seq;
-	struct timeval 			tv;
-	unsigned long long		clock_reg;
-	
-try_again:
-	gettimeofday(&tv, 0);
-	if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
-		get_random_bytes(&clock_seq, sizeof(clock_seq));
-		clock_seq &= 0x1FFF;
-		last = tv;
-		last.tv_sec--;
-	}
-	if ((tv.tv_sec < last.tv_sec) ||
-	    ((tv.tv_sec == last.tv_sec) &&
-	     (tv.tv_usec < last.tv_usec))) {
-		clock_seq = (clock_seq+1) & 0x1FFF;
-		adjustment = 0;
-		last = tv;
-	} else if ((tv.tv_sec == last.tv_sec) &&
-	    (tv.tv_usec == last.tv_usec)) {
-		if (adjustment >= MAX_ADJUSTMENT)
-			goto try_again;
-		adjustment++;
-	} else {
-		adjustment = 0;
-		last = tv;
-	}
-		
-	clock_reg = tv.tv_usec*10 + adjustment;
-	clock_reg += ((unsigned long long) tv.tv_sec)*10000000;
-	clock_reg += (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
-
-	*clock_high = clock_reg >> 32;
-	*clock_low = clock_reg;
-	*ret_clock_seq = clock_seq;
-	return 0;
-}
-
-void uuid_generate_time(uuid_t out)
-{
-	static unsigned char node_id[6];
-	static int has_init = 0;
-	struct uuid uu;
-	__u32	clock_mid;
-
-	if (!has_init) {
-		if (get_node_id(node_id) <= 0) {
-			get_random_bytes(node_id, 6);
-			/*
-			 * Set multicast bit, to prevent conflicts
-			 * with IEEE 802 addresses obtained from
-			 * network cards
-			 */
-			node_id[0] |= 0x01;
-		}
-		has_init = 1;
-	}
-	get_clock(&clock_mid, &uu.time_low, &uu.clock_seq);
-	uu.clock_seq |= 0x8000;
-	uu.time_mid = (__u16) clock_mid;
-	uu.time_hi_and_version = (clock_mid >> 16) | 0x1000;
-	memcpy(uu.node, node_id, 6);
-	uuid_pack2(&uu, out);
-}
-
-void uuid_generate_random(uuid_t out)
-{
-	uuid_t	buf;
-	struct uuid uu;
-
-	get_random_bytes(buf, sizeof(buf));
-	uuid_unpack2(buf, &uu);
-
-	uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
-	uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
-	uuid_pack2(&uu, out);
-}
-
-/*
- * This is the generic front-end to uuid_generate_random and
- * uuid_generate_time.  It uses uuid_generate_random only if
- * /dev/urandom is available, since otherwise we won't have
- * high-quality randomness.
- */
-void uuid_generate(uuid_t out)
-{
-	if (get_random_fd() >= 0)
-		uuid_generate_random(out);
-	else
-		uuid_generate_time(out);
-}
diff --git a/src/uuid/isnull.c b/src/uuid/isnull.c
deleted file mode 100644
index 23b3b78..0000000
--- a/src/uuid/isnull.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * isnull.c --- Check whether or not the UUID is null
- * 
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU 
- * Library General Public License.
- * %End-Header%
- */
-
-#include "uuidP.h"
-
-/* Returns 1 if the uuid is the NULL uuid */
-int uuid_is_null(const uuid_t uu)
-{
-	const unsigned char 	*cp;
-	int			i;
-
-	for (i=0, cp = uu; i < 16; i++)
-		if (*cp++)
-			return 0;
-	return 1;
-}
diff --git a/src/uuid/pack.c b/src/uuid/pack.c
deleted file mode 100644
index f30e276..0000000
--- a/src/uuid/pack.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Internal routine for packing UUID's
- * 
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU 
- * Library General Public License.
- * %End-Header%
- */
-
-#include <string.h>
-#include "uuidP.h"
-
-void uuid_pack2(const struct uuid *uu, uuid_t ptr)
-{
-	__u32	tmp;
-	unsigned char	*out = ptr;
-
-	tmp = uu->time_low;
-	out[3] = (unsigned char) tmp;
-	tmp >>= 8;
-	out[2] = (unsigned char) tmp;
-	tmp >>= 8;
-	out[1] = (unsigned char) tmp;
-	tmp >>= 8;
-	out[0] = (unsigned char) tmp;
-	
-	tmp = uu->time_mid;
-	out[5] = (unsigned char) tmp;
-	tmp >>= 8;
-	out[4] = (unsigned char) tmp;
-
-	tmp = uu->time_hi_and_version;
-	out[7] = (unsigned char) tmp;
-	tmp >>= 8;
-	out[6] = (unsigned char) tmp;
-
-	tmp = uu->clock_seq;
-	out[9] = (unsigned char) tmp;
-	tmp >>= 8;
-	out[8] = (unsigned char) tmp;
-
-	memcpy(out+10, uu->node, 6);
-}
diff --git a/src/uuid/parse.c b/src/uuid/parse.c
deleted file mode 100644
index a36593d..0000000
--- a/src/uuid/parse.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * parse.c --- UUID parsing
- * 
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU 
- * Library General Public License.
- * %End-Header%
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-
-#include "uuidP.h"
-
-int uuid_parse(const char *in, uuid_t uu)
-{
-	struct uuid	uuid;
-	int 		i;
-	const char	*cp;
-	char		buf[3];
-
-	if (strlen(in) != 36)
-		return -1;
-	for (i=0, cp = in; i <= 36; i++,cp++) {
-		if ((i == 8) || (i == 13) || (i == 18) ||
-		    (i == 23)) {
-			if (*cp == '-')
-				continue;
-			else
-				return -1;
-		}
-		if (i== 36)
-			if (*cp == 0)
-				continue;
-		if (!isxdigit(*cp))
-			return -1;
-	}
-	uuid.time_low = strtoul(in, NULL, 16);
-	uuid.time_mid = strtoul(in+9, NULL, 16);
-	uuid.time_hi_and_version = strtoul(in+14, NULL, 16);
-	uuid.clock_seq = strtoul(in+19, NULL, 16);
-	cp = in+24;
-	buf[2] = 0;
-	for (i=0; i < 6; i++) {
-		buf[0] = *cp++;
-		buf[1] = *cp++;
-		uuid.node[i] = strtoul(buf, NULL, 16);
-	}
-	
-	uuid_pack2(&uuid, uu);
-	return 0;
-}
diff --git a/src/uuid/unpack.c b/src/uuid/unpack.c
deleted file mode 100644
index 4fa46f6..0000000
--- a/src/uuid/unpack.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Internal routine for unpacking UUID
- * 
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU 
- * Library General Public License.
- * %End-Header%
- */
-
-#include <string.h>
-#include "uuidP.h"
-
-void uuid_unpack2(const uuid_t in, struct uuid *uu)
-{
-	const __u8	*ptr = in;
-	__u32		tmp;
-
-	tmp = *ptr++;
-	tmp = (tmp << 8) | *ptr++;
-	tmp = (tmp << 8) | *ptr++;
-	tmp = (tmp << 8) | *ptr++;
-	uu->time_low = tmp;
-
-	tmp = *ptr++;
-	tmp = (tmp << 8) | *ptr++;
-	uu->time_mid = tmp;
-	
-	tmp = *ptr++;
-	tmp = (tmp << 8) | *ptr++;
-	uu->time_hi_and_version = tmp;
-
-	tmp = *ptr++;
-	tmp = (tmp << 8) | *ptr++;
-	uu->clock_seq = tmp;
-
-	memcpy(uu->node, ptr, 6);
-}
diff --git a/src/uuid/unparse.c b/src/uuid/unparse.c
deleted file mode 100644
index f951486..0000000
--- a/src/uuid/unparse.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * unparse.c -- convert a UUID to string
- * 
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU 
- * Library General Public License.
- * %End-Header%
- */
-
-#include <stdio.h>
-
-#include "uuidP.h"
-
-void uuid_unparse(const uuid_t uu, char *out)
-{
-	struct uuid uuid;
-
-	uuid_unpack2(uu, &uuid);
-	sprintf(out,
-		"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-		uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
-		uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
-		uuid.node[0], uuid.node[1], uuid.node[2],
-		uuid.node[3], uuid.node[4], uuid.node[5]);
-}
diff --git a/src/uuid/uuid.h b/src/uuid/uuid.h
deleted file mode 100644
index 5720d7f..0000000
--- a/src/uuid/uuid.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Public include file for the UUID library
- * 
- * Copyright (C) 1996, 1997, 1998 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU 
- * Library General Public License.
- * %End-Header%
- */
-
-#ifndef _UUID_UUID_H
-#define _UUID_UUID_H
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
-
-typedef unsigned char uuid_t[16];
-
-/* UUID Variant definitions */
-#define UUID_VARIANT_NCS 	0
-#define UUID_VARIANT_DCE 	1
-#define UUID_VARIANT_MICROSOFT	2
-#define UUID_VARIANT_OTHER	3
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* clear.c */
-void uuid_clear(uuid_t uu);
-
-/* compare.c */
-int uuid_compare(const uuid_t uu1, const uuid_t uu2);
-
-/* copy.c */
-void uuid_copy(uuid_t dst, const uuid_t src);
-
-/* gen_uuid.c */
-void uuid_generate(uuid_t out);
-void uuid_generate_random(uuid_t out);
-void uuid_generate_time(uuid_t out);
-
-/* isnull.c */
-int uuid_is_null(const uuid_t uu);
-
-/* parse.c */
-int uuid_parse(const char *in, uuid_t uu);
-
-/* unparse.c */
-void uuid_unparse(const uuid_t uu, char *out);
-
-/* uuid_time.c */
-time_t uuid_time(const uuid_t uu, struct timeval *ret_tv);
-int uuid_type(const uuid_t uu);
-int uuid_variant(const uuid_t uu);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _UUID_UUID_H */
diff --git a/src/uuid/uuidP.h b/src/uuid/uuidP.h
deleted file mode 100644
index ba7294c..0000000
--- a/src/uuid/uuidP.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * uuid.h -- private header file for uuids
- * 
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU 
- * Library General Public License.
- * %End-Header%
- */
-
-#include <sys/types.h>
-#include "uuid_types.h"
-
-#include "uuid.h"
-
-/*
- * Offset between 15-Oct-1582 and 1-Jan-70
- */
-#define TIME_OFFSET_HIGH 0x01B21DD2
-#define TIME_OFFSET_LOW  0x13814000
-
-struct uuid {
-	__u32	time_low;
-	__u16	time_mid;
-	__u16	time_hi_and_version;
-	__u16	clock_seq;
-	__u8	node[6];
-};
-
-
-/*
- * prototypes
- */
-void uuid_pack2(const struct uuid *uu, uuid_t ptr);
-void uuid_unpack2(const uuid_t in, struct uuid *uu);
diff --git a/src/uuid/uuid_time.c b/src/uuid/uuid_time.c
deleted file mode 100644
index 23e2174..0000000
--- a/src/uuid/uuid_time.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * uuid_time.c --- Interpret the time field from a uuid.  This program
- * 	violates the UUID abstraction barrier by reaching into the guts
- *	of a UUID and interpreting it.
- * 
- * Copyright (C) 1998, 1999 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU 
- * Library General Public License.
- * %End-Header%
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
-
-#include "uuidP.h"
-
-time_t uuid_time(const uuid_t uu, struct timeval *ret_tv)
-{
-	struct uuid		uuid;
-	__u32			high;
-	struct timeval		tv;
-	unsigned long long	clock_reg;
-
-	uuid_unpack2(uu, &uuid);
-	
-	high = uuid.time_mid | ((uuid.time_hi_and_version & 0xFFF) << 16);
-	clock_reg = uuid.time_low | ((unsigned long long) high << 32);
-
-	clock_reg -= (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
-	tv.tv_sec = clock_reg / 10000000;
-	tv.tv_usec = (clock_reg % 10000000) / 10;
-
-	if (ret_tv)
-		*ret_tv = tv;
-
-	return tv.tv_sec;
-}
-
-int uuid_type(const uuid_t uu)
-{
-	struct uuid		uuid;
-
-	uuid_unpack2(uu, &uuid);	
-	return ((uuid.time_hi_and_version >> 12) & 0xF);
-}
-
-int uuid_variant(const uuid_t uu)
-{
-	struct uuid		uuid;
-	int			var;
-
-	uuid_unpack2(uu, &uuid);	
-	var = uuid.clock_seq;
-
-	if ((var & 0x8000) == 0)
-		return UUID_VARIANT_NCS;
-	if ((var & 0x4000) == 0)
-		return UUID_VARIANT_DCE;
-	if ((var & 0x2000) == 0)
-		return UUID_VARIANT_MICROSOFT;
-	return UUID_VARIANT_OTHER;
-}
-
-#ifdef DEBUG
-static const char *variant_string(int variant)
-{
-	switch (variant) {
-	case UUID_VARIANT_NCS:
-		return "NCS";
-	case UUID_VARIANT_DCE:
-		return "DCE";
-	case UUID_VARIANT_MICROSOFT:
-		return "Microsoft";
-	default:
-		return "Other";
-	}
-}
-
-	
-int
-main(int argc, char **argv)
-{
-	uuid_t		buf;
-	time_t		time_reg;
-	struct timeval	tv;
-	int		type, variant;
-
-	if (argc != 2) {
-		fprintf(stderr, "Usage: %s uuid\n", argv[0]);
-		exit(1);
-	}
-	if (uuid_parse(argv[1], buf)) {
-		fprintf(stderr, "Invalid UUID: %s\n", argv[1]);
-		exit(1);
-	}
-	variant = uuid_variant(buf);
-	type = uuid_type(buf);
-	time_reg = uuid_time(buf, &tv);
-
-	printf("UUID variant is %d (%s)\n", variant, variant_string(variant));
-	if (variant != UUID_VARIANT_DCE) {
-		printf("Warning: This program only knows how to interpret "
-		       "DCE UUIDs.\n\tThe rest of the output is likely "
-		       "to be incorrect!!\n");
-	}
-	printf("UUID type is %d", type);
-	switch (type) {
-	case 1:
-		printf(" (time based)\n");
-		break;
-	case 2:
-		printf(" (DCE)\n");
-		break;
-	case 3:
-		printf(" (name-based)\n");
-		break;
-	case 4:
-		printf(" (random)\n");
-		break;
-	default:
-		printf("\n");
-	}
-	if (type != 1) {
-		printf("Warning: not a time-based UUID, so UUID time "
-		       "decoding will likely not work!\n");
-	}
-	printf("UUID time is: (%ld, %ld): %s\n", tv.tv_sec, tv.tv_usec,
-	       ctime(&time_reg));
-	
-	return 0;
-}
-#endif
diff --git a/src/uuid/uuid_types.h b/src/uuid/uuid_types.h
deleted file mode 100644
index 064c575..0000000
--- a/src/uuid/uuid_types.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 
- * If linux/types.h is already been included, assume it has defined
- * everything we need.  (cross fingers)  Other header files may have 
- * also defined the types that we need.
- */
-#if (!defined(_LINUX_TYPES_H) && !defined(_BLKID_TYPES_H) && \
-	!defined(_UUID_TYPES) && !defined(_EXT2_TYPES_H))
-#define _UUID_TYPES_H
-
-typedef unsigned char __u8;
-typedef signed char __s8;
-
-#if (4 == 8)
-typedef int		__s64;
-typedef unsigned int	__u64;
-#elif (4 == 8)
-typedef long		__s64;
-typedef unsigned long	__u64;
-#elif (8 == 8)
-#if defined(__GNUC__)
-typedef __signed__ long long 	__s64;
-#else
-typedef signed long long 	__s64;
-#endif
-typedef unsigned long long	__u64;
-#endif
-
-#if (4 == 2)
-typedef	int		__s16;
-typedef	unsigned int	__u16;
-#elif (2 == 2)
-typedef	short		__s16;
-typedef	unsigned short	__u16;
-#else
-  ?==error: undefined 16 bit type
-#endif
-
-#if (4 == 4)
-typedef	int		__s32;
-typedef	unsigned int	__u32;
-#elif (4 == 4)
-typedef	long		__s32;
-typedef	unsigned long	__u32;
-#elif (2 == 4)
-typedef	short		__s32;
-typedef	unsigned short	__u32;
-#else
- ?== error: undefined 32 bit type
-#endif
-
-#endif /* _*_TYPES_H */
diff --git a/src/web/action.cc b/src/web/action.cc
index f695371..6ffee14 100644
--- a/src/web/action.cc
+++ b/src/web/action.cc
@@ -29,10 +29,6 @@
 
 /// \file action.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "pages.h"
 #include "content_manager.h"
 
diff --git a/src/web/add.cc b/src/web/add.cc
index 175a88e..571f096 100644
--- a/src/web/add.cc
+++ b/src/web/add.cc
@@ -29,12 +29,8 @@
 
 /// \file add.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "server.h"
-#include <stdio.h>
+#include <cstdio>
 #include "common.h"
 #include "pages.h"
 #include "tools.h"
@@ -60,7 +56,7 @@ void web::add::process()
         path = _(FS_ROOT_DIRECTORY);
     else
         path = hex_decode_string(objID);
-    if (path == nil) throw _Exception(_("web::add::process(): illegal path"));
+    if (path == nullptr) throw _Exception(_("web::add::process(): illegal path"));
 
     Ref<ContentManager> cm = ContentManager::getInstance();
     cm->addFile(path, true);
diff --git a/src/web/add_object.cc b/src/web/add_object.cc
index b32cda9..3143389 100644
--- a/src/web/add_object.cc
+++ b/src/web/add_object.cc
@@ -29,12 +29,8 @@
 
 /// \file add_object.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "server.h"
-#include <stdio.h>
+#include <cstdio>
 #include "common.h"
 #include "content_manager.h"
 #include "cds_objects.h"
@@ -48,13 +44,13 @@ using namespace mxml;
 web::addObject::addObject() : WebRequestHandler()
 {}
 
-/*static Ref<Element> addOption(String option_name, String option_type, String default_value = nil)
+/*static Ref<Element> addOption(String option_name, String option_type, String default_value = nullptr)
 {
     Ref<Element> option (new Element(_("option")));
     option->addAttribute(_("name"), option_name);
     option->addAttribute(_("type"), option_type);
     
-    if (default_value != nil)
+    if (default_value != nullptr)
         option->addAttribute(_("default"), default_value);
     
     return option;
@@ -186,7 +182,7 @@ void web::addObject::process()
     
     int parentID = intParam(_("parent_id"), 0);
     
-    Ref<CdsObject> obj = nil;
+    Ref<CdsObject> obj = nullptr;
     
     Ref<Element> updateContainerEl;
    
@@ -231,7 +227,7 @@ void web::addObject::process()
         throw _Exception(_("unknown object type: ") + obj_type.c_str());
     }
     
-    if (obj != nil)
+    if (obj != nullptr)
     {
         obj->setVirtual(true);
         if (obj_type == STRING_OBJECT_TYPE_ITEM)
diff --git a/src/web/auth.cc b/src/web/auth.cc
index 8560581..746a4c3 100644
--- a/src/web/auth.cc
+++ b/src/web/auth.cc
@@ -29,10 +29,6 @@
 
 /// \file auth.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include <sys/time.h>
 #include "pages.h"
 #include "tools.h"
@@ -46,7 +42,7 @@ using namespace mxml;
 static long get_time()
 {
     struct timeval tv;
-    gettimeofday(&tv, NULL);
+    gettimeofday(&tv, nullptr);
     return tv.tv_sec;
 }
 
@@ -139,10 +135,10 @@ void web::auth::process()
     else if (action == "get_sid")
     {
         log_debug("checking/getting sid...\n");
-        Ref<Session> session = nil;
+        Ref<Session> session = nullptr;
         String sid = param(_("sid"));
         
-        if (sid == nil || (session = sessionManager->getSession(sid)) == nil)
+        if (sid == nullptr || (session = sessionManager->getSession(sid)) == nullptr)
         {
             session = sessionManager->createSession(timeout);
             root->setAttribute(_("sid_was_valid"), _("0"), mxml_bool_type);
@@ -166,7 +162,7 @@ void web::auth::process()
         check_request();
         String sid = param(_("sid"));
         Ref<Session> session = SessionManager::getInstance()->getSession(sid);
-        if (session == nil)
+        if (session == nullptr)
             throw _Exception(_("illegal session id"));
         sessionManager->removeSession(sid);
     }
@@ -192,7 +188,7 @@ void web::auth::process()
             throw LoginException(_("Missing username or password"));
         
         Ref<Session> session = sessionManager->getSession(sid);
-        if (session == nil)
+        if (session == nullptr)
             throw _Exception(_("illegal session id"));
         
         String correctPassword = sessionManager->getUserPassword(username);
diff --git a/src/web/containers.cc b/src/web/containers.cc
index 415d139..691a54f 100644
--- a/src/web/containers.cc
+++ b/src/web/containers.cc
@@ -29,10 +29,6 @@
 
 /// \file containers.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "common.h"
 #include "pages.h"
 #include "storage.h"
@@ -91,7 +87,7 @@ void web::containers::process()
             if (ConfigManager::getInstance()->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY))
             {
                 Ref<AutoscanDirectory> adir = storage->getAutoscanDirectory(cont->getID());
-                if ((adir != nil) && (adir->getScanMode() == InotifyScanMode))
+                if ((adir != nullptr) && (adir->getScanMode() == ScanMode::INotify))
                     autoscanMode = _("inotify");
             }
 #endif
diff --git a/src/web/directories.cc b/src/web/directories.cc
index 5104ceb..8323157 100644
--- a/src/web/directories.cc
+++ b/src/web/directories.cc
@@ -29,10 +29,6 @@
 
 /// \file directories.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "common.h"
 #include "pages.h"
 #include "tools.h"
@@ -53,7 +49,7 @@ void web::directories::process()
 
     String path;
     String parentID = param(_("parent_id"));
-    if (parentID == nil || parentID == "0")
+    if (parentID == nullptr || parentID == "0")
         path = _(FS_ROOT_DIRECTORY);
     else
         path = hex_decode_string(parentID);
diff --git a/src/web/edit_load.cc b/src/web/edit_load.cc
index c0c28f3..1160e9f 100644
--- a/src/web/edit_load.cc
+++ b/src/web/edit_load.cc
@@ -29,13 +29,9 @@
 
 /// \file edit_load.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "pages.h"
 
-#include <stdio.h>
+#include <cstdio>
 #include "common.h"
 #include "cds_objects.h"
 #include "tools.h"
@@ -59,7 +55,7 @@ void web::edit_load::process()
     
     String objID = param(_("object_id"));
     int objectID;
-    if (objID == nil)
+    if (objID == nullptr)
         throw _Exception(_("invalid object id"));
     else
         objectID = objID.toInt();
diff --git a/src/web/edit_save.cc b/src/web/edit_save.cc
index d3e42db..7b46f0a 100644
--- a/src/web/edit_save.cc
+++ b/src/web/edit_save.cc
@@ -29,12 +29,8 @@
 
 /// \file edit_save.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "pages.h"
-#include <stdio.h>
+#include <cstdio>
 #include "content_manager.h"
 #include "storage.h"
 #include "tools.h"
diff --git a/src/web/files.cc b/src/web/files.cc
index d6f2492..c19bf85 100644
--- a/src/web/files.cc
+++ b/src/web/files.cc
@@ -29,10 +29,6 @@
 
 /// \file files.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "common.h"
 #include "pages.h"
 #include "tools.h"
diff --git a/src/web/items.cc b/src/web/items.cc
index 7e25f17..7928c81 100644
--- a/src/web/items.cc
+++ b/src/web/items.cc
@@ -29,10 +29,6 @@
 
 /// \file items.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "pages.h"
 #include "common.h"
 #include "storage.h"
@@ -108,7 +104,7 @@ void web::items::process()
         if (startpoint_id != INVALID_OBJECT_ID)
         {
             Ref<AutoscanDirectory> adir = storage->getAutoscanDirectory(startpoint_id);
-            if ((adir != nil) && (adir->getScanMode() == InotifyScanMode))
+            if ((adir != nullptr) && (adir->getScanMode() == ScanMode::INotify))
             {
                 protectItems = 1;
                 if (autoscanType == 0 || adir->persistent())
diff --git a/src/web/pages.cc b/src/web/pages.cc
index 8ca4ae5..3b0d96b 100644
--- a/src/web/pages.cc
+++ b/src/web/pages.cc
@@ -29,10 +29,6 @@
 
 /// \file pages.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "pages.h"
 
 using namespace zmm;
diff --git a/src/web/remove.cc b/src/web/remove.cc
index b56b4db..88f542e 100644
--- a/src/web/remove.cc
+++ b/src/web/remove.cc
@@ -29,12 +29,8 @@
 
 /// \file remove.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "server.h"
-#include <stdio.h>
+#include <cstdio>
 #include "common.h"
 #include "content_manager.h"
 #include "pages.h"
diff --git a/src/web/tasks.cc b/src/web/tasks.cc
index 7869e77..50e2dcf 100644
--- a/src/web/tasks.cc
+++ b/src/web/tasks.cc
@@ -29,10 +29,6 @@
 
 /// \file tasks.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "pages.h"
 #include "common.h"
 #include "content_manager.h"
@@ -54,7 +50,7 @@ void web::tasks::process()
         tasksEl->setArrayName(_("task"));
         root->appendElementChild(tasksEl); // inherited from WebRequestHandler
         Ref<Array<GenericTask> > taskList = cm->getTasklist();
-        if (taskList == nil)
+        if (taskList == nullptr)
             return;
         int count = taskList->size();
         for (int i = 0; i < count; i++)
diff --git a/src/web/web_autoscan.cc b/src/web/web_autoscan.cc
index 102be8b..0e1dcf7 100644
--- a/src/web/web_autoscan.cc
+++ b/src/web/web_autoscan.cc
@@ -29,10 +29,6 @@
 
 /// \file web_autoscan.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "pages.h"
 #include "storage.h"
 #include "autoscan.h"
@@ -44,8 +40,8 @@ using namespace mxml;
 
 int WebAutoscanProcessListComparator(void *arg1, void *arg2)
 {
-    AutoscanDirectory *a1 = (AutoscanDirectory *)arg1;
-    AutoscanDirectory *a2 = (AutoscanDirectory *)arg2;
+    auto *a1 = (AutoscanDirectory *)arg1;
+    auto *a2 = (AutoscanDirectory *)arg2;
     return strcmp(a1->getLocation().c_str(), a2->getLocation().c_str());
 }
 
@@ -109,7 +105,7 @@ void web::autoscan::process()
                 else
                     cm->removeAutoscanDirectory(intParam(_("object_id")));
             }
-            catch (Exception e)
+            catch (const Exception & e)
             {
                 // didn't work, well we don't care in this case
             }
@@ -121,11 +117,11 @@ void web::autoscan::process()
             bool hidden = boolParam(_("hidden"));
             //bool persistent = boolParam(_("persistent"));
             
-            scan_mode_t scan_mode = AutoscanDirectory::remapScanmode(scan_mode_str);
-            scan_level_t scan_level;
+            ScanMode scan_mode = AutoscanDirectory::remapScanmode(scan_mode_str);
+            ScanLevel scan_level;
             scan_level = AutoscanDirectory::remapScanlevel(param(_("scan_level")));
             int interval = intParam(_("interval"), 0);
-            if (scan_mode == TimedScanMode && interval <= 0)
+            if (scan_mode == ScanMode::Timed && interval <= 0)
                 throw _Exception(_("illegal interval given"));
             
             int objectID = INVALID_OBJECT_ID;
@@ -139,7 +135,7 @@ void web::autoscan::process()
             //    AutoscanDirectory::mapScanlevel(scan_level).c_str(), recursive, interval, hidden);
             
             Ref<AutoscanDirectory> autoscan(new AutoscanDirectory(
-                nil, //location
+                nullptr, //location
                 scan_mode,
                 scan_level,
                 recursive,
@@ -185,7 +181,7 @@ void web::autoscan::process()
 
 void web::autoscan::autoscan2XML(Ref<Element> element, Ref<AutoscanDirectory> adir)
 {
-    if (adir == nil)
+    if (adir == nullptr)
     {
         element->appendTextChild(_("scan_mode"), _("none"));
         element->appendTextChild(_("scan_level"), _("full"));
diff --git a/src/web/web_update.cc b/src/web/web_update.cc
index e592264..a5c9055 100644
--- a/src/web/web_update.cc
+++ b/src/web/web_update.cc
@@ -29,10 +29,6 @@
 
 /// \file web_update.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "pages.h"
 #include "storage.h"
 #include "autoscan.h"
diff --git a/src/web_callbacks.cc b/src/web_callbacks.cc
index a104c8d..82cd4ad 100644
--- a/src/web_callbacks.cc
+++ b/src/web_callbacks.cc
@@ -30,110 +30,62 @@
 /// \file web_callbacks.cc
 /// This handles the VirtualDirCallbacks that come from the web server.
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
+#include <sys/types.h>
 
 #include "common.h"
+#include "file_request_handler.h"
+#include "request_handler.h"
+#include "server.h"
 #include "tools.h"
 #include "web_callbacks.h"
-#include "server.h"
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include "storage.h"
-#include "cds_objects.h"
-#include "process.h"
-#include "update_manager.h"
-#include "ixml.h"
-#include "io_handler.h"
-#include "request_handler.h"
-#include "file_request_handler.h"
 #ifdef HAVE_CURL
-    #include "url_request_handler.h"
+#include "url_request_handler.h"
 #endif
-#include "web_request_handler.h"
 #include "serve_request_handler.h"
 #include "web/pages.h"
-#include "dictionary.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
+#include "web_request_handler.h"
 
 using namespace zmm;
 using namespace mxml;
 
-static Ref<RequestHandler> create_request_handler(const char *filename,
-                                                  const char *headers)
+static Ref<RequestHandler> create_request_handler(const char* filename)
 {
-    String path, parameters;
-
-    String link = url_unescape((char *) filename);
+    String path;
+    String parameters;
+    String link = url_unescape((char*)filename);
 
     log_debug("Filename: %s, Path: %s\n", filename, path.c_str());
-//    log_debug("create_handler: got url parameters: [%s]\n", parameters.c_str());
-    
-    RequestHandler *ret = NULL;
-/*
-    log_debug("Link is: %s, checking against: %s, starts with? %d\n", link.c_str(), 
-                (String(SERVER_VIRTUAL_DIR) + "/" + CONTENT_UI_HANDLER).c_str(), 
-                link.startsWith(String(SERVER_VIRTUAL_DIR) + "/" + CONTENT_UI_HANDLER));
-    log_debug("Link is: %s, checking against: %s, starts with? %d\n", link.c_str(), 
-                (String(SERVER_VIRTUAL_DIR) + "/" + CONTENT_MEDIA_HANDLER).c_str(), 
-                link.startsWith(String(SERVER_VIRTUAL_DIR) + "/" + CONTENT_MEDIA_HANDLER));
-  
-    log_debug("Link is: %s, checking against: %s, starts with? %d\n", link.c_str(), 
-                (String(SERVER_VIRTUAL_DIR) + "/" + CONTENT_SERVE_HANDLER).c_str(), 
-                link.startsWith(String(SERVER_VIRTUAL_DIR) + "/" + CONTENT_SERVE_HANDLER));
-*/  
-    if (link.startsWith(_("/") + SERVER_VIRTUAL_DIR + "/" +
-                        CONTENT_MEDIA_HANDLER))
-    {
-            ret = new FileRequestHandler();
-    }
-    else if (link.startsWith(_("/") + SERVER_VIRTUAL_DIR + "/" +
-                             CONTENT_UI_HANDLER))
-    {  
-        RequestHandler::split_url(filename, URL_UI_PARAM_SEPARATOR, path, 
-                parameters);
+    // log_debug("create_handler: got url parameters: [%s]\n", parameters.c_str());
+
+    RequestHandler* ret = nullptr;
+
+    if (link.startsWith(_("/") + SERVER_VIRTUAL_DIR + "/" + CONTENT_MEDIA_HANDLER)) {
+        ret = new FileRequestHandler();
+    } else if (link.startsWith(_("/") + SERVER_VIRTUAL_DIR + "/" + CONTENT_UI_HANDLER)) {
+        RequestHandler::split_url(filename, URL_UI_PARAM_SEPARATOR, path, parameters);
+
         Ref<Dictionary> dict(new Dictionary());
         dict->decode(parameters);
-        
+
         String r_type = dict->get(_(URL_REQUEST_TYPE));
-        if (r_type != nil)
-        {
+        if (r_type != nullptr) {
             ret = create_web_request_handler(r_type);
-        }
-        else
-        {
+        } else {
             ret = create_web_request_handler(_("index"));
         }
-    } 
-    else if (link.startsWith(_("/") + SERVER_VIRTUAL_DIR + "/" +
-                             CONTENT_SERVE_HANDLER))
-    {
+    } else if (link.startsWith(_("/") + SERVER_VIRTUAL_DIR + "/" + CONTENT_SERVE_HANDLER)) {
         if (string_ok(ConfigManager::getInstance()->getOption(CFG_SERVER_SERVEDIR)))
             ret = new ServeRequestHandler();
         else
             throw _Exception(_("Serving directories is not enabled in configuration"));
     }
-    /// \todo add enable/disable curl to configure.ac, currently this is automatically triggered depending on youtube and external transcoding definitions
+
 #if defined(HAVE_CURL)
-    else if (link.startsWith(_("/") + SERVER_VIRTUAL_DIR + "/" +
-                             CONTENT_ONLINE_HANDLER))
-    {
+    else if (link.startsWith(_("/") + SERVER_VIRTUAL_DIR + "/" + CONTENT_ONLINE_HANDLER)) {
         ret = new URLRequestHandler();
     }
 #endif
-#if defined(HAVE_LIBDVDREAD_DISABLED)
-    else if (link.startsWith(_("/") + SERVER_VIRTUAL_DIR + "/" + 
-                CONTENT_DVD_HANDLER))
-    {
-        ret = new DVDRequestHandler();
-    }
-#endif
-    else
-    {
+    else {
         throw _Exception(_("no valid handler type in ") + filename);
     }
     return Ref<RequestHandler>(ret);
@@ -144,31 +96,25 @@ static Ref<RequestHandler> create_request_handler(const char *filename,
 /// \param File_Info Pointer to the struction that stores information about
 /// the file.
 ///
-/// This function corresponds to get_info from the UpnpVirtualDirCallbacks 
+/// This function corresponds to get_info from the UpnpVirtualDirCallbacks
 /// structure. It is called by the web server to query information about a
-/// file. To perform the operation an appropriate request handler is 
+/// file. To perform the operation an appropriate request handler is
 /// created, it then takes care of filling in the data.
 ///
 /// \return 0 Success.
 /// \return -1 Error.
-static int web_get_info(IN const char *filename, IN const char *headers, OUT struct File_Info *info)
+
+static int web_get_info(IN const char* filename, OUT UpnpFileInfo* info)
 {
-    try
-    {
-        Ref<RequestHandler> reqHandler = create_request_handler(filename, headers);
+    try {
+        Ref<RequestHandler> reqHandler = create_request_handler(filename);
         reqHandler->get_info(filename, info);
-    }
-    catch (ServerShutdownException se)
-    {
+    } catch (const ServerShutdownException& se) {
         return -1;
-    }
-    catch (SubtitlesNotFoundException sex)
-    {
+    } catch (const SubtitlesNotFoundException& sex) {
         log_info("%s\n", sex.getMessage().c_str());
         return -1;
-    }
-    catch (Exception e)
-    {
+    } catch (const Exception& e) {
         log_error("%s\n", e.getMessage().c_str());
         return -1;
     }
@@ -190,81 +136,50 @@ static int web_get_info(IN const char *filename, IN const char *headers, OUT str
 ///
 /// \return UpnpWebFileHandle A valid file handle.
 /// \return NULL Error.
-static UpnpWebFileHandle web_open(IN const char *filename,
-                                  IN const char *headers,
-                                  OUT struct File_Info *info,
-                                  IN enum UpnpOpenFileMode mode)
-{
-    log_debug("web_open(): %s", headers);
-
-    String link = url_unescape((char *) filename);
 
-    char *line = strstr((char *)headers, "TimeSeekRange.dlna.org: npt=");
-    char *timeseek;
-    if (line != NULL)
-    {
-         char *lineend = strstr(line, "\n");
-         int chars = lineend - (line + 28);
-         // limit to some value that makes sense to prevent allocating too much
-         // memory due to some maliciously prepared headers
-         if (chars < 1024)
-         {
-             timeseek = (char *)malloc(chars);
-             if (timeseek)
-             {
-                 strncpy(timeseek, line + 28, chars);
-                 log_debug("timeseek range found: %s\n",timeseek);
-                 link = link + "/range/" + timeseek;
-             }
-         }
-    }
+static UpnpWebFileHandle web_open(IN const char* filename,
+    IN enum UpnpOpenFileMode mode)
+{
+    log_debug("web_open(): %s\n", filename);
+    String link = url_unescape((char*)filename);
 
-    try
-    {
-        Ref<RequestHandler> reqHandler = create_request_handler(filename, headers);
-        Ref<IOHandler> ioHandler = reqHandler->open(link.c_str(), info, mode, nil);
+    try {
+        Ref<RequestHandler> reqHandler = create_request_handler(filename);
+        Ref<IOHandler> ioHandler = reqHandler->open(link.c_str(), mode, nullptr);
         ioHandler->retain();
-        return (UpnpWebFileHandle) ioHandler.getPtr();
-    }
-    catch (ServerShutdownException se)
-    {
-        return NULL;
-    }
-    catch (SubtitlesNotFoundException sex)
-    {
+        return (UpnpWebFileHandle)ioHandler.getPtr();
+    } catch (const ServerShutdownException& se) {
+        return nullptr;
+    } catch (const SubtitlesNotFoundException& sex) {
         log_info("%s\n", sex.getMessage().c_str());
-        return NULL;
-    }
-    catch (Exception ex)
-    {
+        return nullptr;
+    } catch (const Exception& ex) {
         log_error("%s\n", ex.getMessage().c_str());
-        return NULL;
+        return nullptr;
     }
 }
 
-
 /// \brief Reads a previously opened file sequentially.
 /// \param f IOHandler that takes care of this request.
 /// \param buf This buffer will be filled by our read functions.
 /// \param length Number of bytes to read.
 ///
 /// This function is called by the web server to perform a sequential
-/// read from an open file. It calls the read function of the 
+/// read from an open file. It calls the read function of the
 /// appropriate IOHandler, which copies \b length bytes from the file
 /// or memory into the output buffer.
 ///
 /// \return 0   EOF encountered.
 /// \return -1  Error.
-static int web_read(IN UpnpWebFileHandle f, OUT char *buf, 
-                    IN size_t length)
+static int web_read(IN UpnpWebFileHandle f, OUT char* buf, IN size_t length)
 {
     if (Server::getInstance()->getShutdownStatus())
         return -1;
 
-    IOHandler *handler = (IOHandler *)f;
+    auto* handler = (IOHandler*)f;
     return handler->read(buf, length);
 }
-                                                                                                                                                                         
+
 /// \brief Writes to a previously opened file sequentially.
 /// \param f Handle of the file.
 /// \param buf This buffer will be filled by fwrite.
@@ -279,12 +194,11 @@ static int web_read(IN UpnpWebFileHandle f, OUT char *buf,
 /// \return Actual number of bytes written.
 ///
 /// \warning Currently this function is not supported.
-static int web_write(IN UpnpWebFileHandle f, IN char *buf,
-                      IN size_t length)
+static int web_write(IN UpnpWebFileHandle f, IN char* buf, IN size_t length)
 {
     return 0;
 }
-                                                                                                                                                                         
+
 /// \brief Performs a seek on an open file.
 /// \param f Handle of the file.
 /// \param offset Number of bytes to move in the file. For seeking forwards
@@ -300,13 +214,10 @@ static int web_write(IN UpnpWebFileHandle f, IN char *buf,
 /// \return 0 On success, non-zero value on error.
 static int web_seek(IN UpnpWebFileHandle f, IN off_t offset, IN int whence)
 {
-    try 
-    {
-        IOHandler *handler = (IOHandler *)f;
+    try {
+        auto* handler = (IOHandler*)f;
         handler->seek(offset, whence);
-    }
-    catch(Exception e)
-    {
+    } catch (const Exception& e) {
         log_error("web_seek(): Exception during seek: %s\n", e.getMessage().c_str());
         e.printStackTrace();
         return -1;
@@ -317,21 +228,18 @@ static int web_seek(IN UpnpWebFileHandle f, IN off_t offset, IN int whence)
 
 /// \brief Closes a previously opened file.
 /// \param f IOHandler for that file.
-/// 
+///
 /// Same as fclose()
 ///
 /// \return 0 On success, non-zero on error.
-static int web_close( IN UpnpWebFileHandle f)
+static int web_close(IN UpnpWebFileHandle f)
 {
 
-    Ref<IOHandler> handler((IOHandler *)f);
+    Ref<IOHandler> handler((IOHandler*)f);
     handler->release();
-    try
-    {
+    try {
         handler->close();
-    }
-    catch(Exception e)
-    {
+    } catch (const Exception& e) {
         log_error("web_seek(): Exception during seek: %s\n", e.getMessage().c_str());
         e.printStackTrace();
         return -1;
@@ -349,20 +257,18 @@ static int web_close( IN UpnpWebFileHandle f)
 /// \b web_write Sequentially write to a file (not supported).
 /// \b web_seek Perform a seek on a file.
 /// \b web_close Close file.
-/// 
+///
 /// \return UPNP_E_SUCCESS Callbacks registered successfully, else eror code.
 int register_web_callbacks()
 {
-    int ret = UPNP_E_SUCCESS;
+    int ret = 0;
 
-    struct UpnpVirtualDirCallbacks cb;
-    cb.get_info = web_get_info;
-    cb.open = web_open;
-    cb.read = web_read;
-    cb.write = web_write;
-    cb.seek = web_seek;
-    cb.close = web_close;
+    ret = UpnpVirtualDir_set_GetInfoCallback(web_get_info) == UPNP_E_SUCCESS
+        && UpnpVirtualDir_set_OpenCallback(web_open) == UPNP_E_SUCCESS
+        && UpnpVirtualDir_set_ReadCallback(web_read) == UPNP_E_SUCCESS
+        && UpnpVirtualDir_set_WriteCallback(web_write) == UPNP_E_SUCCESS
+        && UpnpVirtualDir_set_SeekCallback(web_seek) == UPNP_E_SUCCESS
+        && UpnpVirtualDir_set_CloseCallback(web_close) == UPNP_E_SUCCESS;
 
-    ret = UpnpSetVirtualDirCallbacks(&cb);
-    return ret;
-}   
+    return ret ? UPNP_E_SUCCESS : UPNP_E_INVALID_PARAM;
+}
diff --git a/src/web_request_handler.cc b/src/web_request_handler.cc
index a896bdf..cffb39d 100644
--- a/src/web_request_handler.cc
+++ b/src/web_request_handler.cc
@@ -29,25 +29,20 @@
 
 /// \file web_request_handler.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include <time.h>
-#include "mem_io_handler.h"
 #include "web_request_handler.h"
 #include "config_manager.h"
 #include "content_manager.h"
-#include "web/pages.h"
+#include "mem_io_handler.h"
 #include "tools.h"
-#include "hash.h"
+#include "web/pages.h"
+#include <ctime>
 
 using namespace zmm;
 using namespace mxml;
 
-WebRequestHandler::WebRequestHandler() : RequestHandler()
+WebRequestHandler::WebRequestHandler()
+    : RequestHandler(), checkRequestCalled(false)
 {
-    checkRequestCalled = false;
     params = Ref<Dictionary>(new Dictionary());
 }
 
@@ -69,157 +64,145 @@ bool WebRequestHandler::boolParam(zmm::String name)
 void WebRequestHandler::check_request(bool checkLogin)
 {
     // we have a minimum set of parameters that are "must have"
-    
+
     // check if the session parameter was supplied and if we have
     // a session with that id
-    
+
     checkRequestCalled = true;
-    
+
     String sid = param(_("sid"));
-    if (sid == nil)
+    if (sid == nullptr)
         throw SessionException(_("no session id given"));
-    
-    if ((session = SessionManager::getInstance()->getSession(sid)) == nil)
+
+    if ((session = SessionManager::getInstance()->getSession(sid)) == nullptr)
         throw SessionException(_("invalid session id"));
-    
-    if (checkLogin && ! session->isLoggedIn())
+
+    if (checkLogin && !session->isLoggedIn())
         throw LoginException(_("not logged in"));
     session->access();
 }
 
 String WebRequestHandler::renderXMLHeader()
 {
-    return _("<?xml version=\"1.0\" encoding=\"") +
-            DEFAULT_INTERNAL_CHARSET +"\"?>\n";
+    return _("<?xml version=\"1.0\" encoding=\"") + DEFAULT_INTERNAL_CHARSET + "\"?>\n";
 }
 
-void WebRequestHandler::get_info(IN const char *filename, OUT struct File_Info *info)
+void WebRequestHandler::get_info(IN const char* filename, OUT UpnpFileInfo* info)
 {
-    info->file_length = -1; // length is unknown
-    info->last_modified = time(NULL);
-    info->is_directory = 0;
-    info->is_readable = 1;
-    
+    this->filename = filename;
+    this->mode = mode;
+
+    String path, parameters;
+    split_url(filename, URL_UI_PARAM_SEPARATOR, path, parameters);
+
+    params->decode(parameters);
+
+    UpnpFileInfo_set_FileLength(info, -1); // length is unknown
+
+#ifdef UPNP_OLD_SNAPSHOT
+    time_t time = 0;
+    UpnpFileInfo_set_LastModified(info, &time);
+#else
+    UpnpFileInfo_set_LastModified(info, 0);
+#endif
+    UpnpFileInfo_set_IsDirectory(info, 0);
+    UpnpFileInfo_set_IsReadable(info, 1);
+
     String contentType;
-    
+
     String mimetype;
     String returnType = param(_("return_type"));
+
     if (string_ok(returnType) && returnType == "xml")
         mimetype = _(MIMETYPE_XML);
     else
         mimetype = _(MIMETYPE_JSON);
-    
+
     contentType = mimetype + "; charset=" + DEFAULT_INTERNAL_CHARSET;
-    
-    info->content_type = ixmlCloneDOMString(contentType.c_str());
-    info->http_header = ixmlCloneDOMString("Cache-Control: no-cache, must-revalidate");
+
+    UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString(contentType.c_str()));
+    UpnpFileInfo_set_ExtraHeaders(info, ixmlCloneDOMString("Cache-Control: no-cache, must-revalidate\n"));
 }
 
 Ref<IOHandler> WebRequestHandler::open(IN enum UpnpOpenFileMode mode)
 {
     root = Ref<Element>(new Element(_("root")));
     out = Ref<StringBuffer>(new StringBuffer());
-    
-    String error = nil;
+
+    String error = nullptr;
     int error_code = 0;
-    
+
     String output;
     // processing page, creating output
-    try
-    {
-        if(!ConfigManager::getInstance()->getBoolOption(CFG_SERVER_UI_ENABLED))
-        {
+    try {
+        if (!ConfigManager::getInstance()->getBoolOption(CFG_SERVER_UI_ENABLED)) {
             log_warning("The UI is disabled in the configuration file. See README.\n");
             error = _("The UI is disabled in the configuration file. See README.");
             error_code = 900;
-        }
-        else
-        {
+        } else {
             process();
-            
-            if (checkRequestCalled)
-            {
+
+            if (checkRequestCalled) {
                 // add current task
                 appendTask(root, ContentManager::getInstance()->getCurrentTask());
-                
+
                 handleUpdateIDs();
             }
         }
-    }
-    catch (LoginException e)
-    {
+    } catch (const LoginException& e) {
         error = e.getMessage();
         error_code = 300;
-    }
-    catch (ObjectNotFoundException e)
-    {
-        error = e.getMessage();;
+    } catch (const ObjectNotFoundException& e) {
+        error = e.getMessage();
+        ;
         error_code = 200;
-    }
-    catch (SessionException e)
-    {
+    } catch (const SessionException& e) {
         error = e.getMessage();
         error_code = 400;
-    }
-    catch (StorageException e)
-    {
+    } catch (const StorageException& e) {
         error = e.getUserMessage();
         error_code = 500;
         e.printStackTrace();
-    }
-    catch (Exception e)
-    {
+    } catch (const Exception& e) {
         error = _("Error: ") + e.getMessage();
         error_code = 800;
         e.printStackTrace();
     }
-    
-    if (! string_ok(error))
-    {
+
+    if (!string_ok(error)) {
         root->setAttribute(_("success"), _("1"), mxml_bool_type);
-    }
-    else
-    {
+    } else {
         root->setAttribute(_("success"), _("0"), mxml_bool_type);
         Ref<Element> errorEl(new Element(_("error")));
         errorEl->setTextKey(_("text"));
         errorEl->setText(error);
-        
+
         if (error_code == 0)
             error_code = 899;
         errorEl->setAttribute(_("code"), String::from(error_code));
         root->appendElementChild(errorEl);
     }
-    
+
     String returnType = param(_("return_type"));
-    if (string_ok(returnType) && returnType == "xml")
-    {
+    if (string_ok(returnType) && returnType == "xml") {
 #ifdef TOMBDEBUG
-        try
-        {
+        try {
             // make sure we can generate JSON w/o exceptions
             XML2JSON::getJSON(root);
             //log_debug("JSON-----------------------\n\n\n%s\n\n\n\n", XML2JSON::getJSON(root).c_str());
-        }
-        catch(Exception e)
-        {
+        } catch (const Exception e) {
             e.printStackTrace();
         }
 #endif
-            output = renderXMLHeader() + root->print();
-    }
-    else
-    {
-        try
-        {
+        output = renderXMLHeader() + root->print();
+    } else {
+        try {
             output = XML2JSON::getJSON(root);
-        }
-        catch(Exception e)
-        {
+        } catch (const Exception e) {
             e.printStackTrace();
         }
     }
-    
+
     /*
     try
     {
@@ -227,25 +210,23 @@ Ref<IOHandler> WebRequestHandler::open(IN enum UpnpOpenFileMode mode)
         String json = XML2JSON::getJSON(root);
         printf("%s\n",json.c_str());
     }
-    catch (Exception e)
+    catch (const Exception e)
     {
         e.printStackTrace();
     }
     */
-    
-    //root = nil;
-    
+
+    //root = nullptr;
+
     Ref<MemIOHandler> io_handler(new MemIOHandler(output));
     io_handler->open(mode);
     return RefCast(io_handler, IOHandler);
 }
 
-Ref<IOHandler> WebRequestHandler::open(IN const char *filename,
-                                       OUT struct File_Info *info,
-                                       IN enum UpnpOpenFileMode mode,
-                                       IN String range)
+Ref<IOHandler> WebRequestHandler::open(IN const char* filename,
+    IN enum UpnpOpenFileMode mode,
+    IN String range)
 {
-    log_debug("request: %s\n", filename);
     this->filename = filename;
     this->mode = mode;
 
@@ -253,26 +234,21 @@ Ref<IOHandler> WebRequestHandler::open(IN const char *filename,
     split_url(filename, URL_UI_PARAM_SEPARATOR, path, parameters);
 
     params->decode(parameters);
-    
-    get_info(NULL, info);
+
     return open(mode);
 }
 
 void WebRequestHandler::handleUpdateIDs()
 {
     // session will be filled by check_request
-    
+
     String updates = param(_("updates"));
-    if (string_ok(updates))
-    {
+    if (string_ok(updates)) {
         Ref<Element> updateIDs(new Element(_("update_ids")));
         root->appendElementChild(updateIDs);
-        if (updates == "check")
-        {
+        if (updates == "check") {
             updateIDs->setAttribute(_("pending"), session->hasUIUpdateIDs() ? _("1") : _("0"), mxml_bool_type);
-        }
-        else if (updates == "get")
-        {
+        } else if (updates == "get") {
             addUpdateIDs(updateIDs, session);
         }
     }
@@ -281,8 +257,7 @@ void WebRequestHandler::handleUpdateIDs()
 void WebRequestHandler::addUpdateIDs(Ref<Element> updateIDsEl, Ref<Session> session)
 {
     String updateIDs = session->getUIUpdateIDs();
-    if (string_ok(updateIDs))
-    {
+    if (string_ok(updateIDs)) {
         log_debug("UI: sending update ids: %s\n", updateIDs.c_str());
         updateIDsEl->setTextKey(_("ids"));
         updateIDsEl->setText(updateIDs);
@@ -292,9 +267,9 @@ void WebRequestHandler::addUpdateIDs(Ref<Element> updateIDsEl, Ref<Session> sess
 
 void WebRequestHandler::appendTask(Ref<Element> el, Ref<GenericTask> task)
 {
-    if (task == nil || el == nil)
+    if (task == nullptr || el == nullptr)
         return;
-    Ref<Element> taskEl (new Element(_("task")));
+    Ref<Element> taskEl(new Element(_("task")));
     taskEl->setAttribute(_("id"), String::from(task->getID()), mxml_int_type);
     taskEl->setAttribute(_("cancellable"), task->isCancellable() ? _("1") : _("0"), mxml_bool_type);
     taskEl->setTextKey(_("text"));
diff --git a/src/web_request_handler.h b/src/web_request_handler.h
index aa114fa..bc57d98 100644
--- a/src/web_request_handler.h
+++ b/src/web_request_handler.h
@@ -83,7 +83,7 @@ protected:
     /// \brief Little support function to access stuff from the dictionary in
     /// in an easier fashion.
     /// \param name of the parameter we are looking for.
-    /// \return Value of the parameter with the given name or nil if not found.
+    /// \return Value of the parameter with the given name or nullptr if not found.
     inline zmm::String param(zmm::String name) { return params->get(name); }
     
     int intParam(zmm::String name, int invalid = 0);
@@ -97,7 +97,7 @@ protected:
     void check_request(bool checkLogin = true);
     
     /// \brief Helper function to create a generic XML document header.
-    /// \param xsl_link If not nil, also adds header information that is required for the XSL processor.
+    /// \param xsl_link If not nullptr, also adds header information that is required for the XSL processor.
     /// \return The header as a string... because our parser does not yet understand <? ?> stuff :)
     zmm::String renderXMLHeader();
     
@@ -139,14 +139,13 @@ public:
     /// dynamic XML) we do not know the size of the data. This is of course different
     /// for the FileRequestHandler, where we can check the file and return all
     /// information about it.
-    virtual void get_info(IN const char *filename, OUT struct File_Info *info);
+    virtual void get_info(IN const char *filename, OUT UpnpFileInfo *info);
     
     /// \brief Decodes the parameters from the filename (URL) and calls the internal open() function.
     /// \param filename The requested URL
     /// \param mode either UPNP_READ or UPNP_WRITE
     /// \return the appropriate IOHandler for the request.
     virtual zmm::Ref<IOHandler> open(IN const char *filename,
-                                     OUT struct File_Info *info,
                                      IN enum UpnpOpenFileMode mode,
                                      IN zmm::String range);
     
diff --git a/src/weborama_content_handler.cc b/src/weborama_content_handler.cc
deleted file mode 100644
index 2d43d95..0000000
--- a/src/weborama_content_handler.cc
+++ /dev/null
@@ -1,240 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    weborama_content_handler.cc - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file weborama_content_handler.cc
-/// \brief Implementation of the WeboramaContentHandler class.
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#if defined(WEBORAMA)
-
-#include "weborama_content_handler.h"
-#include "online_service.h"
-#include "tools.h"
-#include "metadata_handler.h"
-#include "cds_objects.h"
-#include "config_manager.h"
-
-using namespace zmm;
-using namespace mxml;
-
-bool WeboramaContentHandler::setServiceContent(zmm::Ref<mxml::Element> service)
-{
-    String temp;
-
-    if (service->getName() != "playlist")
-        throw _Exception(_("Recieved invalid XML for Weborama service"));
-
-    if (service->getAttribute(_("version")) != "1")
-        throw _Exception(_("Recieved unsupported playlist version from Weborama"
-                           " service"));
-
-    Ref<Element> trackList = service->getChildByName(_("trackList"));
-    if (trackList == nil)
-        throw _Exception(_("Received invalid XML for Weborama service: "
-                           "track list not found!"));
-
-/*    
-    String mood = service->getChildText(_("mood"));
-    if (string_ok(mood))
-        this->mood = mood;
-*/
-
-    this->service_xml = trackList;
-
-    track_count = service_xml->childCount();
-    
-    if (track_count == 0)
-        return false;
-
-    current_track_index = 0;
-
-    return true;
-}
-
-Ref<CdsObject> WeboramaContentHandler::getNextObject()
-{
-    String temp;
-    struct timespec ts;
-
-    while (current_track_index < track_count)
-    {
-        Ref<Node> n = service_xml->getChild(current_track_index);
-
-        current_track_index++;
-      
-        if (n == nil)
-            return nil;
-
-        if (n->getType() != mxml_node_element)
-            continue;
-
-        Ref<Element> track = RefCast(n, Element);
-        if (track->getName() != "track")
-            continue;
-
-        // we know what we are adding
-        Ref<CdsItemExternalURL> item(new CdsItemExternalURL());
-        Ref<CdsResource> resource(new CdsResource(CH_DEFAULT));
-        item->addResource(resource);
-
-        temp = track->getChildText(_("title"));
-        if (!string_ok(temp))
-            item->setTitle(_("Unknown"));
-        else
-            item->setTitle(temp);
-
-        temp = track->getAttribute(_("mimeType"));
-        if (string_ok(temp))
-        {
-            item->setMimeType(temp);
-            resource->addAttribute(MetadataHandler::getResAttrName(R_PROTOCOLINFO), renderProtocolInfo(temp));
-        }
-        else
-        {
-            log_warning("Could not retrieve mime type for %s, skipping...\n",
-                        item->getTitle().c_str());
-            continue;
-        }
-
-        item->setAuxData(_(ONLINE_SERVICE_AUX_ID), String::from(OS_Weborama));
-
-        temp = track->getChildText(_("identifier"));
-        if (!string_ok(temp))
-        {
-            log_warning("Failed to retrieve Weborama track ID for \"%s\", skipping...\n",
-                        item->getTitle().c_str());
-            continue;
-        }
-
-        temp = String(OnlineService::getStoragePrefix(OS_Weborama)) + temp;
-        item->setServiceID(temp);
-
-        temp = track->getChildText(_("location")); 
-        if (string_ok(temp))
-            item->setURL(temp);
-        else
-        {
-            log_error("Could not get location for Weborama item %s, "
-                      "skipping.\n", item->getTitle().c_str());
-            continue;
-        }
-
-        /// \todo what about upnp class mappings from the configuration?
-        item->setClass(_("object.item.audioItem.musicTrack"));
-
-        temp = track->getChildText(_("creator"));
-        if (string_ok(temp))
-            item->setMetadata(MetadataHandler::getMetaFieldName(M_ARTIST), temp);
-      //      item->setAuxData(_(WEBORAMA_AUXDATA_CREATOR), temp);
-
-        temp = track->getChildText(_("album"));
-        if (string_ok(temp))
-            item->setMetadata(MetadataHandler::getMetaFieldName(M_ALBUM), temp);
-
-        temp = track->getChildText(_("duration")); // milliseconds
-        if (string_ok(temp))
-        {
-            int d = temp.toInt();
-            if (d > 0)
-                resource->addAttribute(MetadataHandler::getResAttrName(
-                                                                R_DURATION),
-                                       secondsToHMS(d/1000));
-        }
-
-        temp = track->getChildText(_("bitrate"));
-        if (string_ok(temp))
-        {
-            int br = temp.toInt();
-            br = br / 8;
-            if (br > 0)
-                resource->addAttribute(
-                                    MetadataHandler::getResAttrName(R_BITRATE),
-                                                           String::from(br));
-        }
-
-        temp = track->getChildText(_("frequency"));
-        if (string_ok(temp))
-            resource->addAttribute(
-                            MetadataHandler::getResAttrName(R_SAMPLEFREQUENCY),
-                            temp);
-
-        /// \todo check about trackNum - what is it really?
-        
-        Ref<Element> image = track->getChildByName(_("image"));
-        if (image != nil)
-        {
-            temp = image->getAttribute(_("mimeType"));
-            if (string_ok(temp))
-            {
-                Ref<CdsResource> albumart(new CdsResource(CH_EXTURL));
-                albumart->addOption(_(RESOURCE_CONTENT_TYPE), _(ID3_ALBUM_ART));
-                albumart->addAttribute(MetadataHandler::getResAttrName(
-                            R_PROTOCOLINFO), renderProtocolInfo(temp));
-
-                temp = image->getAttribute(_("size"));
-                if (string_ok(temp))
-                    albumart->addAttribute(MetadataHandler::getResAttrName(
-                                R_RESOLUTION), temp + "x" + temp);
-
-                temp = image->getText();
-                if (string_ok(temp))
-                {
-                    albumart->addOption(_(RESOURCE_OPTION_URL), temp);
-                    albumart->addOption(_(RESOURCE_OPTION_PROXY_URL), _(FALSE));
-                    item->addResource(albumart);
-                }
-            }
-        }
-
-//        item->setAuxData(_(WEBORAMA_AUXDATA_MOOD), mood);
-
-        getTimespecNow(&ts);
-        item->setAuxData(_(ONLINE_SERVICE_LAST_UPDATE), 
-                         String::from(ts.tv_sec));
-
-        item->setFlag(OBJECT_FLAG_ONLINE_SERVICE);
-        try
-        {
-            item->validate();
-            return RefCast(item, CdsObject);
-        }
-        catch (Exception ex)
-        {
-            log_warning("Failed to validate newly created Weborama item: %s\n",
-                        ex.getMessage().c_str());
-            continue;
-        }
-    } // while
-    return nil;
-}
-
-#endif//WEBORAMA
diff --git a/src/weborama_content_handler.h b/src/weborama_content_handler.h
deleted file mode 100644
index bdb51f8..0000000
--- a/src/weborama_content_handler.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    weborama_content_handler.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file weborama_content_handler.h
-/// \brief Definitions of the WeboramaContentHandler class.
-
-#ifdef WEBORAMA
-
-#ifndef __WEBORAMA_CONTENT_HANDLER_H__
-#define __WEBORAMA_CONTENT_HANDLER_H__
-
-#define WEBORAMA_SERVICE                     "Weborama"
-#define WEBORAMA_SERVICE_ID                  "W"
-
-#define WEBORAMA_AUXDATA_REQUEST_NAME       WEBORAMA_SERVICE_ID "0"
-
-#include "zmmf/zmmf.h"
-#include "mxml/mxml.h"
-#include "cds_objects.h"
-
-/// \brief this class is responsible for creating objects from the Weborama
-/// metadata XML.
-class WeboramaContentHandler : public zmm::Object
-{
-public:
-    /// \brief Sets the service XML from which we will extract the objects.
-    /// \return false if service XML contained an error status.
-    bool setServiceContent(zmm::Ref<mxml::Element> service);
-
-    /// \brief retrieves an object from the service.
-    ///
-    /// Each invokation of this funtion will return a new object,
-    /// when the whole service XML is parsed and no more objects are left,
-    /// this function will return nil.
-    ///
-    /// \return CdsObject or nil if there are no more objects to parse.
-    zmm::Ref<CdsObject> getNextObject();
-
-protected:
-    zmm::Ref<mxml::Element> service_xml;
-    int current_track_index;
-    int track_count;
-    zmm::String mood;
-};
-
-#endif//__WEBORAMA_CONTENT_HANDLER_H__
-
-#endif//WEBORAMA
diff --git a/src/weborama_service.cc b/src/weborama_service.cc
deleted file mode 100644
index 8d2cdd2..0000000
--- a/src/weborama_service.cc
+++ /dev/null
@@ -1,595 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    weborama_service.cc - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file weborama_service.cc
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#ifdef WEBORAMA 
-
-#include "zmm/zmm.h"
-#include "weborama_service.h"
-#include "weborama_content_handler.h"
-#include "content_manager.h"
-#include "string_converter.h"
-#include "config_manager.h"
-#include "config_options.h"
-#include "server.h"
-
-using namespace zmm;
-using namespace mxml;
-
-#define WEBORAMA_SERVICE_URL            "www.weborama.ru/modules/player/index_xspf.php"
-
-/// \todo ask Nick if this value makes sense
-#define DEFAULT_PER_TASK_AMOUNT         (1000)
-
-#define WEBORAMA_VALUE_PER_REQUEST_MAX  (100)
-// Weborama defines
-#define FILTER_OPTION_FAVORITE          "favourite"
-#define FILTER_OPTION_FRIENDS           "friends"
-#define FILTER_OPTION_USERID            "userId"
-#define FILTER_OPTION_UPLOADED          "uploaded"
-//#define FILTER_OPTION_USER_COUNT        "user_count"
-#define FILTER_OPTION_USER_LAST         "used_last"
-#define FILTER_OPTION_ALL               "all"
-#define FILTER_OPTION_GENREID           "genreId"
-#define FILTER_OPTION_SORT              "sort"
-#define FILTER_SEPARATOR                ";"
-#define FILTER_VALUE_SEPARATOR          ":"
-
-
-#define PARAM_LIMIT                     "limit"
-#define PARAM_OFFSET                    "offset"
-#define PARAM_COVER_SIZE                "coverSize"
-#define PARAM_FILTER                    "filter"
-#define PARAM_TYPE                      "type"
-#define PARAM_MOOD                      "mood"
-#define PARAM_ACTION                    "action"
-#define PARAM_ID                        "id"
-
-#define VALUE_COVER_SIZE_DLNA           "160"
-#define VALUE_TYPE_PLAYLIST             "playlist"
-#define VALUE_TYPE_AUDIO                "audio"
-
-// config.xml defines
-#define CFG_REQUEST_PLAYLIST            "playlist"
-
-#define CFG_SECTION_FILTER              "filter"
-#define CFG_SECTION_GENRES              "genres"
-#define CFG_SECTION_SORT                "sort"
-#define CFG_SECTION_TYPE                "type"
-
-#define CFG_SORT_FAVORITE        "favorite"
-#define CFG_SORT_FRIENDS         "friends"
-#define CFG_SORT_UPLOADED        "uploaded"
-#define CFG_SORT_USED_LAST       "used_last"
-#define CFG_SORT_ALL             "all"
-
-#define CFG_OPTION_PLAYLIST_NAME        "name"
-
-#define CFG_MOOD_0               "calm-positive"     
-#define CFG_MOOD_1               "positive"
-#define CFG_MOOD_2               "energetic-positive"
-#define CFG_MOOD_3               "calm"
-#define CFG_MOOD_4               "neutral"
-#define CFG_MOOD_5               "energetic"
-#define CFG_MOOD_6               "calm-dark"
-#define CFG_MOOD_7               "dark"
-#define CFG_MOOD_8               "energetic-dark"
-
-#define CFG_TYPE_AUDIO           "audio"
-#define CFG_TYPE_PLAYLIST        "playlist"
-#define CFG_TYPE_ALBUM           "album"
-
-/*
-Электронная       67
-Русская попса     400
-Альтернатива      60
-Саундтрек         353
-Джаз              65
-Русский рок       315
-Металл            272
-Ретро             568
-Поп               69
-Панк              388
-Ритм энд блюз     738
-Рэп               593
-Регги             699
-Рок               68
-Классическая      976
-Шансон            566
-Фолк              63
-*/
-
-#define CFG_GENRE_ELECT          "electronic"
-#define CFG_GENRE_ALT            "alternative"
-#define CFG_GENRE_JAZZ           "jazz"
-#define CFG_GENRE_METAL          "metal"
-#define CFG_GENRE_DMETAL         "death-metal"
-#define CFG_GENRE_POP            "pop"
-#define CFG_GENRE_PUNK           "punk"
-#define CFG_GENRE_RNB            "rhytm-and-blues"
-#define CFG_GENRE_RAP            "rap"
-#define CFG_GENRE_REG            "reggae"
-#define CFG_GENRE_ROCK           "rock"
-#define CFG_GENRE_CLAS           "classic"
-#define CFG_GENRE_ST             "soundtrack"
-#define CFG_GENRE_RETRO          "retro"
-#define CFG_GENRE_RUSROCK        "russian-rock"
-#define CFG_GENRE_RUSPOP         "russian-pop"
-#define CFG_GENRE_CHAN           "chanson"
-#define CFG_GENRE_FOLK           "folk"
-
-typedef struct wr_mood wr_mood;
-struct wr_mood
-{
-    wr_mood_t mood;
-    const char *cfg_name;
-    const char *aux_name;
-};
-
-wr_mood WR_mood[] = 
-{
-    { WR_mood_calm_positive,         CFG_MOOD_0, "Calm-Positive"      },
-    { WR_mood_positive,              CFG_MOOD_1, "Positive"           },
-    { WR_mood_energetic_positive,    CFG_MOOD_2, "Energetic-Positive" },
-    { WR_mood_calm,                  CFG_MOOD_3, "Calm"               },
-    { WR_mood_neutral,               CFG_MOOD_4, "Neutral"            },
-    { WR_mood_energetic,             CFG_MOOD_5, "Energetic"          },
-    { WR_mood_calm_dark,             CFG_MOOD_6, "Calm-Dark"          },
-    { WR_mood_dark,                  CFG_MOOD_7, "Dark"               },
-    { WR_mood_energetic_dark,        CFG_MOOD_8, "Energetic-Dark"     },
-    { WR_mood_none, NULL, NULL },
-};
-
-typedef struct wr_genre wr_genre;
-struct wr_genre
-{
-    wr_genre_t genre;
-    int id;
-    const char *cfg_name;
-    const char *aux_name;
-};
-
-wr_genre WR_genre[] = 
-{   
-    { WR_genre_electronic,      67,  CFG_GENRE_ELECT,   "Electronic"      },
-    { WR_genre_alternative,     60,  CFG_GENRE_ALT,     "Alternative"     },
-    { WR_genre_jazz,            65,  CFG_GENRE_JAZZ,    "Jazz"            }, 
-    { WR_genre_metal,           181, CFG_GENRE_METAL,   "Metal"           },
-    { WR_genre_death_metal,     549, CFG_GENRE_DMETAL,  "Death Metal"     }, 
-    { WR_genre_pop,             69,  CFG_GENRE_POP,     "Pop"             },
-    { WR_genre_punk,            388, CFG_GENRE_PUNK,    "Punk"            },
-    { WR_genre_rhytm_and_blues, 738, CFG_GENRE_RNB,     "Rhytm And Blues" },
-    { WR_genre_rap,             593, CFG_GENRE_RAP,     "Rap"             },
-    { WR_genre_reggae,          699, CFG_GENRE_REG,     "Reggae"          },
-    { WR_genre_rock,            68,  CFG_GENRE_ROCK,    "Rock"            },
-    { WR_genre_classic,         976, CFG_GENRE_CLAS,    "Classic"         },
-    { WR_genre_soundtrack,      353, CFG_GENRE_ST,      "Soundtrack"      },
-    { WR_genre_retro,           568, CFG_GENRE_RETRO,   "Retro"           },
-    { WR_genre_russian_rock,    315, CFG_GENRE_RUSROCK, "Russian Rock"    },
-    { WR_genre_russian_pop,     400, CFG_GENRE_RUSPOP,  "Russian Pop"     },
-    { WR_genre_chanson,         566, CFG_GENRE_CHAN,    "Chanson"         },
-    { WR_genre_folk,            63,  CFG_GENRE_FOLK,    "Folk"            },
-    { WR_genre_none, -1, NULL, NULL },                           
-};
-
-WeboramaService::WeboramaService()
-{
-    url = Ref<URL>(new URL());
-    pid = 0;
-    curl_handle = curl_easy_init();
-    if (!curl_handle)
-        throw _Exception(_("failed to initialize curl!\n"));
-
-    current_task = 0;
-}
-
-WeboramaService::~WeboramaService()
-{
-    if (curl_handle)
-        curl_easy_cleanup(curl_handle);
-}
-
-WeboramaService::WeboramaTask::WeboramaTask()
-{
-    parameters = zmm::Ref<Dictionary>(new Dictionary());
-    amount = 0;
-    amount_fetched = 0;
-    start_index = 0;
-}
-
-
-service_type_t WeboramaService::getServiceType()
-{
-    return OS_Weborama;
-}
-
-String WeboramaService::getServiceName()
-{
-    return _("Weborama");
-}
-
-wr_mood_t WeboramaService::getMood(Ref<Element> xml)
-{
-    String temp = xml->getAttribute(_("mood"));
-    if (!string_ok(temp))
-        return WR_mood_none;
-
-    int i = temp.toInt();
-    if ((i < 0) || (i >= WR_mood_none))
-        throw _Exception(_("Weborama: invalid mood specified for tag <") + 
-                         xml->getName() + ">");
-
-    return WR_mood[i].mood;
-}
-
-wr_genre_t WeboramaService::getGenre(String genre)
-{
-    if (!string_ok(genre))
-        return WR_genre_none;
-
-    for (int i = (int)WR_genre_electronic; i < (int)WR_genre_none; i++)
-    {
-        if (genre == WR_genre[i].cfg_name)
-            return WR_genre[i].genre;
-    }
-
-    return WR_genre_none;
-}
-
-int WeboramaService::getGenreID(wr_genre_t genre)
-{
-    if (((int)genre < 0) || ((int)genre > WR_genre_none))
-        return -1;
-
-    return WR_genre[genre].id;
-}
-
-Ref<Object> WeboramaService::defineServiceTask(Ref<Element> xmlopt, Ref<Object> params)
-{
-    Ref<WeboramaTask> task(new WeboramaTask());
-    String temp = xmlopt->getName();
-        
-    task->parameters->put(_(PARAM_COVER_SIZE), _(VALUE_COVER_SIZE_DLNA));
-    task->amount = DEFAULT_PER_TASK_AMOUNT;
-
-    if (temp == CFG_REQUEST_PLAYLIST)
-    {
-        task->name = getCheckAttr(xmlopt, _(CFG_OPTION_PLAYLIST_NAME));
-
-        Ref<Element> type = xmlopt->getChildByName(_(CFG_SECTION_TYPE));
-        if (type != nil)
-        {
-            String id = type->getAttribute(_("id"));
-
-            temp = type->getText();
-            if (string_ok(temp))
-            {
-                if ((temp != CFG_TYPE_ALBUM) && (temp != CFG_TYPE_AUDIO) &&
-                    (temp != CFG_TYPE_PLAYLIST))
-                    throw _Exception(_("Weborama: ") + temp + 
-                            _(" type is invalid!"));
-
-                if (((temp == CFG_TYPE_ALBUM) || (temp == CFG_TYPE_AUDIO))
-                        && (!string_ok(id) || id == "0"))
-                {
-                    throw _Exception(_("Weborama: ") + temp + 
-                                     _(" type requires a valid id parameter!"));
-                }
-
-                task->parameters->put(_(PARAM_TYPE), temp);
-                if (string_ok(id))
-                    task->parameters->put(_(PARAM_ID), id);
-            }
-        }
-
-        wr_mood_t mood = getMood(xmlopt);
-        if (mood != WR_mood_none)
-            task->parameters->put(_(PARAM_MOOD), String::from((int)mood));
-        
-
-        Ref<Element> filter = xmlopt->getChildByName(_(CFG_SECTION_FILTER));
-        if (filter != nil)
-        {
-            String filters;
-            String genres = filter->getChildText(_(CFG_SECTION_GENRES));
-            if (string_ok(genres))
-            {
-                String g;
-                Ref<Array<StringBase> > parts = split_string(genres, ',');
-                for (int i = 0; i < parts->size(); i++)
-                {
-                    wr_genre_t genre = getGenre(parts->get(i));
-                    if (genre == WR_genre_none)
-                        continue;
-
-                    g = g + String::from(getGenreID(genre)) + _(",");
-                }
-
-                if (string_ok(g))
-                    filters = _(FILTER_OPTION_GENREID) + 
-                              _(FILTER_VALUE_SEPARATOR) + 
-                              g.substring(0, g.length()-1);
-            }
-
-            Ref<Element> sort_tag = filter->getChildByName(_("sort"));
-            if (sort_tag != nil)
-            {
-                String user_id = sort_tag->getAttribute(_("user-id"));
-                String sort = sort_tag->getText();
-                if (string_ok(sort))
-                {
-                    if (!string_ok(user_id))
-                        throw _Exception(_("Weborama: sort option requires a "
-                                           "valid user-id setting!"));
-
-                    if ((sort != CFG_SORT_FAVORITE)  &&
-                        (sort != CFG_SORT_FRIENDS)   && 
-                        (sort != CFG_SORT_UPLOADED)  &&
-                        (sort != CFG_SORT_USED_LAST) && 
-                        (sort != CFG_SORT_ALL))
-                        throw _Exception(_("Weborama: ") + sort + 
-                                         _(" sort is invalid!"));
-
-                        // ok, this is a little hack'ish, but so far the config 
-                        // names match nicely with the actual parameters... 
-                        // all but one
-                    if (sort == CFG_SORT_FAVORITE) 
-                        sort = _(FILTER_OPTION_FAVORITE);
-
-                    if (string_ok(filters))
-                        filters = filters + _(FILTER_SEPARATOR);
-
-                    filters = filters + _(FILTER_OPTION_SORT) + 
-                             _(FILTER_VALUE_SEPARATOR) + sort +
-                             _(FILTER_SEPARATOR) +
-                             _(FILTER_OPTION_USERID) + user_id;
-                }
-            }
-
-            if (string_ok(filters))
-                task->parameters->put(_(PARAM_FILTER), filters);
-        }
-
-        temp = xmlopt->getAttribute(_("amount"));
-        if (string_ok(temp))
-        {
-            int amount = temp.toInt();
-            if (amount < 0)
-                throw _Exception(_("Weborama: invalid amount specified for task ") + xmlopt->getName());
-
-            task->amount = amount;
-        }
-        else
-            task->amount = DEFAULT_PER_TASK_AMOUNT;
-    } 
-    else
-        return nil;
-
-    return RefCast(task, Object);
-}
-
-Ref<Element> WeboramaService::getData(Ref<Dictionary> params)
-{
-    long retcode;
-    Ref<StringConverter> sc = StringConverter::i2i();
-
-    Ref<StringBuffer> buffer;
-    
-    try 
-    {
-        String URL = _(WEBORAMA_SERVICE_URL) + _("?") + params->encode();
-        log_debug("DOWNLOADING URL: %s\n", URL.c_str());
-        buffer = url->download(URL, &retcode, 
-                               curl_handle, false, true, true);
-    }
-    catch (Exception ex)
-    {
-        log_error("Failed to download Weborama XML data: %s\n", 
-                  ex.getMessage().c_str());
-        return nil;
-    }
-
-    if (buffer == nil)
-        return nil;
-
-    if (retcode != 200)
-        return nil;
-
-    log_debug("GOT BUFFER\n%s\n", buffer->toString().c_str()); 
-    Ref<Parser> parser(new Parser());
-    try
-    {
-        return parser->parseString(sc->convert(buffer->toString()))->getRoot();
-    }
-    catch (ParseException pe)
-    {
-        log_error("Error parsing Weborama XML %s line %d:\n%s\n",
-               pe.context->location.c_str(),
-               pe.context->line,
-               pe.getMessage().c_str());
-        return nil;
-    }
-    catch (Exception ex)
-    {
-        log_error("Error parsing Weborama XML %s\n", ex.getMessage().c_str());
-        return nil;
-    }
-    
-    return nil;
-}
-
-bool WeboramaService::refreshServiceData(Ref<Layout> layout)
-{
-    log_debug("Refreshing Weborama service\n");
-    // the layout is in full control of the service items
-    
-    // this is a safeguard to ensure that this class is not called from
-    // multiple threads - it is not allowed to use the same curl handle
-    // from multiple threads
-    // we do it here because the handle is initialized in a different thread
-    // which is OK
-    if (pid == 0)
-        pid = pthread_self();
-
-    if (pid != pthread_self())
-        throw _Exception(_("Not allowed to call refreshServiceData from different threads!"));
-
-    Ref<ConfigManager> config = ConfigManager::getInstance();
-    Ref<Array<Object> > tasklist = config->getObjectArrayOption(CFG_ONLINE_CONTENT_WEBORAMA_TASK_LIST);
-
-    if (tasklist->size() == 0)
-        throw _Exception(_("Not specified what content to fetch!"));
-
-    Ref<WeboramaTask> task = RefCast(tasklist->get(current_task), WeboramaTask);
-    if (task ==  nil)
-        throw _Exception(_("Encountered invalid task!"));
-
-    if (task->amount_fetched < task->amount)
-    {
-        task->start_index = task->amount_fetched;
-        task->parameters->put(_(PARAM_OFFSET), String::from(task->start_index));
-        if ((task->amount - task->amount_fetched) >=
-                WEBORAMA_VALUE_PER_REQUEST_MAX)
-        {
-            task->parameters->put(_(PARAM_LIMIT), 
-                                  String::from(WEBORAMA_VALUE_PER_REQUEST_MAX));
-        }
-        else if ((task->amount - task->amount_fetched) <
-                 WEBORAMA_VALUE_PER_REQUEST_MAX)
-        {
-             task->parameters->put(_(PARAM_LIMIT), 
-                     String::from(task->amount - task->amount_fetched));
-        }
-    }
-    bool b = false;
-
-    Ref<Element> reply = getData(task->parameters);
-
-    Ref<WeboramaContentHandler> sc(new WeboramaContentHandler());
-    if (reply != nil)
-        b = sc->setServiceContent(reply);
-    else
-    {
-        log_debug("Failed to get XML content from Weborama service\n");
-        throw _Exception(_("Failed to get XML content from Weborama service"));
-    }
-
-    if (!b)
-    {
-        log_debug("End of pages\n");
-        task->amount_fetched = 0;
-        task->start_index = 0;
-
-        current_task++;
-        if (current_task >= tasklist->size())
-        {
-            current_task = 0;
-            return false;
-        }
-
-        return true;
-    }
-
-    /// \todo make sure the CdsResourceManager knows whats going on,
-    /// since those items do not contain valid links but need to be
-    /// processed later on (i.e. need to figure out the real link to the flv)
-    Ref<CdsObject> obj;
-    do
-    {
-        obj = sc->getNextObject();
-        if (obj == nil)
-        {
-            if (task->amount_fetched < task->amount)
-                return true;
-            else
-                break;
-        }
-
-        obj->setVirtual(true);
-        obj->setAuxData(_(WEBORAMA_AUXDATA_REQUEST_NAME), task->name);
-        RefCast(obj, 
-                CdsItemExternalURL)->setTrackNumber(task->amount_fetched+1);
-
-        Ref<CdsObject> old = Storage::getInstance()->loadObjectByServiceID(RefCast(obj, CdsItem)->getServiceID());
-        if (old == nil)
-        {
-            log_debug("Adding new Weborama object\n");
-            
-            if (layout != nil)
-                layout->processCdsObject(obj, nil);
-        }
-        else
-        {
-            log_debug("Updating existing Weborama object\n");
-            obj->setID(old->getID());
-            obj->setParentID(old->getParentID());
-            struct timespec oldt, newt;
-            oldt.tv_nsec = 0;
-            oldt.tv_sec = old->getAuxData(_(ONLINE_SERVICE_LAST_UPDATE)).toLong();
-            newt.tv_nsec = 0;
-            newt.tv_sec = obj->getAuxData(_(ONLINE_SERVICE_LAST_UPDATE)).toLong();
-            ContentManager::getInstance()->updateObject(obj);
-        }
-
-        task->amount_fetched++;
-        if (task->amount_fetched >= task->amount)
-        {
-            task->amount_fetched = 0;
-            task->start_index = 0;
-
-            current_task++;
-            if (current_task >= tasklist->size())
-            {
-                current_task = 0;
-                return false;
-            }
-        }
-
-        if (Server::getInstance()->getShutdownStatus())
-            return false;
-
-    }
-    while (obj != nil);
-
-    current_task++;
-    if (current_task >= tasklist->size())
-    {
-        current_task = 0;
-        return false;
-    }
-
-    return false;
-}
-
-#endif//WEBORAMA
diff --git a/src/weborama_service.h b/src/weborama_service.h
deleted file mode 100644
index 7577e8e..0000000
--- a/src/weborama_service.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    weborama_service.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file weborama_service.h
-/// \brief Definition of the WeboramaService class.
-
-#ifdef WEBORAMA
-
-#ifndef __WEBORAMA_SERVICE_H__
-#define __WEBORAMA_SERVICE_H__
-
-#include "zmm/zmm.h"
-#include "mxml/mxml.h"
-#include "online_service.h"
-#include "url.h"
-#include "dictionary.h"
-#include <curl/curl.h>
-
-
-typedef enum
-{
-    WR_mood_calm_positive = 0,
-    WR_mood_positive,
-    WR_mood_energetic_positive,
-    WR_mood_calm,
-    WR_mood_neutral,
-    WR_mood_energetic,
-    WR_mood_calm_dark,
-    WR_mood_dark,
-    WR_mood_energetic_dark,
-    WR_mood_none,
-} wr_mood_t;
-
-typedef enum
-{
-    WR_genre_electronic = 0,
-    WR_genre_alternative,
-    WR_genre_jazz,
-    WR_genre_metal,
-    WR_genre_death_metal,
-    WR_genre_pop,
-    WR_genre_punk,
-    WR_genre_rhytm_and_blues,
-    WR_genre_rap,
-    WR_genre_reggae,
-    WR_genre_rock,
-    WR_genre_classic,
-    WR_genre_soundtrack,
-    WR_genre_retro,
-    WR_genre_russian_rock,
-    WR_genre_russian_pop,
-    WR_genre_chanson,
-    WR_genre_folk,
-    WR_genre_none,
-} wr_genre_t;
-
-/// \brief This is an interface for all online services, the function
-/// handles adding/refreshing content in the database.
-class WeboramaService : public OnlineService
-{
-public:
-    WeboramaService();
-    ~WeboramaService();
-    /// \brief Retrieves user specified content from the service and adds
-    /// the items to the database.
-    virtual bool refreshServiceData(zmm::Ref<Layout> layout);
-
-    /// \brief Get the type of the service (i.e. Weborama, Shoutcast, etc.)
-    virtual service_type_t getServiceType();
-
-    /// \brief Get the human readable name for the service
-    virtual zmm::String getServiceName();
-
-    /// \brief Parse the xml fragment from the configuration and gather
-    /// the user settings in a service task structure.
-    virtual zmm::Ref<zmm::Object> defineServiceTask(zmm::Ref<mxml::Element> xmlopt, zmm::Ref<zmm::Object> params);
-
-protected:
-    // the handle *must never be used from multiple threads*
-    CURL *curl_handle;
-    // safeguard to ensure the above
-    pthread_t pid;
-
-    // url retriever class
-    zmm::Ref<URL> url;
-
-    /// \brief This function will retrieve the XML according to the parametrs
-    zmm::Ref<mxml::Element> getData(zmm::Ref<Dictionary> params);
-
-    /// \brief task that we will be working with when refreshServiceData is
-    /// called.
-    int current_task;
-
-    class WeboramaTask : public zmm::Object
-    {
-    public:
-        WeboramaTask();
-
-        /// \brief Name of the task as defined by the user.
-        zmm::String name;
-
-        /// \brief Weborama API URL parameters
-        zmm::Ref<Dictionary> parameters;
-
-        /// \brief Amount of items that we are allowed to get.
-        int amount;
-
-        /// \brief Amount of items that have been fetched.
-        int amount_fetched;
-
-        /// \brief Starting index of the item to fetch
-        int start_index;
-    };
-
-    wr_mood_t getMood(zmm::Ref<mxml::Element> xml);
-    wr_genre_t getGenre(zmm::String genre);
-    int getGenreID(wr_genre_t genre);
-};
-
-#endif//__ONLINE_SERVICE_H__
-
-#endif//WEBORAMA
diff --git a/src/xpath.cc b/src/xpath.cc
index a107fec..781e2ed 100644
--- a/src/xpath.cc
+++ b/src/xpath.cc
@@ -29,10 +29,6 @@
 
 /// \file xpath.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "common.h"
 #include "tools.h"
 #include "xpath.h"
@@ -48,7 +44,7 @@ XPath::XPath(Ref<Element> context) : Object()
 Ref<Element> XPath::getElement(String xpath)
 {
     String axisPart = getAxisPart(xpath);
-    if (axisPart != nil)
+    if (axisPart != nullptr)
     {
         throw _Exception(_("XPath::getElement: unexpected axis in ") + xpath);
     }
@@ -61,10 +57,10 @@ String XPath::getText(String xpath)
     String pathPart = getPathPart(xpath);
     
     Ref<Element> el = elementAtPath(pathPart);
-    if (el == nil)
-        return nil;
+    if (el == nullptr)
+        return nullptr;
     
-    if (axisPart == nil)
+    if (axisPart == nullptr)
         return el->getText();
     
     String axis = getAxis(axisPart);
@@ -99,7 +95,7 @@ Ref<Element> XPath::elementAtPath(String path)
     {
         String part = parts->get(i);
         cur = cur->getChildByName(part);
-        if (cur == nil)
+        if (cur == nullptr)
             break;
     }
     return cur;
@@ -114,17 +110,17 @@ String XPath::getAxisPart(String xpath)
     {
         return xpath.substring(slashPos + 1);
     }
-    return nil;
+    return nullptr;
 }
 
 String XPath::getAxis(String axisPart)
 {
-    char *pos = strstr(axisPart.c_str(), "::");
+    const char *pos = strstr(axisPart.c_str(), "::");
     return axisPart.substring(0, pos - axisPart.c_str());
 }
 
 String XPath::getSpec(String axisPart)
 {
-    char *pos = strstr(axisPart.c_str(), "::");
+    const char *pos = strstr(axisPart.c_str(), "::");
     return pos + 2;
 }
diff --git a/src/xpath.h b/src/xpath.h
index 22cb627..38165ca 100644
--- a/src/xpath.h
+++ b/src/xpath.h
@@ -32,7 +32,7 @@
 #ifndef __XPATH_H__
 #define __XPATH_H__
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 #include "mxml/mxml.h"
 
 class XPath : public zmm::Object
diff --git a/src/youtube_content_handler.cc b/src/youtube_content_handler.cc
index 58d9f4d..b5a9db0 100644
--- a/src/youtube_content_handler.cc
+++ b/src/youtube_content_handler.cc
@@ -30,10 +30,6 @@
 /// \file youtube_content_handler.cc
 /// \brief Implementation of the YouTubeContentHandler class.
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #if defined(YOUTUBE)
 
 #include "youtube_content_handler.h"
@@ -57,7 +53,7 @@ bool YouTubeContentHandler::setServiceContent(zmm::Ref<mxml::Element> service)
         throw _Exception(_("Invalid XML for YouTube service received"));
 
     Ref<Element> channel = service->getChildByName(_("channel"));
-    if (channel == nil)
+    if (channel == nullptr)
         throw _Exception(_("Invalid XML for YouTube service received - channel not found!"));
 
     this->service_xml = channel;
@@ -83,7 +79,7 @@ bool YouTubeContentHandler::setServiceContent(zmm::Ref<mxml::Element> service)
     while (item_node_index < channel_child_count)
     {
         Ref<Node> n = service_xml->getChild(item_node_index);
-        if (n == nil)
+        if (n == nullptr)
             return false;
         
         item_node_index++;
@@ -132,7 +128,7 @@ Ref<YouTubeSubFeed> YouTubeContentHandler::getSubFeed(Ref<Element> feedxml)
         throw _Exception(_("Invalid XML for YouTube feed received"));
 
     Ref<Element> channel = feedxml->getChildByName(_("channel"));
-    if (channel == nil)
+    if (channel == nullptr)
         throw _Exception(_("Invalid XML for YouTube service received - channel not found!"));
    
     subfeed->title = channel->getChildText(_("title"));
@@ -156,7 +152,7 @@ Ref<YouTubeSubFeed> YouTubeContentHandler::getSubFeed(Ref<Element> feedxml)
             continue;
 
         Ref<Element> link = channel_item->getChildByName(_("gd:feedLink"));
-        if (link == nil)
+        if (link == nullptr)
             continue;
         temp = link->getAttribute(_("href"));
         if (!string_ok(temp))
@@ -182,8 +178,8 @@ Ref<CdsObject> YouTubeContentHandler::getNextObject()
 
         current_node_index++;
       
-        if (n == nil)
-            return nil;
+        if (n == nullptr)
+            return nullptr;
 
         if (n->getType() != mxml_node_element)
             continue;
@@ -229,7 +225,7 @@ Ref<CdsObject> YouTubeContentHandler::getNextObject()
         {
             datebuf[0] = '\0';
             // Tue, 18 Jul 2006 17:43:47 +0000
-            if (strptime(temp.c_str(),  "%a, %d %b %Y %T +000", &t) != NULL)
+            if (strptime(temp.c_str(),  "%a, %d %b %Y %T +000", &t) != nullptr)
             {
                 if (strftime(datebuf, sizeof(datebuf), "%F", &t) != 0)
                 {
@@ -249,7 +245,7 @@ Ref<CdsObject> YouTubeContentHandler::getNextObject()
             item->setAuxData(_(YOUTUBE_AUXDATA_AUTHOR), temp);
 
         Ref<Element> mediagroup = channel_item->getChildByName(_("media:group"));
-        if (mediagroup == nil)
+        if (mediagroup == nullptr)
             continue;
 
         // media:group uses a couple of elements with the same name, so
@@ -261,7 +257,7 @@ Ref<CdsObject> YouTubeContentHandler::getNextObject()
         for (int mcc = 0; mcc < mediagroup_child_count; mcc++)
         {
             Ref<Element> el = mediagroup->getElementChild(mcc);
-            if (el == nil)
+            if (el == nullptr)
                 continue;
 
             if (el->getName() == "media:title")
@@ -301,14 +297,12 @@ Ref<CdsObject> YouTubeContentHandler::getNextObject()
 
                 String mt;
                 if (ConfigManager::getInstance()->getBoolOption(CFG_ONLINE_CONTENT_YOUTUBE_FORMAT_MP4))
-                {
                     mt = mp4_mimetype;
-                }
                 else
                     mt = _("video/x-flv");
 
-                    item->setMimeType(mt);
-                    resource->addAttribute(MetadataHandler::getResAttrName(R_PROTOCOLINFO), renderProtocolInfo(mt));
+                item->setMimeType(mt);
+                resource->addAttribute(MetadataHandler::getResAttrName(R_PROTOCOLINFO), renderProtocolInfo(mt));
 
                 content_set = true;
  
@@ -352,7 +346,7 @@ Ref<CdsObject> YouTubeContentHandler::getNextObject()
         }
       
         Ref<Element> stats = channel_item->getChildByName(_("yt:statistics"));
-        if (stats != nil)
+        if (stats != nullptr)
         {
             temp = stats->getAttribute(_("viewCount"));
             if (string_ok(temp))
@@ -364,7 +358,7 @@ Ref<CdsObject> YouTubeContentHandler::getNextObject()
         }
 
         Ref<Element> rating = channel_item->getChildByName(_("gd:rating"));
-        if (rating != nil)
+        if (rating != nullptr)
         {
             temp = rating->getAttribute(_("average"));
             if (string_ok(temp))
@@ -387,20 +381,20 @@ Ref<CdsObject> YouTubeContentHandler::getNextObject()
             item->validate();
             return RefCast(item, CdsObject);
         }
-        catch (Exception ex)
+        catch (const Exception & ex)
         {
             log_warning("Failed to validate newly created YouTube item: %s\n",
                         ex.getMessage().c_str());
             continue;
         }
     } // while
-    return nil;
+    return nullptr;
 }
 
 YouTubeSubFeed::YouTubeSubFeed()
 {
     links = Ref<Array<StringBase> >(new Array<StringBase>());
-    title = nil;
+    title = nullptr;
 }
 
 #endif//YOUTUBE
diff --git a/src/youtube_content_handler.h b/src/youtube_content_handler.h
index 9777dba..6f3aa35 100644
--- a/src/youtube_content_handler.h
+++ b/src/youtube_content_handler.h
@@ -50,7 +50,7 @@
 #define YOUTUBE_AUXDATA_CATEGORY            YOUTUBE_SERVICE_ID "10"
 #define YOUTUBE_AUXDATA_REGION              YOUTUBE_SERVICE_ID "11"
 
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 #include "mxml/mxml.h"
 #include "cds_objects.h"
 
@@ -80,9 +80,9 @@ public:
     ///
     /// Each invokation of this funtion will return a new object,
     /// when the whole service XML is parsed and no more objects are left,
-    /// this function will return nil.
+    /// this function will return nullptr.
     ///
-    /// \return CdsObject or nil if there are no more objects to parse.
+    /// \return CdsObject or nullptr if there are no more objects to parse.
     zmm::Ref<CdsObject> getNextObject();
 
     /// \brief Retrieves a list of feed URLs from a subscription request along
diff --git a/src/youtube_service.cc b/src/youtube_service.cc
index 09c566e..603d710 100644
--- a/src/youtube_service.cc
+++ b/src/youtube_service.cc
@@ -29,10 +29,6 @@
 
 /// \file youtube_service.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef YOUTUBE 
 
 #include "zmm/zmm.h"
@@ -83,7 +79,7 @@ static const char *YT_stdfeeds[] =
     GDATA_REQUEST_STDFEED_MOST_RESPONDED,   // has time
     GDATA_REQUEST_STDFEED_RECENTLY_FEATURED,
     GDATA_REQUEST_STDFEED_WATCH_ON_MOBILE,
-    NULL,
+    nullptr,
 };
 
 // gdata default parameters
@@ -243,7 +239,7 @@ static regions YT_regions[] =
     { YT_region_es, CFG_OPTION_SPAIN,                 "Spain"           },
     { YT_region_tw, CFG_OPTION_TAIWAN,                "Taiwan"          },
     { YT_region_us, CFG_OPTION_UNITED_STATES,         "United States"   },
-    { YT_region_none, NULL , NULL },
+    { YT_region_none, nullptr , nullptr },
 };
 
 YouTubeService::YouTubeService()
@@ -314,7 +310,7 @@ String YouTubeService::getRequestName(yt_requests_t request)
             break;
         case YT_request_none:
         default:
-            temp = nil;
+            temp = nullptr;
             break;
     }
 
@@ -324,7 +320,7 @@ String YouTubeService::getRequestName(yt_requests_t request)
 String YouTubeService::getRegionName(yt_regions_t region_code)
 {
     if ((region_code < 0) || (region_code >= YT_region_none))
-        return nil;
+        return nullptr;
     else
         return _(YT_regions[region_code].country);
 }
@@ -337,9 +333,9 @@ String YouTubeService::getCheckAttr(Ref<Element> xml, String attrname)
         return temp;
     else
         throw _Exception(_("Tag <") + xml->getName() +
-                _("> is missing the requred \"") + attrname + 
+                _("> is missing the required \"") + attrname + 
                 _("\" attribute!"));
-    return nil;
+    return nullptr;
 }
 
 int YouTubeService::getCheckPosIntAttr(Ref<Element> xml, String attrname)
@@ -350,7 +346,7 @@ int YouTubeService::getCheckPosIntAttr(Ref<Element> xml, String attrname)
         itmp = temp.toInt();
     else
         throw _Exception(_("Tag <") + xml->getName() +
-                _("> is missing the requred \"") + attrname + 
+                _("> is missing the required \"") + attrname + 
                 _("\" attribute!"));
 
     if (itmp < 1)
@@ -424,7 +420,7 @@ yt_regions_t YouTubeService::getRegion(Ref<Element> xml)
         return YT_region_none;
 
     int count = 0;
-    while (YT_regions[count].region_code != NULL)
+    while (YT_regions[count].region_code != nullptr)
     {
         if (region == YT_regions[count].region_code)
             return YT_regions[count].region;
@@ -442,7 +438,7 @@ String YouTubeService::getFeed(Ref<Element> xml)
         throw _Exception(_("<") + xml->getName() + _("> tag is missing the required feed setting!"));
 
     int count = 0;
-    while (YT_stdfeeds[count] != NULL)
+    while (YT_stdfeeds[count] != nullptr)
     {
         if (feed == YT_stdfeeds[count])
             return feed;
@@ -586,7 +582,7 @@ Ref<Element> YouTubeService::getData(String url_part, Ref<Dictionary> params, bo
     else
         URL = url_part;
     
-    if ((params != nil) && (params->size() > 0))
+    if ((params != nullptr) && (params->size() > 0))
     {
         if (URL.index('?') > 0)
             URL = URL + _("&") + params->encode();
@@ -601,18 +597,18 @@ Ref<Element> YouTubeService::getData(String url_part, Ref<Dictionary> params, bo
     {
         buffer = url->download(URL, &retcode, curl_handle, false, true);
     }
-    catch (Exception ex)
+    catch (const Exception & ex)
     {
         log_error("Failed to download YouTube XML data: %s\n", 
                   ex.getMessage().c_str());
-        return nil;
+        return nullptr;
     }
 
-    if (buffer == nil)
-        return nil;
+    if (buffer == nullptr)
+        return nullptr;
 
     if (retcode != 200)
-        return nil;
+        return nullptr;
 
 //    log_debug("GOT BUFFER\n%s\n", buffer->toString().c_str()); 
     Ref<Parser> parser(new Parser());
@@ -620,21 +616,21 @@ Ref<Element> YouTubeService::getData(String url_part, Ref<Dictionary> params, bo
     {
         return parser->parseString(sc->convert(buffer->toString()))->getRoot();
     }
-    catch (ParseException pe)
+    catch (const ParseException & pe)
     {
         log_error("Error parsing YouTube XML %s line %d:\n%s\n",
                pe.context->location.c_str(),
                pe.context->line,
                pe.getMessage().c_str());
-        return nil;
+        return nullptr;
     }
-    catch (Exception ex)
+    catch (const Exception & ex)
     {
         log_error("Error parsing YouTube XML %s\n", ex.getMessage().c_str());
-        return nil;
+        return nullptr;
     }
     
-    return nil;
+    return nullptr;
 }
 
 void YouTubeService::killOneTimeTasks(Ref<Array<Object> > tasklist)
@@ -648,7 +644,7 @@ void YouTubeService::killOneTimeTasks(Ref<Array<Object> > tasklist)
     while (true)
     {
         Ref<YouTubeTask> task = RefCast(tasklist->get(current), YouTubeTask);
-        if ((task != nil) && (task->kill))
+        if ((task != nullptr) && (task->kill))
             tasklist->removeUnordered(current);
         else
             current++;
@@ -685,7 +681,7 @@ bool YouTubeService::refreshServiceData(Ref<Layout> layout)
         throw _Exception(_("Not specified what content to fetch!"));
 
     Ref<YouTubeTask> task = RefCast(tasklist->get(current_task), YouTubeTask);
-    if (task == nil)
+    if (task == nullptr)
         throw _Exception(_("Encountered invalid task!"));
 
     if (task->amount_fetched < task->amount)
@@ -720,7 +716,7 @@ bool YouTubeService::refreshServiceData(Ref<Layout> layout)
         (task->request == YT_request_user_playlists)) 
     {
        reply = getData(task->url_part, task->parameters, true);
-       if (reply == nil)
+       if (reply == nullptr)
            throw _Exception(_("Failed to retrieve YouTube subfeed"));
 
        task->subfeed = yt->getSubFeed(reply);
@@ -764,7 +760,7 @@ bool YouTubeService::refreshServiceData(Ref<Layout> layout)
 
     reply = getData(task->url_part, task->parameters, construct_url);
 
-    if (reply != nil)
+    if (reply != nullptr)
         b = yt->setServiceContent(reply);
     else
     {
@@ -799,13 +795,13 @@ bool YouTubeService::refreshServiceData(Ref<Layout> layout)
         /// \todo add try/catch here and a possibility do find out if we
         /// may request more stuff or if we are at the end of the list
         obj = yt->getNextObject();
-        if (obj == nil)
+        if (obj == nullptr)
             break;
 
         obj->setVirtual(true);
 
         Ref<CdsObject> old = Storage::getInstance()->loadObjectByServiceID(RefCast(obj, CdsItem)->getServiceID());
-        if (old == nil)
+        if (old == nullptr)
         {
             log_debug("Adding new YouTube object\n");
             obj->setAuxData(_(YOUTUBE_AUXDATA_REQUEST), 
@@ -824,8 +820,8 @@ bool YouTubeService::refreshServiceData(Ref<Layout> layout)
                          String::from((int)task->region));
             }
             
-            if (layout != nil)
-                layout->processCdsObject(obj, nil);
+            if (layout != nullptr)
+                layout->processCdsObject(obj, nullptr);
             else
             {
                 log_warning("Your virtual layout is disabled, YouTube objects will not be added\n");
@@ -867,7 +863,7 @@ bool YouTubeService::refreshServiceData(Ref<Layout> layout)
             return false;
 
     }
-    while (obj != nil);
+    while (obj != nullptr);
 
     current_task++;
     if (current_task >= tasklist->size())
diff --git a/src/youtube_video_url.cc b/src/youtube_video_url.cc
index 7e296d9..6b05794 100644
--- a/src/youtube_video_url.cc
+++ b/src/youtube_video_url.cc
@@ -30,10 +30,6 @@
 /// \file youtube_video_url.cc
 /// \brief Definitions of the Transcoding classes. 
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #ifdef YOUTUBE
 
 #include <pthread.h>
@@ -82,14 +78,8 @@ YouTubeVideoURL::~YouTubeVideoURL()
 
 String YouTubeVideoURL::getVideoURL(String video_id, bool mp4, bool hd)
 {
-    long retcode; 
     String flv_location;
     String watch;
-#ifdef TOMBDEBUG
-    bool verbose = true;
-#else
-    bool verbose = false;
-#endif
 
    /*
 // ###########################################################
@@ -117,89 +107,69 @@ String YouTubeVideoURL::getVideoURL(String video_id, bool mp4, bool hd)
 
     watch = _(YOUTUBE_URL_WATCH) + video_id;
 
-    Ref<URL> url(new URL(YOUTUBE_PAGESIZE));
-
-    Ref<StringBuffer> buffer = url->download(watch, &retcode, curl_handle,
-                                             false, verbose, true);
-    if (retcode != 200)
+    /*
+     * NOTE ON PATCH:
+     *
+     * The original code does not seem to work anymore.
+     *
+     * I have commented-out all the original code, and instead
+     * replaced it with a call/exec to youtube-dl (this is a separate/stand-alone python script).
+     *
+     * Available at http://rg3.github.io/youtube-dl/
+     *
+     *
+     * The current code works on a/my samsung TV. I have not tested it further on other devices.
+     * (I needed a quick fix, because I wanted to watch some video's.  :) )
+     *
+     * I thought I would share the results.
+     *
+     * Suggestions / feedback  -> bas-patch at tcfaa.nl
+     *
+     * Regards, Bas Nedermeijer
+     */ 
+
+    int pipefd[2];
+    pipe(pipefd);
+
+    if (fork() == 0)
     {
-        throw _Exception(_("Failed to get URL for video with id ")
-                         + watch + _("HTTP response code: ") + 
-                         String::from(retcode));
-    }
+        // close reading end in the child
+        close(pipefd[0]);
 
-    log_debug("------> GOT BUFFER %s\n", buffer->toString().c_str());
+        // send stdout to the pipe
+        dup2(pipefd[1], 1); 
+        // send stderr to the pipe
+        dup2(pipefd[1], 2); 
 
-    Ref<Matcher> matcher =  reVideoURLParams->matcher(buffer->toString());
-    String params;
-    if (matcher->next())
-    {
-//        params = trim_string(matcher->group(1));
-        params = trim_string( matcher->group( 0 ) );
-      /*
-        int brace = params.index( '{' );
-        if ( brace > 0 )
-            params = params.substring( brace );
-        brace = params.index( '}' );
-        if ( brace > 0 )
-            params = params.substring( 0, brace + 1 );
-            */
-        Ref<Matcher> m2 = param_t->matcher(params);
-        if (m2->next())
-        {
-            String hmm = m2->group(1);
-            if (string_ok(hmm))
-                params = hmm; 
-            else 
-            {
-                throw _Exception(_("Could not retrieve \"t\" parameter."));
-            }
-        }
+        // this descriptor is no longer needed
+        close(pipefd[1]); 
+
+        // This code assumes youtube-dl is available for usage.
+        execl("/usr/bin/youtube-dl", "/usr/bin/youtube-dl","-g",watch.c_str(),NULL);
+        return String();
     }
     else
     {
-        throw _Exception(_("Failed to get URL for video with id (step 1)") + video_id);
-    }
+        // parent
+        char buffery[8192];
+        memset(&buffery[0], 0, sizeof(buffery));
 
-    params = _(YOUTUBE_URL_GET) + YOUTUBE_URL_PARAM_VIDEO_ID + '=' + 
-             video_id + '&' + YOUTUBE_URL_PARAM_T + '=' + params;
+        close(pipefd[1]);  // close the write end of the pipe in the parent
 
-    if (mp4)
-    {
-        String format = _("&fmt=18");
-        
-        if (hd)
+        // Hopefully the read is never called twice, otherwise the buffer will become corrupt.
+        while (read(pipefd[0], buffery, sizeof(buffery)) != 0)
         {
-            matcher = HD->matcher(buffer->toString());
-            if (matcher->next())
-            {
-                if (trim_string(matcher->group(1)) == "true")
-                    format = _("&fmt=22");
-            }
         }
-                    
-        params = params + format;
-    }
 
-    buffer = url->download(params, &retcode, curl_handle, true, verbose, true);
+       log_debug("------> GOT BUFFER %s\n", buffery);
+       String result = _(buffery);
 
-    matcher = redirectLocation->matcher(buffer->toString());
-    if (matcher->next())
-    {
-        if (string_ok(trim_string(matcher->group(1))))
-            return trim_string(matcher->group(1));
-        else
-            throw _Exception(_("Failed to get URL for video with id (step 2)")+ 
-                             video_id);
-    }
+       result = trim_string(result);
 
-    if (retcode != 303)
-    {
-        throw _Exception(_("Unexpected reply from YouTube: ") + 
-                         String::from(retcode));
-    }
+       log_debug("------> GOT BUFFER (after trimming) %s\n", result.c_str());
 
-    throw _Exception(_("Could not retrieve YouTube video URL"));
+       return result;
+    }
 }
 
 #endif//YOUTUBE
diff --git a/src/youtube_video_url.h b/src/youtube_video_url.h
index 58d02f5..a2836a6 100644
--- a/src/youtube_video_url.h
+++ b/src/youtube_video_url.h
@@ -36,7 +36,7 @@
 #define __YOUTUBE_VIDEO_URL_H__
 
 #include <curl/curl.h>
-#include "zmmf/zmmf.h"
+#include "zmm/zmmf.h"
 #include "zmm/zmm.h"
 #include "rexp.h"
 
diff --git a/src/zmmf/array.cc b/src/zmm/array.cc
similarity index 97%
rename from src/zmmf/array.cc
rename to src/zmm/array.cc
index a6a2872..0bae431 100644
--- a/src/zmmf/array.cc
+++ b/src/zmm/array.cc
@@ -29,10 +29,6 @@
 
 /// \file array.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "array.h"
 
 //#include <string.h>
@@ -95,7 +91,7 @@ void ArrayBase::remove(int index, int count)
         Object *obj = arr[i];
         if(obj)
             obj->release();
-        arr[i] = NULL;
+        arr[i] = nullptr;
     }
     int move = siz - max;
     if (move) // if there is anything to shift
@@ -115,7 +111,7 @@ void ArrayBase::removeUnordered(int index)
     Object *obj = arr[index];
     obj->release();
     arr[index] = arr[--siz];
-    arr[siz] = NULL;
+    arr[siz] = nullptr;
 }
 void ArrayBase::insert(int index, Object *obj)
 {
diff --git a/src/zmmf/array.h b/src/zmm/array.h
similarity index 99%
rename from src/zmmf/array.h
rename to src/zmm/array.h
index 6f4c620..6c09617 100644
--- a/src/zmmf/array.h
+++ b/src/zmm/array.h
@@ -32,7 +32,7 @@
 #ifndef __ZMMF_ARRAY_H__
 #define __ZMMF_ARRAY_H__
 
-#include "zmm/zmm.h"
+#include "zmm.h"
 
 #define DEFAULT_ARRAY_CAPACITY 16
 
diff --git a/src/zmm/atomic.h b/src/zmm/atomic.h
deleted file mode 100644
index 4724de4..0000000
--- a/src/zmm/atomic.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    atomic.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file atomic.h
-
-#ifndef __ATOMIC_H__
-#define __ATOMIC_H__
-
-typedef struct { volatile int x; } mt_atomic_t;
-//#define ATOMIC_INIT(y) {(y)}
-
-static inline void atomic_set(mt_atomic_t *at, int val)
-{
-    at->x = val;
-}
-
-static inline int atomic_get(mt_atomic_t *at)
-{
-    return (at->x);
-}
-
-#undef ATOMIC_DEFINED
-
-#ifdef ATOMIC_X86_SMP
-    #ifdef ATOMIC_X86
-        #error ATOMIC_X86_SMP and ATOMIC_X86 are defined at the same time!
-    #endif
-    #define ASM_LOCK "lock; "
-#endif
-
-#ifdef ATOMIC_X86
-    #define ASM_LOCK
-#endif
-
-#if defined(ATOMIC_X86_SMP) || defined(ATOMIC_X86)
-    #define ATOMIC_DEFINED
-    static inline void atomic_inc(mt_atomic_t *at)
-    {
-        __asm__ __volatile__(
-            ASM_LOCK "incl %0"
-            :"=m" (at->x)
-            :"m" (at->x)
-            :"cc"
-        );
-    }
-    
-    static inline bool atomic_dec(mt_atomic_t *at)
-    {
-        unsigned char c;
-        __asm__ __volatile__(
-            ASM_LOCK "decl %0; sete %1"
-            :"=m" (at->x), "=g" (c)
-            :"m" (at->x)
-            :"cc"
-        );
-        return (c!=0);
-    }
-#endif
-
-#ifdef ATOMIC_TORTURE
-    #ifdef ATOMIC_DEFINED
-        #error ATOMIC_X86(_SMP) and ATOMIC_TORTURE are defined at the same time!
-    #else
-        #define ATOMIC_DEFINED
-    #endif
-
-    // this is NOT atomic in most cases! Don't use ATOMIC_TORTURE!
-    static inline void atomic_inc(mt_atomic_t *at)
-    {
-        at->x++;
-    }
-    
-    static inline bool atomic_dec(mt_atomic_t *at)
-    {
-        return ((--at->x) == 0);
-    }
-#endif
-
-#ifndef ATOMIC_DEFINED
-    #include <pthread.h>
-    #define ATOMIC_NEED_MUTEX
-    static inline void atomic_inc(mt_atomic_t *at, pthread_mutex_t *mutex)
-    {
-        pthread_mutex_lock(mutex);
-        at->x++;
-        pthread_mutex_unlock(mutex);
-    }
-    static inline bool atomic_dec(mt_atomic_t *at, pthread_mutex_t *mutex)
-    {
-        pthread_mutex_lock(mutex);
-        int newval = (--at->x);
-        pthread_mutex_unlock(mutex);
-        return (newval == 0);
-    }
-#else
-    #undef ATOMIC_DEFINED
-#endif
-
-#endif // __ATOMIC_H__
diff --git a/src/zmmf/base_array.h b/src/zmm/base_array.h
similarity index 97%
rename from src/zmmf/base_array.h
rename to src/zmm/base_array.h
index eeb0376..2dc7ee6 100644
--- a/src/zmmf/base_array.h
+++ b/src/zmm/base_array.h
@@ -32,7 +32,7 @@
 #ifndef __ZMMF_BASE_ARRAY_H__
 #define __ZMMF_BASE_ARRAY_H__
 
-#include "zmm/zmm.h"
+#include "zmm.h"
 #include "memory.h"
 
 #define DEFAULT_ARRAY_CAPACITY 16
@@ -174,8 +174,8 @@ public:
     
     void addCSV(String csv, char sep = ',')
     {
-        char *data = csv.c_str();
-        char *dataEnd = data + csv.length();
+        const char *data = csv.c_str();
+        const char *dataEnd = data + csv.length();
         while (data < dataEnd)
         {
             char *endptr;
diff --git a/src/zmmf/base_queue.h b/src/zmm/base_queue.h
similarity index 99%
rename from src/zmmf/base_queue.h
rename to src/zmm/base_queue.h
index 28ef13e..80d7030 100644
--- a/src/zmmf/base_queue.h
+++ b/src/zmm/base_queue.h
@@ -32,7 +32,7 @@
 #ifndef __ZMMF_BASE_QUEUE_H__
 #define __ZMMF_BASE_QUEUE_H__
 
-#include "zmm/zmm.h"
+#include "zmm.h"
 
 namespace zmm
 {
diff --git a/src/zmmf/base_stack.h b/src/zmm/base_stack.h
similarity index 99%
rename from src/zmmf/base_stack.h
rename to src/zmm/base_stack.h
index 3f3ca6d..52255b2 100644
--- a/src/zmmf/base_stack.h
+++ b/src/zmm/base_stack.h
@@ -32,7 +32,7 @@
 #ifndef __ZMMF_BASE_STACK_H__
 #define __ZMMF_BASE_STACK_H__
 
-#include "zmm/zmm.h"
+#include "zmm.h"
 #include "memory.h"
 
 namespace zmm
diff --git a/src/zmmf/exception.cc b/src/zmm/exception.cc
similarity index 94%
rename from src/zmmf/exception.cc
rename to src/zmm/exception.cc
index b569431..7528aa0 100644
--- a/src/zmmf/exception.cc
+++ b/src/zmm/exception.cc
@@ -29,10 +29,6 @@
 
 /// \file exception.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "exception.h"
 
 #ifdef HAVE_EXECINFO_H
@@ -69,8 +65,8 @@ Exception::Exception(String message, const char* file, int line, const char* fun
 Exception::Exception(String message)
 {
     this->message = message;
-    this->file = nil;
-    this->function = nil;
+    this->file = nullptr;
+    this->function = nullptr;
     this->line = -1;
 #if defined HAVE_BACKTRACE && defined HAVE_BACKTRACE_SYMBOLS
     void *b[100];
@@ -88,7 +84,7 @@ Exception::Exception(String message)
 #endif
 }
 
-String Exception::getMessage()
+String Exception::getMessage() const
 {
     return message;
 }
@@ -99,7 +95,7 @@ Ref<Array<StringBase> > Exception::getStackTrace()
 }
 
 #ifdef TOMBDEBUG
-void Exception::printStackTrace(FILE *file)
+void Exception::printStackTrace(FILE *file) const
 {
     if (line >= 0)
     {
diff --git a/src/zmmf/exception.h b/src/zmm/exception.h
similarity index 85%
rename from src/zmmf/exception.h
rename to src/zmm/exception.h
index 3ad2b87..ddaed92 100644
--- a/src/zmmf/exception.h
+++ b/src/zmm/exception.h
@@ -32,13 +32,14 @@
 #ifndef __ZMMF_EXCEPTION_H__
 #define __ZMMF_EXCEPTION_H__
 
-#include "zmm/zmm.h"
+#include <stdio.h>
 
+#include "zmm.h"
 #include "array.h"
-#include <stdio.h>
-#include "logger.h"
 
-#define _Exception(format) zmm::Exception(format, __FILE__, __LINE__, __func__)
+#include "../logger.h"
+
+#define _Exception(format) zmm::Exception(format, __FILENAME__, __LINE__, __func__)
 
 namespace zmm
 {
@@ -56,13 +57,13 @@ protected:
 public:
     Exception(String message, const char* file, int line, const char* function);
     Exception(String message);
-    String getMessage();
+    String getMessage() const;
 
     Ref<Array<StringBase> > getStackTrace();
 #ifdef TOMBDEBUG
-    void printStackTrace(FILE *file = LOG_FILE);
+    void printStackTrace(FILE *file = LOG_FILE) const;
 #else
-    inline void printStackTrace(FILE *file = LOG_FILE) {}; 
+    inline void printStackTrace(FILE *file = LOG_FILE) const {};
 #endif
 
 };
diff --git a/src/zmm/nil.cc b/src/zmm/nil.cc
deleted file mode 100644
index 113ca8c..0000000
--- a/src/zmm/nil.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    nil.cc - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file nil.cc
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include "nil.h"
-
-struct nil_struct_t *nil_inst;
diff --git a/src/zmm/nil.h b/src/zmm/nil.h
deleted file mode 100644
index ab80883..0000000
--- a/src/zmm/nil.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    nil.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file nil.h
-
-#ifndef __ZMM_NIL_H__
-#define __ZMM_NIL_H__
-
-struct nil_struct_t
-{
-    int dummy1;
-    char dummy2;
-};
-
-typedef struct nil_struct_t * NIL_VAR;
-
-extern NIL_VAR nil_inst;
-
-#define nil nil_inst
-
-#endif // __ZMM_NIL_H__
diff --git a/src/zmm/null.h b/src/zmm/null.h
deleted file mode 100644
index c321cc0..0000000
--- a/src/zmm/null.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    null.h - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/// \file null.h
-
-#ifndef __ZMM_NULL_H__
-#define __ZMM_NULL_H__
-
-// #define NULL ((void *)(0))
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif // __ZMM_NULL_H__
diff --git a/src/zmm/object.cc b/src/zmm/object.cc
index 9d60de0..b90fcd5 100644
--- a/src/zmm/object.cc
+++ b/src/zmm/object.cc
@@ -29,62 +29,43 @@
 
 /// \file object.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
+#include <cstdio>
+#include <cstdlib>
 
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "object.h"
 #include "memory.h"
+#include "object.h"
 
 using namespace zmm;
 
 Object::Object()
 {
-    atomic_set(&_ref_count, 0);
-#ifdef ATOMIC_NEED_MUTEX
-    pthread_mutex_init(&mutex, NULL);
-#endif
+    _ref_count.store(0);
 }
 Object::~Object()
 {
-#ifdef ATOMIC_NEED_MUTEX
-    pthread_mutex_destroy(&mutex);
-#endif
 }
 
-void Object::retain()
+void Object::retain() const
 {
-#ifdef ATOMIC_NEED_MUTEX
-    atomic_inc(&_ref_count, &mutex);
-#else
-    atomic_inc(&_ref_count);
-#endif
+    _ref_count++;
 }
-void Object::release()
+void Object::release() const
 {
-#ifdef ATOMIC_NEED_MUTEX
-    if(atomic_dec(&_ref_count, &mutex))
-#else
-    if(atomic_dec(&_ref_count))
-#endif
-    {
+    if (--_ref_count == 0) {
         delete this;
     }
 }
 
-int Object::getRefCount()
+int Object::getRefCount() const
 {
-    return atomic_get(&_ref_count);
+    return _ref_count.load();
 }
 
-void* Object::operator new (size_t size)
+void* Object::operator new(size_t size)
 {
     return MALLOC(size);
 }
-void Object::operator delete (void *ptr)
+void Object::operator delete(void* ptr)
 {
     FREE(ptr);
 }
diff --git a/src/zmm/object.h b/src/zmm/object.h
index 09172ef..8264b48 100644
--- a/src/zmm/object.h
+++ b/src/zmm/object.h
@@ -32,33 +32,27 @@
 #ifndef __ZMM_OBJECT_H__
 #define __ZMM_OBJECT_H__
 
+#include <atomic>
+#include <cstddef>
 #include <new> // for size_t
-#include "atomic.h"
-#include <stddef.h>
 
-namespace zmm
-{
+namespace zmm {
 
-
-class Object
-{
+class Object {
 public:
     Object();
     virtual ~Object();
-    void retain();
-    void release();
-    int getRefCount();
+    void retain() const;
+    void release() const;
+    int getRefCount() const;
+
+    static void* operator new(size_t size);
+    static void operator delete(void* ptr);
 
-    static void* operator new (size_t size); 
-    static void operator delete (void *ptr);
 protected:
-    mt_atomic_t _ref_count;
-#ifdef ATOMIC_NEED_MUTEX
-    pthread_mutex_t mutex;
-#endif
+    mutable std::atomic_uint _ref_count;
 };
 
-
 } // namespace
 
 #endif // __ZMM_OBJECT_H__
diff --git a/src/zmmf/object_queue.h b/src/zmm/object_queue.h
similarity index 96%
rename from src/zmmf/object_queue.h
rename to src/zmm/object_queue.h
index 3108018..4d33c56 100644
--- a/src/zmmf/object_queue.h
+++ b/src/zmm/object_queue.h
@@ -32,7 +32,7 @@
 #ifndef __ZMMF_OBJECT_QUEUE_H__
 #define __ZMMF_OBJECT_QUEUE_H__
 
-#include "zmm/zmm.h"
+#include "zmm.h"
 #include "base_queue.h"
 
 namespace zmm
@@ -66,7 +66,7 @@ namespace zmm
         {
             Object *obj = BaseQueue<Object *>::dequeue();
             if (obj == NULL)
-                return nil;
+                return nullptr;
             Ref<T> ret((T *)obj);
             obj->release();
             return ret;
@@ -76,7 +76,7 @@ namespace zmm
         {
             Object *obj = BaseQueue<Object *>::get(index);
             if (obj == NULL)
-                return nil;
+                return nullptr;
             return Ref<T>((T *)obj);
         }
     };
diff --git a/src/zmmf/object_stack.h b/src/zmm/object_stack.h
similarity index 96%
rename from src/zmmf/object_stack.h
rename to src/zmm/object_stack.h
index 6ac20e0..090b848 100644
--- a/src/zmmf/object_stack.h
+++ b/src/zmm/object_stack.h
@@ -32,7 +32,8 @@
 #ifndef __ZMMF_OBJECT_STACK_H__
 #define __ZMMF_OBJECT_STACK_H__
 
-#include "zmm/zmm.h"
+#include <logger.h>
+#include "zmm.h"
 #include "memory.h"
 #include "base_stack.h"
 
@@ -67,7 +68,7 @@ namespace zmm
         {
             Object *obj = BaseStack<Object *>::pop();
             if (obj == NULL)
-                return nil;
+                return nullptr;
             Ref<T> ret((T *)obj);
             obj->release();
             return ret;
diff --git a/src/zmm/ref.h b/src/zmm/ref.h
index d9f0043..b2c14c9 100644
--- a/src/zmm/ref.h
+++ b/src/zmm/ref.h
@@ -32,8 +32,6 @@
 #ifndef __ZMM_REF_H__
 #define __ZMM_REF_H__
 
-#include "nil.h"
-
 namespace zmm
 {
 
@@ -47,14 +45,14 @@ public:
         if(_ptr)
             _ptr->retain();
     }
-    explicit Ref(T* ptr = NULL) : _ptr(ptr)
+    explicit Ref(T* ptr = nullptr) : _ptr(ptr)
     {
         if(ptr)
             ptr->retain();
     }
-    Ref(NIL_VAR)
+    Ref(std::nullptr_t)
     {
-        _ptr = NULL;
+        _ptr = nullptr;
     }
     ~Ref()
     {
@@ -73,11 +71,11 @@ public:
             _ptr->retain();
         return *this;
     }
-    inline Ref& operator=(NIL_VAR)
+    inline Ref& operator=(std::nullptr_t)
     {
         if(_ptr)
             _ptr->release();
-        _ptr = NULL;
+        _ptr = nullptr;
         return *this;
     }
 
@@ -93,19 +91,19 @@ public:
     {
         return _ptr;
     }
-    inline int operator==(NIL_VAR)
+    inline int operator==(std::nullptr_t) const
     {
-        return (_ptr == NULL);
+        return (_ptr == nullptr);
     }
-    inline int operator!=(NIL_VAR)
+    inline int operator!=(std::nullptr_t) const
     {
-        return (_ptr != NULL);
+        return (_ptr != nullptr);
     }
-    inline int operator==(const Ref& other)
+    inline int operator==(const Ref& other) const
     {
         return (_ptr == other._ptr);
     }
-    inline int operator!=(const Ref& other)
+    inline int operator!=(const Ref& other) const
     {
         return (_ptr != other._ptr);
     }
@@ -115,6 +113,6 @@ protected:
 
 } // namespace
 
-#define RefCast(ref, klass) zmm::Ref<klass>((klass *)ref.getPtr())
+#define RefCast(ref, klass) zmm::Ref< klass >(( klass *)ref.getPtr())
 
 #endif // __ZMM_REF_H__
diff --git a/src/zmm/stringbuffer.cc b/src/zmm/stringbuffer.cc
index 85b5b5d..1ec2325 100644
--- a/src/zmm/stringbuffer.cc
+++ b/src/zmm/stringbuffer.cc
@@ -29,13 +29,9 @@
 
 /// \file stringbuffer.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "stringbuffer.h"
 
-#include <string.h>
+#include <cstring>
 #include "memory.h"
 #include "strings.h"
 #include "exceptions.h"
@@ -86,7 +82,7 @@ StringBuffer &StringBuffer::operator<<(const char *str)
 {
     if(! str)
         return *this;
-    int otherLen = (int)strlen(str);
+    auto otherLen = (int)strlen(str);
     if(otherLen)
     {
         addCapacity(otherLen);
@@ -208,7 +204,7 @@ void StringBuffer::ensureCapacity(int neededCapacity)
 {
     if(neededCapacity > capacity)
     {
-        int newCapacity = (int)(capacity * STRINGBUFFER_CAPACITY_INCREMENT);
+        auto newCapacity = (int)(capacity * STRINGBUFFER_CAPACITY_INCREMENT);
         if(neededCapacity > newCapacity)
             newCapacity = neededCapacity;
         capacity = newCapacity;
diff --git a/src/zmm/strings.cc b/src/zmm/strings.cc
index ed9631d..f3e6427 100644
--- a/src/zmm/strings.cc
+++ b/src/zmm/strings.cc
@@ -29,11 +29,8 @@
 
 /// \file strings.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include <ctype.h>
+#include <string>
+#include <cctype>
 
 #include "memory.h"
 #include "strings.h"
@@ -75,7 +72,7 @@ bool StringBase::startsWith(StringBase *other)
 
 String::String()
 {
-    base = NULL;
+    base = nullptr;
 }
 String::String(int capacity)
 {
@@ -90,7 +87,7 @@ String::String(const char *str)
         base->retain();
     }
     else
-        base = NULL;
+        base = nullptr;
 }
 String::String(const char *str, int len)
 {
@@ -100,7 +97,7 @@ String::String(const char *str, int len)
         base->retain();
     }
     else
-        base = NULL;
+        base = nullptr;
 }
 String::String(char ch)
 {
@@ -139,12 +136,12 @@ int String::length()
     else
         return 0;
 }
-char *String::c_str()
+const char *String::c_str() const
 {
     if(base)
         return base->data;
     else
-        return NULL;
+        return nullptr;
 }
 String String::operator+(String other)
 {
@@ -167,7 +164,7 @@ String String::operator+(const char *other)
     if(! base)
         return String::copy(other);
     int len = base->len;
-    int otherLen = (int)strlen(other);
+    auto otherLen = (int)strlen(other);
     String res(len + otherLen);
     strcpy(res.base->data, base->data);
     strcpy(res.base->data + len, other);
@@ -196,37 +193,37 @@ String String::operator+(double x)
 
 String String::from(int x)
 {
-    StringBase *b = new StringBase(MAX_INT_STRING_LENGTH);
+    auto *b = new StringBase(MAX_INT_STRING_LENGTH);
     b->len = sprintf(b->data, "%d", x);
     return (String(b));
 }
 String String::from(unsigned int x)
 {
-    StringBase *b = new StringBase(MAX_INT_STRING_LENGTH);
+    auto *b = new StringBase(MAX_INT_STRING_LENGTH);
     b->len = sprintf(b->data, "%u", x);
     return (String(b));
 }
 String String::from(long x)
 {
-    StringBase *b = new StringBase(MAX_LONG_STRING_LENGTH);
+    auto *b = new StringBase(MAX_LONG_STRING_LENGTH);
     b->len = sprintf(b->data, "%ld", x);
     return (String(b));
 }
 String String::from(unsigned long x)
 {
-    StringBase *b = new StringBase(MAX_LONG_STRING_LENGTH);
+    auto *b = new StringBase(MAX_LONG_STRING_LENGTH);
     b->len = sprintf(b->data, "%ld", x);
     return (String(b));
 }
 String String::from(double x)
 {
-    StringBase *b = new StringBase(MAX_DOUBLE_STRING_LENGTH);
+    auto *b = new StringBase(MAX_DOUBLE_STRING_LENGTH);
     b->len = sprintf(b->data, "%lf", x);
     return (String(b));
 }
 String String::from(long long x)
 {
-    StringBase *b = new StringBase(MAX_LONG_LONG_STRING_LENGTH);
+    auto *b = new StringBase(MAX_LONG_LONG_STRING_LENGTH);
     b->len = sprintf(b->data, "%lld", x);
     return (String(b));
 }
@@ -244,7 +241,7 @@ String String::allocate(int size)
 }
 String String::take(const char *data)
 {
-    StringBase *base = new StringBase();
+    auto *base = new StringBase();
     base->data = (char *)data;
     base->len = strlen(data);
     base->store = true;
@@ -252,7 +249,7 @@ String String::take(const char *data)
 }
 String String::take(const char *data, int length)
 {
-    StringBase *base = new StringBase();
+    auto *base = new StringBase();
     base->data = (char *)data;
     base->len = length;
     base->store = true;
@@ -260,7 +257,7 @@ String String::take(const char *data, int length)
 }
 String String::refer(const char *data)
 {
-    StringBase *base = new StringBase();
+    auto *base = new StringBase();
     base->data = (char *)data;
     base->len = strlen(data);
     base->store = false;
@@ -268,7 +265,7 @@ String String::refer(const char *data)
 }
 String String::refer(const char *data, int len)
 {
-    StringBase *base = new StringBase();
+    auto *base = new StringBase();
     base->data = (char *)data;
     base->len = len;
     base->store = false;
@@ -278,13 +275,13 @@ String String::copy(const char *data)
 {
     if (data)
     {
-        StringBase *base = new StringBase(data);
+        auto *base = new StringBase(data);
         return String(base);
     }
     else
         return String();
 }
-int String::operator==(String other)
+int String::operator==(String other) const
 {
     if(! base && ! other.base)
         return 1;
@@ -292,7 +289,7 @@ int String::operator==(String other)
         return ( ! strcmp(base->data, other.base->data) );
     return 0;
 }
-int String::operator==(const char *other)
+int String::operator==(const char *other) const
 {
     if(! base && ! other)
         return 1;
@@ -300,7 +297,7 @@ int String::operator==(const char *other)
         return ( ! strcmp(base->data, other ) );
     return 0;
 }
-int String::operator==(char c)
+int String::operator==(char c) const
 {
     if(! base || base->len != 1)
         return 0;
@@ -316,7 +313,7 @@ String& String::operator=(const char *str)
         base->retain();
     }
     else
-        base = NULL;
+        base = nullptr;
     return *this;
 }
 String& String::operator=(String other)
@@ -331,7 +328,7 @@ String& String::operator=(String other)
     return *this;
 }
 
-int String::equals(String other, bool ignoreCase)
+int String::equals(String other, bool ignoreCase) const
 {
     if(! base && ! other.base)
         return 1;
@@ -350,7 +347,7 @@ int String::equals(String other, bool ignoreCase)
 String String::toLower()
 {
     if (!base)
-        return nil;
+        return nullptr;
 
     String result = String(base->data, base->len);
     for (int i = 0; i < result.base->len; i++)
@@ -363,7 +360,7 @@ String String::toLower()
 String String::toUpper()
 {
     if (!base)
-        return nil;
+        return nullptr;
 
     String result = String(base->data, base->len);
     for (int i = 0; i < base->len; i++)
@@ -421,14 +418,14 @@ off_t String::toOFF_T()
 String String::substring(int from)
 {
     if(! base)
-        return nil;
+        return nullptr;
     int count = base->len - from;
     return substring(from, count);
 }
 String String::substring(int from, int count)
 {
     if(! base || count < 0)
-        return nil;
+        return nullptr;
     if(count == 0)
         return _("");
     if(from + count > base->len)
@@ -476,7 +473,7 @@ int String::rindex(int end, char ch)
 String String::reduce(char ch)
 { 
     if (!base)
-        return nil;
+        return nullptr;
 
     char *pos = ::strchr(base->data, ch);
     if (!pos)
@@ -546,7 +543,7 @@ int String::find(String needle)
 String String::replace(String needle, String replacement)
 {
     if (! replacement.base || ! needle.base)
-        return nil;
+        return nullptr;
     int pos = find(needle);
     if (pos < 0)
         return *this; 
diff --git a/src/zmm/strings.h b/src/zmm/strings.h
index 49e9583..870d319 100644
--- a/src/zmm/strings.h
+++ b/src/zmm/strings.h
@@ -32,6 +32,8 @@
 #ifndef __ZMM_STRINGS_H__
 #define __ZMM_STRINGS_H__
 
+#include <string>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -56,14 +58,14 @@
 
 namespace zmm
 {
-        
+
 class StringBase : public Object
 {
 public:
     char *data;
     int len;
     bool store; // if true, the object is responsible for freeing data
-    
+
     StringBase(int capacity);
     StringBase(const char *str);
     StringBase(const char *str, int len);
@@ -90,24 +92,24 @@ public:
     String(const String &other);
     String(StringBase *other);
     String(Ref<StringBase> other);
-    
+
     inline StringBase *getBase()
     {
         return base;
     }
-    
-    inline String(NIL_VAR)
+
+    inline String(std::nullptr_t)
     {
         base = NULL;
     }
-    
+
     ~String();
-    
+
     String &operator=(const char *str);
-    
+
     String &operator=(String other);
-    
-    inline String &operator=(NIL_VAR)
+
+    inline String &operator=(std::nullptr_t)
     {
         if(base)
             base->release();
@@ -122,30 +124,30 @@ public:
     String operator+(unsigned int x);
     String operator+(double x);
 
-    int operator==(String other);
-    int operator==(const char *str);
-    int operator==(char c);
-    
-    inline int operator!=(String other)
+    int operator==(String other) const;
+    int operator==(const char *str) const;
+    int operator==(char c) const;
+
+    inline int operator!=(String other) const
     {
         return ! operator==(other);
     }
-    inline int operator!=(const char *str)
+    inline int operator!=(const char *str) const
     {
         return ! operator==(str);
     }
-    inline int operator!=(char c)
+    inline int operator!=(char c) const
     {
         return ! operator==(c);
     }
 
-    inline int operator==(NIL_VAR)
+    inline int operator==(std::nullptr_t) const
     {
-        return (base == NULL);
+        return (base == nullptr);
     }
-    inline int operator!=(NIL_VAR)
+    inline int operator!=(std::nullptr_t) const
     {
-        return (base != NULL);
+        return (base != nullptr);
     }
 
 
@@ -154,20 +156,21 @@ public:
         return Ref<StringBase>(base);
     }
 
-    int equals(String other, bool ignoreCase = false);
+    int equals(String other, bool ignoreCase = false) const;
     String toLower();
     String toUpper();
 
     String substring(int from);
     String substring(int from, int count);
-    
+
     /// \brief reduces multiple consecutive occurences of the character ch
     /// to one occurence
     /// \param ch the character to reduce
     /// \return the new string, with ch reduced
     String reduce(char ch);
-    
+
     inline char charAt(int index) {  return base->data[index]; }
+    inline char operator[](int index) { return base->data[index]; }
     inline char *charPtrAt(int index) { return base->data + index; }
     inline int index(char ch) { return index(0, ch); }
     int index(int start, char ch);
@@ -185,17 +188,17 @@ public:
     {
         base->len = length;
     }
-    char *c_str();
+    const char *c_str() const;
     inline void updateLength()
     {
         base->len = strlen(base->data);
     }
-    
+
     bool startsWith(String str)
     {
         return base->startsWith(str.base);
     }
-    
+
     int find(const char *needle);
     int find(String needle);
     String replace(String needle, String replacement);
@@ -207,7 +210,7 @@ public:
     static String from(unsigned long x);
     static String from(double x);
     static String from(long long x);
-    
+
     static String allocate(int size);
     static String take(const char *data, int length);
     static String take(const char *data);
@@ -221,4 +224,20 @@ protected:
 
 }; // namespace
 
+// custom specialization of std::hash so we can be used in std::hash'd maps/sets
+namespace std
+{
+template<>
+struct hash<zmm::String>
+{
+    typedef zmm::String argument_type;
+    typedef std::size_t value_type;
+
+    value_type operator()(argument_type const& s) const
+    {
+        return std::hash<std::string>{}(s.c_str());
+    }
+};
+}
+
 #endif // __STRINGS_H__
diff --git a/src/zmmf/stringtokenizer.cc b/src/zmm/stringtokenizer.cc
similarity index 91%
rename from src/zmmf/stringtokenizer.cc
rename to src/zmm/stringtokenizer.cc
index f573264..1381adb 100644
--- a/src/zmmf/stringtokenizer.cc
+++ b/src/zmm/stringtokenizer.cc
@@ -29,13 +29,9 @@
 
 /// \file stringtokenizer.cc
 
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
 #include "stringtokenizer.h"
 
-#include <string.h>
+#include <cstring>
 
 using namespace zmm;
 
@@ -47,8 +43,8 @@ StringTokenizer::StringTokenizer(String str)
 }
 String StringTokenizer::nextToken(String seps)
 {
-    char *cstr = str.c_str();
-    char *cseps = seps.c_str();
+    const char *cstr = str.c_str();
+    const char *cseps = seps.c_str();
     while(pos < len && strchr(cseps, cstr[pos]))
         pos++;
     if(pos < len)
@@ -58,5 +54,5 @@ String StringTokenizer::nextToken(String seps)
             pos++;
         return str.substring(start, pos - start);
     }
-    return nil;
+    return nullptr;
 }
diff --git a/src/zmmf/stringtokenizer.h b/src/zmm/stringtokenizer.h
similarity index 98%
rename from src/zmmf/stringtokenizer.h
rename to src/zmm/stringtokenizer.h
index 485c36b..f9c808b 100644
--- a/src/zmmf/stringtokenizer.h
+++ b/src/zmm/stringtokenizer.h
@@ -32,7 +32,7 @@
 #ifndef __ZMMF_STRINGTOKENIZER_H__
 #define __ZMMF_STRINGTOKENIZER_H__
 
-#include "zmm/zmm.h"
+#include "zmm.h"
 
 namespace zmm
 {
diff --git a/src/zmm/zmm.h b/src/zmm/zmm.h
index defa6dc..13c7d5d 100644
--- a/src/zmm/zmm.h
+++ b/src/zmm/zmm.h
@@ -32,8 +32,6 @@
 #ifndef __ZMM_H__
 #define __ZMM_H__
 
-#include "nil.h"
-#include "null.h"
 #include "object.h"
 #include "ref.h"
 #include "strings.h"
diff --git a/src/zmmf/zmmf.h b/src/zmm/zmmf.h
similarity index 98%
rename from src/zmmf/zmmf.h
rename to src/zmm/zmmf.h
index 553cc4a..b3b6f9f 100644
--- a/src/zmmf/zmmf.h
+++ b/src/zmm/zmmf.h
@@ -32,7 +32,7 @@
 #ifndef __ZMMF_H__
 #define __ZMMF_H__
 
-#include "zmm/zmm.h"
+#include "zmm.h"
 #include "exception.h"
 #include "array.h"
 #include "base_array.h"
diff --git a/tombupnp/AUTHORS b/tombupnp/AUTHORS
deleted file mode 100644
index e69de29..0000000
diff --git a/tombupnp/COPYING b/tombupnp/COPYING
deleted file mode 100644
index 5ab7695..0000000
--- a/tombupnp/COPYING
+++ /dev/null
@@ -1,504 +0,0 @@
-		  GNU LESSER GENERAL PUBLIC LICENSE
-		       Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL.  It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it.  You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
-  When we speak of free software, we are referring to freedom of use,
-not price.  Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
-  To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights.  These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  To protect each distributor, we want to make it very clear that
-there is no warranty for the free library.  Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
-  Finally, software patents pose a constant threat to the existence of
-any free program.  We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder.  Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
-  Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License.  This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License.  We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
-  When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library.  The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom.  The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
-  We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License.  It also provides other free software developers Less
-of an advantage over competing non-free programs.  These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries.  However, the Lesser license provides advantages in certain
-special circumstances.
-
-  For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard.  To achieve this, non-free programs must be
-allowed to use the library.  A more frequent case is that a free
-library does the same job as widely used non-free libraries.  In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
-  In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software.  For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
-  Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
-		  GNU LESSER GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
-  6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Use a suitable shared library mechanism for linking with the
-    Library.  A suitable mechanism is one that (1) uses at run time a
-    copy of the library already present on the user's computer system,
-    rather than copying library functions into the executable, and (2)
-    will operate properly with a modified version of the library, if
-    the user installs one, as long as the modified version is
-    interface-compatible with the version that the work was made with.
-
-    c) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    d) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    e) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-			    NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-           How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/tombupnp/ChangeLog b/tombupnp/ChangeLog
deleted file mode 100644
index e56ad6d..0000000
--- a/tombupnp/ChangeLog
+++ /dev/null
@@ -1,387 +0,0 @@
-	* fixed AMD64 issues and got rid of all warnings
-	* added chunked encoding patch from Serge Nikitin
-	* added special PS3 hack to timeout on hanging sockets
-	* fixed warning in uri.c on Solaris
-	* made sure that the close() callback is also triggered in error cases
-	  (else files might stayed open)
-	* read error was never checked, so when we returned -1 to indicate an
-	  error things went terribly wrong
-	* made sure that range requests specified as "bytes=0-" do not trigger
-	  a 416 response on media with unknown filesize
-	* added a special check where read can return a special value to indicate
-	  that we should check if the remote socket is still alive
-
-2006-08-08  Sergey Bostandzhyan <jin(at)mediatomb.org>
-    * integration - moved libupnp 1.4.1 into the MediaTomb environment
-    
-    * upnp/src/inc/config.h - changed thread configuration to improve
-      internal webserver performance
-
-    * upnp/src/genlib/net/http/webserver.c - added .css to text/css
-      mimetype mapping to the internal webserver
-
-    * added largefile support, based on patch originally submitted
-      by Peter Enzerink <sf(at)enzerink.net>
-
-    * sock.c - reverted a change regarding SIGPIPE, unhandled signal
-      when HTTP transfer was cancelled by the client.
-
-    * added possibility to specify custom HTTP headers
-
-    * fixed a bug in UpnpRemoveVirtualDir - when a directory to be
-      removed was first in the list the whole list was invalidated
-    
-    * added possibility to add custom HTTP headers to all responses.
-      did not yet covered really all responses, some are still missing.
-
-    * added possibility to supply a custom HTTP header through the
-      File_Info struct via the get_info() callback, this allows to
-      add custom headers only to certain HTTP responses.
-
-    * removed all references to malloc.h (only stays in one WIN32 ifdef)
-    * removed use of ftime function (deprecated), using gettimeofday now
-    * added UTF-8 charset patch submitted by 
-      Olga Soiko <o.soiko(at)sam-solutions.net>
-    * added HTTP 1.1 conformance patch submitted by
-      Olga Soiko <o.soiko(at)sam-solutions.net>
-
-    * changed theadpool implementation; if all threads in the thread pool
-      are busy executing jobs, a new worker thread will be created
-      if a job is scheduled
-
-    * implemented correct select timeout handling, webserver sockets are
-      now put in non blocking mode; this solves the problem when the SDK
-      would not shut down properly because of a blocking send.
-
-2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
-
-	* Finished const-ifications as suggested by Erik Johansson in
-	SF Patch tracker [ 1587272 ].
-
-2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
-
-	* Erik Johansson's patch for const-ified ixml
-	SF Patch tracker [ 1587272 ].
-
-2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
-
-	* David Maass's patch for VStudio2005 compilation failure.
-	SF Patch tracker [ 1581161 ].
-
-2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
-
-	* Erik Johansson's patch for invalid xml output.
-	SF Bug Tracker [ 1590466 ].
-
-2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
-
-	* Erik Johansson's patch for typo in ixmlparser.c.
-	SF Bug tracker [ 1590469 ].
-
-2006-07-07 Oxy <virtual_worlds(at)gmx.de>
-
-	* full support for Windows added, static library and DLL are fully
-        working, code compiles with Borland Builder C++ and MS Visual
-        C/C++
-
-2006-07-05 Nektarios K. Papadopoulos <npapadop(at)inaccessnetworks.com>
-
-	* Include prebuilt documentation (html,pdf), dropping doc++ 
-	dependancy.
-
-2006-07-03 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
-
-	* Patch for FreeBSD, thanks to Markus Strobl.
-
-2006-06-26 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
-
-	* Fix for missing "else" in httpreadwrite.c. Thanks to npapadop
-	for the patch.
-
-2006-06-26 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
-
-	* Fix for va_list initialization in x86_64 architectures.
-
-2006-06-08 Oxy <virtual_worlds(at)gmx.de>
-
-	* Patch to fix memory leaks and reasons for crashes added (thanks
-	to loigu)
-
-*************************************************************************
-Release of version 1.4.0
-*************************************************************************
-
-2006-05-26 Oxy <virtual_worlds(at)gmx.de>
-
-	* defines in iasnprintf.h changed to work with GCC-version < 3
-
-2006-05-22 Oxy <virtual_worlds(at)gmx.de>
-
-	* BSD-patch added (not tested yet on an BSD system)
-
-2006-05-19 Oxy <virtual_worlds(at)gmx.de>
-
-	* Patch added for bug: ixml parser colapsed on empty args (arg="")
-
-2006-05-18 Oxy <virtual_worlds(at)gmx.de>
-
-	* DSM-320 patch added (fetched from project MediaTomb)
-	* httpGet additons atch added, Added proxy support by introducing
-	  UpnpOpenHttpGetProxy. UpnpOpenHttpGet now just calls
-	  UpnpOpenHttpGetProxy with the proxy url set to NULL.
-	* Bugfix for typo ("\0" / "0") in ixmlparser.c
-	* Bugfix for M-Search packet
-
-*************************************************************************
-FORK FROM DEAD libupnp
-*************************************************************************
-
-2006-04-29  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* THANKS: new file with list of contributors
-
-	* upnp/src/gena/gena_device.c (respond_ok): add 'Content-Length: 0'
-	  in subscription response. Patch by Chaos (Bug # 1455367).
-
-2006-04-08  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* upnp/doc/UPnP_Programming_Guide.pdf: replace this document with 
-	  the one in libupnp-doc-1.2.1 because current CVS version 
-	  was corrupted.
-
-2006-04-06
-
-	* changes applied to several files to work under Sparc Solaris, temporarily
-	  requiring a define SPARC_SOLARIS
-
-2006-04-03  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* upnp/Makefile.am: install upnp samples in $(docdir)/examples
-
-2006-03-28  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* configure.ac: add --with-docdir option to choose where documentation
-	  is installed (or -without-docdir to not install the documentation)
-
-2006-03-27  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* ixml/test: add simple test suite for xml parser
-
-2006-03-26  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* ixml/src/ixmlparser.c (Parser_processCDSect): fix bug which prevents
-	  CDATA sections which contain a 0 (zero) to be parsed (instead the
-	  parsing of the whole document is aborted). Patch by Arno Willig 
-	  (Patch # 1432124).
-
-	* configure.ac, upnp/Makefile.am: add "--disable-samples" configure
-	  option, and move samples compilation from check_PROGRAMS to
-	  noinst_PROGRAMS
-
-2006-03-25  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* upnp/src/genlib/miniserver/miniserver.c (get_miniserver_sockets): 
-	  fix bug if new socket created has fd 0 (can only occur when stdin
-	  has been closed). Patch by Oskar Liljeblad 2004-07-02 :
-	  http://sourceforge.net/mailarchive/message.php?msg_id=8870528
-	
-2006-03-21  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* upnp/test/test_init.c: add some version checks and exit if failure
-
-2006-03-05  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* libupnp version 1.3.1
-
-	* upnp/inc/upnpconfig.h.in: add new define UPNP_VERSION_PATCH
-
-	* upnp/test/test_init.c: add simple test to run during checks
-
-	* upnp/inc/upnp.h: include "upnpdebug.h" only if debug enabled
-	  in the library (else header file is not installed)
-
-	* upnp/Makefile.am (libupnp_la_LDFLAGS): add inter-library libtool
-	  dependencies between upnp and ixml / threadutil, so that programs 
-	  linking against upnp only still work.
-
-2006-03-04  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* libupnp version 1.3.0
-
-2006-03-03  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* upnp/src/genlib/net/http/httpreadwrite.c (get_sdk_info): use
-	  package version string from configure to set sdk info
-
-	* upnp/Makefile.am: add sample/tvdevice/web/ files in EXTRA_DIST
-	  + do not distribute generated upnpconfig.h file.
-
-2006-02-28  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* upnp/src/inc/config.h, configure.ac: use only new defines
-	  UPNP_HAVE_xx instead of INCLUDE_yyy_APIS and INTERNAL_WEB_SERVER
-
-	* upnp/Makefile.am, ixml/Makefile.am: add -export-symbols-regex to
-	  the librarie LDFLAGS in order to export only the symbols defined 
-	  in the API
-
-2006-02-27  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* configure.ac: add libtool versions for the 3 libraries
-
-	* ixml/src/ixml.c (copy_with_escape): add missing 'static' to function
-
-	* threadutil/src/ThreadPool.c (SetSeed): add missing 'static' 
-
-2006-02-26  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* threadutil/inc/iasnprintf.h: add gcc __printf__ format attribute
-	  to "iasnprintf"
-
-	* upnp/src/api/upnpapi.c: fix invalid UpnpPrintf formats
-
-	* upnp/src/gena/gena_device.c: fix invalid UpnpPrintf formats
-
-	* upnp/src/inc/config.h: move upnp/inc/config.h to internal
-	  sources (this file is no longer installed with the libraries)
-
-	* upnp/inc/upnpdebug.h: new file created from debug definitions
-	  previously in upnp/inc/config.h
-
-	* upnp/src/api/config.c: rename to upnp/src/api/upnpdebug.c
-
-	* upnp/inc/upnpconfig.h.in: new file to contain information on    
-	  the configuration of the installed libraries (generates installed
-	  file <upnp/upnpconfig.h>)
-
-2006-02-22  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* upnp/ : add missing include of config.h in some .c files
-
-2006-02-21  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* upnp/inc/upnp.h: move some definitions which should not be
-	  exported into "upnp/src/inc/util.h"
-
-	* import all modifications below from libupnp in djmount 0.51
-	  into official libupnp
-	
-2006-01-17  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* threadutil/Makefile.am (libthreadutil_la_SOURCES): remove extraneous
-	  file
-
-2006-01-15  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* configure.ac: add checks for large-file support
-
-	* upnp/inc/config.h: rename to "upnpconfig.h". The new "config.h" file
-	  is the one generated by autoconf.
-
-	* m4/type_socklen_t.m4: added new check for socklen_t (fallback to
-	  int if not defined)
-
-	* upnp/src/genlib/miniserver/miniserver.c, 
-	  upnp/src/ssdp/ssdp_server.c: use socklen_t where appropriate 
-	  (instead of int)
-
-	* upnp/src/genlib/net/http/httpreadwrite.c (get_sdk_info): remove
-	  XINLINE declaration (unused and too late)
-
-	* ixml/src/node.c (ixmlNode_getNodeType): fix compilation warning
-	  on const return type
-
-2006-01-12  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* upnp/src/inc/readwrite.h : suppress unused C++ header file
-
-2006-01-11  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* upnp/inc/config.h, upnp/src/inc/upnpapi.h, 
-	  upnp/src/inc/httpreadwrite.h: remove internal configuration variable 
-	  MINIMUM_DELAY (no clear purpose)
-
-2005-12-05  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* upnp/inc/upnp.h: re-declare obsolete method UpnpSetContentLength,
-	  for binary compatibility with previous libupnp version.
-
-	* upnp/src/api/upnpapi.c: correct type of g_maxContentLength to size_t
-
-2005-11-01  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* autoconfiscate library : replace all makefiles by Makefile.am
-	  for automake support, + preliminary autoconf support
-	  (generated config.h not yet used in source files)
-
-2005-10-18  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* upnp/src/makefile: fix location of DEBUG STATIC libupnp library
-	
-	* upnp/sample/tvctrlpt/linux/Makefile, 
-	  upnp/sample/tvdevice/linux/Makefile: fix STATIC library support
-
-2005-10-16  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* threadutil/src/Makefile (clean): remove built library
-
-2005-08-28  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* ixml/src/ixml.h, ixml/src/ixml.c (ixmlRelaxParser) : new function
-
-	* ixml/src/ixmlparser.h, ixml/src/ixmlparser.c (Parser_setErrorChar) :
-	  new function
-
-2005-08-02  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* ixml/src/Makefile: correct bug for static library being incorrectly 
-	  stripped when building non-debug
-
-2005-06-09  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* ixml/src/element.c (ixmlElement_removeAttributeNode): 
-	  remove some compilation warning
-
-	* ixml/inc/ixml.h, ixml/src/document.c : 
-	  add some missing const's in public API 
-
-	* upnp/inc/upnptools.h, upnp/src/api/upnptools.c : 
-	  add missing const's in public API
-
-2005-05-28  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* upnp/inc/config.h: suppress HTTP_READ_BYTES (unused)
-	  and replace by DEFAULT_SOAP_CONTENT_LENGTH (previously in upnpapi.h)
-	
-	* upnp/inc/upnp.h, upnp/src/api/upnpapi.c : replace 
-	  UpnpSetContentLength (which was not using its Handle argument) 
-	  by global function UpnpSetMaxContentLength. 
-	  Remove "hard" limitation to 32K (not suitable for using in UPnP AV).
-	
-	* upnp/src/inc/upnpapi.h : removed DEFAULT_SOAP_CONTENT_LENGTH
-	  (moved to config.h) and MAX_SOAP_CONTENT_LENGTH (now unused)
-
-	* upnp/src/api/upnptools.c : add more error message strings
-
-	* upnp/src/genlib/net/http/httpreadwrite.c : return OUTOF_BOUNDS
-	  instead of BAD_HTTPMSG when allowed Content Length is exceeded.
-
-	* upnp/src/genlib/net/http/httpreadwrite.c : corrected an incorrect
-	  sprintf format
-	
-2005-05-27  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* upnp/makefile, upnp/src/makefile, 
-	  ixml/Makefile, ixml/src/Makefile, 
-	  threadutil/Makefile, threadutil/src/Makefile : 
-	  implement STATIC library support (from patch at 
-	  http://sourceforge.net/tracker/?group_id=7189&atid=307189 )
-
-2005-05-26  Rémi Turboult  <r3mi(at)users.sourceforge.net>
-
-	* upnp/src/api/upnpapi.c, upnp/src/soap/soap_device.c,
-	  upnp/src/soap/makefile : 
-	  corrections for compilation with CLIENT=1 only
-	
-	* importing "libupnp-1.2.1a" as baseline
-	
diff --git a/tombupnp/INSTALL b/tombupnp/INSTALL
deleted file mode 100644
index e69de29..0000000
diff --git a/tombupnp/LICENSE b/tombupnp/LICENSE
deleted file mode 100644
index 0436e93..0000000
--- a/tombupnp/LICENSE
+++ /dev/null
@@ -1,31 +0,0 @@
-Copyright (c) 2006 Sergey Bostandzhyan
-All additional changes that were made to the original sources are covered 
-by the GNU LGPL license. See COPYING.
-
-Copyright (c) 2000-2003 Intel Corporation 
-All rights reserved. 
-
-Redistribution and use in source and binary forms, with or without 
-modification, are permitted provided that the following conditions are met: 
-
-* Redistributions of source code must retain the above copyright notice, 
-  this list of conditions and the following disclaimer. 
-* Redistributions in binary form must reproduce the above copyright notice, 
-  this list of conditions and the following disclaimer in the documentation 
-  and/or other materials provided with the distribution. 
-* Neither name of Intel Corporation nor the names of its contributors 
-  may be used to endorse or promote products derived from this software 
-  without specific prior written permission.
- 
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/tombupnp/Makefile.am b/tombupnp/Makefile.am
deleted file mode 100644
index e616475..0000000
--- a/tombupnp/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-SUBDIRS=build
-
diff --git a/tombupnp/NEWS b/tombupnp/NEWS
deleted file mode 100644
index aedbfd3..0000000
--- a/tombupnp/NEWS
+++ /dev/null
@@ -1,84 +0,0 @@
-
-What is new in libupnp 1.3.1
-
-* fix: "upnp.h" includes "upnpdebug.h" only if debug enabled in the library 
-  (else header file is not installed)
-
-* fix: add inter-library dependencies between upnp and ixml / threadutil, 
-  so that programs linking against upnp only still work.
-
-============================================================================
-
-What is new in libupnp 1.3.0
-
-* major change: autoconfiscate build system. automake + autoconf replace the 
-  previous makefiles. This should allow for easier build and installation on
-  various distributions.
-
-* change: optional library features are selected with configure options 
-  (such as "./configure --enable-debug --disable-device") : see README file
-  for the main options, and "./configure --help" to display a complete list.
-
-* new: install a pkgconfig file "libupnp.pc"
-
-* new: a new installed file <upnp/upnpconfig.h> provides macros to know
-  the installed library version, and the optional features which have
-  been configured in the library.
-
-* change: the old included file "config.h", which contained internal 
-  definitions needed to compile the library, is no longer installed in <upnp>
-
-* change: the debug definitions previously available in <upnp/config.h>
-  are now available in <upnp/upnpdebug.h> (only if library configured with 
-  debug enabled).
-
-* change: add libtool versionning for the 3 libraries. 
-  Also hide all library symbols not part of the public API.
-
-* change: remove "hard" limit to 32K in UpnpSetContentLength
-  (not suitable for UPnP AV clients).
-
-* new: new "UpnpSetMaxContentLength" function to globally set the maximum 
-  incoming content-length that the SDK will process (should be used instead 
-  of UpnpSetContentLength, which does not uses its handle argument)
-
-* change: returns OUTOF_BOUNDS instead of BAD_HTTPMSG when exceed allowed
-  Content Length
-
-* new: ixml: new function ixmlRelaxParser to make the XML parser more tolerant
-  to malformed text, if required (default behaviour is unchanged : abort 
-  on error)
-
-* fix: compilation error with gcc4
-
-* fix: add some missing const's in public API
-
-* fix: add check for availability of socklen_t type
-
-* fix: miscellaneous bugs and warnings (see details in ChangeLog)
-
-============================================================================
-
-Changes to the SDK for UPnP Devices version 1.2.1a:
-
-- Changes the NAME_SIZE constant used for URL buffers to 256 bytes to 
-  accomodate longer URLs.
-
-============================================================================
-
-Changes to the SDK for UPnP Devices version 1.2.1:
- 
-- Integrates an entirely new XML parser that features DOM2 API support and
-  a much smaller code size.
-- Integrates a new threading utility library that manages all threads in
-  the library.
-- Elimination of C++ and other code optimizations have reduced the binary
-  size by over 60%.
-- The web server now supports application-level callbacks to handle 
-  dynamically generated data.
-- The web server now correctly handles chunked encoding.
-- A new client HTTP API has been added that allows downloading of items
-  of unlimited size.
-- The SDK supports much better cross-compilation support.
-- Numerous memory leaks and bugs have been fixed.
-
diff --git a/tombupnp/README b/tombupnp/README
deleted file mode 100644
index 3cf78cf..0000000
--- a/tombupnp/README
+++ /dev/null
@@ -1,23 +0,0 @@
-TombUPnP is based on Portable SDK for UPnP* Devices 
-(http://pupnp.sf.net/ (libupnp))
-
-
-Copyright (c) 2000-2003 Intel Corporation - All Rights Reserved.
-Copyright (c) 2005-2006 Rémi Turboult <r3mi at users.sourceforge.net>
-Copyright (c) 2006 Michel Pfeiffer and others <virtual_worlds at gmx.de>
-Copyright (c) 2006 Sergey 'Jin' Bostandzhyan <jin at mediatomb.org>
-
-See LICENSE for details. Note, that all changes that were added by
-the MediaTomb team are covered by LGPL, see README_LICENSE for more information.
-
-Also note, that contrary to TombUPnP, MediaTomb sources are covered by the 
-GPL license.
-
-Allthough it is possible, TombUPnP is not meant to be used as a standalone
-library. The motivation behind creating one more fork of the libupnp 
-project is the independance that is requried to achieve rapid development
-of the MediaTomb server.
-
-* Other brands, names, and trademarks are the property of their respective 
-owners.
-
diff --git a/tombupnp/README_LICENSE b/tombupnp/README_LICENSE
deleted file mode 100644
index 72a043f..0000000
--- a/tombupnp/README_LICENSE
+++ /dev/null
@@ -1,43 +0,0 @@
-TombUPnP ist licensed under the GNU Lesser General Public License version 2.1 
-as published by the Free Software Foundation. See COPYING for the whole license
-text.
-
-TombUPnP is based on pupnp (http://pupnp.sf.net) and libupnp 
-(http://upnp.sf.net), both are under the BSD license. 
-That means that portions of TombUPnP code are under the following license:
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-To clarify once again: all changes that were made by us to the original 
-libraries are under LGPL, that means that you are bound by the LGPL if you
-want to use/distribute TombUPnP as a whole. 
-
-
diff --git a/tombupnp/README_PUPNP b/tombupnp/README_PUPNP
deleted file mode 100644
index eede54d..0000000
--- a/tombupnp/README_PUPNP
+++ /dev/null
@@ -1,332 +0,0 @@
-Portable SDK for UPnP* Devices (libupnp)
-
-Copyright (c) 2000-2003 Intel Corporation - All Rights Reserved.
-Copyright (c) 2005-2006 Rémi Turboult <r3mi at users.sourceforge.net>
-Copyright (c) 2006 Michel Pfeiffer and others <virtual_worlds at gmx.de>
-
-See LICENSE for details.
-
-This file contains information about the above product in the following 
-sections: 
-
-1.  Release Contents
-2.  Package Contents
-3.  System Requirements
-4.  Build Instructions
-5.  Install/Uninstall Instructions
-6.  Product Release Notes
-7.  New Features
-8.  Support and Contact Information
-
-
-1) Release Contents
--------------------------------------------
-
-The Portable SDK for UPnP Devices is an SDK for development of UPnP device 
-and control point applications.  It consists of the core UPnP 
-protocols along with a UPnP-specific eXtensible Markup Language (XML) parser 
-supporting the Document Object Model (DOM) Level 2 API and an optional, 
-integrated mini web server for serving UPnP related documents.
-
-
-2) Package Contents
--------------------------------------------
-
-The SDK for UPnP Devices contains the following: 
-
-README    	This file.  Contains the installation and build instructions.
-LICENSE   	The licensing terms the SDK is distributed under.
-NEWS		Changes and new features.
-ixml\doc	The files for generating the XML parser documentation from
-		the source code.
-ixml\inc	The public include files required to use the XML parser.
-ixml\src	The source code to the XML parser library.
-threadutil\inc	The public include files required to the threading 
-		utility library.
-threadutil\src	The source code to the threading utility library.
-upnp\doc	The files for generating the SDK documentation from the
-		source code.
-upnp\inc	The public include files required to use the SDK.
-upnp\src      	The source files comprising the SDK, libupnp.so.
-upnp\sample	A sample device and control point application, illustrating the
-          	usage of the SDK.
-
-
-3) System Requirements
--------------------------------------------
-
-The SDK for UPnP Devices is designed to compile and run under several
-operating systems.  It does, however, have dependencies on some
-packages that may not be installed by default.  All packages that it
-requires are listed below.
-
-libpthread  The header and library are installed as part of the glibc-devel
-            package (or equivalent).
-
-Additionally, the documentation for the SDK can be auto-generated from 
-the UPNP.H header file using DOC++, a documentation system for C, C++, 
-IDL, and Java*.  DOC++ generates the documentation in HTML or TeX format.
-Using some additional tools, the TeX output can be converted into a
-PDF file.  To generate the documentation these tools are required:
-
-DOC++       The homepage for DOC++ is http://docpp.sourceforge.net/.
-            The current version as of this release of the SDK is
-            version 3.4.9.  DOC++ is the only requirement for generating
-            the HTML documentation.
-LaTeX/TeX   To generate the PDF documentation, LaTeX and TeX tools are
-            necessary.  The tetex and tetex-latex packages provide these
-            tools.
-dvips       dvips converts the DVI file produced by LaTeX into a PostScript*
-            file.  The tetex-dvips package provides this tool.
-ps2pdf      The final step to making the PDF is converting the PostStript
-            into Portable Document Format.  The ghostscript package provides
-            this tool.
-
-For the UPnP library to function correctly, networking must be configured
-properly for multicasting.  To do this:
-
-route add -net 239.0.0.0 netmask 255.0.0.0 eth0
-
-where 'eth0' is the network adapter that the UPnP library will use.  Without
-this addition, device advertisements and control point searches will not
-function.
-
-
-
-4) Build Instructions
--------------------------------------------
-
-CORE LIBRARIES
-
-The in the examples below, replace $(LIBUPNP) with "libupnp-x.y.z",
-with x, y, and z corresponding to the version of the library that you have.
-
-All pieces of the SDK are configured and built from the $(LIBUPNP) directory. 
-
-% cd $(LIBUPNP)
-% ./configure
-% make
-
-will build a version of the binaries without debug support, and with default 
-options enabled (see below for options available at configure time).
-
-% cd $(LIBUPNP)
-% ./configure CFLAGS="-DSPARC_SOLARIS -mtune=<cputype> -mcpu=<cputype>"
-% make
-
-will build a Sparc Solaris version of the binaries without debug support
-and with default options enabled (see below for options available at
-configure time). Please note: <cputype> has to be replaced by a token that
-fits to your platform and CPU (e.g. "supersparc").
-
-To build the documentation, assuming all the necessary tools are installed 
-(see section 3) :
-
-To generate the HTML documentation:
-
-% cd $(LIBUPNP)
-% make html
-
-To generate the PDF file:
-
-% cd $(LIBUPNP)
-% make pdf
-
-
-A few options are available at configure time. Use "./configure --help"
-to display a complete list of options. Note that these options 
-may be combined in any order.
-After installation, the file <upnp/upnpconfig.h> will provide a summary
-of the optional features that have been included in the library.
-
-
-% cd $(LIBUPNP)
-% ./configure --enable-debug
-% make 
-
-will build a debug version with symbols support.
-
-To build the library with the optional, integrated mini web server (note
-that this is the default):
-
-% cd $(LIBUPNP)
-% ./configure --enable-webserver
-% make 
-
-To build without:
-
-% cd $(LIBUPNP)
-% ./configure --disable-webserver
-% make 
-
-
-The SDK also contains some additional helper APIs, declared in
-inc/tools/upnptools.h.  If these additional tools are not required, they can
-be compiled out:
-
-% cd $(LIBUPNP)
-% ./configure --disable-tools
-% make 
-
-By default, the tools are included in the library.
-
-To further remove code that is not required, the library can be build with or 
-with out the control point (client) or device specific code.  To remove this
-code:
-
-% cd $(LIBUPNP)
-% ./configure --disable-client
-% make 
-
-to remove client only code or:
-
-% cd $(LIBUPNP)
-% ./configure --disable-device
-% make 
-
-to remove device only code.
-
-By default, both client and device code is included in the library.  The
-integrated web server is automatically removed when configuring with 
---disable-device.
-
-To build the library without large-file support (enabled by default) :
-
-% cd $(LIBUPNP)
-% ./configure --disable-largefile
-% make 
-
-
-To remove all the targets, object files, and built documentation:
-
-% cd $(LIBUPNP)
-% make clean
-
-
-CROSS COMPILATION
-
-To cross compile the SDK, a special "configure" directive is all that is
-required:
-
-% cd $(LIBUPNP)
-% ./configure --host=arm-linux
-% make
-
-This will invoke the "arm-linux-gcc" cross compiler to build the library.
-
-
-SAMPLES
-
-The SDK contains two samples: a TV device application and a control point
-that talks with the TV device.  They are found in the $(LIBUPNP)/upnp/sample 
-directory.  
-
-To build the samples (note: this is the default behaviour):
-
-% cd $(LIBUPNP)
-% ./configure --enable-samples
-% make
-
-will build the sample device "$(LIBUPNP)/upnp/upnp_tv_device" and
-sample control point "$(LIBUPNP)/upnp/upnp_tv_ctrlpt". 
-Note : the sample device won't be built if --disable-device has been 
-configured, and the sample control point won't be build if --disable-client 
-has been configured.
-
-To run the sample device, you need the "$(LIBUPNP)/upnp/sample/tvdevice/web" 
-sub-directory. Example :
-
-% cd $(LIBUPNP)/upnp/sample/tvdevice
-% ../../upnp_tv_device
-
-
-
-SOLARIS BUILD
-
-The building process for the Solaris operating system is similar to the one
-described above. Only the call to ./configure has to be done using an
-additional parameter:
-
-./configure CFLAGS="-mcpu=<cputype> -mtune=<cputype> -DSPARC_SOLARIS"
-
-where <cputype> has to be replaced by the appropriate CPU tuning flag (e.g.
-"supersparc"). Afterwards
-
-make
-make install
-
-can be called as described above.
-
-
-
-WINDOWS BUILD
-
-In order to build libupnp under Windows the pthreads-w32 package is required.
-You can download a self-extracting ZIP file from the following location:
-
-ftp://sources.redhat.com/pub/pthreads-win32/pthreads-w32-2-7-0-release.exe
-
-Execute the self-extracting archive and copy the Pre-build.2 folder to the
-top level source folder.
-Rename Pre-build.2 to pthreads. 
-Open the provided workspace build\libupnp.dsw with Visual C++ 6.0 and select
-Build->Build libupnp.dll (F7)
-
-For building a static library instead of a DLL and for using the static
-pthreads-w32 library following switches need to be defined additionally:
-
-UPNP_STATIC_LIB - for creating a statically linkable UPnP-library
-PTW32_STATIC_LIB - for using the static pthreads32 library
-
-
-5) Install/Uninstall Instructions
--------------------------------------------
-
-Install
-
-The top-level makefile for the UPnP SDK contains rules to install the 
-necessary components.  To install the SDK, as root:
-
-make install
-
-Uninstall
-
-Likewise, the top-level makefile contains an uninstall rule, reversing 
-the steps in the install:
-
-make uninstall
-
-
-6) Product Release Notes
--------------------------------------------
-
-The SDK for UPnP Devices v1.2.1a has these known issues:
-
-- The UPnP library may not work with older versions of gcc and libstdc++, 
-  causing a segmentation fault when the library loads.  It is recommended
-  that gcc version 2.9 or later be used in building library.
-- The UPnP library does not work the glibc 2.1.92-14 that ships with
-  Red Hat 7.0.  For the library to function, you must updated the glibc
-  and glibc-devel packages to 2.1.94-3 or later.  There is some issue with
-  libpthreads that has been resolved in the 2.1.94 version.
-
-
-7) New Features
--------------------------------------------
-
-See NEWS file.
-
-
-8) Support and Contact Information
--------------------------------------------
-
-Intel is not providing support for the SDK for UPnP Devices. Mailing lists
-and discussion boards can be found at http://www.libupnp.org/.
-
-If you find this SDK useful, please send an email to upnp at intel.com and let
-us know.
-
-
-* Other brands, names, and trademarks are the property of their respective 
-owners.
-
diff --git a/tombupnp/THANKS b/tombupnp/THANKS
deleted file mode 100644
index 0f79e9c..0000000
--- a/tombupnp/THANKS
+++ /dev/null
@@ -1,29 +0,0 @@
-
-libupnp was originally written by Intel Corporation.
-
-Many people further contributed to libupnp by reporting problems,
-suggesting various improvements or submitting actual code.
-Here is a list of these people. Help us keep it complete and
-exempt of errors.
-
-- Arno Willig
-- Chaos
-- David Maass
-- Erik Johansson
-- Eric Tanguy
-- Erwan Velu
-- Fredrik Svensson
-- Jiri Zouhar
-- John Dennis
-- Leuk_He
-- Loigu
-- Marcelo Roberto Jimenez
-- Markus Strobl
-- Nektarios K. Papadopoulos
-- Oskar Liljeblad
-- Oxy
-- Paul Vixie
-- Robert Buckley (rbuckley)
-- Siva Chandran
-- Zexian Chen
-- Zheng Peng (darkelf2010)
diff --git a/tombupnp/TODO b/tombupnp/TODO
deleted file mode 100644
index 00c2dee..0000000
--- a/tombupnp/TODO
+++ /dev/null
@@ -1,29 +0,0 @@
-
-To Be Done
-==========
-
-- add FreeBSD patches
-  ( http://sf.net/tracker/index.php?func=detail&aid=1332618&group_id=7189&atid=307189 ?)
-
-- non-regression testing 
-
-- replace doc++ by Doxygen for documentation generation
-
-- incorporate public patches and fix reported bugs : 
-http://sourceforge.net/tracker/?group_id=7189&atid=107189 and 
-http://sourceforge.net/tracker/?group_id=7189&atid=307189
-
-- RPM packaging (a preliminary one here :
-    https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=176617 )
-
-- make API clean for large files and 64 bits
-
-
-To Be Decided
-=============
-
-- IPV6 support ?
-
-
-
-
diff --git a/tombupnp/build/Makefile.am b/tombupnp/build/Makefile.am
deleted file mode 100644
index 1bb9c7c..0000000
--- a/tombupnp/build/Makefile.am
+++ /dev/null
@@ -1,12 +0,0 @@
-EXTRA_DIST=gen_libtombupnp_src.sh
-
-noinst_LIBRARIES=libtombupnp.a
-include $(srcdir)/libtombupnp_src
-libtombupnp_a_CFLAGS = \
-          -I$(top_srcdir)/tombupnp/ixml/src/inc \
-          -I$(top_srcdir)/tombupnp/ixml/inc \
-          -I$(top_srcdir)/tombupnp/threadutil/inc \
-          -I$(top_srcdir)/tombupnp/upnp/src/inc \
-          -I$(top_srcdir)/tombupnp/upnp/inc \
-          -I$(top_srcdir)
-
diff --git a/tombupnp/build/dummy.h b/tombupnp/build/dummy.h
deleted file mode 100644
index e69de29..0000000
diff --git a/tombupnp/build/gen_libtombupnp_src.sh b/tombupnp/build/gen_libtombupnp_src.sh
deleted file mode 100755
index fd5c6dd..0000000
--- a/tombupnp/build/gen_libtombupnp_src.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-echo 'libtombupnp_a_SOURCES = \'
-
-find ../ | egrep '\.(c|h)$' | egrep -v 'win_dll\.c' | sed 's/$/ \\/' | sort 
-
-echo "dummy.h"
-
diff --git a/tombupnp/build/libtombupnp_src b/tombupnp/build/libtombupnp_src
deleted file mode 100644
index 0e51e9c..0000000
--- a/tombupnp/build/libtombupnp_src
+++ /dev/null
@@ -1,98 +0,0 @@
-libtombupnp_a_SOURCES = \
-../build/dummy.h \
-../ixml/inc/ixml.h \
-../ixml/src/attr.c \
-../ixml/src/document.c \
-../ixml/src/element.c \
-../ixml/src/inc/ixmlmembuf.h \
-../ixml/src/inc/ixmlparser.h \
-../ixml/src/ixml.c \
-../ixml/src/ixmlmembuf.c \
-../ixml/src/ixmlparser.c \
-../ixml/src/namedNodeMap.c \
-../ixml/src/node.c \
-../ixml/src/nodeList.c \
-../threadutil/inc/FreeList.h \
-../threadutil/inc/iasnprintf.h \
-../threadutil/inc/ithread.h \
-../threadutil/inc/LinkedList.h \
-../threadutil/inc/ThreadPool.h \
-../threadutil/inc/TimerThread.h \
-../threadutil/src/FreeList.c \
-../threadutil/src/iasnprintf.c \
-../threadutil/src/LinkedList.c \
-../threadutil/src/ThreadPool.c \
-../threadutil/src/TimerThread.c \
-../upnp/inc/upnpconfig.h \
-../upnp/inc/upnpdebug.h \
-../upnp/inc/upnp.h \
-../upnp/inc/upnptools.h \
-../upnp/src/api/upnpapi.c \
-../upnp/src/api/upnpdebug.c \
-../upnp/src/api/upnptools.c \
-../upnp/src/gena/gena_callback2.c \
-../upnp/src/gena/gena_ctrlpt.c \
-../upnp/src/gena/gena_device.c \
-../upnp/src/genlib/client_table/client_table.c \
-../upnp/src/genlib/miniserver/miniserver.c \
-../upnp/src/genlib/net/http/httpparser.c \
-../upnp/src/genlib/net/http/httpreadwrite.c \
-../upnp/src/genlib/net/http/parsetools.c \
-../upnp/src/genlib/net/http/statcodes.c \
-../upnp/src/genlib/net/http/webserver.c \
-../upnp/src/genlib/net/sock.c \
-../upnp/src/genlib/net/uri/uri.c \
-../upnp/src/genlib/service_table/service_table.c \
-../upnp/src/genlib/util/membuffer.c \
-../upnp/src/genlib/util/strintmap.c \
-../upnp/src/genlib/util/strtoofft.c \
-../upnp/src/genlib/util/upnp_timeout.c \
-../upnp/src/genlib/util/util.c \
-../upnp/src/inc/client_table.h \
-../upnp/src/inc/config.h \
-../upnp/src/inc/gena_ctrlpt.h \
-../upnp/src/inc/gena_device.h \
-../upnp/src/inc/gena.h \
-../upnp/src/inc/global.h \
-../upnp/src/inc/gmtdate.h \
-../upnp/src/inc/http_client.h \
-../upnp/src/inc/httpparser.h \
-../upnp/src/inc/httpreadwrite.h \
-../upnp/src/inc/inet_pton.h \
-../upnp/src/inc/membuffer.h \
-../upnp/src/inc/miniserver.h \
-../upnp/src/inc/netall.h \
-../upnp/src/inc/parsetools.h \
-../upnp/src/inc/server.h \
-../upnp/src/inc/service_table.h \
-../upnp/src/inc/soaplib.h \
-../upnp/src/inc/sock.h \
-../upnp/src/inc/ssdplib.h \
-../upnp/src/inc/statcodes.h \
-../upnp/src/inc/statuscodes.h \
-../upnp/src/inc/strintmap.h \
-../upnp/src/inc/strtoofft.h \
-../upnp/src/inc/sysdep.h \
-../upnp/src/inc/unixutil.h \
-../upnp/src/inc/upnpapi.h \
-../upnp/src/inc/upnpclosesocket.h \
-../upnp/src/inc/upnp_md5.h \
-../upnp/src/inc/upnp_timeout.h \
-../upnp/src/inc/upnp_uuid.h \
-../upnp/src/inc/uri.h \
-../upnp/src/inc/urlconfig.h \
-../upnp/src/inc/utilall.h \
-../upnp/src/inc/util.h \
-../upnp/src/inc/webserver.h \
-../upnp/src/inet_pton.c \
-../upnp/src/soap/soap_common.c \
-../upnp/src/soap/soap_ctrlpt.c \
-../upnp/src/soap/soap_device.c \
-../upnp/src/ssdp/ssdp_ctrlpt.c \
-../upnp/src/ssdp/ssdp_device.c \
-../upnp/src/ssdp/ssdp_server.c \
-../upnp/src/urlconfig/urlconfig.c \
-../upnp/src/uuid/sysdep.c \
-../upnp/src/uuid/upnp_md5.c \
-../upnp/src/uuid/upnp_uuid.c \
-dummy.h
diff --git a/tombupnp/ixml/doc/docxx.sty b/tombupnp/ixml/doc/docxx.sty
deleted file mode 100644
index 4da4d39..0000000
--- a/tombupnp/ixml/doc/docxx.sty
+++ /dev/null
@@ -1,1083 +0,0 @@
-%  docxx.sty
-%
-%  Copyright (c) 1996 Roland Wunderling, Malte Zoeckler
-%  Copyright (c) 1999-2001 Dragos Acostachioaie
-%
-%  This file is part of DOC++.
-%
-%  DOC++ is free software; you can redistribute it and/or
-%  modify it under the terms of the GNU General Public
-%  License as published by the Free Software Foundation; either
-%  version 2 of the license, or (at your option) any later version.
-%
-%  This program is distributed in the hope that it will be useful,
-%  but WITHOUT ANY WARRANTY; without even the implied warranty of
-%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%  General Public License for more details.
-%
-%  You should have received a copy of the GNU General Public
-%  License along with this program; if not, write to the Free
-%  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-%
-%
-% Switch off special characters except {}\ for the rest of the text.
-%
-\def\cxxtilde{{\tt\~\relax}}
-\addtolength{\parskip}{6pt}
-
-\catcode`\,=\active%
-\def,{\char`\,\penalty-8\ }
-%\def,{++ }
-\catcode`\,=12
-
-\def\<{{\tt <}}
-\def\>{{\tt >}}
-\def\TEX{}
-\def\cxxExceptionsStr{}
-\def\cxxParameterStr{}
-\def\cxxReturnStr{}
-\def\cxxInvariantsStr{}
-\def\cxxPreconditionsStr{}
-\def\cxxPostconditionsStr{}
-\def\cxxSeeStr{}
-\def\cxxAuthorStr{}
-\def\cxxVersionStr{}
-\def\cxxDeprecatedStr{}
-\def\cxxSinceStr{}
-\def\cxxFileStr{}
-\def\cxxExceptions#1{\def\cxxExceptionsStr{#1}}
-\def\cxxParameter#1{\def\cxxParameterStr{#1}}
-\def\cxxReturn#1{\def\cxxReturnStr{#1}}
-\def\cxxInvariants#1{\def\cxxInvariantsStr{#1}}
-\def\cxxPreconditions#1{\def\cxxPreconditionsStr{#1}}
-\def\cxxPostconditions#1{\def\cxxPostconditionsStr{#1}}
-\def\cxxSee#1{\def\cxxSeeStr{#1}}
-\def\cxxAuthor#1{\def\cxxAuthorStr{#1}}
-\def\cxxVersion#1{\def\cxxVersionStr{#1}}
-\def\cxxDeprecated#1{\def\cxxDeprecatedStr{#1}}
-\def\cxxSince#1{\def\cxxSinceStr{#1}}
-\def\cxxFile#1{\def\cxxFileStr{#1}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% Define ... to do verbatim listing
-%
-\catcode`\=\active
-\catcode`\=\active
-{\obeyspaces\gdef {\ }}
-
-\def\ccverbatim{\strut\begingroup
-	    \catcode`\\=12 \catcode`\{=12
-	    \catcode`\}=12 \catcode`\$=12
-	    \catcode`\&=12 \catcode`\#=12
-	    \catcode`\%=12 \catcode`\~=12
-	    \catcode`\_=12 \catcode`\^=12
-	    \catcode`\|=12 \catcode`\/=12
-	    \obeyspaces\tt}
-\def{\let\par=\endgraf \ccverbatim \parskip=0pt \ccfinish}
-{\catcode`\=0 catcode`\=12
-gdefccfinish#1{#1endgroup}}
-
-%
-% Definition of structuring comands.
-%
-\newcommand{\Section}[1]{\section{#1}}
-\newcommand{\SubSection}[1]{\subsection{#1}}
-\newcommand{\SubSubSection}[1]{\subsubsection{#1}}
-\newcommand{\Paragraph}[1]{\paragraph{#1}}
-
-\newcommand{\Ref}[1]{{\bf #1} ($\rightarrow$ \ref{#1})}
-\newcommand{\URL}[2][]{%
-   \def\name{#1}%
-   \def\empty{}%
-   \ifx\name\empty%
-	{\tt #2}%
-   \else%
-	#1 ({\tt #2})%
-   \fi%
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% printing line #1 of code #2
-%
-\newdimen\cxxcodewidth
-\cxxcodewidth=\textwidth
-\advance\cxxcodewidth by -21pt
-
-\def\cxxCodeLine#1#2{%
-{\hbox to 20pt{\tiny\hss#1}\parbox[t]{\cxxcodewidth}{\small#2}}%
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for listing manual entries
-%
-\newdimen\cxxIdWidth
-\newdimen\cxxTypeWidth
-\newdimen\cxxProtoWidth
-\newdimen\cxxMemoWidth
-\newdimen\cxxPageWidth
-
-\cxxIdWidth=0.1\textwidth
-\cxxTypeWidth=0.15\textwidth
-\cxxProtoWidth=0.25\textwidth
-\cxxMemoWidth=0.43\textwidth
-
-\cxxPageWidth=\textwidth
-\advance\cxxPageWidth by-\cxxIdWidth
-\advance\cxxPageWidth by-\cxxTypeWidth
-\advance\cxxPageWidth by-\cxxProtoWidth
-\advance\cxxPageWidth by-\cxxMemoWidth
-
-\newdimen\cxxProtoMemoWidth
-\cxxProtoMemoWidth=\cxxProtoWidth
-\advance\cxxProtoMemoWidth by\cxxMemoWidth
-
-\def\cxxStrut{\vrule width0pt height0pt depth9pt}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% 1: type
-% 2: name
-% 3: args
-% 4: memo
-% 5: id
-\def\cxxitem#1#2#3#4#5{\noindent{%
-    \setbox5\hbox{#5 }%
-    \ifdim\wd5>\cxxIdWidth%
-	\setbox5\hbox{\hbox to \cxxIdWidth{\hss#5}}%
-    \else
-	\setbox5\hbox{\hbox to \cxxIdWidth{#5\hss}}%
-    \fi%
-    \setbox1\hbox{{%
-	\catcode`\&=4%
-	\catcode`\_=8%
-	\def{\ccverbatim \ccfinish}#1%
-    }}%
-    \setbox2\hbox{{%
-	\catcode`\&=4%
-	\catcode`\_=8%
-	\def{\ccverbatim \ccfinish}\textbf{#2} #3%
-    }}%
-    \setbox4\hbox{\parbox[t]{\cxxMemoWidth}{{%
-	\raggedright\sloppy%
-	\catcode`\&=4%
-	\catcode`\_=8%
-	\def{\ccverbatim \ccfinish}{\em #4}
-	\cxxStrut%
-	\def\page{#5}%
-	\ifx\page\empty%
-	    \hss%
-	\else%
-	    \ \dotfill%
-	    \hbox to 0pt{\hbox to \cxxPageWidth{\hss%
-		\pageref{cxx.#5}%
-	    }\hss}%
-	\fi%
-    }}}%
-    %
-    \ifdim\wd1>\cxxTypeWidth%
-	\hbox to \hsize{\unhbox5\hbox to \cxxTypeWidth{\unhbox1\hss}\hss}\\\nopagebreak%
-	\setbox5\hbox{\hskip\cxxIdWidth}%
-	\setbox1\hbox{\hskip\cxxTypeWidth}%
-    \else%
-	\setbox1\hbox{\hbox to \cxxTypeWidth{\unhbox1\hss}}%
-    \fi%
-    \ifdim\wd2>\cxxProtoWidth%
-	\ifdim\wd2<\cxxProtoMemoWidth%
-	    \def\tmp{#4}%
-	    \ifx\tmp\empty%
-		\def\tmp{#5}%
-		\ifx\tmp\empty%
-		    \hbox to \hsize{\unhbox5\unhbox1\unhbox2\hss\cxxStrut}\\%
-		\else%
-		    \hbox to \hsize{\unhbox5\unhbox1\unhbox2
-			\dotfill\hbox to \cxxPageWidth{\hss\pageref{cxx.#5}}%
-			\cxxStrut}\\%
-		\fi%
-	    \else%
-		\hbox to \hsize{\unhbox5\unhbox1\unhbox2\hss}\\\nopagebreak%
-		\hbox to \hsize{%
-		    \hskip\cxxIdWidth%
-		    \hskip\cxxTypeWidth%
-		    \hskip\cxxProtoWidth%
-		    \unhbox4\hss%
-		}\\%
-	    \fi%
-	\else%
-	    \hbox to \hsize{%
-		\unhbox5%
-		\unhbox1%
-		\parbox[t]{\cxxProtoMemoWidth}{%
-		    \setbox255\hbox{\textbf{#2} (}%
-		    \hangindent=\wd255\hangafter=1%
-		    \raggedright\sloppy%
-		    {\catcode`\&=4\catcode`\_=8%
-			\def{\ccverbatim \ccfinish}\textbf{#2} #3\strut}%
-		}\hss%
-	    }\\\nopagebreak%
-	    \hbox to \hsize{%
-		\hskip\cxxIdWidth%
-		\hskip\cxxTypeWidth%
-		\hskip\cxxProtoWidth%
-		\unhbox4\hss%
-	    }\\%
-	\fi%
-    \else%
-	\hbox to \hsize{%
-	    \unhbox5%
-	    \unhbox1%
-	    \hbox to \cxxProtoWidth{\unhbox2\hss}%
-	    \unhbox4\hss%
-	}\\%
-    \fi%
-}}
-
-
-\newdimen\cxxtypestart
-\cxxtypestart=0.05\textwidth
-%\advance\cxxtypestart by \labelsep
-
-\newdimen\cxxnamestart
-\cxxnamestart=\cxxtypestart
-\advance\cxxnamestart by 0.25\textwidth
-
-\newdimen\cxxargsstart
-\cxxargsstart=\cxxnamestart
-\advance\cxxargsstart by 0.2\textwidth
-\newdimen\cxxargswidth
-\cxxargswidth=\textwidth
-\advance\cxxargswidth by -\cxxargsstart
-\advance\cxxargswidth by -\spaceskip
-
-\newdimen\cxxmemostart
-\cxxmemostart=\cxxargsstart
-\advance\cxxmemostart by 0.12\textwidth
-
-\newenvironment{cxxlist}[1]{
-\begingroup
-\catcode`\,=\active%
-\paragraph{#1}\strut\smallskip\\
-}{
-\endgroup
-}
-
-\newenvironment{cxxnames}{\begin{cxxlist}{Names}}{\end{cxxlist}}
-\newenvironment{cxxpublic}{\begin{cxxlist}{Public Members}}{\end{cxxlist}}
-\newenvironment{cxxprivate}{\begin{cxxlist}{Private Members}}{\end{cxxlist}}
-\newenvironment{cxxprotected}{\begin{cxxlist}{Protected Members}}{\end{cxxlist}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%	Numbered Frame box
-%
-\newlength{\cxxBoxLen}%
-\newlength{\cxxBoxHt}%
-\newlength{\cxxBoxDp}%
-\newlength{\cxxSideHt}%
-\newlength{\cxxSideLen}%
-\newlength{\cxxTitleLen}%
-\def\empty{}
-\def\idPos{1cm}
-
-%
-% box with id and name [optional width]
-%
-\newcommand{\aBox}[3][1pt]{{%
-\small%
-\def\width{#1}%
-\def\num{#2}%
-\def\name{#3}%
-\setbox0\hbox{\hskip\width{ \strut\name\strut} \hskip\width}%
-%
-\setlength{\cxxBoxLen}{\wd0}%
-\addtolength{\cxxBoxLen}{\width}%
-\addtolength{\cxxBoxLen}{\width}%
-\setbox2\hbox{\normalsize\strut\rule{\cxxBoxLen}{\width}}%
-%
-\ifx\num\empty%
-    \setbox1\hbox{\strut}%
-\else%
-    \setbox1\hbox{\rule{\idPos}{\width} { \sf\bf\strut #2 } }%
-\fi%
-\addtolength{\cxxBoxLen}{-\wd1}%
-\setbox1\hbox{\unhbox1\rule{\cxxBoxLen}{\width}}%
-%
-\setlength{\cxxSideHt}{\dp0}%
-\addtolength{\cxxSideHt}{\width}%
-\setlength{\cxxSideLen}{\dp0}%
-\addtolength{\cxxSideLen}{\ht0}%
-\addtolength{\cxxSideLen}{\dp1}%
-\addtolength{\cxxSideLen}{\width}%
-\addtolength{\cxxSideLen}{\width}%
-\setbox3\hbox{\hbox to 0pt{\hss\rule[-\cxxSideHt]{\width}{\cxxSideLen}}}%
-\setbox4\hbox{\hbox to 0pt{\rule[-\cxxSideHt]{\width}{\cxxSideLen}\hss}}%
-%
-\setlength{\cxxBoxHt}{\dp1}%
-\addtolength{\cxxBoxHt}{1pt}%
-\setlength{\cxxBoxDp}{\ht2}%
-\addtolength{\cxxBoxDp}{-\width}%
-\addtolength{\cxxBoxDp}{1pt}%
-%
-\setlength{\cxxBoxLen}{\ht3}%
-\addtolength{\cxxBoxLen}{\ht1}%
-%
-\vbox to \cxxBoxLen{%
-\hbox{\unhbox1}%
-\vskip-\cxxBoxHt%
-\hbox{\hskip\width\unhbox3\unhbox0\unhbox4}%
-%\vskip-\ht2%
-\vskip-\cxxBoxDp%
-\hbox{\unhbox2}%
-\vss%
-}%
-}}
-
-%
-% box with id and name [optional width] of size #4
-%
-\newcommand{\sizeBox}[4][3pt]{{%
-    \setbox0\hbox{ }%
-    \setlength{\cxxSideLen}{#4}%
-    \addtolength{\cxxSideLen}{-\wd0}%
-    \addtolength{\cxxSideLen}{-\wd0}%
-    \addtolength{\cxxSideLen}{-#1}%
-    \addtolength{\cxxSideLen}{-#1}%
-    \addtolength{\cxxSideLen}{-#1}%
-    \addtolength{\cxxSideLen}{-#1}%
-    \aBox[#1]{#2}{\hbox to \cxxSideLen{#3}}%
-}}
-
-%
-% centered box with id and name [optional width] of size #4
-%
-\newcommand{\cBox}[4][3pt]{{%
-\setbox0\hbox{\aBox[#1]{#2}{#3}}%
-\ifdim\wd0<#4%
-    \sizeBox[#1]{#2}{\hss#3\hss}{#4}%
-\else%
-    \setlength{\cxxSideLen}{\wd0}%
-    \advance\cxxSideLen by -#4%
-    \hskip -0.5\cxxSideLen%
-    \unhbox0%
-\fi%
-}}
-
-%
-% right expanding box with id and name [optional width] of size at least #4
-%
-\newcommand{\rBox}[4][3pt]{{%
-\setbox0\hbox{\aBox[#1]{#2}{#3}\hss}%
-\ifdim\wd0>#4%
-    \unhbox0%
-\else%
-    \sizeBox[#1]{#2}{\hss#3\hss}{#4}%
-\fi%
-}}
-
-%
-% left expanding box with id and name [optional width] of size at least #4
-%
-\newcommand{\lBox}[4][3pt]{{%
-\setbox0\hbox{\aBox[#1]{#2}{#3}\hss}%
-\ifdim\wd0>#4%
-    \setlength{\cxxSideLen}{\wd0}%
-    \advance\cxxSideLen by -#4%
-    \hskip -\cxxSideLen%
-    \unhbox0%
-\else%
-    \sizeBox[#1]{#2}{\hss#3\hss}{#4}%
-\fi%
-}}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%	Pagestyle for documentation.
-%
-\newsavebox{\cxxHeadName}
-\newcommand{\ps at docxx}{%
-    \renewcommand{\@oddhead}{\headlinetext}%
-    \renewcommand{\@evenhead}{\headlinetext}%
-    \renewcommand{\@oddfoot}{\footlinetext}%
-    \renewcommand{\@evenfoot}{\footlinetext}%
-}
-\newcommand{\makeHeadLine}[2]{
-    \global\sbox{\cxxHeadName}{\vbox to 0pt{\vss%
-	\hbox to \textwidth{%
-	    \hbox to 0pt{\strut\hbox to 1cm{\hss}\quad#1\hss}%
-	    \hfil#2\hfil%
-	}%
-	\vskip 1pt%
-	\hbox to \textwidth{\hrulefill}%
-    }}%
-}
-\newcommand{\headlinetext}{\usebox{\cxxHeadName}}
-\providecommand{\cxxCopyright}{%
-    \vtop{%
-	\hbox to \textwidth{{
-	    \tiny\sf This page was generated with the help of DOC++
-	\hss}}%
-	\vskip -20pt
-	\hbox to \textwidth{
-	    \hbox{{\tiny\sf http://docpp.sourceforge.net}}
-	\hss}%
-    }%
-}
-\def\footlinetext{\hbox to \textwidth{
-    \vtop{%
-	\hbox to \textwidth{\hrulefill}%
-	\vskip -20pt%
-	\cxxCopyright%
-    }%
-    \hss\vtop{\vskip 10pt\hbox{\today\hspace*{3cm}\textrm{\thepage} }}
-}}
-\pagestyle{docxx}
-
-\def\cxxTitle#1#2#3#4#5{\noindent{%
-    \thispagestyle{empty}
-    \vfill
-    \begin{center}
-    \Huge\bf
-    \catcode`\&=4%
-    \catcode`\_=8%
-    \def{\ccverbatim \ccfinish}#1%
-    \strut\\
-    \def{\ccverbatim \ccfinish}#2%
-    \strut\\
-    \def{\ccverbatim \ccfinish}#3%
-    \strut\\
-    \end{center}
-    \if\cxxVersionStr\empty%
-    \else%
-	\begin{center}
-	\small\sf
-	--- Version \cxxVersionStr\ ---
-	\end{center}
-	\global\def\cxxVersionStr{}
-    \fi
-    \vfill
-    \large
-    \begin{center}
-    \Large\em
-    \def{\ccverbatim \ccfinish}#4%
-    \end{center}
-    \vfill
-    \if\cxxAuthorStr\empty%
-    \else%
-	\begin{center}
-	\sf\cxxAuthorStr
-	\end{center}
-	\global\def\cxxAuthorStr{}
-	\vfill
-    \fi
-    \pagebreak
-    \makeHeadLine{}{#2}
-}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%	environment for contents
-%
-\newcounter{cxxContentsDepth}
-\setcounter{cxxContentsDepth}{0}
-\newdimen\cxxContentsLengthIncr
-\cxxContentsLengthIncr=18pt
-\newdimen\cxxContentsLength
-\cxxContentsLength=\textwidth
-\advance\cxxContentsLength by -\cxxContentsLengthIncr
-
-\makeHeadLine{}{Contents}
-
-\newenvironment{cxxContents}{
-    \ifcase \value{cxxContentsDepth}
-	\vskip 40pt
-	\hbox to \hsize{\hskip 8pt\hskip\cxxContentsLengthIncr\Huge\bf Contents\hss}
-	\vskip 40pt
-	\bf
-    \else					% >1
-	\rm
-    \fi
-    \begingroup
-    \addtocounter{cxxContentsDepth}{1}
-    \advance\cxxContentsLengthIncr by  8pt
-    \advance\cxxContentsLength     by -\cxxContentsLengthIncr
-}{
-    \addtocounter{cxxContentsDepth}{-1}
-    \advance\cxxContentsLength     by  \cxxContentsLengthIncr
-    \advance\cxxContentsLengthIncr by  -8pt
-    \ifcase \value{cxxContentsDepth}
-	\vskip 12pt
-    \or	
-	\vskip 9pt
-    \else
-	\vskip 3pt
-    \fi
-    \endgroup
-}
-
-\newcommand{\cxxContentsEntry}[3]{{
-    \def\emtpty{}
-    \def\memo{#3}
-    \ifx\memo\empty
-	\setbox0\hbox{\parbox[t]{\cxxContentsLength}{\strut#2 \dotfill }}
-    \else
-	\setbox0\hbox{\parbox[t]{\cxxContentsLength}{\strut#2 --- {\em #3} \dotfill }}
-    \fi
-    \setbox1\hbox{\vtop{\vskip\dp0\vskip-\ht0\vskip-1.5pt\hbox to 20pt{\hss\rm \pageref{cxx.#1}}}}
-    \hbox to \textwidth{%
-	\hss\hbox to \cxxContentsLengthIncr{#1\hss}%
-	\unhbox0\unhbox1%
-    }
-}}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%	environment for class graph
-%
-\newdimen\cxxClassGraphShift
-\newdimen\cxxClassGraphLength
-\newdimen\cxxClassGraphHeight
-\newdimen\cxxClassGraphDepth
-\newdimen\cxxClassGraphTotV
-\setlength{\cxxClassGraphLength}{0.23\hsize}
-\setlength{\cxxClassGraphShift}{30pt}
-\setbox0\vbox{\aBox[5pt]{\strut}{\strut}}
-\setlength{\cxxClassGraphHeight}{\ht0}
-\setlength{\cxxClassGraphDepth}{\dp0}
-\addtolength{\cxxClassGraphDepth}{10pt}
-\setlength{\cxxClassGraphTotV}{\dp0}
-\addtolength{\cxxClassGraphTotV}{\ht0}
-
-\newenvironment{cxxInheritance}{
-    \par\medskip
-    \begingroup
-    \newcommand{\cxxCGSpace}[1]{%
-	\vtop to \cxxClassGraphTotV{\hbox to \cxxClassGraphShift{%
-	    \vrule width0pt height \cxxClassGraphHeight depth \cxxClassGraphDepth%
-	##1}}%
-    }
-    \newcommand{\cxxSlashHline}{%
-	\vrule width 0.1\cxxClassGraphShift height 3.5pt depth -3pt%
-	\vrule width 0.1\cxxClassGraphShift height 0pt depth 0pt%
-	\vrule width 0.1\cxxClassGraphShift height 3.5pt depth -3pt%
-	\vrule width 0.1\cxxClassGraphShift height 0pt depth 0pt%
-	\vrule width 0.1\cxxClassGraphShift height 3.5pt depth -3pt%
-    }
-    \newcommand{\cxxDotHline}{%
-	\vrule width 0.06\cxxClassGraphShift height 3.5pt depth -3pt%
-	\vrule width 0.05\cxxClassGraphShift height 0pt depth 0pt%
-	\vrule width 0.06\cxxClassGraphShift height 3.5pt depth -3pt%
-	\vrule width 0.05\cxxClassGraphShift height 0pt depth 0pt%
-	\vrule width 0.06\cxxClassGraphShift height 3.5pt depth -3pt%
-	\vrule width 0.05\cxxClassGraphShift height 0pt depth 0pt%
-	\vrule width 0.06\cxxClassGraphShift height 3.5pt depth -3pt%
-	\vrule width 0.05\cxxClassGraphShift height 0pt depth 0pt%
-	\vrule width 0.06\cxxClassGraphShift height 3.5pt depth -3pt%
-    }
-    \newcommand{\cxxHline}{%
-	\vrule width 0.5\cxxClassGraphShift height 3.5pt depth -3pt%
-    }
-    \newcommand{\cxxVup}{\hbox to 0pt{\hss%
-	\vrule width 0.5pt height \cxxClassGraphHeight depth -3pt%
-    \hss}}
-    \newcommand{\cxxVlow}{\hbox to 0pt{\hss%
-	\vtop to 0pt{\vskip-3pt%
-	    \hbox{\vrule width 0.5pt height 13pt depth \cxxClassGraphDepth}%
-	\vss}%
-    \hss}}
-    \newcommand{\cxxLinkUp}{\hbox to 0pt{\hss\hskip 0.5\cxxClassGraphShift%
-	\raise0.7\cxxClassGraphHeight\hbox to 0pt{\hss\textbf{\symbol{94}}\hss}}}%
-    \newcommand{\cxxLinkDown}{\hbox to 0pt{\hss\hskip 0.5\cxxClassGraphShift%
-	\raise-0.6\cxxClassGraphHeight\vbox to 0pt{%
-	    \hbox to 0pt{\hss\textbf{$\lor$}\hss}\vss}}}%
-    \newcommand{\cxxLinkLeft}{\hbox to 0pt{\hss\hskip 0.0\cxxClassGraphShift%
-	\raise0.0\cxxClassGraphHeight\hbox to 0pt{\textbf{\tt\<}\hss}}}%
-    \newcommand{\cxxLinkRight}{\hbox to 0pt{\hss\hskip 1.0\cxxClassGraphShift%
-	\raise0.0\cxxClassGraphHeight\hbox to 0pt{\hss\textbf{\tt\>}}}}%
-    \newcommand{\cxxInheritanceEntry}[5][]{
-	\hbox to \hsize{\hss%
-	    \vrule width0pt height \cxxClassGraphHeight depth \cxxClassGraphDepth%
-	    ##2%
-	    \def\tmp{##1}%
-	    \ifx\tmp\empty%
-		\def\tmp{##5}%
-		\ifx\tmp\empty%
-		    \rBox[1pt]{##3}{##4}{0.24\hsize}%
-		\else%
-		    \lBox[1pt]{##3}{##4}{0.24\hsize}%
-		\fi%
-	    \else%
-		\cBox[2pt]{##3}{##4}{0.24\hsize}%
-	    \fi%
-	    ##5\hfill%
-	}\vskip-1pt
-    }
-    \newcommand{\cxxNone}{\cxxCGSpace{\hss}}
-    \newcommand{\cxxLong}{\cxxCGSpace{\hss\cxxVup\cxxVlow\hss}}
-%
-    \newcommand{\cxxPubLeft}{\cxxCGSpace{\cxxHline\cxxVup\cxxVlow\hss}}
-    \newcommand{\cxxProLeft}{\cxxCGSpace{\cxxSlashHline\cxxVup\cxxVlow\hss}}
-    \newcommand{\cxxPriLeft}{\cxxCGSpace{\cxxDotHline\cxxVup\cxxVlow\hss}}
-    \newcommand{\cxxPubleft}{\cxxCGSpace{\cxxHline\cxxVlow\hss}}
-    \newcommand{\cxxProleft}{\cxxCGSpace{\cxxSlashHline\cxxVlow\hss}}
-    \newcommand{\cxxPrileft}{\cxxCGSpace{\cxxDotHline\cxxVlow\hss}}
-    \newcommand{\cxxLastPubLeft}{\cxxCGSpace{\cxxHline%
-    		    	\cxxVup\cxxLinkDown\cxxVlow\hss}}
-    \newcommand{\cxxLastProLeft}{\cxxCGSpace{\cxxSlashHline%
-    		    	\cxxVup\cxxLinkDown\cxxVlow\hss}}
-    \newcommand{\cxxLastPriLeft}{\cxxCGSpace{\cxxDotHline%
-    		    	\cxxVup\cxxLinkDown\cxxVlow\hss}}
-    \newcommand{\cxxLastPubleft}{\cxxCGSpace{\cxxHline%
-    		    	\cxxVlow\cxxLinkDown\hss}}
-    \newcommand{\cxxLastProleft}{\cxxCGSpace{\cxxSlashHline%
-    		    	\cxxVlow\cxxLinkDown\hss}}
-    \newcommand{\cxxLastPrileft}{\cxxCGSpace{\cxxDotHline%
-    				\cxxVlow\cxxLinkDown\hss}}
-    \newcommand{\cxxLinkPubLeft}{\cxxCGSpace{\cxxLinkLeft\cxxHline\cxxVup\cxxVlow\hss}}
-    \newcommand{\cxxLinkProLeft}{\cxxCGSpace{\cxxLinkLeft\cxxSlashHline%
-    				\cxxVup\cxxVlow\hss}}
-    \newcommand{\cxxLinkPriLeft}{\cxxCGSpace{\cxxLinkLeft\cxxDotHline%
-    				\cxxVup\cxxVlow\hss}}
-    \newcommand{\cxxLinkPubleft}{\cxxCGSpace{\cxxLinkLeft\cxxHline\cxxVlow\hss}}
-    \newcommand{\cxxLinkProleft}{\cxxCGSpace{\cxxLinkLeft\cxxSlashHline\cxxVlow\hss}}
-    \newcommand{\cxxLinkPrileft}{\cxxCGSpace{\cxxLinkLeft\cxxDotHline\cxxVlow\hss}}
-%
-    \newcommand{\cxxPubRight}{\cxxCGSpace{\hss\cxxVup\cxxVlow\cxxHline}}
-    \newcommand{\cxxProRight}{\cxxCGSpace{\hss\cxxVup\cxxVlow\cxxSlashHline}}
-    \newcommand{\cxxPriRight}{\cxxCGSpace{\hss\cxxVup\cxxVlow\cxxDotHline}}
-    \newcommand{\cxxPubright}{\cxxCGSpace{\hss\cxxVup\cxxHline}}
-    \newcommand{\cxxProright}{\cxxCGSpace{\hss\cxxVup\cxxSlashHline}}
-    \newcommand{\cxxPriright}{\cxxCGSpace{\hss\cxxVup\cxxDotHline}}
-
-    \newcommand{\cxxLinkPubRight}{\cxxCGSpace{\hss\cxxVup\cxxVlow\cxxHline\cxxLinkRight}}
-    \newcommand{\cxxLinkProRight}{\cxxCGSpace{\hss\cxxVup\cxxVlow%
-    				   \cxxSlashHline\cxxLinkRight}}
-    \newcommand{\cxxLinkPriRight}{\cxxCGSpace{\hss\cxxVup\cxxVlow%
-				   \cxxDotHline\cxxLinkRight}}
-    \newcommand{\cxxLinkPubright}{\cxxCGSpace{\hss\cxxVup\cxxHline\cxxLinkRight}}
-    \newcommand{\cxxLinkProright}{\cxxCGSpace{\hss\cxxVup\cxxSlashHline\cxxLinkRight}}
-    \newcommand{\cxxLinkPriright}{\cxxCGSpace{\hss\cxxVup\cxxDotHline\cxxLinkRight}}
-
-    \newcommand{\cxxFirstPubRight}{\cxxCGSpace{\hss\cxxVup\cxxLinkUp\cxxVlow\cxxHline}}
-    \newcommand{\cxxFirstProRight}{\cxxCGSpace{\hss\cxxVup\cxxLinkUp\cxxVlow%
-    				   \cxxSlashHline}}
-    \newcommand{\cxxFirstPriRight}{\cxxCGSpace{\hss\cxxVup\cxxLinkUp\cxxVlow\cxxDotHline}}
-    \newcommand{\cxxFirstPubright}{\cxxCGSpace{\hss\cxxVup\cxxLinkUp\cxxHline}}
-    \newcommand{\cxxFirstProright}{\cxxCGSpace{\hss\cxxVup\cxxLinkUp\cxxSlashHline}}
-    \newcommand{\cxxFirstPriright}{\cxxCGSpace{\hss\cxxVup\cxxLinkUp\cxxDotHline}}
-}{
-    \endgroup
-}
-
-\newenvironment{cxxClassGraph}{
-    \begin{cxxInheritance}
-    \newcommand{\cxxClassGraphEntry}[4]{
-	\hbox to \hsize{\hss%
-	    \vrule width0pt height \cxxClassGraphHeight depth \cxxClassGraphDepth%
-	    ##1%
-	    \def\tmp{##4}%
-	    \rBox[1pt]{##2}{##3}{0.24\hsize}%
-	    ##4%
-	    \hskip\cxxClassGraphShift\dotfill%
-	    \hbox to \cxxClassGraphShift{\hss\pageref{cxx.##2}}%
-	}\vskip-1pt
-    }
-    \newcommand{\cxxClassGraphEntryUnknownPackage}[3]{
-	\hbox to \hsize{\hss%
-	    \vrule width0pt height \cxxClassGraphHeight depth \cxxClassGraphDepth%
-	    ##1%
-	    \def\tmp{##3}%
-	    \rBox[1pt]{}{##2}{0.24\hsize}%
-	    ##3%
-	    \hskip\cxxClassGraphShift\hfill%
-	}\vskip-1pt
-    }
-    \clearpage
-    \pagebreak\strut
-    \makeHeadLine{}{Class Graph}
-    \vskip 20pt
-    \hbox to \hsize{\Huge\bf \quad Class Graph\hss}
-    \vskip 40pt
-}
-{
-    \end{cxxInheritance}
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for generic manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newdimen\cxxgenericstart
-\cxxgenericstart=\labelwidth
-\advance\cxxgenericstart by \labelsep
-\newdimen\cxxgenericwidth
-\cxxgenericwidth=\textwidth
-\advance\cxxgenericwidth by -\cxxgenericstart
-
-\newcounter{cxxDepth}
-\setcounter{cxxDepth}{0}
-
-\newlength{\cxxSize}
-\newenvironment{cxxgeneric}[5]{
-%
-%	some local definitions
-%
-    \def\empty{}
-    \def\type{#1}
-    \def\args{#3}
-    \def\memo{#4}
-    \def\id  {#5}
-%
-%	pagebreak ?
-%
-\ifcase \value{cxxDepth}
-	\clearpage			%  0
-	\pagebreak
-	\makeHeadLine{#5}{#2}
-	\setlength{\cxxSize}{2pt}
-\or					%  1
-	\strut\bigskip\bigskip\goodbreak%
-	\setlength{\cxxSize}{1pt}
-\else					% >2
-	\strut\bigskip\bigskip\goodbreak%
-	\setlength{\cxxSize}{0.5pt}
-\fi
-\addtocounter{cxxDepth}{1}
-%
-%	write synopsis
-%
-\setbox0\hbox{ }%
-\setbox1\hbox{\strut\large #1 {\bf#2} }%
-\setbox3\hbox{\strut\large #1 {\bf#2} #3}%
-%
-% box with id and name [optional width] over entire page width
-%
-\setlength{\cxxSideLen}{\hsize}%
-\addtolength{\cxxSideLen}{-4\cxxSize}%
-\addtolength{\cxxSideLen}{-2\wd0}%
-\setlength{\cxxTitleLen}{\cxxSideLen}%
-\addtolength{\cxxTitleLen}{-8\wd0}%
-\hbox{\aBox[\cxxSize]{\id}{\vbox{\vskip 1.5\parskip%
-    \hbox to \cxxSideLen{\strut%
-	\hbox to 4\wd0{}%
-	\ifdim\wd3<\cxxTitleLen%
-	    \parbox[b]{\cxxTitleLen}{%
-		\begin{raggedright}
-		\noindent\large #1 {\bf#2} #3
-		\end{raggedright}
-	    }
-	\else%
-	    \ifdim\wd1>0.7\cxxTitleLen%
-		\parbox[b]{\cxxTitleLen}{%
-		    \begin{raggedright}
-		    \noindent\large #1 {\bf#2} #3
-		    \end{raggedright}
-		}
-	    \else%
-		\addtolength{\cxxTitleLen}{-\wd1}%
-		\unhbox1%
-		\parbox[t]{\cxxTitleLen}{%
-		    \advance\lineskip 7pt%
-		    \begin{raggedright}
-		    \noindent\large\strut #3
-		    \end{raggedright}
-		}
-	    \fi%
-	\fi%
-	\hss\strut%
-    }\vskip\parskip}%
-}}
-% \parbox[b]{\cxxSideLen}{\begingroup
-% 	\catcode`\&=12%
-% 	\catcode`\_=12%
-% 	\begin{flushleft}
-% 	    \quad\large%
-% 	    \ifx\type\empty
-% 		\ifx\args\empty
-% 		    \strut{\bf #2}\\
-% 		\else
-% 		    \strut{\bf #2}\ \args
-% 		\fi
-% 	    \else
-% 		\strut\type\ {\bf #2}\ \args
-% 	    \fi
-% 	\end{flushleft}
-% \endgroup}}}%
-\ifx\memo\empty\else
-    \vskip 10pt
-    \begin{flushright}
-	\it\memo
-    \end{flushright}
-\fi
-\label{cxx.\id}
-\begingroup
-\def\cxxExceptionsStr{}
-\def\cxxParameterStr{}
-\def\cxxReturnStr{}
-\def\cxxInvariantsStr{}
-\def\cxxPreconditionsStr{}
-\def\cxxPostconditionsStr{}
-\def\cxxSeeStr{}
-\def\cxxAuthorStr{}
-\def\cxxVersionStr{}
-\def\cxxDeprecatedStr{}
-\def\cxxSinceStr{}
-\def\cxxFileStr{}
-\def\cxxExceptions##1{\def\cxxExceptionsStr{##1}}
-\def\cxxParameter##1{\def\cxxParameterStr{##1}}
-\def\cxxReturn##1{\def\cxxReturnStr{##1}}
-\def\cxxInvariants##1{\def\cxxInvariantsStr{##1}}
-\def\cxxPreconditions##1{\def\cxxPreconditionsStr{##1}}
-\def\cxxPostconditions##1{\def\cxxPostconditionsStr{##1}}
-\def\cxxSee##1{\def\cxxSeeStr{##1}}
-\def\cxxAuthor##1{\def\cxxAuthorStr{##1}}
-\def\cxxVersion##1{\def\cxxVersionStr{##1}}
-\def\cxxDeprecated##1{\def\cxxDeprecatedStr{##1}}
-\def\cxxSince##1{\def\cxxSinceStr{##1}}
-\def\cxxFile##1{\def\cxxFileStr{##1}}
-}{
-\endgroup
-\addtocounter{cxxDepth}{-1}
-}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for function manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxfunction}[5]{
-\begin{cxxgeneric}{#1}{#2}{#3}{#4}{#5}
-\renewenvironment{cxxnames}{\begin{cxxlist}{Arguments}}{\end{cxxlist}}
-}{
-\end{cxxgeneric}
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxentry}[5]{
-\begin{cxxgeneric}{#1}{#2}{#3}{#4}{#5}}{\end{cxxgeneric}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for union manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxunion}[5]{
-\begin{cxxgeneric}{#1}{#2}{#3}{#4}{#5}
-\renewenvironment{cxxnames}{\begin{cxxlist}{Members}}{\end{cxxlist}}
-}{
-\end{cxxgeneric}
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for typedef manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxtypedef}[5]{
-\begin{cxxgeneric}{#1}{#2}{}{#4}{#5}
-\renewenvironment{cxxnames}{\begin{cxxlist}{Members}}{\end{cxxlist}}
-}{
-\end{cxxgeneric}
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for macro manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxmacro}[5]{
-\begin{cxxgeneric}{\#define}{#2}{#3}{#4}{#5}}{\end{cxxgeneric}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for class manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxclass}[5]{
-\begin{cxxgeneric}{#1}{#2}{#3}{#4}{#5}}{\end{cxxgeneric}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for namespace manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxnamespace}[5]{
-\begin{cxxgeneric}{#1}{#2}{#3}{#4}{#5}}{\end{cxxgeneric}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for interface manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxinterface}[5]{
-\begin{cxxgeneric}{#1}{#2}{#3}{#4}{#5}}{\end{cxxgeneric}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for variable manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxvariable}[5]{
-\begin{cxxgeneric}{#1}{#2}{#3}{#4}{#5}
-\renewenvironment{cxxnames}{\begin{cxxlist}{Names}}{\end{cxxlist}}
-}{
-\end{cxxgeneric}
-}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for documentation
-%
-\newenvironment{cxxdocumentation}{
-%
-% switch on special characters for documentation section
-%
-\begingroup
-\catcode`\&=4
-\catcode`\_=8
-}{
-\endgroup
-}
-
-\newenvironment{cxxdoc}{
-%
-% switch on special characters for documentation section
-%
-\begin{cxxdocumentation}
-\strut\\\noindent%
-}{
-\smallskip
-\def\empty{}%
-\ifx\cxxReturnStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Return Value:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxReturnStr}\\
-\fi
-\ifx\cxxParameterStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Parameters:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxParameterStr}\\
-\fi
-\ifx\cxxExceptionsStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Exceptions:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxExceptionsStr}\\
-\fi
-\ifx\cxxInvariantsStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Invariants:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxInvariantsStr}\\
-\fi
-\ifx\cxxPreconditionsStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Preconditions:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxPreconditionsStr}\\
-\fi
-\ifx\cxxPostconditionsStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Postconditions:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxPostconditionsStr}\\
-\fi
-\ifx\cxxSeeStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf See Also:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxSeeStr}\\
-\fi
-\ifx\cxxAuthorStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Author:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxAuthorStr}\\
-\fi
-\ifx\cxxVersionStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Version:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxVersionStr}\\
-\fi
-\ifx\cxxDeprecatedStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf\it Deprecated:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxDeprecatedStr}\\
-\fi
-\ifx\cxxSinceStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Since:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxSinceStr}\\
-\fi
-\ifx\cxxFileStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf File:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxFileStr}\\
-\fi
-\end{cxxdocumentation}
-}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for commented listing
-% arguments are:
-%	#1	Section title
-%
-\newenvironment{cxximplementation}[1]{
-\goodbreak
-\begin{cxxdocumentation}
-}{
-\end{cxxdocumentation}
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\def\cxxCodeLine#1{
-\strut\hbox to 20pt{\tiny\hss #1}\small
-%\advance\leftmargin by 20pt
-%\advance\textwidth by -20pt
-\ccverbatim \parskip=0pt \cxxCodeFinish}
-{\catcode`\=0 catcode`\=12
-gdefcxxCodeFinish#1{hbox{#1}endgroup}}
-
diff --git a/tombupnp/ixml/doc/intro.dxx b/tombupnp/ixml/doc/intro.dxx
deleted file mode 100644
index 2b88f89..0000000
--- a/tombupnp/ixml/doc/intro.dxx
+++ /dev/null
@@ -1,28 +0,0 @@
-/**@name Introduction
- * The Linux DOM2 XML Parser Version 1.2 (IXML) is a lightweight, portable XML
- * parser supporting the standard Document Object Model (DOM) Level 2 
- * interfaces. The parser uses a C-style interface, making it idea for small, 
- * embedded applications.  This document describes the interfaces supported by
- * IXML 1.2, referencing the W3C DOM2 recommendations when necessary, and the 
- * additional utility application programming interfaces (APIs) that it 
- * supports. 
- * 
- * Note that this document assumes that the reader has a copy of the DOM2-Core
- * recommendation.  Refer to the link below to obtain a copy.  Only a brief
- * description is included here and the reader is pointed to the DOM2-Core
- * recommendation for more details.  This document does, however, clarify 
-*  IXML-specific behavior when the recommendation is unclear.
- *
- * {\bf About DOM}
- *
- * The Document Object Model (DOM) is a set of interfaces that give a 
- * programmatic interface to documents.  It provides a platform-neutral and 
- * language-neutral interface for random access and updating elements inside 
- * XML documents.  DOM Level 1 provided the basic interfaces to access 
- * document elements.  DOM Level 2 extended the interfaces to provide proper 
- * support for XML namespaces.
- *
- * The latest DOM 2 recommendation is maintained by W3C and is available from 
- * {\tt http://www.w3.org/TR/DOM-Level-2-Core}.
- */
-
diff --git a/tombupnp/ixml/doc/ixml.dxx b/tombupnp/ixml/doc/ixml.dxx
deleted file mode 100644
index d4fd090..0000000
--- a/tombupnp/ixml/doc/ixml.dxx
+++ /dev/null
@@ -1,15 +0,0 @@
-/**@name IXML v1.2 
- * \begin{center}
- *   {\bf Linux DOM2 XML Parser Version 1.2}
- * 
- *   Copyright (C) 2000-2003 Intel Corporation  ALL RIGHTS RESERVED
- *
- *   Revision 1.2.1 (\Date)
- * \end{center}
- */
-//@{
-  //@Include: intro.dxx
-  //@Include: license.dxx 
-  //@Include: ../inc/ixml.h
-//@}
-
diff --git a/tombupnp/ixml/doc/license.dxx b/tombupnp/ixml/doc/license.dxx
deleted file mode 100644
index 88b21cf..0000000
--- a/tombupnp/ixml/doc/license.dxx
+++ /dev/null
@@ -1,32 +0,0 @@
-/**@name License
- *
- * \begin{center}
- *    Copyright (c) 2000-2003 Intel Corporation 
- *    All rights reserved. 
- * \end{center}
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met: 
- * \begin{itemize}
- * \item Redistributions of source code must retain the above copyright notice, 
- *   this list of conditions and the following disclaimer. 
- * \item Redistributions in binary form must reproduce the above copyright 
- *   notice, this list of conditions and the following disclaimer in the 
- *   documentation and/or other materials provided with the distribution. 
- * \item Neither name of Intel Corporation nor the names of its contributors 
- *   may be used to endorse or promote products derived from this software 
- *   without specific prior written permission.
- * \end{itemize}
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
diff --git a/tombupnp/ixml/inc/ixml.h b/tombupnp/ixml/inc/ixml.h
deleted file mode 100644
index 8d0e2f5..0000000
--- a/tombupnp/ixml/inc/ixml.h
+++ /dev/null
@@ -1,1917 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef _IXML_H_
-#define _IXML_H_
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-#ifdef WIN32
- #ifndef UPNP_STATIC_LIB
-  #ifdef LIBUPNP_EXPORTS
-  // set up declspec for dll export to make functions visible to library users
-   #define EXPORT_SPEC __declspec(dllexport)
-  #else
-   #define EXPORT_SPEC __declspec(dllimport)
-  #endif
- #else
-  #define EXPORT_SPEC
- #endif
-#else
- #define EXPORT_SPEC
-#endif
-
-typedef int BOOL;
-
-#define DOMString   char *
-
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef IN
-#define IN
-#endif
-
-#ifndef OUT
-#define OUT
-#endif
-
-#ifndef INOUT
-#define INOUT
-#endif
-
-/**@name DOM Interfaces 
- * The Document Object Model consists of a set of objects and interfaces
- * for accessing and manipulating documents.  IXML does not implement all
- * the interfaces documented in the DOM2-Core recommendation but defines
- * a subset of the most useful interfaces.  A description of the supported
- * interfaces and methods is presented in this section.
- *
- * For a complete discussion on the object model, the object hierarchy,
- * etc., refer to section 1.1 of the DOM2-Core recommendation.
- */
-
-//@{
-
-/*================================================================
-*
-*   DOM node type 
-*
-*
-*=================================================================*/
-typedef enum
-{
-    eINVALID_NODE                   = 0,
-    eELEMENT_NODE                   = 1,
-    eATTRIBUTE_NODE                 = 2,
-    eTEXT_NODE                      = 3,
-    eCDATA_SECTION_NODE             = 4,
-    eENTITY_REFERENCE_NODE          = 5,
-    eENTITY_NODE                    = 6,                
-    ePROCESSING_INSTRUCTION_NODE    = 7,
-    eCOMMENT_NODE                   = 8,
-    eDOCUMENT_NODE                  = 9,
-    eDOCUMENT_TYPE_NODE             = 10,
-    eDOCUMENT_FRAGMENT_NODE         = 11,
-    eNOTATION_NODE                  = 12,
-
-}   IXML_NODE_TYPE;
-
-/*================================================================
-*
-*   error code 
-*
-*
-*=================================================================*/
-typedef enum 
-{   // see DOM spec
-    IXML_INDEX_SIZE_ERR                 = 1,
-    IXML_DOMSTRING_SIZE_ERR             = 2,
-    IXML_HIERARCHY_REQUEST_ERR          = 3,
-    IXML_WRONG_DOCUMENT_ERR             = 4,
-    IXML_INVALID_CHARACTER_ERR          = 5,
-    IXML_NO_DATA_ALLOWED_ERR            = 6,
-    IXML_NO_MODIFICATION_ALLOWED_ERR    = 7,
-    IXML_NOT_FOUND_ERR                  = 8,
-    IXML_NOT_SUPPORTED_ERR              = 9,
-    IXML_INUSE_ATTRIBUTE_ERR            = 10,
-    IXML_INVALID_STATE_ERR              = 11,
-    IXML_SYNTAX_ERR                     = 12,
-    IXML_INVALID_MODIFICATION_ERR       = 13,
-    IXML_NAMESPACE_ERR                  = 14,
-    IXML_INVALID_ACCESS_ERR             = 15,
-
-    IXML_SUCCESS                        = 0,
-    IXML_NO_SUCH_FILE                   = 101,
-    IXML_INSUFFICIENT_MEMORY            = 102,
-    IXML_FILE_DONE                      = 104,
-    IXML_INVALID_PARAMETER              = 105,
-    IXML_FAILED                         = 106,
-    IXML_INVALID_ITEM_NUMBER            = 107,
-
-} IXML_ERRORCODE;
-
-
-#define DOCUMENTNODENAME    "#document"
-#define TEXTNODENAME        "#text"
-#define CDATANODENAME       "#cdata-section"
-
-/*================================================================
-*
-*   DOM data structures
-*
-*
-*=================================================================*/
-typedef struct _IXML_Document *Docptr;
-
-typedef struct _IXML_Node    *Nodeptr;
-typedef struct _IXML_Node
-{
-    DOMString       nodeName;
-    DOMString       nodeValue;
-    IXML_NODE_TYPE  nodeType;
-    DOMString       namespaceURI;
-    DOMString       prefix;
-    DOMString       localName;
-    BOOL            readOnly;
-
-    Nodeptr         parentNode;
-    Nodeptr         firstChild;
-    Nodeptr         prevSibling;
-    Nodeptr         nextSibling;
-    Nodeptr         firstAttr;
-    Docptr          ownerDocument;
-
-} IXML_Node;
-
-typedef struct _IXML_Document
-{
-    IXML_Node    n;
-} IXML_Document;
-
-typedef struct _IXML_CDATASection
-{
-    IXML_Node    n;
-} IXML_CDATASection;
-
-typedef struct _IXML_Element
-{
-    IXML_Node   n;
-    DOMString   tagName;
-
-} IXML_Element;
-
-typedef struct _IXML_ATTR
-{
-    IXML_Node   n;
-    BOOL        specified;
-    IXML_Element *ownerElement;
-} IXML_Attr;
-
-typedef struct _IXML_Text
-{
-    IXML_Node   n;
-} IXML_Text;
-
-typedef struct _IXML_NodeList
-{
-    IXML_Node    *nodeItem;
-    struct  _IXML_NodeList *next;
-} IXML_NodeList;
-
-
-typedef struct _IXML_NamedNodeMap
-{
-    IXML_Node                 *nodeItem;
-    struct _IXML_NamedNodeMap *next;
-} IXML_NamedNodeMap;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*================================================================
-*
-*   NODE interfaces
-*
-*
-*=================================================================*/
-
-/**@name Interface {\it Node}
- * The {\bf Node} interface forms the primary datatype for all other DOM 
- * objects.  Every other interface is derived from this interface, inheriting 
- * its functionality.  For more information, refer to DOM2-Core page 34.
- */
-
-//@{
-
-  /** Returns the name of the {\bf Node}, depending on what type of 
-   *  {\bf Node} it is, in a read-only string. Refer to the table in the 
-   *  DOM2-Core for a description of the node names for various interfaces.
-   *
-   *  @return [const DOMString] A constant {\bf DOMString} of the node name.
-   */
-
-EXPORT_SPEC const DOMString
-ixmlNode_getNodeName(IXML_Node *nodeptr 
-		       /** Pointer to the node to retrieve the name. */
-                    );
-
-  /** Returns the value of the {\bf Node} as a string.  Note that this string 
-   *  is not a copy and modifying it will modify the value of the {\bf Node}.
-   *
-   *  @return [DOMString] A {\bf DOMString} of the {\bf Node} value.
-   */
-
-EXPORT_SPEC const DOMString               
-ixmlNode_getNodeValue(IXML_Node *nodeptr  
-		        /** Pointer to the {\bf Node} to retrieve the value. */
-                     );
-
-  /** Assigns a new value to a {\bf Node}.  The {\bf newNodeValue} string is
-   *  duplicated and stored in the {\bf Node} so that the original does not
-   *  have to persist past this call.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: The {\bf Node*} is not a valid 
-   *            pointer.
-   *      \item {\tt IXML_INSUFFICIENT_MEMORY}: Not enough free memory exists 
-   *            to complete this operation.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int                     
-ixmlNode_setNodeValue(IXML_Node *nodeptr, 
-		        /** The {\bf Node} to which to assign a new value. */
-                      const char *newNodeValue  
-		        /** The new value of the {\bf Node}. */
-                  );
-
-  /** Retrieves the type of a {\bf Node}.  The defined {\bf Node} constants 
-   *  are:
-   *  \begin{itemize}
-   *    \item {\tt eATTRIBUTE_NODE} 
-   *    \item {\tt eCDATA_SECTION_NODE}
-   *    \item {\tt eCOMMENT_NODE}
-   *    \item {\tt eDOCUMENT_FRAGMENT_NODE} 
-   *    \item {\tt eDOCUMENT_NODE} 
-   *    \item {\tt eDOCUMENT_TYPE_NODE} 
-   *    \item {\tt eELEMENT_NODE} 
-   *    \item {\tt eENTITY_NODE}
-   *    \item {\tt eENTITY_REFERENCE_NODE}
-   *    \item {\tt eNOTATION_NODE} 
-   *    \item {\tt ePROCESSING_INSTRUCTION_NODE}
-   *    \item {\tt eTEXT_NODE}
-   *  \end{itemize}
-   *
-   *  @return [const unsigned short] An integer representing the type of the 
-   *          {\bf Node}.
-   */
-
-EXPORT_SPEC unsigned short    
-ixmlNode_getNodeType(IXML_Node *nodeptr  
-		       /** The {\bf Node} from which to retrieve the type. */
-                    );
-
-  /** Retrieves the parent {\bf Node} for a {\bf Node}.
-   *
-   *  @return [Node*] A pointer to the parent {\bf Node} or {\tt NULL} if the 
-   *          {\bf Node} has no parent.
-   */
-
-EXPORT_SPEC IXML_Node*                   
-ixmlNode_getParentNode(IXML_Node *nodeptr  
-		         /** The {\bf Node} from which to retrieve the 
-			     parent. */ 
-                      );
-
-  /** Retrieves the list of children of a {\bf Node} in a {\bf NodeList} 
-   *  structure.  If a {\bf Node} has no children, {\bf ixmlNode_getChildNodes} 
-   *  returns a {\bf NodeList} structure that contains no {\bf Node}s.
-   *
-   *  @return [NodeList*] A {\bf NodeList} of the children of the {\bf Node}.
-   */
-
-EXPORT_SPEC IXML_NodeList*               
-ixmlNode_getChildNodes(IXML_Node *nodeptr  
-		         /** The {\bf Node} from which to retrieve the 
-			     children. */
-                   );
-
-  /** Retrieves the first child {\bf Node} of a {\bf Node}.
-   *
-   *  @return [Node*] A pointer to the first child {\bf Node} or {\tt NULL} 
-   *                  if the {\bf Node} does not have any children.
-   */
-
-EXPORT_SPEC IXML_Node*                   
-ixmlNode_getFirstChild(IXML_Node *nodeptr  
-		         /** The {\bf Node} from which to retrieve the first 
-			     child.  */ 
-);
-
-  /** Retrieves the last child {\bf Node} of a {\bf Node}.
-   *
-   *  @return [Node*] A pointer to the last child {\bf Node} or {\tt NULL} if 
-   *                  the {\bf Node} does not have any children.
-   */
-
-EXPORT_SPEC IXML_Node*                   
-ixmlNode_getLastChild(IXML_Node *nodeptr  
-		        /** The {\bf Node} from which to retrieve the last 
-			    child. */
-                  );
-
-  /** Retrieves the sibling {\bf Node} immediately preceding this {\bf Node}.
-   *
-   *  @return [Node*] A pointer to the previous sibling {\bf Node} or 
-   *                  {\tt NULL} if no such {\bf Node} exists.
-   */
-
-EXPORT_SPEC IXML_Node*                   
-ixmlNode_getPreviousSibling(IXML_Node *nodeptr  
-		              /** The {\bf Node} for which to retrieve the 
-			          previous sibling.  */
-                        );
-
-  /** Retrieves the sibling {\bf Node} immediately following this {\bf Node}.
-   *
-   *  @return [Node*] A pointer to the next sibling {\bf Node} or {\tt NULL} 
-   *                  if no such {\bf Node} exists.
-   */
-
-EXPORT_SPEC IXML_Node*                   
-ixmlNode_getNextSibling(IXML_Node *nodeptr  
-		          /** The {\bf Node} from which to retrieve the next 
-			      sibling. */ 
-                    );
-
-  /** Retrieves the attributes of a {\bf Node}, if it is an {\bf Element} node,
-   *  in a {\bf NamedNodeMap} structure.
-   *
-   *  @return [NamedNodeMap*] A {\bf NamedNodeMap} of the attributes or 
-   *                          {\tt NULL}.
-   */
-
-EXPORT_SPEC IXML_NamedNodeMap*           
-ixmlNode_getAttributes(IXML_Node *nodeptr  
-		         /** The {\bf Node} from which to retrieve the 
-			     attributes. */ 
-                   );
-
-  /** Retrieves the document object associated with this {\bf Node}.  This 
-   *  owner document {\bf Node} allows other {\bf Node}s to be created in the 
-   *  context of this document.  Note that {\bf Document} nodes do not have 
-   *  an owner document.
-   *
-   *  @return [Document*] A pointer to the owning {\bf Document} or 
-   *                      {\tt NULL}, if the {\bf Node} does not have an owner.
-   */
-
-EXPORT_SPEC IXML_Document*               
-ixmlNode_getOwnerDocument(IXML_Node *nodeptr  
-		            /** The {\bf Node} from which to retrieve the 
-			        owner document. */
-                      );
-
-  /** Retrieves the namespace URI for a {\bf Node} as a {\bf DOMString}.  Only
-   *  {\bf Node}s of type {\tt eELEMENT_NODE} or {\tt eATTRIBUTE_NODE} can 
-   *  have a namespace URI.  {\bf Node}s created through the {\bf Document} 
-   *  interface will only contain a namespace if created using 
-   *  {\bf ixmlDocument_createElementNS}.
-   *
-   *  @return [const DOMString] A {\bf DOMString} representing the URI of the 
-   *                            namespace or {\tt NULL}.
-   */
-
-EXPORT_SPEC const DOMString         
-ixmlNode_getNamespaceURI(IXML_Node *nodeptr  
-		           /** The {\bf Node} for which to retrieve the 
-			       namespace. */
-                     );
-
-  /** Retrieves the namespace prefix, if present.  The prefix is the name
-   *  used as an alias for the namespace URI for this element.  Only 
-   *  {\bf Node}s of type {\tt eELEMENT_NODE} or {\tt eATTRIBUTE_NODE} can have 
-   *  a prefix. {\bf Node}s created through the {\bf Document} interface will 
-   *  only contain a prefix if created using {\bf ixmlDocument_createElementNS}.
-   *
-   *  @return [DOMString] A {\bf DOMString} representing the namespace prefix 
-   *                      or {\tt NULL}.
-   */
-
-EXPORT_SPEC const DOMString               
-ixmlNode_getPrefix(IXML_Node *nodeptr  
-		     /** The {\bf Node} from which to retrieve the prefix. */
-               );
-
-  /** Retrieves the local name of a {\bf Node}, if present.  The local name is
-   *  the tag name without the namespace prefix.  Only {\bf Node}s of type
-   *  {\tt eELEMENT_NODE} or {\tt eATTRIBUTE_NODE} can have a local name.
-   *  {\Bf Node}s created through the {\bf Document} interface will only 
-   *  contain a local name if created using {\bf ixmlDocument_createElementNS}.
-   *
-   *  @return [const DOMString] A {\bf DOMString} representing the local name 
-   *                            of the {\bf Element} or {\tt NULL}.
-   */
-
-EXPORT_SPEC const DOMString         
-ixmlNode_getLocalName(IXML_Node *nodeptr  
-		        /** The {\bf Node} from which to retrieve the local 
-			    name. */
-                  );
-
-  /** Inserts a new child {\bf Node} before the existing child {\bf Node}.  
-   *  {\bf refChild} can be {\tt NULL}, which inserts {\bf newChild} at the
-   *  end of the list of children.  Note that the {\bf Node} (or {\bf Node}s) 
-   *  in {\bf newChild} must already be owned by the owner document (or have no
-   *  owner at all) of {\bf nodeptr} for insertion.  If not, the {\bf Node} 
-   *  (or {\bf Node}s) must be imported into the document using 
-   *  {\bf ixmlDocument_importNode}.  If {\bf newChild} is already in the tree,
-   *  it is removed first.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf nodeptr} or 
-   *            {\bf newChild} is {\tt NULL}.
-   *      \item {\tt IXML_HIERARCHY_REQUEST_ERR}: The type of the {\bf Node} 
-   *            does not allow children of the type of {\bf newChild}.
-   *      \item {\tt IXML_WRONG_DOCUMENT_ERR}: {\bf newChild} has an owner 
-   *            document that does not match the owner of {\bf nodeptr}.
-   *      \item {\tt IXML_NO_MODIFICATION_ALLOWED_ERR}: {\bf nodeptr} is 
-   *            read-only or the parent of the {\bf Node} being inserted is 
-   *            read-only.
-   *      \item {\tt IXML_NOT_FOUND_ERR}: {\bf refChild} is not a child of 
-   *            {\bf nodeptr}.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int     
-ixmlNode_insertBefore(IXML_Node *nodeptr,   
-		        /** The parent of the {\bf Node} before which to 
-			    insert the new child. */
-                      IXML_Node* newChild,      
-		        /** The {\bf Node} to insert into the tree. */
-                      IXML_Node* refChild       
-		        /** The reference child where the new {\bf Node} 
-			    should be inserted. The new {\bf Node} will
-			    appear directly before the reference child. */
-                  );
-
-  /** Replaces an existing child {\bf Node} with a new child {\bf Node} in 
-   *  the list of children of a {\bf Node}. If {\bf newChild} is already in 
-   *  the tree, it will first be removed. {\bf returnNode} will contain the 
-   *  {\bf oldChild} {\bf Node}, appropriately removed from the tree (i.e. it 
-   *  will no longer have an owner document).
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMTER: Either {\bf nodeptr}, {\bf 
-   *            newChild}, or {\bf oldChild} is {\tt NULL}.
-   *      \item {\tt IXML_HIERARCHY_REQUEST_ERR}: The {\bf newChild} is not 
-   *            a type of {\bf Node} that can be inserted into this tree or 
-   *            {\bf newChild} is an ancestor of {\bf nodePtr}.
-   *      \item {\tt IXML_WRONG_DOCUMENT_ERR}: {\bf newChild} was created from 
-   *            a different document than {\bf nodeptr}.
-   *      \item {\tt IXML_NO_MODIFICATION_ALLOWED_ERR}: {\bf nodeptr} or 
-   *            its parent is read-only.
-   *      \item {\tt IXML_NOT_FOUND_ERR}: {\bf oldChild} is not a child of 
-   *            {\bf nodeptr}.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int     
-ixmlNode_replaceChild(IXML_Node *nodeptr,     
-		        /** The parent of the {\bf Node} which contains the 
-			    child to replace. */
-                      IXML_Node* newChild,        
-		        /** The child with which to replace {\bf oldChild}. */
-                      IXML_Node* oldChild,        
-		        /** The child to replace with {\bf newChild}. */
-                      IXML_Node** returnNode      
-		        /** Pointer to a {\bf Node} to place the removed {\bf 
-			    oldChild} {\bf Node}. */
-                  );
-
-  /** Removes a child from the list of children of a {\bf Node}.
-   *  {\bf returnNode} will contain the {\bf oldChild} {\bf Node}, 
-   *  appropriately removed from the tree (i.e. it will no longer have an 
-   *  owner document).
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf nodeptr} or 
-   *            {\bf oldChild} is {\tt NULL}.
-   *      \item {\tt IXML_NO_MODIFICATION_ALLOWED_ERR}: {\bf nodeptr} or its 
-   *            parent is read-only.
-   *      \item {\tt IXML_NOT_FOUND_ERR}: {\bf oldChild} is not among the 
-   *            children of {\bf nodeptr}.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int     
-ixmlNode_removeChild(IXML_Node *nodeptr,     
-		       /** The parent of the child to remove. */
-                     IXML_Node* oldChild,  
-		       /** The child {\bf Node} to remove. */
-                     IXML_Node **returnNode
-		       /** Pointer to a {\bf Node} to place the removed {\bf 
-			   oldChild} {\bf Node}. */
-                 );
-
-  /** Appends a child {\bf Node} to the list of children of a {\bf Node}.  If
-   *  {\bf newChild} is already in the tree, it is removed first.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf nodeptr} or 
-   *            {\bf newChild} is {\tt NULL}.
-   *      \item {\tt IXML_HIERARCHY_REQUEST_ERR}: {\bf newChild} is of a type 
-   *            that cannot be added as a child of {\bf nodeptr} or 
-   *            {\bf newChild} is an ancestor of {\bf nodeptr}.
-   *      \item {\tt IXML_WRONG_DOCUMENT_ERR}: {\bf newChild} was created from 
-   *            a different document than {\bf nodeptr}.
-   *      \item {\tt IXML_NO_MODIFICATION_ALLOWED_ERR}: {\bf nodeptr} is a 
-   *            read-only {\bf Node}.
-   */
-
-EXPORT_SPEC int     
-ixmlNode_appendChild(IXML_Node *nodeptr,  
-		       /** The {\bf Node} in which to append the new child. */
-                     IXML_Node* newChild      
-		       /** The new child to append. */
-                 );
-
-  /** Queries whether or not a {\bf Node} has children.
-   *
-   *  @return [BOOL] {\tt TRUE} if the {\bf Node} has one or more children 
-   *                 otherwise {\tt FALSE}.
-   */
-
-EXPORT_SPEC BOOL    
-ixmlNode_hasChildNodes(IXML_Node *nodeptr  
-		         /** The {\bf Node} to query for children. */
-                   );
-
-  /** Clones a {\bf Node}.  The new {\bf Node} does not have a parent.  The
-   *  {\bf deep} parameter controls whether the subtree of the {\bf Node} is
-   *  also cloned.  For details on cloning specific types of {\bf Node}s, 
-   *  refer to the DOM2-Core recommendation.
-   *
-   *  @return [Node*] A clone of {\bf nodeptr} or {\tt NULL}.
-   */
-
-EXPORT_SPEC IXML_Node*   
-ixmlNode_cloneNode(IXML_Node *nodeptr,  
-		     /** The {\bf Node} to clone.  */
-                   BOOL deep
-		     /** {\tt TRUE} to clone the subtree also or {\tt FALSE} 
-		         to clone only {\bf nodeptr}. */
-                  );
-
-  /** Queries whether this {\bf Node} has attributes.  Note that only 
-   *  {\bf Element} nodes have attributes.
-   *
-   *  @return [BOOL] {\tt TRUE} if the {\bf Node} has attributes otherwise 
-   *                 {\tt FALSE}.
-   */
-
-EXPORT_SPEC BOOL    
-ixmlNode_hasAttributes(IXML_Node *node  
-		         /** The {\bf Node} to query for attributes. */
-                      );
-
-  /** Frees a {\bf Node} and all {\bf Node}s in its subtree.
-   *
-   *  @return [void] This function does not return a value.
-   */
-
-EXPORT_SPEC void    
-ixmlNode_free(IXML_Node *IXML_Node  
-		/** The {\bf Node} to free. */
-             );
-
-//@}
-
-/*================================================================
-*
-*   Attribute interfaces
-*
-*
-*=================================================================*/
-
-/**@name Interface {\it Attr}
- * The {\bf Attr} interface represents an attribute of an {\bf Element}.
- * The document type definition (DTD) or schema usually dictate the
- * allowable attributes and values for a particular element.  For more 
- * information, refer to the {\it Interface Attr} section in the DOM2-Core.
- */
-//@{
-
-
-  /** Frees an {\bf Attr} node.
-   *
-   *  @return [void] This function does not return a value.
-   */
-
-EXPORT_SPEC void    
-ixmlAttr_free(IXML_Attr *attrNode  
-		/** The {\bf Attr} node to free.  */
-             );
-
-//@}
-
-
-/*================================================================
-*
-*   CDATASection interfaces
-*
-*
-*=================================================================*/
-
-/**@name Interface {\it CDATASection}
- * The {\bf CDATASection} is used to escape blocks of text containing
- * characters that would otherwise be regarded as markup. CDATA sections
- * cannot be nested. Their primary purpose is for including material such
- * XML fragments, without needing to escape all the delimiters.  For more 
- * information, refer to the {\it Interface CDATASection} section in the
- * DOM2-Core.
- */
-//@{
-
-
-  /** Initializes a {\bf CDATASection} node.
-   *
-   *  @return [void] This function does not return a value.
-   */
-
-EXPORT_SPEC void    
-ixmlCDATASection_init(IXML_CDATASection *nodeptr  
-		        /** The {\bf CDATASection} node to initialize.  */
-                     );
-
-
-  /** Frees a {\bf CDATASection} node.
-   *
-   *  @return [void] This function does not return a value.
-   */
-
-EXPORT_SPEC void    
-ixmlCDATASection_free(IXML_CDATASection *nodeptr  
-		        /** The {\bf CDATASection} node to free. */
-                     );
-
-//@}
-
-/*================================================================
-*
-*   Document interfaces
-*
-*
-*=================================================================*/
-
-/**@name Interface {\it Document}
- * The {\bf Document} interface represents the entire XML document.
- * In essence, it is the root of the document tree and provides the
- * primary interface to the elements of the document.  For more information,
- * refer to the {\it Interface Document} section in the DOM2Core.
- */
-//@{
-
-  /** Initializes a {\bf Document} node.
-   *
-   *  @return [void] This function does not return a value.
-   */
-
-EXPORT_SPEC void    
-ixmlDocument_init(IXML_Document *nodeptr  
-		    /** The {\bf Document} node to initialize.  */
-                 );
-
-  /** Creates a new empty {\bf Document} node.  The 
-   *  {\bf ixmlDocument_createDocumentEx} API differs from the {\bf
-   *  ixmlDocument_createDocument} API in that it returns an error code
-   *  describing the reason for the failure rather than just {\tt NULL}.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INSUFFICIENT_MEMORY}: Not enough free memory exists 
-   *            to complete this operation.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int ixmlDocument_createDocumentEx(IXML_Document** doc 
-		                    /** Pointer to a {\bf Document} where the 
-				        new object will be stored. */
-		                  );
-
-
-  /** Creates a new empty {\bf Document} node.
-   *
-   *  @return [Document*] A pointer to the new {\bf Document} or {\tt NULL} on 
-   *                      failure.
-   */
-
-EXPORT_SPEC IXML_Document* ixmlDocument_createDocument();
-
-  /** Creates a new {\bf Element} node with the given tag name.  The new
-   *  {\bf Element} node has a {\tt nodeName} of {\bf tagName} and
-   *  the {\tt localName}, {\tt prefix}, and {\tt namespaceURI} set 
-   *  to {\tt NULL}.  To create an {\bf Element} with a namespace, 
-   *  see {\bf ixmlDocument_createElementNS}.
-   *
-   *  The {\bf ixmlDocument_createElementEx} API differs from the {\bf
-   *  ixmlDocument_createElement} API in that it returns an error code
-   *  describing the reason for failure rather than just {\tt NULL}.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf doc} or 
-   *            {\bf tagName} is {\tt NULL}.
-   *      \item {\tt IXML_INSUFFICIENT_MEMORY}: Not enough free memory exists 
-   *            to complete this operation.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int
-ixmlDocument_createElementEx(IXML_Document *doc,  
-		               /** The owner {\bf Document} of the new node. */
-                             const DOMString tagName,  
-			       /** The tag name of the new {\bf Element} 
-				   node. */
-                             IXML_Element **rtElement
-			       /** Pointer to an {\bf Element} where the new 
-				   object will be stored. */
-                            );
-
-  /** Creates a new {\bf Element} node with the given tag name.  The new
-   *  {\bf Element} node has a {\tt nodeName} of {\bf tagName} and
-   *  the {\tt localName}, {\tt prefix}, and {\tt namespaceURI} set 
-   *  to {\tt NULL}.  To create an {\bf Element} with a namespace, 
-   *  see {\bf ixmlDocument_createElementNS}.
-   *
-   *  @return [Document*] A pointer to the new {\bf Element} or {\tt NULL} on 
-   *                      failure.
-   */
-
-EXPORT_SPEC IXML_Element*
-ixmlDocument_createElement(IXML_Document *doc,  
-		             /** The owner {\bf Document} of the new node. */
-                           const DOMString tagName    
-			     /** The tag name of the new {\bf Element} node. */
-                           );
-
-
-  /** Creates a new {\bf Text} node with the given data.  
-   *  The {\bf ixmlDocument_createTextNodeEx} API differs from the {\bf
-   *  ixmlDocument_createTextNode} API in that it returns an error code
-   *  describing the reason for failure rather than just {\tt NULL}.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf doc} or {\bf data} 
-   *            is {\tt NULL}.
-   *      \item {\tt IXML_INSUFFICIENT_MEMORY}: Not enough free memory exists 
-   *            to complete this operation.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int
-ixmlDocument_createTextNodeEx(IXML_Document *doc,  
-		                /** The owner {\bf Document} of the new node. */
-                              const DOMString data,      
-			        /** The data to associate with the new {\bf 
-				    Text} node. */
-                              IXML_Node** textNode 
-			        /** A pointer to a {\bf Node} where the new 
-				    object will be stored. */
-                              );
-
-
-  /** Creates a new {\bf Text} node with the given data.
-   *
-   *  @return [Node*] A pointer to the new {\bf Node} or {\tt NULL} on failure.
-   */
-
-EXPORT_SPEC IXML_Node*
-ixmlDocument_createTextNode(IXML_Document *doc,  
-		              /** The owner {\bf Document} of the new node. */
-                            const DOMString data       
-			      /** The data to associate with the new {\bf Text} 
-			          node. */
-                            );
-
-  /** Creates a new {\bf CDATASection} node with given data.
-   *
-   *  The {\bf ixmlDocument_createCDATASectionEx} API differs from the {\bf
-   *  ixmlDocument_createCDATASection} API in that it returns an error code
-   *  describing the reason for failure rather than just {\tt NULL}.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf doc} or {\bd data} 
-   *            is {\tt NULL}.
-   *      \item {\tt IXML_INSUFFICIENT_MEMORY}: Not enough free memory exists 
-   *            to complete this operation.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int
-ixmlDocument_createCDATASectionEx(IXML_Document *doc,  
-		                    /** The owner {\bf Document} of the new 
-				        node. */
-                                  const DOMString data,      
-				    /** The data to associate with the new 
-				        {\bf CDATASection} node. */
-                                  IXML_CDATASection** cdNode   
-				    /** A pointer to a {\bf Node} where the 
-				        new object will be stored. */ 
-                                 );
-
-
-  /** Creates a new {\bf CDATASection} node with given data.
-   *
-   *  @return [CDATASection*] A pointer to the new {\bf CDATASection} or 
-   *                          {\tt NULL} on failure.
-   */
-
-EXPORT_SPEC IXML_CDATASection*
-ixmlDocument_createCDATASection(IXML_Document *doc,  
-				  /** The owner {\bf Document} of the new 
-				      node. */
-                                const DOMString data  
-				  /** The data to associate with the new {\bf 
-				      CDATASection} node. */
-                               );
-
-  /** Creates a new {\bf Attr} node with the given name.  
-   *
-   *  @return [Attr*] A pointer to the new {\bf Attr} or {\tt NULL} on failure.
-   */
-
-EXPORT_SPEC IXML_Attr*
-ixmlDocument_createAttribute(IXML_Document *doc,  
-		               /** The owner {\bf Document} of the new node. */
-                             const char *name      
-			       /** The name of the new attribute. */
-                            );
-
-
-  /** Creates a new {\bf Attr} node with the given name.  
-   *
-   *  The {\bf ixmlDocument_createAttributeEx} API differs from the {\bf
-   *  ixmlDocument_createAttribute} API in that it returns an error code
-   *  describing the reason for failure rather than just {\tt NULL}.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf doc} or {\bf name} 
-   *            is {\tt NULL}.
-   *      \item {\tt IXML_INSUFFICIENT_MEMORY}: Not enough free memory exists 
-   *            to complete this operation.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int
-ixmlDocument_createAttributeEx(IXML_Document *doc,  
-		                 /** The owner {\bf Document} of the new 
-				     node. */
-                               const char *name,      
-			         /** The name of the new attribute. */
-                               IXML_Attr** attrNode
-			         /** A pointer to a {\bf Attr} where the new 
-				     object will be stored. */
-                              );
-
-
-  /** Returns a {\bf NodeList} of all {\bf Elements} that match the given
-   *  tag name in the order in which they were encountered in a preorder
-   *  traversal of the {\bf Document} tree.  
-   *
-   *  @return [NodeList*] A pointer to a {\bf NodeList} containing the 
-   *                      matching items or {\tt NULL} on an error.
-   */
-
-EXPORT_SPEC IXML_NodeList*
-ixmlDocument_getElementsByTagName(IXML_Document *doc,     
-		                    /** The {\bf Document} to search. */
-                                  const DOMString tagName  
-				    /** The tag name to find. */
-                                 );
-
-// introduced in DOM level 2
-
-  /** Creates a new {\bf Element} node in the given qualified name and
-   *  namespace URI.
-   *
-   *  The {\bf ixmlDocument_createElementNSEx} API differs from the {\bf
-   *  ixmlDocument_createElementNS} API in that it returns an error code
-   *  describing the reason for failure rather than just {\tt NULL}.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf doc}, 
-   *            {\bf namespaceURI}, or {\bf qualifiedName} is {\tt NULL}.
-   *      \item {\tt IXML_INSUFFICIENT_MEMORY}: Not enough free memory exists 
-   *            to complete this operation.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int
-ixmlDocument_createElementNSEx(IXML_Document *doc,           
-		                 /** The owner {\bf Document} of the new 
-				     node. */
-                               const DOMString namespaceURI,  
-			         /** The namespace URI for the new {\bf 
-				     Element}. */
-                               const DOMString qualifiedName,  
-			         /** The qualified name of the new {\bf 
-				     Element}. */
-                               IXML_Element** rtElement
-			         /** A pointer to an {\bf Element} where the 
-				     new object will be stored. */
-                              );
-
-
-  /** Creates a new {\bf Element} node in the given qualified name and
-   *  namespace URI.
-   *
-   *  @return [Element*] A pointer to the new {\bf Element} or {\tt NULL} on 
-   *                     failure.
-   */
-
-EXPORT_SPEC IXML_Element*
-ixmlDocument_createElementNS(IXML_Document *doc,           
-		               /** The owner {\bf Document} of the new node. */
-                             const DOMString namespaceURI,  
-			       /** The namespace URI for the new {\bf 
-				   Element}. */
-                             const DOMString qualifiedName  
-			       /** The qualified name of the new {\bf 
-				   Element}. */
-                             );
-
-  /** Creates a new {\bf Attr} node with the given qualified name and
-   *  namespace URI.
-   *
-   *  The {\bf ixmlDocument_createAttributeNSEx} API differs from the {\bf
-   *  ixmlDocument_createAttributeNS} API in that it returns an error code
-   *  describing the reason for failure rather than just {\tt NULL}.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf doc}, 
-   *            {\bf namespaceURI}, or {\bf qualifiedName} is {\tt NULL}.
-   *      \item {\tt IXML_INSUFFICIENT_MEMORY}: Not enough free memory exists 
-   *            to complete this operation.
-   *    \end{itemize}   
-   */
-
-EXPORT_SPEC int
-ixmlDocument_createAttributeNSEx(IXML_Document *doc,
-		                   /** The owner {\bf Document} of the new 
-				       {\bf Attr}. */
-                                 const DOMString namespaceURI, 
-				   /** The namespace URI for the attribute. */
-                                 const DOMString qualifiedName, 
-				   /** The qualified name of the attribute. */
-                                 IXML_Attr** attrNode
-				   /** A pointer to an {\bf Attr} where the 
-				       new object will be stored. */
-                                );   
-
-  /** Creates a new {\bf Attr} node with the given qualified name and
-   *  namespace URI.
-   *
-   *  @return [Attr*] A pointer to the new {\bf Attr} or {\tt NULL} on failure.
-   */
-
-EXPORT_SPEC IXML_Attr*
-ixmlDocument_createAttributeNS(IXML_Document *doc, 
-		                 /** The owner {\bf Document} of the new 
-				     {\bf Attr}. */
-                               const DOMString namespaceURI, 
-			         /** The namespace URI for the attribute. */
-                               const DOMString qualifiedName 
-			         /** The qualified name of the attribute. */
-                              );   
-
-  /** Returns a {\bf NodeList} of {\bf Elements} that match the given
-   *  local name and namespace URI in the order they are encountered
-   *  in a preorder traversal of the {\bf Document} tree.  Either 
-   *  {\bf namespaceURI} or {\bf localName} can be the special {\tt "*"}
-   *  character, which matches any namespace or any local name respectively.
-   *
-   *  @return [NodeList*] A pointer to a {\bf NodeList} containing the 
-   *                      matching items or {\tt NULL} on an error.
-   */
-
-EXPORT_SPEC IXML_NodeList*   
-ixmlDocument_getElementsByTagNameNS(IXML_Document* doc,          
-		                      /** The {\bf Document} to search. */
-                                    const DOMString namespaceURI, 
-				      /** The namespace of the elements to 
-                                          find or {\tt "*"} to match any 
-                                          namespace. */
-                                    const DOMString localName     
-				      /** The local name of the elements to 
-                                          find or {\tt "*"} to match any local 
-                                          name.  */
-                                    );
-
-  /** Returns the {\bf Element} whose {\tt ID} matches that given id.
-   *
-   *  @return [Element*] A pointer to the matching {\bf Element} or 
-   *                     {\tt NULL} on an error.
-   */
-
-EXPORT_SPEC IXML_Element*    
-ixmlDocument_getElementById(IXML_Document* doc,         
-		              /** The owner {\bf Document} of the {\bf 
-			          Element}. */
-                            const DOMString tagName  
-			      /** The name of the {\bf Element}.*/
-                            );
-
-  /** Frees a {\bf Document} object and all {\bf Node}s associated with it.  
-   *  Any {\bf Node}s extracted via any other interface function, e.g. 
-   *  {\bf ixmlDocument_GetElementById}, become invalid after this call unless
-   *  explicitly cloned.
-   *
-   *  @return [void] This function does not return a value.
-   */
-
-EXPORT_SPEC void        
-ixmlDocument_free(IXML_Document* doc  
-		    /** The {\bf Document} to free.  */
-                 );
-
-  /** Imports a {\bf Node} from another {\bf Document} into this 
-   *  {\bf Document}.  The new {\bf Node} does not a have parent node: it is a 
-   *  clone of the original {\bf Node} with the {\tt ownerDocument} set to 
-   *  {\bf doc}.  The {\bf deep} parameter controls whether all the children 
-   *  of the {\bf Node} are imported.  Refer to the DOM2-Core recommendation 
-   *  for details on importing specific node types.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf doc} or 
-   *            {\bf importNode} is not a valid pointer.
-   *      \item {\tt IXML_NOT_SUPPORTED_ERR}: {\bf importNode} is a 
-   *            {\bf Document}, which cannot be imported.
-   *      \item {\tt IXML_FAILED}: The import operation failed because the 
-   *            {\bf Node} to be imported could not be cloned.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int         
-ixmlDocument_importNode(IXML_Document* doc,     
-		          /** The {\bf Document} into which to import. */
-                        IXML_Node* importNode,  
-			  /** The {\bf Node} to import. */
-                        BOOL deep,         
-			  /** {\tt TRUE} to import all children of {\bf 
-			      importNode} or {\tt FALSE} to import only the 
-			      root node. */
-                        IXML_Node** rtNode      
-			  /** A pointer to a new {\bf Node} owned by {\bf 
-			      doc}. */
-                       );
-//@}
-
-/*================================================================
-*
-*   Element interfaces
-*
-*
-*=================================================================*/
-
-/**@name Interface {\it Element}
- * The {\bf Element} interface represents an element in an XML document.
- * Only {\bf Element}s are allowed to have attributes, which are stored in the
- * {\tt attributes} member of a {\bf Node}.  The {\bf Element} interface
- * extends the {\bf Node} interface and adds more operations to manipulate
- * attributes.
- */
-//@{
-
-  /** Initializes a {\bf IXML_Element} node.
-   *
-   *  @return [void] This function does not return a value.
-   */
-
-EXPORT_SPEC void ixmlElement_init(IXML_Element *element  
-		        /** The {\bf Element} to initialize.*/
-                     );
-
-
-  /** Returns the name of the tag as a constant string.
-   *
-   *  @return [const DOMString] A {\bf DOMString} representing the name of the 
-   *                            {\bf Element}.
-   */
-
-EXPORT_SPEC const DOMString
-ixmlElement_getTagName(IXML_Element* element  
-		         /** The {\bf Element} from which to retrieve the 
-			     name. */
-                      );
-
-  /** Retrieves an attribute of an {\bf Element} by name.  
-   *
-   *  @return [DOMString] A {\bf DOMString} representing the value of the 
-   *                      attribute.
-   */
-
-EXPORT_SPEC const DOMString   
-ixmlElement_getAttribute(IXML_Element* element,  
-		           /** The {\bf Element} from which to retrieve the 
-			       attribute. */
-                         const DOMString name     
-			   /** The name of the attribute to retrieve. */
-                        );
-
-  /** Adds a new attribute to an {\bf Element}.  If an attribute with the same
-   *  name already exists, the attribute value will be updated with the
-   *  new value in {\bf value}.  
-   *
-   *  @return [int] An integer representing of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf element}, 
-   *            {\bf name}, or {\bf value} is {\tt NULL}.
-   *      \item {\tt IXML_INVALID_CHARACTER_ERR}: {\bf name} contains an 
-   *            illegal character.
-   *      \item {\tt IXML_INSUFFICIENT_MEMORY}: Not enough free memory exists 
-   *            to complete the operation.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int         
-ixmlElement_setAttribute(IXML_Element* element,  
-		           /** The {\bf Element} on which to set the 
-			       attribute. */
-                         const DOMString name,    
-			   /** The name of the attribute. */
-                         const DOMString value
-			   /** The value of the attribute.  Note that this is 
-			       a non-parsed string and any markup must be 
-			       escaped. */
-                        );
-
-  /** Removes an attribute by name.  
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf element} or 
-   *            {\bf name} is {\tt NULL}.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int         
-ixmlElement_removeAttribute(IXML_Element* element,  
-		              /** The {\bf Element} from which to remove the 
-			          attribute. */
-                            const DOMString name     
-			      /** The name of the attribute to remove.  */
-                           );              
-
-  /** Retrieves an attribute node by name.  See 
-   *  {\bf ixmlElement_getAttributeNodeNS} to retrieve an attribute node using
-   *  a qualified name or namespace URI.
-   *
-   *  @return [Attr*] A pointer to the attribute matching {\bf name} or 
-   *                  {\tt NULL} on an error.
-   */
-
-EXPORT_SPEC IXML_Attr*       
-ixmlElement_getAttributeNode(IXML_Element* element,  
-		               /** The {\bf Element} from which to get the 
-				   attribute node.  */
-                             const DOMString name     
-			       /** The name of the attribute node to find. */
-                            );
-
-  /** Adds a new attribute node to an {\bf Element}.  If an attribute already
-   *  exists with {\bf newAttr} as a name, it will be replaced with the
-   *  new one and the old one will be returned in {\bf rtAttr}.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf element} or 
-   *            {\bf newAttr} is {\tt NULL}.
-   *      \item {\tt IXML_WRONG_DOCUMENT_ERR}: {\bf newAttr} does not belong 
-   *            to the same one as {\bf element}.
-   *      \item {\tt IXML_INUSE_ATTRIBUTE_ERR}: {\bf newAttr} is already 
-   *            an attribute of another {\bf Element}.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int         
-ixmlElement_setAttributeNode(IXML_Element* element,  
-		               /** The {\bf Element} in which to add the new 
-				   attribute. */
-                             IXML_Attr* newAttr,     
-			       /** The new {\bf Attr} to add. */
-                             IXML_Attr** rtAttr      
-			       /** A pointer to an {\bf Attr} where the old 
-				   {\bf Attr} will be stored.  This will have  
-				   a {\tt NULL} if no prior node 
-				   existed. */
-                            );
-
-  /** Removes the specified attribute node from an {\bf Element}.  
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf element} or 
-   *            {\bf oldAttr} is {\tt NULL}.
-   *      \item {\tt IXML_NOT_FOUND_ERR}: {\bf oldAttr} is not among the list 
-   *            attributes of {\bf element}.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int         
-ixmlElement_removeAttributeNode(IXML_Element* element,  
-		                  /** The {\bf Element} from which to remove 
-				      the attribute. */
-                                IXML_Attr* oldAttr,     
-				  /** The attribute to remove from the {\bf 
-				      Element}. */
-                                IXML_Attr** rtAttr      
-				  /** A pointer to an attribute in which to 
-				      place the removed attribute. */
-                               );
-
-  /** Returns a {\bf NodeList} of all {\it descendant} {\bf Elements} with
-   *  a given tag name, in the order in which they are encountered in a
-   *  pre-order traversal of this {\bf Element} tree.
-   *
-   *  @return [NodeList*] A {\bf NodeList} of the matching {\bf Element}s or 
-   *                      {\tt NULL} on an error.
-   */
-
-EXPORT_SPEC IXML_NodeList*   
-ixmlElement_getElementsByTagName(IXML_Element* element,  
-		                   /** The {\bf Element} from which to start 
-				       the search. */
-                                 const DOMString tagName
-				   /** The name of the tag for which to 
-				       search. */
-                                );
-
-// introduced in DOM 2
-
-  /** Retrieves an attribute value using the local name and namespace URI.
-   *
-   *  @return [DOMString] A {\bf DOMString} representing the value of the 
-   *                      matching attribute.
-   */
-
-EXPORT_SPEC const DOMString
-ixmlElement_getAttributeNS(IXML_Element* element,       
-		             /** The {\bf Element} from which to get the 
-			         attribute value. */
-                           const DOMString namespaceURI, 
-			     /** The namespace URI of the attribute. */
-                           const DOMString localname     
-			     /** The local name of the attribute. */
-                          );
-
-  /** Adds a new attribute to an {\bf Element} using the local name and 
-   *  namespace URI.  If another attribute matches the same local name and 
-   *  namespace, the prefix is changed to be the prefix part of the 
-   *  {\tt qualifiedName} and the value is changed to {\bf value}.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf element}, 
-   *            {\bf namespaceURI}, {\bf qualifiedName}, or {\bf value} is 
-   *            {\tt NULL}.
-   *      \item {\tt IXML_INVALID_CHARACTER_ERR}: {\bf qualifiedName} contains 
-   *            an invalid character.
-   *      \item {\tt IXML_NAMESPACE_ERR}: Either the {\bf qualifiedName} or 
-   *            {\bf namespaceURI} is malformed.  Refer to the DOM2-Core for 
-   *            possible reasons.
-   *      \item {\tt IXML_INSUFFICIENT_MEMORY}: Not enough free memory exist 
-   *            to complete the operation.
-   *      \item {\tt IXML_FAILED}: The operation could not be completed.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int         
-ixmlElement_setAttributeNS(IXML_Element* element,         
-		             /** The {\bf Element} on which to set the 
-			         attribute. */
-                           const DOMString namespaceURI,   
-		             /** The namespace URI of the new attribute. */
-                           const DOMString qualifiedName,  
-			     /** The qualified name of the attribute. */
-                           const DOMString value 
-			     /** The new value for the attribute. */
-                          );
-
-  /** Removes an attribute using the namespace URI and local name.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf element}, 
-   *            {\bf namespaceURI}, or {\bf localName} is {\tt NULL}.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int         
-ixmlElement_removeAttributeNS(IXML_Element* element,        
-		                /** The {\bf Element} from which to remove the 
-				    the attribute. */
-                              const DOMString namespaceURI,  
-			        /** The namespace URI of the attribute. */
-                              const DOMString localName      
-			        /** The local name of the attribute.*/
-                             );
-
-  /** Retrieves an {\bf Attr} node by local name and namespace URI.
-   *
-   *  @return [Attr*] A pointer to an {\bf Attr} or {\tt NULL} on an error.
-   */
-
-EXPORT_SPEC IXML_Attr*       
-ixmlElement_getAttributeNodeNS(IXML_Element* element,        
-		                 /** The {\bf Element} from which to get the 
-				     attribute. */
-                               const DOMString namespaceURI,  
-			         /** The namespace URI of the attribute. */
-                               const DOMString localName      
-			         /** The local name of the attribute. */
-                              );
-
-  /** Adds a new attribute node.  If an attribute with the same local name
-   *  and namespace URI already exists in the {\bf Element}, the existing 
-   *  attribute node is replaced with {\bf newAttr} and the old returned in 
-   *  {\bf rcAttr}.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: Either {\bf element} or 
-   *            {\bf newAttr} is {\tt NULL}.
-   *      \item {\tt IXML_WRONG_DOCUMENT_ERR}: {\bf newAttr} does not belong 
-   *            to the same document as {\bf element}.
-   *      \item {\tt IXML_INUSE_ATTRIBUTE_ERR}: {\bf newAttr} already is an 
-   *            attribute of another {\bf Element}.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int         
-ixmlElement_setAttributeNodeNS(IXML_Element* element,  
-		                 /** The {\bf Element} in which to add the 
-				     attribute node. */
-                               IXML_Attr*   newAttr,     
-			         /** The new {\bf Attr} to add. */
-                               IXML_Attr**  rcAttr      
-			         /** A pointer to the replaced {\bf Attr}, if 
-				     it exists. */
-                              );
-
-  /** Returns a {\bf NodeList} of all {\it descendant} {\bf Elements} with a
-   *  given tag name, in the order in which they are encountered in the
-   *  pre-order traversal of the {\bf Element} tree.
-   *
-   *  @return [NodeList*] A {\bf NodeList} of matching {\bf Element}s or 
-   *                      {\tt NULL} on an error.
-   */
-
-EXPORT_SPEC IXML_NodeList*   
-ixmlElement_getElementsByTagNameNS(IXML_Element* element,        
-		                     /** The {\bf Element} from which to start 
-				         the search. */
-                                   const DOMString namespaceURI,
-				     /** The namespace URI of the {\bf 
-				         Element}s to find. */
-                                   const DOMString localName      
-				     /** The local name of the {\bf Element}s 
-				         to find. */
-                                  );
-
-  /** Queries whether the {\bf Element} has an attribute with the given name
-   *  or a default value.
-   *
-   *  @return [BOOL] {\tt TRUE} if the {\bf Element} has an attribute with 
-   *                 this name or has a default value for that attribute, 
-   *                 otherwise {\tt FALSE}.
-   */
-
-EXPORT_SPEC BOOL        
-ixmlElement_hasAttribute(IXML_Element* element, 
-		           /** The {\bf Element} on which to check for an 
-			       attribute. */
-                         const DOMString name    
-			   /** The name of the attribute for which to check. */
-                        );
-
-  /** Queries whether the {\bf Element} has an attribute with the given
-   *  local name and namespace URI or has a default value for that attribute.
-   *
-   *  @return [BOOL] {\tt TRUE} if the {\bf Element} has an attribute with 
-   *                 the given namespace and local name or has a default 
-   *                 value for that attribute, otherwise {\tt FALSE}.
-   */
-
-EXPORT_SPEC BOOL        
-ixmlElement_hasAttributeNS(IXML_Element* element,       
-		             /** The {\bf Element} on which to check for the 
-			         attribute. */
-                           const DOMString namespaceURI, 
-			     /** The namespace URI of the attribute. */
-                           const DOMString localName     
-			     /** The local name of the attribute. */
-                          );
-
-  /** Frees the given {\bf Element} and any subtree of the {\bf Element}.
-   *
-   *  @return [void] This function does not return a value.
-   */
-
-EXPORT_SPEC void        
-ixmlElement_free(IXML_Element* element  
-		   /** The {\bf Element} to free. */
-                );
-
-//@}
-
-/*================================================================
-*
-*   NamedNodeMap interfaces
-*
-*
-*=================================================================*/
-
-/**@name Interface {\it NamedNodeMap}
- * A {\bf NamedNodeMap} object represents a list of objects that can be
- * accessed by name.  A {\bf NamedNodeMap} maintains the objects in 
- * no particular order.  The {\bf Node} interface uses a {\bf NamedNodeMap}
- * to maintain the attributes of a node.
- */
-//@{
-
-  /** Returns the number of items contained in this {\bf NamedNodeMap}.
-   *
-   *  @return [unsigned long] The number of nodes in this map.
-   */
-
-EXPORT_SPEC unsigned long 
-ixmlNamedNodeMap_getLength(IXML_NamedNodeMap *nnMap  
-		             /** The {\bf NamedNodeMap} from which to retrieve 
-			         the size. */
-                          );
-
-  /** Retrieves a {\bf Node} from the {\bf NamedNodeMap} by name.
-   *
-   *  @return [Node*] A {\bf Node} or {\tt NULL} if there is an error.
-   */
-
-EXPORT_SPEC IXML_Node*   
-ixmlNamedNodeMap_getNamedItem(IXML_NamedNodeMap *nnMap, 
-		                /** The {\bf NamedNodeMap} to search. */
-                              const DOMString name       
-			        /** The name of the {\bf Node} to find. */
-                             );
-
-  /** Adds a new {\bf Node} to the {\bf NamedNodeMap} using the {\bf Node} 
-   *  name attribute.
-   *
-   *  @return [Node*] The old {\bf Node} if the new {\bf Node} replaces it or 
-   *                  {\tt NULL} if the {\bf Node} was not in the 
-   *                  {\bf NamedNodeMap} before.
-   */
-
-EXPORT_SPEC IXML_Node*   
-ixmlNamedNodeMap_setNamedItem(IXML_NamedNodeMap *nnMap, 
-		                /** The {\bf NamedNodeMap} in which to add the 
-				    new {\bf Node}. */
-                              IXML_Node *arg            
-			        /** The new {\bf Node} to add to the {\bf 
-				    NamedNodeMap}. */
-                             );
-
-  /** Removes a {\bf Node} from a {\bf NamedNodeMap} specified by name.
-   *
-   *  @return [Node*] A pointer to the {\bf Node}, if found, or {\tt NULL} if 
-   *                  it wasn't.
-   */
-
-EXPORT_SPEC IXML_Node*   
-ixmlNamedNodeMap_removeNamedItem(IXML_NamedNodeMap *nnMap,  
-		                   /** The {\bf NamedNodeMap} from which to 
-				       remove the item. */
-                                 const DOMString name        
-				   /** The name of the item to remove. */
-                                );
-
-  /** Retrieves a {\bf Node} from a {\bf NamedNodeMap} specified by a
-   *  numerical index.
-   *
-   *  @return [Node*] A pointer to the {\bf Node}, if found, or {\tt NULL} if 
-   *                  it wasn't.
-   */
-
-EXPORT_SPEC IXML_Node*   
-ixmlNamedNodeMap_item(IXML_NamedNodeMap *nnMap, 
-		        /** The {\bf NamedNodeMap} from which to remove the 
-			    {\bf Node}. */
-                      unsigned long index  
-		        /** The index into the map to remove. */
-                     );
-
-// introduced in DOM level 2
-
-  /** Retrieves a {\bf Node} from a {\bf NamedNodeMap} specified by
-   *  namespace URI and local name.
-   *
-   *  @return [Node*] A pointer to the {\bf Node}, if found, or {\tt NULL} if 
-   *                  it wasn't
-   */
-
-EXPORT_SPEC IXML_Node*   
-ixmlNamedNodeMap_getNamedItemNS(IXML_NamedNodeMap *nnMap,    
-		                  /** The {\bf NamedNodeMap} from which to 
-				      remove the {\bf Node}. */
-                                const DOMString *namespaceURI,
-				  /** The namespace URI of the {\bf Node} to 
-                                      remove. */
-                                const DOMString localName     
-				  /** The local name of the {\bf Node} to 
-				      remove. */
-                               );
-
-  /** Adds a new {\bf Node} to the {\bf NamedNodeMap} using the {\bf Node} 
-   *  local name and namespace URI attributes.
-   *
-   *  @return [Node*] The old {\bf Node} if the new {\bf Node} replaces it or 
-   *                  {\tt NULL} if the {\bf Node} was not in the 
-   *                  {\bf NamedNodeMap} before.
-   */
-
-EXPORT_SPEC IXML_Node*   
-ixmlNamedNodeMap_setNamedItemNS(IXML_NamedNodeMap *nnMap, 
-		                  /** The {\bf NamedNodeMap} in which to add 
-				      the {\bf Node}. */
-                                IXML_Node *arg 
-				  /** The {\bf Node} to add to the map. */
-                               );
-
-  /** Removes a {\bf Node} from a {\bf NamedNodeMap} specified by 
-   *  namespace URI and local name.
-   *
-   *  @return [Node*] A pointer to the {\bf Node}, if found, or {\tt NULL} if 
-   *          it wasn't.
-   */
-
-EXPORT_SPEC IXML_Node*   
-ixmlNamedNodeMap_removeNamedItemNS(IXML_NamedNodeMap *nnMap,    
-		                     /** The {\bf NamedNodeMap} from which to 
-				         remove the {\bf Node}. */
-                                   const DOMString namespaceURI, 
-				     /** The namespace URI of the {\bf Node} 
-				         to remove. */
-                                   const DOMString localName     
-				     /** The local name of the {\bf Node} to 
-				         remove. */
-                                  );
-
-  /** Frees a {\bf NamedNodeMap}.  The {\bf Node}s inside the map are not
-   *  freed, just the {\bf NamedNodeMap} object.
-   *
-   *  @return [void] This function does not return a value.
-   */
-
-EXPORT_SPEC void    
-ixmlNamedNodeMap_free(IXML_NamedNodeMap *nnMap  
-		        /** The {\bf NamedNodeMap to free}. */
-                     );
-
-//@}
-
-/*================================================================
-*
-*   NodeList interfaces
-*
-*
-*=================================================================*/
-
-/**@name Interface {\it NodeList}
- * The {\bf NodeList} interface abstracts an ordered collection of
- * nodes.  Note that changes to the underlying nodes will change
- * the nodes contained in a {\bf NodeList}.  The DOM2-Core refers to
- * this as being {\it live}.
- */
-//@{
-
-  /** Retrieves a {\bf Node} from a {\bf NodeList} specified by a 
-   *  numerical index.
-   *
-   *  @return [Node*] A pointer to a {\bf Node} or {\tt NULL} if there was an 
-   *                  error.
-   */
-
-EXPORT_SPEC IXML_Node*           
-ixmlNodeList_item(IXML_NodeList *nList,     
-		    /** The {\bf NodeList} from which to retrieve the {\bf 
-		        Node}. */
-                  unsigned long index  
-		    /** The index into the {\bf NodeList} to retrieve. */
-                 );
-
-  /** Returns the number of {\bf Nodes} in a {\bf NodeList}.
-   *
-   *  @return [unsigned long] The number of {\bf Nodes} in the {\bf NodeList}.
-   */
-
-EXPORT_SPEC unsigned long   
-ixmlNodeList_length(IXML_NodeList *nList  
-		      /** The {\bf NodeList} for which to retrieve the 
-		          number of {\bf Nodes}. */
-                   );
-
-  /** Frees a {\bf NodeList} object.  Since the underlying {\bf Nodes} are
-   *  references, they are not freed using this operating.  This only
-   *  frees the {\bf NodeList} object.
-   *
-   *  @return [void] This function does not return a value.
-   */
-
-EXPORT_SPEC void            
-ixmlNodeList_free(IXML_NodeList *nList  
-		    /** The {\bf NodeList} to free.  */
-                 );
-
-//@} Interface NodeList
-//@} DOM Interfaces
-
-/**@name IXML API
- * The IXML API contains utility functions that are not part of the standard
- * DOM interfaces.  They include functions to create a DOM structure from a
- * file or buffer, create an XML file from a DOM structure, and manipulate 
- * DOMString objects.
- */
-//@{
-
-/*================================================================
-* 
-*   ixml interfaces
-*
-*
-*=================================================================*/
-
-  /** Renders a {\bf Node} and all sub-elements into an XML document
-   *  representation.  The caller is required to free the {\bf DOMString}
-   *  returned from this function using {\bf ixmlFreeDOMString} when it
-   *  is no longer required.
-   *
-   *  Note that this function can be used for any {\bf Node}-derived
-   *  interface.  The difference between {\bf ixmlPrintDocument} and
-   *  {\bf ixmlPrintNode} is {\bf ixmlPrintDocument} includes the XML prolog
-   *  while {\bf ixmlPrintNode} only produces XML elements. An XML
-   *  document is not well formed unless it includes the prolog
-   *  and at least one element.
-   *
-   *  This function  introduces lots of white space to print the
-   *  {\bf DOMString} in readable  format.
-   * 
-   *  @return [DOMString] A {\bf DOMString} with the XML document representation 
-   *                      of the DOM tree or {\tt NULL} on an error.
-   */
-
-DOMString
-ixmlPrintDocument(IXML_Document *doc);
-
-  /** Renders a {\bf Node} and all sub-elements into an XML text
-   *  representation.  The caller is required to free the {\bf DOMString}
-   *  returned from this function using {\bf ixmlFreeDOMString} when it
-   *  is no longer required.
-   *
-   *  Note that this function can be used for any {\bf Node}-derived
-   *  interface.  A similar {\bf ixmlPrintDocument} function is defined
-   *  to avoid casting when printing whole documents. This function
-   *  introduces lots of white space to print the {\bf DOMString} in readable
-   *  format.
-   * 
-   *  @return [DOMString] A {\bf DOMString} with the XML text representation 
-   *                      of the DOM tree or {\tt NULL} on an error.
-   */
-
-DOMString   
-ixmlPrintNode(IXML_Node *doc  
-                /** The root of the {\bf Node} tree to render to XML text. */
-             );
-
-  /** Renders a {\bf Node} and all sub-elements into an XML document
-   *  representation.  The caller is required to free the {\bf DOMString}
-   *  returned from this function using {\bf ixmlFreeDOMString} when it
-   *  is no longer required.
-   *
-   *  Note that this function can be used for any {\bf Node}-derived
-   *  interface.  The difference between {\bf ixmlDocumenttoString} and
-   *  {\bf ixmlNodetoString} is {\bf ixmlDocumenttoString} includes the XML
-   *  prolog while {\bf ixmlNodetoString} only produces XML elements. An XML
-   *  document is not well formed unless it includes the prolog
-   *  and at least one element.
-   *
-   *  @return [DOMString] A {\bf DOMString} with the XML text representation 
-   *                      of the DOM tree or {\tt NULL} on an error.
-   */
-
-DOMString
-ixmlDocumenttoString(IXML_Document *doc);
-
-  /** Renders a {\bf Node} and all sub-elements into an XML text
-   *  representation.  The caller is required to free the {\bf DOMString}
-   *  returned from this function using {\bf ixmlFreeDOMString} when it
-   *  is no longer required.
-   *
-   *  Note that this function can be used for any {\bf Node}-derived
-   *  interface.  The difference between {\bf ixmlNodetoString} and
-   *  {\bf ixmlDocumenttoString} is {\bf ixmlNodetoString} does not include
-   *  the XML prolog, it only produces XML elements.
-   *
-   *  @return [DOMString] A {\bf DOMString} with the XML text representation 
-   *                      of the DOM tree or {\tt NULL} on an error.
-   */
-
-EXPORT_SPEC DOMString   
-ixmlNodetoString(IXML_Node *doc  
-		   /** The root of the {\bf Node} tree to render to XML text. */
-                );
-
-
-  /** Makes the XML parser more tolerant to malformed text.
-   *       
-   * If {\bf errorChar} is 0 (default), the parser is strict about XML 
-   * encoding : invalid UTF-8 sequences or "&" entities are rejected, and 
-   * the parsing aborts.
-   * If {\bf errorChar} is not 0, the parser is relaxed : invalid UTF-8 
-   * characters are replaced by the {\bf errorChar}, and invalid "&" entities 
-   * are left untranslated. The parsing is then allowed to continue.
-   */
-void
-ixmlRelaxParser(char errorChar);
-
-
-  /** Parses an XML text buffer converting it into an IXML DOM representation.
-   *
-   *  @return [Document*] A {\bf Document} if the buffer correctly parses or 
-   *                      {\tt NULL} on an error. 
-   */
-EXPORT_SPEC IXML_Document*
-ixmlParseBuffer(const char *buffer 
-		  /** The buffer that contains the XML text to convert to a 
-		      {\bf Document}. */
-               );
-
-
-  /** Parses an XML text buffer converting it into an IXML DOM representation.
-   *
-   *  The {\bf ixmlParseBufferEx} API differs from the {\bf ixmlParseBuffer}
-   *  API in that it returns an error code representing the actual failure
-   *  rather than just {\tt NULL}.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: The {\bf buffer} is not a valid 
-   *            pointer.
-   *      \item {\tt IXML_INSUFFICIENT_MEMORY}: Not enough free memory exists 
-   *            to complete this operation.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int
-ixmlParseBufferEx(const char *buffer, 
-		    /** The buffer that contains the XML text to convert to a 
-		        {\bf Document}. */
-                  IXML_Document** doc 
-		    /** A point to store the {\bf Document} if file correctly 
-		        parses or {\bf NULL} on an error. */
-                );
-
-  /** Parses an XML text file converting it into an IXML DOM representation.
-   *
-   *  @return [Document*] A {\bf Document} if the file correctly parses or 
-   *                      {\tt NULL} on an error.
-   */
-
-EXPORT_SPEC IXML_Document*
-ixmlLoadDocument(const char* xmlFile      
-		   /** The filename of the XML text to convert to a {\bf 
-		       Document}. */
-                );
-
-  /** Parses an XML text file converting it into an IXML DOM representation.
-   *
-   *  The {\bf ixmlLoadDocumentEx} API differs from the {\bf ixmlLoadDocument}
-   *  API in that it returns a an error code representing the actual failure
-   *  rather than just {\tt NULL}.
-   *
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt IXML_SUCCESS}: The operation completed successfully.
-   *      \item {\tt IXML_INVALID_PARAMETER}: The {\bf xmlFile} is not a valid 
-   *            pointer.
-   *      \item {\tt IXML_INSUFFICIENT_MEMORY}: Not enough free memory exists 
-   *            to complete this operation.
-   *    \end{itemize}
-   */
-
-EXPORT_SPEC int 
-ixmlLoadDocumentEx(const char* xmlFile,      
-		     /** The filename of the XML text to convert to a {\bf 
-		         Document}. */
-                   IXML_Document** doc   
-		     /** A pointer to the {\bf Document} if file correctly 
-		         parses or {\bf NULL} on an error. */
-                 );
-
-  /** Clones an existing {\bf DOMString}.
-   *
-   *  @return [DOMString] A new {\bf DOMString} that is a duplicate of the 
-   *                      original or {\tt NULL} if the operation could not 
-   *                      be completed.
-   */
-
-EXPORT_SPEC DOMString   
-ixmlCloneDOMString(const DOMString src  
-		     /** The source {\bf DOMString} to clone. */
-                  );
-
-  /** Frees a {\bf DOMString}.
-   *
-   *  @return [void] This function does not return a value.
-   */
-
-EXPORT_SPEC void        
-ixmlFreeDOMString(DOMString buf  
-		    /** The {\bf DOMString} to free. */
-                 );
-
-#ifdef __cplusplus
-}
-#endif
-
-//@} IXML API
-
-#endif  // _IXML_H_
diff --git a/tombupnp/ixml/src/attr.c b/tombupnp/ixml/src/attr.c
deleted file mode 100644
index 4f0732d..0000000
--- a/tombupnp/ixml/src/attr.c
+++ /dev/null
@@ -1,60 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include "ixmlparser.h"
-
-/*================================================================
-*   Function: Attr_init
-*       Initializes an attribute node
-*       External function.
-*
-*=================================================================*/
-void
-ixmlAttr_init( IN IXML_Attr * attr )
-{
-    if( attr != NULL ) {
-        memset( attr, 0, sizeof( IXML_Attr ) );
-    }
-}
-
-/*================================================================
-*   Function: Attr_free
-*       Frees an attribute node.
-*       external function.
-*
-*=================================================================*/
-void
-ixmlAttr_free( IN IXML_Attr * attr )
-{
-    if( attr != NULL ) {
-        ixmlNode_free( ( IXML_Node * ) attr );
-    }
-}
diff --git a/tombupnp/ixml/src/document.c b/tombupnp/ixml/src/document.c
deleted file mode 100644
index 8b03ea2..0000000
--- a/tombupnp/ixml/src/document.c
+++ /dev/null
@@ -1,804 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "ixmlparser.h"
-
-/*================================================================
-*   ixmlDocument_init
-*       It initialize the document structure.
-*       External function.
-*   
-*=================================================================*/
-void
-ixmlDocument_init( IN IXML_Document * doc )
-{
-    memset( doc, 0, sizeof( IXML_Document ) );
-}
-
-/*================================================================
-*   ixmlDocument_free
-*       It frees the whole document tree.
-*       External function.
-*
-*=================================================================*/
-void
-ixmlDocument_free( IN IXML_Document * doc )
-{
-    if( doc != NULL ) {
-        ixmlNode_free( ( IXML_Node * ) doc );
-    }
-
-}
-
-/*================================================================
-*   ixmlDocument_setOwnerDocument
-*       
-*       When this function is called first time, nodeptr is the root
-*       of the subtree, so it is not necessay to do two steps
-*       recursion.
-*        
-*       Internal function called by ixmlDocument_importNode
-*
-*=================================================================*/
-void
-ixmlDocument_setOwnerDocument( IN IXML_Document * doc,
-                               IN IXML_Node * nodeptr )
-{
-    if( nodeptr != NULL ) {
-        nodeptr->ownerDocument = doc;
-        ixmlDocument_setOwnerDocument( doc,
-                                       ixmlNode_getFirstChild( nodeptr ) );
-        ixmlDocument_setOwnerDocument( doc,
-                                       ixmlNode_getNextSibling
-                                       ( nodeptr ) );
-    }
-}
-
-/*================================================================
-*   ixmlDocument_importNode
-*       Imports a node from another document to this document. The
-*       returned node has no parent; (parentNode is null). The source
-*       node is not altered or removed from the original document;
-*       this method creates a new copy of the source node.
- 
-*       For all nodes, importing a node creates a node object owned
-*       by the importing document, with attribute values identical to
-*       the source node's nodeName and nodeType, plus the attributes
-*       related to namespaces (prefix, localName, and namespaceURI).
-*       As in the cloneNode operation on a node, the source node is
-*       not altered.
-*       
-*       External function.
-*
-*=================================================================*/
-int
-ixmlDocument_importNode( IN IXML_Document * doc,
-                         IN IXML_Node * importNode,
-                         IN BOOL deep,
-                         OUT IXML_Node ** rtNode )
-{
-    unsigned short nodeType;
-    IXML_Node *newNode;
-
-    *rtNode = NULL;
-
-    if( ( doc == NULL ) || ( importNode == NULL ) ) {
-        return IXML_INVALID_PARAMETER;
-    }
-
-    nodeType = ixmlNode_getNodeType( importNode );
-    if( nodeType == eDOCUMENT_NODE ) {
-        return IXML_NOT_SUPPORTED_ERR;
-    }
-
-    newNode = ixmlNode_cloneNode( importNode, deep );
-    if( newNode == NULL ) {
-        return IXML_FAILED;
-    }
-
-    ixmlDocument_setOwnerDocument( doc, newNode );
-    *rtNode = newNode;
-
-    return IXML_SUCCESS;
-}
-
-/*================================================================
-*   ixmlDocument_createElementEx
-*       Creates an element of the type specified. 
-*       External function.
-*   Parameters:
-*       doc:        pointer to document
-*       tagName:    The name of the element, it is case-sensitive.
-*   Return Value:
-*       IXML_SUCCESS
-*       IXML_INVALID_PARAMETER:     if either doc or tagName is NULL
-*       IXML_INSUFFICIENT_MEMORY:   if not enough memory to finish this operations.
-*
-*=================================================================*/
-int
-ixmlDocument_createElementEx( IN IXML_Document * doc,
-                              IN const DOMString tagName,
-                              OUT IXML_Element ** rtElement )
-{
-
-    int errCode = IXML_SUCCESS;
-    IXML_Element *newElement = NULL;
-
-    if( ( doc == NULL ) || ( tagName == NULL ) ) {
-        errCode = IXML_INVALID_PARAMETER;
-        goto ErrorHandler;
-    }
-
-    newElement = ( IXML_Element * ) malloc( sizeof( IXML_Element ) );
-    if( newElement == NULL ) {
-        errCode = IXML_INSUFFICIENT_MEMORY;
-        goto ErrorHandler;
-    }
-
-    ixmlElement_init( newElement );
-    newElement->tagName = strdup( tagName );
-    if( newElement->tagName == NULL ) {
-        ixmlElement_free( newElement );
-        newElement = NULL;
-        errCode = IXML_INSUFFICIENT_MEMORY;
-        goto ErrorHandler;
-    }
-    // set the node fields 
-    newElement->n.nodeType = eELEMENT_NODE;
-    newElement->n.nodeName = strdup( tagName );
-    if( newElement->n.nodeName == NULL ) {
-        ixmlElement_free( newElement );
-        newElement = NULL;
-        errCode = IXML_INSUFFICIENT_MEMORY;
-        goto ErrorHandler;
-    }
-
-    newElement->n.ownerDocument = doc;
-
-  ErrorHandler:
-    *rtElement = newElement;
-    return errCode;
-
-}
-
-/*================================================================
-*   ixmlDocument_createElement
-*       Creates an element of the type specified. 
-*       External function.
-*   Parameters:
-*       doc:        pointer to document
-*       tagName:    The name of the element, it is case-sensitive.
-*   Return Value: 
-*       A new element object with the nodeName set to tagName, and
-*       localName, prefix and namespaceURI set to null.
-*
-*=================================================================*/
-IXML_Element *
-ixmlDocument_createElement( IN IXML_Document * doc,
-                            IN const DOMString tagName )
-{
-    IXML_Element *newElement = NULL;
-
-    ixmlDocument_createElementEx( doc, tagName, &newElement );
-    return newElement;
-
-}
-
-/*================================================================
-*   ixmlDocument_createDocumentEx
-*       Creates an document object
-*       Internal function.
-*   Parameters:
-*       rtDoc:  the document created or NULL on failure
-*   Return Value:
-*       IXML_SUCCESS
-*       IXML_INSUFFICIENT_MEMORY:   if not enough memory to finish this operations.
-*
-*=================================================================*/
-int
-ixmlDocument_createDocumentEx( OUT IXML_Document ** rtDoc )
-{
-    IXML_Document *doc;
-    int errCode = IXML_SUCCESS;
-
-    doc = NULL;
-    doc = ( IXML_Document * ) malloc( sizeof( IXML_Document ) );
-    if( doc == NULL ) {
-        errCode = IXML_INSUFFICIENT_MEMORY;
-        goto ErrorHandler;
-    }
-
-    ixmlDocument_init( doc );
-
-    doc->n.nodeName = strdup( DOCUMENTNODENAME );
-    if( doc->n.nodeName == NULL ) {
-        ixmlDocument_free( doc );
-        doc = NULL;
-        errCode = IXML_INSUFFICIENT_MEMORY;
-        goto ErrorHandler;
-    }
-
-    doc->n.nodeType = eDOCUMENT_NODE;
-    doc->n.ownerDocument = doc;
-
-  ErrorHandler:
-    *rtDoc = doc;
-    return errCode;
-}
-
-/*================================================================
-*   ixmlDocument_createDocument
-*       Creates an document object
-*       Internal function.
-*   Parameters:
-*       none
-*   Return Value:
-*       A new document object with the nodeName set to "#document".
-*
-*=================================================================*/
-IXML_Document *
-ixmlDocument_createDocument(  )
-{
-    IXML_Document *doc = NULL;
-
-    ixmlDocument_createDocumentEx( &doc );
-
-    return doc;
-
-}
-
-/*================================================================
-*   ixmlDocument_createTextNodeEx
-*       Creates an text node. 
-*       External function.
-*   Parameters:
-*       data: text data for the text node. It is stored in nodeValue field.
-*   Return Value:
-*       IXML_SUCCESS
-*       IXML_INVALID_PARAMETER:     if either doc or data is NULL
-*       IXML_INSUFFICIENT_MEMORY:   if not enough memory to finish this operations.
-*
-*=================================================================*/
-int
-ixmlDocument_createTextNodeEx( IN IXML_Document * doc,
-                               IN const char *data,
-                               OUT IXML_Node ** textNode )
-{
-    IXML_Node *returnNode;
-    int rc = IXML_SUCCESS;
-
-    returnNode = NULL;
-    if( ( doc == NULL ) || ( data == NULL ) ) {
-        rc = IXML_INVALID_PARAMETER;
-        goto ErrorHandler;
-    }
-
-    returnNode = ( IXML_Node * ) malloc( sizeof( IXML_Node ) );
-    if( returnNode == NULL ) {
-        rc = IXML_INSUFFICIENT_MEMORY;
-        goto ErrorHandler;
-    }
-    // initialize the node
-    ixmlNode_init( returnNode );
-
-    returnNode->nodeName = strdup( TEXTNODENAME );
-    if( returnNode->nodeName == NULL ) {
-        ixmlNode_free( returnNode );
-        returnNode = NULL;
-        rc = IXML_INSUFFICIENT_MEMORY;
-        goto ErrorHandler;
-    }
-    // add in node value
-    if( data != NULL ) {
-        returnNode->nodeValue = strdup( data );
-        if( returnNode->nodeValue == NULL ) {
-            ixmlNode_free( returnNode );
-            returnNode = NULL;
-            rc = IXML_INSUFFICIENT_MEMORY;
-            goto ErrorHandler;
-        }
-    }
-
-    returnNode->nodeType = eTEXT_NODE;
-    returnNode->ownerDocument = doc;
-
-  ErrorHandler:
-    *textNode = returnNode;
-    return rc;
-
-}
-
-/*================================================================
-*   ixmlDocument_createTextNode
-*       Creates an text node. 
-*       External function.
-*   Parameters:
-*       data: text data for the text node. It is stored in nodeValue field.
-*   Return Value:
-*       The new text node.
-*
-*=================================================================*/
-IXML_Node *
-ixmlDocument_createTextNode( IN IXML_Document * doc,
-                             IN const char *data )
-{
-    IXML_Node *returnNode = NULL;
-
-    ixmlDocument_createTextNodeEx( doc, data, &returnNode );
-
-    return returnNode;
-}
-
-/*================================================================
-*   ixmlDocument_createAttributeEx
-*       Creates an attribute of the given name.             
-*       External function.
-*   Parameters:
-*       name: The name of the Attribute node.
-*   Return Value:
-*       IXML_SUCCESS
-*       IXML_INSUFFICIENT_MEMORY:   if not enough memory to finish this operations.
-*
-================================================================*/
-int
-ixmlDocument_createAttributeEx( IN IXML_Document * doc,
-                                IN const char *name,
-                                OUT IXML_Attr ** rtAttr )
-{
-    IXML_Attr *attrNode = NULL;
-    int errCode = IXML_SUCCESS;
-
-    attrNode = ( IXML_Attr * ) malloc( sizeof( IXML_Attr ) );
-    if( attrNode == NULL ) {
-        errCode = IXML_INSUFFICIENT_MEMORY;
-        goto ErrorHandler;
-    }
-
-    if( ( doc == NULL ) || ( name == NULL ) ) {
-        ixmlAttr_free( attrNode );
-        attrNode = NULL;
-        errCode = IXML_INVALID_PARAMETER;
-        goto ErrorHandler;
-    }
-
-    ixmlAttr_init( attrNode );
-
-    attrNode->n.nodeType = eATTRIBUTE_NODE;
-
-    // set the node fields
-    attrNode->n.nodeName = strdup( name );
-    if( attrNode->n.nodeName == NULL ) {
-        ixmlAttr_free( attrNode );
-        attrNode = NULL;
-        errCode = IXML_INSUFFICIENT_MEMORY;
-        goto ErrorHandler;
-    }
-
-    attrNode->n.ownerDocument = doc;
-
-  ErrorHandler:
-    *rtAttr = attrNode;
-    return errCode;
-
-}
-
-/*================================================================
-*   ixmlDocument_createAttribute
-*       Creates an attribute of the given name.             
-*       External function.
-*   Parameters:
-*       name: The name of the Attribute node.
-*   Return Value:   
-*       A new attr object with the nodeName attribute set to the
-*       given name, and the localName, prefix and namespaceURI set to NULL.
-*       The value of the attribute is the empty string.
-*
-================================================================*/
-IXML_Attr *
-ixmlDocument_createAttribute( IN IXML_Document * doc,
-                              IN const char *name )
-{
-    IXML_Attr *attrNode = NULL;
-
-    ixmlDocument_createAttributeEx( doc, name, &attrNode );
-    return attrNode;
-
-}
-
-/*================================================================
-*   ixmlDocument_createAttributeNSEx
-*       Creates an attrbute of the given name and namespace URI
-*       External function.
-*   Parameters:
-*       namespaceURI: the namespace fo the attribute to create
-*       qualifiedName: qualifiedName of the attribute to instantiate
-*   Return Value:
-*       IXML_SUCCESS
-*       IXML_INVALID_PARAMETER:     if either doc,namespaceURI or qualifiedName is NULL
-*       IXML_INSUFFICIENT_MEMORY:   if not enough memory to finish this operations.
-*
-*=================================================================*/
-int
-ixmlDocument_createAttributeNSEx( IN IXML_Document * doc,
-                                  IN const DOMString namespaceURI,
-                                  IN const DOMString qualifiedName,
-                                  OUT IXML_Attr ** rtAttr )
-{
-    IXML_Attr *attrNode = NULL;
-    int errCode = IXML_SUCCESS;
-
-    if( ( doc == NULL ) || ( namespaceURI == NULL )
-        || ( qualifiedName == NULL ) ) {
-        errCode = IXML_INVALID_PARAMETER;
-        goto ErrorHandler;
-    }
-
-    errCode =
-        ixmlDocument_createAttributeEx( doc, qualifiedName, &attrNode );
-    if( errCode != IXML_SUCCESS ) {
-        goto ErrorHandler;
-    }
-    // set the namespaceURI field 
-    attrNode->n.namespaceURI = strdup( namespaceURI );
-    if( attrNode->n.namespaceURI == NULL ) {
-        ixmlAttr_free( attrNode );
-        attrNode = NULL;
-        errCode = IXML_INSUFFICIENT_MEMORY;
-        goto ErrorHandler;
-    }
-    // set the localName and prefix 
-    errCode =
-        ixmlNode_setNodeName( ( IXML_Node * ) attrNode, qualifiedName );
-    if( errCode != IXML_SUCCESS ) {
-        ixmlAttr_free( attrNode );
-        attrNode = NULL;
-        goto ErrorHandler;
-    }
-
-  ErrorHandler:
-    *rtAttr = attrNode;
-    return errCode;
-
-}
-
-/*================================================================
-*   ixmlDocument_createAttributeNS
-*       Creates an attrbute of the given name and namespace URI
-*       External function.
-*   Parameters:
-*       namespaceURI: the namespace fo the attribute to create
-*       qualifiedName: qualifiedName of the attribute to instantiate
-*   Return Value:   
-*       Creates an attribute node with the given namespaceURI and
-*       qualifiedName. The prefix and localname are extracted from 
-*       the qualifiedName. The node value is empty.
-*	
-*=================================================================*/
-IXML_Attr *
-ixmlDocument_createAttributeNS( IN IXML_Document * doc,
-                                IN const DOMString namespaceURI,
-                                IN const DOMString qualifiedName )
-{
-    IXML_Attr *attrNode = NULL;
-
-    ixmlDocument_createAttributeNSEx( doc, namespaceURI, qualifiedName,
-                                      &attrNode );
-    return attrNode;
-}
-
-/*================================================================
-*   ixmlDocument_createCDATASectionEx
-*       Creates an CDATASection node whose value is the specified string
-*       External function.
-*   Parameters:
-*       data: the data for the CDATASection contents.
-*   Return Value:
-*       IXML_SUCCESS
-*       IXML_INVALID_PARAMETER:     if either doc or data is NULL
-*       IXML_INSUFFICIENT_MEMORY:   if not enough memory to finish this operations.
-*
-*=================================================================*/
-int
-ixmlDocument_createCDATASectionEx( IN IXML_Document * doc,
-                                   IN const DOMString data,
-                                   OUT IXML_CDATASection ** rtCD )
-{
-    int errCode = IXML_SUCCESS;
-    IXML_CDATASection *cDSectionNode = NULL;
-
-    if( ( doc == NULL ) || ( data == NULL ) ) {
-        errCode = IXML_INVALID_PARAMETER;
-        goto ErrorHandler;
-    }
-
-    cDSectionNode =
-        ( IXML_CDATASection * ) malloc( sizeof( IXML_CDATASection ) );
-    if( cDSectionNode == NULL ) {
-        errCode = IXML_INSUFFICIENT_MEMORY;
-        goto ErrorHandler;
-    }
-
-    ixmlCDATASection_init( cDSectionNode );
-
-    cDSectionNode->n.nodeType = eCDATA_SECTION_NODE;
-    cDSectionNode->n.nodeName = strdup( CDATANODENAME );
-    if( cDSectionNode->n.nodeName == NULL ) {
-        ixmlCDATASection_free( cDSectionNode );
-        cDSectionNode = NULL;
-        errCode = IXML_INSUFFICIENT_MEMORY;
-        goto ErrorHandler;
-    }
-
-    cDSectionNode->n.nodeValue = strdup( data );
-    if( cDSectionNode->n.nodeValue == NULL ) {
-        ixmlCDATASection_free( cDSectionNode );
-        cDSectionNode = NULL;
-        errCode = IXML_INSUFFICIENT_MEMORY;
-        goto ErrorHandler;
-    }
-
-    cDSectionNode->n.ownerDocument = doc;
-
-  ErrorHandler:
-    *rtCD = cDSectionNode;
-    return errCode;
-
-}
-
-/*================================================================
-*   ixmlDocument_createCDATASection
-*       Creates an CDATASection node whose value is the specified string
-*       External function.
-*   Parameters:
-*       data: the data for the CDATASection contents.
-*   Return Value:   
-*       The new CDATASection object.
-*	
-*=================================================================*/
-IXML_CDATASection *
-ixmlDocument_createCDATASection( IN IXML_Document * doc,
-                                 IN const DOMString data )
-{
-
-    IXML_CDATASection *cDSectionNode = NULL;
-
-    ixmlDocument_createCDATASectionEx( doc, data, &cDSectionNode );
-    return cDSectionNode;
-}
-
-/*================================================================
-*   ixmlDocument_createElementNSEx
-*       Creates an element of the given qualified name and namespace URI.
-*       External function.
-*   Parameters:
-*       namespaceURI: the namespace URI of the element to create.
-*       qualifiedName: the qualified name of the element to instantiate.
-*   Return Value:   
-*   Return Value:
-*       IXML_SUCCESS
-*       IXML_INVALID_PARAMETER:     if either doc,namespaceURI or qualifiedName is NULL
-*       IXML_INSUFFICIENT_MEMORY:   if not enough memory to finish this operations.
-*
-*=================================================================*/
-int
-ixmlDocument_createElementNSEx( IN IXML_Document * doc,
-                                IN const DOMString namespaceURI,
-                                IN const DOMString qualifiedName,
-                                OUT IXML_Element ** rtElement )
-{
-
-    IXML_Element *newElement = NULL;
-    int errCode = IXML_SUCCESS;
-
-    if( ( doc == NULL ) || ( namespaceURI == NULL )
-        || ( qualifiedName == NULL ) ) {
-        errCode = IXML_INVALID_PARAMETER;
-        goto ErrorHandler;
-    }
-
-    errCode =
-        ixmlDocument_createElementEx( doc, qualifiedName, &newElement );
-    if( errCode != IXML_SUCCESS ) {
-        goto ErrorHandler;
-    }
-    // set the namespaceURI field 
-    newElement->n.namespaceURI = strdup( namespaceURI );
-    if( newElement->n.namespaceURI == NULL ) {
-        ixmlElement_free( newElement );
-        newElement = NULL;
-        errCode = IXML_INSUFFICIENT_MEMORY;
-        goto ErrorHandler;
-    }
-    // set the localName and prefix 
-    errCode =
-        ixmlNode_setNodeName( ( IXML_Node * ) newElement, qualifiedName );
-    if( errCode != IXML_SUCCESS ) {
-        ixmlElement_free( newElement );
-        newElement = NULL;
-        errCode = IXML_INSUFFICIENT_MEMORY;
-        goto ErrorHandler;
-    }
-
-    newElement->n.nodeValue = NULL;
-
-  ErrorHandler:
-    *rtElement = newElement;
-    return errCode;
-
-}
-
-/*================================================================
-*   ixmlDocument_createElementNS
-*       Creates an element of the given qualified name and namespace URI.
-*       External function.
-*   Parameters:
-*       namespaceURI: the namespace URI of the element to create.
-*       qualifiedName: the qualified name of the element to instantiate.
-*   Return Value:   
-*       The new element object with tagName qualifiedName, prefix and
-*       localName extraced from qualfiedName, nodeName of qualfiedName,
-*	    namespaceURI of namespaceURI.
-*
-*=================================================================*/
-IXML_Element *
-ixmlDocument_createElementNS( IN IXML_Document * doc,
-                              IN const DOMString namespaceURI,
-                              IN const DOMString qualifiedName )
-{
-    IXML_Element *newElement = NULL;
-
-    ixmlDocument_createElementNSEx( doc, namespaceURI, qualifiedName,
-                                    &newElement );
-    return newElement;
-}
-
-/*================================================================
-*   ixmlDocument_getElementsByTagName
-*       Returns a nodeList of all the Elements with a given tag name
-*       in the order in which they are encountered in a preorder traversal
-*       of the document tree.
-*       External function.
-*   Parameters:
-*       tagName: the name of the tag to match on. The special value "*"
-*                matches all tags.
-*   Return Value:
-*       A new nodeList object containing all the matched Elements.    
-*
-*=================================================================*/
-IXML_NodeList *
-ixmlDocument_getElementsByTagName( IN IXML_Document * doc,
-                                   IN const char *tagName )
-{
-    IXML_NodeList *returnNodeList = NULL;
-
-    if( ( doc == NULL ) || ( tagName == NULL ) ) {
-        return NULL;
-    }
-
-    ixmlNode_getElementsByTagName( ( IXML_Node * ) doc, tagName,
-                                   &returnNodeList );
-    return returnNodeList;
-}
-
-/*================================================================
-*   ixmlDocument_getElementsByTagNameNS
-*       Returns a nodeList of all the Elements with a given local name and
-*       namespace URI in the order in which they are encountered in a 
-*       preorder traversal of the document tree.
-*       External function.
-*   Parameters:
-*       namespaceURI: the namespace of the elements to match on. The special
-*               value "*" matches all namespaces.
-*       localName: the local name of the elements to match on. The special
-*               value "*" matches all local names.
-*   Return Value:
-*       A new nodeList object containing all the matched Elements.    
-*
-*=================================================================*/
-IXML_NodeList *
-ixmlDocument_getElementsByTagNameNS( IN IXML_Document * doc,
-                                     IN const DOMString namespaceURI,
-                                     IN const DOMString localName )
-{
-    IXML_NodeList *returnNodeList = NULL;
-
-    if( ( doc == NULL ) || ( namespaceURI == NULL )
-        || ( localName == NULL ) ) {
-        return NULL;
-    }
-
-    ixmlNode_getElementsByTagNameNS( ( IXML_Node * ) doc, namespaceURI,
-                                     localName, &returnNodeList );
-    return returnNodeList;
-}
-
-/*================================================================
-*   ixmlDocument_getElementById
-*       Returns the element whose ID is given by tagName. If no such
-*       element exists, returns null. 
-*       External function.
-*   Parameter:
-*       tagName: the tag name for an element.
-*   Return Values:
-*       The matching element.
-*
-*=================================================================*/
-IXML_Element *
-ixmlDocument_getElementById( IN IXML_Document * doc,
-                             IN const DOMString tagName )
-{
-    IXML_Element *rtElement = NULL;
-    IXML_Node *nodeptr = ( IXML_Node * ) doc;
-    const char *name;
-
-    if( ( nodeptr == NULL ) || ( tagName == NULL ) ) {
-        return rtElement;
-    }
-
-    if( ixmlNode_getNodeType( nodeptr ) == eELEMENT_NODE ) {
-        name = ixmlNode_getNodeName( nodeptr );
-        if( name == NULL ) {
-            return rtElement;
-        }
-
-        if( strcmp( tagName, name ) == 0 ) {
-            rtElement = ( IXML_Element * ) nodeptr;
-            return rtElement;
-        } else {
-            rtElement = ixmlDocument_getElementById( ( IXML_Document * )
-                                                     ixmlNode_getFirstChild
-                                                     ( nodeptr ),
-                                                     tagName );
-            if( rtElement == NULL ) {
-                rtElement = ixmlDocument_getElementById( ( IXML_Document
-                                                           * )
-                                                         ixmlNode_getNextSibling
-                                                         ( nodeptr ),
-                                                         tagName );
-            }
-        }
-    } else {
-        rtElement = ixmlDocument_getElementById( ( IXML_Document * )
-                                                 ixmlNode_getFirstChild
-                                                 ( nodeptr ), tagName );
-        if( rtElement == NULL ) {
-            rtElement = ixmlDocument_getElementById( ( IXML_Document * )
-                                                     ixmlNode_getNextSibling
-                                                     ( nodeptr ),
-                                                     tagName );
-        }
-    }
-
-    return rtElement;
-}
diff --git a/tombupnp/ixml/src/element.c b/tombupnp/ixml/src/element.c
deleted file mode 100644
index 524d9b6..0000000
--- a/tombupnp/ixml/src/element.c
+++ /dev/null
@@ -1,969 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include "ixmlparser.h"
-
-/*================================================================
-*   ixmlElement_Init
-*       Initializes an element node.
-*       External function.
-*
-*=================================================================*/
-void
-ixmlElement_init( IN IXML_Element * element )
-{
-    if( element != NULL ) {
-        memset( element, 0, sizeof( IXML_Element ) );
-    }
-}
-
-/*================================================================
-*   ixmlElement_getTagName
-*       Gets the element node's tagName
-*       External function.
-*
-*=================================================================*/
-const DOMString
-ixmlElement_getTagName( IN IXML_Element * element )
-{
-
-    if( element != NULL ) {
-        return element->tagName;
-    } else {
-        return NULL;
-    }
-}
-
-/*================================================================
-*   ixmlElement_setTagName
-*       Sets the given element's tagName.
-*   Parameters:
-*       tagName: new tagName for the element.
-*
-*=================================================================*/
-int
-ixmlElement_setTagName( IN IXML_Element * element,
-                        IN const char *tagName )
-{
-    int rc = IXML_SUCCESS;
-
-    assert( ( element != NULL ) && ( tagName != NULL ) );
-    if( ( element == NULL ) || ( tagName == NULL ) ) {
-        return IXML_FAILED;
-    }
-
-    if( element->tagName != NULL ) {
-        free( element->tagName );
-    }
-
-    element->tagName = strdup( tagName );
-    if( element->tagName == NULL ) {
-        rc = IXML_INSUFFICIENT_MEMORY;
-    }
-
-    return rc;
-
-}
-
-/*================================================================
-*   ixmlElement_getAttribute
-*       Retrievea an attribute value by name.
-*       External function.
-*   Parameters:
-*       name: the name of the attribute to retrieve.
-*   Return Values:
-*       attribute value as a string, or the empty string if that attribute
-*       does not have a specified value.
-*
-*=================================================================*/
-const DOMString
-ixmlElement_getAttribute( IN IXML_Element * element,
-                          IN const DOMString name )
-{
-    IXML_Node *attrNode;
-
-    if( ( element == NULL ) || ( name == NULL ) ) {
-        return NULL;
-    }
-
-    attrNode = element->n.firstAttr;
-    while( attrNode != NULL ) {
-        if( strcmp( attrNode->nodeName, name ) == 0 ) { // found it
-            return attrNode->nodeValue;
-        } else {
-            attrNode = attrNode->nextSibling;
-        }
-    }
-
-    return NULL;
-}
-
-/*================================================================
-*   ixmlElement_setAttribute
-*       Adds a new attribute.  If an attribute with that name is already
-*       present in the element, its value is changed to be that of the value
-*       parameter. If not, a new attribute is inserted into the element.
-*
-*       External function.
-*   Parameters:
-*       name: the name of the attribute to create or alter.
-*       value: value to set in string form
-*   Return Values:
-*       IXML_SUCCESS or failure code.    
-*
-*=================================================================*/
-int
-ixmlElement_setAttribute( IN IXML_Element * element,
-                          IN const char *name,
-                          IN const char *value )
-{
-    IXML_Node *attrNode;
-    IXML_Attr *newAttrNode;
-    short errCode = IXML_SUCCESS;
-
-    if( ( element == NULL ) || ( name == NULL ) || ( value == NULL ) ) {
-        errCode = IXML_INVALID_PARAMETER;
-        goto ErrorHandler;
-    }
-
-    if( Parser_isValidXmlName( name ) == FALSE ) {
-        errCode = IXML_INVALID_CHARACTER_ERR;
-        goto ErrorHandler;
-    }
-
-    attrNode = element->n.firstAttr;
-    while( attrNode != NULL ) {
-        if( strcmp( attrNode->nodeName, name ) == 0 ) {
-            break;              //found it
-        } else {
-            attrNode = attrNode->nextSibling;
-        }
-    }
-
-    if( attrNode == NULL ) {    // add a new attribute
-        errCode =
-            ixmlDocument_createAttributeEx( ( IXML_Document * ) element->n.
-                                            ownerDocument, name,
-                                            &newAttrNode );
-        if( errCode != IXML_SUCCESS ) {
-            goto ErrorHandler;
-        }
-
-        attrNode = ( IXML_Node * ) newAttrNode;
-
-        attrNode->nodeValue = strdup( value );
-        if( attrNode->nodeValue == NULL ) {
-            ixmlAttr_free( newAttrNode );
-            errCode = IXML_INSUFFICIENT_MEMORY;
-            goto ErrorHandler;
-        }
-
-        errCode =
-            ixmlElement_setAttributeNode( element, newAttrNode, NULL );
-        if( errCode != IXML_SUCCESS ) {
-            ixmlAttr_free( newAttrNode );
-            goto ErrorHandler;
-        }
-
-    } else {
-        if( attrNode->nodeValue != NULL ) { // attribute name has a value already
-            free( attrNode->nodeValue );
-        }
-
-        attrNode->nodeValue = strdup( value );
-        if( attrNode->nodeValue == NULL ) {
-            errCode = IXML_INSUFFICIENT_MEMORY;
-        }
-    }
-
-  ErrorHandler:
-    return errCode;
-}
-
-/*================================================================
-*   ixmlElement_removeAttribute
-*       Removes an attribute value by name. The attribute node is
-*       not removed.
-*       External function.
-*   Parameters:
-*       name: the name of the attribute to remove.
-*   Return Values:
-*       IXML_SUCCESS or error code.
-*
-*=================================================================*/
-int
-ixmlElement_removeAttribute( IN IXML_Element * element,
-                             IN const char *name )
-{
-
-    IXML_Node *attrNode;
-
-    if( ( element == NULL ) || ( name == NULL ) ) {
-        return IXML_INVALID_PARAMETER;
-    }
-
-    attrNode = element->n.firstAttr;
-    while( attrNode != NULL ) {
-        if( strcmp( attrNode->nodeName, name ) == 0 ) {
-            break;              //found it
-        } else {
-            attrNode = attrNode->nextSibling;
-        }
-    }
-
-    if( attrNode != NULL ) {    // has the attribute
-        if( attrNode->nodeValue != NULL ) {
-            free( attrNode->nodeValue );
-            attrNode->nodeValue = NULL;
-        }
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*================================================================
-*   ixmlElement_getAttributeNode
-*       Retrieve an attribute node by name.
-*       External function.        
-*   Parameters:
-*       name: the name(nodeName) of the attribute to retrieve.
-*   Return Value:
-*       The attr node with the specified name (nodeName) or NULL if
-*       there is no such attribute.  
-*
-*=================================================================*/
-IXML_Attr *
-ixmlElement_getAttributeNode( IN IXML_Element * element,
-                              IN const char *name )
-{
-
-    IXML_Node *attrNode;
-
-    if( ( element == NULL ) || ( name == NULL ) ) {
-        return NULL;
-    }
-
-    attrNode = element->n.firstAttr;
-    while( attrNode != NULL ) {
-        if( strcmp( attrNode->nodeName, name ) == 0 ) { // found it
-            break;
-        } else {
-            attrNode = attrNode->nextSibling;
-        }
-    }
-
-    return ( IXML_Attr * ) attrNode;
-
-}
-
-/*================================================================
-*   ixmlElement_setAttributeNode
-*       Adds a new attribute node.  If an attribute with that name(nodeName)
-*       is already present in the element, it is replaced by the new one.
-*       External function.
-*   Parameters:
-*       The attr node to add to the attribute list.
-*   Return Value:
-*       if newAttr replaces an existing attribute, the replaced
-*       attr node is returned, otherwise NULL is returned.           
-*
-*=================================================================*/
-int
-ixmlElement_setAttributeNode( IN IXML_Element * element,
-                              IN IXML_Attr * newAttr,
-                              OUT IXML_Attr ** rtAttr )
-{
-
-    IXML_Node *attrNode;
-    IXML_Node *node;
-    IXML_Node *nextAttr = NULL;
-    IXML_Node *prevAttr = NULL;
-    IXML_Node *preSib,
-     *nextSib;
-
-    if( ( element == NULL ) || ( newAttr == NULL ) ) {
-        return IXML_INVALID_PARAMETER;
-    }
-
-    if( newAttr->n.ownerDocument != element->n.ownerDocument ) {
-        return IXML_WRONG_DOCUMENT_ERR;
-    }
-
-    if( newAttr->ownerElement != NULL ) {
-        return IXML_INUSE_ATTRIBUTE_ERR;
-    }
-
-    newAttr->ownerElement = element;
-    node = ( IXML_Node * ) newAttr;
-
-    attrNode = element->n.firstAttr;
-    while( attrNode != NULL ) {
-        if( strcmp( attrNode->nodeName, node->nodeName ) == 0 ) {
-            break;              //found it
-        } else {
-            attrNode = attrNode->nextSibling;
-        }
-    }
-
-    if( attrNode != NULL )      // already present, will replace by newAttr
-    {
-        preSib = attrNode->prevSibling;
-        nextSib = attrNode->nextSibling;
-
-        if( preSib != NULL ) {
-            preSib->nextSibling = node;
-        }
-
-        if( nextSib != NULL ) {
-            nextSib->prevSibling = node;
-        }
-
-        if( element->n.firstAttr == attrNode ) {
-            element->n.firstAttr = node;
-        }
-
-        if( rtAttr != NULL ) {
-            *rtAttr = ( IXML_Attr * ) attrNode;
-        }
-    } else                      // add this attribute 
-    {
-        if( element->n.firstAttr != NULL ) {
-            prevAttr = element->n.firstAttr;
-            nextAttr = prevAttr->nextSibling;
-            while( nextAttr != NULL ) {
-                prevAttr = nextAttr;
-                nextAttr = prevAttr->nextSibling;
-            }
-            prevAttr->nextSibling = node;
-            node->prevSibling = prevAttr;
-        } else                  // this is the first attribute node
-        {
-            element->n.firstAttr = node;
-            node->prevSibling = NULL;
-            node->nextSibling = NULL;
-        }
-
-        if( rtAttr != NULL ) {
-            *rtAttr = NULL;
-        }
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*================================================================
-*   ixmlElement_findAttributeNode
-*       Find a attribute node whose contents are the same as the oldAttr.
-*       Internal only to parser.
-*   Parameter:
-*       oldAttr: the attribute node to match
-*   Return:
-*       if found it, the attribute node is returned,
-*       otherwise, return NULL.
-*
-*=================================================================*/
-IXML_Node *
-ixmlElement_findAttributeNode( IN IXML_Element * element,
-                               IN IXML_Attr * oldAttr )
-{
-    IXML_Node *attrNode;
-    IXML_Node *oldAttrNode = ( IXML_Node * ) oldAttr;
-
-    assert( ( element != NULL ) && ( oldAttr != NULL ) );
-
-    attrNode = element->n.firstAttr;
-    while( attrNode != NULL ) { // parentNode, prevSib, nextSib and ownerDocument doesn't matter
-        if( ixmlNode_compare( attrNode, oldAttrNode ) == TRUE ) {
-            break;              //found it
-        } else {
-            attrNode = attrNode->nextSibling;
-        }
-    }
-
-    return attrNode;
-
-}
-
-/*================================================================
-*   ixmlElement_removeAttributeNode	
-*       Removes the specified attribute node.
-*       External function.
-*
-*   Parameters:
-*       oldAttr: the attr node to remove from the attribute list.
-*       
-*   Return Value:
-*       IXML_SUCCESS or failure
-*
-*=================================================================*/
-int
-ixmlElement_removeAttributeNode( IN IXML_Element * element,
-                                 IN IXML_Attr * oldAttr,
-                                 OUT IXML_Attr ** rtAttr )
-{
-    IXML_Node *attrNode;
-    IXML_Node *preSib,
-     *nextSib;
-
-    if( ( element == NULL ) || ( oldAttr == NULL ) ) {
-        return IXML_INVALID_PARAMETER;
-    }
-
-    attrNode = ixmlElement_findAttributeNode( element, oldAttr );
-    if( attrNode != NULL ) {    // has the attribute
-        preSib = attrNode->prevSibling;
-        nextSib = attrNode->nextSibling;
-
-        if( preSib != NULL ) {
-            preSib->nextSibling = nextSib;
-        }
-
-        if( nextSib != NULL ) {
-            nextSib->prevSibling = preSib;
-        }
-
-        if( element->n.firstAttr == attrNode ) {
-            element->n.firstAttr = nextSib;
-        }
-
-        /* ( IXML_Attr * ) */ attrNode->parentNode = NULL;
-        /* ( IXML_Attr * ) */ attrNode->prevSibling = NULL;
-        /* ( IXML_Attr * ) */ attrNode->nextSibling = NULL;
-        *rtAttr = ( IXML_Attr * ) attrNode;
-        return IXML_SUCCESS;
-
-    } else {
-        return IXML_NOT_FOUND_ERR;
-    }
-
-}
-
-/*================================================================
-*   ixmlElement_getElementsByTagName
-*       Returns a nodeList of all descendant Elements with a given
-*       tag name, in the order in which they are encountered in a preorder
-*       traversal of this element tree.
-*       External function.
-*
-*   Parameters:
-*       tagName: the name of the tag to match on. The special value "*"
-*       matches all tags.
-*
-*   Return Value:
-*       a nodeList of matching element nodes.
-*
-*=================================================================*/
-IXML_NodeList *
-ixmlElement_getElementsByTagName( IN IXML_Element * element,
-                                  IN const char *tagName )
-{
-    IXML_NodeList *returnNodeList = NULL;
-
-    if( ( element != NULL ) && ( tagName != NULL ) ) {
-        ixmlNode_getElementsByTagName( ( IXML_Node * ) element, tagName,
-                                       &returnNodeList );
-    }
-    return returnNodeList;
-}
-
-/*================================================================
-*   ixmlElement_getAttributeNS
-*       Retrieves an attribute value by local name and namespace URI.
-*       External function.
-*
-*   Parameters:
-*       namespaceURI: the namespace URI of the attribute to retrieve.
-*       localName: the local name of the attribute to retrieve.
-*
-*   Return Value:
-*       the attr value as a string, or NULL if that attribute does
-*       not have the specified value.
-*
-*=================================================================*/
-const DOMString
-ixmlElement_getAttributeNS( IN IXML_Element * element,
-                            IN const DOMString namespaceURI,
-                            IN const DOMString localName )
-{
-    IXML_Node *attrNode;
-
-    if( ( element == NULL ) || ( namespaceURI == NULL )
-        || ( localName == NULL ) ) {
-        return NULL;
-    }
-
-    attrNode = element->n.firstAttr;
-    while( attrNode != NULL ) {
-        if( strcmp( attrNode->localName, localName ) == 0 && strcmp( attrNode->namespaceURI, namespaceURI ) == 0 ) {    // found it
-            return attrNode->nodeValue;
-        } else {
-            attrNode = attrNode->nextSibling;
-        }
-    }
-
-    return NULL;
-
-}
-
-/*================================================================
-*   ixmlElement_setAttributeNS
-*       Adds a new attribute. If an attribute with the same local name
-*       and namespace URI is already present on the element, its prefix
-*       is changed to be the prefix part of the qualifiedName, and its
-*       value is changed to be the value parameter.  This value is a
-*       simple string.
-*       External function.
-*
-*   Parameter:
-*       namespaceURI: the namespace of the attribute to create or alter.
-*       qualifiedName: the qualified name of the attribute to create or alter.
-*       value: the value to set in string form.
-*
-*   Return Value:
-*       IXML_SUCCESS or failure 
-*
-*=================================================================*/
-int
-ixmlElement_setAttributeNS( IN IXML_Element * element,
-                            IN const DOMString namespaceURI,
-                            IN const DOMString qualifiedName,
-                            IN const DOMString value )
-{
-    IXML_Node *attrNode = NULL;
-    IXML_Node newAttrNode;
-    IXML_Attr *newAttr;
-    int rc;
-
-    if( ( element == NULL ) || ( namespaceURI == NULL ) ||
-        ( qualifiedName == NULL ) || ( value == NULL ) ) {
-        return IXML_INVALID_PARAMETER;
-    }
-
-    if( Parser_isValidXmlName( qualifiedName ) == FALSE ) {
-        return IXML_INVALID_CHARACTER_ERR;
-    }
-
-    ixmlNode_init( &newAttrNode );
-
-    newAttrNode.nodeName = strdup( qualifiedName );
-    if( newAttrNode.nodeName == NULL ) {
-        return IXML_INSUFFICIENT_MEMORY;
-    }
-
-    rc = Parser_setNodePrefixAndLocalName( &newAttrNode );
-    if( rc != IXML_SUCCESS ) {
-        Parser_freeNodeContent( &newAttrNode );
-        return rc;
-    }
-    // see DOM 2 spec page 59
-    if( ( newAttrNode.prefix != NULL && namespaceURI == NULL ) ||
-        ( strcmp( newAttrNode.prefix, "xml" ) == 0 &&
-          strcmp( namespaceURI,
-                  "http://www.w3.org/XML/1998/namespace" ) != 0 )
-        || ( strcmp( qualifiedName, "xmlns" ) == 0
-             && strcmp( namespaceURI,
-                        "http://www.w3.org/2000/xmlns/" ) != 0 ) ) {
-        Parser_freeNodeContent( &newAttrNode );
-        return IXML_NAMESPACE_ERR;
-    }
-
-    attrNode = element->n.firstAttr;
-    while( attrNode != NULL ) {
-        if( strcmp( attrNode->localName, newAttrNode.localName ) == 0 &&
-            strcmp( attrNode->namespaceURI, namespaceURI ) == 0 ) {
-            break;              //found it
-        } else {
-            attrNode = attrNode->nextSibling;
-        }
-    }
-
-    if( attrNode != NULL ) {
-        if( attrNode->prefix != NULL ) {
-            free( attrNode->prefix );   // remove the old prefix
-        }
-        // replace it with the new prefix
-        attrNode->prefix = strdup( newAttrNode.prefix );
-        if( attrNode->prefix == NULL ) {
-            Parser_freeNodeContent( &newAttrNode );
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-
-        if( attrNode->nodeValue != NULL ) {
-            free( attrNode->nodeValue );
-        }
-
-        attrNode->nodeValue = strdup( value );
-        if( attrNode->nodeValue == NULL ) {
-            free( attrNode->prefix );
-            Parser_freeNodeContent( &newAttrNode );
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-
-    } else {
-        // add a new attribute
-        rc = ixmlDocument_createAttributeNSEx( ( IXML_Document * )
-                                               element->n.ownerDocument,
-                                               namespaceURI, qualifiedName,
-                                               &newAttr );
-        if( rc != IXML_SUCCESS ) {
-            return rc;
-        }
-
-        newAttr->n.nodeValue = strdup( value );
-        if( newAttr->n.nodeValue == NULL ) {
-            ixmlAttr_free( newAttr );
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-
-        if( ixmlElement_setAttributeNodeNS( element, newAttr, NULL ) !=
-            IXML_SUCCESS ) {
-            ixmlAttr_free( newAttr );
-            return IXML_FAILED;
-        }
-
-    }
-
-    Parser_freeNodeContent( &newAttrNode );
-    return IXML_SUCCESS;
-}
-
-/*================================================================
-*   ixmlElement_removeAttributeNS
-*       Removes an attribute by local name and namespace URI. The replacing
-*       attribute has the same namespace URI and local name, as well as
-*       the original prefix.
-*       External function.
-*
-*   Parameters:
-*       namespaceURI: the namespace URI of the attribute to remove.
-*       localName: the local name of the atribute to remove.
-*
-*   Return Value:
-*       IXML_SUCCESS or failure.
-*
-*=================================================================*/
-int
-ixmlElement_removeAttributeNS( IN IXML_Element * element,
-                               IN const DOMString namespaceURI,
-                               IN const DOMString localName )
-{
-    IXML_Node *attrNode;
-
-    if( ( element == NULL ) || ( namespaceURI == NULL )
-        || ( localName == NULL ) ) {
-        return IXML_INVALID_PARAMETER;
-    }
-
-    attrNode = element->n.firstAttr;
-    while( attrNode != NULL ) {
-        if( strcmp( attrNode->localName, localName ) == 0 &&
-            strcmp( attrNode->namespaceURI, namespaceURI ) == 0 ) {
-            break;              //found it
-        } else {
-            attrNode = attrNode->nextSibling;
-        }
-    }
-
-    if( attrNode != NULL ) {    // has the attribute
-        if( attrNode->nodeValue != NULL ) {
-            free( attrNode->nodeValue );
-            attrNode->nodeValue = NULL;
-        }
-    }
-
-    return IXML_SUCCESS;
-
-}
-
-/*================================================================
-*   ixmlElement_getAttributeNodeNS
-*       Retrieves an attr node by local name and namespace URI. 
-*       External function.
-*
-*   Parameter:
-*       namespaceURI: the namespace of the attribute to retrieve.
-*       localName: the local name of the attribute to retrieve.
-*
-*   Return Value:
-*       The attr node with the specified attribute local name and 
-*       namespace URI or null if there is no such attribute.
-*
-*=================================================================*/
-IXML_Attr *
-ixmlElement_getAttributeNodeNS( IN IXML_Element * element,
-                                IN const DOMString namespaceURI,
-                                IN const DOMString localName )
-{
-
-    IXML_Node *attrNode;
-
-    if( ( element == NULL ) || ( namespaceURI == NULL )
-        || ( localName == NULL ) ) {
-        return NULL;
-    }
-
-    attrNode = element->n.firstAttr;
-    while( attrNode != NULL ) {
-        if( strcmp( attrNode->localName, localName ) == 0 && strcmp( attrNode->namespaceURI, namespaceURI ) == 0 ) {    // found it
-            break;
-        } else {
-            attrNode = attrNode->nextSibling;
-        }
-    }
-
-    return ( IXML_Attr * ) attrNode;
-
-}
-
-/*================================================================
-*   ixmlElement_setAttributeNodeNS
-*       Adds a new attribute. If an attribute with that local name and
-*       that namespace URI is already present in the element, it is replaced
-*       by the new one.
-*       External function.
-*
-*   Parameter:
-*       newAttr: the attr node to add to the attribute list.
-*
-*   Return Value:
-*       If the newAttr attribute replaces an existing attribute with the
-*       same local name and namespace, the replaced attr node is returned,
-*       otherwise null is returned.
-*
-*=================================================================*/
-int
-ixmlElement_setAttributeNodeNS( IN IXML_Element * element,
-                                IN IXML_Attr * newAttr,
-                                OUT IXML_Attr ** rtAttr )
-{
-    IXML_Node *attrNode;
-    IXML_Node *node;
-    IXML_Node *prevAttr = NULL,
-     *nextAttr = NULL;
-    IXML_Node *preSib,
-     *nextSib;
-
-    if( ( element == NULL ) || ( newAttr == NULL ) ) {
-        return IXML_INVALID_PARAMETER;
-    }
-
-    if( newAttr->n.ownerDocument != element->n.ownerDocument ) {
-        return IXML_WRONG_DOCUMENT_ERR;
-    }
-
-    if( ( newAttr->ownerElement != NULL )
-        && ( newAttr->ownerElement != element ) ) {
-        return IXML_INUSE_ATTRIBUTE_ERR;
-    }
-
-    newAttr->ownerElement = element;
-    node = ( IXML_Node * ) newAttr;
-
-    attrNode = element->n.firstAttr;
-    while( attrNode != NULL ) {
-        if( strcmp( attrNode->localName, node->localName ) == 0 &&
-            strcmp( attrNode->namespaceURI, node->namespaceURI ) == 0 ) {
-            break;              //found it
-        } else {
-            attrNode = attrNode->nextSibling;
-        }
-    }
-
-    if( attrNode != NULL )      // already present, will replace by newAttr
-    {
-        preSib = attrNode->prevSibling;
-        nextSib = attrNode->nextSibling;
-
-        if( preSib != NULL ) {
-            preSib->nextSibling = node;
-        }
-
-        if( nextSib != NULL ) {
-            nextSib->prevSibling = node;
-        }
-
-        if( element->n.firstAttr == attrNode ) {
-            element->n.firstAttr = node;
-        }
-
-        *rtAttr = ( IXML_Attr * ) attrNode;
-
-    } else                      // add this attribute 
-    {
-        if( element->n.firstAttr != NULL )  // element has attribute already
-        {
-            prevAttr = element->n.firstAttr;
-            nextAttr = prevAttr->nextSibling;
-            while( nextAttr != NULL ) {
-                prevAttr = nextAttr;
-                nextAttr = prevAttr->nextSibling;
-            }
-            prevAttr->nextSibling = node;
-        } else                  // this is the first attribute node
-        {
-            element->n.firstAttr = node;
-            node->prevSibling = NULL;
-            node->nextSibling = NULL;
-        }
-
-        if( rtAttr != NULL ) {
-            *rtAttr = NULL;
-        }
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*================================================================
-*   ixmlElement_getElementsByTagNameNS
-*       Returns a nodeList of all the descendant Elements with a given
-*       local name and namespace in the order in which they are encountered
-*       in a preorder traversal of the element tree.
-*       External function.
-*
-*   Parameters:
-*       namespaceURI: the namespace URI of the elements to match on. The
-*               special value "*" matches all namespaces.
-*       localName: the local name of the elements to match on. The special
-*               value "*" matches all local names.
-*
-*   Return Value:
-*       A new nodeList object containing all the matched Elements.
-*
-*=================================================================*/
-IXML_NodeList *
-ixmlElement_getElementsByTagNameNS( IN IXML_Element * element,
-                                    IN const DOMString namespaceURI,
-                                    IN const DOMString localName )
-{
-    IXML_Node *node = ( IXML_Node * ) element;
-    IXML_NodeList *nodeList = NULL;
-
-    if( ( element != NULL ) && ( namespaceURI != NULL )
-        && ( localName != NULL ) ) {
-        ixmlNode_getElementsByTagNameNS( node, namespaceURI, localName,
-                                         &nodeList );
-    }
-
-    return nodeList;
-}
-
-/*================================================================
-*   ixmlElement_hasAttribute
-*       Returns true when an attribute with a given name is specified on
-*       this element, false otherwise.
-*       External function.
-*
-*   Parameters:
-*       name: the name of the attribute to look for.
-*
-*   Return Value:
-*       ture if an attribute with the given name is specified on this
-*       element, false otherwise.
-*
-*=================================================================*/
-BOOL
-ixmlElement_hasAttribute( IN IXML_Element * element,
-                          IN const DOMString name )
-{
-
-    IXML_Node *attrNode;
-
-    if( ( element == NULL ) || ( name == NULL ) ) {
-        return FALSE;
-    }
-
-    attrNode = element->n.firstAttr;
-    while( attrNode != NULL ) {
-        if( strcmp( attrNode->nodeName, name ) == 0 ) {
-            return TRUE;
-        } else {
-            attrNode = attrNode->nextSibling;
-        }
-    }
-
-    return FALSE;
-}
-
-/*================================================================
-*   ixmlElement_hasAttributeNS
-*       Returns true when attribute with a given local name and namespace
-*       URI is specified on this element, false otherwise.
-*       External function.
-*
-*   Parameters:
-*       namespaceURI: the namespace URI of the attribute to look for.
-*       localName: the local name of the attribute to look for.
-*
-*   Return Value:
-*       true if an attribute with the given local name and namespace URI
-*       is specified, false otherwise.
-*
-*=================================================================*/
-BOOL
-ixmlElement_hasAttributeNS( IN IXML_Element * element,
-                            IN const DOMString namespaceURI,
-                            IN const DOMString localName )
-{
-
-    IXML_Node *attrNode;
-
-    if( ( element == NULL ) || ( namespaceURI == NULL )
-        || ( localName == NULL ) ) {
-        return FALSE;
-    }
-
-    attrNode = element->n.firstAttr;
-    while( attrNode != NULL ) {
-        if( strcmp( attrNode->localName, localName ) == 0 &&
-            strcmp( attrNode->namespaceURI, namespaceURI ) == 0 ) {
-            return TRUE;
-        } else {
-            attrNode = attrNode->nextSibling;
-        }
-    }
-
-    return FALSE;
-}
-
-/*================================================================
-*   ixmlElement_free
-*       frees a element node.
-*       External function.
-*
-*=================================================================*/
-void
-ixmlElement_free( IN IXML_Element * element )
-{
-    if( element != NULL ) {
-        ixmlNode_free( ( IXML_Node * ) element );
-    }
-}
diff --git a/tombupnp/ixml/src/inc/ixmlmembuf.h b/tombupnp/ixml/src/inc/ixmlmembuf.h
deleted file mode 100644
index cd99c25..0000000
--- a/tombupnp/ixml/src/inc/ixmlmembuf.h
+++ /dev/null
@@ -1,77 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef _IXML_MEMBUF_H
-#define _IXML_MEMBUF_H
-
-#include <stdlib.h>
-#include "ixml.h"
-
-#define MINVAL( a, b ) ( (a) < (b) ? (a) : (b) )
-#define MAXVAL( a, b ) ( (a) > (b) ? (a) : (b) )
-
-#ifndef WIN32
- #define	XINLINE inline
-#endif
-
-#define MEMBUF_DEF_SIZE_INC		20
-
-
-typedef struct // ixml_membuf 
-{
-	char	*buf;
-				
-	size_t	length;
-	size_t	capacity;
-	size_t	size_inc;
-
-} ixml_membuf;
-
-//--------------------------------------------------
-//////////////// functions /////////////////////////
-//--------------------------------------------------
-/*
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-*/
-
-void ixml_membuf_init(INOUT ixml_membuf *m);
-void ixml_membuf_destroy(INOUT ixml_membuf *m);
-int ixml_membuf_assign(INOUT ixml_membuf *m, IN const void *buf, 
-					 IN size_t buf_len );
-int ixml_membuf_assign_str(INOUT ixml_membuf *m, IN const char *c_str );
-int ixml_membuf_append(INOUT ixml_membuf *m, IN const void *buf);
-int ixml_membuf_append_str(INOUT ixml_membuf *m, IN const char *c_str);
-int ixml_membuf_insert(INOUT ixml_membuf *m, IN const void* buf, 
-					 IN size_t buf_len, int index );
-
-#endif // _IXML_MEMBUF_H
diff --git a/tombupnp/ixml/src/inc/ixmlparser.h b/tombupnp/ixml/src/inc/ixmlparser.h
deleted file mode 100644
index f41bafb..0000000
--- a/tombupnp/ixml/src/inc/ixmlparser.h
+++ /dev/null
@@ -1,119 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
- 
-#ifndef _IXMLPARSER_H
-#define _IXMLPARSER_H
-
-#include "ixml.h"
-#include "ixmlmembuf.h"
-
-// Parser definitions
-#define QUOT        """
-#define LT          "<"
-#define GT          ">"
-#define APOS        "'"
-#define AMP         "&"
-#define ESC_HEX     "&#x"
-#define ESC_DEC     "&#"
-
-typedef struct _IXML_NamespaceURI 
-{
-    char                        *nsURI;
-    char                        *prefix;
-    struct _IXML_NamespaceURI   *nextNsURI;
-} IXML_NamespaceURI;
-
-
-typedef struct _IXML_ElementStack
-{
-    char                    *element;
-    char                    *prefix;
-    char                    *namespaceUri;
-    IXML_NamespaceURI            *pNsURI;
-    struct _IXML_ElementStack    *nextElement;
-} IXML_ElementStack;
-
-
-typedef enum
-{
-    eELEMENT,
-    eATTRIBUTE,
-    eCONTENT,
-} PARSER_STATE;
-
-typedef struct _Parser
-{
-    char            *dataBuffer;	//data buffer
-    char            *curPtr;		//ptr to the token parsed 
-    char            *savePtr;		//Saves for backup
-    ixml_membuf     lastElem;
-    ixml_membuf     tokenBuf;    
-
-    IXML_Node           *pNeedPrefixNode;
-    IXML_ElementStack   *pCurElement;
-    IXML_Node           *currentNodePtr;
-    PARSER_STATE        state;
-
-    BOOL                bHasTopLevel;
-
-} Parser;
-
-
-
-int     Parser_LoadDocument( IXML_Document **retDoc, const char * xmlFile, BOOL file);
-BOOL    Parser_isValidXmlName( const DOMString name);
-int     Parser_setNodePrefixAndLocalName(IXML_Node *newIXML_NodeIXML_Attr);
-void    Parser_freeNodeContent( IXML_Node *IXML_Nodeptr);
-
-void    Parser_setErrorChar( char c );
-
-void    ixmlAttr_free(IXML_Attr *attrNode);
-void    ixmlAttr_init(IXML_Attr *attrNode);
-
-int     ixmlElement_setTagName(IXML_Element *element, const char *tagName);
-
-void    ixmlNamedNodeMap_init(IXML_NamedNodeMap *nnMap);
-int     ixmlNamedNodeMap_addToNamedNodeMap(IXML_NamedNodeMap **nnMap, IXML_Node *add);
-
-void    ixmlNode_init(IXML_Node *IXML_Nodeptr);
-BOOL    ixmlNode_compare(IXML_Node *srcIXML_Node, IXML_Node *destIXML_Node);
-
-void    ixmlNode_getElementsByTagName( IXML_Node *n, const char *tagname, IXML_NodeList **list);
-void    ixmlNode_getElementsByTagNameNS( IXML_Node *IXML_Node, const char *namespaceURI,
-                const char *localName, IXML_NodeList **list);
-
-int     ixmlNode_setNodeProperties(IXML_Node* node, IXML_Node *src);
-int     ixmlNode_setNodeName( IXML_Node* node, const DOMString qualifiedName);
-
-void    ixmlNodeList_init(IXML_NodeList *nList);
-int     ixmlNodeList_addToNodeList(IXML_NodeList **nList, IXML_Node *add);
-
-#endif  // _IXMLPARSER_H
diff --git a/tombupnp/ixml/src/ixml.c b/tombupnp/ixml/src/ixml.c
deleted file mode 100644
index 32388bb..0000000
--- a/tombupnp/ixml/src/ixml.c
+++ /dev/null
@@ -1,531 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include "ixmlmembuf.h"
-#include "ixmlparser.h"
-
-/*================================================================
-*   copy_with_escape
-*
-*
-*=================================================================*/
-static void
-copy_with_escape( INOUT ixml_membuf * buf,
-                  IN const char *p )
-{
-    int i;
-    int plen;
-
-    if( p == NULL )
-        return;
-
-    plen = strlen( p );
-
-    for( i = 0; i < plen; i++ ) {
-        switch ( p[i] ) {
-            case '<':
-                ixml_membuf_append_str( buf, "<" );
-                break;
-
-            case '>':
-                ixml_membuf_append_str( buf, ">" );
-                break;
-
-            case '&':
-                ixml_membuf_append_str( buf, "&" );
-                break;
-
-            case '\'':
-                ixml_membuf_append_str( buf, "'" );
-                break;
-
-            case '\"':
-                ixml_membuf_append_str( buf, """ );
-                break;
-
-            default:
-                ixml_membuf_append( buf, &p[i] );
-        }
-    }
-}
-
-/*================================================================
-*	ixmlPrintDomTreeRecursive
-*       It is a recursive function to print all the node in a tree.
-*       Internal to parser only.
-*
-*=================================================================*/
-void
-ixmlPrintDomTreeRecursive( IN IXML_Node * nodeptr,
-                           IN ixml_membuf * buf )
-{
-    const char *nodeName = NULL;
-    const char *nodeValue = NULL;
-    IXML_Node *child = NULL,
-     *sibling = NULL;
-
-    if( nodeptr != NULL ) {
-        nodeName = ( const char * )ixmlNode_getNodeName( nodeptr );
-        nodeValue = ixmlNode_getNodeValue( nodeptr );
-
-        switch ( ixmlNode_getNodeType( nodeptr ) ) {
-
-            case eTEXT_NODE:
-                copy_with_escape( buf, nodeValue );
-                break;
-
-            case eCDATA_SECTION_NODE:
-                ixml_membuf_append_str( buf, "<![CDATA[" );
-                ixml_membuf_append_str( buf, nodeValue );
-                ixml_membuf_append_str( buf, "]]>" );
-                break;
-
-            case ePROCESSING_INSTRUCTION_NODE:
-                ixml_membuf_append_str( buf, "<?" );
-                ixml_membuf_append_str( buf, nodeName );
-                ixml_membuf_append_str( buf, " " );
-                copy_with_escape( buf, nodeValue );
-                ixml_membuf_append_str( buf, "?>\n" );
-                break;
-
-            case eDOCUMENT_NODE:
-                ixmlPrintDomTreeRecursive( ixmlNode_getFirstChild
-                                           ( nodeptr ), buf );
-                break;
-
-            case eATTRIBUTE_NODE:
-                ixml_membuf_append_str( buf, nodeName );
-                ixml_membuf_append_str( buf, "=\"" );
-                copy_with_escape( buf, nodeValue );
-                ixml_membuf_append_str( buf, "\"" );
-
-                if( nodeptr->nextSibling != NULL ) {
-                    ixml_membuf_append_str( buf, " " );
-                    ixmlPrintDomTreeRecursive( nodeptr->nextSibling, buf );
-                }
-                break;
-
-            case eELEMENT_NODE:
-                ixml_membuf_append_str( buf, "<" );
-                ixml_membuf_append_str( buf, nodeName );
-
-                if( nodeptr->firstAttr != NULL ) {
-                    ixml_membuf_append_str( buf, " " );
-                    ixmlPrintDomTreeRecursive( nodeptr->firstAttr, buf );
-                }
-
-                child = ixmlNode_getFirstChild( nodeptr );
-                if( ( child != NULL )
-                    && ( ixmlNode_getNodeType( child ) ==
-                         eELEMENT_NODE ) ) {
-                    ixml_membuf_append_str( buf, ">\r\n" );
-                } else {
-                    ixml_membuf_append_str( buf, ">" );
-                }
-
-                //  output the children
-                ixmlPrintDomTreeRecursive( ixmlNode_getFirstChild
-                                           ( nodeptr ), buf );
-
-                // Done with children.  Output the end tag.
-                ixml_membuf_append_str( buf, "</" );
-                ixml_membuf_append_str( buf, nodeName );
-
-                sibling = ixmlNode_getNextSibling( nodeptr );
-                if( sibling != NULL
-                    && ixmlNode_getNodeType( sibling ) == eTEXT_NODE ) {
-                    ixml_membuf_append_str( buf, ">" );
-                } else {
-                    ixml_membuf_append_str( buf, ">\r\n" );
-                }
-                ixmlPrintDomTreeRecursive( ixmlNode_getNextSibling
-                                           ( nodeptr ), buf );
-                break;
-
-            default:
-                break;
-        }
-    }
-}
-
-/*================================================================
-*   ixmlPrintDomTree
-*       Print a DOM tree.
-*       Element, and Attribute nodes are handled differently.
-*       We don't want to print the Element and Attribute nodes' sibling.
-*       External function.
-*
-*=================================================================*/
-void
-ixmlPrintDomTree( IN IXML_Node * nodeptr,
-                  IN ixml_membuf * buf )
-{
-    const char *nodeName = NULL;
-    const char *nodeValue = NULL;
-    IXML_Node *child = NULL;
-
-    if( ( nodeptr == NULL ) || ( buf == NULL ) ) {
-        return;
-    }
-
-    nodeName = ( const char * )ixmlNode_getNodeName( nodeptr );
-    nodeValue = ixmlNode_getNodeValue( nodeptr );
-
-    switch ( ixmlNode_getNodeType( nodeptr ) ) {
-
-        case eTEXT_NODE:
-        case eCDATA_SECTION_NODE:
-        case ePROCESSING_INSTRUCTION_NODE:
-        case eDOCUMENT_NODE:
-            ixmlPrintDomTreeRecursive( nodeptr, buf );
-            break;
-
-        case eATTRIBUTE_NODE:
-            ixml_membuf_append_str( buf, nodeName );
-            ixml_membuf_append_str( buf, "=\"" );
-            copy_with_escape( buf, nodeValue );
-            ixml_membuf_append_str( buf, "\"" );
-            break;
-
-        case eELEMENT_NODE:
-            ixml_membuf_append_str( buf, "<" );
-            ixml_membuf_append_str( buf, nodeName );
-
-            if( nodeptr->firstAttr != NULL ) {
-                ixml_membuf_append_str( buf, " " );
-                ixmlPrintDomTreeRecursive( nodeptr->firstAttr, buf );
-            }
-
-            child = ixmlNode_getFirstChild( nodeptr );
-            if( ( child != NULL )
-                && ( ixmlNode_getNodeType( child ) == eELEMENT_NODE ) ) {
-                ixml_membuf_append_str( buf, ">\r\n" );
-            } else {
-                ixml_membuf_append_str( buf, ">" );
-            }
-
-            //  output the children
-            ixmlPrintDomTreeRecursive( ixmlNode_getFirstChild( nodeptr ),
-                                       buf );
-
-            // Done with children.  Output the end tag.
-            ixml_membuf_append_str( buf, "</" );
-            ixml_membuf_append_str( buf, nodeName );
-            ixml_membuf_append_str( buf, ">\r\n" );
-            break;
-
-        default:
-            break;
-    }
-}
-
-/*================================================================
-*   ixmlDomTreetoString
-*       Converts a DOM tree into a text string
-*       Element, and Attribute nodes are handled differently.
-*       We don't want to print the Element and Attribute nodes' sibling.
-*       External function.
-*
-*=================================================================*/
-void
-ixmlDomTreetoString( IN IXML_Node * nodeptr,
-                     IN ixml_membuf * buf )
-{
-    const char *nodeName = NULL;
-    const char *nodeValue = NULL;
-    IXML_Node *child = NULL;
-
-    if( ( nodeptr == NULL ) || ( buf == NULL ) ) {
-        return;
-    }
-
-    nodeName = ( const char * )ixmlNode_getNodeName( nodeptr );
-    nodeValue = ixmlNode_getNodeValue( nodeptr );
-
-    switch ( ixmlNode_getNodeType( nodeptr ) ) {
-
-        case eTEXT_NODE:
-        case eCDATA_SECTION_NODE:
-        case ePROCESSING_INSTRUCTION_NODE:
-        case eDOCUMENT_NODE:
-            ixmlPrintDomTreeRecursive( nodeptr, buf );
-            break;
-
-        case eATTRIBUTE_NODE:
-            ixml_membuf_append_str( buf, nodeName );
-            ixml_membuf_append_str( buf, "=\"" );
-            copy_with_escape( buf, nodeValue );
-            ixml_membuf_append_str( buf, "\"" );
-            break;
-
-        case eELEMENT_NODE:
-            ixml_membuf_append_str( buf, "<" );
-            ixml_membuf_append_str( buf, nodeName );
-
-            if( nodeptr->firstAttr != NULL ) {
-                ixml_membuf_append_str( buf, " " );
-                ixmlPrintDomTreeRecursive( nodeptr->firstAttr, buf );
-            }
-
-            child = ixmlNode_getFirstChild( nodeptr );
-            if( ( child != NULL )
-                && ( ixmlNode_getNodeType( child ) == eELEMENT_NODE ) ) {
-                ixml_membuf_append_str( buf, ">" );
-            } else {
-                ixml_membuf_append_str( buf, ">" );
-            }
-
-            //  output the children
-            ixmlPrintDomTreeRecursive( ixmlNode_getFirstChild( nodeptr ),
-                                       buf );
-
-            // Done with children.  Output the end tag.
-            ixml_membuf_append_str( buf, "</" );
-            ixml_membuf_append_str( buf, nodeName );
-            ixml_membuf_append_str( buf, ">" );
-            break;
-
-        default:
-            break;
-    }
-}
-
-/*================================================================
-*   ixmlLoadDocumentEx
-*       Parses the given file, and returns the DOM tree from it.
-*       External function.
-*
-*=================================================================*/
-int
-ixmlLoadDocumentEx( IN const char *xmlFile,
-                    IXML_Document ** doc )
-{
-
-    if( ( xmlFile == NULL ) || ( doc == NULL ) ) {
-        return IXML_INVALID_PARAMETER;
-    }
-
-    return Parser_LoadDocument( doc, xmlFile, TRUE );
-}
-
-/*================================================================
-*   ixmlLoadDocument
-*       Parses the given file, and returns the DOM tree from it.
-*       External function.
-*
-*=================================================================*/
-IXML_Document *
-ixmlLoadDocument( IN const char *xmlFile )
-{
-
-    IXML_Document *doc = NULL;
-
-    ixmlLoadDocumentEx( xmlFile, &doc );
-    return doc;
-}
-
-/*================================================================
-*   ixmlPrintDocument
-*       Prints entire document, prepending XML prolog first.
-*       Puts lots of white spaces.
-*       External function.
-*
-*=================================================================*/
-
-DOMString
-ixmlPrintDocument(IXML_Document *doc)
-{
-    IXML_Node* rootNode = ( IXML_Node * )doc;
-    ixml_membuf memBuf;
-    ixml_membuf *buf = &memBuf;
-
-    if( rootNode == NULL ) {
-        return NULL;
-    }
-
-    ixml_membuf_init( buf );
-    ixml_membuf_append_str( buf, "<?xml version=\"1.0\"?>\r\n" );
-    ixmlPrintDomTree( rootNode, buf );
-    return buf->buf;
-
-}
-
-/*================================================================
-*   ixmlPrintNode
-*       Print DOM tree under node. Puts lots of white spaces
-*       External function.
-*
-*=================================================================*/
-DOMString
-ixmlPrintNode( IN IXML_Node * node )
-{
-
-    ixml_membuf memBuf;
-    ixml_membuf *buf = &memBuf;
-
-    if( node == NULL ) {
-        return NULL;
-    }
-
-    ixml_membuf_init( buf );
-    ixmlPrintDomTree( node, buf );
-    return buf->buf;
-
-}
-
-/*================================================================
-*   ixmlDocumenttoString
-*       converts DOM tree under node to text string,
-*       prepending XML prolog first.
-*       External function.
-*
-*=================================================================*/
-
-DOMString
-ixmlDocumenttoString(IXML_Document *doc)
-{
-    IXML_Node* rootNode = ( IXML_Node * )doc;
-    ixml_membuf memBuf;
-    ixml_membuf *buf = &memBuf;
-
-    if( rootNode == NULL ) {
-        return NULL;
-    }
-
-    ixml_membuf_init( buf );
-    ixml_membuf_append_str( buf, "<?xml version=\"1.0\"?>\r\n" );
-    ixmlDomTreetoString( rootNode, buf );
-    return buf->buf;
-
-}
-
-/*================================================================
-*   ixmlNodetoString
-*       converts DOM tree under node to text string
-*       External function.
-*
-*=================================================================*/
-DOMString
-ixmlNodetoString( IN IXML_Node * node )
-{
-
-    ixml_membuf memBuf;
-    ixml_membuf *buf = &memBuf;
-
-    if( node == NULL ) {
-        return NULL;
-    }
-
-    ixml_membuf_init( buf );
-    ixmlDomTreetoString( node, buf );
-    return buf->buf;
-
-}
-
-/*================================================================
-*   ixmlRelaxParser
-*       Makes the XML parser more tolerant to malformed text.
-*       External function.
-*
-*=================================================================*/
-void
-ixmlRelaxParser(char errorChar)
-{
-    Parser_setErrorChar( errorChar );
-}
-
-
-/*================================================================
-*   ixmlParseBufferEx
-*       Parse xml file stored in buffer.
-*       External function.
-*
-*=================================================================*/
-int
-ixmlParseBufferEx( IN const char *buffer,
-                   IXML_Document ** retDoc )
-{
-
-    if( ( buffer == NULL ) || ( retDoc == NULL ) ) {
-        return IXML_INVALID_PARAMETER;
-    }
-
-    if( buffer[0] == '\0' ) {
-        return IXML_INVALID_PARAMETER;
-    }
-
-    return Parser_LoadDocument( retDoc, buffer, FALSE );
-}
-
-/*================================================================
-*   ixmlParseBuffer
-*       Parse xml file stored in buffer.
-*       External function.
-*
-*=================================================================*/
-IXML_Document *
-ixmlParseBuffer( IN const char *buffer )
-{
-    IXML_Document *doc = NULL;
-
-    ixmlParseBufferEx( buffer, &doc );
-    return doc;
-}
-
-/*================================================================
-*   ixmlCloneDOMString
-*       Clones a DOM String.
-*       External function.
-*
-*=================================================================*/
-DOMString
-ixmlCloneDOMString( IN const DOMString src )
-{
-    if( src == NULL ) {
-        return NULL;
-    }
-
-    return ( strdup( src ) );
-}
-
-/*================================================================
-*   ixmlFreeDOMString
-*       Frees a DOM String.
-*       External function.
-*
-*=================================================================*/
-void
-ixmlFreeDOMString( IN DOMString buf )
-{
-    if( buf != NULL ) {
-        free( buf );
-    }
-}
diff --git a/tombupnp/ixml/src/ixmlmembuf.c b/tombupnp/ixml/src/ixmlmembuf.c
deleted file mode 100644
index 31cbac6..0000000
--- a/tombupnp/ixml/src/ixmlmembuf.c
+++ /dev/null
@@ -1,236 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include "ixmlmembuf.h"
-#include "ixml.h"
-
-/*================================================================
-*   ixml_membuf_set_size
-*
-*   Increases or decreases buffer cap so that at least
-*   'new_length' bytes can be stored
-*
-*   On error, m's fields do not change.
-*
-*   returns:
-*       UPNP_E_SUCCESS
-*       UPNP_E_OUTOF_MEMORY
-*
-*=================================================================*/
-static int
-ixml_membuf_set_size( INOUT ixml_membuf * m,
-                      IN size_t new_length )
-{
-    size_t diff;
-    size_t alloc_len;
-    char *temp_buf;
-
-    if( new_length >= m->length )   // increase length
-    {
-        // need more mem?
-        if( new_length <= m->capacity ) {
-            return 0;           // have enough mem; done
-        }
-
-        diff = new_length - m->length;
-        alloc_len = MAXVAL( m->size_inc, diff ) + m->capacity;
-    } else                      // decrease length
-    {
-        assert( new_length <= m->length );
-
-        // if diff is 0..m->size_inc, don't free
-        if( ( m->capacity - new_length ) <= m->size_inc ) {
-            return 0;
-        }
-
-        alloc_len = new_length + m->size_inc;
-    }
-
-    assert( alloc_len >= new_length );
-
-    temp_buf = realloc( m->buf, alloc_len + 1 );
-    if( temp_buf == NULL ) {
-        // try smaller size
-        alloc_len = new_length;
-        temp_buf = realloc( m->buf, alloc_len + 1 );
-
-        if( temp_buf == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-    }
-    // save
-    m->buf = temp_buf;
-    m->capacity = alloc_len;
-    return 0;
-}
-
-/*================================================================
-*   membuffer_init
-*
-*
-*=================================================================*/
-void
-ixml_membuf_init( INOUT ixml_membuf * m )
-{
-    assert( m != NULL );
-
-    m->size_inc = MEMBUF_DEF_SIZE_INC;
-    m->buf = NULL;
-    m->length = 0;
-    m->capacity = 0;
-}
-
-/*================================================================
-*   membuffer_destroy
-*
-*
-*=================================================================*/
-void
-ixml_membuf_destroy( INOUT ixml_membuf * m )
-{
-    if( m == NULL ) {
-        return;
-    }
-
-    free( m->buf );
-    ixml_membuf_init( m );
-}
-
-/*================================================================
-*   ixml_membuf_assign
-*
-*
-*=================================================================*/
-int
-ixml_membuf_assign( INOUT ixml_membuf * m,
-                    IN const void *buf,
-                    IN size_t buf_len )
-{
-    int return_code;
-
-    assert( m != NULL );
-
-    // set value to null
-    if( buf == NULL ) {
-        ixml_membuf_destroy( m );
-        return IXML_SUCCESS;
-    }
-    // alloc mem
-    return_code = ixml_membuf_set_size( m, buf_len );
-    if( return_code != 0 ) {
-        return return_code;
-    }
-    // copy
-    memcpy( m->buf, buf, buf_len );
-    m->buf[buf_len] = 0;        // null-terminate
-
-    m->length = buf_len;
-
-    return IXML_SUCCESS;
-
-}
-
-/*================================================================
-*   ixml_membuf_assign_str
-*
-*
-*=================================================================*/
-int
-ixml_membuf_assign_str( INOUT ixml_membuf * m,
-                        IN const char *c_str )
-{
-    return ixml_membuf_assign( m, c_str, strlen( c_str ) );
-}
-
-/*================================================================
-*   ixml_membuf_append
-*
-*
-*=================================================================*/
-int
-ixml_membuf_append( INOUT ixml_membuf * m,
-                    IN const void *buf )
-{
-    assert( m != NULL );
-
-    return ixml_membuf_insert( m, buf, 1, m->length );
-}
-
-/*================================================================
-*   ixml_membuf_append_str
-*
-*
-*=================================================================*/
-int
-ixml_membuf_append_str( INOUT ixml_membuf * m,
-                        IN const char *c_str )
-{
-    return ixml_membuf_insert( m, c_str, strlen( c_str ), m->length );
-}
-
-/*================================================================
-*   ixml_membuf_insert
-*
-*
-*=================================================================*/
-int
-ixml_membuf_insert( INOUT ixml_membuf * m,
-                    IN const void *buf,
-                    IN size_t buf_len,
-                    int index )
-{
-    int return_code;
-
-    assert( m != NULL );
-
-    if( index < 0 || index > ( int )m->length )
-        return IXML_INDEX_SIZE_ERR;
-
-    if( buf == NULL || buf_len == 0 ) {
-        return 0;
-    }
-    // alloc mem
-    return_code = ixml_membuf_set_size( m, m->length + buf_len );
-    if( return_code != 0 ) {
-        return return_code;
-    }
-    // insert data
-    // move data to right of insertion point
-    memmove( m->buf + index + buf_len, m->buf + index, m->length - index );
-    memcpy( m->buf + index, buf, buf_len );
-    m->length += buf_len;
-    m->buf[m->length] = 0;      // null-terminate
-
-    return 0;
-}
diff --git a/tombupnp/ixml/src/ixmlparser.c b/tombupnp/ixml/src/ixmlparser.c
deleted file mode 100644
index b19591c..0000000
--- a/tombupnp/ixml/src/ixmlparser.c
+++ /dev/null
@@ -1,2494 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include <string.h>
-#include "ixmlparser.h"
-
-#ifdef WIN32
- #define strncasecmp strnicmp
-#endif
-
-static char g_error_char = '\0';
-
-static const char LESSTHAN = '<';
-static const char GREATERTHAN = '>';
-static const char SLASH = '/';
-static const char EQUALS = '=';
-static const char QUOTE = '\"';
-static const char SINGLEQUOTE = '\'';
-
-static const char *WHITESPACE = "\n\t\r ";
-static const char *COMPLETETAG = "/>";
-static const char *ENDTAG = "</";
-static const char *XMLDECL = "<?xml ";
-static const char *XMLDECL2 = "<?xml?";
-static const char *BEGIN_COMMENT = "<!--";
-static const char *END_COMMENT = "-->";
-static const char *BEGIN_PI = "<?";
-static const char *END_PI = "?>";
-static const char *BEGIN_DOCTYPE = "<!DOCTYPE";
-static const char *CDSTART = "<![CDATA[";
-static const char *CDEND = "]]>";
-static const char *DEC_NUMBERS = "0123456789";
-static const char *HEX_NUMBERS = "0123456789ABCDEFabcdef";
-
-typedef struct char_info {
-    unsigned short l,
-      h;
-} char_info_t;
-
-typedef char utf8char[8];
-
-/*==============================================================================*
-*	Letter table contains all characters in XML 1.0 plus ":", "_" and
-*   ideographic.
-*
-*   This table contains all the characters that an element name can start with.
-*   See XML 1.0 (2nd Edition) for more details.	
-*
-*===============================================================================*/
-static char_info_t Letter[] = {
-    {0x003A, 0x003A},           // character ":"
-    {0x0041, 0x005A},
-    {0x005F, 0x005F},           // character "_"
-    {0x0061, 0x007A}, {0x00C0, 0x00D6}, {0x00D8, 0x00F6}, {0x00F8, 0x00FF},
-    {0x0100, 0x0131}, {0x0134, 0x013E}, {0x0141, 0x0148}, {0x014A, 0x017E},
-    {0x0180, 0x01C3}, {0x01CD, 0x01F0}, {0x01F4, 0x01F5}, {0x01FA, 0x0217},
-    {0x0250, 0x02A8}, {0x02BB, 0x02C1}, {0x0386, 0x0386}, {0x0388, 0x038A},
-    {0x038C, 0x038C}, {0x038E, 0x03A1}, {0x03A3, 0x03CE}, {0x03D0, 0x03D6},
-    {0x03DA, 0x03DA},
-    {0x03DC, 0x03DC}, {0x03DE, 0x03DE}, {0x03E0, 0x03E0}, {0x03E2, 0x03F3},
-    {0x0401, 0x040C}, {0x040E, 0x044F}, {0x0451, 0x045C}, {0x045E, 0x0481},
-    {0x0490, 0x04C4}, {0x04C7, 0x04C8}, {0x04CB, 0x04CC}, {0x04D0, 0x04EB},
-    {0x04EE, 0x04F5}, {0x04F8, 0x04F9}, {0x0531, 0x0556}, {0x0559, 0x0559},
-    {0x0561, 0x0586}, {0x05D0, 0x05EA}, {0x05F0, 0x05F2}, {0x0621, 0x063A},
-    {0x0641, 0x064A}, {0x0671, 0x06B7}, {0x06BA, 0x06BE}, {0x06C0, 0x06CE},
-    {0x06D0, 0x06D3}, {0x06D5, 0x06D5}, {0x06E5, 0x06E6}, {0x0905, 0x0939},
-    {0x093D, 0x093D}, {0x0958, 0x0961}, {0x0985, 0x098C}, {0x098F, 0x0990},
-    {0x0993, 0x09A8}, {0x09AA, 0x09B0}, {0x09B2, 0x09B2}, {0x09B6, 0x09B9},
-    {0x09DC, 0x09DD}, {0x09DF, 0x09E1}, {0x09F0, 0x09F1}, {0x0A05, 0x0A0A},
-    {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, {0x0A32, 0x0A33},
-    {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E},
-    {0x0A72, 0x0A74}, {0x0A85, 0x0A8B}, {0x0A8D, 0x0A8D}, {0x0A8F, 0x0A91},
-    {0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9},
-    {0x0ABD, 0x0ABD}, {0x0AE0, 0x0AE0}, {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10},
-    {0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, {0x0B36, 0x0B39},
-    {0x0B3D, 0x0B3D}, {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B61}, {0x0B85, 0x0B8A},
-    {0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C},
-    {0x0B9E, 0x0B9F}, {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB5},
-    {0x0BB7, 0x0BB9}, {0x0C05, 0x0C0C}, {0x0C0E, 0x0C10}, {0x0C12, 0x0C28},
-    {0x0C2A, 0x0C33}, {0x0C35, 0x0C39}, {0x0C60, 0x0C61}, {0x0C85, 0x0C8C},
-    {0x0C8E, 0x0C90}, {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9},
-    {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE1}, {0x0D05, 0x0D0C}, {0x0D0E, 0x0D10},
-    {0x0D12, 0x0D28}, {0x0D2A, 0x0D39}, {0x0D60, 0x0D61}, {0x0E01, 0x0E2E},
-    {0x0E30, 0x0E30}, {0x0E32, 0x0E33}, {0x0E40, 0x0E45}, {0x0E81, 0x0E82},
-    {0x0E84, 0x0E84}, {0x0E87, 0x0E88}, {0x0E8A, 0x0E8A}, {0x0E8D, 0x0E8D},
-    {0x0E94, 0x0E97}, {0x0E99, 0x0E9F}, {0x0EA1, 0x0EA3}, {0x0EA5, 0x0EA5},
-    {0x0EA7, 0x0EA7}, {0x0EAA, 0x0EAB}, {0x0EAD, 0x0EAE}, {0x0EB0, 0x0EB0},
-    {0x0EB2, 0x0EB3}, {0x0EBD, 0x0EBD}, {0x0EC0, 0x0EC4}, {0x0F40, 0x0F47},
-    {0x0F49, 0x0F69}, {0x10A0, 0x10C5}, {0x10D0, 0x10F6}, {0x1100, 0x1100},
-    {0x1102, 0x1103}, {0x1105, 0x1107}, {0x1109, 0x1109}, {0x110B, 0x110C},
-    {0x110E, 0x1112}, {0x113C, 0x113C}, {0x113E, 0x113E}, {0x1140, 0x1140},
-    {0x114C, 0x114C}, {0x114E, 0x114E}, {0x1150, 0x1150}, {0x1154, 0x1155},
-    {0x1159, 0x1159}, {0x115F, 0x1161}, {0x1163, 0x1163}, {0x1165, 0x1165},
-    {0x1167, 0x1167}, {0x1169, 0x1169}, {0x116D, 0x116E}, {0x1172, 0x1173},
-    {0x1175, 0x1175}, {0x119E, 0x119E}, {0x11A8, 0x11A8}, {0x11AB, 0x11AB},
-    {0x11AE, 0x11AF}, {0x11B7, 0x11B8}, {0x11BA, 0x11BA}, {0x11BC, 0x11C2},
-    {0x11EB, 0x11EB}, {0x11F0, 0x11F0}, {0x11F9, 0x11F9}, {0x1E00, 0x1E9B},
-    {0x1EA0, 0x1EF9}, {0x1F00, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45},
-    {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B},
-    {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FBC},
-    {0x1FBE, 0x1FBE}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, {0x1FD0, 0x1FD3},
-    {0x1FD6, 0x1FDB}, {0x1FE0, 0x1FEC}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC},
-    {0x2126, 0x2126}, {0x212A, 0x212B}, {0x212E, 0x212E}, {0x2180, 0x2182},
-    {0x3007, 0x3007}, {0x3021, 0x3029}, // these two are ideographic
-    {0x3041, 0x3094}, {0x30A1, 0x30FA}, {0x3105, 0x312C},
-    {0x4E00, 0x9FA5},           // ideographic
-    {0xAC00, 0xD7A3}
-};
-
-#define LETTERTABLESIZE (sizeof(Letter)/sizeof(Letter[0]))
-
-/*==============================================================================*
-*   NameChar table contains
-*   CombiningChar, Extender, Digit, '-', '.', less '_', ':'
-*   NameChar ::= Digit | '-' | '.' | CombiningChar | Extender
-*   See XML 1.0 2nd Edition 
-*
-*===============================================================================*/
-static char_info_t NameChar[] = {
-    {0x002D, 0x002D},           // character "-"
-    {0x002E, 0x002E},           // character "."
-    {0x0030, 0x0039},           // digit
-    {0x00B7, 0x00B7}, {0x02D0, 0x02D0}, {0x02D1, 0x02D1},   // extended
-    {0x0300, 0x0345}, {0x0360, 0x0361},
-    {0x0387, 0x0387},           // extended
-    {0x0483, 0x0486}, {0x0591, 0x05A1}, {0x05A3, 0x05B9},
-    {0x05BB, 0x05BD}, {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, {0x05C4, 0x05C4},
-    {0x0640, 0x0640},           // extended
-    {0x064B, 0x0652},
-    {0x0660, 0x0669},           // digit
-    {0x0670, 0x0670},
-    {0x06D6, 0x06DC}, {0x06DD, 0x06DF}, {0x06E0, 0x06E4}, {0x06E7, 0x06E8},
-    {0x06EA, 0x06ED},
-    {0x06F0, 0x06F9},           // digit
-    {0x0901, 0x0903}, {0x093C, 0x093C},
-    {0x093E, 0x094C}, {0x094D, 0x094D}, {0x0951, 0x0954}, {0x0962, 0x0963},
-    {0x0966, 0x096F},           // digit
-    {0x0981, 0x0983}, {0x09BC, 0x09BC}, {0x09BE, 0x09BE},
-    {0x09BF, 0x09BF}, {0x09C0, 0x09C4}, {0x09C7, 0x09C8}, {0x09CB, 0x09CD},
-    {0x09D7, 0x09D7}, {0x09E2, 0x09E3},
-    {0x09E6, 0x09EF},           // digit
-    {0x0A02, 0x0A02},
-    {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A3E}, {0x0A3F, 0x0A3F}, {0x0A40, 0x0A42},
-    {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D},
-    {0x0A66, 0x0A6F},           // digit
-    {0x0A70, 0x0A71},
-    {0x0A81, 0x0A83}, {0x0ABC, 0x0ABC}, {0x0ABE, 0x0AC5}, {0x0AC7, 0x0AC9},
-    {0x0ACB, 0x0ACD},
-    {0x0AE6, 0x0AEF},           // digit
-    {0x0B01, 0x0B03}, {0x0B3C, 0x0B3C},
-    {0x0B3E, 0x0B43}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4D}, {0x0B56, 0x0B57},
-    {0x0B66, 0x0B6F},           // digit
-    {0x0B82, 0x0B83}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8},
-    {0x0BCA, 0x0BCD}, {0x0BD7, 0x0BD7},
-    {0x0BE7, 0x0BEF},           // digit
-    {0x0C01, 0x0C03},
-    {0x0C3E, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56},
-    {0x0C66, 0x0C6F},           // digit
-    {0x0C82, 0x0C83}, {0x0CBE, 0x0CC4}, {0x0CC6, 0x0CC8},
-    {0x0CCA, 0x0CCD}, {0x0CD5, 0x0CD6},
-    {0x0CE6, 0x0CEF},           // digit
-    {0x0D02, 0x0D03},
-    {0x0D3E, 0x0D43}, {0x0D46, 0x0D48}, {0x0D4A, 0x0D4D}, {0x0D57, 0x0D57},
-    {0x0D66, 0x0D6F},           // digit
-    {0x0E31, 0x0E31}, {0x0E34, 0x0E3A},
-    {0x0E46, 0x0E46},           // extended
-    {0x0E47, 0x0E4E},
-    {0x0E50, 0x0E59},           // digit
-    {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9},
-    {0x0EBB, 0x0EBC},
-    {0x0EC6, 0x0EC6},           // extended
-    {0x0EC8, 0x0ECD},
-    {0x0ED0, 0x0ED9},           // digit
-    {0x0F18, 0x0F19},
-    {0x0F20, 0x0F29},           // digit
-    {0x0F35, 0x0F35}, {0x0F37, 0x0F37},
-    {0x0F39, 0x0F39}, {0x0F3E, 0x0F3E}, {0x0F3F, 0x0F3F}, {0x0F71, 0x0F84},
-    {0x0F86, 0x0F8B}, {0x0F90, 0x0F95}, {0x0F97, 0x0F97}, {0x0F99, 0x0FAD},
-    {0x0FB1, 0x0FB7}, {0x0FB9, 0x0FB9}, {0x20D0, 0x20DC}, {0x20E1, 0x20E1},
-    {0x3005, 0x3005},           // extended
-    {0x302A, 0x302F},
-    {0x3031, 0x3035},           // extended 
-    {0x3099, 0x3099}, {0x309A, 0x309A}, // combining char
-    {0x309D, 0x309E}, {0x30FC, 0x30FE}  // extended
-};
-
-#define NAMECHARTABLESIZE   (sizeof(NameChar)/sizeof(NameChar[0]))
-
-// functions used in this file
-static void Parser_free( Parser * myParser );
-static int Parser_skipDocType( char **pstr );
-static int Parser_skipProlog( Parser * xmlParser );
-static int Parser_skipMisc( Parser * xmlParser );
-static void Parser_freeElementStackItem( IXML_ElementStack * pItem );
-static void Parser_freeNsURI( IXML_NamespaceURI * pNsURI );
-
-static int Parser_getNextNode( Parser * myParser,
-                               IXML_Node * newNode,
-                               BOOL * isEnd );
-static int Parser_getNextToken( Parser * myParser );
-static int Parser_xmlNamespace( Parser * myParser,
-                                IXML_Node * newNode );
-static BOOL Parser_ElementPrefixDefined( Parser * myParser,
-                                         IXML_Node * newNode,
-                                         char **nsURI );
-static int Parser_setElementNamespace( IXML_Element * newElement,
-                                       const char *nsURI );
-static int Parser_parseDocument( IXML_Document ** retDoc,
-                                 Parser * domParser );
-static BOOL Parser_hasDefaultNamespace( Parser * xmlParser,
-                                        IXML_Node * newNode,
-                                        char **nsURI );
-static int Parser_getChar( IN const char *src,
-                           INOUT int *cLen );
-
-/*==============================================================================*
-*   safe_strdup
-*       strdup that handles NULL input.
-*   
-*===============================================================================*/
-static char *
-safe_strdup(const char *s) 
-{
-    assert(s != NULL);
-    if (s == NULL) {
-        return strdup("");
-    }
-    return strdup(s);
-}
-
-/*==============================================================================*
-*   Parser_isCharInTable
-*       will determine whether character c is in the table of tbl
-*       (either Letter table or NameChar table)
-*   
-*===============================================================================*/
-static BOOL
-Parser_isCharInTable( IN int c,
-                      IN char_info_t * tbl,
-                      IN int sz )
-{
-    int t = 0,
-      b = sz,
-      m;
-
-    while( t <= b ) {
-        m = ( t + b ) / 2;
-        if( c < tbl[m].l ) {
-            b = m - 1;
-        } else if( c > tbl[m].h ) {
-            t = m + 1;
-        } else {
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
-/*==============================================================================*
-*	Parser_isXmlChar
-*	    see XML 1.0 (2nd Edition) 2.2.
-*       Internal to parser only
-*
-*===============================================================================*/
-static BOOL
-Parser_isXmlChar( IN int c )
-{
-    return ( c == 0x9 || c == 0xA || c == 0xD ||
-             ( c >= 0x20 && c <= 0xD7FF ) ||
-             ( c >= 0xE000 && c <= 0xFFFD ) ||
-             ( c >= 0x10000 && c <= 0x10FFFF ) );
-}
-
-/*==============================================================================*
-*   Parser_isNameChar
-*       check whether c (int) is in LetterTable or NameCharTable
-*       Internal to parser only.
-*
-*===============================================================================*/
-static BOOL
-Parser_isNameChar( IN int c,
-                   IN BOOL bNameChar )
-{
-    if( Parser_isCharInTable( c, Letter, LETTERTABLESIZE ) ) {
-        return TRUE;
-    }
-
-    if( bNameChar
-        && Parser_isCharInTable( c, NameChar, NAMECHARTABLESIZE ) ) {
-        return TRUE;
-    }
-    return FALSE;
-}
-
-/*==============================================================================*
-*   Parser_isValidXmlName
-*       Check to see whether name is a valid xml name.
-*       External function.
-*
-*===============================================================================*/
-BOOL
-Parser_isValidXmlName( IN const DOMString name )
-{
-    const char *pstr = NULL;
-    int i = 0,
-      nameLen = 0;
-
-    assert( name != NULL );
-
-    nameLen = strlen( name );
-
-    pstr = name;
-    if( Parser_isNameChar( *pstr, FALSE ) == TRUE ) {
-        for( i = 1; i < nameLen; i++ ) {
-            if( Parser_isNameChar( *( pstr + i ), TRUE ) == FALSE ) {   //illegal char
-                return FALSE;
-            }
-        }
-    }
-
-    return TRUE;
-}
-
-/*==============================================================================*
-*   Parser_setErrorChar:	
-*       If 'c' is 0 (default), the parser is strict about XML encoding :
-*       invalid UTF-8 sequences or "&" entities are rejected, and the parsing 
-*       aborts.
-*       If 'c' is not 0, the parser is relaxed : invalid UTF-8 characters
-*       are replaced by this character, and invalid "&" entities are left
-*       untranslated. The parsing is then allowed to continue.
-*       External function.
-*   
-*===============================================================================*/
-void
-Parser_setErrorChar( IN char c )
-{
-     g_error_char = c;
-}
-
-
-/*==============================================================================*
-*   Parser_intToUTF8:	
-*       Encoding a character to its UTF-8 character string, and return its length
-*       internal function.
-*   
-*===============================================================================*/
-static int
-Parser_intToUTF8( IN int c,
-                  IN utf8char s )
-{
-    if( c < 0 ) {
-        return 0;
-    }
-
-    if( c <= 127 ) {
-        s[0] = c;
-        s[1] = 0;
-        return 1;
-    } else if( c <= 0x07FF ) {  // 0x0080 < c <= 0x07FF
-        s[0] = 0xC0 | ( c >> 6 );
-        s[1] = 0x80 | ( c & 0x3f );
-        s[2] = 0;
-        return 2;
-    } else if( c <= 0xFFFF ) {  // 0x0800 < c <= 0xFFFF
-        s[0] = 0xE0 | ( c >> 12 );
-        s[1] = 0x80 | ( ( c >> 6 ) & 0x3f );
-        s[2] = 0x80 | ( c & 0x3f );
-        s[3] = 0;
-        return 3;
-    } else if( c <= 0x1FFFFF ) {    // 0x10000 < c <= 0x1FFFFF
-        s[0] = 0xF0 | ( c >> 18 );
-        s[1] = 0x80 | ( ( c >> 12 ) & 0x3f );
-        s[2] = 0x80 | ( ( c >> 6 ) & 0x3f );
-        s[3] = 0x80 | ( c & 0x3f );
-        s[4] = 0;
-        return 4;
-    } else if( c <= 0x3FFFFFF ) {   // 0x200000 < c <= 3FFFFFF
-        s[0] = 0xF8 | ( c >> 24 );
-        s[1] = 0x80 | ( ( c >> 18 ) & 0x3f );
-        s[2] = 0x80 | ( ( c >> 12 ) & 0x3f );
-        s[3] = 0x80 | ( ( c >> 6 ) & 0x3f );
-        s[4] = 0x80 | ( c & 0x3f );
-        s[5] = 0;
-        return 5;
-    } else if( c <= 0x7FFFFFFF ) {  // 0x4000000 < c <= 7FFFFFFF
-        s[0] = 0xFC | ( c >> 30 );
-        s[1] = 0x80 | ( ( c >> 24 ) & 0x3f );
-        s[2] = 0x80 | ( ( c >> 18 ) & 0x3f );
-        s[3] = 0x80 | ( ( c >> 12 ) & 0x3f );
-        s[4] = 0x80 | ( ( c >> 6 ) & 0x3f );
-        s[5] = 0x80 | ( c & 0x3f );
-        s[6] = 0;
-        return 6;
-    } else {                    // illegal
-        return 0;
-    }
-}
-
-/*==============================================================================*
-*   Parser_UTF8ToInt
-*       In UTF-8, characters are encoded using sequences of 1 to 6 octets.
-*       This functions will return a UTF-8 character value and its octets number.
-*       Internal to parser only.
-*       Internal to parser only
-*          
-*===============================================================================*/
-static int
-Parser_UTF8ToInt( IN const char *ss,
-                  OUT int *len )
-{
-
-    const unsigned char *s = ( const unsigned char * )ss;
-    int c = *s;
-
-    if( c <= 127 ) {            // if c<=127, c is just the character.
-        *len = 1;
-        return c;
-    } else if( ( c & 0xE0 ) == 0xC0 && ( s[1] & 0xc0 ) == 0x80 ) {  // a sequence of 110xxxxx and 10xxxxxx?
-        *len = 2;
-        return ( ( ( c & 0x1f ) << 6 ) | ( s[1] & 0x3f ) );
-    } else if( ( c & 0xF0 ) == 0xE0 && ( s[1] & 0xc0 ) == 0x80 && ( s[2] & 0xc0 ) == 0x80 ) {   // a sequence of 1110xxxx,10xxxxxx and 10xxxxxx ?
-        *len = 3;
-        return ( ( ( c & 0xf ) << 12 ) | ( ( s[1] & 0x3f ) << 6 ) |
-                 ( s[2] & 0x3f ) );
-    } else if( ( c & 0xf8 ) == 0xf0 && ( s[1] & 0xc0 ) == 0x80 && ( s[2] & 0xc0 ) == 0x80 && ( s[3] & 0xc0 ) == 0x80 ) {    // a sequence of 11110xxx,10xxxxxx,10xxxxxx and 10xxxxxx ?
-        *len = 4;
-        return ( ( ( c & 0x7 ) << 18 ) | ( ( s[1] & 0x3f ) << 12 ) |
-                 ( ( s[2] & 0x3f ) << 6 ) | ( s[3] & 0x3f ) );
-    } else if( ( c & 0xfc ) == 0xf8 && ( s[1] & 0xc0 ) == 0x80 && ( s[2] & 0xc0 ) == 0x80 && ( s[3] & 0xc0 ) == 0x80 && ( s[4] & 0xc0 ) == 0x80 ) { // a sequence of 111110xx,10xxxxxx,10xxxxxx,10xxxxxx,10xxxxxx ?
-        *len = 5;
-        return ( ( ( c & 0x3 ) << 24 ) | ( ( s[1] & 0x3f ) << 18 ) |
-                 ( ( s[2] & 0x3f ) << 12 ) | ( ( s[3] & 0x3f ) << 6 ) |
-                 ( s[4] & 0x3f ) );
-    } else if( ( c & 0xfe ) == 0xfc && ( s[1] & 0xc0 ) == 0x80 && ( s[2] & 0xc0 ) == 0x80 && ( s[3] & 0xc0 ) == 0x80 && ( s[4] & 0xc0 ) == 0x80 && ( s[5] & 0xc0 ) == 0x80 ) {  // a sequence of 1111110x,10xxxxxx,10xxxxxx,10xxxxxx,10xxxxxx and 10xxxxxx ?
-        *len = 6;
-        return ( ( ( c & 0x1 ) << 30 ) | ( ( s[1] & 0x3f ) << 24 ) |
-                 ( ( s[2] & 0x3f ) << 18 ) | ( ( s[3] & 0x3f ) << 12 ) |
-                 ( ( s[4] & 0x3f ) << 6 ) | ( s[5] & 0x3f ) );
-    } else {                    // none of above, error
-        if (g_error_char) {
-            *len = 1;
-            return g_error_char;
-        } else {
-            *len = 0;
-            return -1;
-        }
-    }
-}
-
-/*==============================================================================*
-*   Parser_init
-*       Initializes a xml parser.
-*       Internal to parser only
-*			
-*===============================================================================*/
-static Parser *
-Parser_init(  )
-{
-    Parser *newParser = NULL;
-
-    newParser = ( Parser * ) malloc( sizeof( Parser ) );
-    if( newParser == NULL ) {
-        return NULL;
-    }
-
-    memset( newParser, 0, sizeof( Parser ) );
-
-    ixml_membuf_init( &( newParser->tokenBuf ) );
-    ixml_membuf_init( &( newParser->lastElem ) );
-
-    return newParser;
-}
-
-/*================================================================
-*   Parser_isValidEndElement
-*       check if a new node->nodeName matches top of element stack.
-*       Internal to parser only.
-*
-*=================================================================*/
-static int
-Parser_isValidEndElement( IN Parser * xmlParser,
-                          IN IXML_Node * newNode )
-{
-    return ( strcmp( xmlParser->pCurElement->element, newNode->nodeName )
-             == 0 );
-}
-
-/*===============================================================
-*   Parser_pushElement
-*       push a new element onto element stack
-*       Internal to parser only.
-*
-*=================================================================*/
-static int
-Parser_pushElement( IN Parser * xmlParser,
-                    IN IXML_Node * newElement )
-{
-
-    IXML_ElementStack *pCurElement = NULL;
-    IXML_ElementStack *pNewStackElement = NULL;
-
-    assert( newElement );
-    if( newElement != NULL ) {
-        // push new element
-        pNewStackElement =
-            ( IXML_ElementStack * ) malloc( sizeof( IXML_ElementStack ) );
-        if( pNewStackElement == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-
-        memset( pNewStackElement, 0, sizeof( IXML_ElementStack ) );
-        // the element member includes both prefix and name 
-
-        pNewStackElement->element = safe_strdup( newElement->nodeName );
-        if( pNewStackElement->element == NULL ) {
-            free( pNewStackElement );
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-
-        if( newElement->prefix != 0 ) {
-            pNewStackElement->prefix = safe_strdup( newElement->prefix );
-            if( pNewStackElement->prefix == NULL ) {
-                Parser_freeElementStackItem( pNewStackElement );
-                free( pNewStackElement );
-                return IXML_INSUFFICIENT_MEMORY;
-            }
-        }
-
-        if( newElement->namespaceURI != 0 ) {
-            pNewStackElement->namespaceUri =
-                safe_strdup( newElement->namespaceURI );
-            if( pNewStackElement->namespaceUri == NULL ) {
-                Parser_freeElementStackItem( pNewStackElement );
-                free( pNewStackElement );
-                return IXML_INSUFFICIENT_MEMORY;
-            }
-        }
-
-        pCurElement = xmlParser->pCurElement;
-
-        // insert the new element into the top of the stack
-        pNewStackElement->nextElement = pCurElement;
-        xmlParser->pCurElement = pNewStackElement;
-
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*================================================================
-*   Parser_popElement
-*       Remove element from element stack.
-*       Internal to parser only.       
-*
-*=================================================================*/
-static void
-Parser_popElement( IN Parser * xmlParser )
-{
-    IXML_ElementStack *pCur = NULL;
-    IXML_NamespaceURI *pnsUri = NULL,
-     *pNextNS = NULL;
-
-    pCur = xmlParser->pCurElement;
-    if( pCur != NULL ) {
-        xmlParser->pCurElement = pCur->nextElement;
-
-        Parser_freeElementStackItem( pCur );
-
-        pnsUri = pCur->pNsURI;
-        while( pnsUri != NULL ) {
-            pNextNS = pnsUri->nextNsURI;
-
-            Parser_freeNsURI( pnsUri );
-            free( pnsUri );
-            pnsUri = pNextNS;
-        }
-
-        free( pCur );
-    }
-
-}
-
-/*================================================================
-*   Parser_readFileOrBuffer
-*       read a xml file or buffer contents into xml parser.
-*       Internal to parser only.
-*
-*=================================================================*/
-static int
-Parser_readFileOrBuffer( IN Parser * xmlParser,
-                         IN const char *xmlFileName,
-                         IN BOOL file )
-{
-    int fileSize = 0;
-    int bytesRead = 0;
-    FILE *xmlFilePtr = NULL;
-
-    if( file ) {
-        xmlFilePtr = fopen( xmlFileName, "rb" );
-        if( xmlFilePtr == NULL ) {
-            return IXML_NO_SUCH_FILE;
-        } else {
-            fseek( xmlFilePtr, 0, SEEK_END );
-            fileSize = ftell( xmlFilePtr );
-            if( fileSize == 0 ) {
-                fclose( xmlFilePtr );
-                return IXML_SYNTAX_ERR;
-            }
-
-            xmlParser->dataBuffer = ( char * )malloc( fileSize + 1 );
-            if( xmlParser->dataBuffer == NULL ) {
-                fclose( xmlFilePtr );
-                return IXML_INSUFFICIENT_MEMORY;
-            }
-
-            fseek( xmlFilePtr, 0, SEEK_SET );
-            bytesRead =
-                fread( xmlParser->dataBuffer, 1, fileSize, xmlFilePtr );
-            xmlParser->dataBuffer[bytesRead] = '\0';    // append null
-            fclose( xmlFilePtr );
-        }
-    } else {
-        xmlParser->dataBuffer = safe_strdup( xmlFileName );
-        if( xmlParser->dataBuffer == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*================================================================
-*   Parser_LoadDocument
-*       parses a xml file and return the DOM tree.
-*       Internal to parser only
-*
-*=================================================================*/
-int
-Parser_LoadDocument( OUT IXML_Document ** retDoc,
-                     IN const char *xmlFileName,
-                     IN BOOL file )
-{
-    int rc = IXML_SUCCESS;
-    Parser *xmlParser = NULL;
-
-    xmlParser = Parser_init(  );
-    if( xmlParser == NULL ) {
-        return IXML_INSUFFICIENT_MEMORY;
-    }
-
-    rc = Parser_readFileOrBuffer( xmlParser, xmlFileName, file );
-    if( rc != IXML_SUCCESS ) {
-        Parser_free( xmlParser );
-        return rc;
-    }
-
-    xmlParser->curPtr = xmlParser->dataBuffer;
-    rc = Parser_parseDocument( retDoc, xmlParser );
-    return rc;
-
-}
-
-/*================================================================
-*   isTopLevelElement
-*       decides whether we have top level element already.
-*       Internal to parser only.
-*
-*=================================================================*/
-static int
-isTopLevelElement( IN Parser * xmlParser )
-{
-    assert( xmlParser );
-    return ( xmlParser->pCurElement == NULL );
-}
-
-/*================================================================
-*   isDuplicateAttribute
-*       Decide whether the new attribute is the same as an
-*       existing one.
-*       Internal to parser only.
-*
-*=================================================================*/
-static int
-isDuplicateAttribute( IN Parser * xmlParser,
-                      IN IXML_Node * newAttrNode )
-{
-    IXML_Node *elementNode = NULL;
-    IXML_Node *attrNode = NULL;
-
-    elementNode = xmlParser->currentNodePtr;
-    attrNode = elementNode->firstAttr;
-    while( attrNode != NULL ) {
-        if( strcmp( attrNode->nodeName, newAttrNode->nodeName ) == 0 ) {
-            return TRUE;
-        }
-
-        attrNode = attrNode->nextSibling;
-    }
-
-    return FALSE;
-}
-
-/*================================================================
-*   Parser_processAttributeName
-*       processes the attribute name.
-*       Internal to parser only.
-*
-*=================================================================*/
-static int
-Parser_processAttributeName( IN IXML_Document * rootDoc,
-                             IN Parser * xmlParser,
-                             IN IXML_Node * newNode )
-{
-    IXML_Attr *attr = NULL;
-    int rc = IXML_SUCCESS;
-
-    if( isDuplicateAttribute( xmlParser, newNode ) == TRUE ) {
-        return IXML_SYNTAX_ERR;
-    }
-
-    rc = ixmlDocument_createAttributeEx( rootDoc, newNode->nodeName,
-                                         &attr );
-    if( rc != IXML_SUCCESS ) {
-        return rc;
-    }
-
-    rc = ixmlNode_setNodeProperties( ( IXML_Node * ) attr, newNode );
-    if( rc != IXML_SUCCESS ) {
-        return rc;
-    }
-
-    rc = ixmlElement_setAttributeNode( ( IXML_Element * ) xmlParser->
-                                       currentNodePtr, attr, NULL );
-    return rc;
-}
-
-/*================================================================
-*   Parser_processElementName
-*       Processes element name 
-*       Internal to parser only.
-*
-*=================================================================*/
-static int
-Parser_processElementName( IN IXML_Document * rootDoc,
-                           IN Parser * xmlParser,
-                           IN IXML_Node * newNode )
-{
-    IXML_Element *newElement = NULL;
-    char *nsURI = NULL;
-    int rc = IXML_SUCCESS;
-
-    if( xmlParser->bHasTopLevel == TRUE ) {
-        if( isTopLevelElement( xmlParser ) == TRUE ) {
-            return IXML_SYNTAX_ERR;
-        }
-    } else {
-        xmlParser->bHasTopLevel = TRUE;
-    }
-
-    xmlParser->savePtr = xmlParser->curPtr;
-    rc = ixmlDocument_createElementEx( rootDoc, newNode->nodeName,
-                                       &newElement );
-    if( rc != IXML_SUCCESS ) {
-        return rc;
-    }
-
-    rc = ixmlNode_setNodeProperties( ( IXML_Node * ) newElement, newNode );
-    if( rc != IXML_SUCCESS ) {
-        ixmlElement_free( newElement );
-        return rc;
-    }
-
-    if( newNode->prefix != NULL ) { // element has namespace prefix 
-        if( Parser_ElementPrefixDefined( xmlParser, newNode, &nsURI ) !=
-            TRUE ) {
-            // read next node to see whether it includes namespace definition
-            xmlParser->pNeedPrefixNode = ( IXML_Node * ) newElement;
-        } else {                // fill in the namespace
-            Parser_setElementNamespace( newElement, nsURI );
-        }
-    } else                      // does element has default namespace
-    {
-        // the node may have default namespace definition
-        if( Parser_hasDefaultNamespace( xmlParser, newNode, &nsURI ) ==
-            TRUE ) {
-            Parser_setElementNamespace( newElement, nsURI );
-        } else if( xmlParser->state == eATTRIBUTE ) {
-            // the default namespace maybe defined later
-            xmlParser->pNeedPrefixNode = ( IXML_Node * ) newElement;
-        }
-    }
-
-    rc = ixmlNode_appendChild( xmlParser->currentNodePtr,
-                               ( IXML_Node * ) newElement );
-    if( rc != IXML_SUCCESS ) {
-        ixmlElement_free( newElement );
-        return rc;
-    }
-
-    xmlParser->currentNodePtr = ( IXML_Node * ) newElement;
-
-    // push element to stack
-    rc = Parser_pushElement( xmlParser, ( IXML_Node * ) newElement );
-    return rc;
-}
-
-/*================================================================
-*   Parser_eTagVerification
-*       Verifies endof element tag is the same as the openning 
-*       element tag.
-*       Internal to parser only.
-*
-*=================================================================*/
-static int
-Parser_eTagVerification( IN Parser * xmlParser,
-                         IN IXML_Node * newNode )
-{
-
-    assert( newNode->nodeName );
-    assert( xmlParser->currentNodePtr );
-
-    if( newNode->nodeType == eELEMENT_NODE ) {
-        if( Parser_isValidEndElement( xmlParser, newNode ) == TRUE ) {
-            Parser_popElement( xmlParser );
-        } else {                // syntax error
-            return IXML_SYNTAX_ERR;
-        }
-    }
-
-    if( strcmp( newNode->nodeName, xmlParser->currentNodePtr->nodeName ) ==
-        0 ) {
-        xmlParser->currentNodePtr = xmlParser->currentNodePtr->parentNode;
-    } else {
-        return IXML_SYNTAX_ERR;
-    }
-
-    return IXML_SUCCESS;
-
-}
-
-/*================================================================
-*   Parser_freeNodeContent
-*       frees a node contents
-*       Internal to parser only.
-*
-*=================================================================*/
-void
-Parser_freeNodeContent( IN IXML_Node * nodeptr )
-{
-
-    if( nodeptr == NULL ) {
-        return;
-    }
-
-    if( nodeptr->nodeName != NULL ) {
-        free( nodeptr->nodeName );
-    }
-
-    if( nodeptr->nodeValue != NULL ) {
-        free( nodeptr->nodeValue );
-    }
-
-    if( nodeptr->namespaceURI != NULL ) {
-        free( nodeptr->namespaceURI );
-    }
-
-    if( nodeptr->prefix != NULL ) {
-        free( nodeptr->prefix );
-    }
-
-    if( nodeptr->localName != NULL ) {
-        free( nodeptr->localName );
-    }
-
-}
-
-/*================================================================
-*   Parser_parseDocument
-*       Parses the xml file and returns the DOM document tree.
-*       External function.
-*
-*=================================================================*/
-static int
-Parser_parseDocument( OUT IXML_Document ** retDoc,
-                      IN Parser * xmlParser )
-{
-
-    IXML_Document *gRootDoc = NULL;
-    IXML_Node newNode;
-    BOOL bETag = FALSE;
-    IXML_Node *tempNode = NULL;
-    int rc = IXML_SUCCESS;
-    IXML_CDATASection *cdataSecNode = NULL;
-
-    ixmlNode_init( &newNode );
-
-    rc = ixmlDocument_createDocumentEx( &gRootDoc );
-    if( rc != IXML_SUCCESS ) {
-        goto ErrorHandler;
-    }
-
-    xmlParser->currentNodePtr = ( IXML_Node * ) gRootDoc;
-
-    rc = Parser_skipProlog( xmlParser );
-    if( rc != IXML_SUCCESS ) {
-        goto ErrorHandler;
-    }
-
-    while( bETag == FALSE ) {
-        // clear the newNode contents
-        ixmlNode_init( &newNode );
-
-        if( Parser_getNextNode( xmlParser, &newNode, &bETag ) ==
-            IXML_SUCCESS ) {
-            if( bETag == FALSE ) {
-                switch ( newNode.nodeType ) {
-                    case eELEMENT_NODE:
-                        rc = Parser_processElementName( gRootDoc,
-                                                        xmlParser,
-                                                        &newNode );
-                        if( rc != IXML_SUCCESS ) {
-                            goto ErrorHandler;
-                        }
-                        break;
-
-                    case eTEXT_NODE:
-                        rc = ixmlDocument_createTextNodeEx( gRootDoc,
-                                                            newNode.
-                                                            nodeValue,
-                                                            &tempNode );
-                        if( rc != IXML_SUCCESS ) {
-                            goto ErrorHandler;
-                        }
-
-                        rc = ixmlNode_appendChild( xmlParser->
-                                                   currentNodePtr,
-                                                   tempNode );
-                        if( rc != IXML_SUCCESS ) {
-                            goto ErrorHandler;
-                        }
-
-                        break;
-
-                    case eCDATA_SECTION_NODE:
-                        rc = ixmlDocument_createCDATASectionEx( gRootDoc,
-                                                                newNode.
-                                                                nodeValue,
-                                                                &cdataSecNode );
-                        if( rc != IXML_SUCCESS ) {
-                            goto ErrorHandler;
-                        }
-
-                        rc = ixmlNode_appendChild( xmlParser->
-                                                   currentNodePtr,
-                                                   &( cdataSecNode->n ) );
-                        if( rc != IXML_SUCCESS ) {
-                            goto ErrorHandler;
-                        }
-                        break;
-
-                    case eATTRIBUTE_NODE:
-                        rc = Parser_processAttributeName( gRootDoc,
-                                                          xmlParser,
-                                                          &newNode );
-                        if( rc != IXML_SUCCESS ) {
-                            goto ErrorHandler;
-                        }
-                        break;
-
-                    default:
-                        break;
-                }
-            } else              // ETag==TRUE, endof element tag.  
-            {
-                rc = Parser_eTagVerification( xmlParser, &newNode );
-                if( rc != IXML_SUCCESS ) {
-                    goto ErrorHandler;
-                }
-                xmlParser->state = eCONTENT;
-            }
-
-            // reset bETag flag
-            bETag = FALSE;
-
-        } else if( bETag == TRUE ) {    // file is done
-            break;
-        } else {
-            rc = IXML_FAILED;
-            goto ErrorHandler;
-        }
-        Parser_freeNodeContent( &newNode );
-
-    }
-
-    if( xmlParser->pCurElement != NULL ) {
-        rc = IXML_SYNTAX_ERR;
-        goto ErrorHandler;
-    }
-
-    *retDoc = ( IXML_Document * ) gRootDoc;
-    Parser_free( xmlParser );
-    return rc;
-
-  ErrorHandler:
-    Parser_freeNodeContent( &newNode );
-    ixmlDocument_free( gRootDoc );
-    Parser_free( xmlParser );
-    return rc;
-
-}
-
-/*==============================================================================*
-*   Parser_setLastElem
-*       set the last element to be the given string.
-*       Internal to parser only.			
-*
-*===============================================================================*/
-static int
-Parser_setLastElem( IN Parser * xmlParser,
-                    IN const char *s )
-{
-    int rc;
-
-    if( ( xmlParser == NULL ) || ( s == NULL ) ) {
-        return IXML_FAILED;
-    }
-
-    rc = ixml_membuf_assign_str( &( xmlParser->lastElem ), s );
-    return rc;
-}
-
-/*==============================================================================*
-*
-*   Parser_clearTokenBuf
-*       clear token buffer.
-*       Internal to parser only.
-*
-*===============================================================================*/
-static void
-Parser_clearTokenBuf( IN Parser * xmlParser )
-{
-    ixml_membuf_destroy( &( xmlParser->tokenBuf ) );
-}
-
-/*==============================================================================*
-*
-*   Parser_appendTokBufStr
-*       Appends string s to token buffer
-*       Internal to parser only.
-*       
-*===============================================================================*/
-static int
-Parser_appendTokBufStr( IN Parser * xmlParser,
-                        IN const char *s )
-{
-    int rc = IXML_SUCCESS;
-
-    if( s != NULL ) {
-        rc = ixml_membuf_append_str( &( xmlParser->tokenBuf ), s );
-    }
-
-    return rc;
-}
-
-/*==============================================================================*
-*
-*   Parser_appendTokBufChar   
-*       Appends c to token buffer.
-*       Internal to parser only.
-*
-*===============================================================================*/
-static int
-Parser_appendTokBufChar( IN Parser * xmlParser,
-                         IN char c )
-{
-    int rc;
-
-    rc = ixml_membuf_append( &( xmlParser->tokenBuf ), &c );
-    return rc;
-}
-
-/*==============================================================================*
-*
-*   Parser_skipWhiteSpaces
-*       skip white spaces 
-*       Internal to parser only			
-*
-*===============================================================================*/
-static void
-Parser_skipWhiteSpaces( IN Parser * xmlParser )
-{
-    while( ( *( xmlParser->curPtr ) != 0 ) &&
-           ( strchr( WHITESPACE, *( xmlParser->curPtr ) ) != NULL ) ) {
-        xmlParser->curPtr++;
-    }
-
-}
-
-/*==============================================================================*
-*   Parser_getChar	
-*       returns next char value and its length			
-*       Internal to parser only
-*
-*===============================================================================*/
-static int
-Parser_getChar( IN const char *src,
-                INOUT int *cLen )
-{
-    const char *pnum;
-    int sum;
-    char c;
-    int i;
-
-    if( src == NULL || cLen == NULL ) {
-        return -1;
-    }
-
-    *cLen = 0;
-
-    if( *src != '&' ) {
-        if( *src > 0 && Parser_isXmlChar( *src ) ) {
-            *cLen = 1;
-            return *src;
-        }
-
-        i = Parser_UTF8ToInt( src, cLen );
-        if( !Parser_isXmlChar( i ) ) {
-            return ( g_error_char ? g_error_char : -1 );
-        }
-        return i;
-    } else if( strncasecmp( src, QUOT, strlen( QUOT ) ) == 0 ) {
-        *cLen = strlen( QUOT );
-        return '"';
-    } else if( strncasecmp( src, LT, strlen( LT ) ) == 0 ) {
-        *cLen = strlen( LT );
-        return '<';
-    } else if( strncasecmp( src, GT, strlen( GT ) ) == 0 ) {
-        *cLen = strlen( GT );
-        return '>';
-    } else if( strncasecmp( src, APOS, strlen( APOS ) ) == 0 ) {
-        *cLen = strlen( APOS );
-        return '\'';
-    } else if( strncasecmp( src, AMP, strlen( AMP ) ) == 0 ) {
-        *cLen = strlen( AMP );
-        return '&';
-    } else if( strncasecmp( src, ESC_HEX, strlen( ESC_HEX ) ) == 0 ) {  // Read in escape characters of type &#xnn where nn is a hexadecimal value
-        pnum = src + strlen( ESC_HEX );
-        sum = 0;
-        while( strchr( HEX_NUMBERS, *pnum ) != 0 ) {
-            c = *pnum;
-            if( c <= '9' ) {
-                sum = sum * 16 + ( c - '0' );
-            } else if( c <= 'F' ) {
-                sum = sum * 16 + ( c - 'A' + 10 );
-            } else {
-                sum = sum * 16 + ( c - 'a' + 10 );
-            }
-
-            pnum++;
-        }
-
-        if( ( pnum == src ) || *pnum != ';' || !Parser_isXmlChar( sum ) ) {
-            goto fail_entity;
-        }
-
-        *cLen = pnum - src + 1;
-        return sum;
-
-    } else if( strncasecmp( src, ESC_DEC, strlen( ESC_DEC ) ) == 0 ) {
-        // Read in escape characters of type &#nn where nn is a decimal value
-        pnum = src + strlen( ESC_DEC );
-        sum = 0;
-        while( strchr( DEC_NUMBERS, *pnum ) != 0 ) {
-            sum = sum * 10 + ( *pnum - '0' );
-            pnum++;
-        }
-
-        if( ( pnum == src ) || *pnum != ';' || !Parser_isXmlChar( sum ) ) {
-            goto fail_entity;
-        }
-
-        *cLen = pnum - src + 1;
-        return sum;
-    }
-
-fail_entity:
-    if (g_error_char) {
-        *cLen = 1;
-        return '&';
-    }
-    return -1;
-}
-
-/*==============================================================================*
-*   Parser_copyToken	
-*       copy string in src into xml parser token buffer
-*		Internal to parser only.	
-*
-*===============================================================================*/
-static int
-Parser_copyToken( IN Parser * xmlParser,
-                  IN const char *src,
-                  IN int len )
-{
-    int i,
-      c,
-      cl;
-    const char *psrc,
-     *pend;
-    utf8char uch;
-
-    if( !src || len <= 0 ) {
-        return IXML_FAILED;
-    }
-
-    psrc = src;
-    pend = src + len;
-
-    while( psrc < pend ) {
-        if( ( c = Parser_getChar( psrc, &cl ) ) <= 0 ) {
-            return IXML_FAILED;
-        }
-
-        if( cl == 1 ) {
-            Parser_appendTokBufChar( xmlParser, ( char )c );
-            psrc++;
-        } else {
-
-            i = Parser_intToUTF8( c, uch );
-            if( i == 0 ) {
-                return IXML_FAILED;
-            }
-
-            Parser_appendTokBufStr( xmlParser, uch );
-            psrc += cl;
-        }
-    }
-
-    if( psrc > pend ) {
-        return IXML_FAILED;
-    } else {
-        return IXML_SUCCESS;    // success
-    }
-
-}
-
-/*==============================================================================*
-*
-*   Parser_skipString
-*       Skips all characters in the string until it finds the skip key.
-*       Then it skips the skip key and returns.
-*       Internal to parser only
-*
-*===============================================================================*/
-static int
-Parser_skipString( INOUT char **pstrSrc,
-                   IN const char *strSkipKey )
-{
-    if( !( *pstrSrc ) || !strSkipKey ) {
-        return IXML_FAILED;
-    }
-
-    while( ( **pstrSrc )
-           && strncmp( *pstrSrc, strSkipKey,
-                       strlen( strSkipKey ) ) != 0 ) {
-        ( *pstrSrc )++;
-    }
-
-    if( **pstrSrc == '\0' ) {
-        return IXML_SYNTAX_ERR;
-    }
-    *pstrSrc = *pstrSrc + strlen( strSkipKey );
-
-    return IXML_SUCCESS;        //success
-}
-
-/*==============================================================================*
-*
-* Function:	
-* Returns:	
-*			
-*
-*===============================================================================*/
-static int
-Parser_skipPI( INOUT char **pSrc )
-{
-    char *pEnd = NULL;
-
-    assert( *pSrc );
-    if( *pSrc == NULL ) {
-        return IXML_FAILED;
-    }
-
-    if( ( strncasecmp( *pSrc, ( char * )XMLDECL, strlen( XMLDECL ) ) == 0 ) || ( strncasecmp( *pSrc, ( char * )XMLDECL2, strlen( XMLDECL2 ) ) == 0 ) ) {    // not allowed
-        return IXML_SYNTAX_ERR;
-    }
-
-    if( strncasecmp( *pSrc, ( char * )BEGIN_PI, strlen( BEGIN_PI ) ) == 0 ) {
-        pEnd = strstr( *pSrc, END_PI );
-        if( ( pEnd != NULL ) && ( pEnd != *pSrc ) ) {
-            *pSrc = pEnd + strlen( BEGIN_PI );
-        } else {
-            return IXML_SYNTAX_ERR;
-        }
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*==============================================================================*
-*   Parser_skipXMLDecl:	
-*       skips XML declarations.
-*       Internal only to parser.			
-*
-*===============================================================================*/
-static int
-Parser_skipXMLDecl( INOUT Parser * xmlParser )
-{
-    int rc = IXML_FAILED;
-
-    assert( xmlParser );
-    if( xmlParser == NULL ) {
-        return rc;
-    }
-
-    rc = Parser_skipString( &( xmlParser->curPtr ), END_PI );
-    Parser_skipWhiteSpaces( xmlParser );
-    return rc;
-
-}
-
-/*==============================================================================*
-*   Parser_skipProlog
-*       skip prolog
-*       Internal to parser only.			
-*
-*===============================================================================*/
-static int
-Parser_skipProlog( INOUT Parser * xmlParser )
-{
-    int rc = IXML_SUCCESS;
-
-    assert( xmlParser != NULL );
-    if( xmlParser == NULL ) {
-        return IXML_FAILED;
-    }
-
-    Parser_skipWhiteSpaces( xmlParser );
-
-    if( strncmp( xmlParser->curPtr, ( char * )XMLDECL, strlen( XMLDECL ) ) == 0 ) { // <?xml
-        rc = Parser_skipXMLDecl( xmlParser );
-        if( rc != IXML_SUCCESS ) {
-            return rc;
-        }
-    }
-
-    rc = Parser_skipMisc( xmlParser );
-    if( ( rc == IXML_SUCCESS ) && strncmp( xmlParser->curPtr, ( char * )BEGIN_DOCTYPE, strlen( BEGIN_DOCTYPE ) ) == 0 ) {   // <! DOCTYPE
-        xmlParser->curPtr++;
-        rc = Parser_skipDocType( &( xmlParser->curPtr ) );
-    }
-
-    if( rc == IXML_SUCCESS ) {
-        rc = Parser_skipMisc( xmlParser );
-    }
-
-    return rc;
-}
-
-/*==============================================================================*
-*
-* Function:
-* Returns:
-*       Skips all characters in the string until it finds the skip key.
-*       Then it skips the skip key and returns.
-*
-*===============================================================================*/
-static int
-Parser_skipComment( INOUT char **pstrSrc )
-{
-    char *pStrFound = NULL;
-
-    assert( ( *pstrSrc ) != NULL );
-    if( *pstrSrc == NULL ) {
-        return IXML_FAILED;
-    }
-
-    pStrFound = strstr( *pstrSrc, END_COMMENT );
-    if( ( pStrFound != NULL ) && ( pStrFound != *pstrSrc ) &&
-        ( *( pStrFound - 1 ) != '-' ) ) {
-        *pstrSrc = pStrFound + strlen( END_COMMENT );
-    } else {
-        return IXML_SYNTAX_ERR;
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*==============================================================================*
-*   Parser_skipDocType
-*       skips document type declaration
-*
-*===============================================================================*/
-static int
-Parser_skipDocType( INOUT char **pstr )
-{
-    char *pCur = *pstr;
-    char *pNext = NULL;         // default there is no nested <
-    int num = 1;
-
-    assert( ( *pstr ) != NULL );
-    if( *pstr == NULL ) {
-        return IXML_FAILED;
-    }
-
-    while( ( pCur != NULL ) && ( num != 0 ) && ( *pCur != 0 ) ) {
-        if( *pCur == '<' ) {
-            num++;
-        } else if( *pCur == '>' ) {
-            num--;
-        } else if( *pCur == '"' ) {
-            pNext = strchr( pCur + 1, '"' );
-            if( pNext == NULL ) {
-                return IXML_SYNTAX_ERR;
-            }
-
-            pCur = pNext;
-        }
-
-        pCur++;
-    }
-
-    if( num == 0 ) {
-        *pstr = pCur;
-        return IXML_SUCCESS;
-    } else {
-        return IXML_SYNTAX_ERR;
-    }
-}
-
-/*==============================================================================*
-*
-*   Parser_skipMisc:	
-*       skip comment, PI and white space 
-*			
-*
-*===============================================================================*/
-static int
-Parser_skipMisc( IN Parser * xmlParser )
-{
-    int rc = IXML_SUCCESS;
-    int done = FALSE;
-
-    while( ( done == FALSE ) && ( rc == IXML_SUCCESS ) ) {
-        if( strncasecmp( xmlParser->curPtr, ( char * )BEGIN_COMMENT, strlen( BEGIN_COMMENT ) ) == 0 ) { // <!--
-            rc = Parser_skipComment( &( xmlParser->curPtr ) );
-
-        } else if( ( strncasecmp( xmlParser->curPtr, ( char * )XMLDECL, strlen( XMLDECL ) ) == 0 ) || ( strncasecmp( xmlParser->curPtr, ( char * )XMLDECL2, strlen( XMLDECL2 ) ) == 0 ) ) { // <?xml or <?xml?
-            rc = IXML_SYNTAX_ERR;
-        } else if( strncasecmp( xmlParser->curPtr, ( char * )BEGIN_PI, strlen( BEGIN_PI ) ) == 0 ) {    // <?
-            rc = Parser_skipString( &( xmlParser->curPtr ), END_PI );
-        } else {
-            done = TRUE;
-        }
-
-        Parser_skipWhiteSpaces( xmlParser );
-    }
-
-    return rc;
-}
-
-/*==============================================================================*
-*
-*   Parser_getNextToken
-*       return the length of next token in tokenBuff
-*			
-*
-*===============================================================================*/
-static int
-Parser_getNextToken( IN Parser * xmlParser )
-{
-    int tokenLength = 0;
-    int temp,
-      tlen;
-    int rc;
-
-    Parser_clearTokenBuf( xmlParser );
-
-    if( *( xmlParser->curPtr ) == '\0' ) {
-        return 0;
-    }
-    // skip XML instructions
-    rc = Parser_skipMisc( xmlParser );
-    if( rc != IXML_SUCCESS ) {
-        return 0;
-    }
-    // Attribute value logic must come first, since all text untokenized until end-quote
-    if( *( xmlParser->curPtr ) == QUOTE ) {
-        tokenLength = 1;
-    } else if( *( xmlParser->curPtr ) == SINGLEQUOTE ) {
-        tokenLength = 1;
-    } else if( *( xmlParser->curPtr ) == LESSTHAN ) {   // Check for start tags
-        temp = Parser_UTF8ToInt( xmlParser->curPtr + 1, &tlen );
-        if( temp == '/' ) {
-            tokenLength = 2;    // token is '</' end tag
-        } else if( Parser_isNameChar( temp, FALSE ) == TRUE ) {
-            tokenLength = 1;    // '<' found, so return '<' token
-        } else {
-            return 0;           //error
-        }
-    } else if( *( xmlParser->curPtr ) == EQUALS ) { // Check for '=' token, return it as a token
-        tokenLength = 1;
-    } else if( *( xmlParser->curPtr ) == SLASH ) {
-        if( *( xmlParser->curPtr + 1 ) == GREATERTHAN ) {   // token '/>' found
-            tokenLength = 2;
-            xmlParser->savePtr = xmlParser->curPtr; // fix
-        }
-    } else if( *( xmlParser->curPtr ) == GREATERTHAN ) {    // > found, so return it as a token
-        tokenLength = 1;
-    } else if( Parser_isNameChar( Parser_UTF8ToInt( xmlParser->curPtr, &tlen ), FALSE ) ) { // Check for name tokens, name found, so find out how long it is
-        int iIndex = tlen;
-
-        while( Parser_isNameChar
-               ( Parser_UTF8ToInt( xmlParser->curPtr + iIndex, &tlen ),
-                 TRUE ) ) {
-            iIndex += tlen;
-        }
-        tokenLength = iIndex;
-    } else {
-        return 0;
-    }
-
-    // Copy the token to the return string
-    if( Parser_copyToken( xmlParser, xmlParser->curPtr, tokenLength ) !=
-        IXML_SUCCESS ) {
-        return 0;
-    }
-
-    xmlParser->curPtr += tokenLength;
-    return tokenLength;
-}
-
-/*==============================================================================*
-*
-*   Parser_getNameSpace	
-*       return the namespce as defined as prefix.
-*       Internal to parser only			
-*
-*===============================================================================*/
-static char *
-Parser_getNameSpace( IN Parser * xmlParser,
-                     IN const char *prefix )
-{
-    IXML_ElementStack *pCur;
-    IXML_NamespaceURI *pNsUri;
-
-    pCur = xmlParser->pCurElement;
-    if( strcmp( pCur->prefix, prefix ) != 0 ) {
-        pNsUri = pCur->pNsURI;
-        while( pNsUri != NULL ) {
-            if( strcmp( pNsUri->prefix, prefix ) == 0 ) {
-                return pNsUri->nsURI;
-            }
-            pNsUri = pNsUri->nextNsURI;
-        }
-    } else {
-        return pCur->namespaceUri;
-    }
-
-    return NULL;
-
-}
-
-/*==============================================================================*
-*
-*   Parser_addNamespace
-*       Add a namespace definition
-*       Internal to parser only			
-*
-*===============================================================================*/
-static int
-Parser_addNamespace( IN Parser * xmlParser )
-{
-    IXML_Node *pNode;
-    IXML_ElementStack *pCur;
-    const char *namespaceUri;
-
-    pNode = xmlParser->pNeedPrefixNode;
-    pCur = xmlParser->pCurElement;
-
-    if( pNode->prefix == NULL ) {   // element does not have prefix
-        if( strcmp( pNode->nodeName, pCur->element ) != 0 ) {
-            return IXML_FAILED;
-        }
-        if( pCur->namespaceUri != NULL ) {
-            // it would be wrong that pNode->namespace != NULL.
-            assert( pNode->namespaceURI == NULL );
-
-            pNode->namespaceURI = safe_strdup( pCur->namespaceUri );
-            if( pNode->namespaceURI == NULL ) {
-                return IXML_INSUFFICIENT_MEMORY;
-            }
-        }
-
-        xmlParser->pNeedPrefixNode = NULL;
-
-    } else {
-        if( ( strcmp( pNode->nodeName, pCur->element ) != 0 ) &&
-            ( strcmp( pNode->prefix, pCur->prefix ) != 0 ) ) {
-            return IXML_FAILED;
-        }
-
-        namespaceUri = Parser_getNameSpace( xmlParser, pCur->prefix );
-        if( namespaceUri != NULL ) {
-            pNode->namespaceURI = safe_strdup( namespaceUri );
-            if( pNode->namespaceURI == NULL ) {
-                return IXML_INSUFFICIENT_MEMORY;
-            }
-
-            xmlParser->pNeedPrefixNode = NULL;
-        }
-    }
-    return IXML_SUCCESS;
-}
-
-/*==============================================================================*
-*
-*   Parser_setNodePrefixAndLocalName
-*       set the node prefix and localName as defined by the nodeName
-*       in the form of ns:name
-*       Internal to parser only.			
-*
-*===============================================================================*/
-int
-Parser_setNodePrefixAndLocalName( IN IXML_Node * node )
-{
-
-    char *pStrPrefix = NULL;
-    char *pLocalName;
-    int nPrefix;
-
-    assert( node != NULL );
-    if( node == NULL ) {
-        return IXML_FAILED;
-    }
-
-    pStrPrefix = strchr( node->nodeName, ':' );
-    if( pStrPrefix == NULL ) {
-        node->prefix = NULL;
-        node->localName = safe_strdup( node->nodeName );
-        if( node->localName == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-
-    } else {                    // fill in the local name and prefix
-
-        pLocalName = ( char * )pStrPrefix + 1;
-        nPrefix = pStrPrefix - node->nodeName;
-        node->prefix = malloc( nPrefix + 1 );
-        if( node->prefix == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-
-        memset( node->prefix, 0, nPrefix + 1 );
-        strncpy( node->prefix, node->nodeName, nPrefix );
-
-        node->localName = safe_strdup( pLocalName );
-        if( node->localName == NULL ) {
-            free( node->prefix );
-            node->prefix = NULL;    //no need to free really, main loop will frees it
-            //when return code is not success
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*==============================================================================*
-*
-*   Parser_xmlNamespace
-*       add namespace definition. 
-*       internal to parser only.			
-*
-*===============================================================================*/
-static int
-Parser_xmlNamespace( IN Parser * xmlParser,
-                     IN IXML_Node * newNode )
-{
-
-    IXML_ElementStack *pCur = xmlParser->pCurElement;
-    IXML_NamespaceURI *pNewNs = NULL,
-     *pNs = NULL,
-     *pPrevNs = NULL;
-    int rc;
-
-    // if the newNode contains a namespace definition
-    assert( newNode->nodeName != NULL );
-
-    if( strcmp( newNode->nodeName, "xmlns" ) == 0 ) // default namespace def.
-    {
-        if( pCur->namespaceUri != NULL ) {
-            free( pCur->namespaceUri );
-        }
-///here it goes to segfault on "" when not copying
-	if(newNode->nodeValue){
-         pCur->namespaceUri = safe_strdup( newNode->nodeValue );
-         if( pCur->namespaceUri == NULL ) {
-             return IXML_INSUFFICIENT_MEMORY;
-         }
-    }
-
-    } else if( strncmp( newNode->nodeName, "xmlns:", strlen( "xmlns:" ) ) == 0 ) {  // namespace definition
-        rc = Parser_setNodePrefixAndLocalName( newNode );
-        if( rc != IXML_SUCCESS ) {
-            return rc;
-        }
-
-        assert( newNode->localName != NULL );
-
-        if( pCur == NULL ) {
-            return IXML_FAILED;
-        }
-
-        if( ( pCur->prefix != NULL )
-            && ( strcmp( pCur->prefix, newNode->localName ) == 0 ) ) {
-            pCur->namespaceUri = safe_strdup( newNode->nodeValue );
-            if( pCur->namespaceUri == NULL ) {
-                return IXML_INSUFFICIENT_MEMORY;
-            }
-        } else {
-            pPrevNs = pCur->pNsURI;
-            pNs = pPrevNs;
-            while( pNs != NULL ) {
-                if( ( pNs->prefix != NULL ) &&
-                    ( strcmp( pNs->prefix, newNode->localName ) == 0 ) ) {
-                    break;      // replace namespace definition
-                } else {
-                    pPrevNs = pNs;
-                    pNs = pNs->nextNsURI;
-                }
-            }
-
-            if( pNs == NULL )   // a new definition
-            {
-                pNewNs =
-                    ( IXML_NamespaceURI * )
-                    malloc( sizeof( IXML_NamespaceURI ) );
-                if( pNewNs == NULL ) {
-                    return IXML_INSUFFICIENT_MEMORY;
-                }
-                memset( pNewNs, 0, sizeof( IXML_NamespaceURI ) );
-
-                pNewNs->prefix = safe_strdup( newNode->localName );
-                if( pNewNs->prefix == NULL ) {
-                    free( pNewNs );
-                    return IXML_INSUFFICIENT_MEMORY;
-                }
-
-                pNewNs->nsURI = safe_strdup( newNode->nodeValue );
-                if( pNewNs->nsURI == NULL ) {
-                    Parser_freeNsURI( pNewNs );
-                    free( pNewNs );
-                    return IXML_INSUFFICIENT_MEMORY;
-                }
-
-                if( pCur->pNsURI == NULL ) {
-                    pCur->pNsURI = pNewNs;
-                } else {
-                    pPrevNs->nextNsURI = pNewNs;
-                }
-            } else              // udpate the namespace
-            {
-                if( pNs->nsURI != NULL ) {
-                    free( pNs->nsURI );
-                }
-
-                pNs->nsURI = safe_strdup( newNode->nodeValue );
-                if( pNs->nsURI == NULL ) {
-                    return IXML_INSUFFICIENT_MEMORY;
-                }
-            }
-        }
-    }
-
-    if( xmlParser->pNeedPrefixNode != NULL ) {
-        rc = Parser_addNamespace( xmlParser );
-        return rc;
-    } else {
-        return IXML_SUCCESS;
-    }
-
-}
-
-/*==============================================================================*
-*
-*   Parser_processSTag:	
-*       Processes the STag as defined by XML spec. 
-*       Internal to parser only.			
-*
-*===============================================================================*/
-static int
-Parser_processSTag( IN Parser * xmlParser,
-                    IN IXML_Node * node )
-{
-    char *pCurToken = NULL;
-    int rc;
-
-    if( Parser_getNextToken( xmlParser ) == 0 ) {
-        return IXML_SYNTAX_ERR;
-    }
-
-    pCurToken = ( xmlParser->tokenBuf ).buf;
-    if( pCurToken != NULL ) {
-        node->nodeName = safe_strdup( pCurToken );
-        if( node->nodeName == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-    } else {
-        return IXML_SYNTAX_ERR;
-    }
-
-    rc = Parser_setLastElem( xmlParser, node->nodeName );
-    if( rc != IXML_SUCCESS ) {  // no need to free node->nodeName, main loop will free it
-        return IXML_FAILED;
-    }
-
-    rc = Parser_setNodePrefixAndLocalName( node );
-    if( rc != IXML_SUCCESS ) {  // no need to free node->nodeName, main loop will free it
-        return IXML_FAILED;
-    }
-
-    node->nodeValue = NULL;
-    node->nodeType = eELEMENT_NODE;
-
-    xmlParser->savePtr = xmlParser->curPtr;
-    if( Parser_getNextToken( xmlParser ) == 0 ) {   // no need to free node->nodeName, main loop will free it
-        return IXML_SYNTAX_ERR;
-    }
-
-    pCurToken = ( xmlParser->tokenBuf ).buf;
-    // check to see what is the next token
-    if( strcmp( pCurToken, "/>" ) == 0 )    // empty element 
-    {
-        xmlParser->state = eELEMENT;
-        xmlParser->curPtr = xmlParser->savePtr; // backup to /> 
-    } else if( strcmp( pCurToken, ">" ) == 0 )  // expecting text node
-    {
-        xmlParser->state = eCONTENT;
-    } else {
-        xmlParser->state = eATTRIBUTE;
-        xmlParser->curPtr = xmlParser->savePtr;
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*==============================================================================*
-*
-*   Parser_hasDefaultNamespace   	
-*       decide whether the current element has default namespace
-*       Internal to parser only.       			
-*
-*===============================================================================*/
-static BOOL
-Parser_hasDefaultNamespace( IN Parser * xmlParser,
-                            IN IXML_Node * newNode,
-                            IN char **nsURI )
-{
-    IXML_ElementStack *pCur = xmlParser->pCurElement;
-
-    while( pCur != NULL ) {
-        if( ( pCur->prefix == NULL ) && ( pCur->namespaceUri != NULL ) ) {
-            *nsURI = pCur->namespaceUri;
-            return TRUE;
-        } else {
-            pCur = pCur->nextElement;
-        }
-    }
-
-    return FALSE;
-
-}
-
-/*==============================================================================*
-*
-*   Parser_ElementPrefixDefined
-*       decides whether element's prefix is already defined.
-*       Internal to parser only. 
-*
-*===============================================================================*/
-static BOOL
-Parser_ElementPrefixDefined( IN Parser * xmlParser,
-                             IN IXML_Node * newNode,
-                             IN char **nsURI )
-{
-
-    IXML_ElementStack *pCur = xmlParser->pCurElement;
-    IXML_NamespaceURI *pNsUri;
-
-    while( pCur != NULL ) {
-        if( ( pCur->prefix != NULL )
-            && ( strcmp( pCur->prefix, newNode->prefix ) == 0 ) ) {
-            *nsURI = pCur->namespaceUri;
-            return TRUE;
-        } else {
-            pNsUri = pCur->pNsURI;
-
-            while( pNsUri != NULL ) {
-                if( strcmp( pNsUri->prefix, newNode->prefix ) == 0 ) {
-                    *nsURI = pNsUri->nsURI;
-                    return TRUE;
-                } else {
-                    pNsUri = pNsUri->nextNsURI;
-                }
-            }
-        }
-
-        pCur = pCur->nextElement;
-
-    }
-
-    return FALSE;
-
-}
-
-/*==============================================================================*
-*
-*   Parser_processCDSect   
-*       Processes CDSection as defined by XML spec.
-*       Internal to parser only.
-*
-*===============================================================================*/
-static int
-Parser_processCDSect( IN char **pSrc,
-                      IN IXML_Node * node )
-{
-
-    char *pEnd;
-    int tokenLength = 0;
-    char *pCDataStart;
-
-    if( *pSrc == NULL ) {
-        return IXML_FAILED;
-    }
-
-    pCDataStart = *pSrc + strlen( CDSTART );
-    pEnd = pCDataStart;
-    while( ( Parser_isXmlChar( *pEnd ) == TRUE ) && ( *pEnd != '\0' ) ) {
-        if( strncmp( pEnd, CDEND, strlen( CDEND ) ) == 0 ) {
-            break;
-        } else {
-            pEnd++;
-        }
-    }
-
-    if( ( pEnd - pCDataStart > 0 ) && ( *pEnd != '\0' ) ) {
-        tokenLength = pEnd - pCDataStart;
-        node->nodeValue = ( char * )malloc( tokenLength + 1 );
-        if( node->nodeValue == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-        strncpy( node->nodeValue, pCDataStart, tokenLength );
-        node->nodeValue[tokenLength] = '\0';
-
-        node->nodeName = safe_strdup( CDATANODENAME );
-        if( node->nodeName == NULL ) {
-            // no need to free node->nodeValue at all, bacause node contents
-            // will be freed by the main loop.
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-
-        node->nodeType = eCDATA_SECTION_NODE;
-        *pSrc = pEnd + strlen( CDEND );
-        return IXML_SUCCESS;
-    } else {
-        return IXML_SYNTAX_ERR;
-    }
-
-}
-
-/*==============================================================================*
-*
-*   Parser_setElementNamespace
-*       set element's namespace
-*       Internal to parser only.			
-*
-*===============================================================================*/
-static int
-Parser_setElementNamespace( IN IXML_Element * newElement,
-                            IN const char *nsURI )
-{
-    if( newElement != NULL ) {
-        if( newElement->n.namespaceURI != NULL ) {
-            return IXML_SYNTAX_ERR;
-        } else {
-            ( newElement->n ).namespaceURI = safe_strdup( nsURI );
-            if( ( newElement->n ).namespaceURI == NULL ) {
-                return IXML_INSUFFICIENT_MEMORY;
-            }
-        }
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*==============================================================================*
-*
-*   Parser_processContent
-*       processes the CONTENT as defined in XML spec.
-*       Internal to parser only			
-*
-*===============================================================================*/
-static int
-Parser_processContent( IN Parser * xmlParser,
-                       IN IXML_Node * node )
-{
-    char *pEndContent;
-    int tokenLength;
-    char *notAllowed = "]]>";
-    char *pCurToken = NULL;
-
-    // save pointer for backup
-    xmlParser->savePtr = xmlParser->curPtr;
-    Parser_skipWhiteSpaces( xmlParser );
-
-    if( *( xmlParser->curPtr ) == '\0' ) {  // end of file is reached
-        return IXML_SUCCESS;
-    }
-
-    pEndContent = xmlParser->curPtr;
-    if( *pEndContent == LESSTHAN ) {
-        if( strncmp( pEndContent, ( char * )CDSTART, strlen( CDSTART ) ) ==
-            0 ) {
-            if( Parser_processCDSect( &pEndContent, node ) !=
-                IXML_SUCCESS ) {
-                return IXML_SYNTAX_ERR;
-            } else {
-                xmlParser->curPtr = pEndContent;
-            }
-        } else
-            if( strncmp
-                ( pEndContent, ( char * )BEGIN_COMMENT,
-                  strlen( BEGIN_COMMENT ) ) == 0 ) {
-            if( Parser_skipComment( &pEndContent ) != IXML_SUCCESS ) {
-                return IXML_SYNTAX_ERR;
-            } else {
-                xmlParser->curPtr = pEndContent;
-            }
-        } else
-            if( strncmp
-                ( pEndContent, ( char * )BEGIN_PI,
-                  strlen( BEGIN_PI ) ) == 0 ) {
-            if( Parser_skipPI( &pEndContent ) != IXML_SUCCESS ) {
-                return IXML_SYNTAX_ERR;
-            } else {
-                xmlParser->curPtr = pEndContent;
-            }
-        } else                  // empty content
-        {
-            xmlParser->state = eELEMENT;
-        }
-    } else {
-        // backup 
-        xmlParser->curPtr = xmlParser->savePtr;
-        pEndContent = xmlParser->curPtr;
-
-        while( ( *pEndContent != LESSTHAN ) &&
-               ( strncmp
-                 ( pEndContent, ( const char * )notAllowed,
-                   strlen( notAllowed ) ) != 0 ) && *pEndContent ) {
-            pEndContent++;
-        }
-
-        if( strncmp
-            ( pEndContent, ( const char * )notAllowed,
-              strlen( notAllowed ) ) == 0 ) {
-            return IXML_SYNTAX_ERR;
-        }
-
-        tokenLength = pEndContent - xmlParser->curPtr;
-        Parser_clearTokenBuf( xmlParser );
-
-        if( Parser_copyToken( xmlParser, xmlParser->curPtr, tokenLength )
-            != IXML_SUCCESS ) {
-            return IXML_SYNTAX_ERR;
-        }
-
-        pCurToken = ( xmlParser->tokenBuf ).buf;
-        if( pCurToken != NULL ) {
-            node->nodeValue = safe_strdup( pCurToken );
-            if( node->nodeValue == NULL ) {
-                return IXML_INSUFFICIENT_MEMORY;
-            }
-        } else {
-            return IXML_SYNTAX_ERR;
-        }
-
-        node->nodeName = safe_strdup( TEXTNODENAME );
-        if( node->nodeName == NULL ) {
-            return IXML_SYNTAX_ERR;
-        }
-        node->nodeType = eTEXT_NODE;
-
-        // adjust curPtr
-        xmlParser->curPtr += tokenLength;
-
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*==============================================================================*
-*
-*   Parser_processETag
-*       process ETag as defined by XML spec.
-*       Internal to parser only.			
-*
-*===============================================================================*/
-static int
-Parser_processETag( IN Parser * xmlParser,
-                    IN IXML_Node * node,
-                    OUT BOOL * bETag )
-{
-    char *pCurToken = NULL;
-
-    assert( xmlParser != NULL );
-    if( Parser_getNextToken( xmlParser ) == 0 ) {
-        return IXML_SYNTAX_ERR;
-    }
-
-    pCurToken = ( xmlParser->tokenBuf ).buf;
-    if( pCurToken == NULL ) {
-        return IXML_SYNTAX_ERR;
-    }
-    node->nodeName = safe_strdup( pCurToken );
-    if( node->nodeName == NULL ) {
-        return IXML_INSUFFICIENT_MEMORY;
-    }
-
-    node->nodeValue = NULL;
-    node->nodeType = eELEMENT_NODE;
-
-    Parser_skipWhiteSpaces( xmlParser );
-
-    // read the > 
-    if( Parser_getNextToken( xmlParser ) == 0 ) {
-        return IXML_SYNTAX_ERR;
-    }
-
-    pCurToken = ( xmlParser->tokenBuf ).buf;
-    if( pCurToken == NULL ) {   // no need to free node->nodeName, it is freed by main loop
-        return IXML_SYNTAX_ERR;
-    }
-
-    if( strcmp( pCurToken, ">" ) != 0 ) {
-        return IXML_SYNTAX_ERR;
-    }
-
-    *bETag = TRUE;
-    return IXML_SUCCESS;
-}
-
-/*==============================================================================*
-*
-*   Parser_freeElementStackItem
-*       frees one ElementStack item.
-*       Internal to parser only.			
-*
-*===============================================================================*/
-static void
-Parser_freeElementStackItem( IN IXML_ElementStack * pItem )
-{
-    assert( pItem != NULL );
-    if( pItem->element != NULL ) {
-        free( pItem->element );
-        pItem->element = NULL;
-    }
-    if( pItem->namespaceUri != NULL ) {
-        free( pItem->namespaceUri );
-        pItem->namespaceUri = NULL;
-    }
-    if( pItem->prefix != NULL ) {
-        free( pItem->prefix );
-        pItem->prefix = NULL;
-    }
-
-}
-
-/*==============================================================================*
-*
-*   Parser_freeNsURI
-*       frees namespaceURI item.
-*       Internal to parser only. 		
-*
-*===============================================================================*/
-static void
-Parser_freeNsURI( IN IXML_NamespaceURI * pNsURI )
-{
-    assert( pNsURI != NULL );
-    if( pNsURI->nsURI != NULL ) {
-        free( pNsURI->nsURI );
-    }
-    if( pNsURI->prefix != NULL ) {
-        free( pNsURI->prefix );
-    }
-}
-
-/*==============================================================================*
-*
-*   Parser_free
-*       frees all temporary memory allocated by xmlparser.
-*       Internal to parser only       
-*			
-*
-*===============================================================================*/
-static void
-Parser_free( IN Parser * xmlParser )
-{
-    IXML_ElementStack *pElement,
-     *pNextElement;
-    IXML_NamespaceURI *pNsURI,
-     *pNextNsURI;
-
-    if( xmlParser == NULL ) {
-        return;
-    }
-
-    if( xmlParser->dataBuffer != NULL ) {
-        free( xmlParser->dataBuffer );
-    }
-
-    ixml_membuf_destroy( &( xmlParser->tokenBuf ) );
-    ixml_membuf_destroy( &( xmlParser->lastElem ) );
-
-    pElement = xmlParser->pCurElement;
-    while( pElement != NULL ) {
-        Parser_freeElementStackItem( pElement );
-
-        pNsURI = pElement->pNsURI;
-        while( pNsURI != NULL ) {
-            pNextNsURI = pNsURI->nextNsURI;
-            Parser_freeNsURI( pNsURI );
-            free( pNsURI );
-            pNsURI = pNextNsURI;
-        }
-
-        pNextElement = pElement->nextElement;
-        free( pElement );
-        pElement = pNextElement;
-    }
-
-    free( xmlParser );
-
-}
-
-/*==============================================================================*
-*
-*   Parser_parseReference	
-*       return IXML_SUCCESS or not
-*			
-*
-*===============================================================================*/
-static int
-Parser_parseReference( IN char *pStr )
-{                               // place holder for future implementation
-    return IXML_SUCCESS;
-}
-
-/*==============================================================================*
-*
-*   Parser_processAttribute	
-*       processes attribute.
-*       Internal to parser only.
-*       returns IXML_SUCCESS or failure
-*			
-*
-*===============================================================================*/
-static int
-Parser_processAttribute( IN Parser * xmlParser,
-                         IN IXML_Node * node )
-{
-
-    char *strEndQuote = NULL;
-    int tlen = 0;
-    char *pCur = NULL;
-    char *pCurToken = NULL;
-
-    assert( xmlParser );
-    if( xmlParser == NULL ) {
-        return IXML_FAILED;
-    }
-
-    pCurToken = ( xmlParser->tokenBuf ).buf;
-    if( pCurToken == NULL ) {
-        return IXML_SYNTAX_ERR;
-    }
-
-    if( Parser_isNameChar( Parser_UTF8ToInt( pCurToken, &tlen ), FALSE ) ==
-        FALSE ) {
-        return IXML_SYNTAX_ERR;
-    }
-    // copy in the attribute name
-    node->nodeName = safe_strdup( pCurToken );
-    if( node->nodeName == NULL ) {
-        return IXML_INSUFFICIENT_MEMORY;
-    }
-    // read in the "=" sign 
-    if( Parser_getNextToken( xmlParser ) == 0 ) {
-        return IXML_SYNTAX_ERR;
-    }
-
-    pCurToken = ( xmlParser->tokenBuf ).buf;
-    if( *pCurToken != EQUALS ) {
-        return IXML_SYNTAX_ERR;
-    }
-    // read in the single quote or double quote
-    if( Parser_getNextToken( xmlParser ) == 0 ) {
-        return IXML_SYNTAX_ERR;
-    }
-    // pCurToken is either quote or singlequote
-    pCurToken = ( xmlParser->tokenBuf ).buf;
-    if( ( *pCurToken != QUOTE ) && ( *pCurToken != SINGLEQUOTE ) ) {
-        return IXML_SYNTAX_ERR;
-    }
-
-    strEndQuote = strstr( xmlParser->curPtr, pCurToken );
-    if( strEndQuote == NULL ) {
-        return IXML_SYNTAX_ERR;
-    }
-    // check between curPtr and strEndQuote, whether there are illegal chars.
-    pCur = xmlParser->curPtr;
-    while( pCur < strEndQuote ) {
-        if( *pCur == '<' ) {
-            return IXML_SYNTAX_ERR;
-        }
-
-        if( *pCur == '&' ) {
-            Parser_parseReference( ++pCur );
-        }
-        pCur++;
-    }
-    //clear token buffer
-    Parser_clearTokenBuf( xmlParser );
-    if( strEndQuote != xmlParser->curPtr ) {
-        if( Parser_copyToken( xmlParser, xmlParser->curPtr,
-                              strEndQuote - xmlParser->curPtr ) !=
-            IXML_SUCCESS ) {
-            return IXML_SYNTAX_ERR;
-        }
-    }
-    // skip the ending quote
-    xmlParser->curPtr = strEndQuote + 1;
-
-    pCurToken = ( xmlParser->tokenBuf ).buf;
-    if( pCurToken != NULL ) {   // attribute has value, like a="c"
-        node->nodeValue = safe_strdup( pCurToken );
-        if( node->nodeValue == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-    }else{
-       // if attribute doesn't have value, like a=""
-        ///somewhere on other places is this copied
-       node->nodeValue = malloc(sizeof(char));
-       *(node->nodeValue) = '\0';
-    }
-    node->nodeType = eATTRIBUTE_NODE;
-
-    // check whether this is a new namespace definition
-    if( Parser_xmlNamespace( xmlParser, node ) != IXML_SUCCESS ) {
-        return IXML_FAILED;
-    }
-    // read ahead to see whether we have more attributes
-    xmlParser->savePtr = xmlParser->curPtr;
-    if( Parser_getNextToken( xmlParser ) == 0 ) {
-        return IXML_SYNTAX_ERR;
-    }
-
-    pCurToken = ( xmlParser->tokenBuf ).buf;
-    if( strcmp( pCurToken, "<" ) == 0 ) {
-        return IXML_FAILED;
-    } else if( strcmp( pCurToken, ">" ) != 0 )  // more attribute?
-    {                           // backup
-        xmlParser->curPtr = xmlParser->savePtr;
-    } else {
-        xmlParser->state = eCONTENT;
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*==============================================================================*
-*
-*   Parser_getNextNode
-*       return next node 
-*   returns IXML_SUCCESS or 
-*			
-*
-*===============================================================================*/
-static int
-Parser_getNextNode( IN Parser * xmlParser,
-                    OUT IXML_Node * node,
-                    OUT BOOL * bETag )
-{
-    char *pCurToken = NULL;
-    char *lastElement = NULL;
-
-    // endof file reached?
-    if( *( xmlParser->curPtr ) == '\0' ) {
-        *bETag = TRUE;
-        return IXML_FILE_DONE;
-    }
-
-    if( xmlParser->state == eCONTENT ) {
-        if( Parser_processContent( xmlParser, node ) != IXML_SUCCESS ) {
-            return IXML_FAILED;
-        }
-    } else {
-        Parser_skipWhiteSpaces( xmlParser );
-
-        if( ( Parser_getNextToken( xmlParser ) == 0 ) && ( xmlParser->pCurElement == NULL ) && ( *( xmlParser->curPtr ) == '\0' ) ) {   // comments after the xml doc
-            return IXML_SUCCESS;
-        } else if( ( xmlParser->tokenBuf ).length == 0 ) {
-            return IXML_SYNTAX_ERR;
-        }
-
-        pCurToken = ( xmlParser->tokenBuf ).buf;
-        if( *pCurToken == GREATERTHAN ) {
-            return IXML_SUCCESS;
-        } else if( strcmp( pCurToken, ENDTAG ) == 0 ) { //  we got </, read next element
-            return Parser_processETag( xmlParser, node, bETag );
-        } else if( *pCurToken == LESSTHAN ) {
-            return Parser_processSTag( xmlParser, node );
-        } else if( strcmp( pCurToken, COMPLETETAG ) == 0 ) {
-            lastElement = ( xmlParser->lastElem ).buf;
-            if( lastElement == NULL ) {
-                goto ErrorHandler;
-            }
-
-            node->nodeName = safe_strdup( lastElement );
-            if( node->nodeName == NULL ) {
-                return IXML_INSUFFICIENT_MEMORY;
-            }
-            node->nodeType = eELEMENT_NODE;
-            *bETag = TRUE;
-
-            return IXML_SUCCESS;
-        } else if( (xmlParser->state == eATTRIBUTE) && 
-                   (xmlParser->pCurElement != NULL) ) {
-            if( Parser_processAttribute( xmlParser, node ) !=
-                IXML_SUCCESS ) {
-                return IXML_SYNTAX_ERR;
-            }
-        } else {
-            return IXML_SYNTAX_ERR;
-        }
-    }
-
-    return IXML_SUCCESS;
-
-  ErrorHandler:
-
-    return IXML_SYNTAX_ERR;
-
-}
diff --git a/tombupnp/ixml/src/namedNodeMap.c b/tombupnp/ixml/src/namedNodeMap.c
deleted file mode 100644
index a9f45e9..0000000
--- a/tombupnp/ixml/src/namedNodeMap.c
+++ /dev/null
@@ -1,242 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include "ixmlparser.h"
-
-/*================================================================
-*   NamedNodeMap_getItemNumber
-*       return the item number of a item in NamedNodeMap.
-*       Internal to parser only.
-*   Parameters:
-*       name: the name of the item to find
-*   
-*=================================================================*/
-unsigned long
-ixmlNamedNodeMap_getItemNumber( IN IXML_NamedNodeMap * nnMap,
-                                IN const char *name )
-{
-    IXML_Node *tempNode;
-    unsigned long returnItemNo = 0;
-
-    assert( nnMap != NULL && name != NULL );
-    if( ( nnMap == NULL ) || ( name == NULL ) ) {
-        return IXML_INVALID_ITEM_NUMBER;
-    }
-
-    tempNode = nnMap->nodeItem;
-    while( tempNode != NULL ) {
-        if( strcmp( name, tempNode->nodeName ) == 0 ) {
-            return returnItemNo;
-        }
-
-        tempNode = tempNode->nextSibling;
-        returnItemNo++;
-    }
-
-    return IXML_INVALID_ITEM_NUMBER;
-}
-
-/*================================================================
-*   NamedNodeMap_init
-*       Initializes a NamedNodeMap object.
-*       External function.
-*
-*=================================================================*/
-void
-ixmlNamedNodeMap_init( IN IXML_NamedNodeMap * nnMap )
-{
-    assert( nnMap != NULL );
-    memset( nnMap, 0, sizeof( IXML_NamedNodeMap ) );
-}
-
-/*================================================================
-*   NamedNodeMap_getNamedItem
-*       Retrieves a node specified by name.
-*       External function.
-*
-*   Parameter:
-*       name: type nodeName of a node to retrieve.
-*
-*   Return Value:
-*       A Node with the specified nodeName, or null if it
-*       does not identify any node in this map.
-*
-*=================================================================*/
-IXML_Node *
-ixmlNamedNodeMap_getNamedItem( IN IXML_NamedNodeMap * nnMap,
-                               IN const char *name )
-{
-    long index;
-
-    if( ( nnMap == NULL ) || ( name == NULL ) ) {
-        return NULL;
-    }
-
-    index = ixmlNamedNodeMap_getItemNumber( nnMap, name );
-    if( index == IXML_INVALID_ITEM_NUMBER ) {
-        return NULL;
-    } else {
-        return ( ixmlNamedNodeMap_item( nnMap, ( unsigned long )index ) );
-    }
-}
-
-/*================================================================
-*   NamedNodeMap_item
-*       Returns the indexth item in the map. If index is greater than or
-*       equal to the number of nodes in this map, this returns null.
-*       External function.
-*
-*   Parameter:
-*       index: index into this map.
-*
-*   Return Value:
-*       The node at the indexth position in the map, or null if that is
-*       not a valid index.
-*
-*=================================================================*/
-IXML_Node *
-ixmlNamedNodeMap_item( IN IXML_NamedNodeMap * nnMap,
-                       IN unsigned long index )
-{
-    IXML_Node *tempNode;
-    unsigned int i;
-
-    if( nnMap == NULL ) {
-        return NULL;
-    }
-
-    if( index > ixmlNamedNodeMap_getLength( nnMap ) - 1 ) {
-        return NULL;
-    }
-
-    tempNode = nnMap->nodeItem;
-    for( i = 0; i < index && tempNode != NULL; ++i ) {
-        tempNode = tempNode->nextSibling;
-    }
-
-    return tempNode;
-}
-
-/*================================================================
-*   NamedNodeMap_getLength	
-*       Return the number of Nodes in this map.       
-*       External function.
-*   
-*   Parameters:
-*
-*=================================================================*/
-unsigned long
-ixmlNamedNodeMap_getLength( IN IXML_NamedNodeMap * nnMap )
-{
-    IXML_Node *tempNode;
-    unsigned long length = 0;
-
-    if( nnMap != NULL ) {
-        tempNode = nnMap->nodeItem;
-        for( length = 0; tempNode != NULL; ++length ) {
-            tempNode = tempNode->nextSibling;
-        }
-    }
-    return length;
-}
-
-/*================================================================
-*   ixmlNamedNodeMap_free
-*       frees a NamedNodeMap.
-*       External function.
-*
-*=================================================================*/
-void
-ixmlNamedNodeMap_free( IXML_NamedNodeMap * nnMap )
-{
-    IXML_NamedNodeMap *pNext;
-
-    while( nnMap != NULL ) {
-        pNext = nnMap->next;
-        free( nnMap );
-        nnMap = pNext;
-    }
-}
-
-/*================================================================
-*   NamedNodeMap_addToNamedNodeMap
-*       add a node to a NamedNodeMap.
-*       Internal to parser only.
-*   Parameters:
-*       add: the node to add into NamedNodeMap.
-*   Return:
-*       IXML_SUCCESS or failure.
-*
-*=================================================================*/
-int
-ixmlNamedNodeMap_addToNamedNodeMap( IN IXML_NamedNodeMap ** nnMap,
-                                    IN IXML_Node * add )
-{
-    IXML_NamedNodeMap *traverse = NULL,
-     *p = NULL;
-    IXML_NamedNodeMap *newItem = NULL;
-
-    if( add == NULL ) {
-        return IXML_SUCCESS;
-    }
-
-    if( *nnMap == NULL )        // nodelist is empty
-    {
-        *nnMap =
-            ( IXML_NamedNodeMap * ) malloc( sizeof( IXML_NamedNodeMap ) );
-        if( *nnMap == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-        ixmlNamedNodeMap_init( *nnMap );
-    }
-
-    if( ( *nnMap )->nodeItem == NULL ) {
-        ( *nnMap )->nodeItem = add;
-    } else {
-        traverse = *nnMap;
-        p = traverse;
-        while( traverse != NULL ) {
-            p = traverse;
-            traverse = traverse->next;
-        }
-
-        newItem =
-            ( IXML_NamedNodeMap * ) malloc( sizeof( IXML_NamedNodeMap ) );
-        if( newItem == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-        p->next = newItem;
-        newItem->nodeItem = add;
-        newItem->next = NULL;
-    }
-
-    return IXML_SUCCESS;
-}
diff --git a/tombupnp/ixml/src/node.c b/tombupnp/ixml/src/node.c
deleted file mode 100644
index 29a9c77..0000000
--- a/tombupnp/ixml/src/node.c
+++ /dev/null
@@ -1,1641 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include "ixmlparser.h"
-
-/*================================================================
-*   ixmlNode_init
-*       Intializes a node.
-*       External function.
-*
-*=================================================================*/
-void
-ixmlNode_init( IN IXML_Node * nodeptr )
-{
-    assert( nodeptr != NULL );
-    memset( nodeptr, 0, sizeof( IXML_Node ) );
-
-}
-
-/*================================================================
-*   ixmlCDATASection_init
-*       Initializes a CDATASection node.
-*       External function.
-*
-*=================================================================*/
-void
-ixmlCDATASection_init( IN IXML_CDATASection * nodeptr )
-{
-    memset( nodeptr, 0, sizeof( IXML_CDATASection ) );
-}
-
-/*================================================================
-*   ixmlCDATASection_free
-*       frees a CDATASection node.
-*       External function.
-*
-*=================================================================*/
-void
-ixmlCDATASection_free( IN IXML_CDATASection * nodeptr )
-{
-    if( nodeptr != NULL ) {
-        ixmlNode_free( ( IXML_Node * ) nodeptr );
-    }
-}
-
-/*================================================================
-*   ixmlNode_freeSingleNode
-*       frees a node content.
-*       Internal to parser only.
-*
-*=================================================================*/
-void
-ixmlNode_freeSingleNode( IN IXML_Node * nodeptr )
-{
-    IXML_Element *element = NULL;
-
-    if( nodeptr != NULL ) {
-        if( nodeptr->nodeName != NULL ) {
-            free( nodeptr->nodeName );
-        }
-
-        if( nodeptr->nodeValue != NULL ) {
-            free( nodeptr->nodeValue );
-        }
-
-        if( nodeptr->namespaceURI != NULL ) {
-            free( nodeptr->namespaceURI );
-        }
-
-        if( nodeptr->prefix != NULL ) {
-            free( nodeptr->prefix );
-        }
-
-        if( nodeptr->localName != NULL ) {
-            free( nodeptr->localName );
-        }
-
-        if( nodeptr->nodeType == eELEMENT_NODE ) {
-            element = ( IXML_Element * ) nodeptr;
-            free( element->tagName );
-        }
-
-        free( nodeptr );
-
-    }
-}
-
-/*================================================================
-*   ixmlNode_free
-*       Frees all nodes under nodeptr subtree.
-*       External function.
-*
-*=================================================================*/
-void
-ixmlNode_free( IN IXML_Node * nodeptr )
-{
-    if( nodeptr != NULL ) {
-        ixmlNode_free( nodeptr->firstChild );
-        ixmlNode_free( nodeptr->nextSibling );
-        ixmlNode_free( nodeptr->firstAttr );
-
-        ixmlNode_freeSingleNode( nodeptr );
-    }
-}
-
-/*================================================================
-*   ixmlNode_getNodeName
-*       Returns the nodename(the qualified name)
-*       External function.
-*
-*=================================================================*/
-const DOMString
-ixmlNode_getNodeName( IN IXML_Node * nodeptr )
-{
-
-    if( nodeptr != NULL ) {
-        return ( nodeptr->nodeName );
-    }
-
-    return NULL;
-}
-
-/*================================================================
-*   ixmlNode_getLocalName
-*       Returns the node local name
-*       External function.          		
-*
-*=================================================================*/
-const DOMString
-ixmlNode_getLocalName( IN IXML_Node * nodeptr )
-{
-
-    if( nodeptr != NULL ) {
-        return ( nodeptr->localName );
-    }
-
-    return NULL;
-}
-
-/*================================================================
-*   ixmlNode_setNamespaceURI
-*       sets the namespace URI of the node.
-*       Internal function.
-*	Return:
-*       IXML_SUCCESS or failure	
-*
-*=================================================================*/
-int
-ixmlNode_setNamespaceURI( IN IXML_Node * nodeptr,
-                          IN const char *namespaceURI )
-{
-
-    if( nodeptr == NULL ) {
-        return IXML_INVALID_PARAMETER;
-    }
-
-    if( nodeptr->namespaceURI != NULL ) {
-        free( nodeptr->namespaceURI );
-        nodeptr->namespaceURI = NULL;
-    }
-
-    if( namespaceURI != NULL ) {
-        nodeptr->namespaceURI = strdup( namespaceURI );
-        if( nodeptr->namespaceURI == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*================================================================
-*   ixmlNode_setPrefix
-*       set the prefix of the node.
-*       Internal to parser only.
-*	Returns:	
-*       IXML_SUCCESS or failure.
-*
-*=================================================================*/
-int
-ixmlNode_setPrefix( IN IXML_Node * nodeptr,
-                    IN const char *prefix )
-{
-
-    if( nodeptr == NULL ) {
-        return IXML_INVALID_PARAMETER;
-    }
-
-    if( nodeptr->prefix != NULL ) {
-        free( nodeptr->prefix );
-        nodeptr->prefix = NULL;
-    }
-
-    if( prefix != NULL ) {
-        nodeptr->prefix = strdup( prefix );
-        if( nodeptr->prefix == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-    }
-
-    return IXML_SUCCESS;
-
-}
-
-/*================================================================
-*   ixmlNode_setLocalName
-*	    set the localName of the node.
-*       Internal to parser only.
-*	Returns:	
-*       IXML_SUCCESS or failure.
-*
-*=================================================================*/
-int
-ixmlNode_setLocalName( IN IXML_Node * nodeptr,
-                       IN const char *localName )
-{
-
-    assert( nodeptr != NULL );
-
-    if( nodeptr->localName != NULL ) {
-        free( nodeptr->localName );
-        nodeptr->localName = NULL;
-    }
-
-    if( localName != NULL ) {
-        nodeptr->localName = strdup( localName );
-        if( nodeptr->localName == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*================================================================
-*   ixmlNode_getNodeNamespaceURI
-*       Returns the node namespaceURI
-*       External function.
-*   Returns:		
-*       the namespaceURI of the node
-*
-*=================================================================*/
-const DOMString
-ixmlNode_getNamespaceURI( IN IXML_Node * nodeptr )
-{
-    DOMString retNamespaceURI = NULL;
-
-    if( nodeptr != NULL ) {
-        retNamespaceURI = nodeptr->namespaceURI;
-    }
-
-    return retNamespaceURI;
-}
-
-/*================================================================
-*   ixmlNode_getPrefix
-*       Returns the node prefix
-*       External function.
-*   Returns:		
-*       the prefix of the node.
-*
-*=================================================================*/
-const DOMString
-ixmlNode_getPrefix( IN IXML_Node * nodeptr )
-{
-    const DOMString prefix = NULL;
-
-    if( nodeptr != NULL ) {
-        prefix = nodeptr->prefix;
-    }
-
-    return prefix;
-
-}
-
-/*================================================================
-*   ixmlNode_getNodeValue
-*       Returns the nodeValue of this node
-*       External function.
-*   Return:
-*       the nodeValue of the node.
-*
-*=================================================================*/
-const DOMString
-ixmlNode_getNodeValue( IN IXML_Node * nodeptr )
-{
-
-    if( nodeptr != NULL ) {
-        return ( nodeptr->nodeValue );
-    }
-
-    return NULL;
-}
-
-/*================================================================
-*   ixmlNode_setNodeValue
-*       Sets the nodeValue
-*       Internal function.
-*   Returns:    
-*       IXML_SUCCESS or failure
-*
-*=================================================================*/
-int
-ixmlNode_setNodeValue( IN IXML_Node * nodeptr,
-                       IN const char *newNodeValue )
-{
-    int rc = IXML_SUCCESS;
-
-    if( nodeptr == NULL ) {
-        return IXML_INVALID_PARAMETER;
-    }
-
-    if( nodeptr->nodeValue != NULL ) {
-        free( nodeptr->nodeValue );
-        nodeptr->nodeValue = NULL;
-    }
-
-    if( newNodeValue != NULL ) {
-        nodeptr->nodeValue = strdup( newNodeValue );
-        if( nodeptr->nodeValue == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-    }
-
-    return rc;
-}
-
-/*================================================================
-*   ixmlNode_getNodeType
-*       Gets the NodeType of this node
-*       External function.
-*
-*=================================================================*/
-unsigned short
-ixmlNode_getNodeType( IN IXML_Node * nodeptr )
-{
-    if( nodeptr != NULL ) {
-        return ( nodeptr->nodeType );
-    } else {
-        return ( eINVALID_NODE );
-    }
-}
-
-/*================================================================
-*   ixmlNode_getParentNode
-*       Get the parent node
-*       External function.
-*   Return:    
-*       
-*=================================================================*/
-IXML_Node *
-ixmlNode_getParentNode( IN IXML_Node * nodeptr )
-{
-
-    if( nodeptr != NULL ) {
-        return nodeptr->parentNode;
-    } else {
-        return NULL;
-    }
-}
-
-/*================================================================
-*   ixmlNode_getFirstChild
-*       Returns the first child of nodeptr.
-*       External function.
-*
-*=================================================================*/
-IXML_Node *
-ixmlNode_getFirstChild( IN IXML_Node * nodeptr )
-{
-    if( nodeptr != NULL ) {
-        return nodeptr->firstChild;
-    } else {
-        return NULL;
-    }
-}
-
-/*================================================================
-*   ixmlNode_getLastChild
-*       Returns the last child of nodeptr.
-*       External function.
-*
-*=================================================================*/
-IXML_Node *
-ixmlNode_getLastChild( IN IXML_Node * nodeptr )
-{
-    IXML_Node *prev,
-     *next;
-
-    if( nodeptr != NULL ) {
-        prev = nodeptr;
-        next = nodeptr->firstChild;
-
-        while( next != NULL ) {
-            prev = next;
-            next = next->nextSibling;
-        }
-        return prev;
-    } else {
-        return NULL;
-    }
-
-}
-
-/*================================================================
-*   ixmlNode_getPreviousSibling
-*       returns the previous sibling node of nodeptr.
-*       External function.
-*
-*=================================================================*/
-IXML_Node *
-ixmlNode_getPreviousSibling( IN IXML_Node * nodeptr )
-{
-    if( nodeptr != NULL ) {
-        return nodeptr->prevSibling;
-    } else {
-        return NULL;
-    }
-}
-
-/*================================================================
-*   ixmlNode_getNextSibling
-*       Returns the next sibling node.
-*       External function.
-*
-*=================================================================*/
-IXML_Node *
-ixmlNode_getNextSibling( IN IXML_Node * nodeptr )
-{
-
-    if( nodeptr != NULL ) {
-        return nodeptr->nextSibling;
-    } else {
-        return NULL;
-    }
-
-}
-
-/*================================================================
-*   ixmlNode_getOwnerDocument
-*       Returns the owner document node.
-*       External function.
-*
-*=================================================================*/
-IXML_Document *
-ixmlNode_getOwnerDocument( IN IXML_Node * nodeptr )
-{
-    if( nodeptr != NULL ) {
-        return ( IXML_Document * ) nodeptr->ownerDocument;
-    } else {
-        return NULL;
-    }
-}
-
-/*================================================================
-*   ixmlNode_isAncestor
-*       check if ancestorNode is ancestor of toFind 
-*       Internal to parser only.
-*   Returns:
-*       TRUE or FALSE
-*
-*=================================================================*/
-BOOL
-ixmlNode_isAncestor( IXML_Node * ancestorNode,
-                     IXML_Node * toFind )
-{
-
-    BOOL found = FALSE;
-
-    if( ( ancestorNode != NULL ) && ( toFind != NULL ) ) {
-        if( toFind->parentNode == ancestorNode ) {
-            return TRUE;
-        } else {
-            found =
-                ixmlNode_isAncestor( ancestorNode->firstChild, toFind );
-            if( found == FALSE ) {
-                found =
-                    ixmlNode_isAncestor( ancestorNode->nextSibling,
-                                         toFind );
-            }
-        }
-    }
-
-    return found;
-}
-
-/*================================================================
-*   ixmlNode_isParent
-*       Check whether toFind is a children of nodeptr.
-*       Internal to parser only.
-*   Return:
-*       TRUE or FALSE       
-*
-*=================================================================*/
-BOOL
-ixmlNode_isParent( IXML_Node * nodeptr,
-                   IXML_Node * toFind )
-{
-    BOOL found = FALSE;
-
-    assert( nodeptr != NULL && toFind != NULL );
-    if( toFind->parentNode == nodeptr ) {
-        found = TRUE;
-    }
-
-    return found;
-}
-
-/*================================================================
-*   ixmlNode_allowChildren
-*       Check to see whether nodeptr allows children of type newChild.    
-*       Internal to parser only.
-*   Returns:      
-*       TRUE, if nodeptr can have newChild as children
-*       FALSE,if nodeptr cannot have newChild as children
-*
-*=================================================================*/
-BOOL
-ixmlNode_allowChildren( IXML_Node * nodeptr,
-                        IXML_Node * newChild )
-{
-
-    assert( nodeptr != NULL && newChild != NULL );
-    switch ( nodeptr->nodeType ) {
-        case eATTRIBUTE_NODE:
-        case eTEXT_NODE:
-        case eCDATA_SECTION_NODE:
-            return FALSE;
-            break;
-
-        case eELEMENT_NODE:
-            if( ( newChild->nodeType == eATTRIBUTE_NODE ) ||
-                ( newChild->nodeType == eDOCUMENT_NODE ) ) {
-                return FALSE;
-            }
-            break;
-
-        case eDOCUMENT_NODE:
-            if( newChild->nodeType != eELEMENT_NODE ) {
-                return FALSE;
-            }
-
-        default:
-            break;
-    }
-
-    return TRUE;
-}
-
-/*================================================================
-*   ixmlNode_compare
-*       Compare two nodes to see whether they are the same node.
-*       Parent, sibling and children node are ignored.
-*       Internal to parser only.
-*   Returns:
-*       TRUE, the two nodes are the same.
-*       FALSE, the two nodes are not the same.
-*
-*=================================================================*/
-BOOL
-ixmlNode_compare( IXML_Node * srcNode,
-                  IXML_Node * destNode )
-{
-    assert( srcNode != NULL && destNode != NULL );
-    if( ( srcNode == destNode ) ||
-        ( strcmp( srcNode->nodeName, destNode->nodeName ) == 0 &&
-          strcmp( srcNode->nodeValue, destNode->nodeValue ) == 0 &&
-          ( srcNode->nodeType == destNode->nodeType ) &&
-          strcmp( srcNode->namespaceURI, destNode->namespaceURI ) == 0 &&
-          strcmp( srcNode->prefix, destNode->prefix ) == 0 &&
-          strcmp( srcNode->localName, destNode->localName ) == 0 ) ) {
-        return TRUE;
-    } else {
-        return FALSE;
-    }
-}
-
-/*================================================================
-*   ixmlNode_insertBefore
-*       Inserts the node newChild before the existing child node refChild.
-*       If refChild is null, insert newChild at the end of the list of
-*       children. If the newChild is already in the tree, it is first
-*       removed.   
-*       External function.
-*   Parameters:
-*       newChild: the node to insert.
-*   Returns:
-*
-*=================================================================*/
-int
-ixmlNode_insertBefore( IN IXML_Node * nodeptr,
-                       IN IXML_Node * newChild,
-                       IN IXML_Node * refChild )
-{
-
-    int ret = IXML_SUCCESS;
-
-    if( ( nodeptr == NULL ) || ( newChild == NULL ) ) {
-        return IXML_INVALID_PARAMETER;
-    }
-    // whether nodeptr allow children of the type of newChild 
-    if( ixmlNode_allowChildren( nodeptr, newChild ) == FALSE ) {
-        return IXML_HIERARCHY_REQUEST_ERR;
-    }
-    // or if newChild is one of nodeptr's ancestors
-    if( ixmlNode_isAncestor( newChild, nodeptr ) == TRUE ) {
-        return IXML_HIERARCHY_REQUEST_ERR;
-    }
-    // if newChild was created from a different document 
-    if( nodeptr->ownerDocument != newChild->ownerDocument ) {
-        return IXML_WRONG_DOCUMENT_ERR;
-    }
-    // if refChild is not a child of nodeptr
-    if( ixmlNode_isParent( nodeptr, refChild ) == FALSE ) {
-        return IXML_NOT_FOUND_ERR;
-    }
-
-    if( refChild != NULL ) {
-        if( ixmlNode_isParent( nodeptr, newChild ) == TRUE ) {
-            ixmlNode_removeChild( nodeptr, newChild, NULL );
-            newChild->nextSibling = NULL;
-            newChild->prevSibling = NULL;
-        }
-
-        newChild->nextSibling = refChild;
-        if( refChild->prevSibling != NULL ) {
-            ( refChild->prevSibling )->nextSibling = newChild;
-            newChild->prevSibling = refChild->prevSibling;
-        }
-
-        refChild->prevSibling = newChild;
-
-        if( newChild->prevSibling == NULL ) {
-            nodeptr->firstChild = newChild;
-        }
-
-        newChild->parentNode = nodeptr;
-
-    } else {
-        ret = ixmlNode_appendChild( nodeptr, newChild );
-    }
-
-    return ret;
-}
-
-/*================================================================
-*   ixmlNode_replaceChild
-*       Replaces the child node oldChild with newChild in the list of children,
-*       and returns the oldChild node.
-*       External function.
-*   Parameters:
-*       newChild:   the new node to put in the child list.
-*       oldChild:   the node being replaced in the list.
-*       returnNode: the node replaced.
-*   Return Value:
-*       IXML_SUCCESS
-*       IXML_INVALID_PARAMETER:     if anyone of nodeptr, newChild or oldChild is NULL.
-*       IXML_HIERARCHY_REQUEST_ERR: if the newChild is ancestor of nodeptr or nodeptr
-*                                   is of a type that does not allow children of the
-*                                   type of the newChild node.
-*       IXML_WRONG_DOCUMENT_ERR:    if newChild was created from a different document than
-*                                   the one that created this node.
-*       IXML_NOT_FOUND_ERR:         if oldChild is not a child of nodeptr.
-*
-*=================================================================*/
-int
-ixmlNode_replaceChild( IN IXML_Node * nodeptr,
-                       IN IXML_Node * newChild,
-                       IN IXML_Node * oldChild,
-                       OUT IXML_Node ** returnNode )
-{
-    int ret = IXML_SUCCESS;
-
-    if( ( nodeptr == NULL ) || ( newChild == NULL )
-        || ( oldChild == NULL ) ) {
-        return IXML_INVALID_PARAMETER;
-    }
-    // if nodetype of nodeptr does not allow children of the type of newChild 
-    // needs to add later
-
-    // or if newChild is one of nodeptr's ancestors
-    if( ixmlNode_isAncestor( newChild, nodeptr ) == TRUE ) {
-        return IXML_HIERARCHY_REQUEST_ERR;
-    }
-
-    if( ixmlNode_allowChildren( nodeptr, newChild ) == FALSE ) {
-        return IXML_HIERARCHY_REQUEST_ERR;
-    }
-    // if newChild was created from a different document 
-    if( nodeptr->ownerDocument != newChild->ownerDocument ) {
-        return IXML_WRONG_DOCUMENT_ERR;
-    }
-    // if refChild is not a child of nodeptr
-    if( ixmlNode_isParent( nodeptr, oldChild ) != TRUE ) {
-        return IXML_NOT_FOUND_ERR;
-    }
-
-    ret = ixmlNode_insertBefore( nodeptr, newChild, oldChild );
-    if( ret != IXML_SUCCESS ) {
-        return ret;
-    }
-
-    ret = ixmlNode_removeChild( nodeptr, oldChild, returnNode );
-    return ret;
-}
-
-/*================================================================
-*   ixmlNode_removeChild
-*       Removes the child node indicated by oldChild from the list of
-*       children, and returns it.
-*       External function.
-*   Parameters:
-*       oldChild: the node being removed.
-*       returnNode: the node removed.
-*   Return Value:
-*       IXML_SUCCESS
-*       IXML_NOT_FOUND_ERR: if oldChild is not a child of this node.
-*       IXML_INVALID_PARAMETER: if either oldChild or nodeptr is NULL
-*
-*=================================================================*/
-int
-ixmlNode_removeChild( IN IXML_Node * nodeptr,
-                      IN IXML_Node * oldChild,
-                      OUT IXML_Node ** returnNode )
-{
-
-    if( ( nodeptr == NULL ) || ( oldChild == NULL ) ) {
-        return IXML_INVALID_PARAMETER;
-    }
-
-    if( ixmlNode_isParent( nodeptr, oldChild ) == FALSE ) {
-        return IXML_NOT_FOUND_ERR;
-    }
-
-    if( oldChild->prevSibling != NULL ) {
-        ( oldChild->prevSibling )->nextSibling = oldChild->nextSibling;
-    }
-
-    if( nodeptr->firstChild == oldChild ) {
-        nodeptr->firstChild = oldChild->nextSibling;
-    }
-
-    if( oldChild->nextSibling != NULL ) {
-        ( oldChild->nextSibling )->prevSibling = oldChild->prevSibling;
-    }
-
-    oldChild->nextSibling = NULL;
-    oldChild->prevSibling = NULL;
-    oldChild->parentNode = NULL;
-
-    if( returnNode != NULL ) {
-        *returnNode = oldChild;
-    }
-    return IXML_SUCCESS;
-}
-
-/*=============================================================================
-*   ixmlNode_appendChild
-*       Adds the node newChild to the end of the list of children of this node.
-*       If the newChild is already in the tree, it is first removed.
-*       External function.   
-*   Parameter:
-*       newChild: the node to add.
-*   Return Value:
-*       IXML_SUCCESS
-*       IXML_INVALID_PARAMETER:     if either nodeptr or newChild is NULL
-*       IXML_WRONG_DOCUMENT_ERR:    if newChild was created from a different document than
-*                                   the one that created nodeptr.
-*       IXML_HIERARCHY_REQUEST_ERR: if newChild is ancestor of nodeptr or if nodeptr is of
-*                                   a type that does not allow children of the type of the
-*                                   newChild node.
-*
-*=================================================================*/
-int
-ixmlNode_appendChild( IN IXML_Node * nodeptr,
-                      IN IXML_Node * newChild )
-{
-
-    IXML_Node *prev = NULL,
-     *next = NULL;
-
-    if( ( nodeptr == NULL ) || ( newChild == NULL ) ) {
-        return IXML_INVALID_PARAMETER;
-    }
-    // if newChild was created from a different document 
-    if( ( newChild->ownerDocument != NULL ) &&
-        ( nodeptr->ownerDocument != newChild->ownerDocument ) ) {
-        return IXML_WRONG_DOCUMENT_ERR;
-    }
-    // if newChild is an ancestor of nodeptr
-    if( ixmlNode_isAncestor( newChild, nodeptr ) == TRUE ) {
-        return IXML_HIERARCHY_REQUEST_ERR;
-    }
-    // if nodeptr does not allow to have newChild as children
-    if( ixmlNode_allowChildren( nodeptr, newChild ) == FALSE ) {
-        return IXML_HIERARCHY_REQUEST_ERR;
-    }
-
-    if( ixmlNode_isParent( nodeptr, newChild ) == TRUE ) {
-        ixmlNode_removeChild( nodeptr, newChild, NULL );
-    }
-    // set the parent node pointer
-    newChild->parentNode = nodeptr;
-    newChild->ownerDocument = nodeptr->ownerDocument;
-
-    //if the first child
-    if( nodeptr->firstChild == NULL ) {
-        nodeptr->firstChild = newChild;
-    } else {
-        prev = nodeptr->firstChild;
-        next = prev->nextSibling;
-        while( next != NULL ) {
-            prev = next;
-            next = prev->nextSibling;
-        }
-        prev->nextSibling = newChild;
-        newChild->prevSibling = prev;
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*================================================================
-*   ixmlNode_cloneTextNode
-*       Returns a clone of nodeptr
-*       Internal to parser only.
-*
-*=================================================================*/
-IXML_Node *
-ixmlNode_cloneTextNode( IN IXML_Node * nodeptr )
-{
-    IXML_Node *newNode = NULL;
-
-    assert( nodeptr != NULL );
-
-    newNode = ( IXML_Node * ) malloc( sizeof( IXML_Node ) );
-    if( newNode == NULL ) {
-        return NULL;
-    } else {
-        ixmlNode_init( newNode );
-
-        ixmlNode_setNodeName( newNode, nodeptr->nodeName );
-        ixmlNode_setNodeValue( newNode, nodeptr->nodeValue );
-        newNode->nodeType = eTEXT_NODE;
-    }
-
-    return newNode;
-}
-
-/*================================================================
-*   ixmlNode_cloneCDATASect
-*       Return a clone of CDATASection node.
-*       Internal to parser only.
-*
-*=================================================================*/
-IXML_CDATASection *
-ixmlNode_cloneCDATASect( IN IXML_CDATASection * nodeptr )
-{
-    IXML_CDATASection *newCDATA = NULL;
-    IXML_Node *newNode;
-    IXML_Node *srcNode;
-
-    assert( nodeptr != NULL );
-    newCDATA =
-        ( IXML_CDATASection * ) malloc( sizeof( IXML_CDATASection ) );
-    if( newCDATA != NULL ) {
-        newNode = ( IXML_Node * ) newCDATA;
-        ixmlNode_init( newNode );
-
-        srcNode = ( IXML_Node * ) nodeptr;
-        ixmlNode_setNodeName( newNode, srcNode->nodeName );
-        ixmlNode_setNodeValue( newNode, srcNode->nodeValue );
-        newNode->nodeType = eCDATA_SECTION_NODE;
-    }
-
-    return newCDATA;
-}
-
-/*================================================================
-*   ixmlNode_cloneElement
-*       returns a clone of element node
-*       Internal to parser only.
-*
-*=================================================================*/
-IXML_Element *
-ixmlNode_cloneElement( IN IXML_Element * nodeptr )
-{
-    IXML_Element *newElement;
-    IXML_Node *elementNode;
-    IXML_Node *srcNode;
-    int rc;
-
-    assert( nodeptr != NULL );
-
-    newElement = ( IXML_Element * ) malloc( sizeof( IXML_Element ) );
-    if( newElement == NULL ) {
-        return NULL;
-    }
-
-    ixmlElement_init( newElement );
-    rc = ixmlElement_setTagName( newElement, nodeptr->tagName );
-    if( rc != IXML_SUCCESS ) {
-        ixmlElement_free( newElement );
-	return NULL;
-    }
-
-    elementNode = ( IXML_Node * ) newElement;
-    srcNode = ( IXML_Node * ) nodeptr;
-    rc = ixmlNode_setNodeName( elementNode, srcNode->nodeName );
-    if( rc != IXML_SUCCESS ) {
-        ixmlElement_free( newElement );
-        return NULL;
-    }
-
-    rc = ixmlNode_setNodeValue( elementNode, srcNode->nodeValue );
-    if( rc != IXML_SUCCESS ) {
-        ixmlElement_free( newElement );
-        return NULL;
-    }
-
-    rc = ixmlNode_setNamespaceURI( elementNode, srcNode->namespaceURI );
-    if( rc != IXML_SUCCESS ) {
-        ixmlElement_free( newElement );
-        return NULL;
-    }
-
-    rc = ixmlNode_setPrefix( elementNode, srcNode->prefix );
-    if( rc != IXML_SUCCESS ) {
-        ixmlElement_free( newElement );
-        return NULL;
-    }
-
-    rc = ixmlNode_setLocalName( elementNode, srcNode->localName );
-    if( rc != IXML_SUCCESS ) {
-        ixmlElement_free( newElement );
-        return NULL;
-    }
-
-    elementNode->nodeType = eELEMENT_NODE;
-
-    return newElement;
-
-}
-
-/*================================================================
-*   ixmlNode_cloneDoc
-*       Returns a clone of document node
-*       Internal to parser only.
-*
-*=================================================================*/
-IXML_Document *
-ixmlNode_cloneDoc( IN IXML_Document * nodeptr )
-{
-    IXML_Document *newDoc;
-    IXML_Node *docNode;
-    int rc;
-
-    assert( nodeptr != NULL );
-    newDoc = ( IXML_Document * ) malloc( sizeof( IXML_Document ) );
-    if( newDoc == NULL ) {
-        return NULL;
-    }
-
-    ixmlDocument_init( newDoc );
-    docNode = ( IXML_Node * ) newDoc;
-
-    rc = ixmlNode_setNodeName( docNode, DOCUMENTNODENAME );
-    if( rc != IXML_SUCCESS ) {
-        ixmlDocument_free( newDoc );
-        return NULL;
-    }
-
-    newDoc->n.nodeType = eDOCUMENT_NODE;
-
-    return newDoc;
-
-}
-
-/*================================================================
-*   ixmlNode_cloneAttr
-*       Returns a clone of attribute node
-*       Internal to parser only
-*
-*=================================================================*/
-IXML_Attr *
-ixmlNode_cloneAttr( IN IXML_Attr * nodeptr )
-{
-    IXML_Attr *newAttr;
-    IXML_Node *attrNode;
-    IXML_Node *srcNode;
-    int rc;
-
-    assert( nodeptr != NULL );
-    newAttr = ( IXML_Attr * ) malloc( sizeof( IXML_Attr ) );
-    if( newAttr == NULL ) {
-        return NULL;
-    }
-
-    ixmlAttr_init( newAttr );
-    attrNode = ( IXML_Node * ) newAttr;
-    srcNode = ( IXML_Node * ) nodeptr;
-
-    rc = ixmlNode_setNodeName( attrNode, srcNode->nodeName );
-    if( rc != IXML_SUCCESS ) {
-        ixmlAttr_free( newAttr );
-        return NULL;
-    }
-
-    rc = ixmlNode_setNodeValue( attrNode, srcNode->nodeValue );
-    if( rc != IXML_SUCCESS ) {
-        ixmlAttr_free( newAttr );
-        return NULL;
-    }
-    //check to see whether we need to split prefix and localname for attribute
-    rc = ixmlNode_setNamespaceURI( attrNode, srcNode->namespaceURI );
-    if( rc != IXML_SUCCESS ) {
-        ixmlAttr_free( newAttr );
-        return NULL;
-    }
-
-    rc = ixmlNode_setPrefix( attrNode, srcNode->prefix );
-    if( rc != IXML_SUCCESS ) {
-        ixmlAttr_free( newAttr );
-        return NULL;
-    }
-
-    rc = ixmlNode_setLocalName( attrNode, srcNode->localName );
-    if( rc != IXML_SUCCESS ) {
-        ixmlAttr_free( newAttr );
-        return NULL;
-    }
-
-    attrNode->nodeType = eATTRIBUTE_NODE;
-
-    return newAttr;
-}
-
-/*================================================================
-*   ixmlNode_cloneAttrDirect
-*       Return a clone of attribute node, with specified field set
-*       to TRUE.
-*
-*=================================================================*/
-IXML_Attr *
-ixmlNode_cloneAttrDirect( IN IXML_Attr * nodeptr )
-{
-
-    IXML_Attr *newAttr;
-
-    assert( nodeptr != NULL );
-
-    newAttr = ixmlNode_cloneAttr( nodeptr );
-    if( newAttr != NULL ) {
-        newAttr->specified = TRUE;
-    }
-
-    return newAttr;
-}
-
-void
-ixmlNode_setSiblingNodesParent( IXML_Node * nodeptr )
-{
-    IXML_Node *parentNode = nodeptr->parentNode;
-    IXML_Node *nextptr = nodeptr->nextSibling;
-
-    while( nextptr != NULL ) {
-        nextptr->parentNode = parentNode;
-        nextptr = nextptr->nextSibling;
-    }
-}
-
-/*================================================================
-*   ixmlNode_cloneNodeTreeRecursive
-*       recursive functions that clones node tree of nodeptr.
-*       Internal to parser only.
-*       
-*=================================================================*/
-IXML_Node *
-ixmlNode_cloneNodeTreeRecursive( IN IXML_Node * nodeptr,
-                                 IN BOOL deep )
-{
-    IXML_Node *newNode = NULL;
-    IXML_Element *newElement;
-    IXML_Attr *newAttr = NULL;
-    IXML_CDATASection *newCDATA = NULL;
-    IXML_Document *newDoc;
-    IXML_Node *nextSib;
-
-    if( nodeptr != NULL ) {
-        switch ( nodeptr->nodeType ) {
-            case eELEMENT_NODE:
-                newElement =
-                    ixmlNode_cloneElement( ( IXML_Element * ) nodeptr );
-                newElement->n.firstAttr =
-                    ixmlNode_cloneNodeTreeRecursive( nodeptr->firstAttr,
-                                                     deep );
-                if( deep ) {
-                    newElement->n.firstChild =
-                        ixmlNode_cloneNodeTreeRecursive( nodeptr->
-                                                         firstChild,
-                                                         deep );
-                    if( newElement->n.firstChild != NULL ) {
-                        ( newElement->n.firstChild )->parentNode =
-                            ( IXML_Node * ) newElement;
-                        ixmlNode_setSiblingNodesParent( newElement->n.
-                                                        firstChild );
-                    }
-                    nextSib =
-                        ixmlNode_cloneNodeTreeRecursive( nodeptr->
-                                                         nextSibling,
-                                                         deep );
-                    newElement->n.nextSibling = nextSib;
-                    if( nextSib != NULL ) {
-                        nextSib->prevSibling = ( IXML_Node * ) newElement;
-                    }
-                }
-
-                newNode = ( IXML_Node * ) newElement;
-                break;
-
-            case eATTRIBUTE_NODE:
-                newAttr = ixmlNode_cloneAttr( ( IXML_Attr * ) nodeptr );
-                nextSib =
-                    ixmlNode_cloneNodeTreeRecursive( nodeptr->nextSibling,
-                                                     deep );
-                newAttr->n.nextSibling = nextSib;
-
-                if( nextSib != NULL ) {
-                    nextSib->prevSibling = ( IXML_Node * ) newAttr;
-                }
-                newNode = ( IXML_Node * ) newAttr;
-                break;
-
-            case eTEXT_NODE:
-                newNode = ixmlNode_cloneTextNode( nodeptr );
-                break;
-
-            case eCDATA_SECTION_NODE:
-                newCDATA =
-                    ixmlNode_cloneCDATASect( ( IXML_CDATASection * )
-                                             nodeptr );
-                newNode = ( IXML_Node * ) newCDATA;
-                break;
-
-            case eDOCUMENT_NODE:
-                newDoc = ixmlNode_cloneDoc( ( IXML_Document * ) nodeptr );
-                newNode = ( IXML_Node * ) newDoc;
-                if( deep ) {
-                    newNode->firstChild =
-                        ixmlNode_cloneNodeTreeRecursive( nodeptr->
-                                                         firstChild,
-                                                         deep );
-                    if( newNode->firstChild != NULL ) {
-                        newNode->firstChild->parentNode = newNode;
-                    }
-                }
-
-                break;
-
-            case eINVALID_NODE:
-            case eENTITY_REFERENCE_NODE:
-            case eENTITY_NODE:
-            case ePROCESSING_INSTRUCTION_NODE:
-            case eCOMMENT_NODE:
-            case eDOCUMENT_TYPE_NODE:
-            case eDOCUMENT_FRAGMENT_NODE:
-            case eNOTATION_NODE:
-                break;
-        }
-    }
-
-    return newNode;
-}
-
-/*================================================================
-*   ixmlNode_cloneNodeTree
-*       clones a node tree.
-*       Internal to parser only.
-*
-*=================================================================*/
-IXML_Node *
-ixmlNode_cloneNodeTree( IN IXML_Node * nodeptr,
-                        IN BOOL deep )
-{
-    IXML_Node *newNode = NULL;
-    IXML_Element *newElement;
-    IXML_Node *childNode;
-
-    assert( nodeptr != NULL );
-
-    switch ( nodeptr->nodeType ) {
-        case eELEMENT_NODE:
-            newElement =
-                ixmlNode_cloneElement( ( IXML_Element * ) nodeptr );
-            newElement->n.firstAttr =
-                ixmlNode_cloneNodeTreeRecursive( nodeptr->firstAttr,
-                                                 deep );
-            if( deep ) {
-                newElement->n.firstChild =
-                    ixmlNode_cloneNodeTreeRecursive( nodeptr->firstChild,
-                                                     deep );
-                childNode = newElement->n.firstChild;
-                while( childNode != NULL ) {
-                    childNode->parentNode = ( IXML_Node * ) newElement;
-                    childNode = childNode->nextSibling;
-                }
-                newElement->n.nextSibling = NULL;
-            }
-
-            newNode = ( IXML_Node * ) newElement;
-            break;
-
-        case eATTRIBUTE_NODE:
-        case eTEXT_NODE:
-        case eCDATA_SECTION_NODE:
-        case eDOCUMENT_NODE:
-            newNode = ixmlNode_cloneNodeTreeRecursive( nodeptr, deep );
-            break;
-
-        case eINVALID_NODE:
-        case eENTITY_REFERENCE_NODE:
-        case eENTITY_NODE:
-        case ePROCESSING_INSTRUCTION_NODE:
-        case eCOMMENT_NODE:
-        case eDOCUMENT_TYPE_NODE:
-        case eDOCUMENT_FRAGMENT_NODE:
-        case eNOTATION_NODE:
-/* create a new node here?            newNode = (IXML_Node *)malloc(sizeof(IXML_Node));
-            if( newNode == NULL ) {
-                return NULL;
-            }*/
-            break;
-    }
-
-    // by spec, the duplicate node has no parent
-    newNode->parentNode = NULL;
-
-    return newNode;
-}
-
-/*================================================================
-*   ixmlNode_cloneNode
-*       Clones a node, if deep==TRUE, clones subtree under nodeptr.
-*       External function.
-*   Returns:
-*       the cloned node or NULL if error occurs.
-*
-*=================================================================*/
-IXML_Node *
-ixmlNode_cloneNode( IN IXML_Node * nodeptr,
-                    IN BOOL deep )
-{
-
-    IXML_Node *newNode;
-    IXML_Attr *newAttrNode;
-
-    if( nodeptr == NULL ) {
-        return NULL;
-    }
-
-    switch ( nodeptr->nodeType ) {
-        case eATTRIBUTE_NODE:
-            newAttrNode =
-                ixmlNode_cloneAttrDirect( ( IXML_Attr * ) nodeptr );
-            return ( IXML_Node * ) newAttrNode;
-            break;
-
-        default:
-            newNode = ixmlNode_cloneNodeTree( nodeptr, deep );
-            return newNode;
-            break;
-    }
-
-}
-
-/*================================================================
-*   ixmlNode_getChildNodes
-*       Returns a IXML_NodeList of all the child nodes of nodeptr.
-*       External function.
-*   
-*=================================================================*/
-IXML_NodeList *
-ixmlNode_getChildNodes( IN IXML_Node * nodeptr )
-{
-    IXML_Node *tempNode;
-    IXML_NodeList *newNodeList;
-    int rc;
-
-    if( nodeptr == NULL ) {
-        return NULL;
-    }
-
-    newNodeList = ( IXML_NodeList * ) malloc( sizeof( IXML_NodeList ) );
-    if( newNodeList == NULL ) {
-        return NULL;
-    }
-
-    ixmlNodeList_init( newNodeList );
-
-    tempNode = nodeptr->firstChild;
-    while( tempNode != NULL ) {
-        rc = ixmlNodeList_addToNodeList( &newNodeList, tempNode );
-        if( rc != IXML_SUCCESS ) {
-            ixmlNodeList_free( newNodeList );
-            return NULL;
-        }
-
-        tempNode = tempNode->nextSibling;
-    }
-    return newNodeList;
-}
-
-/*================================================================
-*   ixmlNode_getAttributes
-*       returns a namedNodeMap of attributes of nodeptr
-*       External function.
-*   Returns:
-*
-*=================================================================*/
-IXML_NamedNodeMap *
-ixmlNode_getAttributes( IN IXML_Node * nodeptr )
-{
-    IXML_NamedNodeMap *returnNamedNodeMap = NULL;
-    IXML_Node *tempNode;
-    int rc;
-
-    if( nodeptr == NULL ) {
-        return NULL;
-    }
-
-    if( nodeptr->nodeType == eELEMENT_NODE ) {
-        returnNamedNodeMap =
-            ( IXML_NamedNodeMap * ) malloc( sizeof( IXML_NamedNodeMap ) );
-        if( returnNamedNodeMap == NULL ) {
-            return NULL;
-        }
-
-        ixmlNamedNodeMap_init( returnNamedNodeMap );
-
-        tempNode = nodeptr->firstAttr;
-        while( tempNode != NULL ) {
-            rc = ixmlNamedNodeMap_addToNamedNodeMap( &returnNamedNodeMap,
-                                                     tempNode );
-            if( rc != IXML_SUCCESS ) {
-                ixmlNamedNodeMap_free( returnNamedNodeMap );
-                return NULL;
-            }
-
-            tempNode = tempNode->nextSibling;
-        }
-        return returnNamedNodeMap;
-    } else {                    // if not an ELEMENT_NODE
-        return NULL;
-    }
-}
-
-/*================================================================
-*   ixmlNode_hasChildNodes
-*       External function.
-*
-*=================================================================*/
-BOOL
-ixmlNode_hasChildNodes( IXML_Node * nodeptr )
-{
-    if( nodeptr == NULL ) {
-        return FALSE;
-    }
-
-    return ( nodeptr->firstChild != NULL );
-
-}
-
-/*================================================================
-*   ixmlNode_hasAttributes
-*       External function.
-*
-*=================================================================*/
-BOOL
-ixmlNode_hasAttributes( IXML_Node * nodeptr )
-{
-    if( nodeptr != NULL ) {
-        if( ( nodeptr->nodeType == eELEMENT_NODE )
-            && ( nodeptr->firstAttr != NULL ) ) {
-            return TRUE;
-        }
-    }
-    return FALSE;
-
-}
-
-/*================================================================
-*   ixmlNode_getElementsByTagNameRecursive
-*       Recursively traverse the whole tree, search for element
-*       with the given tagname.
-*       Internal to parser.
-*
-*=================================================================*/
-void
-ixmlNode_getElementsByTagNameRecursive( IN IXML_Node * n,
-                                        IN const char *tagname,
-                                        OUT IXML_NodeList ** list )
-{
-    const char *name;
-
-    if( n != NULL ) {
-        if( ixmlNode_getNodeType( n ) == eELEMENT_NODE ) {
-            name = ixmlNode_getNodeName( n );
-            if( strcmp( tagname, name ) == 0
-                || strcmp( tagname, "*" ) == 0 ) {
-                ixmlNodeList_addToNodeList( list, n );
-            }
-        }
-
-        ixmlNode_getElementsByTagNameRecursive( ixmlNode_getFirstChild
-                                                ( n ), tagname, list );
-        ixmlNode_getElementsByTagNameRecursive( ixmlNode_getNextSibling
-                                                ( n ), tagname, list );
-    }
-
-}
-
-/*================================================================
-*   ixmlNode_getElementsByTagName
-*       Returns a nodeList of all descendant Elements with a given 
-*       tagName, in the order in which they are encountered in a
-*       traversal of this element tree.
-*       External function.		
-*
-*=================================================================*/
-void
-ixmlNode_getElementsByTagName( IN IXML_Node * n,
-                               IN const char *tagname,
-                               OUT IXML_NodeList ** list )
-{
-    const char *name;
-
-    assert( n != NULL && tagname != NULL );
-
-    if( ixmlNode_getNodeType( n ) == eELEMENT_NODE ) {
-        name = ixmlNode_getNodeName( n );
-        if( strcmp( tagname, name ) == 0 || strcmp( tagname, "*" ) == 0 ) {
-            ixmlNodeList_addToNodeList( list, n );
-        }
-    }
-
-    ixmlNode_getElementsByTagNameRecursive( ixmlNode_getFirstChild( n ),
-                                            tagname, list );
-
-}
-
-/*================================================================
-*   ixmlNode_getElementsByTagNameNSRecursive
-*	    Internal function to parser.	
-*		
-*
-*=================================================================*/
-void
-ixmlNode_getElementsByTagNameNSRecursive( IN IXML_Node * n,
-                                          IN const char *namespaceURI,
-                                          IN const char *localName,
-                                          OUT IXML_NodeList ** list )
-{
-    const DOMString nsURI;
-    const DOMString name;
-
-    if( n != NULL ) {
-        if( ixmlNode_getNodeType( n ) == eELEMENT_NODE ) {
-            name = ixmlNode_getLocalName( n );
-            nsURI = ixmlNode_getNamespaceURI( n );
-
-            if( ( name != NULL ) && ( nsURI != NULL ) &&
-                ( strcmp( namespaceURI, nsURI ) == 0
-                  || strcmp( namespaceURI, "*" ) == 0 )
-                && ( strcmp( name, localName ) == 0
-                     || strcmp( localName, "*" ) == 0 ) ) {
-                ixmlNodeList_addToNodeList( list, n );
-            }
-        }
-
-        ixmlNode_getElementsByTagNameNSRecursive( ixmlNode_getFirstChild
-                                                  ( n ), namespaceURI,
-                                                  localName, list );
-        ixmlNode_getElementsByTagNameNSRecursive( ixmlNode_getNextSibling
-                                                  ( n ), namespaceURI,
-                                                  localName, list );
-    }
-
-}
-
-/*================================================================
-*   ixmlNode_getElementsByTagNameNS
-*       Returns a nodeList of all the descendant Elements with a given
-*       local name and namespace URI in the order in which they are
-*       encountered in a preorder traversal of this Elememt tree.		
-*		External function.
-*
-*=================================================================*/
-void
-ixmlNode_getElementsByTagNameNS( IN IXML_Node * n,
-                                 IN const char *namespaceURI,
-                                 IN const char *localName,
-                                 OUT IXML_NodeList ** list )
-{
-    const DOMString nsURI;
-    const DOMString name;
-
-    assert( n != NULL && namespaceURI != NULL && localName != NULL );
-
-    if( ixmlNode_getNodeType( n ) == eELEMENT_NODE ) {
-        name = ixmlNode_getLocalName( n );
-        nsURI = ixmlNode_getNamespaceURI( n );
-
-        if( ( name != NULL ) && ( nsURI != NULL ) &&
-            ( strcmp( namespaceURI, nsURI ) == 0
-              || strcmp( namespaceURI, "*" ) == 0 )
-            && ( strcmp( name, localName ) == 0
-                 || strcmp( localName, "*" ) == 0 ) ) {
-            ixmlNodeList_addToNodeList( list, n );
-        }
-    }
-
-    ixmlNode_getElementsByTagNameNSRecursive( ixmlNode_getFirstChild( n ),
-                                              namespaceURI, localName,
-                                              list );
-
-}
-
-/*================================================================
-*   ixmlNode_setNodeName
-*       Internal to parser only.
-*
-*=================================================================*/
-int
-ixmlNode_setNodeName( IN IXML_Node * node,
-                      IN const DOMString qualifiedName )
-{
-    int rc = IXML_SUCCESS;
-
-    assert( node != NULL );
-
-    if( node->nodeName != NULL ) {
-        free( node->nodeName );
-        node->nodeName = NULL;
-    }
-
-    if( qualifiedName != NULL ) {
-        // set the name part
-        node->nodeName = strdup( qualifiedName );
-        if( node->nodeName == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-
-        rc = Parser_setNodePrefixAndLocalName( node );
-        if( rc != IXML_SUCCESS ) {
-            free( node->nodeName );
-        }
-    }
-
-    return rc;
-}
-
-/*================================================================
-*   ixmlNode_setNodeProperties
-*       Internal to parser only.
-*
-*=================================================================*/
-int
-ixmlNode_setNodeProperties( IN IXML_Node * destNode,
-                            IN IXML_Node * src )
-{
-
-    int rc;
-
-    assert( destNode != NULL && src != NULL );
-    if (destNode == NULL || src == NULL) {
-        return IXML_INVALID_PARAMETER;
-    }
-
-    rc = ixmlNode_setNodeValue( destNode, src->nodeValue );
-    if( rc != IXML_SUCCESS ) {
-        goto ErrorHandler;
-    }
-
-    rc = ixmlNode_setLocalName( destNode, src->localName );
-    if( rc != IXML_SUCCESS ) {
-        goto ErrorHandler;
-    }
-
-    rc = ixmlNode_setPrefix( destNode, src->prefix );
-    if( rc != IXML_SUCCESS ) {
-        goto ErrorHandler;
-    }
-    // set nodetype
-    destNode->nodeType = src->nodeType;
-
-    return IXML_SUCCESS;
-
-  ErrorHandler:
-    if( destNode->nodeName != NULL ) {
-        free( destNode->nodeName );
-        destNode->nodeName = NULL;
-    }
-    if( destNode->nodeValue != NULL ) {
-        free( destNode->nodeValue );
-        destNode->nodeValue = NULL;
-    }
-    if( destNode->localName != NULL ) {
-        free( destNode->localName );
-        destNode->localName = NULL;
-    }
-
-    return IXML_INSUFFICIENT_MEMORY;
-}
diff --git a/tombupnp/ixml/src/nodeList.c b/tombupnp/ixml/src/nodeList.c
deleted file mode 100644
index aadd158..0000000
--- a/tombupnp/ixml/src/nodeList.c
+++ /dev/null
@@ -1,176 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include "ixmlparser.h"
-
-/*================================================================
-*   ixmlNodeList_init
-*       initializes a nodelist 
-*       External function.
-*
-*=================================================================*/
-void
-ixmlNodeList_init( IXML_NodeList * nList )
-{
-    assert( nList != NULL );
-
-    memset( nList, 0, sizeof( IXML_NodeList ) );
-
-}
-
-/*================================================================
-*   ixmlNodeList_item
-*       Returns the indexth item in the collection. If index is greater
-*       than or equal to the number of nodes in the list, this returns 
-*       null.
-*       External function.
-*
-*=================================================================*/
-IXML_Node *
-ixmlNodeList_item( IXML_NodeList * nList,
-                   unsigned long index )
-{
-    IXML_NodeList *next;
-    unsigned int i;
-
-    // if the list ptr is NULL
-    if( nList == NULL ) {
-        return NULL;
-    }
-    // if index is more than list length
-    if( index > ixmlNodeList_length( nList ) - 1 ) {
-        return NULL;
-    }
-
-    next = nList;
-    for( i = 0; i < index && next != NULL; ++i ) {
-        next = next->next;
-    }
-
-    if( next == NULL ) return NULL;
-
-    return next->nodeItem;
-
-}
-
-/*================================================================
-*   ixmlNodeList_addToNodeList
-*       Add a node to nodelist
-*       Internal to parser only.
-*
-*=================================================================*/
-int
-ixmlNodeList_addToNodeList( IN IXML_NodeList ** nList,
-                            IN IXML_Node * add )
-{
-    IXML_NodeList *traverse,
-     *p = NULL;
-    IXML_NodeList *newListItem;
-
-    assert( add != NULL );
-
-    if( add == NULL ) {
-        return IXML_FAILED;
-    }
-
-    if( *nList == NULL )        // nodelist is empty
-    {
-        *nList = ( IXML_NodeList * ) malloc( sizeof( IXML_NodeList ) );
-        if( *nList == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-
-        ixmlNodeList_init( *nList );
-    }
-
-    if( ( *nList )->nodeItem == NULL ) {
-        ( *nList )->nodeItem = add;
-    } else {
-        traverse = *nList;
-        while( traverse != NULL ) {
-            p = traverse;
-            traverse = traverse->next;
-        }
-
-        newListItem =
-            ( IXML_NodeList * ) malloc( sizeof( IXML_NodeList ) );
-        if( newListItem == NULL ) {
-            return IXML_INSUFFICIENT_MEMORY;
-        }
-        p->next = newListItem;
-        newListItem->nodeItem = add;
-        newListItem->next = NULL;
-    }
-
-    return IXML_SUCCESS;
-}
-
-/*================================================================
-*   ixmlNodeList_length
-*       Returns the number of nodes in the list.  The range of valid
-*       child node indices is 0 to length-1 inclusive.
-*       External function.       
-*
-*=================================================================*/
-unsigned long
-ixmlNodeList_length( IN IXML_NodeList * nList )
-{
-    IXML_NodeList *list;
-    unsigned long length = 0;
-
-    list = nList;
-    while( list != NULL ) {
-        ++length;
-        list = list->next;
-    }
-
-    return length;
-}
-
-/*================================================================
-*   ixmlNodeList_free
-*       frees a nodeList
-*       External function
-*       
-*=================================================================*/
-void
-ixmlNodeList_free( IN IXML_NodeList * nList )
-{
-    IXML_NodeList *next;
-
-    while( nList != NULL ) {
-        next = nList->next;
-
-        free( nList );
-        nList = next;
-    }
-
-}
diff --git a/tombupnp/threadutil/inc/FreeList.h b/tombupnp/threadutil/inc/FreeList.h
deleted file mode 100644
index d32e74a..0000000
--- a/tombupnp/threadutil/inc/FreeList.h
+++ /dev/null
@@ -1,141 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef FREE_LIST_H
-#define FREE_LIST_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "ithread.h"
-#include <errno.h>
-
-/****************************************************************************
- * Name: FreeListNode
- *
- *  Description:
- *      free list node. points to next free item.
- *      memory for node is borrowed from allocated items.
- *      Internal Use Only.
- *****************************************************************************/
-typedef struct FREELISTNODE
-{
-	struct FREELISTNODE*next; //pointer to next free node
-} FreeListNode;
-
-
-/****************************************************************************
- * Name: FreeList
- *
- *  Description:
- *      Stores head and size of free list, as well as mutex for protection.
- *      Internal Use Only.
- *****************************************************************************/
-typedef struct FREELIST
-{
-	FreeListNode *head; //head of free list
-	size_t element_size;	//size of elements in free 
- 							//list
- 	int maxFreeListLength; //max size of free structures 
-						 //to keep
-	int freeListLength; //current size of free list
-        
-}FreeList;
-
-/****************************************************************************
- * Function: FreeListInit
- *
- *  Description:
- *      Initializes Free List. Must be called first.
- *      And only once for FreeList.
- *  Parameters:
- *      free_list  - must be valid, non null, pointer to a linked list.
- *      size_t -     size of elements to store in free list
- *      maxFreeListSize - max size that the free list can grow to
- *                        before returning memory to O.S.
- *  Returns:
- *      0 on success. Nonzero on failure.
- *      Always returns 0.
- *****************************************************************************/
-int FreeListInit(FreeList *free_list, 
-				 size_t elementSize, 
-				 int maxFreeListSize);
-
-/****************************************************************************
- * Function: FreeListAlloc
- *
- *  Description:
- *      Allocates chunk of set size.
- *      If a free item is available in the list, returnes the stored item.
- *      Otherwise calls the O.S. to allocate memory.
- *  Parameters:
- *      free_list  - must be valid, non null, pointer to a linked list.
- *  Returns:
- *      Non NULL on success. NULL on failure.
- *****************************************************************************/
-void * FreeListAlloc (FreeList *free_list);
-
-/****************************************************************************
- * Function: FreeListFree
- *
- *  Description:
- *      Returns an item to the Free List.
- *      If the free list is smaller than the max size than
- *      adds the item to the free list.
- *      Otherwise returns the item to the O.S.
- *  Parameters:
- *      free_list  - must be valid, non null, pointer to a linked list.
- *  Returns:
- *      0 on success. Nonzero on failure.
- *      Always returns 0.
- *****************************************************************************/
-int FreeListFree (FreeList *free_list,void * element);
-
-/****************************************************************************
- * Function: FreeListDestroy
- *
- *  Description:
- *      Releases the resources stored with the free list.
- *  Parameters:
- *      free_list  - must be valid, non null, pointer to a linked list.
- *  Returns:
- *      0 on success. Nonzero on failure.
- *      Always returns 0.
- *****************************************************************************/
-int FreeListDestroy (FreeList *free_list);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // FREE_LIST_H
diff --git a/tombupnp/threadutil/inc/LinkedList.h b/tombupnp/threadutil/inc/LinkedList.h
deleted file mode 100644
index 2572723..0000000
--- a/tombupnp/threadutil/inc/LinkedList.h
+++ /dev/null
@@ -1,330 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef LINKED_LIST_H
-#define LINKED_LIST_H
-
-#include "FreeList.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define EOUTOFMEM (-7 & 1<<29)
-
-#define FREELISTSIZE 100
-#define LIST_SUCCESS 1
-#define LIST_FAIL 0
-
-/****************************************************************************
- * Name: free_routine
- *
- *  Description:
- *     Function for freeing list items
- *****************************************************************************/
-typedef void (*free_function)(void *arg);
-
-/****************************************************************************
- * Name: cmp_routine
- *
- *  Description:
- *     Function for comparing list items
- *     Returns 1 if itemA==itemB
- *****************************************************************************/
-typedef int (*cmp_routine)(void *itemA,void *itemB);
-
-/****************************************************************************
- * Name: ListNode
- *
- *  Description:
- *      linked list node. stores generic item and pointers to next and prev.
- *      Internal Use Only.
- *****************************************************************************/
-typedef struct LISTNODE
-{
-  struct LISTNODE *prev; //previous node
-  struct LISTNODE *next; //next node
-  void *item; //item
-} ListNode;
-
-/****************************************************************************
- * Name: LinkedList
- *
- *  Description:
- *      linked list (no protection). Internal Use Only.
- *      Because this is for internal use, parameters are NOT checked for 
- *      validity.
- *      The first item of the list is stored at node: head->next
- *      The last item of the list is stored at node: tail->prev
- *      If head->next=tail, then list is empty.
- *      To iterate through the list:
- *
- *       LinkedList g;
- *       ListNode *temp = NULL;
- *       for (temp = ListHead(g);temp!=NULL;temp = ListNext(g,temp))
- *       {
- *        }
- *
- *****************************************************************************/
-typedef struct LINKEDLIST
-{
-  ListNode head; //head, first item is stored at: head->next
-  ListNode tail; //tail, last item is stored at: tail->prev
-  long size;      //size of list
-  FreeList freeNodeList; //free list to use
-  free_function free_func; //free function to use
-  cmp_routine cmp_func; //compare function to use
-} LinkedList;
-
-/****************************************************************************
- * Function: ListInit
- *
- *  Description:
- *      Initializes LinkedList. Must be called first.
- *      And only once for List.
- *  Parameters:
- *      list  - must be valid, non null, pointer to a linked list.
- *      cmp_func - function used to compare items. (May be NULL)
- *      free_func - function used to free items. (May be NULL)
- *  Returns:
- *      0 on success, EOUTOFMEM on failure.
- *****************************************************************************/
-int ListInit(LinkedList *list,cmp_routine cmp_func, free_function free_func);
-
-/****************************************************************************
- * Function: ListAddHead
- *
- *  Description:
- *      Adds a node to the head of the list.
- *      Node gets immediately after list.head.
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *      void * item - item to be added
- *  Returns:
- *      The pointer to the ListNode on success, NULL on failure.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode *ListAddHead(LinkedList *list, void *item);
-
-/****************************************************************************
- * Function: ListAddTail
- *
- *  Description:
- *      Adds a node to the tail of the list.
- *      Node gets added immediately before list.tail.
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *      void * item - item to be added
- *  Returns:
- *      The pointer to the ListNode on success, NULL on failure.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode *ListAddTail(LinkedList *list, void *item);
-
-/****************************************************************************
- * Function: ListAddAfter
- *
- *  Description:
- *      Adds a node after the specified node.
- *      Node gets added immediately after bnode.
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *      void * item - item to be added
- *      ListNode * bnode - node to add after
- *  Returns:
- *      The pointer to the ListNode on success, NULL on failure.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode *ListAddAfter(LinkedList *list, void *item, ListNode *bnode);
-
-
-/****************************************************************************
- * Function: ListAddBefore
- *
- *  Description:
- *      Adds a node before the specified node.
- *      Node gets added immediately before anode.
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *      ListNode * anode  - node to add the in front of.
- *      void * item - item to be added
- *  Returns:
- *      The pointer to the ListNode on success, NULL on failure.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode *ListAddBefore(LinkedList *list,void *item, ListNode *anode);
-
-
-/****************************************************************************
- * Function: ListDelNode
- *
- *  Description:
- *      Removes a node from the list
- *      The memory for the node is freed.
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *      ListNode *dnode - done to delete.
- *      freeItem - if !0 then item is freed using free function.
- *                 if 0 (or free function is NULL) then item is not freed
- *  Returns:
- *      The pointer to the item stored in the node or NULL if the item is freed.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-void *ListDelNode(LinkedList *list,ListNode *dnode, int freeItem);
-
-/****************************************************************************
- * Function: ListDestroy
- *
- *  Description:
- *      Removes all memory associated with list nodes. 
- *      Does not free LinkedList *list. 
- *    
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *      freeItem - if !0 then items are freed using the free_function.
- *                 if 0 (or free function is NULL) then items are not freed.
- *  Returns:
- *      0 on success. Always returns 0.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-int ListDestroy(LinkedList *list, int freeItem);
-
-
-/****************************************************************************
- * Function: ListHead
- *
- *  Description:
- *      Returns the head of the list.
- *    
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *  
- *  Returns:
- *      The head of the list. NULL if list is empty.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode* ListHead(LinkedList *list);
-
-/****************************************************************************
- * Function: ListTail
- *
- *  Description:
- *      Returns the tail of the list.
- *    
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *  
- *  Returns:
- *      The tail of the list. NULL if list is empty.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode* ListTail(LinkedList *list);
-
-/****************************************************************************
- * Function: ListNext
- *
- *  Description:
- *      Returns the next item in the list.
- *    
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *  
- *  Returns:
- *      The next item in the list. NULL if there are no more items in list.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode* ListNext(LinkedList *list, ListNode * node);
-
-/****************************************************************************
- * Function: ListPrev
- *
- *  Description:
- *      Returns the previous item in the list.
- *    
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *  
- *  Returns:
- *      The previous item in the list. NULL if there are no more items in list.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode* ListPrev(LinkedList *list, ListNode * node);
-
-/****************************************************************************
- * Function: ListFind
- *
- *  Description:
- *      Finds the specified item in the list.
- *      Uses the compare function specified in ListInit. If compare function
- *      is NULL then compares items as pointers.
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *      ListNode *start - the node to start from, NULL if to start from 
- *                        beginning.
- *      void * item - the item to search for.
- *  Returns:
- *      The node containing the item. NULL if no node contains the item.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode* ListFind(LinkedList *list, ListNode *start, void * item);
-
-/****************************************************************************
- * Function: ListSize
- *
- *  Description:
- *     Returns the size of the list.
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- 
- *  Returns:
- *      The number of items in the list.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-int ListSize(LinkedList* list);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //LINKED_LIST_H
diff --git a/tombupnp/threadutil/inc/ThreadPool.h b/tombupnp/threadutil/inc/ThreadPool.h
deleted file mode 100644
index bc94c0a..0000000
--- a/tombupnp/threadutil/inc/ThreadPool.h
+++ /dev/null
@@ -1,583 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-#ifndef THREADPOOL_H
-#define THREADPOOL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//Size of job free list
-#define JOBFREELISTSIZE 100
-
-#define INFINITE_THREADS -1
-
-#define EMAXTHREADS (-8 & 1<<29)
-
-//Invalid Policy
-#define INVALID_POLICY (-9 & 1<<29)
-
-//Invalid JOB Id
-#define INVALID_JOB_ID (-2 & 1<<29)
-
-typedef enum duration {SHORT_TERM,PERSISTENT} Duration;
-
-typedef enum priority {LOW_PRIORITY,
-		       MED_PRIORITY,
-		       HIGH_PRIORITY} ThreadPriority;
-
-#define DEFAULT_PRIORITY MED_PRIORITY //default priority used by TPJobInit
-#define DEFAULT_MIN_THREADS 1	      //default minimum used by TPAttrInit
-#define DEFAULT_MAX_THREADS 10	      //default max used by TPAttrInit	
-#define DEFAULT_JOBS_PER_THREAD 10    //default jobs per thread used by TPAttrInit
-#define DEFAULT_STARVATION_TIME	500   //default starvation time used by TPAttrInit
-#define DEFAULT_IDLE_TIME 10 * 1000   //default idle time used by TPAttrInit
-#define DEFAULT_FREE_ROUTINE NULL     //default free routine used TPJobInit
-#define DEFAULT_MAX_JOBS_TOTAL 100    //default max jobs used TPAttrInit
-
-#define STATS 1 //always include stats because code change is minimal
-
-
-//Statistics
-#ifdef WIN32 // todo: check why STATSONLY fails during compilation
- #undef STATS
-#endif
-
-#ifdef STATS
- #define STATSONLY(x) x
-#else
- #define STATSONLY(x)
-#endif
-
-#ifdef _DEBUG
- #define DEBUG 1
-#endif
-
-//DEBUGGING
-#ifndef WIN32
- #ifdef DEBUG
-  #define DBGONLY(x) x
- #else
-  #define DBGONLY(x)
- #endif
-#endif
-
-#include "LinkedList.h"
-#include <sys/time.h>
-#include "FreeList.h"
-
-#include "ithread.h"
-#include <errno.h>
-#define EXPORT 
-typedef int PolicyType;
-#define DEFAULT_POLICY SCHED_OTHER
-#define DEFAULT_SCHED_PARAM 0 //default priority
-
-/****************************************************************************
- * Name: free_routine
- *
- *  Description:
- *     Function for freeing a thread argument
- *****************************************************************************/
-typedef void (*free_routine)(void *arg);
-typedef void (*free_thread_func)(void);
-
-/****************************************************************************
- * Name: ThreadPoolAttr
- *
- *  Description:
- *     Attributes for thread pool. Used to set and change parameters of
- *     thread pool
- *****************************************************************************/
-typedef struct THREADPOOLATTR
-{
-  int minThreads;     // minThreads, ThreadPool will always maintain at least
-                      // this many threads
-
-  int maxThreads;     // maxThreads, ThreadPool will never have more than this
-                      // number of threads
-
-  int maxIdleTime;    // maxIdleTime (in milliseconds)
-                      // this is the maximum time a thread will remain idle
-                      // before dying
-
-  int jobsPerThread;  // jobs per thread to maintain
-
-  int maxJobsTotal;   // maximum number of jobs that can be queued totally.
-
-  int starvationTime; // the time a low priority or med priority
-	              // job waits before getting bumped
-                      // up a priority (in milliseconds)
-
-  PolicyType schedPolicy; // scheduling policy to use
-
-} ThreadPoolAttr;
-
-/****************************************************************************
- * Name: ThreadPool
- *
- *  Description:
- *     Internal ThreadPool Job
- *****************************************************************************/
-typedef struct THREADPOOLJOB
-{
-  start_routine func; //function
-  void *arg;          //arg
-  free_routine free_func; //free function
-  struct timeval requestTime; //time of request
-  int priority;       //priority of request
-  int jobId;         //id 
-} ThreadPoolJob;
-
-/****************************************************************************
- * Name: ThreadPoolStats
- *
- *  Description:
- *     Structure to hold statistics
- *****************************************************************************/
-
-STATSONLY(
-
-typedef struct TPOOLSTATS
-{
-  double totalTimeHQ; //total time spent by all jobs in high priority Q
-  int totalJobsHQ;    //total jobs in HQ run so far
-  double avgWaitHQ;   //average wait in HQ
-  double totalTimeMQ; //total time spent by all jobs in med priority Q
-  int totalJobsMQ;    //total jobs in MQ run so far
-  double avgWaitMQ;   //average wait in MQ
-  double totalTimeLQ; //total time spent by all jobs in low priority Q
-  int totalJobsLQ;    //total jobs in LQ run so far
-  double avgWaitLQ;	//average wait in LQ
-  double totalWorkTime; //total time spent working for all threads
-  double totalIdleTime; //total time spent idle for all threads
-  int workerThreads; //number of current workerThreads
-  int idleThreads;   //number of current idle threads
-  int persistentThreads; //number of persistent threads
-  int totalThreads; //total number of current threads
-  int maxThreads; //max threads so far
-  int currentJobsHQ; // current jobs in Q
-  int currentJobsLQ; //current jobs in Q
-  int currentJobsMQ; //current jobs in Q
-}ThreadPoolStats;
-
-)
-
-
-/****************************************************************************
- * Name: ThreadPool
- *
- *  Description:
- *     A thread pool similar to the thread pool in the UPnP SDK.
- *     Allows jobs to be scheduled for running by threads in a 
- *     thread pool. The thread pool is initialized with a 
- *     minimum and maximum thread number as well as a 
- *	   max idle time
- *     and a jobs per thread ratio. If a worker thread waits the whole
- *     max idle time without receiving a job and the thread pool
- *     currently has more threads running than the minimum
- *     then the worker thread will exit. If when 
- *     scheduling a job the current job to thread ratio
- *     becomes greater than the set ratio and the thread pool currently has
- *     less than the maximum threads then a new thread will
- *     be created.
- *
- *****************************************************************************/
-
-typedef struct THREADPOOL
-{
-  ithread_mutex_t mutex; //mutex to protect job qs
-  ithread_cond_t condition; //condition variable to signal Q
-  ithread_cond_t start_and_shutdown; //condition variable for start 
-                                     //and stop     
-  int lastJobId; //ids for jobs 
-  int shutdown;   //whether or not we are shutting down
-  int totalThreads;       //total number of threads	
-  int busyThreads;        // number of threads that are currently executing jobs
-  int persistentThreads; //number of persistent threads
-  FreeList jobFreeList; //free list of jobs
-  LinkedList lowJobQ;    //low priority job Q
-  LinkedList medJobQ;    //med priority job Q
-  LinkedList highJobQ;   //high priority job Q
-  ThreadPoolJob *persistentJob; //persistent job
- 
-  ThreadPoolAttr attr; //thread pool attributes
- 
-  free_thread_func free_func; // user defined thread cleanup function
-
-  //statistics 
-  STATSONLY(ThreadPoolStats stats;)
- 
-} ThreadPool;
-
-
-
-/****************************************************************************
- * Function: ThreadPoolInit
- *
- *  Description:
- *      Initializes and starts ThreadPool. Must be called first.
- *      And only once for ThreadPool.
- *  Parameters:
- *      tp  - must be valid, non null, pointer to ThreadPool.
- *      attr - can be null
- *
- *       if not null then attr contains the following fields:
- *
- *      minWorkerThreads - minimum number of worker threads
- *                                 thread pool will never have less than this
- *                                  number of threads.
- *      maxWorkerThreads - maximum number of worker threads
- *                         thread pool will never have more than this
- *                         number of threads.
- *      maxIdleTime      - maximum time that a worker thread will spend
- *                         idle. If a worker is idle longer than this
- *                         time and there are more than the min
- *                         number of workers running, than the
- *                         worker thread exits.
- *      jobsPerThread    - ratio of jobs to thread to try and maintain
- *                         if a job is scheduled and the number of jobs per
- *                         thread is greater than this number,and  
- *                         if less than the maximum number of
- *                         workers are running then a new thread is 
- *                         started to help out with efficiency.
- *      schedPolicy      - scheduling policy to try and set (OS dependent)
- *  Returns:
- *      0 on success, nonzero on failure.
- *      EAGAIN if not enough system resources to create minimum threads.
- *      INVALID_POLICY if schedPolicy can't be set
- *      EMAXTHREADS if minimum threads is greater than maximum threads
- *****************************************************************************/
-int ThreadPoolInit(ThreadPool *tp,
-  ThreadPoolAttr *attr);
-
-/****************************************************************************
- * Function: ThreadPoolAddPersistent
- *
- *  Description:
- *      Adds a persistent job to the thread pool.
- *      Job will be run as soon as possible.
- *      Call will block until job is scheduled.
- *  Parameters:
- *      tp - valid thread pool pointer
- *      ThreadPoolJob - valid thread pool job with the following fields:
- *
- *        func - ThreadFunction to run
- *        arg - argument to function.
- *        priority - priority of job.
- * 
- *  Returns:
- *      0 on success, nonzero on failure
- *      EOUTOFMEM not enough memory to add job.
- *      EMAXTHREADS not enough threads to add persistent job.
- *****************************************************************************/
-int ThreadPoolAddPersistent (ThreadPool*tp,
-  ThreadPoolJob *job,
-  int *jobId);
-
-/****************************************************************************
- * Function: ThreadPoolGetAttr
- *
- *  Description:
- *      Gets the current set of attributes
- *      associated with the thread pool.
- *  Parameters:
- *      tp - valid thread pool pointer
- *      out - non null pointer to store attributes
- *  Returns:
- *      0 on success, nonzero on failure
- *      Always returns 0.
- *****************************************************************************/
-int ThreadPoolGetAttr(ThreadPool *tp,
-  ThreadPoolAttr *out);
-/****************************************************************************
- * Function: ThreadPoolSetAttr
- *
- *  Description:
- *      Sets the attributes for the thread pool.
- *      Only affects future calculations. 
- *  Parameters:
- *      tp - valid thread pool pointer
- *      attr - pointer to attributes, null sets attributes to default.
- *  Returns:
- *      0 on success, nonzero on failure
- *      Returns INVALID_POLICY if policy can not be set.
- *****************************************************************************/
-int ThreadPoolSetAttr(ThreadPool *tp,
-  ThreadPoolAttr *attr);
-
-/****************************************************************************
- * Function: ThreadPoolAdd
- *
- *  Description:
- *      Adds a job to the thread pool.
- *      Job will be run as soon as possible.
- *  Parameters:
- *      tp - valid thread pool pointer
- *      func - ThreadFunction to run
- *      arg - argument to function.
- *      priority - priority of job.
- *      poolid - id of job
- *      free_function - function to use when freeing argument 
- *  Returns:
- *      0 on success, nonzero on failure
- *      EOUTOFMEM if not enough memory to add job.
- *****************************************************************************/
-int ThreadPoolAdd (ThreadPool*tp,
-  ThreadPoolJob *job,
-  int *jobId);
-
-/****************************************************************************
- * Function: ThreadPoolRemove
- *
- *  Description:
- *      Removes a job from the thread pool.
- *      Can only remove jobs which are not
- *      currently running.
- *  Parameters:
- *      tp - valid thread pool pointer
- *      jobid - id of job
- *      out - space for removed job.
- *  Returns:
- *      0 on success, nonzero on failure.
- *      INVALID_JOB_ID if job not found. 
- *****************************************************************************/
-int ThreadPoolRemove(ThreadPool *tp,
-  int jobId, ThreadPoolJob *out);
-
-
-
-/****************************************************************************
- * Function: ThreadPoolShutdown
- *
- *  Description:
- *      Shuts the thread pool down.
- *      Waits for all threads to finish. 
- *      May block indefinitely if jobs do not
- *      exit.
- *  Parameters:
- *      tp - must be valid tp     
- *  Returns:
- *      0 on success, nonzero on failure
- *      Always returns 0.
- *****************************************************************************/
-int ThreadPoolShutdown(ThreadPool *tp);
-
-
-/****************************************************************************
- * Function: TPJobInit
- *
- *  Description:
- *      Initializes thread pool job.
- *      Sets the priority to default defined in ThreadPool.h.
- *      Sets the free_routine to default defined in ThreadPool.h
- *  Parameters:
- *      ThreadPoolJob *job - must be valid thread pool attributes.    
- *      start_routine func - function to run, must be valid
- *      void * arg - argument to pass to function.
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-int TPJobInit(ThreadPoolJob *job, start_routine func, void *arg);
-
-/****************************************************************************
- * Function: TPJobSetPriority
- *
- *  Description:
- *      Sets the max threads for the thread pool attributes.
- *  Parameters:
- *      attr - must be valid thread pool attributes. 
- *      maxThreads - value to set
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority);
-
-/****************************************************************************
- * Function: TPJobSetFreeFunction
- *
- *  Description:
- *      Sets the max threads for the thread pool attributes.
- *  Parameters:
- *      attr - must be valid thread pool attributes. 
- *      maxThreads - value to set
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-int TPJobSetFreeFunction(ThreadPoolJob *job, free_routine func);
-
-/****************************************************************************
- * Function: TPAttrInit
- *
- *  Description:
- *      Initializes thread pool attributes.
- *      Sets values to defaults defined in ThreadPool.h.
- *  Parameters:
- *      attr - must be valid thread pool attributes.    
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-int TPAttrInit(ThreadPoolAttr *attr);
-
-/****************************************************************************
- * Function: TPAttrSetMaxThreads
- *
- *  Description:
- *      Sets the max threads for the thread pool attributes.
- *  Parameters:
- *      attr - must be valid thread pool attributes. 
- *      maxThreads - value to set
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-int TPAttrSetMaxThreads(ThreadPoolAttr *attr, int maxThreads);
-
-/****************************************************************************
- * Function: TPAttrSetMinThreads
- *
- *  Description:
- *      Sets the min threads for the thread pool attributes.
- *  Parameters:
- *      attr - must be valid thread pool attributes. 
- *      minThreads - value to set
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads);
-
-/****************************************************************************
- * Function: TPAttrSetIdleTime
- *
- *  Description:
- *      Sets the idle time for the thread pool attributes.
- *  Parameters:
- *      attr - must be valid thread pool attributes.    
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-int TPAttrSetIdleTime(ThreadPoolAttr *attr, int idleTime);
-
-/****************************************************************************
- * Function: TPAttrSetJobsPerThread
- *
- *  Description:
- *      Sets the jobs per thread ratio
- *  Parameters:
- *      attr - must be valid thread pool attributes.
- *      jobsPerThread - number of jobs per thread to maintain
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-int TPAttrSetJobsPerThread(ThreadPoolAttr *attr, int jobsPerThread);
-
-/****************************************************************************
- * Function: TPAttrSetStarvationTime
- *
- *  Description:
- *      Sets the starvation time for the thread pool attributes.
- *  Parameters:
- *      attr - must be valid thread pool attributes.    
- *      int starvationTime - milliseconds
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-int TPAttrSetStarvationTime(ThreadPoolAttr *attr, int starvationTime);
-
-/****************************************************************************
- * Function: TPAttrSetSchedPolicy
- *
- *  Description:
- *      Sets the scheduling policy for the thread pool attributes.
- *  Parameters:
- *      attr - must be valid thread pool attributes.    
- *      PolicyType schedPolicy - must be a valid policy type.
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-int TPAttrSetSchedPolicy(ThreadPoolAttr *attr, PolicyType schedPolicy);
-
-
-/****************************************************************************
- * Function: TPAttrSetMaxJobsTotal
- *
- *  Description:
- *      Sets the maximum number jobs that can be qeued totally.
- *  Parameters:
- *      attr - must be valid thread pool attributes.
- *      maxJobsTotal - maximum number of jobs
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-int TPAttrSetMaxJobsTotal(ThreadPoolAttr *attr, int maxJobsTotal);
-
-/****************************************************************************
- * Function: ThreadPoolGetStats
- *
- *  Description:
- *      Returns various statistics about the
- *      thread pool.
- *      Only valid if STATS has been defined.
- *  Parameters:
- *      ThreadPool *tp - valid initialized threadpool    
- *      ThreadPoolStats *stats - valid stats, out parameter
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-STATSONLY( EXPORT int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats););
-
-STATSONLY(EXPORT void ThreadPoolPrintStats(ThreadPoolStats *stats););
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //ThreadPool
diff --git a/tombupnp/threadutil/inc/TimerThread.h b/tombupnp/threadutil/inc/TimerThread.h
deleted file mode 100644
index 1659de8..0000000
--- a/tombupnp/threadutil/inc/TimerThread.h
+++ /dev/null
@@ -1,191 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef TIMERTHREAD_H
-#define TIMERTHREAD_H
-
-#include "ithread.h"
-#include "LinkedList.h"
-#include "FreeList.h"
-#include "ThreadPool.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define INVALID_EVENT_ID (-10 & 1<<29)
-
-//Timeout Types
-//absolute means in seconds from Jan 1, 1970
-//relative means in seconds from current time
-typedef enum timeoutType {ABS_SEC,REL_SEC} TimeoutType;
-
-
-/****************************************************************************
- * Name: TimerThread
- * 
- *   Description:
- *     A timer thread similar to the one in the Upnp SDK that allows
- *     the scheduling of a job to run at a specified time in the future
- *     Because the timer thread uses the thread pool there is no 
- *     gurantee of timing, only approximate timing.
- *     Uses ThreadPool, Mutex, Condition, Thread
- *    
- * 
- *****************************************************************************/
-typedef struct TIMERTHREAD
-{
-  ithread_mutex_t mutex; //mutex to protect eventQ
-  ithread_cond_t condition; //condition variable
-  int lastEventId;	//last event id
-  LinkedList eventQ; //event q
-  int shutdown;      //whether or not we are shutdown  
-  FreeList freeEvents; //FreeList for events
-  ThreadPool *tp;	 //ThreadPool to use
-} TimerThread;
-
-
-/****************************************************************************
- * Name: TimerEvent
- * 
- *   Description:
- *     
- *     Struct to contain information for a timer event.
- *     Internal to the TimerThread
- *   
- *****************************************************************************/
-typedef struct TIMEREVENT
-{
-  ThreadPoolJob job;
-  time_t eventTime; //absolute time for event in seconds since Jan 1, 1970
-  Duration persistent;          //long term or short term job
-  int id;                //id of job
-} TimerEvent;
-
-
-
-
-/************************************************************************
- * Function: TimerThreadInit
- * 
- *  Description:
- *     Initializes and starts timer thread.
- *
- *  Parameters:
- *             timer - valid timer thread pointer.
- *             tp  - valid thread pool to use. Must be
- *                   started. Must be valid for lifetime
- *                   of timer.  Timer must be shutdown
- *                   BEFORE thread pool.
- *  Return:
- *            0 on success, nonzero on failure
- *            Returns error from ThreadPoolAddPersistent on failure.
- *
- ************************************************************************/
-int TimerThreadInit(TimerThread *timer,
-		    ThreadPool *tp);
-
-
-/************************************************************************
- * Function: TimerThreadSchedule
- * 
- *  Description:
- *     Schedules an event to run at a specified time.
- *
- *  Parameters:
- *             timer - valid timer thread pointer.
- *             time_t - time of event.
- *                      either in absolute seconds,
- *                      or relative seconds in the future.
- *             timeoutType - either ABS_SEC, or REL_SEC.
- *                           if REL_SEC, then the event
- *                           will be scheduled at the
- *                           current time + REL_SEC.
- *             job-> valid Thread pool job with following fields
- *             func - function to schedule
- *             arg - argument to function
- *             priority - priority of job.
- *         
- *             id - id of timer event. (out, can be null)
- *  Return:
- *            0 on success, nonzero on failure
- *            EOUTOFMEM if not enough memory to schedule job.
- *
- ************************************************************************/
-int TimerThreadSchedule(TimerThread* timer,
-			time_t time, 
-			TimeoutType type,
-			ThreadPoolJob *job,
-			Duration duration,
-			int *id);
-
-/************************************************************************
- * Function: TimerThreadRemove
- * 
- *  Description:
- *     Removes an event from the timer Q.
- *     Events can only be removed 
- *     before they have been placed in the
- *     thread pool.
- *
- *  Parameters:
- *             timer - valid timer thread pointer.
- *             id - id of event to remove.
- *             ThreadPoolJob *out - space for thread pool job.
- *  Return:
- *            0 on success, 
- *            INVALID_EVENT_ID on failure
- *			 
- ************************************************************************/
-int TimerThreadRemove(TimerThread *timer,
-			   int id,
-			   ThreadPoolJob *out);
-
-/************************************************************************
- * Function: TimerThreadShutdown
- * 
- *  Description:
- *    Shutdown the timer thread
- *    Events scheduled in the future will NOT be run.
- *    Timer thread should be shutdown BEFORE it's associated
- *    thread pool.
- *  Returns:
- *    returns 0 if succesfull,
- *            nonzero otherwise.
- *            Always returns 0.
- ***********************************************************************/   
-int TimerThreadShutdown(TimerThread *timer);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //TIMER_THREAD_H
diff --git a/tombupnp/threadutil/inc/iasnprintf.h b/tombupnp/threadutil/inc/iasnprintf.h
deleted file mode 100644
index 75c7b15..0000000
--- a/tombupnp/threadutil/inc/iasnprintf.h
+++ /dev/null
@@ -1,66 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include <stdarg.h>
-
-#define EXPORT
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Allocates enough memory for the
- * Formatted string, up to max
- * specified.
- * With max set to -1, allocates
- * as much size as needed.
- * Memory must be freed using free.
- */
-
-EXPORT int iasnprintf(char **ret,
-	       int incr,
-	       int max,
-	       const char * fmt, ...)
-#ifndef SOLARIS
- #if (__GNUC__ >= 3)
-	__attribute__((format (__printf__, 4, 5)));
- #else
- ;
- #endif
- EXPORT void iasnprintfFree(char *);
-#else
-;
-#endif
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/tombupnp/threadutil/inc/ithread.h b/tombupnp/threadutil/inc/ithread.h
deleted file mode 100644
index 01b3f32..0000000
--- a/tombupnp/threadutil/inc/ithread.h
+++ /dev/null
@@ -1,556 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef ITHREADH
-#define ITHREADH
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#ifdef DEBUG
-#define DEBUG_ONLY(x) x
-#else
-#define DEBUG_ONLY(x)
-#endif
-
-#include <pthread.h>
-#ifndef WIN32
- #include <unistd.h>
-#endif
-
-#if defined(__FreeBSD__) || defined(__NetBSD__)
-#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
-#endif    
-
-#define ITHREAD_MUTEX_FAST_NP PTHREAD_MUTEX_FAST_NP
-#define ITHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE_NP
-#define ITHREAD_MUTEX_ERRORCHECK_NP PTHREAD_MUTEX_ERRORCHECK_NP
-#define ITHREAD_CANCELED PTHREAD_CANCELED
-  
-  
-  /***************************************************************************
-   * Name: ithread_t
-   *
-   *  Description:
-   *      Thread handle.
-   *      typedef to pthread_t.
-   *      Internal Use Only.
-   ***************************************************************************/
-  typedef pthread_t ithread_t; 
-  
-  /****************************************************************************
-   * Name: ithread_attr_t
-   *
-   *  Description:
-   *      Thread attribute.
-   *      typedef to pthread_attr_t
-   *      Internal Use Only
-   ***************************************************************************/
-  typedef pthread_attr_t ithread_attr_t;	
-
-
-  /****************************************************************************
-   * Name: start_routine
-   *
-   *  Description:
-   *      Thread start routine 
-   *      Internal Use Only.
-   ***************************************************************************/
-  typedef void * (*start_routine) (void *arg);
-
-  
-  /****************************************************************************
-   * Name: ithread_cond_t
-   *
-   *  Description:
-   *      condition variable.
-   *      typedef to pthread_cond_t
-   *      Internal Use Only.
-   ***************************************************************************/
-  typedef pthread_cond_t ithread_cond_t;
-
-
-  /****************************************************************************
-   * Name: ithread_mutexattr_t
-   *
-   *  Description:
-   *      Mutex attribute.
-   *      typedef to pthread_mutexattr_t
-   *      Internal Use Only
-   ***************************************************************************/
-  typedef pthread_mutexattr_t ithread_mutexattr_t;	
-
-
-  /****************************************************************************
-   * Name: ithread_mutex_t
-   *
-   *  Description:
-   *      Mutex.
-   *      typedef to pthread_mutex_t
-   *      Internal Use Only.
-   ***************************************************************************/
-  typedef pthread_mutex_t ithread_mutex_t;
-
-
-  /****************************************************************************
-   * Name: ithread_condattr_t
-   *
-   *  Description:
-   *      Condition attribute.
-   *      typedef to pthread_condattr_t
-   *      NOT USED
-   *      Internal Use Only
-   ***************************************************************************/
-  typedef pthread_condattr_t ithread_condattr_t;	
-
-  /****************************************************************************
-   * Function: ithread_mutexattr_init
-   *
-   *  Description:
-   *      Initializes a mutex attribute variable.
-   *      Used to set the type of the mutex.
-   *  Parameters:
-   *      ithread_mutexattr_init * attr (must be valid non NULL pointer to 
-   *                                     pthread_mutexattr_t)
-   *  Returns:
-   *      0 on success, Nonzero on failure.
-   *      Always returns 0.
-   *      See man page for pthread_mutexattr_init
-   ***************************************************************************/
-  
-#define ithread_mutexattr_init pthread_mutexattr_init
-  
-  /****************************************************************************
-   * Function: ithread_mutexattr_destroy
-   *
-   *  Description:
-   *      Releases any resources held by the mutex attribute.
-   *      Currently there are no resources associated with the attribute
-   *  Parameters:
-   *      ithread_mutexattr_t * attr (must be valid non NULL pointer to 
-   *                                  pthread_mutexattr_t)
-   *  Returns:
-   *      0 on success, Nonzero on failure.
-   *      Always returns 0.
-   *      See man page for pthread_mutexattr_destroy
-   ***************************************************************************/
-#define ithread_mutexattr_destroy pthread_mutexattr_destroy
-  
-  
-/****************************************************************************
- * Function: ithread_mutexattr_setkind_np
- *
- *  Description:
- *      Sets the mutex type in the attribute.
- *      Valid types are: ITHREAD_MUTEX_FAST_NP 
- *                       ITHREAD_MUTEX_RECURSIVE_NP 
- *                       ITHREAD_MUTEX_ERRORCHECK_NP
- *
- *  Parameters:
- *      ithread_mutexattr_t * mutex (must be valid non NULL pointer to 
- *                                   ithread_mutexattr_t)
- *      int kind (one of ITHREAD_MUTEX_FAST_NP or ITHREAD_MUTEX_RECURSIVE_NP
- *                or ITHREAD_MUTEX_ERRORCHECK_NP)
- *  Returns:
- *      0 on success. Nonzero on failure.
- *      Returns EINVAL if the kind is not supported.
- *      See man page for pthread_mutexattr_setkind_np
- *****************************************************************************/
-#define ithread_mutexattr_setkind_np pthread_mutexattr_setkind_np
-
-
-/****************************************************************************
- * Function: ithread_mutexattr_getkind_np
- *
- *  Description:
- *      Gets the mutex type in the attribute.
- *      Valid types are: ITHREAD_MUTEX_FAST_NP 
- *                       ITHREAD_MUTEX_RECURSIVE_NP 
- *                       ITHREAD_MUTEX_ERRORCHECK_NP
- *
- *  Parameters:
- *      ithread_mutexattr_t * mutex (must be valid non NULL pointer to 
- *                                   pthread_mutexattr_t)
- *      int *kind (one of ITHREAD_MUTEX_FAST_NP or ITHREAD_MUTEX_RECURSIVE_NP
- *                or ITHREAD_MUTEX_ERRORCHECK_NP)
- *  Returns:
- *      0 on success. Nonzero on failure.
- *      Always returns 0.
- *      See man page for pthread_mutexattr_getkind_np
- *****************************************************************************/
-#define ithread_mutexattr_getkind_np pthread_mutexattr_getkind_np
-
-  
-/****************************************************************************
- * Function: ithread_mutex_init
- *
- *  Description:
- *      Initializes mutex.
- *      Must be called before use.
- *      
- *  Parameters:
- *      ithread_mutex_t * mutex (must be valid non NULL pointer to pthread_mutex_t)
- *      const ithread_mutexattr_t * mutex_attr 
- *  Returns:
- *      0 on success, Nonzero on failure.
- *      Always returns 0.
- *      See man page for pthread_mutex_init
- *****************************************************************************/
-#define ithread_mutex_init pthread_mutex_init
-  
-/****************************************************************************
- * Function: ithread_mutex_lock
- *
- *  Description:
- *      Locks mutex.
- *  Parameters:
- *      ithread_mutex_t * mutex (must be valid non NULL pointer to pthread_mutex_t)
- *      mutex must be initialized.
- *      
- *  Returns:
- *      0 on success, Nonzero on failure.
- *      Always returns 0.
- *      See man page for pthread_mutex_lock
- *****************************************************************************/
-#define ithread_mutex_lock pthread_mutex_lock
-  
-
-/****************************************************************************
- * Function: ithread_mutex_unlock
- *
- *  Description:
- *      Unlocks mutex.
- *
- *  Parameters:
- *      ithread_mutex_t * mutex (must be valid non NULL pointer to pthread_mutex_t)
- *      mutex must be initialized.
- *      
- *  Returns:
- *      0 on success, Nonzero on failure.
- *      Always returns 0.
- *      See man page for pthread_mutex_unlock
- *****************************************************************************/
-#define ithread_mutex_unlock pthread_mutex_unlock
-
-
-/****************************************************************************
- * Function: ithread_mutex_destroy
- *
- *  Description:
- *      Releases any resources held by the mutex. 
- *		Mutex can no longer be used after this call.
- *		Mutex is only destroyed when there are no longer any threads waiting on it. 
- *		Mutex cannot be destroyed if it is locked.
- *  Parameters:
- *      ithread_mutex_t * mutex (must be valid non NULL pointer to pthread_mutex_t)
- *      mutex must be initialized.
- *  Returns:
- *      0 on success. Nonzero on failure.
- *      Always returns 0.
- *      See man page for pthread_mutex_destroy
- *****************************************************************************/
-#define ithread_mutex_destroy pthread_mutex_destroy
-
-  
-/****************************************************************************
- * Function: ithread_cond_init
- *
- *  Description:
- *      Initializes condition variable.
- *      Must be called before use.
- *  Parameters:
- *      ithread_cond_t * cond (must be valid non NULL pointer to pthread_cond_t)
- *      const ithread_condattr_t * cond_attr (ignored)
- *  Returns:
- *      0 on success, Nonzero on failure.
- *      See man page for pthread_cond_init
- *****************************************************************************/
-#define ithread_cond_init pthread_cond_init
-
-
-
-/****************************************************************************
- * Function: ithread_cond_signal
- *
- *  Description:
- *      Wakes up exactly one thread waiting on condition.
- *      Associated mutex MUST be locked by thread before entering this call.
- *  Parameters:
- *      ithread_cond_t * cond (must be valid non NULL pointer to 
- *      ithread_cond_t)
- *      cond must be initialized
- *  Returns:
- *      0 on success, Nonzero on failure.
- *      See man page for pthread_cond_signal
- *****************************************************************************/
-#define ithread_cond_signal pthread_cond_signal
-
-
-/****************************************************************************
- * Function: ithread_cond_broadcast
- *
- *  Description:
- *      Wakes up all threads waiting on condition.
- *      Associated mutex MUST be locked by thread before entering this call.
- *  Parameters:
- *      ithread_cond_t * cond (must be valid non NULL pointer to 
- *      ithread_cond_t)
- *      cond must be initialized
- *  Returns:
- *      0 on success, Nonzero on failure.
- *      See man page for pthread_cond_broadcast
- *****************************************************************************/
-#define ithread_cond_broadcast pthread_cond_broadcast
-  
-
-/****************************************************************************
- * Function: ithread_cond_wait
- *
- *  Description:
- *      Atomically releases mutex and waits on condition.
- *      Associated mutex MUST be locked by thread before entering this call.
- *      Mutex is reacquired when call returns.
- *  Parameters:
- *      ithread_cond_t * cond (must be valid non NULL pointer to 
- *      ithread_cond_t)
- *      cond must be initialized
- *      ithread_mutex_t *mutex (must be valid non NULL pointer to 
- *      ithread_mutex_t)
- *      Mutex must be locked.
- *  Returns:
- *      0 on success, Nonzero on failure.
- *      See man page for pthread_cond_wait
- *****************************************************************************/
-#define ithread_cond_wait pthread_cond_wait
-  
-
-  /****************************************************************************
-   * Function: pthread_cond_timedwait
-   *
-   *  Description:      
-   *      Atomically releases the associated mutex and waits on the condition. 
-   *		If the condition is not signaled in the specified time 
-   *              than the 
-   *		call times out and returns.
-   *		Associated mutex MUST be locked by thread before entering 
-   *              this call.
-   *      Mutex is reacquired when call returns.
-   *  Parameters:
-   *      ithread_cond_t * cond (must be valid non NULL pointer to 
-   *      ithread_cond_t)
-   *      cond must be initialized
-   *      ithread_mutex_t *mutex (must be valid non NULL pointer to 
-   *      ithread_mutex_t)
-   *      Mutex must be locked.
-   *      const struct timespec *abstime (absolute time, measured 
-   *      from Jan 1, 1970)
-   *  Returns:
-   *      0 on success. ETIMEDOUT on timeout. Nonzero on failure.
-   *      See man page for pthread_cond_timedwait
-   ***************************************************************************/
- 
-#define ithread_cond_timedwait pthread_cond_timedwait
-  
-
-  /****************************************************************************
-   * Function: ithread_cond_destroy
-   *
-   *  Description:
-   *      Releases any resources held by the condition variable. 
-   *		Condition variable can no longer be used after this call.	
-   *  Parameters:
-   *      ithread_cond_t * cond (must be valid non NULL pointer to 
-   *      ithread_cond_t)
-   *      cond must be initialized.
-   *  Returns:
-   *      0 on success. Nonzero on failure.
-   *      See man page for pthread_cond_destroy
-   ***************************************************************************/
-#define ithread_cond_destroy pthread_cond_destroy
-
-
-  /****************************************************************************
-   * Function: ithread_create
-   *
-   *  Description:
-   *		Creates a thread with the given start routine
-   *      and argument.
-   *  Parameters:
-   *      ithread_t * thread (must be valid non NULL pointer to pthread_t)
-   *      ithread_attr_t *attr, IGNORED
-   *      void * (start_routine) (void *arg) (start routine)
-   *      void * arg - argument.
-   *  Returns:
-   *      0 on success. Nonzero on failure.
-   *	    Returns EAGAIN if a new thread can not be created.
-   *      Returns EINVAL if there is a problem with the arguments.
-   *      See man page fore pthread_create
-   ***************************************************************************/
-#define ithread_create pthread_create
-
-
-  /****************************************************************************
-   * Function: ithread_cancel
-   *
-   *  Description:
-   *		Cancels a thread.
-   *  Parameters:
-   *      ithread_t * thread (must be valid non NULL pointer to ithread_t)
-   *  Returns:
-   *      0 on success. Nonzero on failure.
-   *      See man page for pthread_cancel
-   ***************************************************************************/
-#define ithread_cancel pthread_cancel
-  
-
-  /****************************************************************************
-   * Function: ithread_exit
-   *
-   *  Description:
-   *		Returns a return code from a thread.
-   *      Implicitly called when the start routine returns.
-   *  Parameters:
-   *      void  * return_code return code to return
-   *      See man page for pthread_exit
-   ***************************************************************************/
-#define ithread_exit pthread_exit
-
-/****************************************************************************
-   * Function: ithread_get_current_thread_id
-   *
-   *  Description:
-   *		Returns the handle of the currently running thread.
-   *  Returns:
-   *		The handle of the currently running thread.
-   *              See man page for pthread_self
-   ***************************************************************************/
-#define ithread_get_current_thread_id pthread_self
-
-
-  /****************************************************************************
-   * Function: ithread_self
-   *
-   *  Description:
-   *		Returns the handle of the currently running thread.
-   *  Returns:
-   *		The handle of the currently running thread.
-   *              See man page for pthread_self
-   ***************************************************************************/
-#define ithread_self pthread_self
-
-  /****************************************************************************
-   * Function: ithread_detach
-   *
-   *  Description:
-   *		Makes a thread's resources reclaimed immediately 
-   *            after it finishes
-   *            execution.  
-   *  Returns:
-   *		0 on success, Nonzero on failure.
-   *      See man page for pthread_detach
-   ***************************************************************************/
-#define ithread_detach pthread_detach  
-
-  /****************************************************************************
-   * Function: ithread_join
-   *
-   *  Description:
-   *		Suspends the currently running thread until the 
-   * specified thread
-   *      has finished. 
-   *      Returns the return code of the thread, or ITHREAD_CANCELED 
-   *      if the thread has been canceled.
-   *  Parameters:
-   *      ithread_t *thread (valid non null thread identifier)
-   *      void ** return (space for return code) 
-   *  Returns:
-   *		0 on success, Nonzero on failure.
-   *     See man page for pthread_join
-   ***************************************************************************/
-#define ithread_join pthread_join
-  
-
-
-/****************************************************************************
- * Function: isleep
- *
- *  Description:
- *		Suspends the currently running thread for the specified number 
- *      of seconds
- *      Always returns 0.
- *  Parameters:
- *      unsigned int seconds - number of seconds to sleep.
- *  Returns:
- *		0 on success, Nonzero on failure.
- *              See man page for sleep (man 3 sleep)
- *****************************************************************************/
-#define isleep sleep
-
-/****************************************************************************
- * Function: isleep
- *
- *  Description:
- *		Suspends the currently running thread for the specified number 
- *      of milliseconds
- *      Always returns 0.
- *  Parameters:
- *      unsigned int milliseconds - number of milliseconds to sleep.
- *  Returns:
- *		0 on success, Nonzero on failure.
- *              See man page for sleep (man 3 sleep)
- *****************************************************************************/
-#define imillisleep(x) usleep(1000*x)
-
-#ifdef WIN32
- #ifndef UPNP_STATIC_LIB
-  #ifdef LIBUPNP_EXPORTS
-   // set up declspec for dll export to make functions visible to library users
-   #define EXPORT_SPEC __declspec(dllexport)
-  #else
-   #define EXPORT_SPEC __declspec(dllimport)
-  #endif
- #else
-  #define EXPORT_SPEC
- #endif
-#else
- #define EXPORT_SPEC
-#endif
-
-
-//NK: Added for satisfying the gcc compiler  
-EXPORT_SPEC int pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //ITHREADH
diff --git a/tombupnp/threadutil/src/FreeList.c b/tombupnp/threadutil/src/FreeList.c
deleted file mode 100644
index 80c3ac9..0000000
--- a/tombupnp/threadutil/src/FreeList.c
+++ /dev/null
@@ -1,177 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include "FreeList.h"
-
-#include <assert.h>
-#include <stdlib.h>
-
-/****************************************************************************
- * Function: FreeListInit
- *
- *  Description:
- *      Initializes Free List. Must be called first.
- *      And only once for FreeList.
- *  Parameters:
- *      free_list  - must be valid, non null, pointer to a linked list.
- *      size_t -     size of elements to store in free list
- *      maxFreeListSize - max size that the free list can grow to
- *                        before returning memory to O.S.
- *  Returns:
- *      0 on success. Nonzero on failure.
- *      Always returns 0.
- *****************************************************************************/
-int
-FreeListInit( FreeList * free_list,
-              size_t elementSize,
-              int maxFreeListLength )
-{
-    assert( free_list != NULL );
-
-    if( free_list == NULL )
-        return EINVAL;
-
-    free_list->element_size = elementSize;
-    free_list->maxFreeListLength = maxFreeListLength;
-    free_list->head = NULL;
-    free_list->freeListLength = 0;
-    return 0;
-}
-
-/****************************************************************************
- * Function: FreeListAlloc
- *
- *  Description:
- *      Allocates chunk of set size.
- *      If a free item is available in the list, returnes the stored item.
- *      Otherwise calls the O.S. to allocate memory.
- *  Parameters:
- *      free_list  - must be valid, non null, pointer to a linked list.
- *  Returns:
- *      Non NULL on success. NULL on failure.
- *****************************************************************************/
-void *
-FreeListAlloc( FreeList * free_list )
-{
-    FreeListNode *ret = NULL;
-
-    assert( free_list != NULL );
-
-    if( free_list == NULL )
-        return NULL;
-
-    if( free_list->head ) {
-        ret = free_list->head;
-        free_list->head = free_list->head->next;
-        free_list->freeListLength--;
-    } else {
-        ret = malloc( free_list->element_size );
-    }
-
-    return ret;
-}
-
-/****************************************************************************
- * Function: FreeListFree
- *
- *  Description:
- *      Returns an item to the Free List.
- *      If the free list is smaller than the max size than
- *      adds the item to the free list.
- *      Otherwise returns the item to the O.S.
- *  Parameters:
- *      free_list  - must be valid, non null, pointer to a free list.
- *      element - must be a pointer allocated by FreeListAlloc
- *  Returns:
- *      0 on success. Nonzero on failure.
- *      Always returns 0.
- *****************************************************************************/
-int
-FreeListFree( FreeList * free_list,
-              void *element )
-{
-
-    FreeListNode *temp = NULL;
-
-    assert( free_list != NULL );
-
-    if( free_list == NULL )
-        return EINVAL;
-
-    if( ( element != NULL ) &&
-        ( ( free_list->freeListLength + 1 ) <
-          free_list->maxFreeListLength ) ) {
-        free_list->freeListLength++;
-        temp = ( FreeListNode * ) element;
-        temp->next = free_list->head;
-        free_list->head = temp;
-
-    } else {
-
-        free( element );
-    }
-
-    return 0;
-}
-
-/****************************************************************************
- * Function: FreeListDestroy
- *
- *  Description:
- *      Releases the resources stored with the free list.
- *  Parameters:
- *      free_list  - must be valid, non null, pointer to a linked list.
- *  Returns:
- *      0 on success. Nonzero on failure.
- *      Always returns 0.
- *****************************************************************************/
-int
-FreeListDestroy( FreeList * free_list )
-{
-    FreeListNode *temp = NULL;
-    int i = 0;
-
-    assert( free_list != NULL );
-
-    if( free_list == NULL )
-        return EINVAL;
-
-    while( free_list->head ) {
-        i++;
-        temp = free_list->head->next;
-        free( free_list->head );
-        free_list->head = temp;
-    }
-
-    free_list->freeListLength = 0;
-
-    return 0;
-}
diff --git a/tombupnp/threadutil/src/LinkedList.c b/tombupnp/threadutil/src/LinkedList.c
deleted file mode 100644
index 8f6a918..0000000
--- a/tombupnp/threadutil/src/LinkedList.c
+++ /dev/null
@@ -1,529 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include "LinkedList.h"
-#include <stdlib.h>
-#include <assert.h>
-
-static int
-freeListNode( ListNode * node,
-              LinkedList * list )
-{
-    assert( list != NULL );
-
-    return FreeListFree( &list->freeNodeList, node );
-}
-
-/****************************************************************************
- * Function: CreateListNode
- *
- *  Description:
- *      Creates a list node. Dynamically.
- *      
- *  Parameters:
- *      void * item - the item to store
- *  Returns:
- *      The new node, NULL on failure.
- *****************************************************************************/
-static ListNode *
-CreateListNode( void *item,
-                LinkedList * list )
-{
-
-    ListNode *temp = NULL;
-
-    assert( list != NULL );
-
-    temp = ( ListNode * ) FreeListAlloc( &list->freeNodeList );
-    if( temp ) {
-        temp->prev = NULL;
-        temp->next = NULL;
-        temp->item = item;
-    }
-    return temp;
-}
-
-/****************************************************************************
- * Function: ListInit
- *
- *  Description:
- *      Initializes LinkedList. Must be called first.
- *      And only once for List.
- *  Parameters:
- *      list  - must be valid, non null, pointer to a linked list.
- *      cmp_func - function used to compare items. (May be NULL)
- *      free_func - function used to free items. (May be NULL)
- *  Returns:
- *      0 on success, EOUTOFMEM on failure.
- *****************************************************************************/
-int
-ListInit( LinkedList * list,
-          cmp_routine cmp_func,
-          free_function free_func )
-{
-
-    int retCode = 0;
-
-    assert( list != NULL );
-
-    if( list == NULL )
-        return EINVAL;
-
-    list->size = 0;
-    list->cmp_func = cmp_func;
-    list->free_func = free_func;
-
-    retCode =
-        FreeListInit( &list->freeNodeList, sizeof( ListNode ),
-                      FREELISTSIZE );
-
-    assert( retCode == 0 );
-
-    list->head.item = NULL;
-    list->head.next = &list->tail;
-    list->head.prev = NULL;
-
-    list->tail.item = NULL;
-    list->tail.prev = &list->head;
-    list->tail.next = NULL;
-
-    return 0;
-}
-
-/****************************************************************************
- * Function: ListAddHead
- *
- *  Description:
- *      Adds a node to the head of the list.
- *      Node gets immediately after list.head.
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *      void * item - item to be added
- *  Returns:
- *      The pointer to the ListNode on success, NULL on failure.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode *
-ListAddHead( LinkedList * list,
-             void *item )
-{
-    assert( list != NULL );
-
-    if( list == NULL )
-        return NULL;
-
-    return ListAddAfter( list, item, &list->head );
-}
-
-/****************************************************************************
- * Function: ListAddTail
- *
- *  Description:
- *      Adds a node to the tail of the list.
- *      Node gets added immediately before list.tail.
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *      void * item - item to be added
- *  Returns:
- *      The pointer to the ListNode on success, NULL on failure.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode *
-ListAddTail( LinkedList * list,
-             void *item )
-{
-    assert( list != NULL );
-
-    if( list == NULL )
-        return NULL;
-
-    return ListAddBefore( list, item, &list->tail );
-}
-
-/****************************************************************************
- * Function: ListAddAfter
- *
- *  Description:
- *      Adds a node after the specified node.
- *      Node gets added immediately after bnode.
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *      void * item - item to be added
- *      ListNode * bnode - node to add after
- *  Returns:
- *      The pointer to the ListNode on success, NULL on failure.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode *
-ListAddAfter( LinkedList * list,
-              void *item,
-              ListNode * bnode )
-{
-    ListNode *newNode = NULL;
-
-    assert( list != NULL );
-
-    if( ( list == NULL ) || ( bnode == NULL ) )
-        return NULL;
-
-    newNode = CreateListNode( item, list );
-    if( newNode ) {
-        ListNode *temp = bnode->next;
-
-        bnode->next = newNode;
-        newNode->prev = bnode;
-        newNode->next = temp;
-        temp->prev = newNode;
-        list->size++;
-        return newNode;
-    }
-    return NULL;
-}
-
-/****************************************************************************
- * Function: ListAddBefore
- *
- *  Description:
- *      Adds a node before the specified node.
- *      Node gets added immediately before anode.
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *      ListNode * anode  - node to add the in front of.
- *      void * item - item to be added
- *  Returns:
- *      The pointer to the ListNode on success, NULL on failure.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode *
-ListAddBefore( LinkedList * list,
-               void *item,
-               ListNode * anode )
-{
-    ListNode *newNode = NULL;
-
-    assert( list != NULL );
-
-    if( ( list == NULL ) || ( anode == NULL ) )
-        return NULL;
-
-    newNode = CreateListNode( item, list );
-
-    if( newNode ) {
-        ListNode *temp = anode->prev;
-
-        anode->prev = newNode;
-        newNode->next = anode;
-        newNode->prev = temp;
-        temp->next = newNode;
-        list->size++;
-        return newNode;
-    }
-    return NULL;
-}
-
-/****************************************************************************
- * Function: ListDelNode
- *
- *  Description:
- *      Removes a node from the list
- *      The memory for the node is freed but the
- *      the memory for the items are not.
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *      ListNode *dnode - done to delete.
- *  Returns:
- *      The pointer to the item stored in node on success, NULL on failure.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-void *
-ListDelNode( LinkedList * list,
-             ListNode * dnode,
-             int freeItem )
-{
-    void *temp;
-
-    assert( list != NULL );
-    assert( dnode != &list->head );
-    assert( dnode != &list->tail );
-
-    if( ( list == NULL ) ||
-        ( dnode == &list->head ) ||
-        ( dnode == &list->tail ) || ( dnode == NULL ) ) {
-        return NULL;
-    }
-
-    temp = dnode->item;
-    dnode->prev->next = dnode->next;
-    dnode->next->prev = dnode->prev;
-
-    freeListNode( dnode, list );
-    list->size--;
-
-    if( freeItem && list->free_func ) {
-        list->free_func( temp );
-        temp = NULL;
-    }
-
-    return temp;
-}
-
-/****************************************************************************
- * Function: ListDestroy
- *
- *  Description:
- *      Removes all memory associated with list nodes. 
- *      Does not free LinkedList *list. 
- *      Items stored in the list are not freed, only nodes are.
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *  Returns:
- *      0 on success. Nonzero on failure.
- *      Always returns 0.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-int
-ListDestroy( LinkedList * list,
-             int freeItem )
-{
-    ListNode *dnode = NULL;
-    ListNode *temp = NULL;
-
-    if( list == NULL )
-        return EINVAL;
-
-    for( dnode = list->head.next; dnode != &list->tail; ) {
-        temp = dnode->next;
-        ListDelNode( list, dnode, freeItem );
-        dnode = temp;
-    }
-
-    list->size = 0;
-    FreeListDestroy( &list->freeNodeList );
-    return 0;
-}
-
-/****************************************************************************
- * Function: ListHead
- *
- *  Description:
- *      Returns the head of the list.
- *    
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *  
- *  Returns:
- *      The head of the list. NULL if list is empty.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode *
-ListHead( LinkedList * list )
-{
-    assert( list != NULL );
-
-    if( list == NULL )
-        return NULL;
-
-    if( list->size == 0 )
-        return NULL;
-    else
-        return list->head.next;
-}
-
-/****************************************************************************
- * Function: ListTail
- *
- *  Description:
- *      Returns the tail of the list.
- *    
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *  
- *  Returns:
- *      The tail of the list. NULL if list is empty.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode *
-ListTail( LinkedList * list )
-{
-    assert( list != NULL );
-
-    if( list == NULL )
-        return NULL;
-
-    if( list->size == 0 )
-        return NULL;
-    else
-        return list->tail.prev;
-}
-
-/****************************************************************************
- * Function: ListNext
- *
- *  Description:
- *      Returns the next item in the list.
- *    
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *  
- *  Returns:
- *      The next item in the list. NULL if there are no more items in list.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode *
-ListNext( LinkedList * list,
-          ListNode * node )
-{
-    assert( list != NULL );
-    assert( node != NULL );
-
-    if( ( list == NULL ) || ( node == NULL ) )
-        return NULL;
-
-    if( node->next == &list->tail )
-        return NULL;
-    else
-        return node->next;
-}
-
-/****************************************************************************
- * Function: ListPrev
- *
- *  Description:
- *      Returns the previous item in the list.
- *    
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *  
- *  Returns:
- *      The previous item in the list. NULL if there are no more items in list.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode *
-ListPrev( LinkedList * list,
-          ListNode * node )
-{
-    assert( list != NULL );
-    assert( node != NULL );
-
-    if( ( list == NULL ) || ( node == NULL ) )
-        return NULL;
-
-    if( node->prev == &list->head )
-        return NULL;
-    else
-        return node->prev;
-}
-
-/****************************************************************************
- * Function: ListFind
- *
- *  Description:
- *      Finds the specified item in the list.
- *      Uses the compare function specified in ListInit. If compare function
- *      is NULL then compares items as pointers.
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- *      ListNode *start - the node to start from, NULL if to start from 
- *                        beginning.
- *      void * item - the item to search for.
- *  Returns:
- *      The node containing the item. NULL if no node contains the item.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-ListNode *
-ListFind( LinkedList * list,
-          ListNode * start,
-          void *item )
-{
-
-    ListNode *finger = NULL;
-
-    if( list == NULL )
-        return NULL;
-
-    if( start == NULL )
-        start = &list->head;
-
-    assert( start );
-
-    finger = start->next;
-
-    assert( finger );
-
-    while( finger != &list->tail ) {
-        if( list->cmp_func ) {
-            if( list->cmp_func( item, finger->item ) )
-                return finger;
-        } else {
-            if( item == finger->item )
-                return finger;
-        }
-        finger = finger->next;
-    }
-
-    return NULL;
-
-}
-
-/****************************************************************************
- * Function: ListSize
- *
- *  Description:
- *     Returns the size of the list.
- *  Parameters:
- *      LinkedList *list  - must be valid, non null, pointer to a linked list.
- 
- *  Returns:
- *      The number of items in the list.
- *  Precondition:
- *      The list has been initialized.
- *****************************************************************************/
-int
-ListSize( LinkedList * list )
-{
-    assert( list != NULL );
-
-    if( list == NULL )
-        return EINVAL;
-
-    return list->size;
-}
diff --git a/tombupnp/threadutil/src/ThreadPool.c b/tombupnp/threadutil/src/ThreadPool.c
deleted file mode 100644
index 17794c1..0000000
--- a/tombupnp/threadutil/src/ThreadPool.c
+++ /dev/null
@@ -1,1633 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include "ThreadPool.h"
-#include "FreeList.h"
-#include <assert.h>
-#include <stdlib.h>
-
-#ifdef STATS
-#include <stdio.h>
-#endif
-
-/****************************************************************************
- * Function: CmpThreadPoolJob
- *
- *  Description:
- *      Compares thread pool jobs.
- *  Parameters:
- *      void * - job A
- *      void * - job B
- *****************************************************************************/
-static int
-CmpThreadPoolJob( void *jobA,
-                  void *jobB )
-{
-    ThreadPoolJob *a = ( ThreadPoolJob * ) jobA;
-    ThreadPoolJob *b = ( ThreadPoolJob * ) jobB;
-
-    assert( jobA != NULL );
-    assert( jobB != NULL );
-    return ( a->jobId == b->jobId );
-}
-
-/****************************************************************************
- * Function: FreeThreadPoolJob
- *
- *  Description:
- *      Deallocates a dynamically allocated ThreadPoolJob.
- *  Parameters:
- *      ThreadPoolJob *tpj - must be allocated with CreateThreadPoolJob
- *****************************************************************************/
-static void
-FreeThreadPoolJob( ThreadPool * tp,
-                   ThreadPoolJob * tpj )
-{
-    assert( tp != NULL );
-
-    FreeListFree( &tp->jobFreeList, tpj );
-}
-
-/****************************************************************************
- * Function: SetPolicyType
- *
- *  Description:
- *      Sets the scheduling policy of the current process.
- *      Internal only.
- *  Parameters:
- *      PolocyType in
- *  Returns:
- *      0 on success, nonzero on failure
- *      Returns result of GetLastError() on failure.
- *
- *****************************************************************************/
-static int
-SetPolicyType( PolicyType in )
-{
-    #ifdef WIN32
-     return sched_setscheduler( 0, in);
-    #else
-     return 0;
-    #endif
-}
-
-/****************************************************************************
- * Function: SetPriority
- *
- *  Description:
- *      Sets the priority of the currently running thread.
- *      Internal only.
- *  Parameters:
- *      ThreadPriority priority
- *  Returns:
- *      0 on success, nonzero on failure
- *      EINVAL invalid priority
- *      Returns result of GerLastError on failure.
- *
- *****************************************************************************/
-static int
-SetPriority( ThreadPriority priority )
-{
-#if defined(HAVE_SCHED_GET_PRIORITY_MIN) && defined(HAVE_SCHED_GET_PRIORITY_MAX)
-    int currentPolicy;
-    int minPriority = 0;
-    int maxPriority = 0;
-    int actPriority = 0;
-    int midPriority = 0;
-    struct sched_param newPriority;
-
-    pthread_getschedparam( ithread_self(  ), &currentPolicy,
-                           &newPriority );
-
-    minPriority = sched_get_priority_min( currentPolicy );
-    maxPriority = sched_get_priority_max( currentPolicy );
-    midPriority = ( maxPriority - minPriority ) / 2;
-    switch ( priority ) {
-
-        case LOW_PRIORITY:
-            actPriority = minPriority;
-            break;
-        case MED_PRIORITY:
-            actPriority = midPriority;
-            break;
-        case HIGH_PRIORITY:
-            actPriority = maxPriority;
-            break;
-        default:
-            return EINVAL;
-    };
-
-    newPriority.sched_priority = actPriority;
-    return pthread_setschedparam( ithread_self(  ), currentPolicy,
-                                  &newPriority );
-#else
-    return 0;
-#endif
-}
-
-/****************************************************************************
- * Function: DiffMillis
- *
- *  Description:
- *      Returns the difference in milliseconds between two
- *      timeb structures.
- *      Internal Only.
- *  Parameters:
- *      struct timeb *time1,
- *      struct timeb *time2,
- *  Returns:
- *       the difference in milliseconds, time1-time2.
- *****************************************************************************/
-static double
-DiffMillis( struct timeval *time1,
-            struct timeval *time2 )
-{
-    double temp = 0;
-
-    assert( time1 != NULL );
-    assert( time2 != NULL );
-
-    temp = ( ( double )( time1->tv_sec ) - time2->tv_sec );
-    temp = temp * 1000;
-    temp += ( (time1->tv_usec/1000) - (time2->tv_usec/1000) );
-    return temp;
-}
-
-/****************************************************************************
- * Function: BumpPriority
- *
- *  Description:
- *      Determines whether any jobs
- *      need to be bumped to a higher priority Q and bumps them.
- *
- *      tp->mutex must be locked.
- *      Internal Only.
- *  Parameters:
- *      ThreadPool *tp
- *****************************************************************************/
-static void
-BumpPriority( ThreadPool * tp )
-{
-    int done = 0;
-    struct timeval now;
-    double diffTime = 0;
-    ThreadPoolJob *tempJob = NULL;
-
-    assert( tp != NULL );
-
-    gettimeofday( &now, NULL );
-
-    while( !done ) {
-        if( tp->medJobQ.size ) {
-            tempJob = ( ThreadPoolJob * ) tp->medJobQ.head.next->item;
-            diffTime = DiffMillis( &now, &tempJob->requestTime );
-
-            if( diffTime >= ( tp->attr.starvationTime ) ) {
-                //If job has waited longer than the
-                //starvation time
-                //bump priority (add to higher priority Q)
-
-                STATSONLY( tp->stats.totalJobsMQ++;
-                     );
-                STATSONLY( tp->stats.totalTimeMQ += diffTime;
-                     );
-
-                ListDelNode( &tp->medJobQ, tp->medJobQ.head.next, 0 );
-                ListAddTail( &tp->highJobQ, tempJob );
-                continue;
-            }
-        }
-
-        if( tp->lowJobQ.size ) {
-            tempJob = ( ThreadPoolJob * ) tp->lowJobQ.head.next->item;
-
-            diffTime = DiffMillis( &now, &tempJob->requestTime );
-
-            if( diffTime >= ( tp->attr.maxIdleTime ) ) {
-                //If job has waited longer than the
-                //starvation time
-                //bump priority (add to higher priority Q)
-
-                STATSONLY( tp->stats.totalJobsLQ++;
-                     );
-                STATSONLY( tp->stats.totalTimeLQ += diffTime;
-                     );
-
-                ListDelNode( &tp->lowJobQ, tp->lowJobQ.head.next, 0 );
-                ListAddTail( &tp->medJobQ, tempJob );
-                continue;
-            }
-        }
-
-        done = 1;
-    }
-}
-
-/****************************************************************************
- * Function: SetRelTimeout
- *
- *  Description:
- *      Sets the fields of the
- *      passed in timespec to be relMillis milliseconds in the future.
- *      Internal Only.
- *  Parameters:
- *      struct timespec *time
- *      int relMillis - milliseconds in the future
- *****************************************************************************/
-static void
-SetRelTimeout( struct timespec *time,
-               int relMillis )
-{
-    struct timeval now;
-    int sec = relMillis / 1000;
-    int milliSeconds = relMillis % 1000;
-
-    assert( time != NULL );
-
-    gettimeofday( &now, NULL );
-
-    time->tv_sec = now.tv_sec + sec;
-    time->tv_nsec = ( (now.tv_usec/1000) + milliSeconds ) * 1000000;
-}
-
-/****************************************************************************
- * Function: StatsInit
- *
- *  Description:
- *      Initializes the statistics structure.
- *      Internal Only.
- *  Parameters:
- *      ThreadPoolStats *stats must be valid non null stats structure
- *****************************************************************************/
-#ifdef STATS
-static void StatsInit( ThreadPoolStats * stats ) {
-           assert( stats != NULL ); stats->totalIdleTime = 0; stats->totalJobsHQ = 0; stats->totalJobsLQ = 0; stats->totalJobsMQ = 0; stats->totalTimeHQ = 0; stats->totalTimeMQ = 0; stats->totalTimeLQ = 0; stats->totalWorkTime = 0; stats->totalIdleTime = 0; stats->avgWaitHQ = 0; //average wait in HQ
-           stats->avgWaitMQ = 0;    //average wait in MQ
-           stats->avgWaitLQ = 0;
-           stats->workerThreads = 0;
-           stats->idleThreads = 0;
-           stats->persistentThreads = 0;
-           stats->maxThreads = 0; stats->totalThreads = 0;}
-#endif
-
-/****************************************************************************
- * Function: CalcWaitTime
- *
- *  Description:
- *      Calculates the time the job has been waiting at the specified
- *      priority. Adds to the totalTime and totalJobs kept in the
- *      thread pool statistics structure.
- *      Internal Only.
- *
- *  Parameters:
- *      ThreadPool *tp
- *      ThreadPriority p
- *      ThreadPoolJob *job
- *****************************************************************************/
-#ifdef STATS
-static void CalcWaitTime( ThreadPool * tp,
-                                     ThreadPriority p,
-                                     ThreadPoolJob * job ) {
-           struct timeval now;
-           double diff;
-           assert( tp != NULL );
-           assert( job != NULL );
-           gettimeofday( &now, NULL );
-           diff = DiffMillis( &now, &job->requestTime ); switch ( p ) {
-case HIGH_PRIORITY:
-tp->stats.totalJobsHQ++; tp->stats.totalTimeHQ += diff; break; case MED_PRIORITY:
-tp->stats.totalJobsMQ++; tp->stats.totalTimeMQ += diff; break; case LOW_PRIORITY:
-tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default:
-           assert( 0 );}
-           }
-
-#endif
-
-/****************************************************************************
- * Function: SetSeed
- *
- *  Description:
- *      Sets seed for random number generator.
- *      Each thread sets the seed random number generator.
- *      Internal Only.
- *  Parameters:
- *      
- *****************************************************************************/
-    static void SetSeed(  ) {
-    struct timeval t;
-
-    gettimeofday( &t, NULL );
-#if defined(WIN32)
-    srand( ( unsigned int )(t.tv_usec/1000) + (unsigned int)ithread_get_current_thread_id(  ).p );
-#elif defined(HAVE_ARC4RANDOM)
-    srand( arc4random() );
-#else
-    srand( ( unsigned int )(t.tv_usec/1000) + ithread_get_current_thread_id(  ) );
-#endif
-    }
-
-/****************************************************************************
- * Function: WorkerThread
- *
- *  Description:
- *      Implements a thread pool worker.
- *      Worker waits for a job to become available.
- *      Worker picks up persistent jobs first, high priority, med priority,
- *             then low priority.
- *      If worker remains idle for more than specified max, the worker
- *      is released.
- *      Internal Only.
- *  Parameters:
- *      void * arg -> is cast to ThreadPool *
- *****************************************************************************/
-    static void *WorkerThread( void *arg ) {
-
-        STATSONLY( time_t start = 0;
-             )
-
-        ThreadPoolJob *job = NULL;
-        ListNode *head = NULL;
-
-        struct timespec timeout;
-        int retCode = 0;
-        int persistent = -1;
-        ThreadPool *tp = ( ThreadPool * ) arg;
-        //leuk_he allow static linking
-		  #ifdef WIN32
-		   #ifdef PTW32_STATIC_LIB
-		    pthread_win32_thread_attach_np();
-		   #endif
-		  #endif
-
-        assert( tp != NULL );
-
-        //Increment total thread count
-        ithread_mutex_lock( &tp->mutex );
-        tp->totalThreads++;
-        ithread_cond_broadcast( &tp->start_and_shutdown );
-        ithread_mutex_unlock( &tp->mutex );
-
-        SetSeed(  );
-
-        STATSONLY( time( &start );
-             );
-
-        while( 1 ) {
-
-            ithread_mutex_lock( &tp->mutex );
-
-            if( job ) {
-                tp->busyThreads--;
-                FreeThreadPoolJob( tp, job );
-                job = NULL;
-
-            }
-
-            retCode = 0;
-
-            STATSONLY( tp->stats.idleThreads++;
-                 );
-            STATSONLY( tp->stats.totalWorkTime += ( time( NULL ) - start );
-                 );             //work time
-            STATSONLY( time( &start );
-                 );             //idle time
-
-            if( persistent == 1 ) {
-                //Persistent thread
-                //becomes a regular thread
-                tp->persistentThreads--;
-            }
-
-            STATSONLY( if( persistent == 0 )
-                       tp->stats.workerThreads--; );
-
-            //Check for a job or shutdown
-            while( ( tp->lowJobQ.size == 0 )
-                   && ( tp->medJobQ.size == 0 )
-                   && ( tp->highJobQ.size == 0 )
-                   && ( !tp->persistentJob )
-                   && ( !tp->shutdown ) ) {
-
-                //If wait timed out
-                //and we currently have more than the
-                //min threads, or if we have more than the max threads
-                // (only possible if the attributes have been reset)
-                //let this thread die.
-
-                if( ( ( retCode == ETIMEDOUT )
-                      && ( ( tp->totalThreads ) > tp->attr.minThreads ) )
-                    || ( ( tp->attr.maxThreads != -1 )
-                         && ( ( tp->totalThreads ) >
-                              tp->attr.maxThreads ) ) ) {
-
-                    STATSONLY( tp->stats.idleThreads-- );
-
-                    tp->totalThreads--;
-                   
-                    if (tp->free_func)
-                        tp->free_func();
-
-                    ithread_cond_broadcast( &tp->start_and_shutdown );
-                    ithread_mutex_unlock( &tp->mutex );
-					//leuk_he
-	                 #ifdef WIN32
-	                  #ifdef PTW32_STATIC_LIB
-	                   pthread_win32_thread_detach_np ();
-	                  #endif
-	                 #endif
-
-
-
-                    return NULL;
-                }
-
-                SetRelTimeout( &timeout, tp->attr.maxIdleTime );
-
-                //wait for a job up to the specified max time
-                    retCode = ithread_cond_timedwait( &tp->condition,
-                            &tp->mutex, &timeout );
-
-            }
-
-            STATSONLY( tp->stats.idleThreads--;
-                 );
-            STATSONLY( tp->stats.totalIdleTime += ( time( NULL ) - start );
-                 );             //idle time
-            STATSONLY( time( &start );
-                 );             //work time
-
-            //bump priority of starved jobs
-            BumpPriority( tp );
-
-            //if shutdown then stop
-            if( tp->shutdown ) {
-                tp->totalThreads--;
-
-                if (tp->free_func)
-                    tp->free_func();
-
-                ithread_cond_broadcast( &tp->start_and_shutdown );
-
-                ithread_mutex_unlock( &tp->mutex );
-				//leuk_he
-                #ifdef WIN32
-                 #ifdef PTW32_STATIC_LIB
-                  pthread_win32_thread_detach_np ();
-                 #endif
-                #endif
-
-                return NULL;
-            } else {
-                //Pick up persistent job if available
-                if( tp->persistentJob ) {
-                    job = tp->persistentJob;
-                    tp->persistentJob = NULL;
-                    tp->persistentThreads++;
-                    persistent = 1;
-                    ithread_cond_broadcast( &tp->start_and_shutdown );
-
-                } else {
-                    STATSONLY( tp->stats.workerThreads++ );
-                    persistent = 0;
-
-                    //Pick the highest priority job
-                    if( tp->highJobQ.size > 0 ) {
-                        head = ListHead( &tp->highJobQ );
-                        job = ( ThreadPoolJob * ) head->item;
-                        STATSONLY( CalcWaitTime
-                                   ( tp, HIGH_PRIORITY, job ) );
-                        ListDelNode( &tp->highJobQ, head, 0 );
-
-                    } else if( tp->medJobQ.size > 0 ) {
-                        head = ListHead( &tp->medJobQ );
-                        job = ( ThreadPoolJob * ) head->item;
-                        STATSONLY( CalcWaitTime( tp, MED_PRIORITY, job ) );
-                        ListDelNode( &tp->medJobQ, head, 0 );
-
-                    } else if( tp->lowJobQ.size > 0 ) {
-                        head = ListHead( &tp->lowJobQ );
-                        job = ( ThreadPoolJob * ) head->item;
-                        STATSONLY( CalcWaitTime( tp, LOW_PRIORITY, job ) );
-                        ListDelNode( &tp->lowJobQ, head, 0 );
-
-                    } else {
-                        // Should never get here
-                        assert( 0 );
-                        STATSONLY( tp->stats.workerThreads-- );
-                        tp->totalThreads--;
-                        ithread_cond_broadcast( &tp->start_and_shutdown );
-                        ithread_mutex_unlock( &tp->mutex );
-
-                        return NULL;
-                    }
-
-                }
-            }
-            
-            tp->busyThreads++;
-
-            ithread_mutex_unlock( &tp->mutex );
-
-            if( SetPriority( job->priority ) != 0 ) {
-                // In the future can log
-                // info
-            } else {
-                // In the future can log
-                // info
-            }
-
-            //run the job
-
-            job->func( job->arg );
-
-            //return to Normal
-            SetPriority( DEFAULT_PRIORITY );
-
-        }
-    }
-
-/****************************************************************************
- * Function: CreateThreadPoolJob
- *
- *  Description:
- *      Creates a Thread Pool Job. (Dynamically allocated)
- *      Internal to thread pool.
- *  Parameters:
- *      ThreadPoolJob * job - job is copied
- *      id - id of job
- *
- *  Returns:
- *      ThreadPoolJob * on success, NULL on failure.
- *****************************************************************************/
-    static ThreadPoolJob *CreateThreadPoolJob( ThreadPoolJob * job,
-                                               int id,
-                                               ThreadPool * tp ) {
-
-        ThreadPoolJob *newJob = NULL;
-
-        assert( job != NULL );
-        assert( tp != NULL );
-
-        newJob = ( ThreadPoolJob * ) FreeListAlloc( &tp->jobFreeList );
-
-        if( newJob ) {
-            ( *newJob ) = ( *job );
-            newJob->jobId = id;
-            gettimeofday( &newJob->requestTime, NULL );
-        }
-        return newJob;
-    }
-
-/****************************************************************************
- * Function: CreateWorker
- *
- *  Description:
- *      Creates a worker thread, if the thread pool
- *      does not already have max threads.
- *      Internal to thread pool.
- *  Parameters:
- *      ThreadPool *tp
- *
- *  Returns:
- *      0 on success, <0 on failure
- *      EMAXTHREADS if already max threads reached
- *      EAGAIN if system can not create thread
- *
- *****************************************************************************/
-    static int CreateWorker( ThreadPool * tp ) {
-        ithread_t temp;
-        int rc = 0;
-        int currentThreads = tp->totalThreads + 1;
-
-        assert( tp != NULL );
-
-        if( ( tp->attr.maxThreads != INFINITE_THREADS )
-            && ( currentThreads > tp->attr.maxThreads ) ) {
-            return EMAXTHREADS;
-        }
-
-        rc = ithread_create( &temp, NULL, WorkerThread, tp );
-
-        if( rc == 0 ) {
-
-            rc = ithread_detach( temp );
-
-            while( tp->totalThreads < currentThreads ) {
-
-                ithread_cond_wait( &tp->start_and_shutdown, &tp->mutex );
-
-            }
-
-        }
-
-        STATSONLY( if( tp->stats.maxThreads < tp->totalThreads ) {
-                   tp->stats.maxThreads = tp->totalThreads;}
-         )
-
-            return rc;
-    }
-
-/****************************************************************************
- * Function: AddWorker
- *
- *  Description:
- *      Determines whether or not a thread should be added
- *      based on the jobsPerThread ratio.
- *      Adds a thread if appropriate.
- *      Internal to Thread Pool.
- *  Parameters:
- *      ThreadPool* tp
- *
- *****************************************************************************/
-    static void AddWorker( ThreadPool * tp ) {
-        int jobs = 0;
-        int threads = 0;
-
-        assert( tp != NULL );
-
-        jobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size;
-
-        threads = tp->totalThreads - tp->persistentThreads;
-
-        while( ( threads == 0 )
-               || ( ( jobs / threads ) > tp->attr.jobsPerThread ) || (tp->totalThreads == tp->busyThreads)) {
-
-            if( CreateWorker( tp ) != 0 )
-                return;
-            threads++;
-        }
-
-    }
-
-/****************************************************************************
- * Function: ThreadPoolInit
- *
- *  Description:
- *      Initializes and starts ThreadPool. Must be called first.
- *      And only once for ThreadPool.
- *  Parameters:
- *      tp  - must be valid, non null, pointer to ThreadPool.
- *      minWorkerThreads - minimum number of worker threads
- *                         thread pool will never have less than this
- *                         number of threads.
- *      maxWorkerThreads - maximum number of worker threads
- *                         thread pool will never have more than this
- *                         number of threads.
- *      maxIdleTime      - maximum time that a worker thread will spend
- *                         idle. If a worker is idle longer than this
- *                         time and there are more than the min
- *                         number of workers running, than the
- *                         worker thread exits.
- *      jobsPerThread    - ratio of jobs to thread to try and maintain
- *                         if a job is scheduled and the number of jobs per
- *                         thread is greater than this number,and
- *                         if less than the maximum number of
- *                         workers are running then a new thread is
- *                         started to help out with efficiency.
- *      schedPolicy      - scheduling policy to try and set (OS dependent)
- *  Returns:
- *      0 on success, nonzero on failure.
- *      EAGAIN if not enough system resources to create minimum threads.
- *      INVALID_POLICY if schedPolicy can't be set
- *      EMAXTHREADS if minimum threads is greater than maximum threads
- *****************************************************************************/
-    int ThreadPoolInit( ThreadPool * tp,
-                        ThreadPoolAttr * attr ) {
-        int retCode = 0;
-        int i = 0;
-
-        assert( tp != NULL );
-
-        if( tp == NULL ) {
-            return EINVAL;
-        }
-				//leuk_he
-		  #ifdef WIN32
-		   #ifdef PTW32_STATIC_LIB
-		    pthread_win32_process_attach_np();
-		   #endif
-		  #endif
-
-        retCode += ithread_mutex_init( &tp->mutex, NULL );
-        assert( retCode == 0 );
-
-        retCode += ithread_mutex_lock( &tp->mutex );
-        assert( retCode == 0 );
-
-        retCode += ithread_cond_init( &tp->condition, NULL );
-        assert( retCode == 0 );
-
-        retCode += ithread_cond_init( &tp->start_and_shutdown, NULL );
-        assert( retCode == 0 );
-
-        if( retCode != 0 ) {
-            return EAGAIN;
-        }
-
-        if( attr ) {
-            tp->attr = ( *attr );
-        } else {
-            TPAttrInit( &tp->attr );
-        }
-
-        if( SetPolicyType( tp->attr.schedPolicy ) != 0 ) {
-            ithread_mutex_unlock( &tp->mutex );
-            ithread_mutex_destroy( &tp->mutex );
-            ithread_cond_destroy( &tp->condition );
-            ithread_cond_destroy( &tp->start_and_shutdown );
-            return INVALID_POLICY;
-        }
-
-        retCode += FreeListInit( &tp->jobFreeList, sizeof( ThreadPoolJob ),
-                                 JOBFREELISTSIZE );
-        assert( retCode == 0 );
-
-        STATSONLY( StatsInit( &tp->stats ) );
-
-        retCode += ListInit( &tp->highJobQ, CmpThreadPoolJob, NULL );
-        assert( retCode == 0 );
-
-        retCode += ListInit( &tp->medJobQ, CmpThreadPoolJob, NULL );
-        assert( retCode == 0 );
-
-        retCode += ListInit( &tp->lowJobQ, CmpThreadPoolJob, NULL );
-        assert( retCode == 0 );
-
-        if( retCode != 0 ) {
-            retCode = EAGAIN;
-        } else {
-
-            tp->persistentJob = NULL;
-            tp->lastJobId = 0;
-            tp->shutdown = 0;
-            tp->totalThreads = 0;
-            tp->busyThreads = 0;
-            tp->persistentThreads = 0;
-
-            for( i = 0; i < tp->attr.minThreads; i++ ) {
-
-                if( ( retCode = CreateWorker( tp ) ) != 0 ) {
-                    break;
-                }
-            }
-        }
-
-        ithread_mutex_unlock( &tp->mutex );
-
-        if( retCode != 0 ) {
-            //clean up if the min threads could
-            //not be created
-            ThreadPoolShutdown( tp );
-        }
-
-        return retCode;
-    }
-
-/****************************************************************************
- * Function: ThreadPoolAddPersistent
- *
- *  Description:
- *      Adds a long term job to the thread pool.
- *      Job will be run as soon as possible.
- *      Call will block until job is scheduled.
- *  Parameters:
- *      tp - valid thread pool pointer
- *      job-> valid ThreadPoolJob pointer with following fields
- *          func - ThreadFunction to run
- *          arg - argument to function.
- *          priority - priority of job.
- *          free_function - function to use when freeing argument
- *  Returns:
- *      0 on success, nonzero on failure
- *      EOUTOFMEM not enough memory to add job.
- *      EMAXTHREADS not enough threads to add persistent job.
- *****************************************************************************/
-    int ThreadPoolAddPersistent( ThreadPool * tp,
-                                 ThreadPoolJob * job,
-                                 int *jobId ) {
-        int tempId = -1;
-
-        ThreadPoolJob *temp = NULL;
-
-        assert( tp != NULL );
-        assert( job != NULL );
-
-        if( ( tp == NULL ) || ( job == NULL ) ) {
-            return EINVAL;
-        }
-
-        if( jobId == NULL )
-            jobId = &tempId;
-
-        ( *jobId ) = INVALID_JOB_ID;
-
-        ithread_mutex_lock( &tp->mutex );
-
-        assert( ( job->priority == LOW_PRIORITY )
-                || ( job->priority == MED_PRIORITY )
-                || ( job->priority == HIGH_PRIORITY ) );
-
-        //Create A worker if less than max threads running
-        if( tp->totalThreads < tp->attr.maxThreads ) {
-            CreateWorker( tp );
-        } else {
-            //if there is more than one worker thread
-            //available then schedule job, otherwise fail
-            if( ( tp->totalThreads - tp->persistentThreads ) - 1 == 0 ) {
-                ithread_mutex_unlock( &tp->mutex );
-                return EMAXTHREADS;
-            }
-        }
-
-        temp = CreateThreadPoolJob( job, tp->lastJobId, tp );
-
-        if( temp == NULL ) {
-            ithread_mutex_unlock( &tp->mutex );
-            return EOUTOFMEM;
-        }
-
-        tp->persistentJob = temp;
-
-        //Notify a waiting thread
-
-        ithread_cond_signal( &tp->condition );
-
-        //wait until long job has been picked up
-        while( tp->persistentJob != NULL ) {
-            ithread_cond_wait( &tp->start_and_shutdown, &tp->mutex );
-        }
-
-        ( *jobId ) = tp->lastJobId++;
-        ithread_mutex_unlock( &tp->mutex );
-        return 0;
-    }
-
-/****************************************************************************
- * Function: ThreadPoolAdd
- *
- *  Description:
- *      Adds a job to the thread pool.
- *      Job will be run as soon as possible.
- *  Parameters:
- *      tp - valid thread pool pointer
- *      func - ThreadFunction to run
- *      arg - argument to function.
- *      priority - priority of job.
- *      jobId - id of job
- *      duration - whether or not this is a persistent thread
- *      free_function - function to use when freeing argument
- *  Returns:
- *      0 on success, nonzero on failure
- *      EOUTOFMEM if not enough memory to add job.
- *****************************************************************************/
-    int ThreadPoolAdd( ThreadPool * tp,
-                       ThreadPoolJob * job,
-                       int *jobId ) {
-        int rc = EOUTOFMEM;
-
-        int tempId = -1;
-        int totalJobs;
-
-        ThreadPoolJob *temp = NULL;
-
-        assert( tp != NULL );
-        assert( job != NULL );
-
-        if( ( tp == NULL ) || ( job == NULL ) ) {
-            return EINVAL;
-        }
-
-        ithread_mutex_lock( &tp->mutex );
-
-        assert( ( job->priority == LOW_PRIORITY )
-                || ( job->priority == MED_PRIORITY )
-                || ( job->priority == HIGH_PRIORITY ) );
-
-        totalJobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size;
-        if (totalJobs >= tp->attr.maxJobsTotal) {
-            fprintf(stderr, "total jobs = %d, too many jobs", totalJobs);
-            ithread_mutex_unlock( &tp->mutex );
-            return rc;
-        }
-
-        if( jobId == NULL )
-            jobId = &tempId;
-
-        ( *jobId ) = INVALID_JOB_ID;
-
-        temp = CreateThreadPoolJob( job, tp->lastJobId, tp );
-
-        if( temp == NULL ) {
-            ithread_mutex_unlock( &tp->mutex );
-            return rc;
-        }
-
-        if( job->priority == HIGH_PRIORITY ) {
-            if( ListAddTail( &tp->highJobQ, temp ) )
-                rc = 0;
-        } else if( job->priority == MED_PRIORITY ) {
-            if( ListAddTail( &tp->medJobQ, temp ) )
-                rc = 0;
-        } else {
-            if( ListAddTail( &tp->lowJobQ, temp ) )
-                rc = 0;
-        }
-
-        //AddWorker if appropriate
-        AddWorker( tp );
-
-        //Notify a waiting thread
-        if( rc == 0 ) {
-            ithread_cond_signal( &tp->condition );
-
-        } else {
-            FreeThreadPoolJob( tp, temp );
-        }
-
-        ( *jobId ) = tp->lastJobId++;
-
-        ithread_mutex_unlock( &tp->mutex );
-        return rc;
-    }
-
-/****************************************************************************
- * Function: ThreadPoolRemove
- *
- *  Description:
- *      Removes a job from the thread pool.
- *      Can only remove jobs which are not
- *      currently running.
- *  Parameters:
- *      tp - valid thread pool pointer
- *      jobId - id of job
- *      ThreadPoolJob *out - space for removed job.
- *                           Can be null if not needed.
- *
- *  Returns:
- *      0 on success. INVALID_JOB_ID on failure.
- *****************************************************************************/
-    int ThreadPoolRemove( ThreadPool * tp,
-                          int jobId,
-                          ThreadPoolJob * out ) {
-        ThreadPoolJob *temp = NULL;
-        int ret = INVALID_JOB_ID;
-        ListNode *tempNode = NULL;
-        ThreadPoolJob dummy;
-
-        assert( tp != NULL );
-
-        if( tp == NULL ) {
-            return EINVAL;
-        }
-
-        if( out == NULL ) {
-            out = &dummy;
-        }
-
-        dummy.jobId = jobId;
-
-        ithread_mutex_lock( &tp->mutex );
-
-        tempNode = ListFind( &tp->highJobQ, NULL, &dummy );
-
-        if( tempNode ) {
-            temp = ( ThreadPoolJob * ) tempNode->item;
-            ( *out ) = ( *temp );
-            ListDelNode( &tp->highJobQ, tempNode, 0 );
-            FreeThreadPoolJob( tp, temp );
-            ithread_mutex_unlock( &tp->mutex );
-            return 0;
-        }
-
-        tempNode = ListFind( &tp->medJobQ, NULL, &dummy );
-
-        if( tempNode ) {
-            temp = ( ThreadPoolJob * ) tempNode->item;
-            ( *out ) = ( *temp );
-            ListDelNode( &tp->medJobQ, tempNode, 0 );
-            FreeThreadPoolJob( tp, temp );
-            ithread_mutex_unlock( &tp->mutex );
-            return 0;
-        }
-
-        tempNode = ListFind( &tp->lowJobQ, NULL, &dummy );
-
-        if( tempNode ) {
-            temp = ( ThreadPoolJob * ) tempNode->item;
-            ( *out ) = ( *temp );
-            ListDelNode( &tp->lowJobQ, tempNode, 0 );
-            FreeThreadPoolJob( tp, temp );
-            ithread_mutex_unlock( &tp->mutex );
-            return 0;
-        }
-
-        if( ( tp->persistentJob )
-            && ( tp->persistentJob->jobId == jobId ) ) {
-            ( *out ) = ( *tp->persistentJob );
-            FreeThreadPoolJob( tp, tp->persistentJob );
-            tp->persistentJob = NULL;
-            ithread_mutex_unlock( &tp->mutex );
-            return 0;
-        }
-
-        ithread_mutex_unlock( &tp->mutex );
-        return ret;
-    }
-
-/****************************************************************************
- * Function: ThreadPoolGetAttr
- *
- *  Description:
- *      Gets the current set of attributes
- *      associated with the thread pool.
- *  Parameters:
- *      tp - valid thread pool pointer
- *      out - non null pointer to store attributes
- *  Returns:
- *      0 on success, nonzero on failure
- *      Always returns 0.
- *****************************************************************************/
-    int ThreadPoolGetAttr( ThreadPool * tp,
-                           ThreadPoolAttr * out ) {
-        assert( tp != NULL );
-
-        assert( out != NULL );
-
-        if( ( tp == NULL ) || ( out == NULL ) ) {
-            return EINVAL;
-        }
-
-        if( !tp->shutdown ) {
-            ithread_mutex_lock( &tp->mutex );
-        }
-
-        ( *out ) = tp->attr;
-
-        if( !tp->shutdown ) {
-            ithread_mutex_unlock( &tp->mutex );
-        }
-
-        return 0;
-    }
-
-/****************************************************************************
- * Function: ThreadPoolSetAttr
- *
- *  Description:
- *      Sets the attributes for the thread pool.
- *      Only affects future calculations.
- *  Parameters:
- *      tp - valid thread pool pointer
- *      attr - pointer to attributes, null sets attributes to default.
- *  Returns:
- *      0 on success, nonzero on failure
- *      Returns INVALID_POLICY if policy can not be set.
- *****************************************************************************/
-    int ThreadPoolSetAttr( ThreadPool * tp,
-                           ThreadPoolAttr * attr ) {
-        int retCode = 0;
-        ThreadPoolAttr temp;
-        int i = 0;
-
-        assert( tp != NULL );
-
-        if( tp == NULL ) {
-            return EINVAL;
-        }
-        ithread_mutex_lock( &tp->mutex );
-
-        if( attr != NULL ) {
-            temp = ( *attr );
-        } else {
-            TPAttrInit( &temp );
-        }
-
-        if( SetPolicyType( temp.schedPolicy ) != 0 ) {
-            ithread_mutex_unlock( &tp->mutex );
-            return INVALID_POLICY;
-        }
-
-        tp->attr = ( temp );
-
-        if( tp->totalThreads < tp->attr.minThreads )    //add threads
-        {
-            for( i = tp->totalThreads; i < tp->attr.minThreads; i++ ) {
-
-                if( ( retCode = CreateWorker( tp ) ) != 0 ) {
-                    break;
-                }
-            }
-        }
-
-        ithread_cond_signal( &tp->condition );  //signal changes 
-
-        ithread_mutex_unlock( &tp->mutex );
-
-        if( retCode != 0 ) {
-            //clean up if the min threads could
-            //not be created
-            ThreadPoolShutdown( tp );
-        }
-
-        return retCode;
-    }
-
-/****************************************************************************
- * Function: ThreadPoolShutdown
- *
- *  Description:
- *      Shuts the thread pool down.
- *      Waits for all threads to finish.
- *      May block indefinitely if jobs do not
- *      exit.
- *  Parameters:
- *      tp - must be valid tp
- *  Returns:
- *      0 on success, nonzero on failure
- *      Always returns 0.
- *****************************************************************************/
-    int ThreadPoolShutdown( ThreadPool * tp ) {
-
-        ListNode *head = NULL;
-        ThreadPoolJob *temp = NULL;
-
-        assert( tp != NULL );
-
-        if( tp == NULL ) {
-            return EINVAL;
-        }
-
-        ithread_mutex_lock( &tp->mutex );
-
-        //clean up high priority jobs
-        while( tp->highJobQ.size ) {
-            head = ListHead( &tp->highJobQ );
-            temp = ( ThreadPoolJob * ) head->item;
-            if( temp->free_func )
-                temp->free_func( temp->arg );
-            FreeThreadPoolJob( tp, temp );
-            ListDelNode( &tp->highJobQ, head, 0 );
-        }
-
-        ListDestroy( &tp->highJobQ, 0 );
-
-        //clean up med priority jobs
-        while( tp->medJobQ.size ) {
-            head = ListHead( &tp->medJobQ );
-            temp = ( ThreadPoolJob * ) head->item;
-            if( temp->free_func )
-                temp->free_func( temp->arg );
-            FreeThreadPoolJob( tp, temp );
-            ListDelNode( &tp->medJobQ, head, 0 );
-        }
-
-        ListDestroy( &tp->medJobQ, 0 );
-
-        //clean up low priority jobs
-        while( tp->lowJobQ.size ) {
-            head = ListHead( &tp->lowJobQ );
-            temp = ( ThreadPoolJob * ) head->item;
-            if( temp->free_func )
-                temp->free_func( temp->arg );
-            FreeThreadPoolJob( tp, temp );
-            ListDelNode( &tp->lowJobQ, head, 0 );
-        }
-
-        ListDestroy( &tp->lowJobQ, 0 );
-
-        //clean up long term job
-        if( tp->persistentJob ) {
-            temp = tp->persistentJob;
-            if( temp->free_func )
-                temp->free_func( temp->arg );
-            FreeThreadPoolJob( tp, temp );
-            tp->persistentJob = NULL;
-        }
-
-        tp->shutdown = 1;
-        ithread_cond_broadcast( &tp->condition );   //signal shutdown
-
-        //wait for all threads to finish
-        while( tp->totalThreads > 0 ) {
-
-            ithread_cond_wait( &tp->start_and_shutdown, &tp->mutex );
-        }
-
-        //destroy condition
-        while( ithread_cond_destroy( &tp->condition ) != 0 ) {
-        }
-
-        while( ithread_cond_destroy( &tp->start_and_shutdown ) != 0 ) {
-        }
-
-        FreeListDestroy( &tp->jobFreeList );
-
-        ithread_mutex_unlock( &tp->mutex );
-
-        //destroy mutex
-        while( ithread_mutex_destroy( &tp->mutex ) != 0 ) {
-        }
-
-        return 0;
-    }
-
-/****************************************************************************
- * Function: TPAttrInit
- *
- *  Description:
- *      Initializes thread pool attributes.
- *      Sets values to defaults defined in ThreadPool.h.
- *  Parameters:
- *      attr - must be valid thread pool attributes.
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-    int TPAttrInit( ThreadPoolAttr * attr ) {
-        assert( attr != NULL );
-
-        if( attr == NULL ) {
-            return EINVAL;
-        }
-
-        attr->jobsPerThread = DEFAULT_JOBS_PER_THREAD;
-        attr->maxIdleTime = DEFAULT_IDLE_TIME;
-        attr->maxThreads = DEFAULT_MAX_THREADS;
-        attr->minThreads = DEFAULT_MIN_THREADS;
-        attr->schedPolicy = DEFAULT_POLICY;
-        attr->starvationTime = DEFAULT_STARVATION_TIME;
-        attr->maxJobsTotal = DEFAULT_MAX_JOBS_TOTAL;
-        return 0;
-    }
-
-/****************************************************************************
- * Function: TPJobInit
- *
- *  Description:
- *      Initializes thread pool job.
- *      Sets the priority to default defined in ThreadPool.h.
- *      Sets the free_routine to default defined in ThreadPool.h
- *  Parameters:
- *      ThreadPoolJob *job - must be valid thread pool attributes.
- *      start_routine func - function to run, must be valid
- *      void * arg - argument to pass to function.
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-    int TPJobInit( ThreadPoolJob * job,
-                   start_routine func,
-                   void *arg ) {
-        assert( job != NULL );
-        assert( func != NULL );
-
-        if( ( job == NULL ) || ( func == NULL ) ) {
-            return EINVAL;
-        }
-
-        job->func = func;
-        job->arg = arg;
-        job->priority = DEFAULT_PRIORITY;
-        job->free_func = DEFAULT_FREE_ROUTINE;
-        return 0;
-    }
-
-/****************************************************************************
- * Function: TPJobSetPriority
- *
- *  Description:
- *      Sets the max threads for the thread pool attributes.
- *  Parameters:
- *      attr - must be valid thread pool attributes.
- *      maxThreads - value to set
- *  Returns:
- *      Returns 0 on success nonzero on failure.
- *      Returns EINVAL if invalid priority.
- *****************************************************************************/
-    int TPJobSetPriority( ThreadPoolJob * job,
-                          ThreadPriority priority ) {
-        assert( job != NULL );
-
-        if( job == NULL ) {
-            return EINVAL;
-        }
-
-        if( priority == LOW_PRIORITY || priority == MED_PRIORITY ||
-            priority == HIGH_PRIORITY ) {
-            job->priority = priority;
-            return 0;
-        } else {
-            return EINVAL;
-        }
-    }
-
-/****************************************************************************
- * Function: TPJobSetFreeFunction
- *
- *  Description:
- *      Sets the max threads for the thread pool attributes.
- *  Parameters:
- *      attr - must be valid thread pool attributes.
- *      maxThreads - value to set
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-    int TPJobSetFreeFunction( ThreadPoolJob * job,
-                              free_routine func ) {
-        assert( job != NULL );
-
-        if( job == NULL ) {
-            return EINVAL;
-        }
-
-        job->free_func = func;
-        return 0;
-    }
-
-/****************************************************************************
- * Function: TPAttrSetMaxThreads
- *
- *  Description:
- *      Sets the max threads for the thread pool attributes.
- *  Parameters:
- *      attr - must be valid thread pool attributes.
- *      maxThreads - value to set
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-    int TPAttrSetMaxThreads( ThreadPoolAttr * attr,
-                             int maxThreads ) {
-        assert( attr != NULL );
-
-        if( attr == NULL ) {
-            return EINVAL;
-        }
-
-        attr->maxThreads = maxThreads;
-        return 0;
-    }
-
-/****************************************************************************
- * Function: TPAttrSetMinThreads
- *
- *  Description:
- *      Sets the min threads for the thread pool attributes.
- *  Parameters:
- *      attr - must be valid thread pool attributes.
- *      minThreads - value to set
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-    int TPAttrSetMinThreads( ThreadPoolAttr * attr,
-                             int minThreads ) {
-        assert( attr != NULL );
-
-        if( attr == NULL ) {
-            return EINVAL;
-        }
-
-        attr->minThreads = minThreads;
-        return 0;
-    }
-
-/****************************************************************************
- * Function: TPAttrSetIdleTime
- *
- *  Description:
- *      Sets the idle time for the thread pool attributes.
- *  Parameters:
- *      attr - must be valid thread pool attributes.
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-    int TPAttrSetIdleTime( ThreadPoolAttr * attr,
-                           int idleTime ) {
-        assert( attr != NULL );
-
-        if( attr == NULL ) {
-            return EINVAL;
-        }
-
-        attr->maxIdleTime = idleTime;
-        return 0;
-    }
-
-/****************************************************************************
- * Function: TPAttrSetJobsPerThread
- *
- *  Description:
- *      Sets the max thre
- *  Parameters:
- *      attr - must be valid thread pool attributes.
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-    int TPAttrSetJobsPerThread( ThreadPoolAttr * attr,
-                                int jobsPerThread ) {
-        assert( attr != NULL );
-
-        if( attr == NULL ) {
-            return EINVAL;
-        }
-
-        attr->jobsPerThread = jobsPerThread;
-        return 0;
-    }
-
-/****************************************************************************
- * Function: TPAttrSetStarvationTime
- *
- *  Description:
- *      Sets the starvation time for the thread pool attributes.
- *  Parameters:
- *      attr - must be valid thread pool attributes.
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-    int TPAttrSetStarvationTime( ThreadPoolAttr * attr,
-                                 int starvationTime ) {
-        assert( attr != NULL );
-
-        if( attr == NULL ) {
-            return EINVAL;
-        }
-
-        attr->starvationTime = starvationTime;
-        return 0;
-    }
-
-/****************************************************************************
- * Function: TPAttrSetSchedPolicy
- *
- *  Description:
- *      Sets the scheduling policy for the thread pool attributes.
- *  Parameters:
- *      attr - must be valid thread pool attributes.
- *      PolicyType schedPolicy - must be a valid policy type.
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-    int TPAttrSetSchedPolicy( ThreadPoolAttr * attr,
-                              PolicyType schedPolicy ) {
-        assert( attr != NULL );
-        if( attr == NULL ) {
-            return EINVAL;
-        }
-        attr->schedPolicy = schedPolicy;
-        return 0;
-    }
-
-#ifdef STATS
-    void ThreadPoolPrintStats( ThreadPoolStats * stats ) {
-               assert( stats != NULL ); if( stats == NULL ) {
-               return;}
-
-               printf( "ThreadPoolStats at Time: %ld\n", time( NULL ) );
-               printf
-               ( "Average Wait in High Priority Q in milliseconds: %f\n",
-                 stats->avgWaitHQ );
-               printf
-               ( "Average Wait in Med Priority Q in milliseconds: %f\n",
-                 stats->avgWaitMQ );
-               printf
-               ( "Averate Wait in Low Priority Q in milliseconds: %f\n",
-                 stats->avgWaitLQ );
-               printf( "Max Threads Active: %d\n", stats->maxThreads );
-               printf( "Current Worker Threads: %d\n",
-                       stats->workerThreads );
-               printf( "Current Persistent Threads: %d\n",
-                       stats->persistentThreads );
-               printf( "Current Idle Threads: %d\n", stats->idleThreads );
-               printf( "Total Threads : %d\n", stats->totalThreads );
-               printf( "Total Time spent Working in seconds: %f\n",
-                       stats->totalWorkTime );
-               printf( "Total Time spent Idle in seconds : %f\n",
-                       stats->totalIdleTime );}
-#endif
-
- /****************************************************************************
- * Function: TPAttrSetMaxJobsTotal
- *
- *  Description:
- *      Sets the maximum number jobs that can be qeued totally.
- *  Parameters:
- *      attr - must be valid thread pool attributes.
- *      maxJobsTotal - maximum number of jobs
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-    int TPAttrSetMaxJobsTotal( ThreadPoolAttr * attr,
-                               int  maxJobsTotal ) {
-        assert( attr != NULL );
-
-        if( attr == NULL ) {
-            return EINVAL;
-        }
-
-        attr->maxJobsTotal = maxJobsTotal;
-        return 0;
-    }
-
-/****************************************************************************
- * Function: ThreadPoolGetStats
- *
- *  Description:
- *      Returns various statistics about the
- *      thread pool.
- *      Only valid if STATS has been defined.
- *  Parameters:
- *      ThreadPool *tp - valid initialized threadpool
- *      ThreadPoolStats *stats - valid stats, out parameter
- *  Returns:
- *      Always returns 0.
- *****************************************************************************/
-#ifdef STATS
-int
-                   ThreadPoolGetStats( ThreadPool * tp,
-                                       ThreadPoolStats * stats ) {
-
-                   assert( tp != NULL );
-                   assert( stats != NULL );
-                   if( ( tp == NULL ) || ( stats == NULL ) ) {
-                   return EINVAL;}
-
-                   //if not shutdown then acquire mutex
-                   if( !tp->shutdown ) {
-                   ithread_mutex_lock( &tp->mutex );}
-
-                   ( *stats ) = tp->stats; if( stats->totalJobsHQ > 0 )
-                   stats->avgWaitHQ =
-                   stats->totalTimeHQ / stats->totalJobsHQ;
-                   else
-                   stats->avgWaitHQ = 0; if( stats->totalJobsMQ > 0 )
-                   stats->avgWaitMQ =
-                   stats->totalTimeMQ / stats->totalJobsMQ;
-                   else
-                   stats->avgWaitMQ = 0; if( stats->totalJobsLQ > 0 )
-                   stats->avgWaitLQ =
-                   stats->totalTimeLQ / stats->totalJobsLQ;
-                   else
-                   stats->avgWaitLQ = 0;
-                   stats->totalThreads = tp->totalThreads;
-                   stats->persistentThreads = tp->persistentThreads;
-                   stats->currentJobsHQ = ListSize( &tp->highJobQ );
-                   stats->currentJobsLQ = ListSize( &tp->lowJobQ );
-                   stats->currentJobsMQ = ListSize( &tp->medJobQ );
-                   //if not shutdown then release mutex
-                   if( !tp->shutdown ) {
-                   ithread_mutex_unlock( &tp->mutex );}
-
-                   return 0;}
-
-#endif
diff --git a/tombupnp/threadutil/src/TimerThread.c b/tombupnp/threadutil/src/TimerThread.c
deleted file mode 100644
index 46d6e15..0000000
--- a/tombupnp/threadutil/src/TimerThread.c
+++ /dev/null
@@ -1,528 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include "TimerThread.h"
-#include <assert.h>
-
-/****************************************************************************
- * Function: FreeTimerEvent
- *
- *  Description:
- *      Deallocates a dynamically allocated TimerEvent.
- *  Parameters:
- *      TimerEvent *event - must be allocated with CreateTimerEvent
- *****************************************************************************/
-static void
-FreeTimerEvent( TimerThread * timer,
-                TimerEvent * event )
-{
-
-    assert( timer != NULL );
-
-    FreeListFree( &timer->freeEvents, event );
-}
-
-/****************************************************************************
- * Function: TimerThreadWorker
- *
- *  Description:
- *      Implements timer thread.
- *      Waits for next event to occur and schedules
- *      associated job into threadpool.
- *      Internal Only.
- *  Parameters:
- *      void * arg -> is cast to TimerThread *
- *****************************************************************************/
-static void *
-TimerThreadWorker( void *arg )
-{
-    TimerThread *timer = ( TimerThread * ) arg;
-    ListNode *head = NULL;
-
-    TimerEvent *nextEvent = NULL;
-
-    time_t currentTime = 0;
-    time_t nextEventTime = 0;
-    struct timespec timeToWait;
-
-    int tempId;
-
-    assert( timer != NULL );
-
-    ithread_mutex_lock( &timer->mutex );
-
-    while( 1 )
-    {
-
-        //mutex should always be locked at top of loop
-
-        //Check for shutdown
-
-        if( timer->shutdown )
-        {
-
-            timer->shutdown = 0;
-            ithread_cond_signal( &timer->condition );
-            ithread_mutex_unlock( &timer->mutex );
-            return NULL;
-
-        }
-
-        nextEvent = NULL;
-
-        //Get the next event if possible
-        if( timer->eventQ.size > 0 )
-        {
-            head = ListHead( &timer->eventQ );
-
-            nextEvent = ( TimerEvent * ) head->item;
-            nextEventTime = nextEvent->eventTime;
-        }
-
-        currentTime = time( NULL );
-
-        //If time has elapsed, schedule job
-
-        if( ( nextEvent != NULL ) && ( currentTime >= nextEventTime ) )
-        {
-
-            if( nextEvent->persistent ) {
-
-                if (ThreadPoolAddPersistent( timer->tp, &nextEvent->job,
-                                         &tempId ) != 0) {
-                    if (nextEvent->job.arg != NULL &&
-                            nextEvent->job.free_func != NULL) {
-                        nextEvent->job.free_func(nextEvent->job.arg);
-                    }
-                }
-            } else {
-                if (ThreadPoolAdd( timer->tp, &nextEvent->job, &tempId ) != 0) {
-                    if (nextEvent->job.arg != NULL &&
-                            nextEvent->job.free_func != NULL) {
-                        nextEvent->job.free_func(nextEvent->job.arg);
-                    }
-                }
-            }
-
-            ListDelNode( &timer->eventQ, head, 0 );
-            FreeTimerEvent( timer, nextEvent );
-
-            continue;
-
-        }
-
-        if( nextEvent != NULL ) {
-            timeToWait.tv_nsec = 0;
-            timeToWait.tv_sec = nextEvent->eventTime;
-
-            ithread_cond_timedwait( &timer->condition, &timer->mutex,
-                                    &timeToWait );
-
-        } else {
-            ithread_cond_wait( &timer->condition, &timer->mutex );
-        }
-
-    }
-}
-
-/****************************************************************************
- * Function: CalculateEventTime
- *
- *  Description:
- *      Calculates the appropriate timeout in absolute seconds since
- *      Jan 1, 1970
- *      Internal Only.
- *  Parameters:
- *      time_t *timeout - timeout
- *      
- *****************************************************************************/
-static int
-CalculateEventTime( time_t * timeout,
-                    TimeoutType type )
-{
-    time_t now;
-
-    assert( timeout != NULL );
-
-    if( type == ABS_SEC )
-        return 0;
-    else if( type == REL_SEC ) {
-        time( &now );
-        ( *timeout ) += now;
-        return 0;
-    }
-
-    return -1;
-
-}
-
-/****************************************************************************
- * Function: CreateTimerEvent
- *
- *  Description:
- *      Creates a Timer Event. (Dynamically allocated)
- *      Internal to timer thread.
- *  Parameters:
- *      func - thread function to run.
- *      arg - argument to function.
- *      priority - priority of job.
- *      eventTime - the absoule time of the event
- *                  in seconds from Jan, 1970
- *      id - id of job
- *      
- *  Returns:
- *      TimerEvent * on success, NULL on failure.
- ****************************************************************************/
-static TimerEvent *
-CreateTimerEvent( TimerThread * timer,
-                  ThreadPoolJob * job,
-                  Duration persistent,
-                  time_t eventTime,
-                  int id )
-{
-    TimerEvent *temp = NULL;
-
-    assert( timer != NULL );
-    assert( job != NULL );
-
-    temp = ( TimerEvent * ) FreeListAlloc( &timer->freeEvents );
-    if( temp == NULL )
-        return temp;
-    temp->job = ( *job );
-    temp->persistent = persistent;
-    temp->eventTime = eventTime;
-    temp->id = id;
-
-    return temp;
-}
-
-/************************************************************************
- * Function: TimerThreadInit
- * 
- *  Description:
- *     Initializes and starts timer thread.
- *
- *  Parameters:
- *             timer - valid timer thread pointer.
- *             tp  - valid thread pool to use. Must be
- *                   started. Must be valid for lifetime
- *                   of timer.  Timer must be shutdown
- *                   BEFORE thread pool.
- *  Return:
- *            0 on success, nonzero on failure
- *            Returns error from ThreadPoolAddPersistent if failure.
- ************************************************************************/
-int
-TimerThreadInit( TimerThread * timer,
-                 ThreadPool * tp )
-{
-
-    int rc = 0;
-
-    ThreadPoolJob timerThreadWorker;
-
-    assert( timer != NULL );
-    assert( tp != NULL );
-
-    if( ( timer == NULL ) || ( tp == NULL ) ) {
-        return EINVAL;
-    }
-
-    rc += ithread_mutex_init( &timer->mutex, NULL );
-
-    assert( rc == 0 );
-
-    rc += ithread_mutex_lock( &timer->mutex );
-    assert( rc == 0 );
-
-    rc += ithread_cond_init( &timer->condition, NULL );
-    assert( rc == 0 );
-
-    rc += FreeListInit( &timer->freeEvents, sizeof( TimerEvent ), 100 );
-    assert( rc == 0 );
-
-    timer->shutdown = 0;
-    timer->tp = tp;
-    timer->lastEventId = 0;
-    rc += ListInit( &timer->eventQ, NULL, NULL );
-
-    assert( rc == 0 );
-
-    if( rc != 0 ) {
-        rc = EAGAIN;
-    } else {
-
-        TPJobInit( &timerThreadWorker, TimerThreadWorker, timer );
-        TPJobSetPriority( &timerThreadWorker, HIGH_PRIORITY );
-
-        rc = ThreadPoolAddPersistent( tp, &timerThreadWorker, NULL );
-    }
-
-    ithread_mutex_unlock( &timer->mutex );
-
-    if( rc != 0 ) {
-        ithread_cond_destroy( &timer->condition );
-        ithread_mutex_destroy( &timer->mutex );
-        FreeListDestroy( &timer->freeEvents );
-        ListDestroy( &timer->eventQ, 0 );
-    }
-
-    return rc;
-
-}
-
-/************************************************************************
- * Function: TimerThreadSchedule
- * 
- *  Description:
- *     Schedules an event to run at a specified time.
- *
- *  Parameters:
- *             timer - valid timer thread pointer.
- *             time_t - time of event.
- *                      either in absolute seconds,
- *                      or relative seconds in the future.
- *             timeoutType - either ABS_SEC, or REL_SEC.
- *                           if REL_SEC, then the event
- *                           will be scheduled at the
- *                           current time + REL_SEC.
- *             
- *             func - function to schedule
- *             arg - argument to function
- *             priority - priority of job.
- *             id - id of timer event. (out)
- *  Return:
- *            0 on success, nonzero on failure
- *			  EOUTOFMEM if not enough memory to schedule job
- ************************************************************************/
-int
-TimerThreadSchedule( TimerThread * timer,
-                     time_t timeout,
-                     TimeoutType type,
-                     ThreadPoolJob * job,
-                     Duration duration,
-                     int *id )
-{
-
-    int rc = EOUTOFMEM;
-    int found = 0;
-    int tempId = 0;
-
-    ListNode *tempNode = NULL;
-    TimerEvent *temp = NULL;
-    TimerEvent *newEvent = NULL;
-
-    assert( timer != NULL );
-    assert( job != NULL );
-
-    if( ( timer == NULL ) || ( job == NULL ) ) {
-        return EINVAL;
-    }
-
-    CalculateEventTime( &timeout, type );
-    ithread_mutex_lock( &timer->mutex );
-
-    if( id == NULL )
-        id = &tempId;
-
-    ( *id ) = INVALID_EVENT_ID;
-
-    newEvent = CreateTimerEvent( timer, job, duration, timeout,
-                                 timer->lastEventId );
-
-    if( newEvent == NULL ) {
-        ithread_mutex_unlock( &timer->mutex );
-        return rc;
-    }
-
-    tempNode = ListHead( &timer->eventQ );
-    //add job to Q
-    //Q is ordered by eventTime
-    //with the head of the Q being the next event
-
-    while( tempNode != NULL ) {
-        temp = ( TimerEvent * ) tempNode->item;
-        if( temp->eventTime >= timeout )
-        {
-
-            if( ListAddBefore( &timer->eventQ, newEvent, tempNode ) !=
-                NULL )
-                rc = 0;
-            found = 1;
-            break;
-
-        }
-        tempNode = ListNext( &timer->eventQ, tempNode );
-    }
-
-    //add to the end of Q
-    if( !found ) {
-
-        if( ListAddTail( &timer->eventQ, newEvent ) != NULL )
-            rc = 0;
-
-    }
-    //signal change in Q
-    if( rc == 0 ) {
-
-        ithread_cond_signal( &timer->condition );
-    } else {
-        FreeTimerEvent( timer, newEvent );
-    }
-    ( *id ) = timer->lastEventId++;
-    ithread_mutex_unlock( &timer->mutex );
-
-    return rc;
-}
-
-/************************************************************************
- * Function: TimerThreadRemove
- * 
- *  Description:
- *     Removes an event from the timer Q.
- *     Events can only be removed 
- *     before they have been placed in the
- *     thread pool.
- *
- *  Parameters:
- *             timer - valid timer thread pointer.
- *             id - id of event to remove.
- *             out - space for returned job (Can be NULL)
- *  Return:
- *            0 on success.
- *            INVALID_EVENT_ID on error.
- *
- ************************************************************************/
-int
-TimerThreadRemove( TimerThread * timer,
-                   int id,
-                   ThreadPoolJob * out )
-{
-    int rc = INVALID_EVENT_ID;
-    ListNode *tempNode = NULL;
-    TimerEvent *temp = NULL;
-
-    assert( timer != NULL );
-
-    if( timer == NULL ) {
-        return EINVAL;
-    }
-
-    ithread_mutex_lock( &timer->mutex );
-
-    tempNode = ListHead( &timer->eventQ );
-
-    while( tempNode != NULL ) {
-        temp = ( TimerEvent * ) tempNode->item;
-        if( temp->id == id )
-        {
-
-            ListDelNode( &timer->eventQ, tempNode, 0 );
-            if( out != NULL )
-                ( *out ) = temp->job;
-            FreeTimerEvent( timer, temp );
-            rc = 0;
-            break;
-        }
-        tempNode = ListNext( &timer->eventQ, tempNode );
-    }
-
-    ithread_mutex_unlock( &timer->mutex );
-    return rc;
-}
-
-/************************************************************************
- * Function: TimerThreadShutdown
- * 
- *  Description:
- *    Shutdown the timer thread
- *    Events scheduled in the future will NOT be run.
- *    Timer thread should be shutdown BEFORE it's associated
- *    thread pool.
- *  Returns:
- *    returns 0 if succesfull,
- *            nonzero otherwise.
- *            Always returns 0.
- ***********************************************************************/
-int
-TimerThreadShutdown( TimerThread * timer )
-{
-    ListNode *tempNode2 = NULL;
-    ListNode *tempNode = NULL;
-
-    assert( timer != NULL );
-
-    if( timer == NULL ) {
-        return EINVAL;
-    }
-
-    ithread_mutex_lock( &timer->mutex );
-
-    timer->shutdown = 1;
-    tempNode = ListHead( &timer->eventQ );
-
-    //Delete nodes in Q
-    //call registered free function 
-    //on argument
-    while( tempNode != NULL ) {
-        TimerEvent *temp = ( TimerEvent * ) tempNode->item;
-
-        tempNode2 = ListNext( &timer->eventQ, tempNode );
-        ListDelNode( &timer->eventQ, tempNode, 0 );
-        if( temp->job.free_func ) {
-            temp->job.free_func( temp->job.arg );
-        }
-        FreeTimerEvent( timer, temp );
-        tempNode = tempNode2;
-    }
-
-    ListDestroy( &timer->eventQ, 0 );
-    FreeListDestroy( &timer->freeEvents );
-
-    ithread_cond_broadcast( &timer->condition );
-
-    while( timer->shutdown )    //wait for timer thread to shutdown
-    {
-        ithread_cond_wait( &timer->condition, &timer->mutex );
-    }
-
-    ithread_mutex_unlock( &timer->mutex );
-
-    //destroy condition
-    while( ithread_cond_destroy( &timer->condition ) != 0 ) {
-    }
-
-    //destroy mutex
-    while( ithread_mutex_destroy( &timer->mutex ) != 0 ) {
-    }
-
-    return 0;
-}
diff --git a/tombupnp/threadutil/src/iasnprintf.c b/tombupnp/threadutil/src/iasnprintf.c
deleted file mode 100644
index f1529d2..0000000
--- a/tombupnp/threadutil/src/iasnprintf.c
+++ /dev/null
@@ -1,152 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include <stdarg.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "iasnprintf.h"
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifdef WIN32
- #define vsnprintf _vsnprintf
-#endif
-
-/**
- * Allocates enough memory for the
- * Formatted string, up to max
- * specified.
- * With max set to -1, it allocates as
- * much size as needed.
- * Memory must be freed using free.
- */
-
-int
-iasnprintf( char **ret,
-            int incr,
-            int max,
-            const char *fmt,
-            ... )
-{
-    int size = incr;
-    int retc = 0;
-    va_list ap;
-    char *temp = NULL;
-
-    assert( ret );
-    assert( fmt );
-    ( *ret ) = ( char * )malloc( incr );
-
-    if( ( *ret ) == NULL ) return -1;
-
-    while( 1 ) {
-        va_start( ap, fmt );
-        retc = vsnprintf( ( *ret ), size, fmt, ap );
-        va_end( ap );
-
-        if( retc < 0 ) {
-            //size not big enough
-            //and vsnprintf does NOT return the
-            //necessary number of bytes
-            if( ( max != -1 ) && ( size == max ) )  //max reached
-            {
-                break;
-            }
-
-            incr *= 2;          //increase increment
-            //increase size and try again  
-            if( ( max != -1 ) && ( ( size + incr ) > max ) ) {
-                incr = ( max - size );
-            }
-
-            temp = ( char * )realloc( ( *ret ), size + incr );
-            if( temp == NULL ) {
-                break;
-            }
-            size += incr;
-            ( *ret ) = temp;
-
-        } else {
-            if( ( retc + 1 ) > size ) {
-                //size not big enough
-                //and vsnprintf 
-                //returns the necessary 
-                //number of bytes
-                if( ( max != -1 ) && ( retc + 1 > max ) ) {
-                    retc = -1;
-                    break;
-                }
-
-                temp = ( char * )realloc( ( *ret ), retc + 1 );
-                if( temp == NULL ) {
-                    retc = -1;
-                    break;
-                }
-                size = retc + 1;
-                ( *ret ) = temp;    //size increased try again
-            } else if( ( retc + 1 ) < size ) {
-                //size is bigger than needed
-                //try and reallocate smaller
-
-                temp = ( char * )realloc( ( *ret ), retc + 1 );
-                if( temp != NULL ) {
-                    ( *ret ) = temp;
-                }
-                break;
-            } else              //size is just right, exit
-            {
-                break;
-            }
-
-        }
-    }
-
-    if( retc < 0 ) {
-        free( ( *ret ) );
-        ( *ret ) = NULL;
-    }
-
-    return retc;
-}
-
-void
-iasnprintfFree( char *fChar )
-{
-    free( fChar );
-    fChar = NULL;
-}
diff --git a/tombupnp/upnp/doc/callback.dxx b/tombupnp/upnp/doc/callback.dxx
deleted file mode 100644
index 7823a16..0000000
--- a/tombupnp/upnp/doc/callback.dxx
+++ /dev/null
@@ -1,13 +0,0 @@
-/**@name About Callbacks
- *
- * The Linux SDK for UPnP Devices contains functions that generate 
- * asynchronous callbacks. To simplify the application callback functions, 
- * these callbacks are executed on a thread owned by the SDK itself.  The 
- * SDK executes the application's callback function in a thread 
- * context so the application can allocate memory and preserve the information
- * it needs. The application can also use standard thread synchronization 
- * methods to ensure data integrity.  Due to the possibility of deadlock, the 
- * application cannot call back into the SDK during these callbacks 
- * unless explicitly noted.  There is no restriction in calling into the 
- * operating system or any other application interfaces.
- */
diff --git a/tombupnp/upnp/doc/docxx.sty b/tombupnp/upnp/doc/docxx.sty
deleted file mode 100644
index f876b51..0000000
--- a/tombupnp/upnp/doc/docxx.sty
+++ /dev/null
@@ -1,1082 +0,0 @@
-%  docxx.sty
-%
-%  Copyright (c) 1996 Roland Wunderling, Malte Zoeckler
-%  Copyright (c) 1999-2001 Dragos Acostachioaie
-%
-%  This file is part of DOC++.
-%
-%  DOC++ is free software; you can redistribute it and/or
-%  modify it under the terms of the GNU General Public
-%  License as published by the Free Software Foundation; either
-%  version 2 of the license, or (at your option) any later version.
-%
-%  This program is distributed in the hope that it will be useful,
-%  but WITHOUT ANY WARRANTY; without even the implied warranty of
-%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%  General Public License for more details.
-%
-%  You should have received a copy of the GNU General Public
-%  License along with this program; if not, write to the Free
-%  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-%
-%
-% Switch off special characters except {}\ for the rest of the text.
-%
-\def\cxxtilde{{\tt\~\relax}}
-\addtolength{\parskip}{6pt}
-
-\catcode`\,=\active%
-\def,{\char`\,\penalty-8\ }
-%\def,{++ }
-\catcode`\,=12
-
-\def\<{{\tt <}}
-\def\>{{\tt >}}
-\def\TEX{}
-\def\cxxExceptionsStr{}
-\def\cxxParameterStr{}
-\def\cxxReturnStr{}
-\def\cxxInvariantsStr{}
-\def\cxxPreconditionsStr{}
-\def\cxxPostconditionsStr{}
-\def\cxxSeeStr{}
-\def\cxxAuthorStr{}
-\def\cxxVersionStr{}
-\def\cxxDeprecatedStr{}
-\def\cxxSinceStr{}
-\def\cxxFileStr{}
-\def\cxxExceptions#1{\def\cxxExceptionsStr{#1}}
-\def\cxxParameter#1{\def\cxxParameterStr{#1}}
-\def\cxxReturn#1{\def\cxxReturnStr{#1}}
-\def\cxxInvariants#1{\def\cxxInvariantsStr{#1}}
-\def\cxxPreconditions#1{\def\cxxPreconditionsStr{#1}}
-\def\cxxPostconditions#1{\def\cxxPostconditionsStr{#1}}
-\def\cxxSee#1{\def\cxxSeeStr{#1}}
-\def\cxxAuthor#1{\def\cxxAuthorStr{#1}}
-\def\cxxVersion#1{\def\cxxVersionStr{#1}}
-\def\cxxDeprecated#1{\def\cxxDeprecatedStr{#1}}
-\def\cxxSince#1{\def\cxxSinceStr{#1}}
-\def\cxxFile#1{\def\cxxFileStr{#1}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% Define ... to do verbatim listing
-%
-\catcode`\=\active
-\catcode`\=\active
-{\obeyspaces\gdef {\ }}
-
-\def\ccverbatim{\strut\begingroup
-	    \catcode`\\=12 \catcode`\{=12
-	    \catcode`\}=12 \catcode`\$=12
-	    \catcode`\&=12 \catcode`\#=12
-	    \catcode`\%=12 \catcode`\~=12
-	    \catcode`\_=12 \catcode`\^=12
-	    \catcode`\|=12 \catcode`\/=12
-	    \obeyspaces\tt}
-\def{\let\par=\endgraf \ccverbatim \parskip=0pt \ccfinish}
-{\catcode`\=0 catcode`\=12
-gdefccfinish#1{#1endgroup}}
-
-%
-% Definition of structuring comands.
-%
-\newcommand{\Section}[1]{\section{#1}}
-\newcommand{\SubSection}[1]{\subsection{#1}}
-\newcommand{\SubSubSection}[1]{\subsubsection{#1}}
-\newcommand{\Paragraph}[1]{\paragraph{#1}}
-
-\newcommand{\Ref}[1]{{\bf #1} ($\rightarrow$ \ref{#1})}
-\newcommand{\URL}[2][]{%
-   \def\name{#1}%
-   \def\empty{}%
-   \ifx\name\empty%
-	{\tt #2}%
-   \else%
-	#1 ({\tt #2})%
-   \fi%
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% printing line #1 of code #2
-%
-\newdimen\cxxcodewidth
-\cxxcodewidth=\textwidth
-\advance\cxxcodewidth by -21pt
-
-\def\cxxCodeLine#1#2{%
-{\hbox to 20pt{\tiny\hss#1}\parbox[t]{\cxxcodewidth}{\small#2}}%
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for listing manual entries
-%
-\newdimen\cxxIdWidth
-\newdimen\cxxTypeWidth
-\newdimen\cxxProtoWidth
-\newdimen\cxxMemoWidth
-\newdimen\cxxPageWidth
-
-\cxxIdWidth=0.1\textwidth
-\cxxTypeWidth=0.15\textwidth
-\cxxProtoWidth=0.25\textwidth
-\cxxMemoWidth=0.43\textwidth
-
-\cxxPageWidth=\textwidth
-\advance\cxxPageWidth by-\cxxIdWidth
-\advance\cxxPageWidth by-\cxxTypeWidth
-\advance\cxxPageWidth by-\cxxProtoWidth
-\advance\cxxPageWidth by-\cxxMemoWidth
-
-\newdimen\cxxProtoMemoWidth
-\cxxProtoMemoWidth=\cxxProtoWidth
-\advance\cxxProtoMemoWidth by\cxxMemoWidth
-
-\def\cxxStrut{\vrule width0pt height0pt depth9pt}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% 1: type
-% 2: name
-% 3: args
-% 4: memo
-% 5: id
-\def\cxxitem#1#2#3#4#5{\noindent{%
-    \setbox5\hbox{#5 }%
-    \ifdim\wd5>\cxxIdWidth%
-	\setbox5\hbox{\hbox to \cxxIdWidth{\hss#5}}%
-    \else
-	\setbox5\hbox{\hbox to \cxxIdWidth{#5\hss}}%
-    \fi%
-    \setbox1\hbox{{%
-	\catcode`\&=4%
-	\catcode`\_=8%
-	\def{\ccverbatim \ccfinish}#1%
-    }}%
-    \setbox2\hbox{{%
-	\catcode`\&=4%
-	\catcode`\_=8%
-	\def{\ccverbatim \ccfinish}\textbf{#2} #3%
-    }}%
-    \setbox4\hbox{\parbox[t]{\cxxMemoWidth}{{%
-	\raggedright\sloppy%
-	\catcode`\&=4%
-	\catcode`\_=8%
-	\def{\ccverbatim \ccfinish}{\em #4}
-	\cxxStrut%
-	\def\page{#5}%
-	\ifx\page\empty%
-	    \hss%
-	\else%
-	    \ \dotfill%
-	    \hbox to 0pt{\hbox to \cxxPageWidth{\hss%
-		\pageref{cxx.#5}%
-	    }\hss}%
-	\fi%
-    }}}%
-    %
-    \ifdim\wd1>\cxxTypeWidth%
-	\hbox to \hsize{\unhbox5\hbox to \cxxTypeWidth{\unhbox1\hss}\hss}\\\nopagebreak%
-	\setbox5\hbox{\hskip\cxxIdWidth}%
-	\setbox1\hbox{\hskip\cxxTypeWidth}%
-    \else%
-	\setbox1\hbox{\hbox to \cxxTypeWidth{\unhbox1\hss}}%
-    \fi%
-    \ifdim\wd2>\cxxProtoWidth%
-	\ifdim\wd2<\cxxProtoMemoWidth%
-	    \def\tmp{#4}%
-	    \ifx\tmp\empty%
-		\def\tmp{#5}%
-		\ifx\tmp\empty%
-		    \hbox to \hsize{\unhbox5\unhbox1\unhbox2\hss\cxxStrut}\\%
-		\else%
-		    \hbox to \hsize{\unhbox5\unhbox1\unhbox2
-			\dotfill\hbox to \cxxPageWidth{\hss\pageref{cxx.#5}}%
-			\cxxStrut}\\%
-		\fi%
-	    \else%
-		\hbox to \hsize{\unhbox5\unhbox1\unhbox2\hss}\\\nopagebreak%
-		\hbox to \hsize{%
-		    \hskip\cxxIdWidth%
-		    \hskip\cxxTypeWidth%
-		    \hskip\cxxProtoWidth%
-		    \unhbox4\hss%
-		}\\%
-	    \fi%
-	\else%
-	    \hbox to \hsize{%
-		\unhbox5%
-		\unhbox1%
-		\parbox[t]{\cxxProtoMemoWidth}{%
-		    \setbox255\hbox{\textbf{#2} (}%
-		    \hangindent=\wd255\hangafter=1%
-		    \raggedright\sloppy%
-		    {\catcode`\&=4\catcode`\_=8%
-			\def{\ccverbatim \ccfinish}\textbf{#2} #3\strut}%
-		}\hss%
-	    }\\\nopagebreak%
-	    \hbox to \hsize{%
-		\hskip\cxxIdWidth%
-		\hskip\cxxTypeWidth%
-		\hskip\cxxProtoWidth%
-		\unhbox4\hss%
-	    }\\%
-	\fi%
-    \else%
-	\hbox to \hsize{%
-	    \unhbox5%
-	    \unhbox1%
-	    \hbox to \cxxProtoWidth{\unhbox2\hss}%
-	    \unhbox4\hss%
-	}\\%
-    \fi%
-}}
-
-
-\newdimen\cxxtypestart
-\cxxtypestart=0.05\textwidth
-%\advance\cxxtypestart by \labelsep
-
-\newdimen\cxxnamestart
-\cxxnamestart=\cxxtypestart
-\advance\cxxnamestart by 0.25\textwidth
-
-\newdimen\cxxargsstart
-\cxxargsstart=\cxxnamestart
-\advance\cxxargsstart by 0.2\textwidth
-\newdimen\cxxargswidth
-\cxxargswidth=\textwidth
-\advance\cxxargswidth by -\cxxargsstart
-\advance\cxxargswidth by -\spaceskip
-
-\newdimen\cxxmemostart
-\cxxmemostart=\cxxargsstart
-\advance\cxxmemostart by 0.12\textwidth
-
-\newenvironment{cxxlist}[1]{
-\begingroup
-\catcode`\,=\active%
-\paragraph{#1}\strut\smallskip\\
-}{
-\endgroup
-}
-
-\newenvironment{cxxnames}{\begin{cxxlist}{Names}}{\end{cxxlist}}
-\newenvironment{cxxpublic}{\begin{cxxlist}{Public Members}}{\end{cxxlist}}
-\newenvironment{cxxprivate}{\begin{cxxlist}{Private Members}}{\end{cxxlist}}
-\newenvironment{cxxprotected}{\begin{cxxlist}{Protected Members}}{\end{cxxlist}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%	Numbered Frame box
-%
-\newlength{\cxxBoxLen}%
-\newlength{\cxxBoxHt}%
-\newlength{\cxxBoxDp}%
-\newlength{\cxxSideHt}%
-\newlength{\cxxSideLen}%
-\newlength{\cxxTitleLen}%
-\def\empty{}
-\def\idPos{1cm}
-
-%
-% box with id and name [optional width]
-%
-\newcommand{\aBox}[3][1pt]{{%
-\small%
-\def\width{#1}%
-\def\num{#2}%
-\def\name{#3}%
-\setbox0\hbox{\hskip\width{ \strut\name\strut} \hskip\width}%
-%
-\setlength{\cxxBoxLen}{\wd0}%
-\addtolength{\cxxBoxLen}{\width}%
-\addtolength{\cxxBoxLen}{\width}%
-\setbox2\hbox{\normalsize\strut\rule{\cxxBoxLen}{\width}}%
-%
-\ifx\num\empty%
-    \setbox1\hbox{\strut}%
-\else%
-    \setbox1\hbox{\rule{\idPos}{\width} { \sf\bf\strut #2 } }%
-\fi%
-\addtolength{\cxxBoxLen}{-\wd1}%
-\setbox1\hbox{\unhbox1\rule{\cxxBoxLen}{\width}}%
-%
-\setlength{\cxxSideHt}{\dp0}%
-\addtolength{\cxxSideHt}{\width}%
-\setlength{\cxxSideLen}{\dp0}%
-\addtolength{\cxxSideLen}{\ht0}%
-\addtolength{\cxxSideLen}{\dp1}%
-\addtolength{\cxxSideLen}{\width}%
-\addtolength{\cxxSideLen}{\width}%
-\setbox3\hbox{\hbox to 0pt{\hss\rule[-\cxxSideHt]{\width}{\cxxSideLen}}}%
-\setbox4\hbox{\hbox to 0pt{\rule[-\cxxSideHt]{\width}{\cxxSideLen}\hss}}%
-%
-\setlength{\cxxBoxHt}{\dp1}%
-\addtolength{\cxxBoxHt}{1pt}%
-\setlength{\cxxBoxDp}{\ht2}%
-\addtolength{\cxxBoxDp}{-\width}%
-\addtolength{\cxxBoxDp}{1pt}%
-%
-\setlength{\cxxBoxLen}{\ht3}%
-\addtolength{\cxxBoxLen}{\ht1}%
-%
-\vbox to \cxxBoxLen{%
-\hbox{\unhbox1}%
-\vskip-\cxxBoxHt%
-\hbox{\hskip\width\unhbox3\unhbox0\unhbox4}%
-%\vskip-\ht2%
-\vskip-\cxxBoxDp%
-\hbox{\unhbox2}%
-\vss%
-}%
-}}
-
-%
-% box with id and name [optional width] of size #4
-%
-\newcommand{\sizeBox}[4][3pt]{{%
-    \setbox0\hbox{ }%
-    \setlength{\cxxSideLen}{#4}%
-    \addtolength{\cxxSideLen}{-\wd0}%
-    \addtolength{\cxxSideLen}{-\wd0}%
-    \addtolength{\cxxSideLen}{-#1}%
-    \addtolength{\cxxSideLen}{-#1}%
-    \addtolength{\cxxSideLen}{-#1}%
-    \addtolength{\cxxSideLen}{-#1}%
-    \aBox[#1]{#2}{\hbox to \cxxSideLen{#3}}%
-}}
-
-%
-% centered box with id and name [optional width] of size #4
-%
-\newcommand{\cBox}[4][3pt]{{%
-\setbox0\hbox{\aBox[#1]{#2}{#3}}%
-\ifdim\wd0<#4%
-    \sizeBox[#1]{#2}{\hss#3\hss}{#4}%
-\else%
-    \setlength{\cxxSideLen}{\wd0}%
-    \advance\cxxSideLen by -#4%
-    \hskip -0.5\cxxSideLen%
-    \unhbox0%
-\fi%
-}}
-
-%
-% right expanding box with id and name [optional width] of size at least #4
-%
-\newcommand{\rBox}[4][3pt]{{%
-\setbox0\hbox{\aBox[#1]{#2}{#3}\hss}%
-\ifdim\wd0>#4%
-    \unhbox0%
-\else%
-    \sizeBox[#1]{#2}{\hss#3\hss}{#4}%
-\fi%
-}}
-
-%
-% left expanding box with id and name [optional width] of size at least #4
-%
-\newcommand{\lBox}[4][3pt]{{%
-\setbox0\hbox{\aBox[#1]{#2}{#3}\hss}%
-\ifdim\wd0>#4%
-    \setlength{\cxxSideLen}{\wd0}%
-    \advance\cxxSideLen by -#4%
-    \hskip -\cxxSideLen%
-    \unhbox0%
-\else%
-    \sizeBox[#1]{#2}{\hss#3\hss}{#4}%
-\fi%
-}}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%	Pagestyle for documentation.
-%
-\newsavebox{\cxxHeadName}
-\newcommand{\ps at docxx}{%
-    \renewcommand{\@oddhead}{\headlinetext}%
-    \renewcommand{\@evenhead}{\headlinetext}%
-    \renewcommand{\@oddfoot}{\footlinetext}%
-    \renewcommand{\@evenfoot}{\footlinetext}%
-}
-\newcommand{\makeHeadLine}[2]{
-    \global\sbox{\cxxHeadName}{\vbox to 0pt{\vss%
-	\hbox to \textwidth{%
-	    \hbox to 0pt{\strut\hbox to 1cm{\hss}\quad#1\hss}%
-	    \hfil#2\hfil%
-	}%
-	\vskip 1pt%
-	\hbox to \textwidth{\hrulefill}%
-    }}%
-}
-\newcommand{\headlinetext}{\usebox{\cxxHeadName}}
-\providecommand{\cxxCopyright}{%
-    \vtop{%
-	\hbox to \textwidth{{
-	    \tiny\sf This page was generated with the help of DOC++
-	\hss}}%
-	\vskip -20pt
-	\hbox to \textwidth{
-	    \hbox{{\tiny\sf http://docpp.sourceforge.net}}
-	\hss}%
-    }%
-}
-\def\footlinetext{\hbox to \textwidth{
-    \vtop{%
-	\hbox to \textwidth{\hrulefill}%
-	\vskip -20pt%
-	\cxxCopyright%
-    }%
-    \hss\vtop{\vskip 10pt\hbox{\today\hspace*{3cm}\textrm{\thepage} }}
-}}
-\pagestyle{docxx}
-
-\def\cxxTitle#1#2#3#4#5{\noindent{%
-    \thispagestyle{empty}
-    \vfill
-    \begin{center}
-    \Huge\bf
-    \catcode`\&=4%
-    \catcode`\_=8%
-    \def{\ccverbatim \ccfinish}#1%
-    \strut\\
-    \def{\ccverbatim \ccfinish}#2%
-    \strut\\
-    \def{\ccverbatim \ccfinish}#3%
-    \strut\\
-    \end{center}
-    \if\cxxVersionStr\empty%
-    \else%
-	\begin{center}
-	\small\sf
-	--- Version \cxxVersionStr\ ---
-	\end{center}
-	\global\def\cxxVersionStr{}
-    \fi
-    \vfill
-    \large
-    \begin{center}
-    \Large\em
-    \def{\ccverbatim \ccfinish}#4%
-    \end{center}
-    \vfill
-    \if\cxxAuthorStr\empty%
-    \else%
-	\begin{center}
-	\sf\cxxAuthorStr
-	\end{center}
-	\global\def\cxxAuthorStr{}
-	\vfill
-    \fi
-    \pagebreak
-    \makeHeadLine{}{#2}
-}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%	environment for contents
-%
-\newcounter{cxxContentsDepth}
-\setcounter{cxxContentsDepth}{0}
-\newdimen\cxxContentsLengthIncr
-\cxxContentsLengthIncr=18pt
-\newdimen\cxxContentsLength
-\cxxContentsLength=\textwidth
-\advance\cxxContentsLength by -\cxxContentsLengthIncr
-
-\makeHeadLine{}{Contents}
-
-\newenvironment{cxxContents}{
-    \ifcase \value{cxxContentsDepth}
-	\vskip 40pt
-	\hbox to \hsize{\hskip 8pt\hskip\cxxContentsLengthIncr\Huge\bf Contents\hss}
-	\vskip 40pt
-	\bf
-    \else					% >1
-	\rm
-    \fi
-    \begingroup
-    \addtocounter{cxxContentsDepth}{1}
-    \advance\cxxContentsLengthIncr by  8pt
-    \advance\cxxContentsLength     by -\cxxContentsLengthIncr
-}{
-    \addtocounter{cxxContentsDepth}{-1}
-    \advance\cxxContentsLength     by  \cxxContentsLengthIncr
-    \advance\cxxContentsLengthIncr by  -8pt
-    \ifcase \value{cxxContentsDepth}
-	\vskip 12pt
-    \or	
-	\vskip 9pt
-    \else
-	\vskip 3pt
-    \fi
-    \endgroup
-}
-
-\newcommand{\cxxContentsEntry}[3]{{
-    \def\emtpty{}
-    \def\memo{#3}
-    \ifx\memo\empty
-	\setbox0\hbox{\parbox[t]{\cxxContentsLength}{\strut#2 \dotfill }}
-    \else
-	\setbox0\hbox{\parbox[t]{\cxxContentsLength}{\strut#2 --- {\em #3} \dotfill }}
-    \fi
-    \setbox1\hbox{\vtop{\vskip\dp0\vskip-\ht0\vskip-1.5pt\hbox to 20pt{\hss\rm \pageref{cxx.#1}}}}
-    \hbox to \textwidth{%
-	\hss\hbox to \cxxContentsLengthIncr{#1\hss}%
-	\unhbox0\unhbox1%
-    }
-}}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%	environment for class graph
-%
-\newdimen\cxxClassGraphShift
-\newdimen\cxxClassGraphLength
-\newdimen\cxxClassGraphHeight
-\newdimen\cxxClassGraphDepth
-\newdimen\cxxClassGraphTotV
-\setlength{\cxxClassGraphLength}{0.23\hsize}
-\setlength{\cxxClassGraphShift}{30pt}
-\setbox0\vbox{\aBox[5pt]{\strut}{\strut}}
-\setlength{\cxxClassGraphHeight}{\ht0}
-\setlength{\cxxClassGraphDepth}{\dp0}
-\addtolength{\cxxClassGraphDepth}{10pt}
-\setlength{\cxxClassGraphTotV}{\dp0}
-\addtolength{\cxxClassGraphTotV}{\ht0}
-
-\newenvironment{cxxInheritance}{
-    \par\medskip
-    \begingroup
-    \newcommand{\cxxCGSpace}[1]{%
-	\vtop to \cxxClassGraphTotV{\hbox to \cxxClassGraphShift{%
-	    \vrule width0pt height \cxxClassGraphHeight depth \cxxClassGraphDepth%
-	##1}}%
-    }
-    \newcommand{\cxxSlashHline}{%
-	\vrule width 0.1\cxxClassGraphShift height 3.5pt depth -3pt%
-	\vrule width 0.1\cxxClassGraphShift height 0pt depth 0pt%
-	\vrule width 0.1\cxxClassGraphShift height 3.5pt depth -3pt%
-	\vrule width 0.1\cxxClassGraphShift height 0pt depth 0pt%
-	\vrule width 0.1\cxxClassGraphShift height 3.5pt depth -3pt%
-    }
-    \newcommand{\cxxDotHline}{%
-	\vrule width 0.06\cxxClassGraphShift height 3.5pt depth -3pt%
-	\vrule width 0.05\cxxClassGraphShift height 0pt depth 0pt%
-	\vrule width 0.06\cxxClassGraphShift height 3.5pt depth -3pt%
-	\vrule width 0.05\cxxClassGraphShift height 0pt depth 0pt%
-	\vrule width 0.06\cxxClassGraphShift height 3.5pt depth -3pt%
-	\vrule width 0.05\cxxClassGraphShift height 0pt depth 0pt%
-	\vrule width 0.06\cxxClassGraphShift height 3.5pt depth -3pt%
-	\vrule width 0.05\cxxClassGraphShift height 0pt depth 0pt%
-	\vrule width 0.06\cxxClassGraphShift height 3.5pt depth -3pt%
-    }
-    \newcommand{\cxxHline}{%
-	\vrule width 0.5\cxxClassGraphShift height 3.5pt depth -3pt%
-    }
-    \newcommand{\cxxVup}{\hbox to 0pt{\hss%
-	\vrule width 0.5pt height \cxxClassGraphHeight depth -3pt%
-    \hss}}
-    \newcommand{\cxxVlow}{\hbox to 0pt{\hss%
-	\vtop to 0pt{\vskip-3pt%
-	    \hbox{\vrule width 0.5pt height 13pt depth \cxxClassGraphDepth}%
-	\vss}%
-    \hss}}
-    \newcommand{\cxxLinkUp}{\hbox to 0pt{\hss\hskip 0.5\cxxClassGraphShift%
-	\raise0.7\cxxClassGraphHeight\hbox to 0pt{\hss\textbf{\symbol{94}}\hss}}}%
-    \newcommand{\cxxLinkDown}{\hbox to 0pt{\hss\hskip 0.5\cxxClassGraphShift%
-	\raise-0.6\cxxClassGraphHeight\vbox to 0pt{%
-	    \hbox to 0pt{\hss\textbf{$\lor$}\hss}\vss}}}%
-    \newcommand{\cxxLinkLeft}{\hbox to 0pt{\hss\hskip 0.0\cxxClassGraphShift%
-	\raise0.0\cxxClassGraphHeight\hbox to 0pt{\textbf{\tt\<}\hss}}}%
-    \newcommand{\cxxLinkRight}{\hbox to 0pt{\hss\hskip 1.0\cxxClassGraphShift%
-	\raise0.0\cxxClassGraphHeight\hbox to 0pt{\hss\textbf{\tt\>}}}}%
-    \newcommand{\cxxInheritanceEntry}[5][]{
-	\hbox to \hsize{\hss%
-	    \vrule width0pt height \cxxClassGraphHeight depth \cxxClassGraphDepth%
-	    ##2%
-	    \def\tmp{##1}%
-	    \ifx\tmp\empty%
-		\def\tmp{##5}%
-		\ifx\tmp\empty%
-		    \rBox[1pt]{##3}{##4}{0.24\hsize}%
-		\else%
-		    \lBox[1pt]{##3}{##4}{0.24\hsize}%
-		\fi%
-	    \else%
-		\cBox[2pt]{##3}{##4}{0.24\hsize}%
-	    \fi%
-	    ##5\hfill%
-	}\vskip-1pt
-    }
-    \newcommand{\cxxNone}{\cxxCGSpace{\hss}}
-    \newcommand{\cxxLong}{\cxxCGSpace{\hss\cxxVup\cxxVlow\hss}}
-%
-    \newcommand{\cxxPubLeft}{\cxxCGSpace{\cxxHline\cxxVup\cxxVlow\hss}}
-    \newcommand{\cxxProLeft}{\cxxCGSpace{\cxxSlashHline\cxxVup\cxxVlow\hss}}
-    \newcommand{\cxxPriLeft}{\cxxCGSpace{\cxxDotHline\cxxVup\cxxVlow\hss}}
-    \newcommand{\cxxPubleft}{\cxxCGSpace{\cxxHline\cxxVlow\hss}}
-    \newcommand{\cxxProleft}{\cxxCGSpace{\cxxSlashHline\cxxVlow\hss}}
-    \newcommand{\cxxPrileft}{\cxxCGSpace{\cxxDotHline\cxxVlow\hss}}
-    \newcommand{\cxxLastPubLeft}{\cxxCGSpace{\cxxHline%
-    		    	\cxxVup\cxxLinkDown\cxxVlow\hss}}
-    \newcommand{\cxxLastProLeft}{\cxxCGSpace{\cxxSlashHline%
-    		    	\cxxVup\cxxLinkDown\cxxVlow\hss}}
-    \newcommand{\cxxLastPriLeft}{\cxxCGSpace{\cxxDotHline%
-    		    	\cxxVup\cxxLinkDown\cxxVlow\hss}}
-    \newcommand{\cxxLastPubleft}{\cxxCGSpace{\cxxHline%
-    		    	\cxxVlow\cxxLinkDown\hss}}
-    \newcommand{\cxxLastProleft}{\cxxCGSpace{\cxxSlashHline%
-    		    	\cxxVlow\cxxLinkDown\hss}}
-    \newcommand{\cxxLastPrileft}{\cxxCGSpace{\cxxDotHline%
-    				\cxxVlow\cxxLinkDown\hss}}
-    \newcommand{\cxxLinkPubLeft}{\cxxCGSpace{\cxxLinkLeft\cxxHline\cxxVup\cxxVlow\hss}}
-    \newcommand{\cxxLinkProLeft}{\cxxCGSpace{\cxxLinkLeft\cxxSlashHline%
-    				\cxxVup\cxxVlow\hss}}
-    \newcommand{\cxxLinkPriLeft}{\cxxCGSpace{\cxxLinkLeft\cxxDotHline%
-    				\cxxVup\cxxVlow\hss}}
-    \newcommand{\cxxLinkPubleft}{\cxxCGSpace{\cxxLinkLeft\cxxHline\cxxVlow\hss}}
-    \newcommand{\cxxLinkProleft}{\cxxCGSpace{\cxxLinkLeft\cxxSlashHline\cxxVlow\hss}}
-    \newcommand{\cxxLinkPrileft}{\cxxCGSpace{\cxxLinkLeft\cxxDotHline\cxxVlow\hss}}
-%
-    \newcommand{\cxxPubRight}{\cxxCGSpace{\hss\cxxVup\cxxVlow\cxxHline}}
-    \newcommand{\cxxProRight}{\cxxCGSpace{\hss\cxxVup\cxxVlow\cxxSlashHline}}
-    \newcommand{\cxxPriRight}{\cxxCGSpace{\hss\cxxVup\cxxVlow\cxxDotHline}}
-    \newcommand{\cxxPubright}{\cxxCGSpace{\hss\cxxVup\cxxHline}}
-    \newcommand{\cxxProright}{\cxxCGSpace{\hss\cxxVup\cxxSlashHline}}
-    \newcommand{\cxxPriright}{\cxxCGSpace{\hss\cxxVup\cxxDotHline}}
-
-    \newcommand{\cxxLinkPubRight}{\cxxCGSpace{\hss\cxxVup\cxxVlow\cxxHline\cxxLinkRight}}
-    \newcommand{\cxxLinkProRight}{\cxxCGSpace{\hss\cxxVup\cxxVlow%
-    				   \cxxSlashHline\cxxLinkRight}}
-    \newcommand{\cxxLinkPriRight}{\cxxCGSpace{\hss\cxxVup\cxxVlow%
-				   \cxxDotHline\cxxLinkRight}}
-    \newcommand{\cxxLinkPubright}{\cxxCGSpace{\hss\cxxVup\cxxHline\cxxLinkRight}}
-    \newcommand{\cxxLinkProright}{\cxxCGSpace{\hss\cxxVup\cxxSlashHline\cxxLinkRight}}
-    \newcommand{\cxxLinkPriright}{\cxxCGSpace{\hss\cxxVup\cxxDotHline\cxxLinkRight}}
-
-    \newcommand{\cxxFirstPubRight}{\cxxCGSpace{\hss\cxxVup\cxxLinkUp\cxxVlow\cxxHline}}
-    \newcommand{\cxxFirstProRight}{\cxxCGSpace{\hss\cxxVup\cxxLinkUp\cxxVlow%
-    				   \cxxSlashHline}}
-    \newcommand{\cxxFirstPriRight}{\cxxCGSpace{\hss\cxxVup\cxxLinkUp\cxxVlow\cxxDotHline}}
-    \newcommand{\cxxFirstPubright}{\cxxCGSpace{\hss\cxxVup\cxxLinkUp\cxxHline}}
-    \newcommand{\cxxFirstProright}{\cxxCGSpace{\hss\cxxVup\cxxLinkUp\cxxSlashHline}}
-    \newcommand{\cxxFirstPriright}{\cxxCGSpace{\hss\cxxVup\cxxLinkUp\cxxDotHline}}
-}{
-    \endgroup
-}
-
-\newenvironment{cxxClassGraph}{
-    \begin{cxxInheritance}
-    \newcommand{\cxxClassGraphEntry}[4]{
-	\hbox to \hsize{\hss%
-	    \vrule width0pt height \cxxClassGraphHeight depth \cxxClassGraphDepth%
-	    ##1%
-	    \def\tmp{##4}%
-	    \rBox[1pt]{##2}{##3}{0.24\hsize}%
-	    ##4%
-	    \hskip\cxxClassGraphShift\dotfill%
-	    \hbox to \cxxClassGraphShift{\hss\pageref{cxx.##2}}%
-	}\vskip-1pt
-    }
-    \newcommand{\cxxClassGraphEntryUnknownPackage}[3]{
-	\hbox to \hsize{\hss%
-	    \vrule width0pt height \cxxClassGraphHeight depth \cxxClassGraphDepth%
-	    ##1%
-	    \def\tmp{##3}%
-	    \rBox[1pt]{}{##2}{0.24\hsize}%
-	    ##3%
-	    \hskip\cxxClassGraphShift\hfill%
-	}\vskip-1pt
-    }
-    \clearpage
-    \pagebreak\strut
-    \makeHeadLine{}{Class Graph}
-    \vskip 20pt
-    \hbox to \hsize{\Huge\bf \quad Class Graph\hss}
-    \vskip 40pt
-}
-{
-    \end{cxxInheritance}
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for generic manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newdimen\cxxgenericstart
-\cxxgenericstart=\labelwidth
-\advance\cxxgenericstart by \labelsep
-\newdimen\cxxgenericwidth
-\cxxgenericwidth=\textwidth
-\advance\cxxgenericwidth by -\cxxgenericstart
-
-\newcounter{cxxDepth}
-\setcounter{cxxDepth}{0}
-
-\newlength{\cxxSize}
-\newenvironment{cxxgeneric}[5]{
-%
-%	some local definitions
-%
-    \def\empty{}
-    \def\type{#1}
-    \def\args{#3}
-    \def\memo{#4}
-    \def\id  {#5}
-%
-%	pagebreak ?
-%
-\ifcase \value{cxxDepth}
-	\clearpage			%  0
-	\pagebreak
-	\makeHeadLine{#5}{#2}
-	\setlength{\cxxSize}{2pt}
-\or					%  1
-	\strut\bigskip\bigskip\goodbreak%
-	\setlength{\cxxSize}{1pt}
-\else					% >2
-	\strut\bigskip\bigskip\goodbreak%
-	\setlength{\cxxSize}{0.5pt}
-\fi
-\addtocounter{cxxDepth}{1}
-%
-%	write synopsis
-%
-\setbox0\hbox{ }%
-\setbox1\hbox{\strut\large #1 {\bf#2} }%
-\setbox3\hbox{\strut\large #1 {\bf#2} #3}%
-%
-% box with id and name [optional width] over entire page width
-%
-\setlength{\cxxSideLen}{\hsize}%
-\addtolength{\cxxSideLen}{-4\cxxSize}%
-\addtolength{\cxxSideLen}{-2\wd0}%
-\setlength{\cxxTitleLen}{\cxxSideLen}%
-\addtolength{\cxxTitleLen}{-8\wd0}%
-\hbox{\aBox[\cxxSize]{\id}{\vbox{\vskip 1.5\parskip%
-    \hbox to \cxxSideLen{\strut%
-	\hbox to 4\wd0{}%
-	\ifdim\wd3<\cxxTitleLen%
-	    \parbox[b]{\cxxTitleLen}{%
-		\begin{raggedright}
-		\noindent\large #1 {\bf#2} #3
-		\end{raggedright}
-	    }
-	\else%
-	    \ifdim\wd1>0.7\cxxTitleLen%
-		\parbox[b]{\cxxTitleLen}{%
-		    \begin{raggedright}
-		    \noindent\large #1 {\bf#2} #3
-		    \end{raggedright}
-		}
-	    \else%
-		\addtolength{\cxxTitleLen}{-\wd1}%
-		\unhbox1%
-		\parbox[t]{\cxxTitleLen}{%
-		    \advance\lineskip 7pt%
-		    \begin{raggedright}
-		    \noindent\large\strut #3
-		    \end{raggedright}
-		}
-	    \fi%
-	\fi%
-	\hss\strut%
-    }\vskip\parskip}%
-}}
-% \parbox[b]{\cxxSideLen}{\begingroup
-% 	\catcode`\&=12%
-% 	\catcode`\_=12%
-% 	\begin{flushleft}
-% 	    \quad\large%
-% 	    \ifx\type\empty
-% 		\ifx\args\empty
-% 		    \strut{\bf #2}\\
-% 		\else
-% 		    \strut{\bf #2}\ \args
-% 		\fi
-% 	    \else
-% 		\strut\type\ {\bf #2}\ \args
-% 	    \fi
-% 	\end{flushleft}
-% \endgroup}}}%
-\ifx\memo\empty\else
-    \vskip 10pt
-    \begin{flushright}
-	\it\memo
-    \end{flushright}
-\fi
-\label{cxx.\id}
-\begingroup
-\def\cxxExceptionsStr{}
-\def\cxxParameterStr{}
-\def\cxxReturnStr{}
-\def\cxxInvariantsStr{}
-\def\cxxPreconditionsStr{}
-\def\cxxPostconditionsStr{}
-\def\cxxSeeStr{}
-\def\cxxAuthorStr{}
-\def\cxxVersionStr{}
-\def\cxxDeprecatedStr{}
-\def\cxxSinceStr{}
-\def\cxxFileStr{}
-\def\cxxExceptions##1{\def\cxxExceptionsStr{##1}}
-\def\cxxParameter##1{\def\cxxParameterStr{##1}}
-\def\cxxReturn##1{\def\cxxReturnStr{##1}}
-\def\cxxInvariants##1{\def\cxxInvariantsStr{##1}}
-\def\cxxPreconditions##1{\def\cxxPreconditionsStr{##1}}
-\def\cxxPostconditions##1{\def\cxxPostconditionsStr{##1}}
-\def\cxxSee##1{\def\cxxSeeStr{##1}}
-\def\cxxAuthor##1{\def\cxxAuthorStr{##1}}
-\def\cxxVersion##1{\def\cxxVersionStr{##1}}
-\def\cxxDeprecated##1{\def\cxxDeprecatedStr{##1}}
-\def\cxxSince##1{\def\cxxSinceStr{##1}}
-\def\cxxFile##1{\def\cxxFileStr{##1}}
-}{
-\endgroup
-\addtocounter{cxxDepth}{-1}
-}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for function manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxfunction}[5]{
-\begin{cxxgeneric}{#1}{#2}{#3}{#4}{#5}
-\renewenvironment{cxxnames}{\begin{cxxlist}{Arguments}}{\end{cxxlist}}
-}{
-\end{cxxgeneric}
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxentry}[5]{
-\begin{cxxgeneric}{#1}{#2}{#3}{#4}{#5}}{\end{cxxgeneric}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for union manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxunion}[5]{
-\begin{cxxgeneric}{#1}{#2}{#3}{#4}{#5}
-\renewenvironment{cxxnames}{\begin{cxxlist}{Members}}{\end{cxxlist}}
-}{
-\end{cxxgeneric}
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for typedef manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxtypedef}[5]{
-\begin{cxxgeneric}{#1}{#2}{}{#4}{#5}
-\renewenvironment{cxxnames}{\begin{cxxlist}{Members}}{\end{cxxlist}}
-}{
-\end{cxxgeneric}
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for macro manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxmacro}[5]{
-\begin{cxxgeneric}{\#define}{#2}{#3}{#4}{#5}}{\end{cxxgeneric}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for class manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxclass}[5]{
-\begin{cxxgeneric}{#1}{#2}{#3}{#4}{#5}}{\end{cxxgeneric}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for namespace manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxnamespace}[5]{
-\begin{cxxgeneric}{#1}{#2}{#3}{#4}{#5}}{\end{cxxgeneric}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for interface manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxinterface}[5]{
-\begin{cxxgeneric}{#1}{#2}{#3}{#4}{#5}}{\end{cxxgeneric}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for variable manual entries
-% arguments are:
-%	#1	type
-%	#2	name
-%	#3	args
-%	#4	memo
-%	#5	number
-%
-\newenvironment{cxxvariable}[5]{
-\begin{cxxgeneric}{#1}{#2}{#3}{#4}{#5}
-\renewenvironment{cxxnames}{\begin{cxxlist}{Names}}{\end{cxxlist}}
-}{
-\end{cxxgeneric}
-}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for documentation
-%
-\newenvironment{cxxdocumentation}{
-%
-% switch on special characters for documentation section
-%
-\begingroup
-\catcode`\&=4
-\catcode`\_=8
-}{
-\endgroup
-}
-
-\newenvironment{cxxdoc}{
-%
-% switch on special characters for documentation section
-%
-\begin{cxxdocumentation}
-\strut\\\noindent%
-}{
-\smallskip
-\def\empty{}%
-\ifx\cxxReturnStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Return Value:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxReturnStr}\\
-\fi
-\ifx\cxxParameterStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Parameters:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxParameterStr}\\
-\fi
-\ifx\cxxExceptionsStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Exceptions:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxExceptionsStr}\\
-\fi
-\ifx\cxxInvariantsStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Invariants:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxInvariantsStr}\\
-\fi
-\ifx\cxxPreconditionsStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Preconditions:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxPreconditionsStr}\\
-\fi
-\ifx\cxxPostconditionsStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Postconditions:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxPostconditionsStr}\\
-\fi
-\ifx\cxxSeeStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf See Also:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxSeeStr}\\
-\fi
-\ifx\cxxAuthorStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Author:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxAuthorStr}\\
-\fi
-\ifx\cxxVersionStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Version:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxVersionStr}\\
-\fi
-\ifx\cxxDeprecatedStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf\it Deprecated:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxDeprecatedStr}\\
-\fi
-\ifx\cxxSinceStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf Since:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxSinceStr}\\
-\fi
-\ifx\cxxFileStr\empty\else
-    \noindent\hbox to 0.3\textwidth{{\bf File:}\hss}%
-    \parbox[t]{0.7\textwidth}{\cxxFileStr}\\
-\fi
-\end{cxxdocumentation}
-}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% environment for commented listing
-% arguments are:
-%	#1	Section title
-%
-\newenvironment{cxximplementation}[1]{
-\goodbreak
-\begin{cxxdocumentation}
-}{
-\end{cxxdocumentation}
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\def\cxxCodeLine#1{
-\strut\hbox to 20pt{\tiny\hss #1}\small
-%\advance\leftmargin by 20pt
-%\advance\textwidth by -20pt
-\ccverbatim \parskip=0pt \cxxCodeFinish}
-{\catcode`\=0 catcode`\=12
-gdefcxxCodeFinish#1{hbox{#1}endgroup}}
diff --git a/tombupnp/upnp/doc/intro.dxx b/tombupnp/upnp/doc/intro.dxx
deleted file mode 100644
index 7c1240b..0000000
--- a/tombupnp/upnp/doc/intro.dxx
+++ /dev/null
@@ -1,17 +0,0 @@
-/**@name Introduction
- * This document gives a brief description of the Linux SDK for UPnP
- * Devices API.  Section 1 covers the license under which the SDK is 
- * distributed.  Section 2 talks about the callback functions used 
- * in many parts of the API.  Finally, section 3 details the structures and 
- * functions that comprise the API.
- *
- * The Linux SDK for UPnP Devices version 1.2 supports the following 
- * platforms:
- * \begin{itemize}
- *   \item Linux* running on an Intel Architecture processor
- *   \item Linux running on an Intel StrongARM or XScale processor
- * \end{itemize}
- *
- * {\bf *} Other brands and names are the property of their respective 
- *  owners.
- */
diff --git a/tombupnp/upnp/doc/license.dxx b/tombupnp/upnp/doc/license.dxx
deleted file mode 100644
index 88b21cf..0000000
--- a/tombupnp/upnp/doc/license.dxx
+++ /dev/null
@@ -1,32 +0,0 @@
-/**@name License
- *
- * \begin{center}
- *    Copyright (c) 2000-2003 Intel Corporation 
- *    All rights reserved. 
- * \end{center}
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met: 
- * \begin{itemize}
- * \item Redistributions of source code must retain the above copyright notice, 
- *   this list of conditions and the following disclaimer. 
- * \item Redistributions in binary form must reproduce the above copyright 
- *   notice, this list of conditions and the following disclaimer in the 
- *   documentation and/or other materials provided with the distribution. 
- * \item Neither name of Intel Corporation nor the names of its contributors 
- *   may be used to endorse or promote products derived from this software 
- *   without specific prior written permission.
- * \end{itemize}
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
diff --git a/tombupnp/upnp/doc/upnpsdk.dxx b/tombupnp/upnp/doc/upnpsdk.dxx
deleted file mode 100644
index 0690436..0000000
--- a/tombupnp/upnp/doc/upnpsdk.dxx
+++ /dev/null
@@ -1,20 +0,0 @@
-/**@name Linux SDK for UPnP Devices v1.4
- *
- *\begin{center}
- *  {\bf Linux SDK for UPnP Devices Version 1.4}
- *
- *  Copyright (C) 2000-2003 Intel Corporation  ALL RIGHTS RESERVED
- *
- *  Revision 1.4.1 (\Date)
- *\end{center}
- */
-//@{
-
-  //@Include: intro.dxx
-  //@Include: license.dxx
-  //@Include: callback.dxx
-  //@Include: ../inc/upnp.h
-  //@Include: ../inc/upnptools.h
-  //@Include: ../inc/config.h
-
-//@}
diff --git a/tombupnp/upnp/inc/upnp.h b/tombupnp/upnp/inc/upnp.h
deleted file mode 100644
index a6b50c7..0000000
--- a/tombupnp/upnp/inc/upnp.h
+++ /dev/null
@@ -1,2797 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-#ifndef UPNP_H
-#define UPNP_H
-
-/** @name The API */
-
-//@{
-
-#include <stdio.h>
-#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__NetBSD__)
-#include <time.h>
-#include <sys/types.h>
-#endif
-#include "ixml.h"
-#include "upnpconfig.h"
-#if UPNP_HAVE_DEBUG
-#	include "upnpdebug.h"
-#endif
-
-#ifdef WIN32
- #ifndef UPNP_STATIC_LIB
-  #ifdef LIBUPNP_EXPORTS
-   // set up declspec for dll export to make functions visible to library users
-   #define EXPORT_SPEC __declspec(dllexport)
-  #else
-   #define EXPORT_SPEC __declspec(dllimport)
-  #endif
- #else
-  #define EXPORT_SPEC
- #endif
-#else
- #define EXPORT_SPEC
-#endif
-
-#ifndef WIN32
- #define UpnpCloseSocket         close
-#else
- #define UpnpCloseSocket         closesocket
-#endif
-#define UPNP_SOCKETERROR        -1
-#define UPNP_INVALID_SOCKET     -1
-#ifndef WIN32
- #define SOCKET                  int
-#endif
-
-#ifndef WIN32
- #include <netinet/in.h>
-#else
- #include <winsock2.h>
- #include <time.h>
-#endif
-
-#define NUM_HANDLE 200
-#define LINE_SIZE  180
-#define NAME_SIZE  256
-#define HEADER_SIZE  256
-#define MNFT_NAME_SIZE  64
-#define MODL_NAME_SIZE  32
-#define SERL_NUMR_SIZE  64
-#define MODL_DESC_SIZE  64
-#define UPNP_INFINITE -1
-
-#define UPNP_USING_CHUNKED			-3
-#define UPNP_UNTIL_CLOSE			-4
-
-
-/** @name Error codes 
- *  The functions in the SDK API can return a variety of error 
- *  codes to describe problems encountered during execution.  This section 
- *  lists the error codes and provides a brief description of what each error 
- *  code means.  Refer to the documentation for each function for a 
- *  description of what an error code means in that context.
- */
-//@{
-
-/** @name UPNP_E_SUCCESS [0]
- *  {\tt UPNP_E_SUCCESS} signifies that the operation completed successfully.
- *  For asynchronous functions, this only means that the packet generated by 
- *  the operation was successfully transmitted on the network.  The result of 
- *  the entire operation comes as part of the callback for that operation.
- */
-//@{
-#define UPNP_E_SUCCESS          0
-//@}
-
-/** @name UPNP_E_INVALID_HANDLE [-100]
- *  {\tt UPNP_E_INVALID_HANDLE} signifies that the handle passed to a 
- *  function is not a recognized as a valid handle.
- */
-//@{
-#define UPNP_E_INVALID_HANDLE   -100
-//@}
-
-/** @name UPNP_E_INVALID_PARAM [-101]
- *  {\tt UPNP_E_INVALID_PARAM} signifies that one or more of the parameters 
- *  passed to the function is not valid.  Refer to the documentation for each 
- *  function for more information on the valid ranges of the parameters.
- */
-//@{
-#define UPNP_E_INVALID_PARAM    -101
-//@}
-
-/** @name UPNP_E_OUTOF_HANDLE [-102]
- *  {\tt UPNP_E_OUTOF_HANDLE} signifies that the SDK does not have any
- *  more space for additional handles.  The SDK allocates space for only 
- *  a few handles in order to conserve memory.
- */
-//@{
-#define UPNP_E_OUTOF_HANDLE     -102
-//@}
-
-#define UPNP_E_OUTOF_CONTEXT    -103
-
-/** @name UPNP_E_OUTOF_MEMORY [-104]
- *  {\tt UPNP_E_OUTOF_MEMORY} signifies that not enough resources are 
- *  currently available to complete the operation.  Most operations require 
- *  some free memory in order to complete their work.
- */
-//@{
-#define UPNP_E_OUTOF_MEMORY     -104
-//@}
-
-/** @name UPNP_E_INIT [-105]
- *  {\tt UPNP_E_INIT} signifies that the SDK has already been 
- *  initialized.  The SDK needs to be initialied only once per process.
- *  Any additional initialization attempts simply return this error with
- *  no other ill effects.
- */
-//@{
-#define UPNP_E_INIT             -105
-//@}
-
-#define UPNP_E_BUFFER_TOO_SMALL -106
-
-/** @name UPNP_E_INVALID_DESC [-107]
- *  {\tt UPNP_E_INVALID_DESC} signifies that the description document passed
- *  to {\bf UpnpRegisterRootDevice} or {\bf UpnpRegisterRootDevice2} is an 
- *  invalid description document.  
- */
-//@{
-#define UPNP_E_INVALID_DESC     -107
-//@}
-
-/** @name UPNP_E_INVALID_URL [-108]
- *  {\tt UPNP_E_INVALID_URL} signifies that a URL passed into the function
- *  is invalid.  The actual cause is function specific, but in general, the
- *  URL itself might be malformed (e.g. have invalid characters in it) or
- *  the host might be unreachable.
- */
-//@{
-#define UPNP_E_INVALID_URL      -108
-//@}
-
-#define UPNP_E_INVALID_SID      -109
-#define UPNP_E_INVALID_DEVICE   -110
-
-/** @name UPNP_E_INVALID_SERVICE [-111]
- *  {\tt UPNP_E_INVALID_SERVICE} is returned only by {\bf UpnpNotify}, 
- *  {\bf UpnpNotifyExt}, {\bf UpnpAcceptSubscription}, and 
- *  {\bf UpnpAcceptSubscriptionExt} to signify that the device ID/service
- *  ID pair does not refer to a valid service.
- */
-//@{
-#define UPNP_E_INVALID_SERVICE  -111
-//@}
-
-/** @name UPNP_E_BAD_RESPONSE [-113]
- *  {\tt UPNP_E_BAD_RESPONSE} signifies that the response received from the 
- *  remote side of a connection is not correct for the protocol.  This applies
- *  to the GENA, SOAP, and HTTP protocols.
- */
-//@{
-#define UPNP_E_BAD_RESPONSE     -113
-//@}
-
-#define UPNP_E_BAD_REQUEST      -114
-
-/** @name UPNP_E_INVALID_ACTION [-115]
- *  {\tt UPNP_E_INVALID_ACTION} signifies that the SOAP action message is 
- *  invalid.  This can be because the DOM document passed to the function was
- *  malformed or the action message is not correct for the given action.
- */
-//@{
-#define UPNP_E_INVALID_ACTION   -115
-//@}
-
-/** @name UPNP_E_FINISH [-116]
- *  {\tt UPNP_E_FINISH} signifies that {\bf UpnpInit} has not been called, or
- *  that {\bf UpnpFinish} has already been called.  None of the API functions 
- *  operate until {\bf UpnpInit} successfully completes.
- */
-//@{
-#define UPNP_E_FINISH           -116
-//@}
-
-/** @name UPNP_E_INIT_FAILED [-117]
- *  {\tt UPNP_E_INIT_FAILED} signifies that {\bf UpnpInit} cannot complete.  
- *  The typical reason is failure to allocate sufficient resources.
- */
-//@{
-#define UPNP_E_INIT_FAILED      -117
-//@}
-
-/** @name UPNP_E_URL_TOO_BIG [-118]
- *  {\tt UPNP_E_URL_TOO_BIG} signifies that the URL passed into a function 
- *  is too long.  The SDK limits URLs to 180 characters in length.  
- */
-#define UPNP_E_URL_TOO_BIG      -118
-
-/** @name UPNP_E_BAD_HTTPMSG [-119]
- *  {\tt UPNP_E_BAD_HTTPMSG} signifies that the HTTP message contains invalid
- *  message headers.  The error always refers to the HTTP message header 
- *  received from the remote host.  The main areas where this occurs are in
- *  SOAP control messages (e.g. {\bf UpnpSendAction}), GENA subscription
- *  message (e.g. {\bf UpnpSubscribe}), GENA event notifications (e.g. {\bf
- *  UpnpNotify}), and HTTP transfers (e.g. {\bf UpnpDownloadXmlDoc}).
- */
-//@{
-#define UPNP_E_BAD_HTTPMSG      -119
-//@}
-
-/** @name UPNP_E_ALREADY_REGISTERED [-120]
- *  {\tt UPNP_E_ALREADY_REGISTERED} signifies that a client or a device is
- *  already registered.  The SDK currently has a limit of one registered 
- *  client and one registered device per process.
- */
-//@{
-#define UPNP_E_ALREADY_REGISTERED -120
-//@}
-
-/** @name UPNP_E_NETWORK_ERROR [-200]
- *  {\tt UPNP_E_NETWORK_ERROR} signifies that a network error occurred.  It 
- *  is the generic error code for network problems that are not covered under 
- *  one of the more specific error codes.  The typical meaning is the SDK 
- *  failed to read the local IP address or had problems configuring one of
- *  the sockets.
- */
-//@{
-#define UPNP_E_NETWORK_ERROR    -200
-//@}
-
-/** @name UPNP_E_SOCKET_WRITE [-201]
- *  {\tt UPNP_E_SOCKET_WRITE} signifies an error writing to a socket.  This
- *  occurs in any function that makes network connections, such 
- *  as discovery (e.g. {\bf UpnpSearchAsync} or {\bf UpnpSendAdvertisement}), 
- *  control (e.g. {\bf UpnpSendAction}), eventing (e.g. {\bf UpnpNotify}), 
- *  and HTTP functions (e.g. {\bf UpnpDownloadXmlDoc}).
- */
-//@{
-#define UPNP_E_SOCKET_WRITE     -201
-//@}
-
-/** @name UPNP_E_SOCKET_READ [-202]
- *  {\tt UPNP_E_SOCKET_READ} signifies an error reading from a socket.  This
- *  occurs in any function that makes network connections, such 
- *  as discovery (e.g. {\bf UpnpSearchAsync} or {\bf UpnpSendAdvertisement}), 
- *  control (e.g. {\bf UpnpSendAction}), eventing (e.g. {\bf UpnpNotify}), 
- *  and HTTP functions (e.g. {\bf UpnpDownloadXmlDoc}).
- */
-//@{
-#define UPNP_E_SOCKET_READ      -202
-//@}
-
-/** @name UPNP_E_SOCKET_BIND [-203]
- *  {\tt UPNP_E_SOCKET_BIND} signifies that the SDK had a problem binding
- *  a socket to a network interface.  This occurs in any function that makes 
- *  network connections, such as discovery (e.g. {\bf UpnpSearchAsync} or 
- *  {\bf UpnpSendAdvertisement}), control (e.g. {\bf UpnpSendAction}), eventing 
- *  (e.g. {\bf UpnpNotify}), and HTTP functions (e.g. 
- *  {\bf UpnpDownloadXmlDoc}).
- */
-//@{
-#define UPNP_E_SOCKET_BIND      -203
-//@}
-
-/** @name UPNP_E_SOCKET_CONNECT [-204]
- *  {\tt UPNP_E_SOCKET_CONNECT} signifies that the SDK had a problem
- *  connecting to a remote host.  This occurs in any function that makes 
- *  network connections, such as discovery (e.g. {\bf UpnpSearchAsync} or 
- *  {\bf UpnpSendAdvertisement}), control (e.g. {\bf UpnpSendAction}), eventing 
- *  (e.g. {\bf UpnpNotify}), and HTTP functions (e.g. 
- *  {\bf UpnpDownloadXmlDoc}).
- */
-//@{
-#define UPNP_E_SOCKET_CONNECT   -204
-//@}
-
-/** @name UPNP_E_OUTOF_SOCKET [-205]
- *  {\tt UPNP_E_OUTOF_SOCKET} signifies that the SDK cannot create any
- *  more sockets.  This occurs in any function that makes 
- *  network connections, such as discovery (e.g. {\bf UpnpSearchAsync} or 
- *  {\bf UpnpSendAdvertisement}), control (e.g. {\bf UpnpSendAction}), eventing 
- *  (e.g. {\bf UpnpNotify}), and HTTP functions (e.g. 
- *  {\bf UpnpDownloadXmlDoc}).
- */
-//@{
-#define UPNP_E_OUTOF_SOCKET     -205
-//@}
-
-/** @name UPNP_E_LISTEN [-206]
- *  {\tt UPNP_E_LISTEN} signifies that the SDK had a problem setting the
- *  socket to listen for incoming connections.  This error only happens during
- *  initialization (i.e. {\bf UpnpInit}).
- */
-//@{
-#define UPNP_E_LISTEN           -206
-//@}
-
-/** @name UPNP_E_TIMEDOUT [-207]
- *  {\tt UPNP_E_TIMEDOUT} signifies that too much time elapsed before the
- *  required number of bytes were sent or received over a socket.  This error
- *  can be returned by any function that performs network operations.
- */
-//@{
-#define UPNP_E_TIMEDOUT         -207
-//@}
-
-/** @name UPNP_E_SOCKET_ERROR [-208]
- *  {\tt UPNP_E_SOCKET_ERROR} is the generic socket error code for
- *  conditions not covered by other error codes.  This error can be returned
- *  by any function that performs network operations.
- */
-//@{
-#define UPNP_E_SOCKET_ERROR	    -208
-//@}
-
-#define UPNP_E_FILE_WRITE_ERROR -209
-
-/** @name UPNP_E_CANCELED [-210]
- *  {\tt UPNP_E_CANCELED} signifies that the operation was canceled. This
- *  error can be returned by any function that allows for external
- *  cancelation.
- */
-//@{
-#define UPNP_E_CANCELED         -210
-//@}
-
-#define UPNP_E_EVENT_PROTOCOL         -300
-
-/** @name UPNP_E_SUBSCRIBE_UNACCEPTED [-301]
- *  {\tt UPNP_E_SUBSCRIBE_UNACCEPTED} signifies that a subscription
- *  request was rejected from the remote side.  
- */
-//@{
-#define UPNP_E_SUBSCRIBE_UNACCEPTED   -301
-//@}
-
-/** @name UPNP_E_UNSUBSCRIBE_UNACCAPTED [-302]
- *  {\tt UPNP_E_UNSUBSCRIBE_UNACCEPTED} signifies that an unsubscribe
- *  request was rejected from the remote side.
- */
-//@{
-#define UPNP_E_UNSUBSCRIBE_UNACCEPTED -302
-//@}
-
-/** @name UPNP_E_NOTIFY_UNACCEPTED [-303]
- *  {\tt UPNP_E_NOTIFY_UNACCEPTED} signifies that the remote host did not
- *  accept the notify sent from the local device.
- */
-//@{
-#define UPNP_E_NOTIFY_UNACCEPTED      -303
-//@}
-
-/** @name UPNP_E_INVALID_ARGUMENT [-501]
- *  {\tt UPNP_E_INVALID_ARGUMENT} signifies that one or more of the parameters
- *  passed to a function is invalid.  Refer to the individual function
- *  descriptions for the acceptable ranges for parameters.
- */
-//@{
-#define UPNP_E_INVALID_ARGUMENT       -501
-//@}
-
-/** @name UPNP_E_FILE_NOT_FOUND [-502]
- *  {\tt UPNP_E_FILE_NOT_FOUND} signifies that the filename passed
- *  to one of the device registration functions was not found or was not
- *  accessible.
- */
-//@{
-#define UPNP_E_FILE_NOT_FOUND         -502
-//@}
-
-/** @name UPNP_E_FILE_READ_ERROR [-503]
- *  {\tt UPNP_E_FILE_READ_ERROR} signifies an error when reading a file.
- */
-//@{
-#define UPNP_E_FILE_READ_ERROR        -503
-//@}
-
-/** @name UPNP_E_EXT_NOT_XML [-504]
- *  {\tt UPNP_E_EXT_NOT_XML} signifies that the file name of the description
- *  document passed to {\bf UpnpRegisterRootDevice2} does not end in ".xml".
- */
-//@{
-#define UPNP_E_EXT_NOT_XML            -504
-//@}
-
-#define UPNP_E_NO_WEB_SERVER          -505
-#define UPNP_E_OUTOF_BOUNDS	      -506
-
-/** @name UPNP_E_NOT_FOUND [-507]
- *  {\tt UPNP_E_NOT_FOUND} signifies that the response to a SOAP request
- *  did not contain the required XML constructs.  
- */
-//@{
-#define UPNP_E_NOT_FOUND	      -507
-//@}
-
-/** @name UPNP_E_INTERNAL_ERROR [-911]
- *  {\tt UPNP_E_INTERNAL_ERROR} is the generic error code for internal
- *  conditions not covered by other error codes.
- */
-//@{
-#define UPNP_E_INTERNAL_ERROR         -911
-//@}
-
-// SOAP-related error codes
-#define UPNP_SOAP_E_INVALID_ACTION    401
-#define UPNP_SOAP_E_INVALID_ARGS      402
-#define UPNP_SOAP_E_OUT_OF_SYNC       403
-#define UPNP_SOAP_E_INVALID_VAR       404
-#define UPNP_SOAP_E_ACTION_FAILED     501
-//@}
-
-#ifndef OUT
-#define OUT
-#endif
-
-#ifndef IN
-#define IN
-#endif
-
-#ifndef INOUT
-#define INOUT
-#endif
-
-enum UpnpOpenFileMode{UPNP_READ, UPNP_WRITE};
-
-/// @name Constants, Structures, and Types
-//@{
-
-/** Returned when a control point application registers with {\bf
- *  UpnpRegisterClient}.  Client handles can only be used with 
- *  functions that operate with a client handle.  */
-
-typedef int  UpnpClient_Handle;
-
-/** Returned when a device application registers with {\bf
- *  UpnpRegisterRootDevice} or {\bf UpnpRegisterRootDevice2}.  Device handles 
- *  can only be used with functions that operate with a device handle.  */
-
-typedef int  UpnpDevice_Handle;
-
-/** @name UPnP_EventType
-    @memo The reason code for an event callback.
-    @doc The {\bf Event} parameter will be different depending on the
-         reason for the callback.  The descriptions for each event
-	 type describe the contents of the {\bf Event} parameter.
-  */
-
-enum Upnp_EventType_e {
-
-  //
-  // Control callbacks
-  //
-
-  /** Received by a device when a control point issues a control
-   *  request.  The {\bf Event} parameter contains a pointer to a {\bf
-   *  Upnp_Action_Request} structure containing the action.  The application
-   *  stores the results of the action in this structure. */
-
-  UPNP_CONTROL_ACTION_REQUEST,
-
-  /** A {\bf UpnpSendActionAsync} call completed. The {\bf Event}
-   *  parameter contains a pointer to a {\bf Upnp_Action_Complete} structure
-   *  with the results of the action.  */
-
-  UPNP_CONTROL_ACTION_COMPLETE,
-
-  /** Received by a device when a query for a single service variable
-   *  arrives.  The {\bf Event} parameter contains a pointer to a {\bf
-   *  Upnp_State_Var_Request} structure containing the name of the variable
-   *  and value.  */
-
-  UPNP_CONTROL_GET_VAR_REQUEST,
-
-  /** A {\bf UpnpGetServiceVarStatus} call completed. The {\bf Event}
-   *  parameter contains a pointer to a {\bf Upnp_State_Var_Complete} structure
-   *  containing the value for the variable.  */
-
-  UPNP_CONTROL_GET_VAR_COMPLETE,
-
-  //
-  // Discovery callbacks
-  //
-
-  /** Received by a control point when a new device or service is available.  
-   *  The {\bf Event} parameter contains a pointer to a {\bf
-   *  Upnp_Discovery} structure with the information about the device
-   *  or service.  */
-
-  UPNP_DISCOVERY_ADVERTISEMENT_ALIVE,
-
-  /** Received by a control point when a device or service shuts down. The {\bf
-   *  Event} parameter contains a pointer to a {\bf Upnp_Discovery}
-   *  structure containing the information about the device or
-   *  service.  */
-
-  UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE,
-
-  /** Received by a control point when a matching device or service responds.
-   *  The {\bf Event} parameter contains a pointer to a {\bf
-   *  Upnp_Discovery} structure containing the information about
-   *  the reply to the search request.  */
-
-  UPNP_DISCOVERY_SEARCH_RESULT,
-
-  /** Received by a control point when the search timeout expires.  The
-   *  SDK generates no more callbacks for this search after this 
-   *  event.  The {\bf Event} parameter is {\tt NULL}.  */
-
-  UPNP_DISCOVERY_SEARCH_TIMEOUT,
-
-  //
-  // Eventing callbacks
-  //
-
-  /** Received by a device when a subscription arrives.
-   *  The {\bf Event} parameter contains a pointer to a {\bf
-   *  Upnp_Subscription_Request} structure.  At this point, the
-   *  subscription has already been accepted.  {\bf UpnpAcceptSubscription}
-   *  needs to be called to confirm the subscription and transmit the
-   *  initial state table.  This can be done during this callback.  The SDK
-   *  generates no events for a subscription unless the device 
-   *  application calls {\bf UpnpAcceptSubscription}.
-   */
-
-  UPNP_EVENT_SUBSCRIPTION_REQUEST,
-
-  /** Received by a control point when an event arrives.  The {\bf
-   *  Event} parameter contains a {\bf Upnp_Event} structure
-   *  with the information about the event.  */
-
-  UPNP_EVENT_RECEIVED,
-
-  /** A {\bf UpnpRenewSubscriptionAsync} call completed. The status of
-   *  the renewal is in the {\bf Event} parameter as a {\bf
-   *  Upnp_Event_Subscription} structure.  */
-
-  UPNP_EVENT_RENEWAL_COMPLETE,
-
-  /** A {\bf UpnpSubscribeAsync} call completed. The status of the
-   * subscription is in the {\bf Event} parameter as a {\bf
-   * Upnp_Event_Subscription} structure.  */
-
-  UPNP_EVENT_SUBSCRIBE_COMPLETE,
-
-  /** A {\bf UpnpUnSubscribeAsync} call completed. The status of the
-   *  subscription is in the {\bf Event} parameter as a {\bf
-   *  Upnp_Event_Subscribe} structure.  */
-
-  UPNP_EVENT_UNSUBSCRIBE_COMPLETE,
-
-  /** The auto-renewal of a client subscription failed.   
-   *  The {\bf Event} parameter is a {\bf Upnp_Event_Subscribe} structure 
-   *  with the error code set appropriately. The subscription is no longer 
-   *  valid. */
-
-  UPNP_EVENT_AUTORENEWAL_FAILED,
-
-  /** A client subscription has expired. This will only occur 
-   *  if auto-renewal of subscriptions is disabled.
-   *  The {\bf Event} parameter is a {\bf Upnp_Event_Subscribe}
-   *  structure. The subscription is no longer valid. */
-  
-  UPNP_EVENT_SUBSCRIPTION_EXPIRED
-
-};
-
-typedef enum Upnp_EventType_e Upnp_EventType;
-
-/** The {\bf Upnp_SID} holds the subscription identifier for a subscription
-    between a client and a device.  The SID is a string representation of
-    a globally unique id (GUID) and should not be modified.
-  */
-    
-typedef char Upnp_SID[44];
-
-/** @name Upnp_SType
-    @memo Represents the different types of searches that
-          can be performed using the SDK for UPnP Devices API.
-    @doc  By specifying these different values to 
-          {\bf UpnpSearchAsync}, the control point application
-	  can control the scope of the search from all devices
-	  to specific devices or services.
-  */
-
-enum Upnp_SType_e {
-
-  /** Search for all devices and services on the network. */
-  UPNP_S_ALL,    
-
-  /** Search for all root devices on the network. */
-  UPNP_S_ROOT,   
-
-  /** Search for a particular device type or a particular device
-      instance. */
-  UPNP_S_DEVICE, 
-                       
-  /** Search for a particular service type, possibly on a particular
-   *  device type or device instance.  */
-  UPNP_S_SERVICE 
-                       
-};
-
-typedef enum Upnp_SType_e Upnp_SType;
-
-/** @name Upnp_DescType
-    @memo Specifies the type of description in 
-          {\bf UpnpRegisterRootDevice2}.
-    @doc  These values control how {\bf UpnpRegisterRootDevice2}
-          interprets the {\bf description} parameter.
-   */
-enum Upnp_DescType_e { 
-
-	/** The description is the URL to the description document. */
-	UPNPREG_URL_DESC, 
-	
-	/** The description is a file name on the local file system 
-	    containing the description of the device. */
-	UPNPREG_FILENAME_DESC,
-    
-	/** The description is a pointer to a character array containing 
-	    the XML description document. */
-	UPNPREG_BUF_DESC 
-
-};
-
-typedef enum Upnp_DescType_e Upnp_DescType;
-
-/** Returned as part of a {\bf UPNP_CONTROL_ACTION_COMPLETE} callback.  */
-
-struct Upnp_Action_Request
-{
-  /** The result of the operation. */
-  int ErrCode;
-
-  /** The socket number of the connection to the requestor. */
-  int Socket;
-
-  /** The error string in case of error. */
-  char ErrStr[LINE_SIZE];
-
- /** The Action Name. */
-  char ActionName[NAME_SIZE];
-
-  /** The unique device ID. */
-  char DevUDN[NAME_SIZE];
-
-  /** The service ID. */
-  char ServiceID[NAME_SIZE];
-
-  /** The DOM document describing the action. */
-  IXML_Document *ActionRequest;
-
-  /** The DOM document describing the result of the action. */
-  IXML_Document *ActionResult;
-
-  /** IP address of the control point requesting this action. */
-  struct in_addr CtrlPtIPAddr;
-
-  /** The DOM document containing the information from the
-      the SOAP header. */
-  IXML_Document *SoapHeader;
-};
-
-struct Upnp_Action_Complete
-{
-  /** The result of the operation. */
-  int ErrCode;
-
-  /** The control URL for service. */
-  char CtrlUrl[NAME_SIZE];
-
-  /** The DOM document describing the action. */
-  IXML_Document *ActionRequest;
-
-  /** The DOM document describing the result of the action. */
-  IXML_Document *ActionResult;
-
-};
-
-/** Represents the request for current value of a state variable in a service
- *  state table.  */
-
-struct Upnp_State_Var_Request
-{
-  /** The result of the operation. */
-  int ErrCode;
-
-  /** The socket number of the connection to the requestor. */
-  int Socket;
-
-  /** The error string in case of error. */
-  char ErrStr[LINE_SIZE];
-
-  /** The unique device ID. */
-  char DevUDN[NAME_SIZE];
-
-  /** The  service ID. */
-  char ServiceID[NAME_SIZE];
-
-  /** The name of the variable. */
-  char StateVarName[NAME_SIZE];
-
-  /** IP address of sender requesting the state variable. */
-  struct in_addr CtrlPtIPAddr;
-
-  /** The current value of the variable. This needs to be allocated by 
-   *  the caller.  When finished with it, the SDK frees this {\bf DOMString}. */
-  DOMString CurrentVal;
-};
-
-/** Represents the reply for the current value of a state variable in an
-    asynchronous call. */
-
-struct Upnp_State_Var_Complete
-{
-  /** The result of the operation. */
-  int ErrCode;
-
-  /** The control URL for the service. */
-  char CtrlUrl[NAME_SIZE];
-
-  /** The name of the variable. */
-  char StateVarName[NAME_SIZE];
-
-  /** The current value of the variable or error string in case of error. */
-  DOMString CurrentVal;
-};
-
-/** Returned along with a {\bf UPNP_EVENT_RECEIVED} callback.  */
-
-struct Upnp_Event
-{
-  /** The subscription ID for this subscription. */
-  Upnp_SID Sid;
-
-  /** The event sequence number. */
-  int EventKey;
-
-  /** The DOM tree representing the changes generating the event. */
-  IXML_Document *ChangedVariables;
-
-};
-
-//
-// This typedef is required by Doc++ to parse the last entry of the 
-// Upnp_Discovery structure correctly.
-//
-
-typedef struct sockaddr_in SOCKADDRIN;
-
-/** Returned in a {\bf UPNP_DISCOVERY_RESULT} callback. */
-
-struct Upnp_Discovery
-{
-
-  /** The result code of the {\bf UpnpSearchAsync} call. */
-  int  ErrCode;                  
-				     
-  /** The expiration time of the advertisement. */
-  int  Expires;                  
-                                     
-  /** The unique device identifier. */
-  char DeviceId[LINE_SIZE];      
-
-  /** The device type. */
-  char DeviceType[LINE_SIZE];    
-
-  /** The service type. */
-  char ServiceType[LINE_SIZE];
-
-  /** The service version. */
-  char ServiceVer[LINE_SIZE];    
-
-  /** The URL to the UPnP description document for the device. */
-  char Location[LINE_SIZE];      
-
-  /** The operating system the device is running. */
-  char Os[LINE_SIZE];            
-				     
-  /** Date when the response was generated. */
-  char Date[LINE_SIZE];            
-				     
-  /** Confirmation that the MAN header was understood by the device. */
-  char Ext[LINE_SIZE];           
-				     
-  /** The host address of the device responding to the search. */
-  SOCKADDRIN * DestAddr; 
-
-};
-
-/** Returned along with a {\bf UPNP_EVENT_SUBSCRIBE_COMPLETE} or {\bf
- * UPNP_EVENT_UNSUBSCRIBE_COMPLETE} callback.  */
-
-struct Upnp_Event_Subscribe {
-
-  /** The SID for this subscription.  For subscriptions, this only
-   *  contains a valid SID if the {\bf Upnp_EventSubscribe.result} field
-   *  contains a {\tt UPNP_E_SUCCESS} result code.  For unsubscriptions,
-   *  this contains the SID from which the subscription is being
-   *  unsubscribed.  */
-
-  Upnp_SID Sid;            
-
-  /** The result of the operation. */
-  int ErrCode;              
-
-  /** The event URL being subscribed to or removed from. */
-  char PublisherUrl[NAME_SIZE]; 
-
-  /** The actual subscription time (for subscriptions only). */
-  int TimeOut;              
-                              
-};
-  
-/** Returned along with a {\bf UPNP_EVENT_SUBSCRIPTION_REQUEST}
- *  callback.  */
-
-struct Upnp_Subscription_Request
-{
-  /** The identifier for the service being subscribed to. */
-  char *ServiceId; 
-
-  /** Universal device name. */
-  char *UDN;       
-
-  /** The assigned subscription ID for this subscription. */
-  Upnp_SID Sid;
-
-};
-
-
-struct File_Info
-{
-  /** The length of the file. A length less than 0 indicates the size 
-   *  is unknown, and data will be sent until 0 bytes are returned from
-   *  a read call. */
-  off_t file_length;
-
-  /** The time at which the contents of the file was modified;
-   *  The time system is always local (not GMT). */
-  time_t last_modified;
-
-  /** If the file is a directory, {\bf is_directory} contains
-   * a non-zero value. For a regular file, it should be 0. */
-  int is_directory;
-
-  /** If the file or directory is readable, this contains 
-   * a non-zero value. If unreadable, it should be set to 0. */
-  int is_readable;
-
-  /** set to 1 if the data should be sent out using chunked encoding, otherwise
-   * set to zero **/
-  int force_chunked;
-
-  /** The content type of the file. This string needs to be allocated 
-   *  by the caller using {\bf ixmlCloneDOMString}.  When finished 
-   *  with it, the SDK frees the {\bf DOMString}. */
-  DOMString content_type;
- 
-  /** A header to be added to the HTTP response. The header will be
-   *  automatically terminated with \r\n by the SDK. This string needs 
-   *  to be allocated  by the caller using {\bf ixmlCloneDOMString}.  
-   *  When finished with it, the SDK frees the {\bf DOMString}. */
-  DOMString http_header;
-
-};
-
-/* The type of handle returned by the web server for open requests. */
-
-typedef void *UpnpWebFileHandle;
-
-/** The {\bf UpnpVirtualDirCallbacks} structure contains the pointers to
- *  file-related callback functions a device application can register to
- *  virtualize URLs.  
- */
-struct UpnpVirtualDirCallbacks
-{
-  /** Called by the web server to query information on a file.  The callback
-   *  should return 0 on success or -1 on an error. */
-  int (*get_info) (
-    IN  const char *filename,     /** The name of the file to query. */
-    IN  const char *headers,      /** Request headers */
-    OUT struct File_Info *info    /** Pointer to a structure to store the 
-                                      information on the file. */
-    );
-                                  
-  /** Called by the web server to open a file.  The callback should return
-   *  a valid handle if the file can be opened.  Otherwise, it should return
-   *  {\tt NULL} to signify an error. */
-  UpnpWebFileHandle (*open)(
-    IN const char *filename,       /** The name of the file to open. */ 
-    IN  const char *headers,       /** Request headers */
-    OUT struct File_Info *info,    /** Pointer to a structure to store the 
-                                       information on the file. */
-    IN enum UpnpOpenFileMode Mode  /** The mode in which to open the file. 
-                                       Valid values are {\tt UPNP_READ} or 
-                                       {\tt UPNP_WRITE}. */
-    );
-
-  /** Called by the web server to perform a sequential read from an open
-   *  file.  The callback should copy {\bf buflen} bytes from the file into
-   *  the buffer.
-   *  @return [int] An integer representing one of the following:
-   *    \begin{itemize}
-   *      \item {\tt 0}:  The file contains no more data (EOF).
-   *      \item {\tt >0}: A successful read of the number of bytes in the 
-   *                      return code.
-   *      \item {\tt <0}: An error occurred reading the file.
-   *    \end{itemzie}
-   */
-   int (*read) (
-     IN UpnpWebFileHandle fileHnd,  /** The handle of the file to read. */
-     OUT char *buf,                 /** The buffer in which to place the 
-				        data. */
-     IN size_t buflen               /** The size of the buffer (i.e. the 
-                                        number of bytes to read). */
-     );
-
-  /** Called by the web server to perform a sequential write to an open
-   *  file.  The callback should write {\bf buflen} bytes into the file from
-   *  the buffer.  It should return the actual number of bytes written, 
-   *  which might be less than {\bf buflen} in the case of a write error.
-   */
-   int (*write) (
-     IN UpnpWebFileHandle fileHnd, /** The handle of the file to write. */
-     IN char *buf,                 /** The buffer with the bytes to write. */
-     IN size_t buflen              /** The number of bytes to write. */
-     );
-
-  /** Called by the web server to move the file pointer, or offset, into
-   *  an open file.  The {\bf origin} parameter determines where to start
-   *  moving the file pointer.  A value of {\tt SEEK_CUR} moves the
-   *  file pointer relative to where it is.  The {\bf offset} parameter can
-   *  be either positive (move forward) or negative (move backward).  
-   *  {\tt SEEK_END} moves relative to the end of the file.  A positive 
-   *  {\bf offset} extends the file.  A negative {\bf offset} moves backward 
-   *  in the file.  Finally, {\tt SEEK_SET} moves to an absolute position in 
-   *  the file. In this case, {\bf offset} must be positive.  The callback 
-   *  should return 0 on a successful seek or a non-zero value on an error.
-   */
-   int (*seek) (
-     IN UpnpWebFileHandle fileHnd,  /** The handle of the file to move the 
-                                        file pointer. */
-     IN off_t offset,                /** The number of bytes to move in the 
-                                        file.  Positive values move foward and 
-                                        negative values move backward.  Note 
-                                        that this must be positive if the 
-                                        {\bf origin} is {\tt SEEK_SET}. */
-     IN int origin                  /** The position to move relative to.  It 
-                                        can be {\tt SEEK_CUR} to move relative 
-                                        to the current position, 
-					{\tt SEEK_END} to move relative to 
-					the end of the file, or {\tt 
-					SEEK_SET} to specify an absolute 
-					offset. */
-     );
-
-   /** Called by the web server to close a file opened via the {\bf open}
-    *  callback.  It should return 0 on success, or a non-zero value on an 
-    *  error.
-    */
-   int (*close) (
-     IN UpnpWebFileHandle fileHnd   /** The handle of the file to close. */
-     );
-
-};
-
-typedef struct virtual_Dir_List
-{
-    struct virtual_Dir_List *next;
-    char dirName[NAME_SIZE];
-} virtualDirList;
-
-typedef struct user_HTTP_Header_List
-{
-    struct user_HTTP_Header_List *next;
-    char header[HEADER_SIZE];
-} userHTTPHeaderList;
-
-
-/** All callback functions share the same prototype, documented below.
- *  Note that any memory passed to the callback function
- *  is valid only during the callback and should be copied if it
- *  needs to persist.  This callback function needs to be thread
- *  safe.  The context of the callback is always on a valid thread 
- *  context and standard synchronization methods can be used.  Note, 
- *  however, because of this the callback cannot call SDK functions
- *  unless explicitly noted.
- *
- *  \begin{verbatim}
-      int CallbackFxn( Upnp_EventType EventType, void* Event, void* Cookie );
-    \end{verbatim} 
- *
- *  where {\bf EventType} is the event that triggered the callback, 
- *  {\bf Event} is a structure that denotes event-specific information for that
- *  event, and {\bf Cookie} is the user data passed when the callback was
- *  registered.
- *
- *  See {\bf Upnp_EventType} for more information on the callback values and
- *  the associated {\bf Event} parameter.  
- *
- *  The return value of the callback is currently ignored.  It may be used
- *  in the future to communicate results back to the SDK.
- */
-
-typedef int  (*Upnp_FunPtr) (
-    IN Upnp_EventType EventType, 
-    IN void *Event, 
-    IN void *Cookie
-    );
-
-//@} // Constants, Structures, and Types
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-///@name Initialization and Registration
-//@{
-/** Initializes the Linux SDK for UPnP Devices. This function must be called
- *  before any other API function can be called.  It should be called
- *  only once.  Subsequent calls to this API return a {\tt UPNP_E_INIT}
- *  error code.
- *
- *  Optionally, the application can specify a host IP address (in the
- *  case of a multi-homed configuration) and a port number to use for
- *  all UPnP operations.  Since a port number can be used only by one
- *  process, multiple processes using the SDK must specify
- *  different port numbers.
- *
- *  If unspecified, the SDK will use the first adapter's IP address 
- *  and an arbitrary port.
- *
- *  This call is synchronous.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist 
- *              to initialize the SDK.
- *      \item {\tt UPNP_E_INIT}: The SDK is already initialized. 
- *      \item {\tt UPNP_E_INIT_FAILED}: The SDK initialization 
- *              failed for an unknown reason.
- *      \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding a socket.
- *      \item {\tt UPNP_E_LISTEN}: An error occurred listening to a socket.
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: An error ocurred creating a socket.
- *      \item {\tt UPNP_E_INTERNAL_ERROR}: An internal error ocurred.
- *    \end{itemize} */
-
-EXPORT_SPEC int UpnpInit(
-    IN const char *HostIP,      /** The host IP address to use, in 
-                                    string format, for example "192.168.0.1", 
-                                    or {\tt NULL} to use the first adapter's 
-                                    IP address. */
-    IN unsigned short DestPort, /** The destination port number to use.  0 
-                                    will pick an arbitrary free port. */
-    IN int maxHTTPTimeoutRetries, /** maximum number of retries when select 
-                                      times out on sending data, use a 
-                                      negative value to disable this feature **/
-    IN void *thread_cleanup  /** A user defined callback function that 
-                                    will get triggered each time a thread dies
-                                    (only for threads that were calling other
-                                    user callbacks). We need this to allow
-                                    extra cleanup, for example for MySQL */
-    );
-
-/** Terminates the Linux SDK for UPnP Devices. This function must be the last 
- *  API function called. It should be called only once. Subsequent calls to 
- *  this API return a {\tt UPNP_E_FINISH} error code.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_FINISH}: The SDK is already terminated or 
- *                                 it is not initialized. 
- *    \end{itemize} */
-
-EXPORT_SPEC int UpnpFinish();
-
-/** If '0' is used as the port number in {\bf UpnpInit}, then this
- *  function can be used to retrieve the actual port allocated to
- *  the SDK. If {\bf UpnpInit} has not succeeded then 0 is 
- *  returned.
- *
- *  @return [unsigned short] The port on which an internal server is 
- *                           listening for UPnP related requests. 
- */
-EXPORT_SPEC unsigned short UpnpGetServerPort(void);
-
-/** If {\tt NULL} is used as the IP address in {\bf UpnpInit}, then this
- *  function can be used to retrieve the actual interface address
- *  on which device is running. If {\bf UpnpInit} has not succeeded 
- *  then {\tt NULL} is returned.
- *
- *  @return [char*] The IP address on which an internal server is listening 
- *                  for UPnP related requests. 
- */
-EXPORT_SPEC char * UpnpGetServerIpAddress(void);
-
-/** {\bf UpnpRegisterClient} registers a control point application with the
- *  SDK.  A control point application cannot make any other API calls
- *  until it registers using this function.
- *
- *  {\bf UpnpRegisterClient} is a synchronous call and generates no callbacks.
- *  Callbacks can occur as soon as this function returns.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_FINISH}: The SDK is already terminated or 
- *                                 is not initialized. 
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf Callback} or {\bf Hnd} 
- *              is not a valid pointer.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              register this control point.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpRegisterClient(
-    IN Upnp_FunPtr Callback,   /** Pointer to a function for receiving 
-                                   asynchronous events. */
-    IN const void *Cookie,     /** Pointer to user data returned with the 
-                                   callback function when invoked. */
-    OUT UpnpClient_Handle *Hnd /** Pointer to a variable to store the 
-                                   new control point handle. */
-    );  
-
-/** {\bf UpnpRegisterRootDevice} registers a device application with
- *  the SDK.  A device application cannot make any other API
- *  calls until it registers using this function.  Device applications
- *  can also register as control points (see {\bf UpnpRegisterClient}
- *  to get a control point handle to perform control point
- *  functionality).
- *
- *  {\bf UpnpRegisterRootDevice} is synchronous and does not generate
- *  any callbacks.  Callbacks can occur as soon as this function returns.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_FINISH}: The SDK is already terminated or 
- *                                 is not initialized. 
- *      \item {\tt UPNP_E_INVALID_DESC}: The description document was not 
- *              a valid device description.
- *      \item {\tt UPNP_E_INVALID_URL}: The URL for the description document 
- *              is not valid.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf Callback} or {\bf Hnd} 
- *              is not a valid pointer or {\bf DescURL} is {\tt NULL}.
- *      \item {\tt UPNP_E_NETWORK_ERROR}: A network error occurred.
- *      \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing 
- *              to a socket.
- *      \item {\tt UPNP_E_SOCKET_READ}: An error or timeout occurred reading 
- *              from a socket.
- *      \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding a socket.
- *      \item {\tt UPNP_E_SOCKET_CONNECT}: An error occurred connecting the 
- *              socket.
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: Too many sockets are currently 
- *              allocated.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: There are insufficient resources to 
- *              register this root device.
- *    \end{itemize} */
-
-EXPORT_SPEC int UpnpRegisterRootDevice(
-    IN const char *DescUrl,    /** Pointer to a string containing the 
-                                   description URL for this root device 
-                                   instance. */
-    IN Upnp_FunPtr Callback,   /** Pointer to the callback function for 
-                                   receiving asynchronous events. */
-    IN const void *Cookie,     /** Pointer to user data returned with the 
-                                   callback function when invoked. */
-    OUT UpnpDevice_Handle *Hnd /** Pointer to a variable to store the 
-                                   new device handle. */
-    );
-
-/** {\bf UpnpRegisterRootDevice2} is similar to {\bf UpnpRegisterRootDevice},
- *  except that it also allows the description document to be specified as a 
- *  file or a memory buffer. The description can also be configured to have the
- *  correct IP and port address.
- *
- *  NOTE: For the configuration to be functional, the internal web server
- *  MUST be present. In addition, the web server MUST be activated
- *  (using {\bf UpnpSetWebServerRootDir}) before calling this function.
- *  The only condition where the web server can be absent is if the 
- *  description document is specified as a URL and no configuration is 
- *  required (i.e. {\tt config_baseURL = 0}.)
- *
- *  {\bf UpnpRegisterRootDevice2} is synchronous and does not generate
- *  any callbacks.  Callbacks can occur as soon as this function returns.
- *
- *  Examples of using different types of description documents:
- *  \begin{verbatim}
-    1) Description specified as a URL:
-          descriptionType == UPNPREG_URL_DESC
-          description is the URL
-          bufferLen = 0 (ignored)
-    2) Description specified as a file:
-          descriptionType == UPNPREG_FILENAME_DESC
-          description is a filename
-          bufferLen = 0 (ignored)
-    3) Description specified as a memory buffer:
-          descriptionType == UPNPREG_BUF_DESC
-          description is pointer to a memory buffer
-          bufferLen == length of memory buffer
-    \end{verbatim}
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_FINISH}: The SDK is already terminated or 
- *                                 is not initialized.
- *      \item {\tt UPNP_E_INVALID_DESC}: The description document is not 
- *              a valid device description.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf Callback} or {\bf Hnd} 
- *              is not a valid pointer or {\bf DescURL} is {\tt NULL}.
- *      \item {\tt UPNP_E_NETWORK_ERROR}: A network error occurred.
- *      \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing 
- *              to a socket.
- *      \item {\tt UPNP_E_SOCKET_READ}: An error or timeout occurred reading 
- *              from a socket.
- *      \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding a socket.
- *      \item {\tt UPNP_E_SOCKET_CONNECT}: An error occurred connecting the 
- *              socket.
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: Too many sockets are currently 
- *              allocated.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: There are insufficient resources to 
- *              register this root device.
- *      \item {\tt UPNP_E_URL_TOO_BIG}: Length of the URL is bigger than the 
- *              internal buffer.
- *      \item {\tt UPNP_E_FILE_NOT_FOUND}: The description file could not 
- *              be found.
- *      \item {\tt UPNP_E_FILE_READ_ERROR}: An error occurred reading the 
- *              description file.
- *      \item {\tt UPNP_E_INVALID_URL}: The URL to the description document 
- *              is invalid.
- *      \item {\tt UPNP_E_EXT_NOT_XML}: The URL to the description document 
- *              or file should have a {\tt .xml} extension.
- *      \item {\tt UPNP_E_NO_WEB_SERVER}: The internal web server has been 
- *              compiled out; the SDK cannot configure itself from the 
- *              description document.
- *    \end{itemize} */
- 
-EXPORT_SPEC int UpnpRegisterRootDevice2(
-    IN Upnp_DescType descriptionType,/** The type of the description 
-                                         document. */
-    IN const char* description,      /** Treated as a URL, file name or 
-                                         memory buffer depending on 
-                                         description type. */
-    IN size_t bufferLen,             /** The length of memory buffer if 
-                                         passing a description in a buffer, 
-                                         otherwise it is ignored. */
-    IN int config_baseURL,           /** If nonzero, {\tt URLBase} of 
-                                         description document is 
-                                         configured and the description 
-                                         is served using the internal 
-                                         web server. */
-    IN Upnp_FunPtr Fun,              /** Pointer to the callback function 
-                                         for receiving asynchronous 
-                                         events. */
-    IN const void* Cookie,           /** Pointer to user data returned 
-                                         with the callback function when 
-                                         invoked. */
-    OUT UpnpDevice_Handle* Hnd       /** Pointer to a variable to store 
-                                         the new device handle. */
-    );
-
-/** {\bf UpnpUnRegisterClient} unregisters a control point application, 
- *  unsubscribing all active subscriptions. After this call, the 
- *  {\bf UpnpClient_Handle} is no longer valid.
- *
- *  {\bf UpnpUnRegisterClient} is a synchronous call and generates no
- *  callbacks.  The SDK generates no more callbacks after this 
- *  function returns.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid control 
- *                   point handle.
- *    \end{itemize} */
-
-EXPORT_SPEC int UpnpUnRegisterClient(
-    IN UpnpClient_Handle Hnd  /** The handle of the control point instance 
-                                  to unregister. */
-    );
-
-/** Unregisters a root device registered with {\bf UpnpRegisterRootDevice} or
- *  {\bf UpnpRegisterRootDevice2}. After this call, the 
- *  {\bf UpnpDevice_Handle} is no longer valid. For all advertisements that 
- *  have not yet expired, the SDK sends a device unavailable message 
- *  automatically.
- *
- *  {\bf UpnpUnRegisterRootDevice} is a synchronous call and generates no
- *  callbacks.  Once this call returns, the SDK will no longer 
- *  generate callbacks to the application.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid  
- *              device handle.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpUnRegisterRootDevice(
-   IN UpnpDevice_Handle /** The handle of the root device instance to 
-                            unregister. */
-   );
-
-
-/** OBSOLETE METHOD : use {\bf UpnpSetMaxContentLength} instead.
- * Warning: the Handle argument provided here is not used, so the effect
- * of this function is global to the SDK (= same as 
- * {\bf UpnpSetMaxContentLength} ).
- */
-EXPORT_SPEC int UpnpSetContentLength(
-    IN UpnpClient_Handle Hnd,  
-    IN int contentLength       
-    );
-
-
-/** Sets the maximum content-length that the SDK will process on an incoming 
- *  SOAP requests or responses. This API allows devices that have memory 
- *  constraints to exhibit consistent behaviour if the size of the 
- *  incoming SOAP message exceeds the memory that device can allocate. 
- *  The default maximum content-length is {\tt DEFAULT_SOAP_CONTENT_LENGTH} 
- *  = 16K bytes.
- *   
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *    \end{itemize}
- */
-EXPORT_SPEC int UpnpSetMaxContentLength(
-    IN size_t contentLength    /** The maximum permissible content length 
-			           for incoming SOAP actions, in bytes. */
-    );
-
-//@} // Initialization and Registration
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-//                                                                    //
-//                        D I S C O V E R Y                           //
-//                                                                    //
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-///@name Discovery
-//@{
-
-/** {\bf UpnpSearchAsync} searches for devices matching the given
- *  search target.  The function returns immediately and the SDK 
- *  calls the default callback function, registered during the 
- *  {\bf UpnpRegisterClient} call, for each matching root device,
- *  device, or service.  The application specifies the search type by the 
- *  {\bf Target} parameter.  
- *
- *  Note that there is no way for the SDK to distinguish which client
- *  instance issued a particular search.  Therefore, the client can get
- *  search callbacks that do not match the original criteria of the search.
- *  Also, the application will receive multiple callbacks for each search.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid control 
- *              point handle.
- *      \item {\tt UPNP_E_INVALID_PARAM}: {\bf Target} is {\tt NULL}.
- *    \end{itemize} */
-
-EXPORT_SPEC int UpnpSearchAsync(
-    IN UpnpClient_Handle Hnd, /** The handle of the client performing 
-                                  the search. */
-    IN int Mx,                /** The time, in seconds, to wait for 
-                                  responses. If the time is greater 
-                                  than {\tt MAX_SEARCH_TIME} then the time is 
-                                  set to {\tt MAX_SEARCH_TIME}. If the time is 
-                                  less than {\tt MIN_SEARCH_TIME} then the 
-                                  time is set to {\tt MIN_SEARCH_TIME}. */ 
-    IN const char *Target,    /** The search target as defined in the UPnP 
-                                  Device Architecture v1.0 specification. */
-    IN const void *Cookie     /** The user data to pass when the callback 
-                                  function is invoked. */
-    ); 
-
-/** {\bf UpnpSendAdvertisement} sends out the discovery announcements for
- *  all devices and services for a device.  Each announcement is made with
- *  the same expiration time.
- *
- *  {\bf UpnpSendAdvertisement} is a synchronous call.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid 
- *              device handle.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: There are insufficient resources to 
- *              send future advertisements.
- *    \end{itemize}
- */
-EXPORT_SPEC int UpnpSendAdvertisement(
-    IN UpnpDevice_Handle Hnd, /** The device handle for which to send out the 
-                                  announcements. */
-    IN int Exp                /** The expiration age, in seconds, of 
-                                  the announcements. */
-    );
-
-//@} // Discovery
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-//                                                                    //
-//                            C O N T R O L                           //
-//                                                                    //
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-///@name Control
-//@{
-
-/** {\bf UpnpGetServiceVarStatus} queries the state of a state 
- *  variable of a service on another device.  This is a synchronous call.
- *  A positive return value indicates a SOAP error code, whereas a negative
- *  return code indicates an SDK error code. {\bf Note that the use of this 
- *  function is deprecated by the UPnP Forum}.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid control 
- *              point handle.
- *      \item {\tt UPNP_E_INVALID_URL}: {\bf ActionUrl} is not a valid URL.
- *      \item {\tt UPNP_E_INVALID_DESC}: The XML document was not 
- *              found or it does not contain a valid XML description.
- *      \item {\tt UPNP_E_INVALID_PARAM}: {\bf StVarVal} is not a valid 
- *              pointer or {\bf VarName} or {\bf ActionUrl} is {\tt NULL}. 
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *      \item {\tt UPNP_SOAP_E_INVALID_VAR}: The given variable is invalid 
- *              according to the device.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpGetServiceVarStatus(
-    IN UpnpClient_Handle Hnd,     /** The handle of the control point. */
-    IN const char *ActionURL,     /** The URL of the service. */
-    IN const char *VarName,       /** The name of the variable to query. */
-    OUT DOMString *StVarVal       /** The pointer to store the value 
-                                      for {\bf VarName}. The SDK 
-                                      allocates this string and the caller 
-                                      needs to free it using 
-				      {\bf ixmlFreeDOMString}. */
-    );
-
-/** {\bf UpnpGetServiceVarStatusAsync} queries the state of a variable of a 
- *  service, generating a callback when the operation is complete. {\bf Note 
- *  that the use of this function is deprecated by the UPnP Forum}.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid control 
- *              point handle.
- *      \item {\tt UPNP_E_INVALID_URL}: The {\bf ActionUrl} is not a valid URL.
- *      \item {\tt UPNP_E_INVALID_PARAM}: {\bf VarName}, {\bf Fun} or 
- *              {\bf ActionUrl} is not a valid pointer.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpGetServiceVarStatusAsync(
-    IN UpnpClient_Handle Hnd, /** The handle of the control point. */
-    IN const char *ActionURL, /** The URL of the service. */
-    IN const char *VarName,   /** The name of the variable to query. */
-    IN Upnp_FunPtr Fun,       /** Pointer to a callback function to 
-                                  be invoked when the operation is complete. */
-    IN const void *Cookie     /** Pointer to user data to pass to the 
-                                  callback function when invoked. */
-    );
-
-/** {\bf UpnpSendAction} sends a message to change a state variable
- *  in a service.  This is a synchronous call that does not return until the 
- *  action is complete.
- * 
- *  Note that a positive return value indicates a SOAP-protocol error code.
- *  In this case,  the error description can be retrieved from {\bf RespNode}.
- *  A negative return value indicates an SDK error.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid control 
- *              point handle.
- *      \item {\tt UPNP_E_INVALID_URL}: {\bf ActionUrl} is not a valid URL.
- *      \item {\tt UPNP_E_INVALID_ACTION}: This action is not valid.
- *      \item {\tt UPNP_E_INVALID_DEVICE}: {\bf DevUDN} is not a 
- *              valid device.
- *      \item {\tt UPNP_E_INVALID_PARAM}: {\bf ServiceType}, {\bf Action}, 
- *              {\bf ActionUrl}, or 
- *              {\bf RespNode} is not a valid pointer.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpSendAction(
-    IN UpnpClient_Handle Hnd,     /** The handle of the control point 
-                                      sending the action. */
-    IN const char *ActionURL,     /** The action URL of the service. */
-    IN const char *ServiceType,   /** The type of the service. */
-    IN const char *DevUDN,        /** This parameter is ignored and must be
-				      {\tt NULL}. */
-    IN IXML_Document *Action,     /** The DOM document for the action. */
-    OUT IXML_Document **RespNode  /** The DOM document for the response 
-                                    to the action.  The SDK allocates 
-                                    this document and the caller needs to free 
-                                    it.  */
-   );
-
-/** {\bf UpnpSendActionEx} sends a message to change a state variable
- *  in a service.  This is a synchronous call that does not return until the 
- *  action is complete.
- *
- *  Note that a positive return value indicates a SOAP-protocol error code.
- *  In this case,  the error description can be retrieved from {\bf RespNode}.
- *  A negative return value indicates an SDK error.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid control 
- *              point handle.
- *      \item {\tt UPNP_E_INVALID_URL}: {\bf ActionUrl} is not a valid URL.
- *      \item {\tt UPNP_E_INVALID_ACTION}: This action is not valid.
- *      \item {\tt UPNP_E_INVALID_DEVICE}: {\bf DevUDN} is not a 
- *              valid device.
- *      \item {\tt UPNP_E_INVALID_PARAM}: {\bf ServiceType}, {\bf Action}, 
- *              {\bf ActionUrl}, or 
- *              {\bf RespNode} is not a valid pointer.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpSendActionEx(
-    IN UpnpClient_Handle Hnd,    /** The handle of the control point 
-                                     sending the action. */
-    IN const char *ActionURL,    /** The action URL of the service. */
-    IN const char *ServiceType,  /** The type of the service. */
-    IN const char *DevUDN,       /** This parameter is ignored and must be
-				     {\tt NULL}. */
-    IN IXML_Document *Header,    /** The DOM document for the SOAP header. 
-                                     This may be {\tt NULL} if the header is 
-				     not required. */
-    IN IXML_Document *Action,    /** The DOM document for the action. */
-    OUT IXML_Document **RespNode /** The DOM document for the response 
-                                     to the action.  The SDK allocates 
-                                     this document and the caller needs to free 
-                                     it.  */
-   );
-
-/** {\bf UpnpSendActionAsync} sends a message to change a state variable
- *  in a service, generating a callback when the operation is complete.
- *  See {\bf UpnpSendAction} for comments on positive return values. These 
- *  positive return values are sent in the event struct associated with the
- *  {\tt UPNP_CONTROL_ACTION_COMPLETE} event.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid control 
- *              point handle.
- *      \item {\tt UPNP_E_INVALID_URL}: {\bf ActionUrl} is an invalid URL.
- *      \item {\tt UPNP_E_INVALID_DEVICE}: {\bf DevUDN} is an invalid device.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf Fun} is not a valid 
- *              callback function or {\bf ServiceType}, {\bf Act}, or 
- *              {\bf ActionUrl} is {\tt NULL}.
- *      \item {\tt UPNP_E_INVALID_ACTION}: This action is not valid.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpSendActionAsync(
-    IN UpnpClient_Handle Hnd,   /** The handle of the control point 
-                                    sending the action. */
-    IN const char *ActionURL,   /** The action URL of the service. */
-    IN const char *ServiceType, /** The type of the service. */
-    IN const char *DevUDN,      /** This parameter is ignored and must be
-				    {\tt NULL}. */
-    IN IXML_Document *Action,   /** The DOM document for the action to 
-                                    perform on this device. */
-    IN Upnp_FunPtr Fun,         /** Pointer to a callback function to 
-                                    be invoked when the operation 
-		                    completes. */
-    IN const void *Cookie       /** Pointer to user data that to be 
-                                    passed to the callback when invoked. */
-    );
-
-/** {\bf UpnpSendActionExAsync} sends a message to change a state variable
- *  in a service, generating a callback when the operation is complete.
- *  See {\bf UpnpSendAction} for comments on positive return values. These 
- *  positive return values are sent in the event struct associated with the
- *  {\tt UPNP_CONTROL_ACTION_COMPLETE} event.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid control 
- *              point handle.
- *      \item {\tt UPNP_E_INVALID_URL}: {\bf ActionUrl} is an invalid URL.
- *      \item {\tt UPNP_E_INVALID_DEVICE}: {\bf DevUDN} is an invalid device.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf Fun} is not a valid 
- *              callback function or {\bf ServiceType}, {\bf Act}, or 
- *              {\bf ActionUrl} is {\tt NULL}.
- *      \item {\tt UPNP_E_INVALID_ACTION}: This action is not valid.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpSendActionExAsync(
-    IN UpnpClient_Handle Hnd,   /** The handle of the control point 
-                                    sending the action. */
-    IN const char *ActionURL,   /** The action URL of the service. */
-    IN const char *ServiceType, /** The type of the service. */
-    IN const char *DevUDN,      /** This parameter is ignored and must be
-				    {\tt NULL}. */
-    IN IXML_Document *Header,   /** The DOM document for the SOAP header. 
-                                    This may be {\tt NULL} if the header is 
-				    not required. */
-    IN IXML_Document *Action,   /** The DOM document for the action to 
-                                    perform on this device. */
-    IN Upnp_FunPtr Fun,         /** Pointer to a callback function to 
-                                    be invoked when the operation 
-				    completes. */
-    IN const void *Cookie       /** Pointer to user data that to be 
-                                    passed to the callback when invoked. */
-    );
-
-//@} // Control
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-//                                                                    //
-//                        E V E N T I N G                             //
-//                                                                    //
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-///@name Eventing
-//@{
-
-/** {\bf UpnpAcceptSubscription} accepts a subscription request and sends
- *  out the current state of the eventable variables for a service.  
- *  The device application should call this function when it receives a 
- *  {\tt UPNP_EVENT_SUBSCRIPTION_REQUEST} callback. This function is 
- *  synchronous and generates no callbacks.
- *
- *  {\bf UpnpAcceptSubscription} can be called during the execution of 
- *  a callback function.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid device 
- *              handle.
- *      \item {\tt UPNP_E_INVALID_SERVICE}: The {\bf DevId}/{\bf ServId} 
- *              pair refers to an invalid service. 
- *      \item {\tt UPNP_E_INVALID_SID}: The specified subscription ID is not 
- *              valid.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf VarName}, 
- *              {\bf NewVal}, {\bf DevID}, or {\bf ServID} is not a valid 
- *              pointer or {\bf cVariables} is less than zero.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpAcceptSubscription(
-    IN UpnpDevice_Handle Hnd, /** The handle of the device. */
-    IN const char *DevID,     /** The device ID of the subdevice of the 
-                                  service generating the event. */
-    IN const char *ServID,    /** The unique service identifier of the service 
-                                  generating the event. */
-    IN const char **VarName,  /** Pointer to an array of event variables. */
-    IN const char **NewVal,   /** Pointer to an array of values for 
-                                  the event variables. */
-    IN int cVariables,        /** The number of event variables in 
-                                  {\bf VarName}. */
-    IN Upnp_SID SubsId        /** The subscription ID of the newly 
-                                  registered control point. */
-    );
-
-/** {\bf UpnpAcceptSubscriptionExt} is similar to {\bf UpnpAcceptSubscription}
- *  except that it takes a DOM document for the variables to event rather
- *  than an array of strings. This function is sychronous
- *  and generates no callbacks.
- *
- *  {\bf UpnpAcceptSubscriptionExt} can be called during the execution of 
- *  a callback function.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid device 
- *              handle.
- *      \item {\tt UPNP_E_INVALID_SERVICE}: The {\bf DevId}/{\bf ServId} 
- *              pair refers to an invalid service. 
- *      \item {\tt UPNP_E_INVALID_SID}: The specified subscription ID is not 
- *              valid.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf VarName},  
- *              {\bf NewVal}, {\bf DevID}, {\bf ServID}, or {\bf PropSet} 
- *              is not a valid pointer.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpAcceptSubscriptionExt(
-    IN UpnpDevice_Handle Hnd,  /** The handle of the device. */
-    IN const char *DevID,      /** The device ID of the subdevice of the 
-                                   service generating the event. */
-    IN const char *ServID,     /** The unique service identifier of the service 
-                                   generating the event. */
-    IN IXML_Document *PropSet, /** The DOM document for the property set. 
-                                   Property set documents must conform to
-                                   the XML schema defined in section 4.3 of the
-                                   Universal Plug and Play Device Architecture
-                                   specification. */
-    IN Upnp_SID SubsId         /** The subscription ID of the newly 
-                                   registered control point. */
-    );
-
-/** {\bf UpnpNotify} sends out an event change notification to all
- *  control points subscribed to a particular service.  This function is
- *  synchronous and generates no callbacks.
- *
- *  {\bf UpnpNotify} may be called during a callback function to send out
- *  a notification.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid device 
- *              handle.
- *      \item {\tt UPNP_E_INVALID_SERVICE}: The {\bf DevId}/{\bf ServId} 
- *              pair refers to an invalid service.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf VarName}, {\bf NewVal}, 
- *               {\bf DevID}, or {\bf ServID} is not a valid pointer or 
- *               {\bf cVariables} is less than zero.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpNotify(
-    IN UpnpDevice_Handle,   /** The handle to the device sending the event. */
-    IN const char *DevID,   /** The device ID of the subdevice of the service 
-                                generating the event. */
-    IN const char *ServID,  /** The unique identifier of the service 
-                                generating the event. */
-    IN const char **VarName,/** Pointer to an array of variables that 
-                                have changed. */
-    IN const char **NewVal, /** Pointer to an array of new values for 
-                                those variables. */
-    IN int cVariables       /** The count of variables included in this 
-                                notification. */
-    );
-
-/** {\bf UpnpNotifyExt} is similar to {\bf UpnpNotify} except that it takes
- *  a DOM document for the event rather than an array of strings. This 
- *  function is synchronous and generates no callbacks.
- *
- *  {\bf UpnpNotifyExt} may be called during a callback function to send out
- *  a notification.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid device 
- *              handle.
- *      \item {\tt UPNP_E_INVALID_SERVICE}: The {\bf DevId}/{\bf ServId} 
- *              pair refers to an invalid service.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf VarName}, {\bf NewVal}, 
- *               {\bf DevID}, {\bf ServID}, or {\bf PropSet} 
- *               is not a valid pointer or {\bf cVariables} is less than zero.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpNotifyExt(
-    IN UpnpDevice_Handle,       /** The handle to the device sending the 
-                                    event. */
-    IN const char *DevID,       /** The device ID of the subdevice of the 
-                                    service generating the event. */
-    IN const char *ServID,      /** The unique identifier of the service 
-                                    generating the event. */
-    IN IXML_Document *PropSet   /** The DOM document for the property set. 
-                                    Property set documents must conform to 
-                                    the XML schema defined in section 4.3 of 
-                                    the Universal Plug and Play Device 
-                                    Architecture specification. */
-    );
-
-/** {\bf UpnpRenewSubscription} renews a subscription that is about to 
- *  expire.  This function is synchronous.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid control 
- *              point handle.
- *      \item {\tt UPNP_E_INVALID_PARAM}: {\bf Timeout} is not a valid pointer.
- *      \item {\tt UPNP_E_INVALID_SID}: The SID being passed to this function 
- *              is not a valid subscription ID.
- *      \item {\tt UPNP_E_NETWORK_ERROR}: A network error occured. 
- *      \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing 
- *              to a socket.
- *      \item {\tt UPNP_E_SOCKET_READ}: An error or timeout occurred reading 
- *              from a socket.
- *      \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding a socket.  
- *      \item {\tt UPNP_E_SOCKET_CONNECT}: An error occurred connecting to 
- *              {\bf PublisherUrl}.
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: An error occurred creating a socket.
- *      \item {\tt UPNP_E_BAD_RESPONSE}: An error occurred in response from 
- *              the publisher.
- *      \item {\tt UPNP_E_SUBSCRIBE_UNACCEPTED}: The publisher refused 
- *              the subscription renew.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpRenewSubscription(
-    IN UpnpClient_Handle Hnd, /** The handle of the control point that 
-                                  is renewing the subscription. */
-    INOUT int *TimeOut,       /** Pointer to a variable containing the 
-                                  requested subscription time.  Upon return, 
-                                  it contains the actual renewal time. */
-    IN Upnp_SID SubsId        /** The ID for the subscription to renew. */
-    );
-
-/** {\bf UpnpRenewSubscriptionAsync} renews a subscription that is about
- *  to expire, generating a callback when the operation is complete.
- *
- *  Note that many of the error codes for this function are returned in
- *  the {\bf Upnp_Event_Subscribe} structure.  In those cases, the function
- *  returns {\tt UPNP_E_SUCCESS} and the appropriate error code will
- *  be in the {\bf Upnp_Event_Subscribe.ErrCode} field in the {\bf Event}
- *  structure passed to the callback.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid control 
- *              point handle.
- *      \item {\tt UPNP_E_INVALID_SID}: The {\bf SubsId} is not a valid 
- *              subscription ID.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf Fun} is not a valid 
- *              callback function pointer or {\bf Timeout} is less than zero 
- *              but is not {\tt UPNP_INFINITE}.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *      \item {\tt UPNP_E_NETWORK_ERROR}: A network error occured (returned in 
- *              the {\bf Upnp_Event_Subscribe.ErrCode} field as part of the 
- *              callback).
- *      \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing 
- *              to a socket (returned in the {\bf Upnp_Event_Subscribe.ErrCode} 
- *              field as part of the callback).
- *      \item {\tt UPNP_E_SOCKET_READ}: An error or timeout occurred reading  
- *              from a socket (returned in the 
- *              {\bf Upnp_Event_Subscribe.ErrCode} field as part of the 
- *              callback).
- *      \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding the socket 
- *              (returned in the {\bf Upnp_Event_Subscribe.ErrCode} field as 
- *              part of the callback).
- *      \item {\tt UPNP_E_SOCKET_CONNECT}: An error occurred connecting to 
- *              {\bf PublisherUrl} (returned in the {\bf 
- *              Upnp_Event_Subscribe.ErrCode} field as part of the callback).
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: An error occurred creating socket (
- *              returned in the {\bf Upnp_Event_Subscribe.ErrCode} field as 
- *              part of the callback).
- *      \item {\tt UPNP_E_BAD_RESPONSE}: An error occurred in response from 
- *              the publisher (returned in the {\bf 
- *              Upnp_Event_Subscribe.ErrCode} field as part of the callback).
- *      \item {\tt UPNP_E_SUBSCRIBE_UNACCEPTED}: The publisher refused 
- *              the subscription request (returned in the {\bf 
- *              Upnp_Event_Subscribe.ErrCode} field as part of the callback).
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpRenewSubscriptionAsync(
-    IN UpnpClient_Handle Hnd, /** The handle of the control point that 
-                                  is renewing the subscription. */
-    IN int TimeOut,           /** The requested subscription time.  The 
-                                  actual timeout value is returned when 
-                                  the callback function is called. */
-    IN Upnp_SID SubsId,       /** The ID for the subscription to renew. */
-    IN Upnp_FunPtr Fun,       /** Pointer to a callback function to be 
-                                  invoked when the renewal is complete. */
-    IN const void *Cookie     /** Pointer to user data passed 
-                                  to the callback function when invoked. */
-    );
-
-/** {\bf UpnpSetMaxSubscriptions} sets the maximum number of subscriptions 
- *  accepted per service. The default value accepts as many as system 
- *  resources allow. If the number of current subscriptions for a service is 
- *  greater than the requested value, the SDK accepts no new 
- *  subscriptions or renewals, however, the SDK does not remove
- *  any current subscriptions.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid device 
- *              handle.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpSetMaxSubscriptions(  
-    IN UpnpDevice_Handle Hnd, /** The handle of the device for which 
-				  the maximum number of subscriptions is 
-				  being set. */
-    IN int MaxSubscriptions   /** The maximum number of subscriptions to be 
-				  allowed per service. */
-    );
-
-/** {\bf UpnpSetMaxSubscriptionTimeOut} sets the maximum time-out accepted
- *  for a subscription request or renewal. The default value accepts the 
- *  time-out set by the control point. If a control point requests a 
- *  subscription time-out less than or equal to the maximum, the SDK
- *  grants the value requested by the control point.  If the time-out 
- *  is greater, the SDK returns the maximum value.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid device 
- *              handle.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpSetMaxSubscriptionTimeOut(  
-    IN UpnpDevice_Handle Hnd,       /** The handle of the device for which 
-				        the maximum subscription time-out is 
-                                        being set. */
-    IN int MaxSubscriptionTimeOut   /** The maximum subscription time-out to 
-                                        be accepted. */
-    );
-
-/** {\bf UpnpSubscribe} registers a control point to receive event
- *  notifications from another device.  This operation is synchronous.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid control 
- *              point handle.
- *      \item {\tt UPNP_E_INVALID_URL}: {\bf PublisherUrl} is not a valid URL.
- *      \item {\tt UPNP_E_INVALID_PARAM}: {\bf Timeout} is not a valid pointer 
- *              or {\bf SubsId} or {\bf PublisherUrl} is {\tt NULL}.
- *      \item {\tt UPNP_E_NETWORK_ERROR}: A network error occured. 
- *      \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing 
- *              to a socket.
- *      \item {\tt UPNP_E_SOCKET_READ}: An error or timeout occurred reading 
- *              from a socket.
- *      \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding a socket.
- *      \item {\tt UPNP_E_SOCKET_CONNECT}: An error occurred connecting to 
- *              {\bf PublisherUrl}.
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: An error occurred creating a socket.
- *      \item {\tt UPNP_E_BAD_RESPONSE}: An error occurred in response from 
- *              the publisher.
- *      \item {\tt UPNP_E_SUBSCRIBE_UNACCEPTED}: The publisher refused 
- *              the subscription request.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpSubscribe(
-    IN UpnpClient_Handle Hnd,    /** The handle of the control point. */
-    IN const char *PublisherUrl, /** The URL of the service to subscribe to. */
-    INOUT int *TimeOut,          /** Pointer to a variable containing 
-                                     the requested subscription time.  Upon 
-                                     return, it contains the actual 
-                                     subscription time returned from the 
-                                     service. */
-    OUT Upnp_SID SubsId          /** Pointer to a variable to receive the 
-                                     subscription ID (SID). */
-    );
-
-/** {\bf UpnpSubscribeAsync} performs the same operation as
- *  {\bf UpnpSubscribe}, but returns immediately and calls the registered
- *  callback function when the operation is complete.
- *
- *  Note that many of the error codes for this function are returned in
- *  the {\bf Upnp_Event_Subscribe} structure.  In those cases, the function
- *  returns {\tt UPNP_E_SUCCESS} and the appropriate error code will
- *  be in the {\bf Upnp_Event_Subscribe.ErrCode} field in the {\bf Event}
- *  structure passed to the callback.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid control 
- *              point handle.
- *      \item {\tt UPNP_E_INVALID_URL}: The {\bf PublisherUrl} is not a valid 
- *              URL.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf TimeOut} or {\bf Fun} or 
- *              {\bf PublisherUrl} is not a valid pointer.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *      \item {\tt UPNP_E_NETWORK_ERROR}: A network error occured (returned in 
- *              the {\bf Upnp_Event_Subscribe.ErrCode} field as part of the 
- *              callback).
- *      \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing 
- *              to a socket (returned in the 
- *              {\bf Upnp_Event_Subscribe.ErrCode} field as part of the 
- *              callback).
- *      \item {\tt UPNP_E_SOCKET_READ}: An error or timeout occurred reading 
- *              from a socket (returned in the 
- *              {\bf Upnp_Event_Subscribe.ErrCode} field as part of the 
- *              callback).
- *      \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding the socket 
- *              (returned in the {\bf Upnp_Event_Subscribe.ErrCode} field as 
- *              part of the callback).
- *      \item {\tt UPNP_E_SOCKET_CONNECT}: An error occurred connecting to 
- *              {\bf PublisherUrl} (returned in the {\bf 
- *              Upnp_Event_Subscribe.ErrCode} field as part of the callback).
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: An error occurred creating  the 
- *              socket (returned in the {\bf Upnp_Event_Subscribe.ErrCode} 
- *              field as part of the callback).
- *      \item {\tt UPNP_E_BAD_RESPONSE}: An error occurred in response from 
- *              the publisher (returned in the {\bf 
- *              Upnp_Event_Subscribe.ErrCode} field as part of the callback).
- *      \item {\tt UPNP_E_SUBSCRIBE_UNACCEPTED}: The publisher refused 
- *              the subscription request (returned in the {\bf 
- *              Upnp_Event_Subscribe.ErrCode} field as part of the callback).
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpSubscribeAsync(
-    IN UpnpClient_Handle Hnd,      /** The handle of the control point that 
-                                       is subscribing. */
-    IN const char *PublisherUrl,   /** The URL of the service to subscribe 
-                                       to. */
-    IN int TimeOut,                /** The requested subscription time.  Upon 
-                                       return, it contains the actual 
-                                       subscription time returned from the 
-                                       service. */
-    IN Upnp_FunPtr Fun,            /** Pointer to the callback function for 
-                                       this subscribe request. */
-    IN const void *Cookie          /** A user data value passed to the 
-                                       callback function when invoked. */
-    );
-
-/** {\bf UpnpUnSubscribe} removes the subscription of  a control point from a 
- *  service previously subscribed to using {\bf UpnpSubscribe} or 
- *  {\bf UpnpSubscribeAsync}.  This is a synchronous call.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid control 
- *              point handle.
- *      \item {\tt UPNP_E_INVALID_SID}: The {\bf SubsId} is not a valid 
- *              subscription ID.
- *      \item {\tt UPNP_E_NETWORK_ERROR}: A network error occured. 
- *      \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing 
- *              to a socket.
- *      \item {\tt UPNP_E_SOCKET_READ}: An error or timeout occurred reading 
- *              from a socket.
- *      \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding a socket.
- *      \item {\tt UPNP_E_SOCKET_CONNECT}: An error occurred connecting to 
- *              {\bf PublisherUrl}.
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: An error ocurred creating a socket.
- *      \item {\tt UPNP_E_BAD_RESPONSE}: An error occurred in response from 
- *              the publisher.
- *      \item {\tt UPNP_E_UNSUBSCRIBE_UNACCEPTED}: The publisher refused 
- *              the unsubscribe request (the client is still unsubscribed and 
- *              no longer receives events).
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpUnSubscribe(
-    IN UpnpClient_Handle Hnd, /** The handle of the subscribed control 
-                                  point. */
-    IN Upnp_SID SubsId        /** The ID returned when the control point 
-                                  subscribed to the service. */
-    );
-
-/** {\bf UpnpUnSubscribeAsync} removes a subscription of a control
- *  point from a service previously subscribed to using {\bf
- *  UpnpSubscribe} or {\bf UpnpSubscribeAsync}, generating a callback
- *  when the operation is complete.
- *
- *  Note that many of the error codes for this function are returned in
- *  the {\bf Upnp_Event_Subscribe} structure.  In those cases, the function
- *  returns {\tt UPNP_E_SUCCESS} and the appropriate error code will
- *  be in the {\bf Upnp_Event_Subscribe.ErrCode} field in the {\bf Event}
- *  structure passed to the callback.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_HANDLE}: The handle is not a valid control 
- *              point handle.
- *      \item {\tt UPNP_E_INVALID_SID}: The {\bf SubsId} is not a valid SID.
- *      \item {\tt UPNP_E_INVALID_PARAM}: {\bf Fun} is not a valid callback 
- *              function pointer.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *      \item {\tt UPNP_E_NETWORK_ERROR}: A network error occured (returned in 
- *              the {\bf Upnp_Event_Subscribe.ErrCode} field as part of the 
- *              callback).
- *      \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing 
- *              to a socket (returned in the {\bf 
- *              Upnp_Event_Subscribe.ErrCode} field as part of the callback).
- *      \item {\tt UPNP_E_SOCKET_READ}: An error or timeout occurred reading 
- *              from a socket (returned in the 
- *              {\bf Upnp_Event_Subscribe.ErrCode} field as part of the 
- *              callback).
- *      \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding the socket 
- *              (returned in the {\bf Upnp_Event_Subscribe.ErrCode} field as 
- *              part of the callback).
- *      \item {\tt UPNP_E_SOCKET_CONNECT}: An error occurred connecting to 
- *              {\bf PublisherUrl} (returned in the {\bf 
- *              Upnp_Event_Subscribe.ErrCode} field as part of the callback).
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: An error occurred creating a socket (
- *              returned in the {\bf Upnp_Event_Subscribe.ErrCode} field as 
- *              part of the callback).
- *      \item {\tt UPNP_E_BAD_RESPONSE}: An error occurred in response from 
- *              the publisher (returned in the {\bf 
- *              Upnp_Event_Subscribe.ErrCode} field as part of the callback).
- *      \item {\tt UPNP_E_UNSUBSCRIBE_UNACCEPTED}: The publisher refused 
- *              the subscription request (returned in the {\bf 
- *              Upnp_Event_Subscribe.ErrCode} field as part of the callback).
- *    \end{itemize} */
-
-EXPORT_SPEC int UpnpUnSubscribeAsync(
-    IN UpnpClient_Handle Hnd, /** The handle of the subscribed control 
-                                  point. */
-    IN Upnp_SID SubsId,       /** The ID returned when the 
-                                  control point subscribed to the service. */
-    IN Upnp_FunPtr Fun,       /** Pointer to a callback function to be 
-                                  called when the operation is complete. */
-    IN const void *Cookie     /** Pointer to user data to pass to the 
-                                  callback function when invoked. */
-    );
-
-//@} // Eventing
-
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-//                                                                    //
-//                        C L I E N T - A P I                         //
-//                                                                    //
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-///@name Control Point HTTP API
-//@{
-
-/** {\bf UpnpDownloadUrlItem} downloads a file specified in a URL.
- *  The SDK allocates the memory for {\bf outBuf} and the 
- *  application is responsible for freeing this memory.  Note that
- *  the item is passed as a single buffer.  Large items should not
- *  be transferred using this function.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf url}, {\bf outBuf} 
- *              or {\bf contentType} is not a valid pointer.
- *      \item {\tt UPNP_E_INVALID_URL}: The {\bf url} is not a valid 
- *              URL.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              download this file.
- *      \item {\tt UPNP_E_NETWORK_ERROR}: A network error occurred.
- *      \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing 
- *              to a socket.
- *      \item {\tt UPNP_E_SOCKET_READ}: An error or timeout occurred reading 
- *              from a socket.
- *      \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding a socket.
- *      \item {\tt UPNP_E_SOCKET_CONNECT}: An error occurred connecting a 
- *              socket.
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: Too many sockets are currently 
- *              allocated.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpDownloadUrlItem(
-    IN const char *url,          /** URL of an item to download. */
-    OUT char **outBuf,           /** Buffer to store the downloaded item. */
-    OUT char *contentType        /** HTTP header value content type if 
-                                     present. It should be at least 
-                                     {\tt LINE_SIZE} bytes in size. */
-    );
-
-/** {\bf UpnpOpenHttpGet} gets a file specified in a URL.
- *  The SDK allocates the memory for {\bf handle} and 
- *  {\bf contentType}, the application is responsible for freeing this memory.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf url}, {\bf handle},  
- *              {\bf contentType}, {\bf contentLength} or {\bf httpStatus} 
- *		is not a valid pointer.
- *      \item {\tt UPNP_E_INVALID_URL}: The {\bf url} is not a valid 
- *              URL.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              download this file.
- *      \item {\tt UPNP_E_NETWORK_ERROR}: A network error occurred.
- *      \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing 
- *              to a socket.
- *      \item {\tt UPNP_E_SOCKET_READ}: An error or timeout occurred reading 
- *              from a socket.
- *      \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding a socket.
- *      \item {\tt UPNP_E_SOCKET_CONNECT}: An error occurred connecting a 
- *              socket.
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: Too many sockets are currently 
- *              allocated.
- *	\item {\tt UPNP_E_BAD_RESPONSE}: A bad response was received from the 
- *	        remote server.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpOpenHttpGet(
-	IN const char *url,	    /** The URL of an item to get. */
-	IN OUT void **handle,       /** A pointer to store the handle for 
-				        this connection. */
-	IN OUT char **contentType,  /** A buffer to store the media type of 
-				        the item. */
-	IN OUT off_t *contentLength,  /** A pointer to store the length of the 
-				        item. */
-	IN OUT int *httpStatus,	    /** The status returned on receiving a 
-				        response message. */
-	IN int timeout		    /** The time out value sent with the 
-				        request during which a response is 
-					expected from the server, failing 
-					which, an error is reported back to 
-					the user. */		 
-	  );
-
-/** {\bf UpnpOpenHttpGetProxy} gets a file specified in a URL through the
- * specified proxy.
- *  The SDK allocates the memory for {\bf handle} and 
- *  {\bf contentType}, the application is responsible for freeing this memory.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf url}, {\bf handle},  
- *              {\bf contentType}, {\bf contentLength} or {\bf httpStatus} 
- *		is not a valid pointer.
- *      \item {\tt UPNP_E_INVALID_URL}: The {\bf url} is not a valid 
- *              URL.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              download this file.
- *      \item {\tt UPNP_E_NETWORK_ERROR}: A network error occurred.
- *      \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing 
- *              to a socket.
- *      \item {\tt UPNP_E_SOCKET_READ}: An error or timeout occurred reading 
- *              from a socket.
- *      \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding a socket.
- *      \item {\tt UPNP_E_SOCKET_CONNECT}: An error occurred connecting a 
- *              socket.
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: Too many sockets are currently 
- *              allocated.
- *	\item {\tt UPNP_E_BAD_RESPONSE}: A bad response was received from the 
- *	        remote server.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpOpenHttpGetProxy(
-	IN const char *url,	    /** The URL of an item to get. */
-    IN const char *proxy_str,    /** The URL of the proxy. */
-	IN OUT void **handle,       /** A pointer to store the handle for 
-				        this connection. */
-	IN OUT char **contentType,  /** A buffer to store the media type of 
-				        the item. */
-	IN OUT off_t *contentLength,  /** A pointer to store the length of the 
-				        item. */
-	IN OUT int *httpStatus,	    /** The status returned on receiving a 
-				        response message. */
-	IN int timeout		    /** The time out value sent with the 
-				        request during which a response is 
-					expected from the server, failing 
-					which, an error is reported back to 
-					the user. */		 
-	  );
-
-/** {\bf UpnpOpenHttpGetEx} gets specified number of bytes from a file 
- *  specified in the URL. The number of bytes is specified through a low 
- *  count and a high count which are passed as a range of bytes for the 
- *  request.  The SDK allocates the memory for {\bf handle} and 
- *  {\bf contentType}, the application is responsible for freeing this memory.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf url}, {\bf handle},  
- *              {\bf contentType}, {\bf contentLength} or {\bf httpStatus} 
- *		is not a valid pointer.
- *      \item {\tt UPNP_E_INVALID_URL}: The {\bf url} is not a valid 
- *              URL.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              download this file.
- *      \item {\tt UPNP_E_NETWORK_ERROR}: A network error occurred.
- *      \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing 
- *              to a socket.
- *      \item {\tt UPNP_E_SOCKET_READ}: An error or timeout occurred reading 
- *              from a socket.
- *      \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding a socket.
- *      \item {\tt UPNP_E_SOCKET_CONNECT}: An error occurred connecting a 
- *              socket.
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: Too many sockets are currently 
- *              allocated.
- *	\item {\tt UPNP_E_BAD_RESPONSE}: A bad response was received from the 
- *	        remote server.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpOpenHttpGetEx(
-	IN const char *url,         /** The URL of the item to get. */
-	IN OUT void **handle,       /** A pointer to store the handle for 
-				        this connection. */
-	IN OUT char **contentType,  /** A buffer to store the media type of the 
-	                                item. */
-	IN OUT off_t *contentLength,  /** A buffer to store the length of the 
-				        item. */
-	IN OUT int *httpStatus,	    /** The status returned on receiving a 
-				        response message from the remote 
-					server. */
-	IN int lowRange,            /** An integer value representing the low 
-				        end of a range to retrieve. */
-	IN int highRange,           /** An integer value representing the high 
-				        end of a range to retrieve. */
-	IN int timeout	            /** A time out value sent with the request 
-				      	during which a response is expected 
-					from the server, failing which, an 
-					error is reported back to the user. */	
-	  );
-
-/** {\bf UpnpReadHttpGet} gets specified number of bytes from a file 
- *  specified in a URL. 
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf handle}, {\bf buf} 
- *              or {\bf size} is not a valid pointer.
- *	    \item {\tt UPNP_E_BAD_RESPONSE}: A bad response was received from the 
- *	            remote server.
- *      \item {\tt UPNP_E_BAD_HTTPMSG}: Either the request or response was in 
- *              the incorrect format.
- *      \item {\tt UPNP_E_CANCELED}: another thread called UpnpCancelHttpGet.
- *    \end{itemize}
- *
- *  Note: In case of return values, the status code parameter of the passed 
- *        in handle value may provide additional information on the return 
- *        value.
- */
-
-EXPORT_SPEC int UpnpReadHttpGet(
-	IN void *handle,           /** The token created by the call to 
-				       {\bf UpnpOpenHttpGet}. */
-	IN OUT char *buf,          /** The buffer to store the read item. */
-	IN OUT off_t *size, /** The size of the buffer to be read. */
-	IN int timeout             /** The time out value sent with the 
-				       request during which a response is 
-				       expected from the server, failing 
-				       which, an error is reported back to 
-				       the user. */
-	);
-
-/** {\bf UpnpHttpGetProgress} rettrieve progress information of a http-get 
- *  transfer. 
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf handle}, {\bf length} 
- *              or {\bf total} is not a valid pointer.
- *    \end{itemize}
- *
- */
-EXPORT_SPEC int UpnpHttpGetProgress(
-    IN void *handle,           /** The token created by the call to
-				       {\bf UpnpOpenHttpGet}. */
-	OUT off_t *length, /** The number of bytes received. */
-	OUT off_t *total   /** The content length. */
-    );
-
-
-/** {\bf UpnpCancelHttpGet} set the cancel flag of the  {\bf handle}
- * parameter. 
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: {\bf handle} is not a valid pointer.
- *    \end{itemize}
- */  
-
-EXPORT_SPEC int UpnpCancelHttpGet(IN void *handle);
-
-/** {\bf UpnpCloseHttpGet} closes the connection and frees memory that was 
- *	allocated for the {\bf handle} parameter.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: {\bf handle} is not a valid pointer.
- *    \end{itemize}
- */  
-
-EXPORT_SPEC int UpnpCloseHttpGet(IN void *handle);
-
-
-/** {\bf UpnpOpenHttpPost} makes an HTTP POST request message, opens a 
- *  connection to the server and sends the POST request to the server if 
- *  the connection to the server succeeds.
- *  The SDK allocates the memory for {\bf handle} and 
- *  {\bf contentType}, the application is responsible for freeing this memory.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf url}, {\bf handle} 
- *              or {\bf contentType} is not a valid pointer.
- *      \item {\tt UPNP_E_INVALID_URL}: The {\bf url} is not a valid 
- *              URL.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              download this file.
- *      \item {\tt UPNP_E_SOCKET_ERROR}: Error occured allocating a socket and 
- *		resources or an error occurred binding a socket.
- *      \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing 
- *              to a socket.
- *      \item {\tt UPNP_E_SOCKET_CONNECT}: An error occurred connecting a 
- *              socket.
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: Too many sockets are currently 
- *              allocated.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpOpenHttpPost(
-	IN const char *url,         /** The URL in which to send the POST 
-				        request. */
-	IN OUT void **handle,	    /** A pointer in which to store the 
-	                                handle for this connection.  This 
-					handle is required for futher 
-					operations over this connection. */
-	IN const char *contentType, /** A buffer to store the media type of 
-				        content being sent.  */
-	IN int contentLength,       /** The length of the content, in bytes, 
-				        being posted. */
-	IN int timeout              /** The time out value sent with the 
-				        request during which a response is 
-					expected from the receiver, failing 
-					which, an error is reported. */		 
-	);
-
-
-/** {\bf UpnpWriteHttpPost} sends a request to a server to copy the contents of 
- *	a buffer to the URI specified in the {\bf UpnpOpenHttpPost} call.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf handle}, {\bf buf} 
- *              or {\bf size} is not a valid pointer.
- *      \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing 
- *              to a socket.
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: Too many sockets are currently 
- *              allocated.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpWriteHttpPost(
-	IN void *handle,          /** The handle of the connection created 
-				      by the call to {\bf UpnpOpenHttpPost}. */
-	IN char *buf,             /** The buffer to be posted. */
-	IN off_t *size,    /** The size, in bytes of {\bf buf}. */
-	IN int timeout            /** A timeout value sent with the request 
-				      during which a response is expected 
-				      from the server, failing which, an 
-				      error is reported. */		 
-	);
-
-/** {\bf UpnpCloseHttpPost} sends and receives any pending data, closes the 
- *	connection with the server, and frees memory allocated during the 
- *	{\bfUpnpOpenHttpPost} call.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf handle}, or 
- *				{\bf httpStatus} is not a valid pointer.
- *      \item {\tt UPNP_E_SOCKET_READ}: An error or timeout occurred reading 
- *              from a socket.
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: Too many sockets are currently 
- *              allocated.
- *    \end{itemize}
- */
-  
-EXPORT_SPEC int UpnpCloseHttpPost(
-	IN void *handle,          /** The handle of the connection to close, 
-				      created by the call to 
-				      {\bf UpnpOpenHttpPost}. */
-	IN OUT int *httpStatus,   /** A pointer to a buffer to store the 
-	                              final status of the connection. */
-	IN int timeout            /** A time out value sent with the request 
-				      during which a response is expected from 
-				      the server, failing which, an error is 
-				      reported. */		 
-	);
-  
-
-/** {\bf UpnpDownloadXmlDoc} downloads an XML document specified in a URL.
- *  The SDK parses the document and returns it in the form of a 
- *  DOM document. The application is responsible for freeing the DOM document.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: Either {\bf url} or {\bf xmlDoc} 
- *              is not a valid pointer.
- *      \item {\tt UPNP_E_INVALID_DESC}: The XML document was not 
- *              found or it does not contain a valid XML description.
- *      \item {\tt UPNP_E_INVALID_URL}: The {\bf url} is not a valid 
- *              URL.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: There are insufficient resources to 
- *              download the XML document.
- *      \item {\tt UPNP_E_NETWORK_ERROR}: A network error occurred.
- *      \item {\tt UPNP_E_SOCKET_WRITE}: An error or timeout occurred writing 
- *              to a socket.
- *      \item {\tt UPNP_E_SOCKET_READ}: An error or timeout occurred reading 
- *              from a socket.
- *      \item {\tt UPNP_E_SOCKET_BIND}: An error occurred binding a socket.
- *      \item {\tt UPNP_E_SOCKET_CONNECT}: An error occurred connecting the 
- *              socket.
- *      \item {\tt UPNP_E_OUTOF_SOCKET}: Too many sockets are currently 
- *              allocated.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpDownloadXmlDoc(
-    IN const char *url,          /** URL of the XML document. */
-    OUT IXML_Document **xmlDoc   /** A pointer in which to store the 
-				     XML document. */
-    );
-
-//@} // Control Point HTTP API
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-//                                                                    //
-//                    W E B  S E R V E R  A P I                       //
-//                                                                    //
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-///@name Web Server API
-//@{
-
-/** {\bf UpnpSetWebServerRootDir} sets the document root directory for
- *  the internal web server. This directory is considered the
- *  root directory (i.e. "/") of the web server.
- *
- *  This function also activates or deactivates the web server.
- *  To disable the web server, pass {\tt NULL} for {\bf rootDir}; to 
- *  activate, pass a valid directory string.
- *  
- *  Note that this function is not available when the web server is not
- *  compiled into the SDK.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *       \item {\tt UPPN_E_SUCCESS}: The operation completed successfully.
- *       \item {\tt UPNP_E_INVALID_ARGUMENT}: {\bf rootDir} is an invalid 
- *               directory.
- *    \end{itemize}
- */
- 
-EXPORT_SPEC int UpnpSetWebServerRootDir( 
-    IN const char* rootDir  /** Path of the root directory of the web 
-                                server. */
-    );
-
-/** {\bf UpnpAddHTTPHeader} add a custom header to 
- *  the internal web server. All HTTP responses will contain the
- *  specified header.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *       \item {\tt UPPN_E_SUCCESS}: The operation completed successfully.
- *       \item {\tt UPNP_E_INVALID_ARGUMENT}: {\bf header_string} is empty.
- *    \end{itemize}
- */
- 
-EXPORT_SPEC int UpnpAddCustomHTTPHeader( 
-    IN const char* header_string  /** Header to add (\r\n termination not needed) */
-    );
-
-/** {\bf UpnpRemoveHTTPHeader} removes a header that was previously added
- *  with {\bf UpnpAddHTTPHeader}.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *       \item {\tt UPPN_E_SUCCESS}: The operation completed successfully.
- *       \item {\tt UPNP_E_INVALID_ARGUMENT}: {\bf dirName} is not valid.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpRemoveCustomHTTPHeader( 
-    IN const char* header_string  /** Name of the header to remove */
-    );
-
-/** {\bf UpnpRemoveAll} removes all virtual directory mappings.
- *
- *  @return [void] This function does not return a value.
- *
- */
-
-EXPORT_SPEC void UpnpRemoveAllCustomHTTPHeaders( );
-
-
-/** {\bf UpnpSetVirtualDirCallbacks} sets the callback function to be used to 
- *  access a virtual directory.  Refer to the description of
- *  {\bf UpnpVirtualDirCallbacks} for a description of the functions.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *       \item {\tt UPPN_E_SUCCESS}: The operation completed successfully.
- *       \item {\tt UPNP_E_INVALID_ARGUMENT}: {\bf callbacks} is not a valid 
- *               pointer.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpSetVirtualDirCallbacks(
-    IN struct UpnpVirtualDirCallbacks *callbacks /** Pointer to a structure 
-                                                     containing points to the 
-                                                     virtual interface 
-                                                     functions. */
-    );
-
-/** {\bf UpnpEnableWebServer} enables or disables the webserver.  A value of
- *  {\tt TRUE} enables the webserver, {\tt FALSE} disables it.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *       \item {\tt UPPN_E_SUCCESS}: The operation completed successfully.
- *       \item {\tt UPNP_E_INVALID_ARGUMENT}: {\bf enable} is not valid.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpEnableWebserver(
-    IN int enable /** {\tt TRUE} to enable, {\tt FALSE} to disable. */
-    );
-
-/** {\bf UpnpIsWebServerEnabled} returns {\tt TRUE} if the webserver is
- *  enabled, or {\tt FALSE} if it is not.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *       \item {\tt TRUE}: The webserver is enabled.
- *       \item {\tt FALSE}: The webserver is not enabled
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpIsWebserverEnabled();
-
-/** {\bf UpnpAddVirtualDir} adds a virtual directory mapping.
- *
- *  All webserver requests containing the given directory are read using
- *  functions contained in a {\bf UpnpVirtualDirCallbacks} structure registered
- *  via {\bf UpnpSetVirtualDirCallbacks}.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *       \item {\tt UPPN_E_SUCCESS}: The operation completed successfully.
- *       \item {\tt UPNP_E_INVALID_ARGUMENT}: {\bf dirName} is not valid.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpAddVirtualDir(
-    IN const char *dirName /** The name of the new directory mapping to add. 
-							*/
-    );
-
-/** {\bf UpnpRemoveVirtualDir} removes a virtual directory mapping made with
- *  {\bf UpnpAddVirtualDir}.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *       \item {\tt UPPN_E_SUCCESS}: The operation completed successfully.
- *       \item {\tt UPNP_E_INVALID_ARGUMENT}: {\bf dirName} is not valid.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpRemoveVirtualDir(
-    IN const char *dirName /** The name of the virtual directory mapping to 
-                               remove. */
-    );
-
-/** {\bf UpnpRemoveAllVirtualDirs} removes all virtual directory mappings.
- *
- *  @return [void] This function does not return a value.
- *
- */
-
-EXPORT_SPEC void UpnpRemoveAllVirtualDirs( );
-
-EXPORT_SPEC void UpnpFree(
-    IN void *item /* The item to free. */
-    );
-
-//@} // Web Server API
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-//@} The API
-
-#endif
diff --git a/tombupnp/upnp/inc/upnpconfig.h.in b/tombupnp/upnp/inc/upnpconfig.h.in
deleted file mode 100644
index 309f763..0000000
--- a/tombupnp/upnp/inc/upnpconfig.h.in
+++ /dev/null
@@ -1,96 +0,0 @@
-// -*- C -*-
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2006 Rémi Turboult <r3mi at users.sourceforge.net>
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef UPNP_CONFIG_H
-#define UPNP_CONFIG_H 
-
-
-/***************************************************************************
- * Library version 
- ***************************************************************************/ 
-
-/** The library version (string) e.g. "1.3.0" */
-#undef UPNP_VERSION_STRING
-
-/** Major version of the library */
-#undef UPNP_VERSION_MAJOR
-
-/** Minor version of the library */
-#undef UPNP_VERSION_MINOR
-
-/** Patch version of the library */
-#undef UPNP_VERSION_PATCH
-
-/** The library version (numeric) e.g. 10300 means version 1.3.0 */
-#define UPNP_VERSION	\
-  ((UPNP_VERSION_MAJOR*100 + UPNP_VERSION_MINOR)*100 + UPNP_VERSION_PATCH)
-
-
-
-/***************************************************************************
- * Library optional features
- ***************************************************************************/ 
-
-/*
- * The following defines can be tested in order to know which 
- * optional features have been included in the installed library.
- */
-
-
-/** Defined to 1 if the library has been compiled with DEBUG enabled 
- *  (i.e. configure --enable-debug) : <upnp/upnpdebug.h> file is available */
-#undef UPNP_HAVE_DEBUG
-
-
-/** Defined to 1 if the library has been compiled with client API enabled 
- *  (i.e. configure --enable-client) */
-#undef UPNP_HAVE_CLIENT
-
-
-/** Defined to 1 if the library has been compiled with device API enabled 
- *  (i.e. configure --enable-device) */
-#undef UPNP_HAVE_DEVICE
-
-
-/** Defined to 1 if the library has been compiled with integrated web server
- *  (i.e. configure --enable-webserver --enable-device) */
-#undef UPNP_HAVE_WEBSERVER
-
-
-/** Defined to 1 if the library has been compiled with helper API
- *  (i.e. configure --enable-tools) : <upnp/upnptools.h> file is available */
-#undef UPNP_HAVE_TOOLS
-
-
-#endif // UPNP_CONFIG_H
-
-
diff --git a/tombupnp/upnp/inc/upnpdebug.h b/tombupnp/upnp/inc/upnpdebug.h
deleted file mode 100644
index c250454..0000000
--- a/tombupnp/upnp/inc/upnpdebug.h
+++ /dev/null
@@ -1,255 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// Copyright (c) 2006 Rémi Turboult <r3mi at users.sourceforge.net>
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef UPNP_DEBUG_H
-#define UPNP_DEBUG_H 
-
-#include "upnpconfig.h"
-
-// Function declarations only if debug compiled into the library
-#if UPNP_HAVE_DEBUG
-
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/** @name Other debugging features
-          The UPnP SDK contains other features to aid in debugging.
- */
-
-//@{
-
-/** @name Upnp_LogLevel
- *  The user has the option to select 4 different types of debugging levels,
- *  see {\tt UpnpSetLogLevel}. 
- *  The critical level will show only those messages 
- *  which can halt the normal processing of the library, like memory 
- *  allocation errors. The remaining three levels are just for debugging 
- *  purposes.  Packet level will display all the incoming and outgoing 
- *  packets that are flowing between the control point and the device. 
- *  Info Level displays the other important operational information 
- *  regarding the working of the library. If the user selects All, 
- *  then the library displays all the debugging information that it has.
- *  \begin{itemize}
- *    \item {\tt UPNP_CRITICAL [0]}
- *    \item {\tt UPNP_PACKET [1]}
- *    \item {\tt UPNP_INFO [2]}
- *    \item {\tt UPNP_ALL [3]}
- *  \end{itemize}
- */
-
-typedef enum Upnp_Module {SSDP,SOAP,GENA,TPOOL,MSERV,DOM,API, HTTP} Dbg_Module;
-//@{
-typedef enum Upnp_LogLevel_e {
-	UPNP_CRITICAL,
-	UPNP_PACKET,
-	UPNP_INFO,
-	UPNP_ALL
-} Upnp_LogLevel;
-//@}
-
-// for backward compatibility
-#define Dbg_Level	Upnp_LogLevel
-
-
-/**
- * Default log level : see {\tt Upnp_LogLevel}
- */
-#define UPNP_DEFAULT_LOG_LEVEL	UPNP_ALL
-
-
-
-/***************************************************************************
- * Function : UpnpInitLog						
- *								
- * Parameters:	void						
- *									
- * Description:								
- *	This functions initializes the log files
- * Returns: int
- *	-1 : If fails
- *	UPNP_E_SUCCESS : if success
- ***************************************************************************/
-int UpnpInitLog();
-
-// for backward compatibility
-#define InitLog		UpnpInitLog
-
-
-/***************************************************************************
- * Function : UpnpSetLogLevel
- *				
- * Parameters:	void
- *
- * Description:							
- *	This functions set the log level (see {\tt Upnp_LogLevel}
- * Returns: void
- ***************************************************************************/
-void UpnpSetLogLevel (Upnp_LogLevel);
-
-
-/***************************************************************************
- * Function : UpnpCloseLog						
- *								
- * Parameters:	void					
- *								
- * Description:							
- *	This functions closes the log files
- * Returns: void
- ***************************************************************************/
-void UpnpCloseLog();
-
-// for backward compatibility
-#define CloseLog	UpnpCloseLog
-
-
-/***************************************************************************
- * Function : UpnpSetLogFileNames		
- *							
- * Parameters:						
- *	IN const char* ErrFileName: name of the error file
- *	IN const char *InfoFileName: name of the information file
- *	IN int size: Size of the buffer
- *	IN int starLength: This parameter provides the width of the banner
- *								
- * Description:							
- *	This functions takes the buffer and writes the buffer in the file as 
- *	per the requested banner	
- * Returns: void
- ***************************************************************************/
-void UpnpSetLogFileNames (const char* ErrFileName, const char* InfoFileName);
-
-// for backward compatibility
-#define SetLogFileNames		UpnpSetLogFileNames
-
-
-/***************************************************************************
- * Function : UpnpGetDebugFile		
- *						
- * Parameters:					
- *	IN Dbg_Level DLevel: The level of the debug logging. It will decide 
- *		whether debug statement will go to standard output, 
- *		or any of the log files.
- *	IN Dbg_Module Module: debug will go in the name of this module
- *								
- * Description:
- *	This function checks if the module is turned on for debug 
- *	and returns the file descriptor corresponding to the debug level
- * Returns: FILE *
- *	NULL : if the module is turn off for debug 
- *	else returns the right file descriptor
- ***************************************************************************/
-FILE* UpnpGetDebugFile (Upnp_LogLevel level, Dbg_Module module);
-
-// for backward compatibility
-#define GetDebugFile	UpnpGetDebugFile
-
-
-/***************************************************************************
- * Function : UpnpPrintf				
- *									
- * Parameters:								
- *	IN Dbg_Level DLevel: The level of the debug logging. It will decide 
- *		whether debug statement will go to standard output, 
- *		or any of the log files.
- *	IN Dbg_Module Module: debug will go in the name of this module
- *	IN char *DbgFileName: Name of the file from where debug statement is
- *							coming
- *	IN int DbgLineNo : Line number of the file from where debug statement 
- *				is coming
- *	IN char * FmtStr, ...: Variable number of arguments that will go 
- *				in the debug statement
- *					
- * Description:							
- *	This functions prints the debug statement either on the startdard 
- *	output or log file along with the information from where this 
- *	debug statement is coming
- * Returns: void
- ***************************************************************************/ 
-void UpnpPrintf (Upnp_LogLevel DLevel, Dbg_Module Module,
-		 const char* DbgFileName, int DbgLineNo,
-		 const char* FmtStr,
-		 ...)
-#if (__GNUC__ >= 3)
-	__attribute__((format (__printf__, 5, 6)))
-#endif
-;
-
-
-/***************************************************************************
- * Function : UpnpDisplayBanner				
- *							
- * Parameters:							
- *	IN FILE *fd: file descriptor where the banner will be written
- *	IN char **lines: The buffer that will be written
- *	IN int size: Size of the buffer
- *	IN int starLength: This parameter provides the width of the banner
- *									
- * Description:							
- *	This functions takes the buffer and writes the buffer in the file as 
- *	per the requested banner			
- * Returns: void
- ***************************************************************************/
-void UpnpDisplayBanner (FILE *fd,
-			const char** lines, size_t size, int starlength);
-
-
-/***************************************************************************
- * Function : UpnpDisplayFileAndLine				
- *								
- * Parameters:							
- *	IN FILE *fd: File descriptor where line number and file name will be 
- *			written 
- *	IN char *DbgFileName: Name of the file  
- *	IN int DbgLineNo : Line number of the file
- *								
- * Description:
- *	This function writes the file name and file number from where
- *		debug statement is coming to the log file
- * Returns: void
- ***************************************************************************/
-void UpnpDisplayFileAndLine (FILE *fd, const char *DbgFileName, int DbgLineNo);
-
-
-//@}
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // UPNP_HAVE_DEBUG
-
-#endif // UPNP_DEBUG_H
diff --git a/tombupnp/upnp/inc/upnptools.h b/tombupnp/upnp/inc/upnptools.h
deleted file mode 100644
index cae3163..0000000
--- a/tombupnp/upnp/inc/upnptools.h
+++ /dev/null
@@ -1,228 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-/** @name Optional Tool APIs
- *  The Linux SDK for UPnP Devices contains some additional, optional 
- *  utility APIs that can be helpful in writing applications using the 
- *  SDK. These additional APIs can be compiled out in order to save code 
- *  size in the SDK. Refer to the README for details.
- */
-
-//@{
-
-#ifndef UPNP_TOOLS_H
-#define UPNP_TOOLS_H
-
-#include "upnp.h"
-
-// Function declarations only if tools compiled into the library
-#if UPNP_HAVE_TOOLS
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** {\bf UpnpResolveURL} combines a base URL and a relative URL into
- *  a single absolute URL.  The memory for {\bf AbsURL} needs to be
- *  allocated by the caller and must be large enough to hold the
- *  {\bf BaseURL} and {\bf RelURL} combined.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: {\bf RelURL} is {\tt NULL}.
- *      \item {\tt UPNP_E_INVALID_URL}: The {\bf BaseURL} / {\bf RelURL} 
- *              combination does not form a valid URL.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpResolveURL(
-    IN const char * BaseURL,  /** The base URL to combine. */
-    IN const char * RelURL,   /** The relative URL to {\bf BaseURL}. */
-    OUT char * AbsURL   /** A pointer to a buffer to store the 
-                            absolute URL. */
-    );
-
-/** {\bf UpnpMakeAction} creates an action request packet based on its input 
- *  parameters (status variable name and value pair). Any number of input 
- *  parameters can be passed to this function but every input variable name 
- *  should have a matching value argument. 
- *   
- *  @return [IXML_Document*] The action node of {\bf Upnp_Document} type or 
- *                      {\tt NULL} if the operation failed.
- */
-
-EXPORT_SPEC IXML_Document* UpnpMakeAction(
-    IN const char * ActionName, /** The action name. */
-    IN const char * ServType,   /** The service type.  */
-    IN int NumArg,              /** Number of argument pairs to be passed. */ 
-    IN const char * Arg,        /** Status variable name and value pair. */
-    IN ...                   /*  Other status variable name and value pairs. */
-    );
-
-/** {\bf UpnpAddToAction} creates an action request packet based on its input 
- *  parameters (status variable name and value pair). This API is specially 
- *  suitable inside a loop to add any number input parameters into an existing
- *  action. If no action document exists in the beginning then a 
- *  {\bf Upnp_Document} variable initialized with {\tt NULL} should be passed 
- *  as a parameter.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: One or more of the parameters 
- *                                        are invalid.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpAddToAction(
-        IN OUT IXML_Document ** ActionDoc, 
-	                              /** A pointer to store the action 
-				          document node. */
-        IN const char * ActionName,   /** The action name. */
-        IN const char * ServType,     /** The service type.  */
-        IN const char * ArgName,      /** The status variable name. */
-        IN const char * ArgVal        /** The status variable value.  */
-        );
-
-/** {\bf UpnpMakeActionResponse} creates an action response packet based 
- *  on its output parameters (status variable name and value pair). Any  
- *  number of input parameters can be passed to this function but every output
- *  variable name should have a matching value argument. 
- *   
- *  @return [IXML_Document*] The action node of {\bf Upnp_Document} type or 
- *                           {\tt NULL} if the operation failed.
- */
-
-EXPORT_SPEC IXML_Document* UpnpMakeActionResponse(
-    IN const char * ActionName, /** The action name. */
-    IN const char * ServType,   /** The service type.  */
-    IN int NumArg,              /** The number of argument pairs passed. */  
-    IN const char * Arg,        /** The status variable name and value pair. */
-    IN ...                   /*  Other status variable name and value pairs. */
-    );
-
-/** {\bf UpnpAddToActionResponse} creates an action response
- *  packet based on its output parameters (status variable name
- *  and value pair). This API is especially suitable inside
- *  a loop to add any number of input parameters into an existing action 
- *  response. If no action document exists in the beginning, a 
- *  {\bf Upnp_Document} variable initialized with {\tt NULL} should be passed 
- *  as a parameter.
- *
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: One or more of the parameters 
- *                                        are invalid.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- */
-
-EXPORT_SPEC int UpnpAddToActionResponse(
-        IN OUT IXML_Document ** ActionResponse, 
-	                                   /** Pointer to a document to 
-					       store the action document 
-					       node. */
-        IN const char * ActionName,        /** The action name. */
-        IN const char * ServType,          /** The service type.  */
-        IN const char * ArgName,           /** The status variable name. */
-        IN const char * ArgVal             /** The status variable value.  */
-        );
-
-/** {\bf UpnpAddToPropertySet} can be used when an application needs to 
- *  transfer the status of many variables at once. It can be used 
- *  (inside a loop) to add some extra status variables into an existing
- *  property set. If the application does not already have a property
- *  set document, the application should create a variable initialized 
- *  with {\tt NULL} and pass that as the first parameter.
- *  
- *  @return [int] An integer representing one of the following:
- *    \begin{itemize}
- *      \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
- *      \item {\tt UPNP_E_INVALID_PARAM}: One or more of the parameters 
- *                                        are invalid.
- *      \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to 
- *              complete this operation.
- *    \end{itemize}
- *
- */
-
-EXPORT_SPEC int UpnpAddToPropertySet(
-    IN OUT IXML_Document **PropSet,    
-                                  /** A pointer to the document containing 
-				      the property set document node. */
-    IN const char * ArgName,      /** The status variable name. */  
-    IN const char * ArgVal        /** The status variable value.  */
-    );
-
-/** {\bf UpnpCreatePropertySet} creates a property set  
- *  message packet. Any number of input parameters can be passed  
- *  to this function but every input variable name should have 
- *  a matching value input argument.
- *  
- *  @return [IXML_Document*] {\tt NULL} on failure, or the property-set 
- *                           document node.
- *
- */
-
-EXPORT_SPEC IXML_Document* UpnpCreatePropertySet(
-    IN int NumArg,        /** The number of argument pairs passed. */
-    IN const char* Arg,   /** The status variable name and value pair. */
-    IN ...
-    );
-
-/** {\bf UpnpGetErrorMessage} converts an SDK error code into a 
- *  string error message suitable for display.  The memory returned
- *  from this function should NOT be freed.
- *
- *  @return [char*] An ASCII text string representation of the error message 
- *                  associated with the error code. 
- */
-
-EXPORT_SPEC const char * UpnpGetErrorMessage(
-        int errorcode  /** The SDK error code to convert. */
-        );
-
-//@}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // UPNP_HAVE_TOOLS
-
-#endif // UPNP_TOOLS_H
diff --git a/tombupnp/upnp/src/api/upnpapi.c b/tombupnp/upnp/src/api/upnpapi.c
deleted file mode 100644
index 04fee48..0000000
--- a/tombupnp/upnp/src/api/upnpapi.c
+++ /dev/null
@@ -1,4624 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-//File upnpapi.c
-#include "config.h"
-#include <assert.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#ifndef WIN32
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
-
- #ifndef SOLARIS
-// #include <linux/if.h>
-  #include <net/if.h>
- #else
-  #include <fcntl.h>
-  #include <net/if.h>
-  #include <sys/sockio.h>
- #endif
-
- #include <sys/ioctl.h>
- #include <sys/utsname.h>
- #include <unistd.h>
-#endif
-#include "upnpapi.h"
-#include "httpreadwrite.h"
-#include "ssdplib.h"
-#include "soaplib.h"
-#include "ThreadPool.h"
-#include "membuffer.h"
-
-#include "httpreadwrite.h"
-
-//************************************
-//Needed for GENA
-#include "gena.h"
-#include "service_table.h"
-#include "miniserver.h"
-//*******************************************
-
-/*
- ********************* */
-#ifdef INTERNAL_WEB_SERVER
-#include "webserver.h"
-#include "urlconfig.h"
-#endif // INTERNAL_WEB_SERVER
-/*
- ****************** */
-
-//Mutex to synchronize the subscription handling at the client side
-CLIENTONLY( ithread_mutex_t GlobalClientSubscribeMutex;
-     )
-    //Mutex to synchronize handles ( root device or control point handle)
-     ithread_mutex_t GlobalHndMutex;
-
-//Mutex to synchronize the uuid creation process
-     ithread_mutex_t gUUIDMutex;
-
-     TimerThread gTimerThread;
-
-     ThreadPool gRecvThreadPool;
-
-     ThreadPool gSendThreadPool;
-
-//Flag to indicate the state of web server
-     WebServerState bWebServerState = WEB_SERVER_DISABLED;
-
-// static buffer to store the local host ip address or host name
-     char LOCAL_HOST[LINE_SIZE];
-
-// local port for the mini-server
-     unsigned short LOCAL_PORT;
-
-// UPnP device and control point handle table 
-     void *HandleTable[NUM_HANDLE];
-
-//This structure is for virtual directory callbacks
-     struct UpnpVirtualDirCallbacks virtualDirCallback;
-
-// a local dir which serves as webserver root
-    extern membuffer gDocumentRootDir;
-
-// Maximum content-length that the SDK will process on an incoming packet. 
-// Content-Length exceeding this size will be not processed and error 413 
-// (HTTP Error Code) will be returned to the remote end point.
-off_t g_maxContentLength = DEFAULT_SOAP_CONTENT_LENGTH; // in bytes
-
-// Global variable to denote the state of Upnp SDK 
-//    = 0 if uninitialized, = 1 if initialized.
-     int UpnpSdkInit = 0;
-
-// Global variable to denote the state of Upnp SDK device registration.
-// = 0 if unregistered, = 1 if registered.
-     int UpnpSdkDeviceRegistered = 0;
-
-// Global variable to denote the state of Upnp SDK client registration.
-// = 0 if unregistered, = 1 if registered.
-     int UpnpSdkClientRegistered = 0;
-
-/****************************************************************************
- * Function: UpnpInit
- *
- * Parameters:		
- *	IN const char * HostIP: Local IP Address
- *	IN unsigned short DestPort: Local Port to listen for incoming connections
- *  IN unsigned int maximum number of retries when select returns a timeout
- *                  when sending data to the server.
- * Description:
- *	Initializes 
- *		- Mutex objects, 
- *		- Handle Table
- *		- Thread Pool and Thread Pool Attributes
- *		- MiniServer(starts listening for incoming requests) 
- *			and WebServer (Sends request to the 
- *		        Upper Layer after HTTP Parsing)
- *		- Checks for IP Address passed as an argument. IF NULL, 
- *                gets local host name
- *		- Sets GENA and SOAP Callbacks.
- *		- Starts the timer thread.
- *
- * Returns:
- *	UPNP_E_SUCCESS on success, nonzero on failure.
- *	UPNP_E_INIT_FAILED if Initialization fails.
- *	UPNP_E_INIT if UPnP is already initialized
- *****************************************************************************/
-int UpnpInit( IN const char *HostIP,
-              IN unsigned short DestPort,
-              IN int maxHTTPTimeoutRetries,
-              IN void *thread_cleanup
-            )
-{
-    int retVal = 0;
-    ThreadPoolAttr attr;
-#ifdef WIN32
-	WORD wVersionRequested;
-	WSADATA wsaData;
-	int err;
-#endif
-
-    if( UpnpSdkInit == 1 ) {
-        // already initialized
-        return UPNP_E_INIT;
-    }
-
-    gUpnpSdkShutdown = 0;
-    gMaxHTTPTimeoutRetries = maxHTTPTimeoutRetries;
-#ifdef WIN32
-	wVersionRequested = MAKEWORD( 2, 2 );
-
-	err = WSAStartup( wVersionRequested, &wsaData );
-	if ( err != 0 ) {
-		/* Tell the user that we could not find a usable */
-		/* WinSock DLL.                                  */
-		return UPNP_E_INIT_FAILED;
-	}
-
-	/* Confirm that the WinSock DLL supports 2.2.*/
-	/* Note that if the DLL supports versions greater    */
-	/* than 2.2 in addition to 2.2, it will still return */
-	/* 2.2 in wVersion since that is the version we      */
-	/* requested.                                        */
-	 
-	if ( LOBYTE( wsaData.wVersion ) != 2 ||
-			HIBYTE( wsaData.wVersion ) != 2 ) {
-		/* Tell the user that we could not find a usable */
-		/* WinSock DLL.                                  */
-		WSACleanup( );
-		return UPNP_E_INIT_FAILED; 
-	}
-
-	/* The WinSock DLL is acceptable. Proceed. */
-#endif
-
-    membuffer_init( &gDocumentRootDir );
-    membuffer_init( &gUserHTTPHeaders );
-
-    srand( time( NULL ) );      // needed by SSDP or other parts
-
-    DBGONLY( if( InitLog(  ) != UPNP_E_SUCCESS )
-             return UPNP_E_INIT_FAILED; );
-
-    DBGONLY( UpnpPrintf
-             ( UPNP_INFO, API, __FILE__, __LINE__, "Inside UpnpInit \n" );
-         )
-        //initialize mutex
-        if( ithread_mutex_init( &GlobalHndMutex, NULL ) != 0 ) {
-        return UPNP_E_INIT_FAILED;
-    }
-
-    if( ithread_mutex_init( &gUUIDMutex, NULL ) != 0 ) {
-        return UPNP_E_INIT_FAILED;
-    }
-    //initialize subscribe mutex
-    CLIENTONLY( if
-                ( ithread_mutex_init( &GlobalClientSubscribeMutex, NULL )
-                  != 0 ) {
-                return UPNP_E_INIT_FAILED;}
-     )
-
-        HandleLock(  );
-    if( HostIP != NULL )
-        strcpy( LOCAL_HOST, HostIP );
-    else {
-        if( getlocalhostname( LOCAL_HOST ) != UPNP_E_SUCCESS ) {
-            HandleUnlock(  );
-            return UPNP_E_INIT_FAILED;
-        }
-    }
-
-    if( UpnpSdkInit != 0 ) {
-        HandleUnlock(  );
-        return UPNP_E_INIT;
-    }
-
-    InitHandleList(  );
-    HandleUnlock(  );
-
-    TPAttrInit( &attr );
-    TPAttrSetMaxThreads( &attr, MAX_THREADS );
-    TPAttrSetMinThreads( &attr, MIN_THREADS );
-    TPAttrSetJobsPerThread( &attr, JOBS_PER_THREAD );
-    TPAttrSetIdleTime( &attr, THREAD_IDLE_TIME );
-    TPAttrSetMaxJobsTotal( &attr, MAX_JOBS_TOTAL );
-
-    gSendThreadPool.free_func = (free_thread_func)thread_cleanup;
-    if( ThreadPoolInit( &gSendThreadPool, &attr ) != UPNP_E_SUCCESS ) {
-        UpnpSdkInit = 0;
-        UpnpFinish(  );
-        return UPNP_E_INIT_FAILED;
-    }
-
-    gRecvThreadPool.free_func = (free_thread_func)thread_cleanup;
-    if( ThreadPoolInit( &gRecvThreadPool, &attr ) != UPNP_E_SUCCESS ) {
-        UpnpSdkInit = 0;
-        UpnpFinish(  );
-        return UPNP_E_INIT_FAILED;
-    }
-
-    UpnpSdkInit = 1;
-#if EXCLUDE_SOAP == 0
-    DEVICEONLY( SetSoapCallback( soap_device_callback );
-         );
-#endif
-#if EXCLUDE_GENA == 0
-    SetGenaCallback( genaCallback );
-#endif
-
-    if( ( retVal = TimerThreadInit( &gTimerThread,
-                                    &gSendThreadPool ) ) !=
-        UPNP_E_SUCCESS ) {
-        UpnpSdkInit = 0;
-        UpnpFinish(  );
-        return retVal;
-    }
-#if EXCLUDE_MINISERVER == 0
-    if( ( retVal = StartMiniServer( DestPort ) ) <= 0 ) {
-        DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
-                             "Miniserver failed to start" );
-             )
-            UpnpFinish(  );
-        UpnpSdkInit = 0;
-        if( retVal != -1 )
-            return retVal;
-        else                    // if miniserver is already running for unknown reasons!
-            return UPNP_E_INIT_FAILED;
-    }
-#endif
-    DestPort = retVal;
-    LOCAL_PORT = DestPort;
-
-#if EXCLUDE_WEB_SERVER == 0
-    if( ( retVal =
-          UpnpEnableWebserver( WEB_SERVER_ENABLED ) ) != UPNP_E_SUCCESS ) {
-        UpnpFinish(  );
-        UpnpSdkInit = 0;
-        return retVal;
-    }
-#endif
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                         "Host Ip: %s Host Port: %d\n", LOCAL_HOST,
-                         LOCAL_PORT ) );
-
-    DBGONLY( UpnpPrintf
-             ( UPNP_INFO, API, __FILE__, __LINE__, "Exiting UpnpInit \n" );
-         )
-
-        return UPNP_E_SUCCESS;
-
-} /***************** end of UpnpInit ******************/
-
-DBGONLY(
-static void 
-PrintThreadPoolStats (const char* DbgFileName, int DbgLineNo,
-		      const char* msg, const ThreadPoolStats* const stats)
-{
-	UpnpPrintf (UPNP_INFO, API, DbgFileName, DbgLineNo, 
-		    "%s \n High Jobs pending = %d \nMed Jobs Pending = %d\n"
-		    " Low Jobs Pending = %d \nWorker Threads = %d\n"
-		    "Idle Threads = %d\nPersistent Threads = %d\n"
-		    "Average Time spent in High Q = %lf\n"
-		    "Average Time spent in Med Q = %lf\n"
-		    "Average Time spent in Low Q = %lf\n"
-		    "Max Threads Used: %d\nTotal Work Time= %lf\n"
-		    "Total Idle Time = %lf\n",
-		    msg,
-		    stats->currentJobsHQ, stats->currentJobsMQ,
-		    stats->currentJobsLQ, stats->workerThreads,
-		    stats->idleThreads, stats->persistentThreads,
-		    stats->avgWaitHQ, stats->avgWaitMQ, stats->avgWaitLQ,
-		    stats->maxThreads, stats->totalWorkTime,
-		    stats->totalIdleTime );
-})
-
-     
-/****************************************************************************
- * Function: UpnpFinish
- *
- * Parameters:	NONE
- *
- * Description:
- *	Checks for pending jobs and threads 
- *		Unregisters either the client or device 
- *		Shuts down the Timer Thread
- *		Stops the Mini Server
- *		Uninitializes the Thread Pool
- *		For Win32 cleans up Winsock Interface 
- *		Cleans up mutex objects
- *
- * Return Values:
- *	UPNP_E_SUCCESS on success, nonzero on failure.
- *****************************************************************************/
-int
-UpnpFinish(  )
-{
-    DEVICEONLY( UpnpDevice_Handle device_handle;
-         )
-        CLIENTONLY( UpnpClient_Handle client_handle;
-         )
-    struct Handle_Info *temp;
-
-    DBGONLY( ThreadPoolStats stats;
-         )
-
-#ifdef WIN32
-//	WSACleanup( );
-#endif
-
-        if( UpnpSdkInit != 1 )
-        return UPNP_E_FINISH;
-
-    gUpnpSdkShutdown = 1;
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                         "Inside UpnpFinish : UpnpSdkInit is :%d:\n",
-                         UpnpSdkInit ); if( UpnpSdkInit == 1 ) {
-             UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                         "UpnpFinish : UpnpSdkInit is ONE\n" );}
-             ThreadPoolGetStats( &gRecvThreadPool, &stats );
-             PrintThreadPoolStats (__FILE__, __LINE__,
-				   "Recv Thread Pool", &stats);
-             ThreadPoolGetStats( &gSendThreadPool, &stats );
-             PrintThreadPoolStats (__FILE__, __LINE__,
-				   "Send Thread Pool", &stats);
-	    )
-#ifdef INCLUDE_DEVICE_APIS
-        if( GetDeviceHandleInfo( &device_handle, &temp ) == HND_DEVICE )
-            UpnpUnRegisterRootDevice( device_handle );
-#endif
-
-#ifdef INCLUDE_CLIENT_APIS
-    if( GetClientHandleInfo( &client_handle, &temp ) == HND_CLIENT )
-        UpnpUnRegisterClient( client_handle );
-#endif
-
-    TimerThreadShutdown( &gTimerThread );
-
-    StopMiniServer(  );
-
-#if EXCLUDE_WEB_SERVER == 0
-    web_server_destroy(  );
-#endif
-
-    ThreadPoolShutdown( &gSendThreadPool );
-    ThreadPoolShutdown( &gRecvThreadPool );
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "Exiting UpnpFinish : UpnpSdkInit is :%d:\n", UpnpSdkInit ); ThreadPoolGetStats( &gRecvThreadPool, &stats ); PrintThreadPoolStats ( __FILE__, __LINE__, "Recv Thread Pool", &stats); ThreadPoolGetStats( &gSendThreadPool, &stats ); PrintThreadPoolStats (__FILE__, __LINE__, "Send Thread Pool", &stats); )   // DBGONLY
-        DBGONLY( CloseLog(  );
-         );
-
-    CLIENTONLY( ithread_mutex_destroy( &GlobalClientSubscribeMutex );
-         )
-
-        ithread_mutex_destroy( &GlobalHndMutex );
-    ithread_mutex_destroy( &gUUIDMutex );
-
-    // remove all virtual dirs
-    UpnpRemoveAllVirtualDirs(  );
-    UpnpRemoveAllCustomHTTPHeaders(  );
-    membuffer_destroy(&gUserHTTPHeaders);
-    //leuk_he allow static linking:
-	 #ifdef WIN32
-	  #ifdef PTW32_STATIC_LIB
-	   pthread_win32_thread_detach_np ();
-	  #endif
-	 #endif
-
-
-    UpnpSdkInit = 0;
-
-    return UPNP_E_SUCCESS;
-
-}  /********************* End of  UpnpFinish  *************************/
-
-/****************************************************************************
- * Function: UpnpGetServerPort
- *
- * Parameters: NONE
- *
- * Description:
- *	Gives back the miniserver port.
- *
- * Return Values:
- *	local port on success, zero on failure.
- *****************************************************************************/
-unsigned short
-UpnpGetServerPort( void )
-{
-
-    if( UpnpSdkInit != 1 )
-        return 0;
-
-    return LOCAL_PORT;
-}
-
-/***************************************************************************
- * Function: UpnpGetServerIpAddress
- *
- * Parameters: NONE
- *
- * Description:
- *	Gives back the local ipaddress.
- *
- * Return Values: char *
- *	return the IP address string on success else NULL of failure
- ***************************************************************************/
-char *
-UpnpGetServerIpAddress( void )
-{
-
-    if( UpnpSdkInit != 1 )
-        return NULL;
-
-    return LOCAL_HOST;
-}
-
-#ifdef INCLUDE_DEVICE_APIS
-#if 0
-
-/****************************************************************************
- * Function: UpnpAddRootDevice
- *
- * Parameters:	
- *	IN const char *DescURL: Location of the root device 
- *		description xml file
- *	IN UpnpDevice_Handle Hnd: The device handle
- *
- * Description:
- *	downloads the description file and update the service table of the
- *	device. This function has been deprecated.
- *
- * Return Values:
- *	UPNP_E_SUCCESS on success, nonzero on failure.
- *****************************************************************************/
-int
-UpnpAddRootDevice( IN const char *DescURL,
-                   IN UpnpDevice_Handle Hnd )
-{
-    int retVal = 0;
-    struct Handle_Info *HInfo;
-    IXML_Document *temp;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    if( ( retVal =
-          UpnpDownloadXmlDoc( DescURL, &( temp ) ) ) != UPNP_E_SUCCESS ) {
-        return retVal;
-    }
-
-    HandleLock(  );
-    if( GetHandleInfo( Hnd, &HInfo ) == UPNP_E_INVALID_HANDLE ) {
-        HandleUnlock(  );
-        ixmlDocument_free( temp );
-        return UPNP_E_INVALID_HANDLE;
-    }
-
-    if( addServiceTable
-        ( ( IXML_Node * ) temp, &HInfo->ServiceTable, DescURL ) ) {
-
-        DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "UpnpAddRootDevice: GENA Service Table \n" );
-                 UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "Here are the known services: \n" );
-                 printServiceTable( &HInfo->ServiceTable, UPNP_INFO, API );
-             )
-    } else {
-        DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "\nUpnpAddRootDevice: No Eventing Support Found \n" );
-             )
-    }
-
-    ixmlDocument_free( temp );
-    HandleUnlock(  );
-
-    return UPNP_E_SUCCESS;
-}
-#endif // 0
-#endif //INCLUDE_DEVICE_APIS
-
-#ifdef INCLUDE_DEVICE_APIS
-
-/****************************************************************************
- * Function: UpnpRegisterRootDevice
- *
- * Parameters:	
- *	IN const char *DescUrl:Pointer to a string containing the 
- *		description URL for this root device instance. 
- *	IN Upnp_FunPtr Callback: Pointer to the callback function for 
- *		receiving asynchronous events. 
- *	IN const void *Cookie: Pointer to user data returned with the 
- *		callback function when invoked.
- *	OUT UpnpDevice_Handle *Hnd: Pointer to a variable to store the 
- *		new device handle.
- *
- * Description:
- *	This function registers a device application with
- *	the UPnP Library.  A device application cannot make any other API
- *	calls until it registers using this function.  
- *
- * Return Values:
- *	UPNP_E_SUCCESS on success, nonzero on failure.
- *****************************************************************************/
-int
-UpnpRegisterRootDevice( IN const char *DescUrl,
-                        IN Upnp_FunPtr Fun,
-                        IN const void *Cookie,
-                        OUT UpnpDevice_Handle * Hnd )
-{
-
-    struct Handle_Info *HInfo;
-    int retVal = 0;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                         "Inside UpnpRegisterRootDevice \n" );
-         )
-        HandleLock(  );
-
-    if( UpnpSdkDeviceRegistered ) {
-        HandleUnlock(  );
-        return UPNP_E_ALREADY_REGISTERED;
-    }
-
-    if( Hnd == NULL || Fun == NULL ||
-        DescUrl == NULL || strlen( DescUrl ) == 0 ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    if( ( *Hnd = GetFreeHandle(  ) ) == UPNP_E_OUTOF_HANDLE ) {
-        HandleUnlock(  );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    HInfo = ( struct Handle_Info * )malloc( sizeof( struct Handle_Info ) );
-    if( HInfo == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    HandleTable[*Hnd] = HInfo;
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                         "Root device URL is %s\n", DescUrl );
-         )
-
-        HInfo->aliasInstalled = 0;
-    HInfo->HType = HND_DEVICE;
-    strcpy( HInfo->DescURL, DescUrl );
-    HInfo->Callback = Fun;
-    HInfo->Cookie = ( void * )Cookie;
-    HInfo->MaxAge = DEFAULT_MAXAGE;
-    HInfo->DeviceList = NULL;
-    HInfo->ServiceList = NULL;
-    HInfo->DescDocument = NULL;
-    CLIENTONLY( ListInit( &HInfo->SsdpSearchList, NULL, NULL );
-         );
-    CLIENTONLY( HInfo->ClientSubList = NULL;
-         )
-        HInfo->MaxSubscriptions = UPNP_INFINITE;
-    HInfo->MaxSubscriptionTimeOut = UPNP_INFINITE;
-
-    if( ( retVal =
-          UpnpDownloadXmlDoc( HInfo->DescURL, &( HInfo->DescDocument ) ) )
-        != UPNP_E_SUCCESS ) {
-        CLIENTONLY( ListDestroy( &HInfo->SsdpSearchList, 0 ) );
-        FreeHandle( *Hnd );
-        HandleUnlock(  );
-        return retVal;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "UpnpRegisterRootDevice: Valid Description\n" );
-             UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                         "UpnpRegisterRootDevice: DescURL : %s\n",
-                         HInfo->DescURL );
-         )
-
-        HInfo->DeviceList =
-        ixmlDocument_getElementsByTagName( HInfo->DescDocument, "device" );
-    if( HInfo->DeviceList == NULL ) {
-        CLIENTONLY( ListDestroy( &HInfo->SsdpSearchList, 0 ) );
-        ixmlDocument_free( HInfo->DescDocument );
-        FreeHandle( *Hnd );
-        HandleUnlock(  );
-        DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
-                             "UpnpRegisterRootDevice: No devices found for RootDevice\n" );
-             )
-            return UPNP_E_INVALID_DESC;
-    }
-
-    HInfo->ServiceList =
-        ixmlDocument_getElementsByTagName( HInfo->DescDocument,
-                                           "serviceList" );
-    if( HInfo->ServiceList == NULL ) {
-        CLIENTONLY( ListDestroy( &HInfo->SsdpSearchList, 0 ) );
-        ixmlNodeList_free( HInfo->DeviceList );
-        ixmlDocument_free( HInfo->DescDocument );
-        FreeHandle( *Hnd );
-        HandleUnlock(  );
-        DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
-                             "UpnpRegisterRootDevice: No services found for RootDevice\n" );
-             )
-            return UPNP_E_INVALID_DESC;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "UpnpRegisterRootDevice: Gena Check\n" );
-         )
-        //*******************************
-        //GENA SET UP
-        //*******************************
-        if( getServiceTable( ( IXML_Node * ) HInfo->DescDocument,
-                             &HInfo->ServiceTable, HInfo->DescURL ) ) {
-        DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "UpnpRegisterRootDevice: GENA Service Table \n" );
-                 UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "Here are the known services: \n" );
-                 printServiceTable( &HInfo->ServiceTable, UPNP_INFO, API );
-             )
-    } else {
-        CLIENTONLY( ListDestroy( &HInfo->SsdpSearchList, 0 ) );
-        FreeHandle( *Hnd );
-        HandleUnlock(  );
-        DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "\nUpnpRegisterRootDevice: Errors retrieving service table \n" );
-             )
-            return UPNP_E_INVALID_DESC;
-    }
-
-    UpnpSdkDeviceRegistered = 1;
-    HandleUnlock(  );
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                         "Exiting RegisterRootDevice Successfully\n" );
-         )
-
-        return UPNP_E_SUCCESS;
-
-}  /****************** End of UpnpRegisterRootDevice  *********************/
-
-#endif // INCLUDE_DEVICE_APIS
-
-#ifdef INCLUDE_DEVICE_APIS
-#if 0
-
-/****************************************************************************
- * Function: UpnpRemoveRootDevice
- *
- * Parameters:	
- *	IN const char *DescURL: Location of the root device 
- *		description xml file
- *	IN UpnpDevice_Handle Hnd: The device handle
- *
- * Description:
- *	downloads the description file and update the service table of the
- *	device. This function has been deprecated.
- *
- * Return Values:
- *	UPNP_E_SUCCESS on success, nonzero on failure.
- *****************************************************************************/
-int
-UpnpRemoveRootDevice( IN const char *DescURL,
-                      IN UpnpDevice_Handle Hnd )
-{
-    int retVal = 0;
-    struct Handle_Info *HInfo;
-
-    IXML_Document *temp;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    if( ( retVal =
-          UpnpDownloadXmlDoc( DescURL, &( temp ) ) ) != UPNP_E_SUCCESS ) {
-        return retVal;
-    }
-
-    HandleLock(  );
-    if( GetHandleInfo( Hnd, &HInfo ) == UPNP_E_INVALID_HANDLE ) {
-        HandleUnlock(  );
-        ixmlDocument_free( temp );
-        return UPNP_E_INVALID_HANDLE;
-    }
-
-    if( removeServiceTable( ( IXML_Node * ) temp, &HInfo->ServiceTable ) ) {
-
-        DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "UpnpRemoveRootDevice: GENA Service Table \n" );
-                 UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "Here are the known services: \n" );
-                 printServiceTable( &HInfo->ServiceTable, UPNP_INFO, API );
-             )
-    } else {
-        DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "\nUpnpRemoveRootDevice: No Services Removed\n" );
-                 UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "Here are the known services: \n" );
-                 printServiceTable( &HInfo->ServiceTable, UPNP_INFO, API );
-             )
-    }
-
-    HandleUnlock(  );
-
-    ixmlDocument_free( temp );
-    return UPNP_E_SUCCESS;
-}
-#endif //0
-#endif //INCLUDE_DEVICE_APIS
-
-#ifdef INCLUDE_DEVICE_APIS
-
-/****************************************************************************
- * Function: UpnpUnRegisterRootDevice
- *
- * Parameters:	
- *	IN UpnpDevice_Handle Hnd: The handle of the device instance 
- *		to unregister
- * Description:
- *	This function unregisters a root device registered with 
- *	UpnpRegisterRootDevice} or UpnpRegisterRootDevice2. After this call, the 
- *	UpnpDevice_Handle Hnd is no longer valid. For all advertisements that 
- *	have not yet expired, the UPnP library sends a device unavailable message 
- *	automatically. 
- *
- * Return Values:
- *	UPNP_E_SUCCESS on success, nonzero on failure.
- *****************************************************************************/
-int
-UpnpUnRegisterRootDevice( IN UpnpDevice_Handle Hnd )
-{
-    int retVal = 0;
-    struct Handle_Info *HInfo = NULL;
-
-    // struct Handle_Info *info=NULL;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    HandleLock(  );
-    if( !UpnpSdkDeviceRegistered ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    HandleUnlock(  );
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                         "Inside UpnpUnRegisterRootDevice \n" );
-         )
-#if EXCLUDE_GENA == 0
-        if( genaUnregisterDevice( Hnd ) != UPNP_E_SUCCESS )
-        return UPNP_E_INVALID_HANDLE;
-#endif
-
-    HandleLock(  );
-    if( GetHandleInfo( Hnd, &HInfo ) == UPNP_E_INVALID_HANDLE ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    HandleUnlock(  );
-
-#if EXCLUDE_SSDP == 0
-    retVal = AdvertiseAndReply( -1, Hnd, 0, ( struct sockaddr_in * )NULL,
-                                ( char * )NULL, ( char * )NULL,
-                                ( char * )NULL, HInfo->MaxAge );
-#endif
-
-    HandleLock(  );
-    if( GetHandleInfo( Hnd, &HInfo ) == UPNP_E_INVALID_HANDLE ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    //info = (struct Handle_Info *) HandleTable[Hnd];
-    ixmlNodeList_free( HInfo->DeviceList );
-    ixmlNodeList_free( HInfo->ServiceList );
-    ixmlDocument_free( HInfo->DescDocument );
-
-    CLIENTONLY( ListDestroy( &HInfo->SsdpSearchList, 0 ) );
-
-#ifdef INTERNAL_WEB_SERVER
-    if( HInfo->aliasInstalled ) {
-        web_server_set_alias( NULL, NULL, 0, 0 );
-    }
-#endif // INTERNAL_WEB_SERVER
-
-    FreeHandle( Hnd );
-    UpnpSdkDeviceRegistered = 0;
-    HandleUnlock(  );
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                         "Exiting UpnpUnRegisterRootDevice \n" );
-         )
-
-        return retVal;
-
-}  /****************** End of UpnpUnRegisterRootDevice *********************/
-
-#endif //INCLUDE_DEVICE_APIS
-
-// *************************************************************
-#ifdef INCLUDE_DEVICE_APIS
-#ifdef INTERNAL_WEB_SERVER
-
-/**************************************************************************
- * Function: GetNameForAlias
- *
- * Parameters:	
- *	IN char *name: name of the file
- *	OUT char** alias: pointer to alias string 
- *
- * Description:
- *	This function determines alias for given name which is a file name 
- *	or URL.
- *
- * Return Values:
- *	UPNP_E_SUCCESS on success, nonzero on failure.
- ***************************************************************************/
-static int
-GetNameForAlias( IN char *name,
-                 OUT char **alias )
-{
-    char *ext;
-    char *al;
-
-    ext = strrchr( name, '.' );
-    if( ext == NULL || strcasecmp( ext, ".xml" ) != 0 ) {
-        return UPNP_E_EXT_NOT_XML;
-    }
-
-    al = strrchr( name, '/' );
-    if( al == NULL ) {
-        *alias = name;
-    } else {
-        *alias = al;
-    }
-
-    return UPNP_E_SUCCESS;
-}
-
-/**************************************************************************
- * Function: get_server_addr
- *
- * Parameters:	
- *	OUT struct sockaddr_in* serverAddr: pointer to server address
- *		structure 
- *
- * Description:
- *	This function fills the sockadr_in with miniserver information.
- *
- * Return Values: VOID
- *      
- ***************************************************************************/
-static void
-get_server_addr( OUT struct sockaddr_in *serverAddr )
-{
-    memset( serverAddr, 0, sizeof( struct sockaddr_in ) );
-
-    serverAddr->sin_family = AF_INET;
-    serverAddr->sin_port = htons( LOCAL_PORT );
-    //inet_aton( LOCAL_HOST, &serverAddr->sin_addr );
-    serverAddr->sin_addr.s_addr = inet_addr( LOCAL_HOST );
-}
-
-/**************************************************************************
- * Function: GetDescDocumentAndURL ( In the case of device)
- *
- * Parameters:	
- *	IN Upnp_DescType descriptionType: pointer to server address
- *		structure 
- *	IN char* description:
- *	IN unsigned int bufferLen:
- *	IN int config_baseURL:
- *	OUT IXML_Document **xmlDoc:
- *	OUT char descURL[LINE_SIZE]: 
- *
- * Description:
- *	This function fills the sockadr_in with miniserver information.
- *
- * Return Values: VOID
- *      
- ***************************************************************************/
-static int
-GetDescDocumentAndURL( IN Upnp_DescType descriptionType,
-                       IN char *description,
-                       IN unsigned int bufferLen,
-                       IN int config_baseURL,
-                       OUT IXML_Document ** xmlDoc,
-                       OUT char descURL[LINE_SIZE] )
-{
-    int retVal = 0;
-    char *membuf = NULL;
-    char aliasStr[LINE_SIZE];
-    char *temp_str = NULL;
-    FILE *fp = NULL;
-    off_t fileLen;
-    unsigned num_read;
-    time_t last_modified;
-    struct stat file_info;
-    struct sockaddr_in serverAddr;
-    int rc = UPNP_E_SUCCESS;
-
-    if( description == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-    // non-URL description must have configuration specified
-    if( descriptionType != UPNPREG_URL_DESC && ( !config_baseURL ) ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-    // get XML doc and last modified time
-    if( descriptionType == UPNPREG_URL_DESC ) {
-        if( ( retVal =
-              UpnpDownloadXmlDoc( description,
-                                  xmlDoc ) ) != UPNP_E_SUCCESS ) {
-            return retVal;
-        }
-        last_modified = time( NULL );
-    } else if( descriptionType == UPNPREG_FILENAME_DESC ) {
-        retVal = stat( description, &file_info );
-        if( retVal == -1 ) {
-            return UPNP_E_FILE_NOT_FOUND;
-        }
-        fileLen = file_info.st_size;
-        last_modified = file_info.st_mtime;
-
-        if( ( fp = fopen( description, "rb" ) ) == NULL ) {
-            return UPNP_E_FILE_NOT_FOUND;
-        }
-
-        if( ( membuf = ( char * )malloc( fileLen + 1 ) ) == NULL ) {
-            fclose( fp );
-            return UPNP_E_OUTOF_MEMORY;
-        }
-
-        num_read = fread( membuf, 1, fileLen, fp );
-        if( num_read != fileLen ) {
-            fclose( fp );
-            free( membuf );
-            return UPNP_E_FILE_READ_ERROR;
-        }
-
-        membuf[fileLen] = 0;
-        fclose( fp );
-        rc = ixmlParseBufferEx( membuf, xmlDoc );
-        free( membuf );
-    } else if( descriptionType == UPNPREG_BUF_DESC ) {
-        last_modified = time( NULL );
-        rc = ixmlParseBufferEx( description, xmlDoc );
-    } else {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    if( rc != IXML_SUCCESS && descriptionType != UPNPREG_URL_DESC ) {
-        if( rc == IXML_INSUFFICIENT_MEMORY ) {
-            return UPNP_E_OUTOF_MEMORY;
-        } else {
-            return UPNP_E_INVALID_DESC;
-        }
-    }
-    // determine alias
-    if( config_baseURL ) {
-        if( descriptionType == UPNPREG_BUF_DESC ) {
-            strcpy( aliasStr, "description.xml" );
-        } else                  // URL or filename
-        {
-            retVal = GetNameForAlias( description, &temp_str );
-            if( retVal != UPNP_E_SUCCESS ) {
-                ixmlDocument_free( *xmlDoc );
-                return retVal;
-            }
-            if( strlen( temp_str ) > ( LINE_SIZE - 1 ) ) {
-                ixmlDocument_free( *xmlDoc );
-                free( temp_str );
-                return UPNP_E_URL_TOO_BIG;
-            }
-            strcpy( aliasStr, temp_str );
-        }
-
-        get_server_addr( &serverAddr );
-
-        // config
-        retVal = configure_urlbase( *xmlDoc, &serverAddr,
-                                    aliasStr, last_modified, descURL );
-        if( retVal != UPNP_E_SUCCESS ) {
-            ixmlDocument_free( *xmlDoc );
-            return retVal;
-        }
-    } else                      // manual
-    {
-        if( strlen( description ) > ( LINE_SIZE - 1 ) ) {
-            ixmlDocument_free( *xmlDoc );
-            return UPNP_E_URL_TOO_BIG;
-        }
-        strcpy( descURL, description );
-    }
-
-    assert( *xmlDoc != NULL );
-
-    return UPNP_E_SUCCESS;
-}
-
-#else // no web server
-
-/**************************************************************************
- * Function: GetDescDocumentAndURL ( In the case of control point)
- *
- *  Parameters:	
- *	IN Upnp_DescType descriptionType: pointer to server address
- *		structure 
- *	IN char* description:
- *	IN unsigned int bufferLen:
- *	IN int config_baseURL:
- *	OUT IXML_Document **xmlDoc:
- *	OUT char *descURL: 
- *
- * Description:
- *	This function fills the sockadr_in with miniserver information.
- *
- * Return Values: VOID
- *      
- ***************************************************************************/
-static int
-GetDescDocumentAndURL( IN Upnp_DescType descriptionType,
-                       IN char *description,
-                       IN unsigned int bufferLen,
-                       IN int config_baseURL,
-                       OUT IXML_Document ** xmlDoc,
-                       OUT char *descURL )
-{
-    int retVal;
-
-    if( ( descriptionType != UPNPREG_URL_DESC ) || config_baseURL ) {
-        return UPNP_E_NO_WEB_SERVER;
-    }
-
-    if( description == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    if( strlen( description ) > ( LINE_SIZE - 1 ) ) {
-        return UPNP_E_URL_TOO_BIG;
-    }
-    strcpy( descURL, description );
-
-    if( ( retVal =
-          UpnpDownloadXmlDoc( description, xmlDoc ) ) != UPNP_E_SUCCESS ) {
-        return retVal;
-    }
-
-    return UPNP_E_SUCCESS;
-}
-
-#endif // INTERNAL_WEB_SERVER
-// ********************************************************
-
-/****************************************************************************
- * Function: UpnpRegisterRootDevice2
- *
- * Parameters:	
- *	IN Upnp_DescType descriptionType: The type of description document.
- *	IN const char* description:  Treated as a URL, file name or 
- *		memory buffer depending on description type. 
- *	IN size_t bufferLen: Length of memory buffer if passing a description
- *		in a buffer, otherwize ignored.
- *	IN int config_baseURL: If nonzero, URLBase of description document is 
- *		configured and the description is served using the internal
- *		web server.
- *	IN Upnp_FunPtr Fun: Pointer to the callback function for 
- *		receiving asynchronous events. 
- *	IN const void* Cookie: Pointer to user data returned with the 
- *		callback function when invoked. 
- *	OUT UpnpDevice_Handle* Hnd: Pointer to a variable to store 
- *		the new device handle.
- *
- * Description:
- *	This function is similar to  UpnpRegisterRootDevice except that
- *	it also allows the description document to be specified as a file or 
- *	a memory buffer. The description can also be configured to have the
- *	correct IP and port address.
- *
- * Return Values:
- *      UPNP_E_SUCCESS on success, nonzero on failure.
- *****************************************************************************/
-int
-UpnpRegisterRootDevice2( IN Upnp_DescType descriptionType,
-                         IN const char *description_const,
-                         IN size_t bufferLen,   // ignored unless descType == UPNPREG_BUF_DESC
-
-                         IN int config_baseURL,
-                         IN Upnp_FunPtr Fun,
-                         IN const void *Cookie,
-                         OUT UpnpDevice_Handle * Hnd )
-{
-    struct Handle_Info *HInfo;
-    int retVal = 0;
-    char *description = ( char * )description_const;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                         "Inside UpnpRegisterRootDevice2 \n" );
-         )
-
-        if( Hnd == NULL || Fun == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    HandleLock(  );
-
-    if( UpnpSdkDeviceRegistered ) {
-        HandleUnlock(  );
-        return UPNP_E_ALREADY_REGISTERED;
-    }
-
-    if( ( *Hnd = GetFreeHandle(  ) ) == UPNP_E_OUTOF_HANDLE ) {
-        HandleUnlock(  );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    HInfo = ( struct Handle_Info * )malloc( sizeof( struct Handle_Info ) );
-    if( HInfo == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    HandleTable[*Hnd] = HInfo;
-
-    // prevent accidental removal of a non-existent alias
-    HInfo->aliasInstalled = 0;
-
-    retVal = GetDescDocumentAndURL( descriptionType, description,
-                                    bufferLen, config_baseURL,
-                                    &HInfo->DescDocument, HInfo->DescURL );
-    //HInfo->DescAlias );
-
-    if( retVal != UPNP_E_SUCCESS ) {
-        FreeHandle( *Hnd );
-        HandleUnlock(  );
-        return retVal;
-    }
-
-    HInfo->aliasInstalled = ( config_baseURL != 0 );
-
-    HInfo->HType = HND_DEVICE;
-    HInfo->Callback = Fun;
-    HInfo->Cookie = ( void * )Cookie;
-    HInfo->MaxAge = DEFAULT_MAXAGE;
-    HInfo->DeviceList = NULL;
-    HInfo->ServiceList = NULL;
-    CLIENTONLY( HInfo->ClientSubList = NULL;
-         )
-        CLIENTONLY( ListInit( &HInfo->SsdpSearchList, NULL, NULL );
-         );
-    HInfo->MaxSubscriptions = UPNP_INFINITE;
-    HInfo->MaxSubscriptionTimeOut = UPNP_INFINITE;
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "UpnpRegisterRootDevice2: Valid Description\n" );
-             UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "UpnpRegisterRootDevice2: DescURL : %s\n",
-                         HInfo->DescURL );
-         )
-
-        HInfo->DeviceList =
-        ixmlDocument_getElementsByTagName( HInfo->DescDocument, "device" );
-
-    if( HInfo->DeviceList == NULL ) {
-        CLIENTONLY( ListDestroy( &HInfo->SsdpSearchList, 0 ) );
-        ixmlDocument_free( HInfo->DescDocument );
-        FreeHandle( *Hnd );
-        HandleUnlock(  );
-        DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "UpnpRegisterRootDevice2: No devices found for RootDevice\n" );
-             )
-            return UPNP_E_INVALID_DESC;
-    }
-
-    HInfo->ServiceList =
-        ixmlDocument_getElementsByTagName( HInfo->DescDocument,
-                                           "serviceList" );
-
-    if( HInfo->ServiceList == NULL ) {
-        CLIENTONLY( ListDestroy( &HInfo->SsdpSearchList, 0 ) );
-        ixmlNodeList_free( HInfo->DeviceList );
-        ixmlDocument_free( HInfo->DescDocument );
-        FreeHandle( *Hnd );
-        HandleUnlock(  );
-        DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "UpnpRegisterRootDevice2: No services found for RootDevice\n" );
-             )
-            return UPNP_E_INVALID_DESC;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "UpnpRegisterRootDevice2: Gena Check\n" );
-         )
-        //*******************************
-        //GENA SET UP
-        //*******************************
-        if( getServiceTable( ( IXML_Node * ) HInfo->DescDocument,
-                             &HInfo->ServiceTable, HInfo->DescURL ) ) {
-        DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                             "UpnpRegisterRootDevice2: GENA Service Table \n" );
-             )
-    } else {
-        CLIENTONLY( ListDestroy( &HInfo->SsdpSearchList, 0 ) );
-        FreeHandle( *Hnd );
-        HandleUnlock(  );
-        DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "\nUpnpRegisterRootDevice: Errors retrieving service table \n" );
-             )
-            return UPNP_E_INVALID_DESC;
-    }
-    UpnpSdkDeviceRegistered = 1;
-    HandleUnlock(  );
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting RegisterRootDevice2 Successfully\n" );
-         )
-        return UPNP_E_SUCCESS;
-
-}  /****************** End of UpnpRegisterRootDevice2  *********************/
-
-#endif //INCLUDE_DEVICE_APIS
-
-#ifdef INCLUDE_CLIENT_APIS
-
-/**************************************************************************
- * Function: UpnpRegisterClient
- *
- * Parameters:	
- *	IN Upnp_FunPtr Fun:  Pointer to a function for receiving 
- *		 asynchronous events.
- *	IN const void * Cookie: Pointer to user data returned with the 
- *		callback function when invoked.
- *	OUT UpnpClient_Handle *Hnd: Pointer to a variable to store 
- *		the new control point handle.
- *
- * Description:
- *	This function registers a control point application with the
- *	UPnP Library.  A control point application cannot make any other API 
- *	calls until it registers using this function.
- *
- * Return Values: int
- *      
- ***************************************************************************/
-int
-UpnpRegisterClient( IN Upnp_FunPtr Fun,
-                    IN const void *Cookie,
-                    OUT UpnpClient_Handle * Hnd )
-{
-    struct Handle_Info *HInfo;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpRegisterClient \n" );
-         )
-
-        if( Fun == NULL || Hnd == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    HandleLock(  );
-
-    if( UpnpSdkClientRegistered ) {
-        HandleUnlock(  );
-        return UPNP_E_ALREADY_REGISTERED;
-    }
-
-    if( ( *Hnd = GetFreeHandle(  ) ) == UPNP_E_OUTOF_HANDLE ) {
-        HandleUnlock(  );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    HInfo = ( struct Handle_Info * )malloc( sizeof( struct Handle_Info ) );
-    if( HInfo == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    HInfo->HType = HND_CLIENT;
-    HInfo->Callback = Fun;
-    HInfo->Cookie = ( void * )Cookie;
-    DEVICEONLY( HInfo->MaxAge = 0;
-		)
-    HInfo->ClientSubList = NULL;
-    ListInit( &HInfo->SsdpSearchList, NULL, NULL );
-    DEVICEONLY( HInfo->MaxSubscriptions = UPNP_INFINITE;
-         )
-        DEVICEONLY( HInfo->MaxSubscriptionTimeOut = UPNP_INFINITE;
-         )
-
-        HandleTable[*Hnd] = HInfo;
-
-    UpnpSdkClientRegistered = 1;
-
-    HandleUnlock(  );
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpRegisterClient \n" );
-         )
-
-        return UPNP_E_SUCCESS;
-
-}  /****************** End of UpnpRegisterClient   *********************/
-#endif // INCLUDE_CLIENT_APIS
-
-#ifdef INCLUDE_CLIENT_APIS
-
-/****************************************************************************
- * Function: UpnpUnRegisterClient
- *
- * Parameters:	
- *	IN UpnpClient_Handle Hnd: The handle of the control point instance 
- *		to unregister
- * Description:
- *	This function unregisters a client registered with 
- *	UpnpRegisterclient or UpnpRegisterclient2. After this call, the 
- *	UpnpDevice_Handle Hnd is no longer valid. The UPnP Library generates 
- *	no more callbacks after this function returns.
- *
- * Return Values:
- *	UPNP_E_SUCCESS on success, nonzero on failure.
- *****************************************************************************/
-int
-UpnpUnRegisterClient( IN UpnpClient_Handle Hnd )
-{
-    struct Handle_Info *HInfo;
-    ListNode *node = NULL;
-    SsdpSearchArg *searchArg = NULL;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpUnRegisterClient \n" );
-         )
-        HandleLock(  );
-    if( !UpnpSdkClientRegistered ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    HandleUnlock(  );
-
-#if EXCLUDE_GENA == 0
-    if( genaUnregisterClient( Hnd ) != UPNP_E_SUCCESS )
-        return UPNP_E_INVALID_HANDLE;
-#endif
-    HandleLock(  );
-    if( GetHandleInfo( Hnd, &HInfo ) == UPNP_E_INVALID_HANDLE ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    //clean up search list
-    node = ListHead( &HInfo->SsdpSearchList );
-    while( node != NULL ) {
-        searchArg = ( SsdpSearchArg * ) node->item;
-        if( searchArg ) {
-            free( searchArg->searchTarget );
-            free( searchArg );
-        }
-        ListDelNode( &HInfo->SsdpSearchList, node, 0 );
-        node = ListHead( &HInfo->SsdpSearchList );
-    }
-
-    ListDestroy( &HInfo->SsdpSearchList, 0 );
-    FreeHandle( Hnd );
-    UpnpSdkClientRegistered = 0;
-    HandleUnlock(  );
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpUnRegisterClient \n" );
-         )
-        return UPNP_E_SUCCESS;
-
-}  /****************** End of UpnpUnRegisterClient *********************/
-#endif // INCLUDE_CLIENT_APIS
-
-//-----------------------------------------------------------------------------
-//
-//                                   SSDP interface
-//
-//-----------------------------------------------------------------------------
-
-#ifdef INCLUDE_DEVICE_APIS
-#if EXCLUDE_SSDP == 0
-
-/**************************************************************************
- * Function: UpnpSendAdvertisement 
- *
- * Parameters:	
- *	IN UpnpDevice_Handle Hnd: handle of the device instance
- *	IN int Exp : Timer for resending the advertisement
- *
- * Description:
- *	This function sends the device advertisement. It also schedules a
- *	job for the next advertisement after "Exp" time.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpSendAdvertisement( IN UpnpDevice_Handle Hnd,
-                       IN int Exp )
-{
-    struct Handle_Info *SInfo = NULL;
-    int retVal = 0,
-     *ptrMx;
-    upnp_timeout *adEvent;
-    ThreadPoolJob job;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpSendAdvertisement \n" );
-         )
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    if( Exp < 1 )
-        Exp = DEFAULT_MAXAGE;
-    SInfo->MaxAge = Exp;
-    HandleUnlock(  );
-    retVal = AdvertiseAndReply( 1, Hnd, 0, ( struct sockaddr_in * )NULL,
-                                ( char * )NULL, ( char * )NULL,
-                                ( char * )NULL, Exp );
-
-    if( retVal != UPNP_E_SUCCESS )
-        return retVal;
-    ptrMx = ( int * )malloc( sizeof( int ) );
-    if( ptrMx == NULL )
-        return UPNP_E_OUTOF_MEMORY;
-    adEvent = ( upnp_timeout * ) malloc( sizeof( upnp_timeout ) );
-
-    if( adEvent == NULL ) {
-        free( ptrMx );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    *ptrMx = Exp;
-    adEvent->handle = Hnd;
-    adEvent->Event = ptrMx;
-
-    HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
-        HandleUnlock(  );
-        free( adEvent );
-        free( ptrMx );
-        return UPNP_E_INVALID_HANDLE;
-    }
-#ifdef SSDP_PACKET_DISTRIBUTE
-    TPJobInit( &job, ( start_routine ) AutoAdvertise, adEvent );
-    TPJobSetFreeFunction( &job, ( free_routine ) free_upnp_timeout );
-    TPJobSetPriority( &job, MED_PRIORITY );
-    if( ( retVal = TimerThreadSchedule( &gTimerThread,
-                                        ( ( Exp / 2 ) -
-                                          ( AUTO_ADVERTISEMENT_TIME ) ),
-                                        REL_SEC, &job, SHORT_TERM,
-                                        &( adEvent->eventId ) ) )
-        != UPNP_E_SUCCESS ) {
-        HandleUnlock(  );
-        free( adEvent );
-        free( ptrMx );
-        return retVal;
-    }
-#else
-    TPJobInit( &job, ( start_routine ) AutoAdvertise, adEvent );
-    TPJobSetFreeFunction( &job, ( free_routine ) free_upnp_timeout );
-    TPJobSetPriority( &job, MED_PRIORITY );
-    if( ( retVal = TimerThreadSchedule( &gTimerThread,
-                                        Exp - AUTO_ADVERTISEMENT_TIME,
-                                        REL_SEC, &job, SHORT_TERM,
-                                        &( adEvent->eventId ) ) )
-        != UPNP_E_SUCCESS ) {
-        HandleUnlock(  );
-        free( adEvent );
-        free( ptrMx );
-        return retVal;
-    }
-#endif
-
-    HandleUnlock(  );
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpSendAdvertisement \n" ); )
-
-        return retVal;
-
-}  /****************** End of UpnpSendAdvertisement *********************/
-#endif // INCLUDE_DEVICE_APIS
-#endif
-#if EXCLUDE_SSDP == 0
-#ifdef INCLUDE_CLIENT_APIS
-
-/**************************************************************************
- * Function: UpnpSearchAsync 
- *
- * Parameters:	
- *	IN UpnpClient_Handle Hnd: handle of the control point instance
- *	IN int Mx : Maximum time to wait for the search reply
- *	IN const char *Target_const: 
- *	IN const void *Cookie_const:
- *
- * Description:
- *	This function searches for the devices for the provided maximum time.
- *	It is a asynchronous function. It schedules a search job and returns. 
- *	client is notified about the search results after search timer.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpSearchAsync( IN UpnpClient_Handle Hnd,
-                 IN int Mx,
-                 IN const char *Target_const,
-                 IN const void *Cookie_const )
-{
-    struct Handle_Info *SInfo = NULL;
-    char *Target = ( char * )Target_const;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpSearchAsync \n" );
-         )
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    if( Mx < 1 )
-        Mx = DEFAULT_MX;
-
-    if( Target == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    HandleUnlock(  );
-    SearchByTarget( Mx, Target, ( void * )Cookie_const );
-
-    //HandleUnlock();
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpSearchAsync \n" );
-         )
-
-        return UPNP_E_SUCCESS;
-
-}  /****************** End of UpnpSearchAsync *********************/
-#endif // INCLUDE_CLIENT_APIS
-#endif
-//-----------------------------------------------------------------------------
-//
-//                                   GENA interface 
-//
-//-----------------------------------------------------------------------------
-
-#if EXCLUDE_GENA == 0
-#ifdef INCLUDE_DEVICE_APIS
-
-/**************************************************************************
- * Function: UpnpSetMaxSubscriptions 
- *
- * Parameters:	
- *	IN UpnpDevice_Handle Hnd: The handle of the device for which
- *		the maximum subscriptions is being set.
- *	IN int MaxSubscriptions: The maximum number of subscriptions to be
- *		allowed per service.
- *
- * Description:
- *	This function sets the maximum subscriptions of the control points
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpSetMaxSubscriptions( IN UpnpDevice_Handle Hnd,
-                         IN int MaxSubscriptions )
-{
-    struct Handle_Info *SInfo = NULL;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpSetMaxSubscriptions \n" );
-         )
-
-        HandleLock(  );
-    if( ( ( MaxSubscriptions != UPNP_INFINITE )
-          && ( MaxSubscriptions < 0 ) )
-        || ( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    SInfo->MaxSubscriptions = MaxSubscriptions;
-    HandleUnlock(  );
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpSetMaxSubscriptions \n" );
-         )
-
-        return UPNP_E_SUCCESS;
-
-}  /***************** End of UpnpSetMaxSubscriptions ********************/
-#endif // INCLUDE_DEVICE_APIS
-
-#ifdef INCLUDE_DEVICE_APIS
-
-/**************************************************************************
- * Function: UpnpSetMaxSubscriptionTimeOut 
- *
- * Parameters:	
- *	IN UpnpDevice_Handle Hnd: The handle of the device for which the
- *		maximum subscription time-out is being set.
- *	IN int MaxSubscriptionTimeOut:The maximum subscription time-out 
- *		to be accepted
- *
- * Description:
- *	This function sets the maximum subscription timer. Control points
- *	will require to send the subscription request before timeout.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpSetMaxSubscriptionTimeOut( IN UpnpDevice_Handle Hnd,
-                               IN int MaxSubscriptionTimeOut )
-{
-    struct Handle_Info *SInfo = NULL;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpSetMaxSubscriptionTimeOut \n" );
-         )
-
-        HandleLock(  );
-
-    if( ( ( MaxSubscriptionTimeOut != UPNP_INFINITE )
-          && ( MaxSubscriptionTimeOut < 0 ) )
-        || ( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-
-    SInfo->MaxSubscriptionTimeOut = MaxSubscriptionTimeOut;
-    HandleUnlock(  );
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpSetMaxSubscriptionTimeOut \n" );
-         )
-
-        return UPNP_E_SUCCESS;
-
-}  /****************** End of UpnpSetMaxSubscriptionTimeOut ******************/
-#endif // INCLUDE_DEVICE_APIS
-
-#ifdef INCLUDE_CLIENT_APIS
-
-/**************************************************************************
- * Function: UpnpSubscribeAsync 
- *
- * Parameters:	
- *	IN UpnpClient_Handle Hnd: The handle of the control point for which 
- *		the subscription request is to be sent.
- *	IN const char * EvtUrl_const: URL that control point wants to 
- *		subscribe
- *	IN int TimeOut: The requested subscription time.  Upon 
- *		return, it contains the actual subscription time 
- *		returned from the service
- *	IN Upnp_FunPtr Fun : callback function to tell result of the 
- *		subscription request
- *	IN const void * Cookie_const: cookie passed by client to give back 
- *		in the callback function.
- *
- * Description:
- *	This function performs the same operation as UpnpSubscribeAsync
- *	but returns immediately and calls the registered callback function 
- *	when the operation is complete.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpSubscribeAsync( IN UpnpClient_Handle Hnd,
-                    IN const char *EvtUrl_const,
-                    IN int TimeOut,
-                    IN Upnp_FunPtr Fun,
-                    IN const void *Cookie_const )
-{
-    struct Handle_Info *SInfo = NULL;
-    struct UpnpNonblockParam *Param;
-    char *EvtUrl = ( char * )EvtUrl_const;
-    ThreadPoolJob job;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpSubscribeAsync \n" );
-         )
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    if( EvtUrl == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( TimeOut != UPNP_INFINITE && TimeOut < 1 ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( Fun == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    Param =
-        ( struct UpnpNonblockParam * )
-        malloc( sizeof( struct UpnpNonblockParam ) );
-    if( Param == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    HandleUnlock(  );
-
-    Param->FunName = SUBSCRIBE;
-    Param->Handle = Hnd;
-    strcpy( Param->Url, EvtUrl );
-    Param->TimeOut = TimeOut;
-    Param->Fun = Fun;
-    Param->Cookie = ( void * )Cookie_const;
-
-    TPJobInit( &job, ( start_routine ) UpnpThreadDistribution, Param );
-    TPJobSetFreeFunction( &job, ( free_routine ) free );
-    TPJobSetPriority( &job, MED_PRIORITY );
-    if (ThreadPoolAdd( &gSendThreadPool, &job, NULL ) != 0) {
-        free(Param);
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpSubscribeAsync \n" );
-         )
-
-        return UPNP_E_SUCCESS;
-
-}  /****************** End of UpnpSubscribeAsync *********************/
-#endif // INCLUDE_CLIENT_APIS
-
-#ifdef INCLUDE_CLIENT_APIS
-
-/**************************************************************************
- * Function: UpnpSubscribe 
- *
- * Parameters:	
- *	IN UpnpClient_Handle Hnd: The handle of the control point.
- *	IN const char *PublisherUrl: The URL of the service to subscribe to.
- *	INOUT int *TimeOut: Pointer to a variable containing the requested 
- *		subscription time.  Upon return, it contains the
- *		actual subscription time returned from the service.
- *	OUT Upnp_SID SubsId: Pointer to a variable to receive the 
- *		subscription ID (SID). 
- *
- * Description:
- *	This function registers a control point to receive event
- *	notifications from another device.  This operation is synchronous
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpSubscribe( IN UpnpClient_Handle Hnd,
-               IN const char *EvtUrl_const,
-               INOUT int *TimeOut,
-               OUT Upnp_SID SubsId )
-{
-    struct Handle_Info *SInfo = NULL;
-    int RetVal;
-    char *EvtUrl = ( char * )EvtUrl_const;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpSubscribe \n" );
-         )
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    if( EvtUrl == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( TimeOut == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( SubsId == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    HandleUnlock(  );
-    RetVal = genaSubscribe( Hnd, EvtUrl, TimeOut, SubsId );
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpSubscribe \n" );
-         )
-
-        return RetVal;
-
-}  /****************** End of UpnpSubscribe  *********************/
-#endif // INCLUDE_CLIENT_APIS
-
-#ifdef INCLUDE_CLIENT_APIS
-
-/**************************************************************************
- * Function: UpnpUnSubscribe 
- *
- *  Parameters:	
- *	IN UpnpClient_Handle Hnd: The handle of the control point.
- *	IN Upnp_SID SubsId: The ID returned when the control point 
- *		subscribed to the service.
- *
- * Description:
- *	This function removes the subscription of  a control point from a 
- *	service previously subscribed to using UpnpSubscribe or 
- *	UpnpSubscribeAsync. This is a synchronous call.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpUnSubscribe( IN UpnpClient_Handle Hnd,
-                 IN Upnp_SID SubsId )
-{
-    struct Handle_Info *SInfo = NULL;
-    int RetVal;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpUnSubscribe \n" );
-         )
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    if( SubsId == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    HandleUnlock(  );
-    RetVal = genaUnSubscribe( Hnd, SubsId );
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpUnSubscribe \n" );
-         )
-
-        return RetVal;
-
-}  /****************** End of UpnpUnSubscribe  *********************/
-#endif // INCLUDE_CLIENT_APIS
-
-#ifdef INCLUDE_CLIENT_APIS
-
-/**************************************************************************
- * Function: UpnpUnSubscribeAsync 
- *
- *  Parameters:	
- *	IN UpnpClient_Handle Hnd: The handle of the subscribed control point. 
- *	IN Upnp_SID SubsId: The ID returned when the control point 
- *		subscribed to the service.
- *	IN Upnp_FunPtr Fun: Pointer to a callback function to be called
- *		when the operation is complete. 
- *	IN const void *Cookie:Pointer to user data to pass to the
- *		callback function when invoked.
- *
- *  Description:
- *      This function removes a subscription of a control point
- *  from a service previously subscribed to using UpnpSubscribe or
- *	UpnpSubscribeAsync,generating a callback when the operation is complete.
- *
- *  Return Values: int
- *      UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpUnSubscribeAsync( IN UpnpClient_Handle Hnd,
-                      IN Upnp_SID SubsId,
-                      IN Upnp_FunPtr Fun,
-                      IN const void *Cookie_const )
-{
-    ThreadPoolJob job;
-    struct Handle_Info *SInfo = NULL;
-    struct UpnpNonblockParam *Param;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpUnSubscribeAsync \n" );
-         )
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    if( SubsId == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( Fun == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    HandleUnlock(  );
-    Param =
-        ( struct UpnpNonblockParam * )
-        malloc( sizeof( struct UpnpNonblockParam ) );
-    if( Param == NULL )
-        return UPNP_E_OUTOF_MEMORY;
-
-    Param->FunName = UNSUBSCRIBE;
-    Param->Handle = Hnd;
-    strcpy( Param->SubsId, SubsId );
-    Param->Fun = Fun;
-    Param->Cookie = ( void * )Cookie_const;
-    TPJobInit( &job, ( start_routine ) UpnpThreadDistribution, Param );
-    TPJobSetFreeFunction( &job, ( free_routine ) free );
-    TPJobSetPriority( &job, MED_PRIORITY );
-    if (ThreadPoolAdd( &gSendThreadPool, &job, NULL ) != 0) {
-        free(Param);
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpUnSubscribeAsync \n" );
-         )
-
-        return UPNP_E_SUCCESS;
-
-}  /****************** End of UpnpUnSubscribeAsync  *********************/
-#endif // INCLUDE_CLIENT_APIS
-
-#ifdef INCLUDE_CLIENT_APIS
-
-/**************************************************************************
- * Function: UpnpRenewSubscription 
- *
- * Parameters:	
- *	IN UpnpClient_Handle Hnd: The handle of the control point that 
- *		is renewing the subscription.
- *	INOUT int *TimeOut: Pointer to a variable containing the 
- *		requested subscription time.  Upon return, 
- *		it contains the actual renewal time. 
- *	IN Upnp_SID SubsId: The ID for the subscription to renew. 
- *
- * Description:
- *	This function renews a subscription that is about to 
- *	expire.  This function is synchronous.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpRenewSubscription( IN UpnpClient_Handle Hnd,
-                       INOUT int *TimeOut,
-                       IN Upnp_SID SubsId )
-{
-    struct Handle_Info *SInfo = NULL;
-    int RetVal;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpRenewSubscription \n" );
-         )
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    if( TimeOut == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( SubsId == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    HandleUnlock(  );
-    RetVal = genaRenewSubscription( Hnd, SubsId, TimeOut );
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpRenewSubscription \n" );
-         )
-
-        return RetVal;
-
-}  /****************** End of UpnpRenewSubscription  *********************/
-#endif // INCLUDE_CLIENT_APIS
-
-#ifdef INCLUDE_CLIENT_APIS
-
-/**************************************************************************
- * Function: UpnpRenewSubscriptionAsync 
- *
- * Parameters:	
- *	IN UpnpClient_Handle Hnd: The handle of the control point that 
- *		is renewing the subscription. 
- *	IN int TimeOut: The requested subscription time.  The 
- *		actual timeout value is returned when 
- *		the callback function is called. 
- *	IN Upnp_SID SubsId: The ID for the subscription to renew. 
- *	IN Upnp_FunPtr Fun: Pointer to a callback function to be 
- *		invoked when the renewal is complete. 
- *	IN const void *Cookie  : Pointer to user data passed 
- *		to the callback function when invoked.
- *
- * Description:
- *	This function renews a subscription that is about
- *	to expire, generating a callback when the operation is complete.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpRenewSubscriptionAsync( IN UpnpClient_Handle Hnd,
-                            INOUT int TimeOut,
-                            IN Upnp_SID SubsId,
-                            IN Upnp_FunPtr Fun,
-                            IN const void *Cookie_const )
-{
-    ThreadPoolJob job;
-    struct Handle_Info *SInfo = NULL;
-    struct UpnpNonblockParam *Param;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpRenewSubscriptionAsync \n" );
-         )
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    if( TimeOut != UPNP_INFINITE && TimeOut < 1 ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( SubsId == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( Fun == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    HandleUnlock(  );
-
-    Param =
-        ( struct UpnpNonblockParam * )
-        malloc( sizeof( struct UpnpNonblockParam ) );
-    if( Param == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    Param->FunName = RENEW;
-    Param->Handle = Hnd;
-    strcpy( Param->SubsId, SubsId );
-    Param->Fun = Fun;
-    Param->Cookie = ( void * )Cookie_const;
-    Param->TimeOut = TimeOut;
-
-    TPJobInit( &job, ( start_routine ) UpnpThreadDistribution, Param );
-    TPJobSetFreeFunction( &job, ( free_routine ) free );
-    TPJobSetPriority( &job, MED_PRIORITY );
-    if (ThreadPoolAdd( &gSendThreadPool, &job, NULL ) != 0) {
-        free(Param);
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpRenewSubscriptionAsync \n" );
-         )
-
-        return UPNP_E_SUCCESS;
-
-}  /****************** End of UpnpRenewSubscriptionAsync *******************/
-#endif // INCLUDE_CLIENT_APIS
-
-#ifdef INCLUDE_DEVICE_APIS
-
-/**************************************************************************
- * Function: UpnpNotify 
- *
- *  Parameters:	
- *	IN UpnpDevice_Handle: The handle to the device sending the event.
- *	IN const char *DevID: The device ID of the subdevice of the 
- *		service generating the event. 
- *	IN const char *ServID: The unique identifier of the service 
- *		generating the event. 
- *	IN const char **VarName: Pointer to an array of variables that 
- *		have changed.
- *	IN const char **NewVal: Pointer to an array of new values for 
- *		those variables. 
- *	IN int cVariables: The count of variables included in this 
- *		notification. 
- *
- * Description:
- *	This function sends out an event change notification to all
- *	control points subscribed to a particular service.  This function is
- *	synchronous and generates no callbacks.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpNotify( IN UpnpDevice_Handle Hnd,
-            IN const char *DevID_const,
-            IN const char *ServName_const,
-            IN const char **VarName_const,
-            IN const char **NewVal_const,
-            IN int cVariables )
-{
-
-    struct Handle_Info *SInfo = NULL;
-    int retVal;
-    char *DevID = ( char * )DevID_const;
-    char *ServName = ( char * )ServName_const;
-    char **VarName = ( char ** )VarName_const;
-    char **NewVal = ( char ** )NewVal_const;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpNotify \n" );
-         )
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    if( DevID == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( ServName == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( VarName == NULL || NewVal == NULL || cVariables < 0 ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    HandleUnlock(  );
-    retVal =
-        genaNotifyAll( Hnd, DevID, ServName, VarName, NewVal, cVariables );
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpNotify \n" );
-         )
-
-        return retVal;
-
-} /****************** End of UpnpNotify *********************/
-
-/**************************************************************************
- * Function: UpnpNotifyExt 
- *
- * Parameters:	
- *	IN UpnpDevice_Handle: The handle to the device sending the 
- *		event.
- *	IN const char *DevID: The device ID of the subdevice of the 
- *		service generating the event.
- *	IN const char *ServID: The unique identifier of the service 
- *		generating the event. 
- *	IN IXML_Document *PropSet: The DOM document for the property set. 
- *		Property set documents must conform to the XML schema
- *		defined in section 4.3 of the Universal Plug and Play
- *		Device Architecture specification. 
- *
- * Description:
- *	This function is similar to UpnpNotify except that it takes
- *	a DOM document for the event rather than an array of strings. This 
- *	function is synchronous and generates no callbacks.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpNotifyExt( IN UpnpDevice_Handle Hnd,
-               IN const char *DevID_const,
-               IN const char *ServName_const,
-               IN IXML_Document * PropSet )
-{
-
-    struct Handle_Info *SInfo = NULL;
-    int retVal;
-    char *DevID = ( char * )DevID_const;
-    char *ServName = ( char * )ServName_const;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpNotify \n" );
-         )
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    if( DevID == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( ServName == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    HandleUnlock(  );
-    retVal = genaNotifyAllExt( Hnd, DevID, ServName, PropSet );
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpNotify \n" );
-         )
-
-        return retVal;
-
-}  /****************** End of UpnpNotify *********************/
-
-#endif // INCLUDE_DEVICE_APIS
-
-#ifdef INCLUDE_DEVICE_APIS
-
-/**************************************************************************
- * Function: UpnpAcceptSubscription 
- *
- * Parameters:	
- *	IN UpnpDevice_Handle Hnd: The handle of the device. 
- *	IN const char *DevID: The device ID of the subdevice of the 
- *		service generating the event. 
- *	IN const char *ServID: The unique service identifier of the 
- *		service generating the event.
- *	IN const char **VarName: Pointer to an array of event variables.
- *	IN const char **NewVal: Pointer to an array of values for 
- *		the event variables.
- *	IN int cVariables: The number of event variables in VarName. 
- *	IN Upnp_SID SubsId: The subscription ID of the newly 
- *		registered control point. 
- *
- * Description:
- *	This function accepts a subscription request and sends
- *	out the current state of the eventable variables for a service.  
- *	The device application should call this function when it receives a 
- *	UPNP_EVENT_SUBSCRIPTION_REQUEST callback. This function is sychronous
- *	and generates no callbacks.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpAcceptSubscription( IN UpnpDevice_Handle Hnd,
-                        IN const char *DevID_const,
-                        IN const char *ServName_const,
-                        IN const char **VarName_const,
-                        IN const char **NewVal_const,
-                        int cVariables,
-                        IN Upnp_SID SubsId )
-{
-    struct Handle_Info *SInfo = NULL;
-    int retVal;
-    char *DevID = ( char * )DevID_const;
-    char *ServName = ( char * )ServName_const;
-    char **VarName = ( char ** )VarName_const;
-    char **NewVal = ( char ** )NewVal_const;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpAcceptSubscription \n" );
-         )
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    if( DevID == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( ServName == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( SubsId == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( VarName == NULL || NewVal == NULL || cVariables < 0 ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    HandleUnlock(  );
-    retVal =
-        genaInitNotify( Hnd, DevID, ServName, VarName, NewVal, cVariables,
-                        SubsId );
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpAcceptSubscription \n" );
-         )
-        return retVal;
-
-}  /***************** End of UpnpAcceptSubscription *********************/
-
-/**************************************************************************
- * Function: UpnpAcceptSubscriptionExt 
- *
- * Parameters:	
- * 	IN UpnpDevice_Handle Hnd: The handle of the device. 
- * 	IN const char *DevID: The device ID of the subdevice of the 
- *		service generating the event. 
- *	IN const char *ServID: The unique service identifier of the service 
- *		generating the event. 
- *	IN IXML_Document *PropSet: The DOM document for the property set. 
- *		Property set documents must conform to the XML schema
- *		defined in section 4.3 of the Universal Plug and Play
- *		Device Architecture specification. 
- *	IN Upnp_SID SubsId: The subscription ID of the newly
- *		registered control point. 
- *
- * Description:
- *	This function is similar to UpnpAcceptSubscription except that it
- *	takes a DOM document for the variables to event rather than an array
- *	of strings. This function is sychronous and generates no callbacks.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpAcceptSubscriptionExt( IN UpnpDevice_Handle Hnd,
-                           IN const char *DevID_const,
-                           IN const char *ServName_const,
-                           IN IXML_Document * PropSet,
-                           IN Upnp_SID SubsId )
-{
-    struct Handle_Info *SInfo = NULL;
-    int retVal;
-    char *DevID = ( char * )DevID_const;
-    char *ServName = ( char * )ServName_const;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpAcceptSubscription \n" );
-         )
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    if( DevID == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( ServName == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( SubsId == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    if( PropSet == NULL ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    HandleUnlock(  );
-    retVal = genaInitNotifyExt( Hnd, DevID, ServName, PropSet, SubsId );
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpAcceptSubscription \n" );
-         )
-
-        return retVal;
-
-}  /****************** End of UpnpAcceptSubscription *********************/
-
-#endif // INCLUDE_DEVICE_APIS
-#endif // EXCLUDE_GENA == 0
-
-//---------------------------------------------------------------------------
-//
-//                                   SOAP interface 
-//
-//---------------------------------------------------------------------------
-#if EXCLUDE_SOAP == 0
-#ifdef INCLUDE_CLIENT_APIS
-
-/**************************************************************************
- * Function: UpnpSendAction 
- *
- * Parameters:	
- *	IN UpnpClient_Handle Hnd: The handle of the control point 
- *		sending the action. 
- *	IN const char *ActionURL: The action URL of the service. 
- *	IN const char *ServiceType: The type of the service. 
- *	IN const char *DevUDN: This parameter is ignored. 
- *	IN IXML_Document *Action: The DOM document for the action. 
- *	OUT IXML_Document **RespNode: The DOM document for the response 
- *		to the action.  The UPnP Library allocates this document
- *		and the caller needs to free it.  
- *  
- * Description:
- *	This function sends a message to change a state variable in a service.
- *	This is a synchronous call that does not return until the action is
- *	complete.
- * 
- *	Note that a positive return value indicates a SOAP-protocol error code.
- *	In this case,  the error description can be retrieved from RespNode.
- *	A negative return value indicates a UPnP Library error.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpSendAction( IN UpnpClient_Handle Hnd,
-                IN const char *ActionURL_const,
-                IN const char *ServiceType_const,
-                IN const char *DevUDN_const,
-                IN IXML_Document * Action,
-                OUT IXML_Document ** RespNodePtr )
-{
-    struct Handle_Info *SInfo = NULL;
-    int retVal = 0;
-    char *ActionURL = ( char * )ActionURL_const;
-    char *ServiceType = ( char * )ServiceType_const;
-
-    //char *DevUDN = (char *)DevUDN_const;  // udn not used?
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpSendAction \n" );
-         )
-    if(DevUDN_const !=NULL)
-	DBGONLY(UpnpPrintf(UPNP_ALL,API,__FILE__,__LINE__,"non NULL DevUDN is ignored\n"););
-    DevUDN_const = NULL;
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    HandleUnlock(  );
-
-    if( ActionURL == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    if( ServiceType == NULL || Action == NULL || RespNodePtr == NULL
-        || DevUDN_const != NULL ) {
-
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    retVal = SoapSendAction( ActionURL, ServiceType, Action, RespNodePtr );
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpSendAction \n" );
-         )
-
-        return retVal;
-
-}  /****************** End of UpnpSendAction *********************/
-
-/**************************************************************************
- * Function: UpnpSendActionEx 
- *
- * Parameters:	
- *	IN UpnpClient_Handle Hnd: The handle of the control point sending
- *		the action. 
- *	IN const char *ActionURL_const: The action URL of the service. 
- *	IN const char *ServiceType_const: The type of the service. 
- *	IN const char *DevUDN_const: This parameter is ignored. 
- *	IN IXML_Document *Header: The DOM document for the SOAP header. 
- *		This may be NULL if the header is not required. 
- *	IN IXML_Document *Action:   The DOM document for the action. 
- *	OUT IXML_Document **RespNodePtr: The DOM document for the response to
- *		the action.  The UPnP library allocates this document and the
- *		caller needs to free it.
- *  
- * Description:
- *	this function sends a message to change a state variable in a 
- *	service. This is a synchronous call that does not return until the 
- *	action is complete.
- *
- *	Note that a positive return value indicates a SOAP-protocol error code.
- *	In this case,  the error description can be retrieved from {\bf RespNode}.
- *	A negative return value indicates a UPnP Library error.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpSendActionEx( IN UpnpClient_Handle Hnd,
-                  IN const char *ActionURL_const,
-                  IN const char *ServiceType_const,
-                  IN const char *DevUDN_const,
-                  IN IXML_Document * Header,
-                  IN IXML_Document * Action,
-                  OUT IXML_Document ** RespNodePtr )
-{
-
-    struct Handle_Info *SInfo = NULL;
-    int retVal = 0;
-    char *ActionURL = ( char * )ActionURL_const;
-    char *ServiceType = ( char * )ServiceType_const;
-
-    //char *DevUDN = (char *)DevUDN_const;  // udn not used?
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpSendActionEx \n" );
-         )
-
-        if( Header == NULL ) {
-        retVal = UpnpSendAction( Hnd, ActionURL_const, ServiceType_const,
-                                 DevUDN_const, Action, RespNodePtr );
-        return retVal;
-    }
-
-    HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    HandleUnlock(  );
-
-    if( ActionURL == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( ServiceType == NULL || Action == NULL || RespNodePtr == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    retVal = SoapSendActionEx( ActionURL, ServiceType, Header,
-                               Action, RespNodePtr );
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpSendAction \n" );
-         )
-
-        return retVal;
-
-}  /****************** End of UpnpSendActionEx *********************/
-
-/**************************************************************************
- * Function: UpnpSendActionAsync 
- *
- *  Parameters:	
- *	IN UpnpClient_Handle Hnd: The handle of the control point 
- *		sending the action. 
- *	IN const char *ActionURL: The action URL of the service. 
- *	IN const char *ServiceType: The type of the service. 
- *	IN const char *DevUDN: This parameter is ignored. 
- *	IN IXML_Document *Action: The DOM document for the action to 
- *		perform on this device. 
- *	IN Upnp_FunPtr Fun: Pointer to a callback function to 
- *		be invoked when the operation completes
- *	IN const void *Cookie: Pointer to user data that to be 
- *		passed to the callback when invoked.
- *  
- * Description:
- *	this function sends a message to change a state variable
- *	in a service, generating a callback when the operation is complete.
- *	See UpnpSendAction for comments on positive return values. These 
- *	positive return values are sent in the event struct associated with the
- *	UPNP_CONTROL_ACTION_COMPLETE event.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpSendActionAsync( IN UpnpClient_Handle Hnd,
-                     IN const char *ActionURL_const,
-                     IN const char *ServiceType_const,
-                     IN const char *DevUDN_const,
-                     IN IXML_Document * Act,
-                     IN Upnp_FunPtr Fun,
-                     IN const void *Cookie_const )
-{
-    ThreadPoolJob job;
-    struct Handle_Info *SInfo = NULL;
-    struct UpnpNonblockParam *Param;
-    DOMString tmpStr;
-    char *ActionURL = ( char * )ActionURL_const;
-    char *ServiceType = ( char * )ServiceType_const;
-
-    //char *DevUDN = (char *)DevUDN_const;
-    int rc;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpSendActionAsync \n" );
-         )
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    HandleUnlock(  );
-
-    if( ActionURL == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( ServiceType == NULL ||
-        Act == NULL || Fun == NULL || DevUDN_const != NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-    tmpStr = ixmlPrintNode( ( IXML_Node * ) Act );
-    if( tmpStr == NULL ) {
-        return UPNP_E_INVALID_ACTION;
-    }
-
-    Param =
-        ( struct UpnpNonblockParam * )
-        malloc( sizeof( struct UpnpNonblockParam ) );
-
-    if( Param == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    Param->FunName = ACTION;
-    Param->Handle = Hnd;
-    strcpy( Param->Url, ActionURL );
-    strcpy( Param->ServiceType, ServiceType );
-
-    rc = ixmlParseBufferEx( tmpStr, &( Param->Act ) );
-    if( rc != IXML_SUCCESS ) {
-        free( Param );
-        ixmlFreeDOMString( tmpStr );
-        if( rc == IXML_INSUFFICIENT_MEMORY ) {
-            return UPNP_E_OUTOF_MEMORY;
-        } else {
-            return UPNP_E_INVALID_ACTION;
-        }
-    }
-    ixmlFreeDOMString( tmpStr );
-    Param->Cookie = ( void * )Cookie_const;
-    Param->Fun = Fun;
-
-    TPJobInit( &job, ( start_routine ) UpnpThreadDistribution, Param );
-    TPJobSetFreeFunction( &job, ( free_routine ) free );
-
-    TPJobSetPriority( &job, MED_PRIORITY );
-    if (ThreadPoolAdd( &gSendThreadPool, &job, NULL ) != 0) {
-        free(Param);
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpSendActionAsync \n" );
-         )
-
-        return UPNP_E_SUCCESS;
-
-}  /****************** End of UpnpSendActionAsync *********************/
-
-/*************************************************************************
- * Function: UpnpSendActionExAsync 
- *
- * Parameters:	
- *	IN UpnpClient_Handle Hnd: The handle of the control point 
- *		sending the action. 
- *	IN const char *ActionURL_const: The action URL of the service. 
- *	IN const char *ServiceType_const: The type of the service. 
- *	IN const char *DevUDN_const: This parameter is ignored. 
- *	IN IXML_Document *Header: The DOM document for the SOAP header. 
- *		This may be NULL if the header is not required. 
- *	IN IXML_Document *Act: The DOM document for the action to 
- *		perform on this device. 
- *	IN Upnp_FunPtr Fun: Pointer to a callback function to be invoked
- *		when the operation completes. 
- *	IN const void *Cookie_const: Pointer to user data that to be
- *		passed to the callback when invoked. 
- *
- * Description:
- *	this function sends sends a message to change a state variable
- *	in a service, generating a callback when the operation is complete.
- *	See UpnpSendAction for comments on positive return values. These 
- *	positive return values are sent in the event struct associated with 
- *	the UPNP_CONTROL_ACTION_COMPLETE event.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpSendActionExAsync( IN UpnpClient_Handle Hnd,
-                       IN const char *ActionURL_const,
-                       IN const char *ServiceType_const,
-                       IN const char *DevUDN_const,
-                       IN IXML_Document * Header,
-                       IN IXML_Document * Act,
-                       IN Upnp_FunPtr Fun,
-                       IN const void *Cookie_const )
-{
-    struct Handle_Info *SInfo = NULL;
-    struct UpnpNonblockParam *Param;
-    DOMString tmpStr;
-    DOMString headerStr = NULL;
-    char *ActionURL = ( char * )ActionURL_const;
-    char *ServiceType = ( char * )ServiceType_const;
-    ThreadPoolJob job;
-    int retVal = 0;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpSendActionExAsync \n" );
-         )
-
-        if( Header == NULL ) {
-        retVal = UpnpSendActionAsync( Hnd, ActionURL_const,
-                                      ServiceType_const, DevUDN_const, Act,
-                                      Fun, Cookie_const );
-        return retVal;
-    }
-
-    HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    HandleUnlock(  );
-
-    if( ActionURL == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( ServiceType == NULL || Act == NULL || Fun == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    headerStr = ixmlPrintNode( ( IXML_Node * ) Header );
-
-    tmpStr = ixmlPrintNode( ( IXML_Node * ) Act );
-    if( tmpStr == NULL ) {
-        ixmlFreeDOMString( headerStr );
-        return UPNP_E_INVALID_ACTION;
-    }
-
-    Param =
-        ( struct UpnpNonblockParam * )
-        malloc( sizeof( struct UpnpNonblockParam ) );
-    if( Param == NULL ) {
-        ixmlFreeDOMString( tmpStr );
-        ixmlFreeDOMString( headerStr );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    Param->FunName = ACTION;
-    Param->Handle = Hnd;
-    strcpy( Param->Url, ActionURL );
-    strcpy( Param->ServiceType, ServiceType );
-    retVal = ixmlParseBufferEx( headerStr, &( Param->Header ) );
-    if( retVal != IXML_SUCCESS ) {
-        free( Param );
-        ixmlFreeDOMString( tmpStr );
-        ixmlFreeDOMString( headerStr );
-        if( retVal == IXML_INSUFFICIENT_MEMORY ) {
-            return UPNP_E_OUTOF_MEMORY;
-        } else {
-            return UPNP_E_INVALID_ACTION;
-        }
-    }
-
-    retVal = ixmlParseBufferEx( tmpStr, &( Param->Act ) );
-    if( retVal != IXML_SUCCESS ) {
-        ixmlDocument_free( Param->Header );
-        free( Param );
-        ixmlFreeDOMString( tmpStr );
-        ixmlFreeDOMString( headerStr );
-        if( retVal == IXML_INSUFFICIENT_MEMORY ) {
-            return UPNP_E_OUTOF_MEMORY;
-        } else {
-            return UPNP_E_INVALID_ACTION;
-        }
-
-    }
-
-    ixmlFreeDOMString( tmpStr );
-    ixmlFreeDOMString( headerStr );
-
-    Param->Cookie = ( void * )Cookie_const;
-    Param->Fun = Fun;
-
-    TPJobInit( &job, ( start_routine ) UpnpThreadDistribution, Param );
-    TPJobSetFreeFunction( &job, ( free_routine ) free );
-
-    TPJobSetPriority( &job, MED_PRIORITY );
-    if (ThreadPoolAdd( &gSendThreadPool, &job, NULL ) != 0) {
-        free(Param);
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpSendActionAsync \n" );
-         )
-
-        return UPNP_E_SUCCESS;
-
-}  /****************** End of UpnpSendActionExAsync *********************/
-
-/*************************************************************************
- * Function: UpnpGetServiceVarStatusAsync 
- *
- * Parameters:	
- *	IN UpnpClient_Handle Hnd: The handle of the control point. 
- *	IN const char *ActionURL: The URL of the service. 
- *	IN const char *VarName: The name of the variable to query. 
- *	IN Upnp_FunPtr Fun: Pointer to a callback function to 
- *		be invoked when the operation is complete. 
- *	IN const void *Cookie: Pointer to user data to pass to the 
- *		callback function when invoked. 
- *
- *  Description:
- *      this function queries the state of a variable of a 
- *  service, generating a callback when the operation is complete.
- *
- *  Return Values: int
- *      UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpGetServiceVarStatusAsync( IN UpnpClient_Handle Hnd,
-                              IN const char *ActionURL_const,
-                              IN const char *VarName_const,
-                              IN Upnp_FunPtr Fun,
-                              IN const void *Cookie_const )
-{
-    ThreadPoolJob job;
-    struct Handle_Info *SInfo = NULL;
-    struct UpnpNonblockParam *Param;
-    char *ActionURL = ( char * )ActionURL_const;
-    char *VarName = ( char * )VarName_const;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpGetServiceVarStatusAsync \n" );
-         )
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    HandleUnlock(  );
-
-    if( ActionURL == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( VarName == NULL || Fun == NULL )
-        return UPNP_E_INVALID_PARAM;
-
-    Param =
-        ( struct UpnpNonblockParam * )
-        malloc( sizeof( struct UpnpNonblockParam ) );
-    if( Param == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    Param->FunName = STATUS;
-    Param->Handle = Hnd;
-    strcpy( Param->Url, ActionURL );
-    strcpy( Param->VarName, VarName );
-    Param->Fun = Fun;
-    Param->Cookie = ( void * )Cookie_const;
-
-    TPJobInit( &job, ( start_routine ) UpnpThreadDistribution, Param );
-    TPJobSetFreeFunction( &job, ( free_routine ) free );
-
-    TPJobSetPriority( &job, MED_PRIORITY );
-
-    if (ThreadPoolAdd( &gSendThreadPool, &job, NULL ) != 0) {
-        free(Param);
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpGetServiceVarStatusAsync \n" );
-         )
-
-        return UPNP_E_SUCCESS;
-
-}  /****************** End of UpnpGetServiceVarStatusAsync ****************/
-
-/**************************************************************************
- * Function: UpnpGetServiceVarStatus 
- *
- * Parameters:	
- *	IN UpnpClient_Handle Hnd: The handle of the control point.
- *	IN const char *ActionURL: The URL of the service. 
- *	IN const char *VarName: The name of the variable to query. 
- *	OUT DOMString *StVarVal: The pointer to store the value 
- *		for VarName. The UPnP Library allocates this string and
- *		the caller needs to free it.
- *  
- * Description:
- *	this function queries the state of a state variable of a service on
- *	another device.  This is a synchronous call. A positive return value
- *	indicates a SOAP error code, whereas a negative return code indicates
- *	a UPnP SDK error code.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpGetServiceVarStatus( IN UpnpClient_Handle Hnd,
-                         IN const char *ActionURL_const,
-                         IN const char *VarName_const,
-                         OUT DOMString * StVar )
-{
-    struct Handle_Info *SInfo = NULL;
-    int retVal = 0;
-    char *StVarPtr;
-    char *ActionURL = ( char * )ActionURL_const;
-    char *VarName = ( char * )VarName_const;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpGetServiceVarStatus \n" );
-         )
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-
-    HandleUnlock(  );
-
-    if( ActionURL == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( VarName == NULL || StVar == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    retVal = SoapGetServiceVarStatus( ActionURL, VarName, &StVarPtr );
-    *StVar = StVarPtr;
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpGetServiceVarStatus \n" );
-         )
-
-        return retVal;
-
-}  /****************** End of UpnpGetServiceVarStatus *********************/
-#endif // INCLUDE_CLIENT_APIS
-#endif // EXCLUDE_SOAP
-
-//---------------------------------------------------------------------------
-//
-//                                   Client API's 
-//
-//---------------------------------------------------------------------------
-
-/**************************************************************************
- * Function: UpnpOpenHttpPost 
- *
- * Parameters:	
- *  
- * Description:
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-
-int
-UpnpOpenHttpPost( IN const char *url,
-                  IN OUT void **handle,
-                  IN const char *contentType,
-                  IN int contentLength,
-                  IN int timeout )
-{
-    return http_OpenHttpPost( url, handle, contentType, contentLength,
-                              timeout );
-}
-
-/**************************************************************************
- * Function: UpnpWriteHttpPost 
- *
- * Parameters:	
- *  
- * Description:
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpWriteHttpPost( IN void *handle,
-                   IN char *buf,
-                   IN off_t *size,
-                   IN int timeout )
-{
-    return http_WriteHttpPost( handle, buf, size, timeout );
-}
-
-/**************************************************************************
- * Function: UpnpCloseHttpPost 
- *
- * Parameters:	
- *  
- * Description:
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpCloseHttpPost( IN void *handle,
-                   IN OUT int *httpStatus,
-                   int timeout )
-{
-    return http_CloseHttpPost( handle, httpStatus, timeout );
-}
-
-/**************************************************************************
- * Function: UpnpOpenHttpGet 
- *
- * Parameters:	
- *  
- * Description:
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpOpenHttpGet( IN const char *url_str,
-                 IN OUT void **Handle,
-                 IN OUT char **contentType,
-                 OUT off_t *contentLength,
-                 OUT int *httpStatus,
-                 IN int timeout )
-{
-    return http_OpenHttpGet( url_str, Handle, contentType, contentLength,
-                             httpStatus, timeout );
-}
-
-
-
-/**************************************************************************
- * Function: UpnpOpenHttpGetProxy
- *
- * Parameters:	
- *  
- * Description:
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpOpenHttpGetProxy( IN const char *url_str,
-                 IN const char *proxy_str,
-                 IN OUT void **Handle,
-                 IN OUT char **contentType,
-                 OUT off_t *contentLength,
-                 OUT int *httpStatus,
-                 IN int timeout )
-{
-    return http_OpenHttpGetProxy( url_str, proxy_str, Handle, contentType, contentLength,
-                             httpStatus, timeout );
-}
-
-/**************************************************************************
- * Function: UpnpOpenHttpGetEx
- *
- * Parameters:	
- *  
- * Description:
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpOpenHttpGetEx( IN const char *url_str,
-                   IN OUT void **Handle,
-                   IN OUT char **contentType,
-                   OUT off_t *contentLength,
-                   OUT int *httpStatus,
-                   IN int lowRange,
-                   IN int highRange,
-                   IN int timeout )
-{
-    return http_OpenHttpGetEx( url_str,
-                               Handle,
-                               contentType,
-                               contentLength,
-                               httpStatus, lowRange, highRange, timeout );
-}
-
-
-
-/**************************************************************************
- * Function: UpnpCancelHttpGet 
- *
- * Parameters:	
- *  
- * Description:
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpCancelHttpGet( IN void *Handle )
-{
-    return http_CancelHttpGet( Handle );
-}
-
-/**************************************************************************
- * Function: UpnpCloseHttpGet 
- *
- * Parameters:	
- *  
- * Description:
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpCloseHttpGet( IN void *Handle )
-{
-    return http_CloseHttpGet( Handle );
-}
-
-/**************************************************************************
- * Function: UpnpReadHttpGet 
- *
- * Parameters:	
- *  
- * Description:
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpReadHttpGet( IN void *Handle,
-                 IN OUT char *buf,
-                 IN OUT off_t *size,
-                 IN int timeout )
-{
-    return http_ReadHttpGet( Handle, buf, size, timeout );
-}
-
-
-
-/**************************************************************************
- * Function: UpnpHttpGetProgress 
- *
- * Parameters:	
- *  
- * Description:
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful.
- *	UPNP_E_INVALID_PARAM if the provided pointers were invalid.
- ***************************************************************************/
-int
-UpnpHttpGetProgress( IN void *Handle, 
-                     OUT off_t *length,
-                     OUT off_t *total )
-{
-    return http_HttpGetProgress(Handle, length, total);
-}
-
-/**************************************************************************
- * Function: UpnpDownloadUrlItem 
- *
- * Parameters:	
- *  
- * Description:
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpDownloadUrlItem( const char *url,
-                     char **outBuf,
-                     char *contentType )
-{
-    int ret_code;
-    int dummy;
-
-    if( url == NULL || outBuf == NULL || contentType == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    ret_code = http_Download( url, HTTP_DEFAULT_TIMEOUT, outBuf, &dummy,
-                              contentType );
-    if( ret_code > 0 ) {
-        // error reply was received
-        ret_code = UPNP_E_INVALID_URL;
-    }
-
-    return ret_code;
-}
-
-/**************************************************************************
- * Function: UpnpDownloadXmlDoc 
- *
- * Parameters:	
- *  
- * Description:
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else sends appropriate error.
- ***************************************************************************/
-int
-UpnpDownloadXmlDoc( const char *url,
-                    IXML_Document ** xmlDoc )
-{
-    int ret_code;
-    char *xml_buf;
-    char content_type[LINE_SIZE];
-
-    if( url == NULL || xmlDoc == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    ret_code = UpnpDownloadUrlItem( url, &xml_buf, content_type );
-    if( ret_code != UPNP_E_SUCCESS ) {
-        DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
-                             "retCode: %d\n", ret_code );
-             )
-            return ret_code;
-    }
-
-    if( strncasecmp( content_type, "text/xml", strlen( "text/xml" ) ) ) {
-        DBGONLY(
-            UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "Not text/xml\n" );
-        )
-        // Linksys WRT54G router returns 
-        // "CONTENT-TYPE: application/octet-stream".
-        // Let's be nice to Linksys and try to parse document anyway.
-        // If the data sended is not a xml file, ixmlParseBufferEx
-        // will fail and the function will return UPNP_E_INVALID_DESC too.
-#if 0
-        free( xml_buf );
-        return UPNP_E_INVALID_DESC;
-#endif
-    }
-
-    ret_code = ixmlParseBufferEx( xml_buf, xmlDoc );
-    free( xml_buf );
-
-    if( ret_code != IXML_SUCCESS ) {
-        DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
-                             "Invalid desc\n" );
-             )
-            if( ret_code == IXML_INSUFFICIENT_MEMORY ) {
-            return UPNP_E_OUTOF_MEMORY;
-        } else {
-            return UPNP_E_INVALID_DESC;
-        }
-    } else {
-        DBGONLY( xml_buf = ixmlPrintNode( ( IXML_Node * ) * xmlDoc );
-                 UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                             "Printing the Parsed xml document \n %s\n",
-                             xml_buf );
-                 UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                             "****************** END OF Parsed XML Doc *****************\n" );
-                 ixmlFreeDOMString( xml_buf );
-                 UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                             "Exiting UpnpDownloadXmlDoc\n" ); )
-
-            return UPNP_E_SUCCESS;
-    }
-}
-
-//----------------------------------------------------------------------------
-//
-//                          UPNP-API  Internal function implementation
-//
-//----------------------------------------------------------------------------
-
-#ifdef INCLUDE_CLIENT_APIS
-
-/**************************************************************************
- * Function: UpnpThreadDistribution 
- *
- * Parameters:	
- *  
- * Description:
- *	Function to schedule async functions in threadpool.
- *
- * Return Values: VOID
- *      
- ***************************************************************************/
-void
-UpnpThreadDistribution( struct UpnpNonblockParam *Param )
-{
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside UpnpThreadDistribution \n" );
-         )
-
-        switch ( Param->FunName ) {
-#if EXCLUDE_GENA == 0
-        CLIENTONLY( case SUBSCRIBE:
-{
-struct Upnp_Event_Subscribe Evt;
-Evt.ErrCode = genaSubscribe( Param->Handle, Param->Url,
-                            ( int * )&( Param->TimeOut ),
-                            ( char * )Evt.Sid );
-strcpy( Evt.PublisherUrl, Param->Url ); Evt.TimeOut = Param->TimeOut;
-Param->Fun( UPNP_EVENT_SUBSCRIBE_COMPLETE, &Evt, Param->Cookie );
-free( Param ); break;}
-        case UNSUBSCRIBE:
-                            {
-                            struct Upnp_Event_Subscribe Evt;
-                            Evt.ErrCode =
-                            genaUnSubscribe( Param->Handle,
-                                             Param->SubsId );
-                            strcpy( ( char * )Evt.Sid, Param->SubsId );
-                            strcpy( Evt.PublisherUrl, "" );
-                            Evt.TimeOut = 0;
-                            Param->Fun( UPNP_EVENT_UNSUBSCRIBE_COMPLETE,
-                                        &Evt, Param->Cookie );
-                            free( Param ); break;}
-        case RENEW:
-                            {
-                            struct Upnp_Event_Subscribe Evt;
-                            Evt.ErrCode =
-                            genaRenewSubscription( Param->Handle,
-                                                   Param->SubsId,
-                                                   &( Param->TimeOut ) );
-                            Evt.TimeOut = Param->TimeOut;
-                            strcpy( ( char * )Evt.Sid, Param->SubsId );
-                            Param->Fun( UPNP_EVENT_RENEWAL_COMPLETE, &Evt,
-                                        Param->Cookie ); free( Param );
-                            break;}
-             )
-#endif
-#if EXCLUDE_SOAP == 0
-        case ACTION:
-            {
-                struct Upnp_Action_Complete Evt;
-
-                Evt.ActionResult = NULL;
-#ifdef INCLUDE_CLIENT_APIS
-
-                Evt.ErrCode =
-                    SoapSendAction( Param->Url, Param->ServiceType,
-                                    Param->Act, &Evt.ActionResult );
-#endif
-
-                Evt.ActionRequest = Param->Act;
-                strcpy( Evt.CtrlUrl, Param->Url );
-
-                Param->Fun( UPNP_CONTROL_ACTION_COMPLETE, &Evt,
-                            Param->Cookie );
-
-                ixmlDocument_free( Evt.ActionRequest );
-                ixmlDocument_free( Evt.ActionResult );
-                free( Param );
-                break;
-            }
-        case STATUS:
-            {
-                struct Upnp_State_Var_Complete Evt;
-
-#ifdef INCLUDE_CLIENT_APIS
-
-                Evt.ErrCode = SoapGetServiceVarStatus( Param->Url,
-                                                       Param->VarName,
-                                                       &( Evt.
-                                                          CurrentVal ) );
-#endif
-                strcpy( Evt.StateVarName, Param->VarName );
-                strcpy( Evt.CtrlUrl, Param->Url );
-
-                Param->Fun( UPNP_CONTROL_GET_VAR_COMPLETE, &Evt,
-                            Param->Cookie );
-                free( Evt.CurrentVal );
-                free( Param );
-                break;
-            }
-#endif //EXCLUDE_SOAP
-        default:
-            break;
-    }                           // end of switch(Param->FunName)
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting UpnpThreadDistribution \n" );
-         )
-
-}  /****************** End of UpnpThreadDistribution  *********************/
-#endif
-
-/**************************************************************************
- * Function: GetCallBackFn 
- *
- * Parameters:	
- *  
- * Description:
- *	This function is to get callback function ptr from a handle
- *
- * Return Values: Upnp_FunPtr
- *      
- ***************************************************************************/
-Upnp_FunPtr
-GetCallBackFn( UpnpClient_Handle Hnd )
-{
-    return ( ( struct Handle_Info * )HandleTable[Hnd] )->Callback;
-
-}  /****************** End of GetCallBackFn *********************/
-
-/**************************************************************************
- * Function: InitHandleList 
- *
- * Parameters: VOID
- *  
- * Description:
- *	This function is to initialize handle table
- *
- * Return Values: VOID
- *      
- ***************************************************************************/
-void
-InitHandleList(  )
-{
-    int i;
-
-    for( i = 0; i < NUM_HANDLE; i++ )
-        HandleTable[i] = NULL;
-
-}  /****************** End of InitHandleList *********************/
-
-/**************************************************************************
- * Function: GetFreeHandle 
- *
- * Parameters: VOID
- *  
- * Description:
- *	This function is to get a free handle
- *
- * Return Values: VOID
- *      
- ***************************************************************************/
-int
-GetFreeHandle(  )
-{
-    int i = 1;
-
-    /*
-       Handle 0 is not used as NULL translates to 0 when passed as a handle 
-     */
-    while( i < NUM_HANDLE ) {
-        if( HandleTable[i++] == NULL )
-            break;
-    }
-
-    if( i == NUM_HANDLE )
-        return UPNP_E_OUTOF_HANDLE; //Error
-    else
-        return --i;
-
-}  /****************** End of GetFreeHandle *********************/
-
-/**************************************************************************
- * Function: GetClientHandleInfo 
- *
- * Parameters:	
- *	IN UpnpClient_Handle *client_handle_out: client handle pointer ( key 
- *		for the client handle structure).
- *	OUT struct Handle_Info **HndInfo: Client handle structure passed by 
- *		this function.
- *
- * Description:
- *	This function is to get client handle info
- *
- *  Return Values: HND_CLIENT
- *      
- ***************************************************************************/
-//Assumes at most one client
-Upnp_Handle_Type
-GetClientHandleInfo( IN UpnpClient_Handle * client_handle_out,
-                     OUT struct Handle_Info ** HndInfo )
-{
-    ( *client_handle_out ) = 1;
-    if( GetHandleInfo( 1, HndInfo ) == HND_CLIENT ) {
-        return HND_CLIENT;
-    }
-    ( *client_handle_out ) = 2;
-    if( GetHandleInfo( 2, HndInfo ) == HND_CLIENT ) {
-        return HND_CLIENT;
-    }
-    ( *client_handle_out ) = -1;
-    return HND_INVALID;
-
-}  /****************** End of GetClientHandleInfo *********************/
-
-/**************************************************************************
- * Function: GetDeviceHandleInfo 
- *
- * Parameters:	
- * 	IN UpnpDevice_Handle * device_handle_out: device handle pointer
- * 		(key for the client handle structure).
- *	OUT struct Handle_Info **HndInfo: Device handle structure passed by
- *		this function.
- *  
- *  Description:
- *		This function is to get device handle info.
- *
- *  Return Values: HND_DEVICE
- *      
- ***************************************************************************/
-Upnp_Handle_Type
-GetDeviceHandleInfo( UpnpDevice_Handle * device_handle_out,
-                     struct Handle_Info ** HndInfo )
-{
-    ( *device_handle_out ) = 1;
-    if( GetHandleInfo( 1, HndInfo ) == HND_DEVICE )
-        return HND_DEVICE;
-
-    ( *device_handle_out ) = 2;
-    if( GetHandleInfo( 2, HndInfo ) == HND_DEVICE )
-        return HND_DEVICE;
-    ( *device_handle_out ) = -1;
-
-    return HND_INVALID;
-
-}  /****************** End of GetDeviceHandleInfo *********************/
-
-/**************************************************************************
- * Function: GetDeviceHandleInfo 
- *
- * Parameters:	
- * 	IN UpnpClient_Handle * device_handle_out: handle pointer
- * 		(key for the client handle structure).
- *	OUT struct Handle_Info **HndInfo: handle structure passed by
- *		this function.
- *  
- * Description:
- *	This function is to get  handle info.
- *
- * Return Values: HND_DEVICE
- *      
- ***************************************************************************/
-Upnp_Handle_Type
-GetHandleInfo( UpnpClient_Handle Hnd,
-               struct Handle_Info ** HndInfo )
-{
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                         "GetHandleInfo: Handle is %d\n", Hnd );
-         )
-
-        if( Hnd < 1 || Hnd >= NUM_HANDLE ) {
-
-        DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "GetHandleInfo : Handle out of range\n" );
-             )
-            return UPNP_E_INVALID_HANDLE;
-    }
-    if( HandleTable[Hnd] != NULL ) {
-
-        *HndInfo = ( struct Handle_Info * )HandleTable[Hnd];
-        return ( ( struct Handle_Info * )*HndInfo )->HType;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "GetHandleInfo : exiting\n" );
-         )
-
-        return UPNP_E_INVALID_HANDLE;
-
-}  /****************** End of GetHandleInfo *********************/
-
-/**************************************************************************
- * Function: FreeHandle 
- *
- * Parameters:	
- * 	IN int Upnp_Handle: handle index 
- *  
- * Description:
- *	This function is to to free handle info.
- *	
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else return appropriate error
- ***************************************************************************/
-int
-FreeHandle( int Upnp_Handle )
-{
-    if( Upnp_Handle < 1 || Upnp_Handle >= NUM_HANDLE ) {
-        DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
-                             "FreeHandleInfo : Handle out of range\n" );
-             )
-            return UPNP_E_INVALID_HANDLE;
-    }
-
-    if( HandleTable[Upnp_Handle] == NULL ) {
-        return UPNP_E_INVALID_HANDLE;
-    }
-    free( HandleTable[Upnp_Handle] );
-    HandleTable[Upnp_Handle] = NULL;
-    return UPNP_E_SUCCESS;
-
-}  /****************** End of FreeHandle *********************/
-
-// **DBG****************************************************
-//DBGONLY(
-
-/**************************************************************************
- * Function: PrintHandleInfo 
- *
- * Parameters:	
- *	IN UpnpClient_Handle Hnd: handle index 
- *  
- * Description:
- *	This function is to print handle info.
- *	
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else return appropriate error
- ***************************************************************************/
-            int PrintHandleInfo( IN UpnpClient_Handle Hnd ) {
-            if( HandleTable[Hnd] != NULL ) {
-            DBGONLY(
-                struct Handle_Info * HndInfo;
-                HndInfo = HandleTable[Hnd];
-                     UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                                 "Printing information for Handle_%d\n",
-                                 Hnd );
-                     UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                                 "HType_%d\n", HndInfo->HType );
-		     DEVICEONLY(
-                     if( HndInfo->HType !=
-                         HND_CLIENT ) UpnpPrintf( UPNP_ALL, API, __FILE__,
-                                                  __LINE__, "DescURL_%s\n",
-                                                  HndInfo->DescURL ); )
-		     )
-            }
-            else
-            {
-            return UPNP_E_INVALID_HANDLE;}
-
-            return UPNP_E_SUCCESS;}
-   /****************** End of PrintHandleInfo *********************/
-
-            void printNodes( IXML_Node * tmpRoot, int depth ) {
-            int i;
-            IXML_NodeList * NodeList1;
-            IXML_Node * ChildNode1;
-            NodeList1 = ixmlNode_getChildNodes( tmpRoot );
-            for( i = 0; i < 100; i++ ) {
-            ChildNode1 = ixmlNodeList_item( NodeList1, i );
-            if( ChildNode1 == NULL ) {
-            break;}
-
-            printNodes( ChildNode1, depth + 1 );
-            DBGONLY(
-                const DOMString NodeName;
-                unsigned short NodeType;
-                const DOMString NodeValue;
-
-                NodeType = ixmlNode_getNodeType( ChildNode1 );
-                NodeValue = ixmlNode_getNodeValue( ChildNode1 );
-                NodeName = ixmlNode_getNodeName( ChildNode1 );
-                UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                                 "DEPTH-%2d-IXML_Node Type %d, "
-                                 "IXML_Node Name: %s, IXML_Node Value: %s\n",
-                                 depth, NodeType, NodeName, NodeValue ); )
-            }
-
-            }
-   /****************** End of printNodes *********************/
-
-// )                              // dbgonly
-
-    //********************************************************
-    //* Name: getlocalhostname
-    //* Description:  Function to get local IP address
-    //*               Gets the ip address for the DEFAULT_INTERFACE 
-    //*               interface which is up and not a loopback
-    //*               assumes at most MAX_INTERFACES interfaces
-    //* Called by:    UpnpInit
-    //* In:           char *out
-    //* Out:          Ip address
-    //* Return codes: UPNP_E_SUCCESS
-    //* Error codes:  UPNP_E_INIT
-    //********************************************************
-
- /**************************************************************************
- * Function: getlocalhostname 
- *
- * Parameters:	
- * 	OUT char *out: IP address of the interface.
- *  
- * Description:
- *	This function is to get local IP address. It gets the ip address for 
- *	the DEFAULT_INTERFACE interface which is up and not a loopback
- *	assumes at most MAX_INTERFACES interfaces
- *
- *  Return Values: int
- *	UPNP_E_SUCCESS if successful else return appropriate error
- ***************************************************************************/
-    int getlocalhostname( OUT char *out ) {
-
-#if defined(WIN32) || defined(__CYGWIN__)
-    struct hostent *h=NULL;
-    struct sockaddr_in LocalAddr;
-
- 		gethostname(out,LINE_SIZE);
- 		h=gethostbyname(out);
- 		if (h!=NULL){
- 			memcpy(&LocalAddr.sin_addr,h->h_addr_list[0],4);
- 			strcpy( out, inet_ntoa(LocalAddr.sin_addr));
- 		}
- 		return UPNP_E_SUCCESS;
-#else
-
-    struct ifreq ifReq;
-    int LocalSock;
-    struct sockaddr_in LocalAddr;
-    struct if_nameindex *iflist = NULL;
-    struct if_nameindex *iflist_save = NULL;
-    int interface_set = 0;
-
-    // Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. 
-    if( ( LocalSock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ) {
-        DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                             "Can't create addrlist socket\n" );
-             )
-            return UPNP_E_INIT;
-    }
-
-    iflist = iflist_save = if_nameindex();
-    if (iflist == NULL)
-    {
-        DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,                             
-                    "Can't get interface list\n" );)
-        close( LocalSock );
-        return UPNP_E_INIT;
-    }
-
-    while (iflist->if_index || iflist->if_name)
-    {
-        strncpy( ifReq.ifr_name, iflist->if_name, IF_NAMESIZE );
-        if (ioctl( LocalSock, SIOCGIFFLAGS, &ifReq ) < 0) 
-        {
-            DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                                 "Can't get interface flags for %s:\n",
-                                 ifReq.ifr_name );
-                 )
-            iflist++;
-            continue;
-
-        }
-        
-        // skip loopback interface and also skip interfaces that are down
-        if ((ifReq.ifr_flags & IFF_LOOPBACK) || (!(ifReq.ifr_flags & IFF_UP)))
-        {
-            iflist++;
-            continue;
-        }
-
-        // now get the address for this interface
-        if(ioctl(LocalSock, SIOCGIFADDR, &ifReq) != 0)
-        {
-            DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                                 "Can't get interface address for %s:\n",
-                                 ifReq.ifr_name );
-                 )
-            iflist++;
-            continue;
-        }
-
-        memcpy(&LocalAddr, &ifReq.ifr_addr, sizeof ifReq.ifr_addr);
-        if( LocalAddr.sin_addr.s_addr == htonl( INADDR_LOOPBACK ) ) 
-        {
-            iflist++;
-            continue;
-        }
-
-        iflist++;
-        interface_set = 1;
-    }
-
-    if_freenameindex(iflist_save);
-    
-    close( LocalSock );
-
-    if (!interface_set)
-    {
-        DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                    "Could not find interface to bind to\n");
-               )
-        return UPNP_E_INIT;
-    }
-
-    strncpy( out, inet_ntoa( LocalAddr.sin_addr ), LINE_SIZE );
-
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside getlocalhostname : after strncpy %s\n",
-                         out );
-         )
-        return UPNP_E_SUCCESS;
-#endif
-    }
-
-#ifdef INCLUDE_DEVICE_APIS
-#if EXCLUDE_SSDP == 0
-
- /**************************************************************************
- * Function: AutoAdvertise 
- *
- * Parameters:	
- * 	IN void *input: information provided to the thread.
- *  
- * Description:
- *	This function is a timer thread scheduled by UpnpSendAdvertisement 
- *	to the send advetisement again. 
- *
- * Return Values: VOID
- *     
- ***************************************************************************/
-void
-AutoAdvertise( void *input )
-{
-    upnp_timeout *event = ( upnp_timeout * ) input;
-
-    UpnpSendAdvertisement( event->handle, *( ( int * )event->Event ) );
-    free_upnp_timeout( event );
-}
-#endif //INCLUDE_DEVICE_APIS
-#endif
-
-/*
- **************************** */
-#ifdef INTERNAL_WEB_SERVER
-
- /**************************************************************************
- * Function: UpnpSetWebServerRootDir 
- *
- * Parameters:	
- *	IN const char* rootDir:Path of the root directory of the web server. 
- *  
- * Description:
- *	This function sets the document root directory for
- *	the internal web server. This directory is considered the
- *	root directory (i.e. "/") of the web server.
- *	This function also activates or deactivates the web server.
- *	To disable the web server, pass NULL for rootDir to 
- *	activate, pass a valid directory string.
- *  
- *	Note that this function is not available when the web server is not
- *	compiled into the UPnP Library.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else returns appropriate error
- ***************************************************************************/
-int
-UpnpSetWebServerRootDir( IN const char *rootDir )
-{
-    if( UpnpSdkInit == 0 )
-        return UPNP_E_FINISH;
-    if( ( rootDir == NULL ) || ( strlen( rootDir ) == 0 ) ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    membuffer_destroy( &gDocumentRootDir );
-
-    return ( web_server_set_root_dir( rootDir ) );
-}
-#endif // INTERNAL_WEB_SERVER
-/*
- *************************** */
-
- /**************************************************************************
- * Function: UpnpAddVirtualDir 
- *
- * Parameters:	
- *	IN const char *newDirName:The name of the new directory mapping to add.
- *  
- * Description:
- *	This function adds a virtual directory mapping.
- *
- *	All webserver requests containing the given directory are read using
- *	functions contained in a UpnpVirtualDirCallbacks structure registered
- *	via UpnpSetVirtualDirCallbacks.
- *  
- *	Note that this function is not available when the web server is not
- *	compiled into the UPnP Library.
- *
- *  Return Values: int
- *     UPNP_E_SUCCESS if successful else returns appropriate error
- ***************************************************************************/
-int
-UpnpAddVirtualDir( IN const char *newDirName )
-{
-
-    virtualDirList *pNewVirtualDir,
-     *pLast;
-    virtualDirList *pCurVirtualDir;
-    char dirName[NAME_SIZE];
-
-    if( UpnpSdkInit != 1 ) {
-        // SDK is not initialized
-        return UPNP_E_FINISH;
-    }
-
-    if( ( newDirName == NULL ) || ( strlen( newDirName ) == 0 ) ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    if( *newDirName != '/' ) {
-        dirName[0] = '/';
-        strcpy( dirName + 1, newDirName );
-    } else {
-        strcpy( dirName, newDirName );
-    }
-
-    pCurVirtualDir = pVirtualDirList;
-    while( pCurVirtualDir != NULL ) {
-        // already has this entry
-        if( strcmp( pCurVirtualDir->dirName, dirName ) == 0 ) {
-            return UPNP_E_SUCCESS;
-        }
-
-        pCurVirtualDir = pCurVirtualDir->next;
-    }
-
-    pNewVirtualDir =
-        ( virtualDirList * ) malloc( sizeof( virtualDirList ) );
-    if( pNewVirtualDir == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    pNewVirtualDir->next = NULL;
-    strcpy( pNewVirtualDir->dirName, dirName );
-    *( pNewVirtualDir->dirName + strlen( dirName ) ) = 0;
-
-    if( pVirtualDirList == NULL ) { // first virtual dir
-        pVirtualDirList = pNewVirtualDir;
-    } else {
-        pLast = pVirtualDirList;
-        while( pLast->next != NULL ) {
-            pLast = pLast->next;
-        }
-        pLast->next = pNewVirtualDir;
-    }
-
-    return UPNP_E_SUCCESS;
-}
-
- /**************************************************************************
- * Function: UpnpRemoveVirtualDir 
- *
- * Parameters:	
- * 	IN const char *newDirName:The name of the directory mapping to remove.
- *  
- * Description:
- *	This function removes a virtual directory mapping.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else returns appropriate error
- ***************************************************************************/
-int
-UpnpRemoveVirtualDir( IN const char *dirName )
-{
-
-    virtualDirList *pPrev;
-    virtualDirList *pCur;
-    int found = 0;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    if( dirName == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    if( pVirtualDirList == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-    //
-    // Handle the special case where the directory that we are
-    // removing is the first and only one in the list.
-    //
-
-    /* removing is the first in the list. */
-    if (strcmp( pVirtualDirList->dirName, dirName ) == 0) {
-        pPrev = pVirtualDirList;
-        pVirtualDirList = pVirtualDirList->next;
-        free( pPrev );
-        return UPNP_E_SUCCESS;
-    }
-
-    pCur = pVirtualDirList->next;
-    pPrev = pVirtualDirList;
-
-    while( pCur != NULL ) {
-        if( strcmp( pCur->dirName, dirName ) == 0 ) {
-            pPrev->next = pCur->next;
-            // Jin: deleting first item in the list
-            if (pCur == pVirtualDirList)
-                pVirtualDirList = pCur->next;
-
-            free( pCur );
-            found = 1;
-            break;
-        } else {
-            pPrev = pCur;
-            pCur = pCur->next;
-        }
-    }
-
-    if( found == 1 )
-        return UPNP_E_SUCCESS;
-    else
-        return UPNP_E_INVALID_PARAM;
-
-}
-
- /**************************************************************************
- * Function: UpnpRemoveAllVirtualDirs 
- *
- * Parameters: VOID
- *  
- * Description:
- *	This function removes all the virtual directory mappings.
- *
- * Return Values: VOID
- *     
- ***************************************************************************/
-void
-UpnpRemoveAllVirtualDirs(  )
-{
-
-    virtualDirList *pCur;
-    virtualDirList *pNext;
-
-    if( UpnpSdkInit != 1 ) {
-        return;
-    }
-
-    pCur = pVirtualDirList;
-
-    while( pCur != NULL ) {
-        pNext = pCur->next;
-        free( pCur );
-
-        pCur = pNext;
-    }
-
-    pVirtualDirList = NULL;
-}
-
-/**************************************************************************
- * Function: UpnpAddHTTPHeader 
- *
- * Parameters:	
- *	IN const char *header: string to be added to the HTTP response
- *  
- * Description:
- *	This function adds a HTTP header to the response.
- *  For example "X-User-Agent: something" (\r\n termination is done
- *  automatically.
- *
- *  Return Values: int
- *     UPNP_E_SUCCESS if successful else returns appropriate error
- ***************************************************************************/
-int
-UpnpAddCustomHTTPHeader( IN const char *header_string )
-{
-
-    userHTTPHeaderList *pNewHeader,
-     *pLast;
-    userHTTPHeaderList *pCurrentHeader;
-    char header[HEADER_SIZE];
-
-    if( UpnpSdkInit != 1 ) {
-        // SDK is not initialized
-        return UPNP_E_FINISH;
-    }
-
-    if( ( header_string == NULL ) || ( strlen( header_string ) == 0 ) ||
-        ( strlen(header_string) > HEADER_SIZE )) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    strncpy( header, header_string, HEADER_SIZE);
-
-    pCurrentHeader = pUserHTTPHeaderList;
-    while( pCurrentHeader != NULL ) {
-        // already has this entry
-        if( strcmp( pCurrentHeader->header, header ) == 0 ) {
-            return UPNP_E_SUCCESS;
-        }
-
-        pCurrentHeader = pCurrentHeader->next;
-    }
-
-    pNewHeader =
-        ( userHTTPHeaderList * ) malloc( sizeof( userHTTPHeaderList ) );
-    if( pNewHeader == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    pNewHeader->next = NULL;
-    strncpy( pNewHeader->header, header, HEADER_SIZE );
-    *( pNewHeader->header + strlen( header ) ) = 0;
-
-    if( pUserHTTPHeaderList == NULL ) { // first virtual dir
-        pUserHTTPHeaderList = pNewHeader;
-    } else {
-        pLast = pUserHTTPHeaderList;
-        while( pLast->next != NULL ) {
-            pLast = pLast->next;
-        }
-        pLast->next = pNewHeader;
-    }
-
-    if (gUserHTTPHeaders.length > 0)
-        membuffer_append(&gUserHTTPHeaders, "\r\n", 2);
-    membuffer_append(&gUserHTTPHeaders, header_string, strlen(header_string));
-    return UPNP_E_SUCCESS;
-}
-
- /**************************************************************************
- * Function: UpnpRemoveHTTPHeader 
- *
- * Parameters:	
- * 	IN const char *header:The header string to remove.
- *  
- * Description:
- *	This function removes a virtual directory mapping.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else returns appropriate error
- ***************************************************************************/
-int
-UpnpRemoveCustomHTTPHeader( IN const char *header_string)
-{
-
-    userHTTPHeaderList *pPrev;
-    userHTTPHeaderList *pCur;
-    int found = 0;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    if( header_string == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    if( pUserHTTPHeaderList == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    //
-    // Handle the special case where the directory that we are
-    // removing is the first and only one in the list.
-    //
-
-    if( ( pUserHTTPHeaderList->next == NULL ) &&
-        ( strcmp( pUserHTTPHeaderList->header, header_string ) == 0 ) ) {
-        free( pUserHTTPHeaderList );
-        pUserHTTPHeaderList = NULL;
-        found = 1; 
-    }
- 
-    if (!found)
-    {
-        pCur = pUserHTTPHeaderList;
-
-        pPrev = pCur;
-
-        while( pCur != NULL ) {
-            if( strcmp( pCur->header, header_string ) == 0 ) {
-                pPrev->next = pCur->next;
-                // Jin: we are deleting the first element in the list,
-                // update the global variable!
-                if (pCur == pUserHTTPHeaderList)
-                    pUserHTTPHeaderList = pCur->next;
-
-                free( pCur );
-                found = 1;
-                break;
-            } else {
-                pPrev = pCur;
-                pCur = pCur->next;
-            }
-        }
-    }
-    if( found == 1 )
-    {
-        membuffer_delete(&gUserHTTPHeaders, 0, gUserHTTPHeaders.length);
-        pCur = pUserHTTPHeaderList;
-        while (pCur != NULL)
-        {
-            if (gUserHTTPHeaders.length > 0)
-                membuffer_append(&gUserHTTPHeaders, "\r\n", 2);
-
-            membuffer_append(&gUserHTTPHeaders, pCur->header, strlen(pCur->header));
-        }
-        return UPNP_E_SUCCESS;
-    }
-    else
-        return UPNP_E_INVALID_PARAM;
-
-}
-
- /**************************************************************************
- * Function: UpnpRemoveAllCustomHTTPHeaders 
- *
- * Parameters: VOID
- *  
- * Description:
- *	This function removes all the virtual directory mappings.
- *
- * Return Values: VOID
- *     
- ***************************************************************************/
-void
-UpnpRemoveAllCustomHTTPHeaders(  )
-{
-
-    userHTTPHeaderList *pCur;
-    userHTTPHeaderList *pNext;
-
-    if( UpnpSdkInit != 1 ) {
-        return;
-    }
-
-    pCur = pUserHTTPHeaderList;
-
-    while( pCur != NULL ) {
-        pNext = pCur->next;
-        free( pCur );
-
-        pCur = pNext;
-    }
-
-    pUserHTTPHeaderList = NULL;
-
-    membuffer_delete(&gUserHTTPHeaders, 0, gUserHTTPHeaders.length);
-}
-
- /**************************************************************************
- * Function: UpnpEnableWebserver 
- *
- * Parameters:	
- *	IN int enable: TRUE to enable, FALSE to disable.
- *  
- * Description:
- *	This function enables or disables the webserver.  A value of
- *	TRUE enables the webserver, FALSE disables it.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS if successful else returns appropriate error
- ***************************************************************************/
-int
-UpnpEnableWebserver( IN int enable )
-{
-    int retVal;
-
-    if( UpnpSdkInit != 1 ) {
-        return UPNP_E_FINISH;
-    }
-
-    switch ( enable ) {
-#ifdef INTERNAL_WEB_SERVER
-        case TRUE:
-            if( ( retVal = web_server_init(  ) ) != UPNP_E_SUCCESS ) {
-                return retVal;
-            }
-            bWebServerState = WEB_SERVER_ENABLED;
-            SetHTTPGetCallback( web_server_callback );
-            break;
-
-        case FALSE:
-            web_server_destroy(  );
-            bWebServerState = WEB_SERVER_DISABLED;
-            SetHTTPGetCallback( NULL );
-            break;
-#endif
-        default:
-            return UPNP_E_INVALID_PARAM;
-    }
-
-    return UPNP_E_SUCCESS;
-}
-
- /**************************************************************************
- * Function: UpnpIsWebserverEnabled 
- *
- * Parameters: VOID
- *  
- * Description:
- *	This function  checks if the webserver is enabled or disabled. 
- *
- * Return Values: int
- *	1, if webserver enabled
- *	0, if webserver disabled
- ***************************************************************************/
-int
-UpnpIsWebserverEnabled(  )
-{
-    if( UpnpSdkInit != 1 ) {
-        return 0;
-    }
-
-    return ( bWebServerState == WEB_SERVER_ENABLED );
-}
-
- /**************************************************************************
- * Function: UpnpSetVirtualDirCallbacks 
- *
- * Parameters:	
- *	IN struct UpnpVirtualDirCallbacks *callbacks:a structure that 
- *		contains the callback functions.
- *	
- * Description:
- *	This function sets the callback function to be used to 
- *	access a virtual directory.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS on success, or UPNP_E_INVALID_PARAM
- ***************************************************************************/
-int
-UpnpSetVirtualDirCallbacks( IN struct UpnpVirtualDirCallbacks *callbacks )
-{
-    struct UpnpVirtualDirCallbacks *pCallback;
-
-    if( UpnpSdkInit != 1 ) {
-        // SDK is not initialized
-        return UPNP_E_FINISH;
-    }
-
-    pCallback = &virtualDirCallback;
-
-    if( callbacks == NULL )
-        return UPNP_E_INVALID_PARAM;
-
-    pCallback->get_info = callbacks->get_info;
-    pCallback->open = callbacks->open;
-    pCallback->close = callbacks->close;
-    pCallback->read = callbacks->read;
-    pCallback->write = callbacks->write;
-    pCallback->seek = callbacks->seek;
-
-    return UPNP_E_SUCCESS;
-}
-
- /**************************************************************************
- * Function: UpnpFree 
- *
- * Parameters:	
- *	IN void *item:The item to free.
- *	
- * Description:
- *	This function free the memory allocated by tbe UPnP library
- *
- * Return Values: VOID
- *		
- ***************************************************************************/
-void
-UpnpFree( IN void *item )
-{
-    if( item )
-        free( item );
-}
-
-
-/**************************************************************************
- * Function: UpnpSetContentLength
- * OBSOLETE METHOD : use {\bf UpnpSetMaxContentLength} instead.
- ***************************************************************************/
-int
-UpnpSetContentLength( IN UpnpClient_Handle Hnd,
-                               /** The handle of the device instance
-                                  for which the coincoming content length needs
-                                  to be set. */
-
-                      IN int contentLength
-                               /** Permissible content length  */
-     )
-{
-    int errCode = UPNP_E_SUCCESS;
-    struct Handle_Info *HInfo = NULL;
-
-    do {
-        if( UpnpSdkInit != 1 ) {
-            errCode = UPNP_E_FINISH;
-            break;
-        }
-
-        HandleLock(  );
-
-        errCode = GetHandleInfo( Hnd, &HInfo );
-
-        if( errCode != HND_DEVICE ) {
-            errCode = UPNP_E_INVALID_HANDLE;
-            break;
-        }
-
-        if( contentLength > MAX_SOAP_CONTENT_LENGTH ) {
-            errCode = UPNP_E_OUTOF_BOUNDS;
-            break;
-        }
-
-        g_maxContentLength = contentLength;
-
-    } while( 0 );
-
-    HandleUnlock(  );
-    return errCode;
-
-}
-
-
-/**************************************************************************
- * Function: UpnpSetMaxContentLength
- *
- * Parameters:	
- *	IN int contentLength: The maximum size to be set 
- *	
- * Description:
- *	Sets the maximum content-length that the SDK will process on an 
- *	incoming SOAP requests or responses. This API allows devices that have
- *	memory constraints to exhibit consistent behaviour if the size of the 
- *	incoming SOAP message exceeds the memory that device can allocate. 
- *	The default maximum content-length is {\tt DEFAULT_SOAP_CONTENT_LENGTH}
- *	= 16K bytes.
- *
- * Return Values: int
- *	UPNP_E_SUCCESS: The operation completed successfully.
- *		
- ***************************************************************************/
-int
-UpnpSetMaxContentLength (
-                      IN size_t contentLength
-                               /** Permissible content length, in bytes  */
-     )
-{
-    int errCode = UPNP_E_SUCCESS;
-
-    do {
-        if( UpnpSdkInit != 1 ) {
-            errCode = UPNP_E_FINISH;
-            break;
-        }
-
-        g_maxContentLength = contentLength;
-
-    } while( 0 );
-
-    return errCode;
-
-}
-
-/*********************** END OF FILE upnpapi.c :) ************************/
diff --git a/tombupnp/upnp/src/api/upnpdebug.c b/tombupnp/upnp/src/api/upnpdebug.c
deleted file mode 100644
index 985a034..0000000
--- a/tombupnp/upnp/src/api/upnpdebug.c
+++ /dev/null
@@ -1,388 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include "upnpconfig.h"
-
-#if UPNP_HAVE_DEBUG
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#include "upnpdebug.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include "ithread.h"
-#include "upnp.h"
-#include <stdarg.h>
-#include <string.h>
-
-
-
-//Mutex to synchronize all the log file opeartions in the debug mode
-static ithread_mutex_t GlobalDebugMutex;
-
-// Global log level
-static Upnp_LogLevel g_log_level = UPNP_DEFAULT_LOG_LEVEL;
-
-//File handle for the error log file
-static FILE *ErrFileHnd = NULL;
-
-//File handle for the information log file
-static FILE *InfoFileHnd = NULL;
-
-//Name of the error file
-static const char *errFileName = "IUpnpErrFile.txt";
-
-//Name of the info file
-static const char *infoFileName = "IUpnpInfoFile.txt";
-
-
-
-/***************************************************************************
- * Function : UpnpSetLogFileNames					
- *								
- * Parameters:							
- *	IN const char* ErrFileName: name of the error file
- *	IN const char *InfoFileName: name of the information file
- *	IN int size: Size of the buffer
- *	IN int starLength: This parameter provides the width of the banner
- *									
- * Description:							
- *	This functions takes the buffer and writes the buffer in the file as 
- *	per the requested banner					
- * Returns: void
- ***************************************************************************/
-void
-UpnpSetLogFileNames ( IN const char *ErrFileName,
-		      IN const char *InfoFileName )
-{
-    if( ErrFileName ) {
-        errFileName = ErrFileName;
-    }
-    if( InfoFileName ) {
-        infoFileName = InfoFileName;
-    }
-}
-
-
-/***************************************************************************
- * Function : UpnpInitLog					
- *									
- * Parameters:	void							
- *						
- * Description:							
- *	This functions initializes the log files
- * Returns: int
- *	-1 : If fails
- *	UPNP_E_SUCCESS : if success
- ***************************************************************************/
-int
-UpnpInitLog(  )
-{
-    ithread_mutex_init( &GlobalDebugMutex, NULL );
-
-    if( DEBUG_TARGET == 1 ) {
-        if( ( ErrFileHnd = fopen( errFileName, "a" ) ) == NULL )
-            return -1;
-        if( ( InfoFileHnd = fopen( infoFileName, "a" ) ) == NULL )
-            return -1;
-    }
-    return UPNP_E_SUCCESS;
-}
-
-
-/***************************************************************************
- * Function : UpnpSetLogLevel
- *				
- * Parameters:	void
- *
- * Description:							
- *	This functions set the log level (see {\tt Upnp_LogLevel}
- * Returns: void
- ***************************************************************************/
-void 
-UpnpSetLogLevel (Upnp_LogLevel log_level)
-{
-	g_log_level = log_level;
-}
-
-
-/***************************************************************************
- * Function : UpnpCloseLog					
- *								
- * Parameters:	void					
- *								
- * Description:						
- *	This functions closes the log files
- * Returns: void
- ***************************************************************************/
-void
-UpnpCloseLog(  )
-{
-    if( DEBUG_TARGET == 1 ) {
-        fflush( ErrFileHnd );
-        fflush( InfoFileHnd );
-        fclose( ErrFileHnd );
-        fclose( InfoFileHnd );
-    }
-    ithread_mutex_destroy( &GlobalDebugMutex );
-
-}
-
-
-/***************************************************************************
- * Function : UpnpPrintf					
- *									
- * Parameters:			
- *	IN Dbg_Level DLevel: The level of the debug logging. It will decide 
- *		whether debug statement will go to standard output, 
- *		or any of the log files.
- *	IN Dbg_Module Module: debug will go in the name of this module
- *	IN char *DbgFileName: Name of the file from where debug statement is
- *							coming
- *	IN int DbgLineNo : Line number of the file from where debug statement 
- *				is coming
- *	IN char * FmtStr, ...: Variable number of arguments that will go 
- *				in the debug statement
- *					
- * Description:					
- *	This functions prints the debug statement either on the startdard 
- *	output or log file along with the information from where this debug 
- *	statement is coming
- * Returns: void
- ***************************************************************************/
-DBGONLY( void UpnpPrintf( IN Upnp_LogLevel DLevel,
-                          IN Dbg_Module Module,
-                          IN const char *DbgFileName,
-                          IN int DbgLineNo,
-                          IN const char *FmtStr,
-                          ... ) {
-
-         va_list ArgList;
-         va_start( ArgList, FmtStr );
-         if( g_log_level < DLevel ) return; if( DEBUG_ALL == 0 ) {
-         switch ( Module ) {
-case SSDP:
-         if( DEBUG_SSDP == 1 ) break;
-         else
-return; case SOAP:
-         if( DEBUG_SOAP == 1 ) break;
-         else
-return; case GENA:
-         if( DEBUG_GENA == 1 ) break;
-         else
-return; case TPOOL:
-         if( DEBUG_TPOOL == 1 ) break;
-         else
-return; case MSERV:
-         if( DEBUG_MSERV == 1 ) break;
-         else
-return; case DOM:
-         if( DEBUG_DOM == 1 ) break;
-         else
-return; case HTTP:
-         if( DEBUG_HTTP == 1 ) break;
-         else
-return; case API:
-         if( DEBUG_API == 1 ) break;
-         else
-return; default:
-         return;}
-         }
-
-         ithread_mutex_lock( &GlobalDebugMutex ); if( DEBUG_TARGET == 0 ) {
-         if( DbgFileName ) {
-         UpnpDisplayFileAndLine( stdout, DbgFileName, DbgLineNo );}
-         vfprintf( stdout, FmtStr, ArgList ); fflush( stdout );}
-         else
-         {
-         if( DLevel == 0 ) {
-         if( DbgFileName ) {
-         UpnpDisplayFileAndLine( ErrFileHnd, DbgFileName, DbgLineNo );}
-         vfprintf( ErrFileHnd, FmtStr, ArgList ); fflush( ErrFileHnd );}
-         else
-         {
-         if( DbgFileName ) {
-         UpnpDisplayFileAndLine( InfoFileHnd, DbgFileName, DbgLineNo );}
-         vfprintf( InfoFileHnd, FmtStr, ArgList ); fflush( InfoFileHnd );}
-         }
-         va_end( ArgList ); ithread_mutex_unlock( &GlobalDebugMutex );}
-
- )
-
-
-/***************************************************************************
- * Function : UpnpGetDebugFile					
- *				
- * Parameters:			
- *	IN Dbg_Level DLevel: The level of the debug logging. It will decide 
- *		whether debug statement will go to standard output, 
- *		or any of the log files.
- *	IN Dbg_Module Module: debug will go in the name of this module
- *								
- * Description:
- *	This function checks if the module is turned on for debug 
- *	and returns the file descriptor corresponding to the debug level
- * Returns: FILE *
- *	NULL : if the module is turn off for debug 
- *	else returns the right file descriptor
- ***************************************************************************/
-    DBGONLY( FILE * GetDebugFile( Upnp_LogLevel DLevel, Dbg_Module Module ) {
-             if( g_log_level < DLevel ) return NULL; if( DEBUG_ALL == 0 ) {
-             switch ( Module ) {
-case SSDP:
-             if( DEBUG_SSDP == 1 ) break;
-             else
-return NULL; case SOAP:
-             if( DEBUG_SOAP == 1 ) break;
-             else
-return NULL; case GENA:
-             if( DEBUG_GENA == 1 ) break;
-             else
-return NULL; case TPOOL:
-             if( DEBUG_TPOOL == 1 ) break;
-             else
-return NULL; case MSERV:
-             if( DEBUG_MSERV == 1 ) break;
-             else
-return NULL; case DOM:
-             if( DEBUG_DOM == 1 ) break;
-             else
-return NULL; case API:
-             if( DEBUG_API == 1 ) break;
-             else
-return NULL; default:
-             return NULL;}
-             }
-
-             if( DEBUG_TARGET == 0 ) {
-             return stdout;}
-             else
-             {
-             if( DLevel == 0 ) {
-             return ErrFileHnd;}
-             else
-             {
-             return InfoFileHnd;}
-             }
-             }
- )
-
-
-/***************************************************************************
- * Function : UpnpDisplayFileAndLine				
- *	
- * Parameters:	
- *	IN FILE *fd: File descriptor where line number and file name will be 
- *			written 
- *	IN char *DbgFileName: Name of the file  
- *	IN int DbgLineNo : Line number of the file
- *		
- * Description:
- *	This function writes the file name and file number from where
- *		debug statement is coming to the log file
- * Returns: void
- ***************************************************************************/
-    DBGONLY( void UpnpDisplayFileAndLine( IN FILE * fd,
-                                          IN const char *DbgFileName,
-                                          IN int DbgLineNo ) {
-             int starlength = 66;
-             const char *lines[2];
-             char FileAndLine[500]; lines[0] = "DEBUG"; if( DbgFileName ) {
-             sprintf( FileAndLine, "FILE: %s, LINE: %d", DbgFileName,
-                      DbgLineNo ); lines[1] = FileAndLine;}
-
-             UpnpDisplayBanner( fd, lines, 2, starlength ); fflush( fd );}
- )
-
-
-/***************************************************************************
- * Function : UpnpDisplayBanner	
- *
- * Parameters:			
- *	IN FILE *fd: file descriptor where the banner will be written
- *	IN char **lines: The buffer that will be written
- *	IN int size: Size of the buffer
- *	IN int starLength: This parameter provides the width of the banner
- *	
- * Description:			
- *	This functions takes the buffer and writes the buffer in the file as 
- *	per the requested banner
- * Returns: void
- ***************************************************************************/
-    DBGONLY( void UpnpDisplayBanner( IN FILE * fd,
-                                     IN const char **lines,
-                                     IN size_t size,
-                                     IN int starLength ) {
-             char *stars = ( char * )malloc( starLength + 1 );
-             const char *line = NULL;
-             int leftMarginLength = starLength / 2 + 1;
-             int rightMarginLength = starLength / 2 + 1;
-             char *leftMargin = ( char * )malloc( leftMarginLength );
-             char *rightMargin = ( char * )malloc( rightMarginLength );
-             int i = 0;
-             int LineSize = 0;
-             char *currentLine = ( char * )malloc( starLength + 1 );
-             memset( stars, '*', starLength );
-             stars[starLength] = 0;
-             memset( leftMargin, 0, leftMarginLength );
-             memset( rightMargin, 0, rightMarginLength );
-             fprintf( fd, "\n%s\n", stars ); for( i = 0; i < size; i++ ) {
-             LineSize = strlen( lines[i] );
-             line = lines[i]; while( LineSize > ( starLength - 2 ) ) {
-             memcpy( currentLine, line, ( starLength - 2 ) );
-             currentLine[( starLength - 2 )] = 0;
-             fprintf( fd, "*%s*\n", currentLine );
-             LineSize -= ( starLength - 2 ); line += ( starLength - 2 );}
-
-             if( LineSize % 2 == 0 ) {
-             leftMarginLength = rightMarginLength =
-             ( ( starLength - 2 ) - LineSize ) / 2;}
-             else
-             {
-             leftMarginLength = ( ( starLength - 2 ) - LineSize ) / 2;
-             rightMarginLength =
-             ( ( starLength - 2 ) - LineSize ) / 2 + 1;}
-
-             memset( leftMargin, ' ', leftMarginLength );
-             memset( rightMargin, ' ', rightMarginLength );
-             leftMargin[leftMarginLength] = 0;
-             rightMargin[rightMarginLength] = 0;
-             fprintf( fd, "*%s%s%s*\n", leftMargin, line, rightMargin );}
-
-             fprintf( fd, "%s\n\n", stars );
-             free( leftMargin );
-             free( rightMargin ); free( stars ); free( currentLine );}
- )
-#endif
diff --git a/tombupnp/upnp/src/api/upnptools.c b/tombupnp/upnp/src/api/upnptools.c
deleted file mode 100644
index c014686..0000000
--- a/tombupnp/upnp/src/api/upnptools.c
+++ /dev/null
@@ -1,584 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#if EXCLUDE_DOM == 0
-#include <stdarg.h>
-#include "upnptools.h"
-#include "uri.h"
-#define HEADER_LENGTH 2000
-
-//Structure to maintain a error code and string associated with the 
-// error code
-struct ErrorString {
-    int rc;                     /* error code */
-    const char *rcError;        /* error description */
-
-};
-
-//Intializing the array of error structures. 
-struct ErrorString ErrorMessages[] = { {UPNP_E_SUCCESS, "UPNP_E_SUCCESS"},
-{UPNP_E_INVALID_HANDLE, "UPNP_E_INVALID_HANDLE"},
-{UPNP_E_INVALID_PARAM, "UPNP_E_INVALID_PARAM"},
-{UPNP_E_OUTOF_HANDLE, "UPNP_E_OUTOF_HANDLE"},
-{UPNP_E_OUTOF_CONTEXT, "UPNP_E_OUTOF_CONTEXT"},
-{UPNP_E_OUTOF_MEMORY, "UPNP_E_OUTOF_MEMOR"},
-{UPNP_E_INIT, "UPNP_E_INIT"},
-{UPNP_E_BUFFER_TOO_SMALL, "UPNP_E_BUFFER_TOO_SMALL"},
-{UPNP_E_INVALID_DESC, "UPNP_E_INVALID_DESC"},
-{UPNP_E_INVALID_URL, "UPNP_E_INVALID_URL"},
-{UPNP_E_INVALID_SID, "UPNP_E_INVALID_SID"},
-{UPNP_E_INVALID_DEVICE, "UPNP_E_INVALID_DEVICE"},
-{UPNP_E_INVALID_SERVICE, "UPNP_E_INVALID_SERVICE"},
-{UPNP_E_BAD_RESPONSE, "UPNP_E_BAD_RESPONSE"},
-{UPNP_E_BAD_REQUEST, "UPNP_E_BAD_REQUEST"},
-{UPNP_E_INVALID_ACTION, "UPNP_E_INVALID_ACTION"},
-{UPNP_E_FINISH, "UPNP_E_FINISH"},
-{UPNP_E_INIT_FAILED, "UPNP_E_INIT_FAILED"},
-{UPNP_E_BAD_HTTPMSG, "UPNP_E_BAD_HTTPMSG"},
-{UPNP_E_NETWORK_ERROR, "UPNP_E_NETWORK_ERROR"},
-{UPNP_E_SOCKET_WRITE, "UPNP_E_SOCKET_WRITE"},
-{UPNP_E_SOCKET_READ, "UPNP_E_SOCKET_READ"},
-{UPNP_E_SOCKET_BIND, "UPNP_E_SOCKET_BIND"},
-{UPNP_E_SOCKET_CONNECT, "UPNP_E_SOCKET_CONNECT"},
-{UPNP_E_OUTOF_SOCKET, "UPNP_E_OUTOF_SOCKET"},
-{UPNP_E_LISTEN, "UPNP_E_LISTEN"},
-{UPNP_E_EVENT_PROTOCOL, "UPNP_E_EVENT_PROTOCOL"},
-{UPNP_E_SUBSCRIBE_UNACCEPTED, "UPNP_E_SUBSCRIBE_UNACCEPTED"},
-{UPNP_E_UNSUBSCRIBE_UNACCEPTED, "UPNP_E_UNSUBSCRIBE_UNACCEPTED"},
-{UPNP_E_NOTIFY_UNACCEPTED, "UPNP_E_NOTIFY_UNACCEPTED"},
-{UPNP_E_INTERNAL_ERROR, "UPNP_E_INTERNAL_ERROR"},
-{UPNP_E_INVALID_ARGUMENT, "UPNP_E_INVALID_ARGUMENT"},
-{UPNP_E_OUTOF_BOUNDS, "UPNP_E_OUTOF_BOUNDS"}
-};
-
-/************************************************************************
-* Function : UpnpGetErrorMessage											
-*																	
-* Parameters:														
-*	IN int rc: error code
-*																	
-* Description:														
-*	This functions returns the error string mapped to the error code 
-* Returns: const char *
-*	return either the right string or "Unknown Error"
-***************************************************************************/
-const char *
-UpnpGetErrorMessage( IN int rc )
-{
-    int i;
-
-    for( i = 0; i < sizeof( ErrorMessages ) / sizeof( ErrorMessages[0] );
-         i++ ) {
-        if( rc == ErrorMessages[i].rc )
-            return ErrorMessages[i].rcError;
-
-    }
-
-    return "Unknown Error";
-
-}
-
-/************************************************************************
-* Function : UpnpResolveURL											
-*																	
-* Parameters:														
-*	IN char * BaseURL: Base URL string
-*	IN char * RelURL: relative URL string
-*	OUT char * AbsURL: Absolute URL string
-* Description:														
-*	This functions concatinates the base URL and relative URL to generate 
-*	the absolute URL
-* Returns: int
-*	return either UPNP_E_SUCCESS or appropriate error
-***************************************************************************/
-int
-UpnpResolveURL( IN const char *BaseURL,
-                IN const char *RelURL,
-                OUT char *AbsURL )
-{
-    // There is some unnecessary allocation and
-    // deallocation going on here because of the way
-    // resolve_rel_url was originally written and used
-    // in the future it would be nice to clean this up
-
-    char *tempRel;
-
-    if( RelURL == NULL )
-        return UPNP_E_INVALID_PARAM;
-
-    tempRel = NULL;
-
-    tempRel = resolve_rel_url((char*) BaseURL, (char*) RelURL );
-
-    if( tempRel ) {
-        strcpy( AbsURL, tempRel );
-        free( tempRel );
-    } else {
-        return UPNP_E_INVALID_URL;
-    }
-
-    return UPNP_E_SUCCESS;
-
-}
-
-/************************************************************************
-* Function : addToAction											
-*																	
-* Parameters:														
-*	IN int response: flag to tell if the ActionDoc is for response 
-*					or request
-*	INOUT IXML_Document **ActionDoc: request or response document
-*	IN char *ActionName: Name of the action request or response
-*	IN char *ServType: Service type
-*	IN char * ArgName: Name of the argument
-*	IN char * ArgValue: Value of the argument
-*
-* Description:		
-*	This function adds the argument in the action request or response. 
-* This function creates the action request or response if it is a first
-* argument else it will add the argument in the document
-*
-* Returns: int
-*	returns UPNP_E_SUCCESS if successful else returns appropriate error
-***************************************************************************/
-static int
-addToAction( IN int response,
-             INOUT IXML_Document ** ActionDoc,
-             IN const char *ActionName,
-             IN const char *ServType,
-             IN const char *ArgName,
-             IN const char *ArgValue )
-{
-    char *ActBuff = NULL;
-    IXML_Node *node = NULL;
-    IXML_Element *Ele = NULL;
-    IXML_Node *Txt = NULL;
-    int rc = 0;
-
-    if( ActionName == NULL || ServType == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    if( *ActionDoc == NULL ) {
-        ActBuff = ( char * )malloc( HEADER_LENGTH );
-        if( ActBuff == NULL ) {
-            return UPNP_E_OUTOF_MEMORY;
-        }
-
-        if( response ) {
-            sprintf( ActBuff,
-                "<u:%sResponse xmlns:u=\"%s\">\r\n</u:%sResponse>",
-                ActionName, ServType, ActionName );
-        } else {
-            sprintf( ActBuff,
-                "<u:%s xmlns:u=\"%s\">\r\n</u:%s>",
-                ActionName, ServType, ActionName );
-        }
-
-        rc = ixmlParseBufferEx( ActBuff, ActionDoc );
-        free( ActBuff );
-        if( rc != IXML_SUCCESS ) {
-            if( rc == IXML_INSUFFICIENT_MEMORY ) {
-                return UPNP_E_OUTOF_MEMORY;
-            } else {
-                return UPNP_E_INVALID_DESC;
-            }
-        }
-    }
-
-    if( ArgName != NULL /*&& ArgValue != NULL */  ) {
-        node = ixmlNode_getFirstChild( ( IXML_Node * ) * ActionDoc );
-        Ele = ixmlDocument_createElement( *ActionDoc, ArgName );
-        if( ArgValue ) {
-            Txt = ixmlDocument_createTextNode( *ActionDoc, ArgValue );
-            ixmlNode_appendChild( ( IXML_Node * ) Ele, Txt );
-        }
-
-        ixmlNode_appendChild( node, ( IXML_Node * ) Ele );
-    }
-
-    return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-* Function : makeAction											
-*																	
-* Parameters:														
-*	IN int response: flag to tell if the ActionDoc is for response 
-*					or request
-*	IN char * ActionName: Name of the action request or response
-*	IN char * ServType: Service type
-*	IN int NumArg :Number of arguments in the action request or response
-*	IN char * Arg : pointer to the first argument
-*	IN va_list ArgList: Argument list
-*
-* Description:		
-*	This function creates the action request or response from the argument
-* list.
-* Returns: IXML_Document *
-*	returns action request or response document if successful 
-*	else returns NULL
-***************************************************************************/
-static IXML_Document *
-makeAction( IN int response,
-            IN const char *ActionName,
-            IN const char *ServType,
-            IN int NumArg,
-            IN const char *Arg,
-            IN va_list ArgList )
-{
-    const char *ArgName,
-     *ArgValue;
-    char *ActBuff;
-    int Idx = 0;
-    IXML_Document *ActionDoc;
-    IXML_Node *node;
-    IXML_Element *Ele;
-    IXML_Node *Txt = NULL;
-
-    if( ActionName == NULL || ServType == NULL ) {
-        return NULL;
-    }
-
-    ActBuff = ( char * )malloc( HEADER_LENGTH );
-    if( ActBuff == NULL ) {
-        return NULL;
-    }
-
-    if( response ) {
-        sprintf( ActBuff,
-            "<u:%sResponse xmlns:u=\"%s\">\r\n</u:%sResponse>",
-            ActionName, ServType, ActionName );
-    } else {
-        sprintf( ActBuff,
-            "<u:%s xmlns:u=\"%s\">\r\n</u:%s>",
-            ActionName, ServType, ActionName );
-    }
-
-    if( ixmlParseBufferEx( ActBuff, &ActionDoc ) != IXML_SUCCESS ) {
-        free( ActBuff );
-        return NULL;
-    }
-
-    free( ActBuff );
-
-    if( ActionDoc == NULL ) {
-        return NULL;
-    }
-
-    if( NumArg > 0 ) {
-        //va_start(ArgList, Arg);
-        ArgName = Arg;
-        while( Idx++ != NumArg ) {
-            ArgValue = va_arg( ArgList, const char * );
-
-            if( ArgName != NULL ) {
-                node = ixmlNode_getFirstChild( ( IXML_Node * ) ActionDoc );
-                Ele = ixmlDocument_createElement( ActionDoc, ArgName );
-                if( ArgValue ) {
-                    Txt =
-                        ixmlDocument_createTextNode( ActionDoc, ArgValue );
-                    ixmlNode_appendChild( ( IXML_Node * ) Ele, Txt );
-                }
-
-                ixmlNode_appendChild( node, ( IXML_Node * ) Ele );
-            }
-
-            ArgName = va_arg( ArgList, const char * );
-        }
-        //va_end(ArgList);
-    }
-
-    return ActionDoc;
-}
-
-/************************************************************************
-* Function : UpnpMakeAction											
-*																	
-* Parameters:														
-*	IN char * ActionName: Name of the action request or response
-*	IN char * ServType: Service type
-*	IN int NumArg :Number of arguments in the action request or response
-*	IN char * Arg : pointer to the first argument
-*	IN ... : variable argument list
-*	IN va_list ArgList: Argument list
-*
-* Description:		
-*	This function creates the action request from the argument
-* list. Its a wrapper function that calls makeAction function to create
-* the action request.
-*
-* Returns: IXML_Document *
-*	returns action request document if successful 
-*	else returns NULL
-***************************************************************************/
-IXML_Document *
-UpnpMakeAction( const char *ActionName,
-                const char *ServType,
-                int NumArg,
-                const char *Arg,
-                ... )
-{
-    va_list ArgList;
-    IXML_Document *out = NULL;
-
-    va_start( ArgList, Arg );
-    out = makeAction( 0, ActionName, ServType, NumArg, Arg, ArgList );
-    va_end( ArgList );
-
-    return out;
-}
-
-/************************************************************************
-* Function : UpnpMakeActionResponse											
-*																	
-* Parameters:														
-*	IN char * ActionName: Name of the action request or response
-*	IN char * ServType: Service type
-*	IN int NumArg :Number of arguments in the action request or response
-*	IN char * Arg : pointer to the first argument
-*	IN ... : variable argument list
-*	IN va_list ArgList: Argument list
-*
-* Description:		
-*	This function creates the action response from the argument
-* list. Its a wrapper function that calls makeAction function to create
-* the action response.
-*
-* Returns: IXML_Document *
-*	returns action response document if successful 
-*	else returns NULL
-***************************************************************************/
-IXML_Document *
-UpnpMakeActionResponse( const char *ActionName,
-                        const char *ServType,
-                        int NumArg,
-                        const char *Arg,
-                        ... )
-{
-    va_list ArgList;
-    IXML_Document *out = NULL;
-
-    va_start( ArgList, Arg );
-    out = makeAction( 1, ActionName, ServType, NumArg, Arg, ArgList );
-    va_end( ArgList );
-
-    return out;
-}
-
-/************************************************************************
-* Function : UpnpAddToActionResponse									
-*																	
-* Parameters:
-*	INOUT IXML_Document **ActionResponse: action response document	
-*	IN char * ActionName: Name of the action request or response
-*	IN char * ServType: Service type
-*	IN int ArgName :Name of argument to be added in the action response
-*	IN char * ArgValue : value of the argument
-*
-* Description:		
-*	This function adds the argument in the action response. Its a wrapper 
-* function that calls addToAction function to add the argument in the 
-* action response.
-*
-* Returns: int
-*	returns UPNP_E_SUCCESS if successful 
-*	else returns appropriate error
-***************************************************************************/
-int
-UpnpAddToActionResponse( INOUT IXML_Document ** ActionResponse,
-                         IN const char *ActionName,
-                         IN const char *ServType,
-                         IN const char *ArgName,
-                         IN const char *ArgValue )
-{
-    return addToAction( 1, ActionResponse, ActionName, ServType, ArgName,
-                        ArgValue );
-}
-
-/************************************************************************
-* Function : UpnpAddToAction									
-*																	
-* Parameters:
-*	INOUT IXML_Document **ActionDoc: action request document	
-*	IN char * ActionName: Name of the action request or response
-*	IN char * ServType: Service type
-*	IN int ArgName :Name of argument to be added in the action response
-*	IN char * ArgValue : value of the argument
-*
-* Description:		
-*	This function adds the argument in the action request. Its a wrapper 
-* function that calls addToAction function to add the argument in the 
-* action request.
-*
-* Returns: int
-*	returns UPNP_E_SUCCESS if successful 
-*	else returns appropriate error
-***************************************************************************/
-int
-UpnpAddToAction( IXML_Document ** ActionDoc,
-                 const char *ActionName,
-                 const char *ServType,
-                 const char *ArgName,
-                 const char *ArgValue )
-{
-
-    return addToAction( 0, ActionDoc, ActionName, ServType, ArgName,
-                        ArgValue );
-}
-
-/************************************************************************
-* Function : UpnpAddToPropertySet											
-*																	
-* Parameters:														
-*	INOUT IXML_Document **PropSet: propertyset document
-*	IN char *ArgName: Name of the argument
-*	IN char *ArgValue: value of the argument
-*
-* Description:		
-*	This function adds the argument in the propertyset node 
-*
-* Returns: int
-*	returns UPNP_E_SUCCESS if successful else returns appropriate error
-***************************************************************************/
-int
-UpnpAddToPropertySet( INOUT IXML_Document ** PropSet,
-                      IN const char *ArgName,
-                      IN const char *ArgValue )
-{
-
-    char BlankDoc[] = "<e:propertyset xmlns:e=\"urn:schemas"
-        "-upnp-org:event-1-0\"></e:propertyset>";
-    IXML_Node *node;
-    IXML_Element *Ele;
-    IXML_Element *Ele1;
-    IXML_Node *Txt;
-    int rc;
-
-    if( ArgName == NULL ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    if( *PropSet == NULL ) {
-        rc = ixmlParseBufferEx( BlankDoc, PropSet );
-        if( rc != IXML_SUCCESS ) {
-            return UPNP_E_OUTOF_MEMORY;
-        }
-    }
-
-    node = ixmlNode_getFirstChild( ( IXML_Node * ) * PropSet );
-
-    Ele1 = ixmlDocument_createElement( *PropSet, "e:property" );
-    Ele = ixmlDocument_createElement( *PropSet, ArgName );
-
-    if( ArgValue ) {
-        Txt = ixmlDocument_createTextNode( *PropSet, ArgValue );
-        ixmlNode_appendChild( ( IXML_Node * ) Ele, Txt );
-    }
-
-    ixmlNode_appendChild( ( IXML_Node * ) Ele1, ( IXML_Node * ) Ele );
-    ixmlNode_appendChild( node, ( IXML_Node * ) Ele1 );
-
-    return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-* Function : UpnpCreatePropertySet											
-*																	
-* Parameters:														
-*	IN int NumArg: Number of argument that will go in the propertyset node
-*	IN char * Args: argument strings
-*
-* Description:		
-*	This function creates a propertyset node and put all the input 
-*	parameters in the node as elements
-*
-* Returns: IXML_Document *
-*	returns the document containing propertyset node.
-***************************************************************************/
-IXML_Document *
-UpnpCreatePropertySet( IN int NumArg,
-                       IN const char *Arg,
-                       ... )
-{
-    va_list ArgList;
-    int Idx = 0;
-    char BlankDoc[] = "<e:propertyset xmlns:e=\"urn:schemas-"
-        "upnp-org:event-1-0\"></e:propertyset>";
-    const char *ArgName,
-     *ArgValue;
-    IXML_Node *node;
-    IXML_Element *Ele;
-    IXML_Element *Ele1;
-    IXML_Node *Txt;
-    IXML_Document *PropSet;
-
-    if( ixmlParseBufferEx( BlankDoc, &PropSet ) != IXML_SUCCESS ) {
-        return NULL;
-    }
-
-    if( NumArg < 1 ) {
-        return NULL;
-    }
-
-    va_start( ArgList, Arg );
-    ArgName = Arg;
-
-    while( Idx++ != NumArg ) {
-        ArgValue = va_arg( ArgList, const char * );
-
-        if( ArgName != NULL /*&& ArgValue != NULL */  ) {
-            node = ixmlNode_getFirstChild( ( IXML_Node * ) PropSet );
-            Ele1 = ixmlDocument_createElement( PropSet, "e:property" );
-            Ele = ixmlDocument_createElement( PropSet, ArgName );
-            if( ArgValue ) {
-                Txt = ixmlDocument_createTextNode( PropSet, ArgValue );
-                ixmlNode_appendChild( ( IXML_Node * ) Ele, Txt );
-            }
-
-            ixmlNode_appendChild( ( IXML_Node * ) Ele1,
-                                  ( IXML_Node * ) Ele );
-            ixmlNode_appendChild( node, ( IXML_Node * ) Ele1 );
-        }
-
-        ArgName = va_arg( ArgList, const char * );
-
-    }
-    va_end( ArgList );
-    return PropSet;
-}
-
-#endif
diff --git a/tombupnp/upnp/src/gena/gena_callback2.c b/tombupnp/upnp/src/gena/gena_callback2.c
deleted file mode 100644
index 054e210..0000000
--- a/tombupnp/upnp/src/gena/gena_callback2.c
+++ /dev/null
@@ -1,133 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#if EXCLUDE_GENA == 0
-#include "gena.h"
-#include "gena_device.h"
-#include "gena_ctrlpt.h"
-
-#include "httpparser.h"
-#include "httpreadwrite.h"
-#include "statcodes.h"
-#include "unixutil.h"
-
-/************************************************************************
-* Function : error_respond									
-*																	
-* Parameters:														
-*	IN SOCKINFO *info: Structure containing information about the socket
-*	IN int error_code: error code that will be in the GENA response
-*	IN http_message_t* hmsg: GENA request Packet 
-*
-* Description:														
-*	This function send an error message to the control point in the case
-*	incorrect GENA requests.
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-void
-error_respond( IN SOCKINFO * info,
-               IN int error_code,
-               IN http_message_t * hmsg )
-{
-    int major,
-      minor;
-
-    // retrieve the minor and major version from the GENA request
-    http_CalcResponseVersion( hmsg->major_version,
-                              hmsg->minor_version, &major, &minor );
-
-    http_SendStatusResponse( info, error_code, major, minor );
-}
-
-/************************************************************************
-* Function : genaCallback									
-*																	
-* Parameters:														
-*	IN http_parser_t *parser: represents the parse state of the request
-*	IN http_message_t* request: HTTP message containing GENA request
-*	INOUT SOCKINFO *info: Structure containing information about the socket
-*
-* Description:														
-*	This is the callback function called by the miniserver to handle 
-*	incoming GENA requests. 
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-void
-genaCallback( IN http_parser_t * parser,
-              IN http_message_t * request,
-              INOUT SOCKINFO * info )
-{
-    xboolean found_function = FALSE;
-
-    if( request->method == HTTPMETHOD_SUBSCRIBE ) {
-        DEVICEONLY( found_function = TRUE;
-                    if( httpmsg_find_hdr( request, HDR_NT, NULL ) == NULL )
-                    {
-                    // renew subscription
-                    gena_process_subscription_renewal_request
-                    ( info, request );}
-                    else
-                    {
-                    // subscribe
-                    gena_process_subscription_request( info, request );}
-
-                    DBGONLY( UpnpPrintf
-                             ( UPNP_ALL, GENA, __FILE__, __LINE__,
-                               "got subscription request\n" ); )
-             )
-            }
-            else
-        if( request->method == HTTPMETHOD_UNSUBSCRIBE ) {
-            DEVICEONLY( found_function = TRUE;
-                        // unsubscribe
-                        gena_process_unsubscribe_request( info,
-                                                          request ); )
-        } else if( request->method == HTTPMETHOD_NOTIFY ) {
-            CLIENTONLY( found_function = TRUE;
-                        // notify
-                        gena_process_notification_event( info, request ); )
-        }
-
-        if( !found_function ) {
-            // handle missing functions of device or ctrl pt
-            error_respond( info, HTTP_NOT_IMPLEMENTED, request );
-        }
-    }
-#endif // EXCLUDE_GENA
diff --git a/tombupnp/upnp/src/gena/gena_ctrlpt.c b/tombupnp/upnp/src/gena/gena_ctrlpt.c
deleted file mode 100644
index 6b427fb..0000000
--- a/tombupnp/upnp/src/gena/gena_ctrlpt.c
+++ /dev/null
@@ -1,881 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#if EXCLUDE_GENA == 0
-#ifdef INCLUDE_CLIENT_APIS
-
-#include "gena.h"
-#include "sysdep.h"
-#include "upnp_uuid.h"
-#include "upnpapi.h"
-#include "parsetools.h"
-#include "statcodes.h"
-#include "httpparser.h"
-#include "httpreadwrite.h"
-
-extern ithread_mutex_t GlobalClientSubscribeMutex;
-
-/************************************************************************
-* Function : GenaAutoRenewSubscription									
-*																	
-* Parameters:														
-*	IN void *input: Thread data(upnp_timeout *) needed to send the renewal
-*
-* Description:														
-*	This is a thread function to send the renewal just before the 
-*	subscription times out.
-*
-* Returns: VOID
-*	
-***************************************************************************/
-static void
-GenaAutoRenewSubscription( IN void *input )
-{
-    upnp_timeout *event = ( upnp_timeout * ) input;
-    void *cookie;
-    Upnp_FunPtr callback_fun;
-    struct Handle_Info *handle_info;
-    struct Upnp_Event_Subscribe *sub_struct =
-        ( struct Upnp_Event_Subscribe * )
-        event->Event;
-
-    int send_callback = 0;
-    int eventType = 0;
-
-    if( AUTO_RENEW_TIME == 0 ) {
-        DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                             "GENA SUB EXPIRED" ) );
-        sub_struct->ErrCode = UPNP_E_SUCCESS;
-        send_callback = 1;
-        eventType = UPNP_EVENT_SUBSCRIPTION_EXPIRED;
-    } else {
-        DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                             "GENA AUTO RENEW" ) );
-        if( ( ( sub_struct->ErrCode = genaRenewSubscription( event->handle,
-                                                             sub_struct->
-                                                             Sid,
-                                                             &sub_struct->
-                                                             TimeOut ) ) !=
-              UPNP_E_SUCCESS )
-            && ( sub_struct->ErrCode != GENA_E_BAD_SID )
-            && ( sub_struct->ErrCode != GENA_E_BAD_HANDLE ) ) {
-            send_callback = 1;
-            eventType = UPNP_EVENT_AUTORENEWAL_FAILED;
-        }
-    }
-    if( send_callback ) {
-        HandleLock(  );
-        if( GetHandleInfo( event->handle, &handle_info ) != HND_CLIENT ) {
-            HandleUnlock(  );
-            free_upnp_timeout( event );
-            return;
-        }
-        DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                             "HANDLE IS VALID" ) );
-        callback_fun = handle_info->Callback;
-        cookie = handle_info->Cookie;
-        HandleUnlock(  );
-        //make callback
-
-        callback_fun( eventType, event->Event, cookie );
-    }
-
-    free_upnp_timeout( event );
-}
-
-/************************************************************************
-* Function : ScheduleGenaAutoRenew									
-*																	
-* Parameters:														
-*	IN int client_handle: Handle that also contains the subscription list
-*	IN int TimeOut: The time out value of the subscription
-*	IN client_subscription * sub: Subscription being renewed
-*
-* Description:														
-*	This function schedules a job to renew the subscription just before
-*	time out.
-*
-* Returns: int
-*	return GENA_E_SUCCESS if successful else returns appropriate error
-***************************************************************************/
-static int
-ScheduleGenaAutoRenew( IN int client_handle,
-                       IN int TimeOut,
-                       IN client_subscription * sub )
-{
-    struct Upnp_Event_Subscribe *RenewEventStruct = NULL;
-    upnp_timeout *RenewEvent = NULL;
-    int return_code = GENA_SUCCESS;
-    ThreadPoolJob job;
-
-    if( TimeOut == UPNP_INFINITE ) {
-        return GENA_SUCCESS;
-    }
-
-    RenewEventStruct = ( struct Upnp_Event_Subscribe * )malloc( sizeof
-                                                                ( struct
-                                                                  Upnp_Event_Subscribe ) );
-
-    if( RenewEventStruct == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    RenewEvent = ( upnp_timeout * ) malloc( sizeof( upnp_timeout ) );
-
-    if( RenewEvent == NULL ) {
-        free( RenewEventStruct );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    //schedule expire event
-    strcpy( RenewEventStruct->Sid, sub->sid );
-    RenewEventStruct->ErrCode = UPNP_E_SUCCESS;
-    strncpy( RenewEventStruct->PublisherUrl, sub->EventURL,
-             NAME_SIZE - 1 );
-    RenewEventStruct->TimeOut = TimeOut;
-
-    //RenewEvent->EventType=UPNP_EVENT_SUBSCRIPTION_EXPIRE;
-    RenewEvent->handle = client_handle;
-    RenewEvent->Event = RenewEventStruct;
-
-    TPJobInit( &job, ( start_routine ) GenaAutoRenewSubscription,
-               RenewEvent );
-    TPJobSetFreeFunction( &job, ( free_routine ) free_upnp_timeout );
-    TPJobSetPriority( &job, MED_PRIORITY );
-
-    //Schedule the job
-    if( ( return_code = TimerThreadSchedule( &gTimerThread,
-                                             TimeOut - AUTO_RENEW_TIME,
-                                             REL_SEC, &job, SHORT_TERM,
-                                             &( RenewEvent->
-                                                eventId ) ) ) !=
-        UPNP_E_SUCCESS ) {
-        free( RenewEvent );
-        free( RenewEventStruct );
-        return return_code;
-    }
-
-    sub->RenewEventId = RenewEvent->eventId;
-    return GENA_SUCCESS;
-}
-
-/************************************************************************
-* Function : gena_unsubscribe									
-*																	
-* Parameters:														
-*	IN char *url: Event URL of the service
-*	IN char *sid: The subcription ID.
-*	OUT http_parser_t* response: The UNSUBCRIBE response from the device
-*
-* Description:														
-*	This function sends the UNSUBCRIBE gena request and recieves the 
-*	response from the device and returns it as a parameter
-*
-* Returns: int
-*	return 0 if successful else returns appropriate error
-***************************************************************************/
-static int
-gena_unsubscribe( IN char *url,
-                  IN char *sid,
-                  OUT http_parser_t * response )
-{
-    int return_code;
-    uri_type dest_url;
-    membuffer request;
-
-    // parse url
-    return_code = http_FixStrUrl( url, strlen( url ), &dest_url );
-    if( return_code != 0 ) {
-        return return_code;
-    }
-    // make request msg
-    membuffer_init( &request );
-    request.size_inc = 30;
-    return_code = http_MakeMessage( &request, 1, 1,
-                                    "q" "ssc" "U" "c",
-                                    HTTPMETHOD_UNSUBSCRIBE, &dest_url,
-                                    "SID: ", sid );
-
-    //Not able to make the message so destroy the existing buffer
-    if( return_code != 0 ) {
-        membuffer_destroy( &request );
-        return return_code;
-    }
-    // send request and get reply
-    return_code = http_RequestAndResponse( &dest_url, request.buf,
-                                           request.length,
-                                           HTTPMETHOD_UNSUBSCRIBE,
-                                           HTTP_DEFAULT_TIMEOUT,
-                                           response );
-
-    membuffer_destroy( &request );
-
-    if( return_code != 0 )
-        httpmsg_destroy( &response->msg );
-
-    if( return_code == 0 && response->msg.status_code != HTTP_OK ) {
-        return_code = UPNP_E_UNSUBSCRIBE_UNACCEPTED;
-        httpmsg_destroy( &response->msg );
-    }
-
-    return return_code;
-}
-
-/************************************************************************
-* Function : gena_subscribe									
-*																	
-* Parameters:														
-*	IN char *url: url of service to subscribe
-*	INOUT int* timeout:subscription time desired (in secs)
-*	IN char* renewal_sid:for renewal, this contains a currently h
-*						 held subscription SID. For first time 
-*						 subscription, this must be NULL
-*	OUT char** sid: SID returned by the subscription or renew msg
-*
-* Description:														
-*	This function subscribes or renew subscription
-*
-* Returns: int
-*	return 0 if successful else returns appropriate error
-***************************************************************************/
-static int
-gena_subscribe( IN char *url,
-                INOUT int *timeout,
-                IN char *renewal_sid,
-                OUT char **sid )
-{
-    int return_code;
-    memptr sid_hdr,
-      timeout_hdr;
-    char timeout_str[25];
-    membuffer request;
-    uri_type dest_url;
-    http_parser_t response;
-
-    *sid = NULL;                // init
-
-    // request timeout to string
-    if ( timeout == NULL ) {
-        timeout = (int *)malloc(sizeof(int));
-        if(timeout == 0) return  UPNP_E_OUTOF_MEMORY;
-        sprintf( timeout_str, "%d", CP_MINIMUM_SUBSCRIPTION_TIME );
-    } else if( ( *timeout > 0 )&& ( *timeout < CP_MINIMUM_SUBSCRIPTION_TIME ) ) {
-        sprintf( timeout_str, "%d", CP_MINIMUM_SUBSCRIPTION_TIME );
-    } else if( *timeout >= 0 ) {
-        sprintf( timeout_str, "%d", *timeout );
-    } else {
-        strcpy( timeout_str, "infinite" );
-    }
-
-    // parse url
-    return_code = http_FixStrUrl( url, strlen( url ), &dest_url );
-    if( return_code != 0 ) {
-        return return_code;
-    }
-    // make request msg
-    membuffer_init( &request );
-    request.size_inc = 30;
-    if( renewal_sid ) {
-        // renew subscription
-        return_code = http_MakeMessage( &request, 1, 1,
-                                        "q" "ssc" "ssc" "c",
-                                        HTTPMETHOD_SUBSCRIBE, &dest_url,
-                                        "SID: ", renewal_sid,
-                                        "TIMEOUT: Second-", timeout_str );
-    } else {
-        // subscribe
-        return_code = http_MakeMessage( &request, 1, 1,
-                                        "q" "sssdsscc",
-                                        HTTPMETHOD_SUBSCRIBE, &dest_url,
-                                        "CALLBACK: <http://", LOCAL_HOST,
-                                        ":", LOCAL_PORT,
-                                        "/>" "NT: upnp:event"
-                                        "TIMEOUT: Second-", timeout_str );
-    }
-    if( return_code != 0 ) {
-        return return_code;
-    }
-    // send request and get reply
-    return_code = http_RequestAndResponse( &dest_url, request.buf,
-                                           request.length,
-                                           HTTPMETHOD_SUBSCRIBE,
-                                           HTTP_DEFAULT_TIMEOUT,
-                                           &response );
-
-    membuffer_destroy( &request );
-
-    if( return_code != 0 ) {
-        httpmsg_destroy( &response.msg );
-        return return_code;
-    }
-    if( response.msg.status_code != HTTP_OK ) {
-        httpmsg_destroy( &response.msg );
-        return UPNP_E_SUBSCRIBE_UNACCEPTED;
-    }
-    // get SID and TIMEOUT
-    if( httpmsg_find_hdr( &response.msg, HDR_SID, &sid_hdr ) == NULL ||
-        sid_hdr.length == 0 ||
-        httpmsg_find_hdr( &response.msg,
-                          HDR_TIMEOUT, &timeout_hdr ) == NULL ||
-        timeout_hdr.length == 0 ) {
-        httpmsg_destroy( &response.msg );
-        return UPNP_E_BAD_RESPONSE;
-    }
-    // save timeout
-    if( matchstr( timeout_hdr.buf, timeout_hdr.length, "%iSecond-%d%0",
-                  timeout ) == PARSE_OK ) {
-        // nothing  
-    } else if( memptr_cmp_nocase( &timeout_hdr, "Second-infinite" ) == 0 ) {
-        *timeout = -1;
-    } else {
-        httpmsg_destroy( &response.msg );
-        return UPNP_E_BAD_RESPONSE;
-    }
-
-    // save SID
-    *sid = str_alloc( sid_hdr.buf, sid_hdr.length );
-    if( *sid == NULL ) {
-        httpmsg_destroy( &response.msg );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    httpmsg_destroy( &response.msg );
-    return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-* Function : genaUnregisterClient									
-*																	
-* Parameters:														
-*	IN UpnpClient_Handle client_handle: Handle containing all the control
-*			point related information
-*
-* Description:														
-*	This function unsubcribes all the outstanding subscriptions and cleans
-*	the subscription list. This function is called when control point 
-*	unregisters.
-*
-* Returns: int
-*	return UPNP_E_SUCCESS if successful else returns appropriate error
-***************************************************************************/
-int
-genaUnregisterClient( IN UpnpClient_Handle client_handle )
-{
-    client_subscription sub_copy;
-    int return_code = UPNP_E_SUCCESS;
-    struct Handle_Info *handle_info = NULL;
-    http_parser_t response;
-
-    while( TRUE ) {
-        HandleLock(  );
-        if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
-            HandleUnlock(  );
-            return GENA_E_BAD_HANDLE;
-        }
-
-        if( handle_info->ClientSubList == NULL ) {
-            return_code = UPNP_E_SUCCESS;
-            break;
-        }
-
-        return_code = copy_client_subscription( handle_info->ClientSubList,
-                                                &sub_copy );
-        if( return_code != HTTP_SUCCESS ) {
-            break;
-        }
-
-        RemoveClientSubClientSID( &handle_info->ClientSubList,
-                                  sub_copy.sid );
-
-        HandleUnlock(  );
-
-        return_code = gena_unsubscribe( sub_copy.EventURL,
-                                        sub_copy.ActualSID, &response );
-        if( return_code == 0 ) {
-            httpmsg_destroy( &response.msg );
-        }
-
-        free_client_subscription( &sub_copy );
-    }
-
-    freeClientSubList( handle_info->ClientSubList );
-    HandleUnlock(  );
-    return return_code;
-}
-
-/************************************************************************
-* Function : genaUnSubscribe
-*																	
-* Parameters:														
-*	IN UpnpClient_Handle client_handle: UPnP client handle
-*	IN SID in_sid: The subscription ID
-*
-* Description:														
-*	This function unsubscribes a SID. It first validates the SID and 
-*	client_handle,copies the subscription, sends UNSUBSCRIBE http request 
-*	to service processes request and finally removes the subscription
-*
-* Returns: int
-*	return UPNP_E_SUCCESS if service response is OK else 
-*	returns appropriate error
-***************************************************************************/
-int
-genaUnSubscribe( IN UpnpClient_Handle client_handle,
-                 IN const Upnp_SID in_sid )
-{
-    client_subscription *sub;
-    int return_code = GENA_SUCCESS;
-    struct Handle_Info *handle_info;
-    client_subscription sub_copy;
-    http_parser_t response;
-
-    HandleLock(  );
-
-    // validate handle and sid
-
-    if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return GENA_E_BAD_HANDLE;
-    }
-
-    if( ( sub =
-          GetClientSubClientSID( handle_info->ClientSubList, in_sid ) )
-        == NULL ) {
-        HandleUnlock(  );
-        return GENA_E_BAD_SID;
-    }
-
-    return_code = copy_client_subscription( sub, &sub_copy );
-
-    HandleUnlock(  );
-
-    return_code = gena_unsubscribe( sub_copy.EventURL, sub_copy.ActualSID,
-                                    &response );
-
-    if( return_code == 0 ) {
-        httpmsg_destroy( &response.msg );
-    }
-
-    free_client_subscription( &sub_copy );
-
-    HandleLock(  );
-
-    if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return GENA_E_BAD_HANDLE;
-    }
-
-    RemoveClientSubClientSID( &handle_info->ClientSubList, in_sid );
-
-    HandleUnlock(  );
-
-    return return_code;
-}
-
-/************************************************************************
-* Function : genaSubscribe
-*																	
-* Parameters:														
-*	IN UpnpClient_Handle client_handle: 
-*	IN char * PublisherURL: NULL Terminated, of the form : 
-*						"http://134.134.156.80:4000/RedBulb/Event"
-*	INOUT int * TimeOut: requested Duration, if -1, then "infinite".
-*						in the OUT case: actual Duration granted 
-*						by Service, -1 for infinite
-*	OUT Upnp_SID out_sid:sid of subscription, memory passed in by caller
-*
-* Description:														
-*	This function subscribes to a PublisherURL ( also mentioned as EventURL
-*	some places). It sends SUBSCRIBE http request to service processes 
-*	request. Finally adds a Subscription to 
-*	the clients subscription list, if service responds with OK
-*
-* Returns: int
-*	return UPNP_E_SUCCESS if service response is OK else 
-*	returns appropriate error
-***************************************************************************/
-int
-genaSubscribe( IN UpnpClient_Handle client_handle,
-               IN char *PublisherURL,
-               INOUT int *TimeOut,
-               OUT Upnp_SID out_sid )
-{
-    int return_code = GENA_SUCCESS;
-    client_subscription *newSubscription = NULL;
-    uuid_upnp uid;
-    Upnp_SID temp_sid;
-    char *ActualSID = NULL;
-    struct Handle_Info *handle_info;
-    char *EventURL = NULL;
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                         "GENA SUBSCRIBE BEGIN" ) );
-    HandleLock(  );
-
-    memset( out_sid, 0, sizeof( Upnp_SID ) );
-
-    // validate handle
-    if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return GENA_E_BAD_HANDLE;
-    }
-    HandleUnlock(  );
-
-    // subscribe
-    SubscribeLock(  );
-    return_code =
-        gena_subscribe( PublisherURL, TimeOut, NULL, &ActualSID );
-    HandleLock(  );
-    if( return_code != UPNP_E_SUCCESS ) {
-        DBGONLY( UpnpPrintf( UPNP_CRITICAL, GENA, __FILE__, __LINE__,
-                             "SUBSCRIBE FAILED in transfer error code: %d returned\n",
-                             return_code ) );
-        goto error_handler;
-    }
-
-    if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
-        return_code = GENA_E_BAD_HANDLE;
-        goto error_handler;
-    }
-    // generate client SID
-    uuid_create( &uid );
-    uuid_unpack( &uid, temp_sid );
-    sprintf( out_sid, "uuid:%s", temp_sid );
-
-    // create event url
-    EventURL = ( char * )malloc( strlen( PublisherURL ) + 1 );
-    if( EventURL == NULL ) {
-        return_code = UPNP_E_OUTOF_MEMORY;
-        goto error_handler;
-    }
-
-    strcpy( EventURL, PublisherURL );
-
-    // fill subscription
-    newSubscription =
-        ( client_subscription * ) malloc( sizeof( client_subscription ) );
-    if( newSubscription == NULL ) {
-        return_code = UPNP_E_OUTOF_MEMORY;
-        goto error_handler;
-    }
-    newSubscription->EventURL = EventURL;
-    newSubscription->ActualSID = ActualSID;
-    strcpy( newSubscription->sid, out_sid );
-    newSubscription->RenewEventId = -1;
-    newSubscription->next = handle_info->ClientSubList;
-    handle_info->ClientSubList = newSubscription;
-
-    // schedule expiration event
-    return_code = ScheduleGenaAutoRenew( client_handle, *TimeOut,
-                                         newSubscription );
-
-  error_handler:
-    if( return_code != UPNP_E_SUCCESS ) {
-        free( ActualSID );
-        free( EventURL );
-        free( newSubscription );
-    }
-    HandleUnlock(  );
-    SubscribeUnlock(  );
-    return return_code;
-}
-
-/************************************************************************
-* Function : genaRenewSubscription
-*																	
-* Parameters:														
-*	IN UpnpClient_Handle client_handle: Client handle
-*	IN const Upnp_SID in_sid: subscription ID
-*	INOUT int * TimeOut: requested Duration, if -1, then "infinite".
-*						in the OUT case: actual Duration granted 
-*						by Service, -1 for infinite
-*
-* Description:														
-*	This function renews a SID. It first validates the SID and 
-*	client_handle and copies the subscription. It sends RENEW 
-*	(modified SUBSCRIBE) http request to service and processes
-*	the response.
-*
-* Returns: int
-*	return UPNP_E_SUCCESS if service response is OK else 
-*	returns appropriate error
-***************************************************************************/
-int
-genaRenewSubscription( IN UpnpClient_Handle client_handle,
-                       IN const Upnp_SID in_sid,
-                       INOUT int *TimeOut )
-{
-    int return_code = GENA_SUCCESS;
-    client_subscription *sub;
-    client_subscription sub_copy;
-    struct Handle_Info *handle_info;
-
-    char *ActualSID;
-    ThreadPoolJob tempJob;
-
-    HandleLock(  );
-
-    // validate handle and sid
-    if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return GENA_E_BAD_HANDLE;
-    }
-
-    if( ( sub = GetClientSubClientSID( handle_info->ClientSubList,
-                                       in_sid ) ) == NULL ) {
-        HandleUnlock(  );
-        return GENA_E_BAD_SID;
-    }
-    // remove old events
-    if( TimerThreadRemove( &gTimerThread, sub->RenewEventId, &tempJob ) ==
-        0 ) {
-
-        free_upnp_timeout( ( upnp_timeout * ) tempJob.arg );
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                         "REMOVED AUTO RENEW  EVENT" ) );
-
-    sub->RenewEventId = -1;
-    return_code = copy_client_subscription( sub, &sub_copy );
-
-    HandleUnlock(  );
-
-    if( return_code != HTTP_SUCCESS ) {
-        return return_code;
-    }
-
-    return_code = gena_subscribe( sub_copy.EventURL, TimeOut,
-                                  sub_copy.ActualSID, &ActualSID );
-    HandleLock(  );
-
-    if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        if( return_code == UPNP_E_SUCCESS ) {
-            free( ActualSID );
-        }
-        return GENA_E_BAD_HANDLE;
-    }
-    // we just called GetHandleInfo, so we don't check for return value
-    //GetHandleInfo(client_handle, &handle_info);
-
-    if( return_code != UPNP_E_SUCCESS ) {
-        // network failure (remove client sub)
-        RemoveClientSubClientSID( &handle_info->ClientSubList, in_sid );
-        free_client_subscription( &sub_copy );
-        HandleUnlock(  );
-        return return_code;
-    }
-    // get subscription
-    if( ( sub = GetClientSubClientSID( handle_info->ClientSubList,
-                                       in_sid ) ) == NULL ) {
-        free( ActualSID );
-        free_client_subscription( &sub_copy );
-        HandleUnlock(  );
-        return GENA_E_BAD_SID;
-    }
-    // store actual sid
-    free( sub->ActualSID );
-    sub->ActualSID = ActualSID;
-
-    // start renew subscription timer
-    return_code = ScheduleGenaAutoRenew( client_handle, *TimeOut, sub );
-    if( return_code != GENA_SUCCESS ) {
-        RemoveClientSubClientSID( &handle_info->ClientSubList, sub->sid );
-    }
-    free_client_subscription( &sub_copy );
-    HandleUnlock(  );
-    return return_code;
-}
-
-/************************************************************************
-* Function : gena_process_notification_event
-*																	
-* Parameters:														
-*	IN SOCKINFO *info: Socket structure containing the device socket 
-*					information
-*	IN http_message_t* event: The http message contains the GENA 
-*								notification
-*
-* Description:														
-*	This function processes NOTIFY events that are sent by devices. 
-*	called by genacallback()
-*
-* Returns: void
-*
-* Note : called by genacallback()
-****************************************************************************/
-void
-gena_process_notification_event( IN SOCKINFO * info,
-                                 IN http_message_t * event )
-{
-    struct Upnp_Event event_struct;
-    int eventKey;
-    token sid;
-    client_subscription *subscription;
-    IXML_Document *ChangedVars;
-    struct Handle_Info *handle_info;
-    void *cookie;
-    Upnp_FunPtr callback;
-    UpnpClient_Handle client_handle;
-
-    memptr sid_hdr;
-    memptr nt_hdr,
-      nts_hdr;
-    memptr seq_hdr;
-
-    // get SID
-    if( httpmsg_find_hdr( event, HDR_SID, &sid_hdr ) == NULL ) {
-        error_respond( info, HTTP_PRECONDITION_FAILED, event );
-
-        return;
-    }
-    sid.buff = sid_hdr.buf;
-    sid.size = sid_hdr.length;
-
-    // get event key
-    if( httpmsg_find_hdr( event, HDR_SEQ, &seq_hdr ) == NULL ||
-        matchstr( seq_hdr.buf, seq_hdr.length, "%d%0", &eventKey )
-        != PARSE_OK ) {
-        error_respond( info, HTTP_BAD_REQUEST, event );
-
-        return;
-    }
-    // get NT and NTS headers
-    if( httpmsg_find_hdr( event, HDR_NT, &nt_hdr ) == NULL ||
-        httpmsg_find_hdr( event, HDR_NTS, &nts_hdr ) == NULL ) {
-        error_respond( info, HTTP_BAD_REQUEST, event );
-
-        return;
-    }
-    // verify NT and NTS headers
-    if( memptr_cmp( &nt_hdr, "upnp:event" ) != 0 ||
-        memptr_cmp( &nts_hdr, "upnp:propchange" ) != 0 ) {
-        error_respond( info, HTTP_PRECONDITION_FAILED, event );
-
-        return;
-    }
-    // parse the content (should be XML)
-    if( !has_xml_content_type( event ) ||
-        event->msg.length == 0 ||
-        ( ixmlParseBufferEx( event->entity.buf, &ChangedVars ) ) !=
-        IXML_SUCCESS ) {
-        error_respond( info, HTTP_BAD_REQUEST, event );
-
-        return;
-    }
-
-    HandleLock(  );
-
-    // get client info
-    if( GetClientHandleInfo( &client_handle, &handle_info ) != HND_CLIENT ) {
-        error_respond( info, HTTP_PRECONDITION_FAILED, event );
-        HandleUnlock(  );
-        ixmlDocument_free( ChangedVars );
-
-        return;
-    }
-    // get subscription based on SID
-    if( ( subscription = GetClientSubActualSID( handle_info->ClientSubList,
-                                                &sid ) ) == NULL ) {
-        if( eventKey == 0 ) {
-            // wait until we've finished processing a subscription 
-            //   (if we are in the middle)
-            // this is to avoid mistakenly rejecting the first event if we 
-            //   receive it before the subscription response
-            HandleUnlock(  );
-
-            // try and get Subscription Lock 
-            //   (in case we are in the process of subscribing)
-            SubscribeLock(  );
-
-            // get HandleLock again
-            HandleLock(  );
-
-            if( GetClientHandleInfo( &client_handle, &handle_info )
-                != HND_CLIENT ) {
-                error_respond( info, HTTP_PRECONDITION_FAILED, event );
-                SubscribeUnlock(  );
-                HandleUnlock(  );
-                ixmlDocument_free( ChangedVars );
-
-                return;
-            }
-
-            if( ( subscription =
-                  GetClientSubActualSID( handle_info->ClientSubList,
-                                         &sid ) ) == NULL ) {
-                error_respond( info, HTTP_PRECONDITION_FAILED, event );
-                SubscribeUnlock(  );
-                HandleUnlock(  );
-                ixmlDocument_free( ChangedVars );
-
-                return;
-            }
-
-            SubscribeUnlock(  );
-        } else {
-            error_respond( info, HTTP_PRECONDITION_FAILED, event );
-            HandleUnlock(  );
-            ixmlDocument_free( ChangedVars );
-
-            return;
-        }
-    }
-
-    error_respond( info, HTTP_OK, event );  // success
-
-    // fill event struct
-    strcpy( event_struct.Sid, subscription->sid );
-    event_struct.EventKey = eventKey;
-    event_struct.ChangedVariables = ChangedVars;
-
-    // copy callback
-    callback = handle_info->Callback;
-    cookie = handle_info->Cookie;
-
-    HandleUnlock(  );
-
-    // make callback with event struct
-    // In future, should find a way of mainting
-    // that the handle is not unregistered in the middle of a
-    // callback
-    callback( UPNP_EVENT_RECEIVED, &event_struct, cookie );
-
-    ixmlDocument_free( ChangedVars );
-}
-
-#endif // INCLUDE_CLIENT_APIS
-#endif // EXCLUDE_GENA
diff --git a/tombupnp/upnp/src/gena/gena_device.c b/tombupnp/upnp/src/gena/gena_device.c
deleted file mode 100644
index dfc14b0..0000000
--- a/tombupnp/upnp/src/gena/gena_device.c
+++ /dev/null
@@ -1,1698 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#if EXCLUDE_GENA == 0
-#ifdef INCLUDE_DEVICE_APIS
-
-#include "gena.h"
-#include "sysdep.h"
-#include "upnp_uuid.h"
-#include "upnpapi.h"
-#include "parsetools.h"
-#include "statcodes.h"
-#include "httpparser.h"
-#include "httpreadwrite.h"
-#include "ssdplib.h"
-
-#include "unixutil.h"
-
-/************************************************************************
-* Function : genaUnregisterDevice
-*																	
-* Parameters:														
-*	IN UpnpDevice_Handle device_handle: Handle of the root device
-*
-* Description:														
-*	This function cleans the service table of the device. 
-*
-* Returns: int
-*	returns UPNP_E_SUCCESS if successful else returns GENA_E_BAD_HANDLE
-****************************************************************************/
-int
-genaUnregisterDevice( IN UpnpDevice_Handle device_handle )
-{
-    struct Handle_Info *handle_info;
-
-    HandleLock(  );
-    if( GetHandleInfo( device_handle, &handle_info ) != HND_DEVICE ) {
-
-        DBGONLY( UpnpPrintf( UPNP_CRITICAL, GENA, __FILE__, __LINE__,
-                             "genaUnregisterDevice : BAD Handle : %d\n",
-                             device_handle ) );
-
-        HandleUnlock(  );
-        return GENA_E_BAD_HANDLE;
-    }
-
-    freeServiceTable( &handle_info->ServiceTable );
-    HandleUnlock(  );
-
-    return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-* Function : GeneratePropertySet
-*																	
-* Parameters:														
-*	IN char **names : Array of variable names (go in the event notify)
-*	IN char ** values : Array of variable values (go in the event notify)
-*   IN int count : number of variables
-*   OUT DOMString *out: PropertySet node in the string format
-*
-* Description:														
-*	This function to generate XML propery Set for notifications				
-*
-* Returns: int
-*	returns UPNP_E_SUCCESS if successful else returns GENA_E_BAD_HANDLE
-*
-* Note: XML_VERSION comment is NOT sent due to interop issues with other 
-*		UPnP vendors
-****************************************************************************/
-static int
-GeneratePropertySet( IN char **names,
-                     IN char **values,
-                     IN int count,
-                     OUT DOMString * out )
-{
-    char *buffer;
-    int counter = 0;
-    int size = 0;
-
-    //size+=strlen(XML_VERSION);  the XML_VERSION is not interopeable with 
-    //other vendors
-    size += strlen( XML_PROPERTYSET_HEADER );
-    size += strlen( "</e:propertyset>\n\n" );
-
-    for( counter = 0; counter < count; counter++ ) {
-        size += strlen( "<e:property>\n</e:property>\n" );
-        size +=
-            ( 2 * strlen( names[counter] ) + strlen( values[counter] ) +
-              ( strlen( "<></>\n" ) ) );
-
-    }
-    buffer = ( char * )malloc( size + 1 );
-
-    if( buffer == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    memset( buffer, 0, size + 1 );
-
-    //strcpy(buffer,XML_VERSION);  the XML_VERSION is not interopeable with 
-    //other vendors
-    strcpy( buffer, XML_PROPERTYSET_HEADER );
-
-    for( counter = 0; counter < count; counter++ ) {
-        strcat( buffer, "<e:property>\n" );
-        sprintf( &buffer[strlen( buffer )],
-                 "<%s>%s</%s>\n</e:property>\n", names[counter],
-                 values[counter], names[counter] );
-    }
-    strcat( buffer, "</e:propertyset>\n\n" );
-    ( *out ) = ixmlCloneDOMString( buffer );
-    free( buffer );
-    return XML_SUCCESS;
-}
-
-/************************************************************************
-* Function : free_notify_struct
-*																	
-* Parameters:														
-*	IN notify_thread_struct * input : Notify structure
-*
-* Description:														
-*	This function frees memory used in notify_threads if the reference 
-*	count is 0 otherwise decrements the refrence count
-*
-* Returns: VOID
-*	
-****************************************************************************/
-static void
-free_notify_struct( IN notify_thread_struct * input )
-{
-    ( *input->reference_count )--;
-    if( ( *input->reference_count ) == 0 ) {
-        free( input->headers );
-        ixmlFreeDOMString( input->propertySet );
-        free( input->servId );
-        free( input->UDN );
-        free( input->reference_count );
-    }
-    free( input );
-}
-
-/****************************************************************************
-*	Function :	notify_send_and_recv
-*
-*	Parameters :
-*		IN uri_type* destination_url : subscription callback URL 
-*										(URL of the control point)
-*		IN membuffer* mid_msg :	Common HTTP headers 
-*		IN char* propertySet :	The evented XML 
-*		OUT http_parser_t* response : The response from the control point.
-*
-*	Description :	This function sends the notify message and returns a 
-*					reply.
-*
-*	Return : int
-*		on success: returns UPNP_E_SUCCESS; else returns a UPNP error
-*
-*	Note : called by genaNotify
-****************************************************************************/
-static XINLINE int
-notify_send_and_recv( IN uri_type * destination_url,
-                      IN membuffer * mid_msg,
-                      IN char *propertySet,
-                      OUT http_parser_t * response )
-{
-    uri_type url;
-    int conn_fd;
-    membuffer start_msg;
-    int ret_code;
-    int err_code;
-    int timeout;
-    SOCKINFO info;
-
-    // connect
-    DBGONLY( UpnpPrintf( UPNP_ALL, GENA, __FILE__, __LINE__,
-                         "gena notify to: %.*s\n",
-                         destination_url->hostport.text.size,
-                         destination_url->hostport.text.buff ); )
-
-        conn_fd = http_Connect( destination_url, &url );
-    if( conn_fd < 0 ) {
-        return conn_fd;         // return UPNP error
-    }
-
-    if( ( ret_code = sock_init( &info, conn_fd ) ) != 0 ) {
-        sock_destroy( &info, SD_BOTH );
-        return ret_code;
-    }
-    // make start line and HOST header
-    membuffer_init( &start_msg );
-    if( http_MakeMessage( &start_msg, 1, 1,
-                          "q" "s",
-                          HTTPMETHOD_NOTIFY, &url, mid_msg->buf ) != 0 ) {
-        membuffer_destroy( &start_msg );
-        sock_destroy( &info, SD_BOTH );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    timeout = HTTP_DEFAULT_TIMEOUT;
-
-    // send msg (note +1 for propertyset; null-terminator is also sent)
-    if( ( ret_code = http_SendMessage( &info, &timeout,
-                                       "bb",
-                                       start_msg.buf, (size_t)start_msg.length,
-                                       propertySet,
-                                       strlen( propertySet ) + 1 ) ) !=
-        0 ) {
-        membuffer_destroy( &start_msg );
-        sock_destroy( &info, SD_BOTH );
-        return ret_code;
-    }
-
-    if( ( ret_code = http_RecvMessage( &info, response,
-                                       HTTPMETHOD_NOTIFY, &timeout,
-                                       &err_code ) ) != 0 ) {
-        membuffer_destroy( &start_msg );
-        sock_destroy( &info, SD_BOTH );
-        httpmsg_destroy( &response->msg );
-        return ret_code;
-    }
-
-    sock_destroy( &info, SD_BOTH ); //should shutdown completely
-    //when closing socket
-    //  sock_destroy( &info,SD_RECEIVE);
-    membuffer_destroy( &start_msg );
-
-    return UPNP_E_SUCCESS;
-}
-
-/****************************************************************************
-*	Function :	genaNotify
-*
-*	Parameters :
-*		IN char *headers :	(null terminated) (includes all headers 
-*							(including \r\n) except SID and SEQ)
-*		IN char *propertySet :	The evented XML 
-*		IN subscription* sub :	subscription to be Notified, 
-*								Assumes this is valid for life of function)
-*
-*	Description :	Function to Notify a particular subscription of a 
-*					particular event. In general the service should NOT be 
-*					blocked around this call. (this may cause deadlock 
-*					with a client) NOTIFY http request is sent and the 
-*					reply is processed.
-*
-*	Return :	int
-*		GENA_SUCCESS  if the event was delivered else returns appropriate 
-*		error
-*
-*	Note :
-****************************************************************************/
-int
-genaNotify( IN char *headers,
-            IN char *propertySet,
-            IN subscription * sub )
-{
-    int i;
-    membuffer mid_msg;
-    uri_type *url;
-    http_parser_t response;
-    int return_code = -1;
-
-    membuffer_init( &mid_msg );
-
-    if( http_MakeMessage( &mid_msg, 1, 1,
-                          "s" "ssc" "sdcc",
-                          headers,
-                          "SID: ", sub->sid,
-                          "SEQ: ", sub->ToSendEventKey ) != 0 ) {
-        membuffer_destroy( &mid_msg );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    // send a notify to each url until one goes thru
-    for( i = 0; i < sub->DeliveryURLs.size; i++ ) {
-        url = &sub->DeliveryURLs.parsedURLs[i];
-
-        if( ( return_code = notify_send_and_recv( url,
-                                                  &mid_msg, propertySet,
-                                                  &response ) ) ==
-            UPNP_E_SUCCESS ) {
-            break;
-        }
-    }
-
-    membuffer_destroy( &mid_msg );
-
-    if( return_code == UPNP_E_SUCCESS ) {
-        if( response.msg.status_code == HTTP_OK ) {
-            return_code = GENA_SUCCESS;
-        } else {
-            if( response.msg.status_code == HTTP_PRECONDITION_FAILED ) {
-                //Invalid SID gets removed
-                return_code = GENA_E_NOTIFY_UNACCEPTED_REMOVE_SUB;
-            } else {
-                return_code = GENA_E_NOTIFY_UNACCEPTED;
-            }
-        }
-        httpmsg_destroy( &response.msg );
-    }
-
-    return return_code;
-}
-
-/****************************************************************************
-*	Function :	genaNotifyThread
-*
-*	Parameters :
-*			IN void * input : notify thread structure containing all the 
-*								headers and property set info
-*
-*	Description :	Thread job to Notify a control point. It validates the
-*		subscription and copies the subscription. Also make sure that 
-*		events are sent in order. 
-*
-*	Return : void
-*
-*	Note : calls the genaNotify to do the actual work
-****************************************************************************/
-static void
-genaNotifyThread( IN void *input )
-{
-
-    subscription *sub;
-    service_info *service;
-    subscription sub_copy;
-    notify_thread_struct *in = ( notify_thread_struct * ) input;
-    int return_code;
-    struct Handle_Info *handle_info;
-    ThreadPoolJob job;
-
-    HandleLock(  );
-    //validate context
-
-    if( GetHandleInfo( in->device_handle, &handle_info ) != HND_DEVICE ) {
-        free_notify_struct( in );
-        HandleUnlock(  );
-        return;
-    }
-
-    if( ( ( service = FindServiceId( &handle_info->ServiceTable,
-                                     in->servId, in->UDN ) ) == NULL )
-        || ( !service->active )
-        || ( ( sub = GetSubscriptionSID( in->sid, service ) ) == NULL )
-        || ( ( copy_subscription( sub, &sub_copy ) != HTTP_SUCCESS ) ) ) {
-        free_notify_struct( in );
-        HandleUnlock(  );
-        return;
-    }
-    //If the event is out of order push it back to the job queue
-    if( in->eventKey != sub->ToSendEventKey ) {
-
-        TPJobInit( &job, ( start_routine ) genaNotifyThread, input );
-        TPJobSetFreeFunction( &job, ( free_function ) free_notify_struct );
-        TPJobSetPriority( &job, MED_PRIORITY );
-        ThreadPoolAdd( &gSendThreadPool, &job, NULL );
-
-        freeSubscription( &sub_copy );
-        HandleUnlock(  );
-        return;
-    }
-
-    HandleUnlock(  );
-
-    //send the notify
-    return_code = genaNotify( in->headers, in->propertySet, &sub_copy );
-
-    freeSubscription( &sub_copy );
-
-    HandleLock(  );
-
-    if( GetHandleInfo( in->device_handle, &handle_info ) != HND_DEVICE ) {
-        free_notify_struct( in );
-        HandleUnlock(  );
-        return;
-    }
-    //validate context
-    if( ( ( service = FindServiceId( &handle_info->ServiceTable,
-                                     in->servId, in->UDN ) ) == NULL )
-        || ( !service->active )
-        || ( ( sub = GetSubscriptionSID( in->sid, service ) ) == NULL ) ) {
-        free_notify_struct( in );
-        HandleUnlock(  );
-        return;
-    }
-
-    sub->ToSendEventKey++;
-
-    if( sub->ToSendEventKey < 0 )   //wrap to 1 for overflow
-        sub->ToSendEventKey = 1;
-
-    if( return_code == GENA_E_NOTIFY_UNACCEPTED_REMOVE_SUB ) {
-        RemoveSubscriptionSID( in->sid, service );
-    }
-
-    free_notify_struct( in );
-    HandleUnlock(  );
-}
-
-/****************************************************************************
-*	Function :	genaInitNotify
-*
-*	Parameters :
-*		   IN UpnpDevice_Handle device_handle :	Device handle
-*		   IN char *UDN :	Device udn
-*		   IN char *servId :	Service ID
-*		   IN char **VarNames :	Array of variable names
-*		   IN char **VarValues :	Array of variable values
-*		   IN int var_count :	array size
-*		   IN Upnp_SID sid :	subscription ID
-*
-*	Description :	This function sends the intial state table dump to 
-*		newly subscribed control point. 
-*
-*	Return :	int
-*		returns GENA_E_SUCCESS if successful else returns appropriate error
-* 
-*	Note : No other event will be sent to this control point before the 
-*			intial state table dump.
-****************************************************************************/
-int
-genaInitNotify( IN UpnpDevice_Handle device_handle,
-                IN char *UDN,
-                IN char *servId,
-                IN char **VarNames,
-                IN char **VarValues,
-                IN int var_count,
-                IN Upnp_SID sid )
-{
-    char *UDN_copy = NULL;
-    char *servId_copy = NULL;
-    char *propertySet = NULL;
-    char *headers = NULL;
-    subscription *sub = NULL;
-    service_info *service = NULL;
-    int return_code = GENA_SUCCESS;
-    int headers_size;
-    int *reference_count = NULL;
-    struct Handle_Info *handle_info;
-    ThreadPoolJob job;
-
-    notify_thread_struct *thread_struct = NULL;
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                         "GENA BEGIN INITIAL NOTIFY " ) );
-
-    reference_count = ( int * )malloc( sizeof( int ) );
-
-    if( reference_count == NULL )
-        return UPNP_E_OUTOF_MEMORY;
-
-    ( *reference_count ) = 0;
-
-    UDN_copy = ( char * )malloc( strlen( UDN ) + 1 );
-
-    if( UDN_copy == NULL ) {
-        free( reference_count );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    servId_copy = ( char * )malloc( strlen( servId ) + 1 );
-
-    if( servId_copy == NULL ) {
-        free( UDN_copy );
-        free( reference_count );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    strcpy( UDN_copy, UDN );
-    strcpy( servId_copy, servId );
-
-    HandleLock(  );
-
-    if( GetHandleInfo( device_handle, &handle_info ) != HND_DEVICE ) {
-        free( UDN_copy );
-        free( reference_count );
-        free( servId_copy );
-        HandleUnlock(  );
-        return GENA_E_BAD_HANDLE;
-    }
-
-    if( ( service = FindServiceId( &handle_info->ServiceTable,
-                                   servId, UDN ) ) == NULL ) {
-        free( UDN_copy );
-        free( reference_count );
-        free( servId_copy );
-        HandleUnlock(  );
-        return GENA_E_BAD_SERVICE;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                         "FOUND SERVICE IN INIT NOTFY: UDN %s, ServID: %s ",
-                         UDN, servId ) );
-
-    if( ( ( sub = GetSubscriptionSID( sid, service ) ) == NULL ) ||
-        ( sub->active ) ) {
-        free( UDN_copy );
-        free( reference_count );
-        free( servId_copy );
-        HandleUnlock(  );
-        return GENA_E_BAD_SID;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                         "FOUND SUBSCRIPTION IN INIT NOTIFY: SID %s ",
-                         sid ) );
-
-    sub->active = 1;
-
-    if( ( return_code = GeneratePropertySet( VarNames, VarValues,
-                                             var_count,
-                                             &propertySet ) ) !=
-        XML_SUCCESS ) {
-        free( UDN_copy );
-        free( reference_count );
-        free( servId_copy );
-        HandleUnlock(  );
-        return return_code;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                         "GENERATED PROPERY SET IN INIT NOTIFY: \n'%s'\n",
-                         propertySet ) );
-
-    headers_size = strlen( "CONTENT-TYPE text/xml; charset=UTF-8\r\n" ) +
-        strlen( "CONTENT-LENGTH: \r\n" ) + MAX_CONTENT_LENGTH +
-        strlen( "NT: upnp:event\r\n" ) +
-        strlen( "NTS: upnp:propchange\r\n" ) + 1;
-
-    headers = ( char * )malloc( headers_size );
-
-    if( headers == NULL ) {
-        ixmlFreeDOMString( propertySet );
-        free( UDN_copy );
-        free( servId_copy );
-        free( reference_count );
-        HandleUnlock(  );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    sprintf( headers, "CONTENT-TYPE: text/xml; charset=UTF-8\r\nCONTENT-LENGTH: "
-             "%zu\r\nNT: upnp:event\r\nNTS: upnp:propchange\r\n",
-             strlen( propertySet ) + 1 );
-
-    //schedule thread for initial notification
-
-    thread_struct =
-        ( notify_thread_struct * )
-        malloc( sizeof( notify_thread_struct ) );
-
-    if( thread_struct == NULL ) {
-        return_code = UPNP_E_OUTOF_MEMORY;
-    } else {
-        ( *reference_count ) = 1;
-        thread_struct->servId = servId_copy;
-        thread_struct->UDN = UDN_copy;
-        thread_struct->headers = headers;
-        thread_struct->propertySet = propertySet;
-        strcpy( thread_struct->sid, sid );
-        thread_struct->eventKey = sub->eventKey++;
-        thread_struct->reference_count = reference_count;
-        thread_struct->device_handle = device_handle;
-
-        TPJobInit( &job, ( start_routine ) genaNotifyThread,
-                   thread_struct );
-        TPJobSetFreeFunction( &job, ( free_routine ) free_notify_struct );
-        TPJobSetPriority( &job, MED_PRIORITY );
-
-        if( ( return_code =
-              ThreadPoolAdd( &gSendThreadPool, &job, NULL ) ) != 0 ) {
-            if( return_code == EOUTOFMEM ) {
-                return_code = UPNP_E_OUTOF_MEMORY;
-            }
-        } else {
-            return_code = GENA_SUCCESS;
-        }
-    }
-
-    if( return_code != GENA_SUCCESS ) {
-
-        free( reference_count );
-        free( UDN_copy );
-        free( servId_copy );
-        free( thread_struct );
-        ixmlFreeDOMString( propertySet );
-        free( headers );
-    }
-
-    HandleUnlock(  );
-
-    return return_code;
-}
-
-/****************************************************************************
-*	Function :	genaInitNotifyExt
-*
-*	Parameters :
-*		   IN UpnpDevice_Handle device_handle :	Device handle
-*		   IN char *UDN :	Device udn
-*		   IN char *servId :	Service ID
-*		   IN IXML_Document *PropSet :	Document of the state table
-*		   IN Upnp_SID sid :	subscription ID
-*
-*	Description :	This function is similar to the genaInitNofity. The only 
-*	difference is that it takes the xml document for the state table and 
-*	sends the intial state table dump to newly subscribed control point. 
-*
-*	Return :	int
-*		returns GENA_E_SUCCESS if successful else returns appropriate error
-* 
-*	Note : No other event will be sent to this control point before the 
-*			intial state table dump.
-****************************************************************************/
-int
-genaInitNotifyExt( IN UpnpDevice_Handle device_handle,
-                   IN char *UDN,
-                   IN char *servId,
-                   IN IXML_Document * PropSet,
-                   IN Upnp_SID sid )
-{
-    char *UDN_copy = NULL;
-    char *servId_copy = NULL;
-    char *headers = NULL;
-    subscription *sub = NULL;
-    service_info *service = NULL;
-    int return_code = GENA_SUCCESS;
-    int headers_size;
-    int *reference_count = NULL;
-    struct Handle_Info *handle_info;
-    DOMString propertySet = NULL;
-
-    ThreadPoolJob job;
-
-    notify_thread_struct *thread_struct = NULL;
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                         "GENA BEGIN INITIAL NOTIFY EXT" ) );
-    reference_count = ( int * )malloc( sizeof( int ) );
-
-    if( reference_count == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    ( *reference_count ) = 0;
-
-    UDN_copy = ( char * )malloc( strlen( UDN ) + 1 );
-    if( UDN_copy == NULL ) {
-        free( reference_count );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    servId_copy = ( char * )malloc( strlen( servId ) + 1 );
-    if( servId_copy == NULL ) {
-        free( UDN_copy );
-        free( reference_count );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    strcpy( UDN_copy, UDN );
-    strcpy( servId_copy, servId );
-
-    HandleLock(  );
-
-    if( GetHandleInfo( device_handle, &handle_info ) != HND_DEVICE ) {
-        free( UDN_copy );
-        free( reference_count );
-        free( servId_copy );
-        HandleUnlock(  );
-        return GENA_E_BAD_HANDLE;
-    }
-
-    if( ( service = FindServiceId( &handle_info->ServiceTable,
-                                   servId, UDN ) ) == NULL ) {
-        free( UDN_copy );
-        free( reference_count );
-        free( servId_copy );
-        HandleUnlock(  );
-        return GENA_E_BAD_SERVICE;
-    }
-    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                         "FOUND SERVICE IN INIT NOTFY EXT: UDN %s, ServID: %s\n",
-                         UDN, servId ) );
-
-    if( ( ( sub = GetSubscriptionSID( sid, service ) ) == NULL ) ||
-        ( sub->active ) ) {
-        free( UDN_copy );
-        free( reference_count );
-        free( servId_copy );
-        HandleUnlock(  );
-        return GENA_E_BAD_SID;
-    }
-    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                         "FOUND SUBSCRIPTION IN INIT NOTIFY EXT: SID %s",
-                         sid ) );
-
-    sub->active = 1;
-
-    propertySet = ixmlPrintNode( ( IXML_Node * ) PropSet );
-    if( propertySet == NULL ) {
-        free( UDN_copy );
-        free( reference_count );
-        free( servId_copy );
-        HandleUnlock(  );
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                         "GENERATED PROPERY SET IN INIT EXT NOTIFY: %s",
-                         propertySet ) );
-
-    headers_size = strlen( "CONTENT-TYPE text/xml; charset=UTF-8\r\n" ) +
-        strlen( "CONTENT-LENGTH: \r\n" ) + MAX_CONTENT_LENGTH +
-        strlen( "NT: upnp:event\r\n" ) +
-        strlen( "NTS: upnp:propchange\r\n" ) + 1;
-
-    headers = ( char * )malloc( headers_size );
-    if( headers == NULL ) {
-        free( UDN_copy );
-        free( servId_copy );
-        free( reference_count );
-        ixmlFreeDOMString( propertySet );
-        HandleUnlock(  );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    sprintf( headers, "CONTENT-TYPE: text/xml; charset=UTF-8\r\nCONTENT-LENGTH: "
-             "%ld" "\r\nNT: upnp:event\r\nNTS: upnp:propchange\r\n",
-             (long) strlen( propertySet ) + 1 );
-
-    //schedule thread for initial notification
-
-    thread_struct =
-        ( notify_thread_struct * )
-        malloc( sizeof( notify_thread_struct ) );
-
-    if( thread_struct == NULL ) {
-        return_code = UPNP_E_OUTOF_MEMORY;
-    } else {
-        ( *reference_count ) = 1;
-        thread_struct->servId = servId_copy;
-        thread_struct->UDN = UDN_copy;
-        thread_struct->headers = headers;
-        thread_struct->propertySet = propertySet;
-        strcpy( thread_struct->sid, sid );
-        thread_struct->eventKey = sub->eventKey++;
-        thread_struct->reference_count = reference_count;
-        thread_struct->device_handle = device_handle;
-
-        TPJobInit( &job, ( start_routine ) genaNotifyThread,
-                   thread_struct );
-        TPJobSetFreeFunction( &job, ( free_routine ) free_notify_struct );
-        TPJobSetPriority( &job, MED_PRIORITY );
-
-        if( ( return_code =
-              ThreadPoolAdd( &gSendThreadPool, &job, NULL ) ) != 0 ) {
-            if( return_code == EOUTOFMEM ) {
-                return_code = UPNP_E_OUTOF_MEMORY;
-            }
-        } else {
-            return_code = GENA_SUCCESS;
-        }
-    }
-
-    if( return_code != GENA_SUCCESS ) {
-        ixmlFreeDOMString( propertySet );
-        free( reference_count );
-        free( UDN_copy );
-        free( servId_copy );
-        free( thread_struct );
-        free( headers );
-    }
-    HandleUnlock(  );
-
-    return return_code;
-}
-
-/****************************************************************************
-*	Function :	genaNotifyAllExt
-*
-*	Parameters :
-*			IN UpnpDevice_Handle device_handle : Device handle
-*			IN char *UDN :	Device udn
-*			IN char *servId :	Service ID
-*           IN IXML_Document *PropSet :	XML document Event varible property set
-*
-*	Description : 	This function sends a notification to all the subscribed
-*	control points
-*
-*	Return :	int
-*
-*	Note : This function is similar to the genaNotifyAll. the only difference
-*			is it takes the document instead of event variable array
-****************************************************************************/
-int
-genaNotifyAllExt( IN UpnpDevice_Handle device_handle,
-                  IN char *UDN,
-                  IN char *servId,
-                  IN IXML_Document * PropSet )
-{
-    char *headers = NULL;
-    int headers_size;
-    int return_code = GENA_SUCCESS;
-    char *UDN_copy = NULL;
-    char *servId_copy = NULL;
-    int *reference_count = NULL;
-    struct Handle_Info *handle_info;
-    DOMString propertySet = NULL;
-    ThreadPoolJob job;
-    subscription *finger = NULL;
-
-    notify_thread_struct *thread_struct = NULL;
-
-    service_info *service = NULL;
-
-    reference_count = ( int * )malloc( sizeof( int ) );
-
-    if( reference_count == NULL )
-        return UPNP_E_OUTOF_MEMORY;
-
-    ( *reference_count = 0 );
-
-    UDN_copy = ( char * )malloc( strlen( UDN ) + 1 );
-
-    if( UDN_copy == NULL ) {
-        free( reference_count );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    servId_copy = ( char * )malloc( strlen( servId ) + 1 );
-
-    if( servId_copy == NULL ) {
-        free( UDN_copy );
-        free( reference_count );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    strcpy( UDN_copy, UDN );
-    strcpy( servId_copy, servId );
-
-    propertySet = ixmlPrintNode( ( IXML_Node * ) PropSet );
-    if( propertySet == NULL ) {
-        free( UDN_copy );
-        free( servId_copy );
-        free( reference_count );
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    headers_size = strlen( "CONTENT-TYPE text/xml; charset=UTF-8\r\n" ) +
-        strlen( "CONTENT-LENGTH: \r\n" ) + MAX_CONTENT_LENGTH +
-        strlen( "NT: upnp:event\r\n" ) +
-        strlen( "NTS: upnp:propchange\r\n" ) + 1;
-
-    headers = ( char * )malloc( headers_size );
-    if( headers == NULL ) {
-        free( UDN_copy );
-        free( servId_copy );
-        ixmlFreeDOMString( propertySet );
-        free( reference_count );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    //changed to add null terminator at end of content
-    //content length = (length in bytes of property set) + null char
-    sprintf( headers, "CONTENT-TYPE: text/xml; charset=UTF-8\r\nCONTENT-LENGTH: "
-             "%ld" "\r\nNT: upnp:event\r\nNTS: upnp:propchange\r\n",
-             (long) strlen( propertySet ) + 1 );
-
-    HandleLock(  );
-
-    if( GetHandleInfo( device_handle, &handle_info ) != HND_DEVICE )
-        return_code = GENA_E_BAD_HANDLE;
-    else {
-        if( ( service = FindServiceId( &handle_info->ServiceTable,
-                                       servId, UDN ) ) != NULL ) {
-            finger = GetFirstSubscription( service );
-
-            while( finger ) {
-                thread_struct =
-                    ( notify_thread_struct * )
-                    malloc( sizeof( notify_thread_struct ) );
-                if( thread_struct == NULL ) {
-                    break;
-                    return_code = UPNP_E_OUTOF_MEMORY;
-                }
-
-                ( *reference_count )++;
-                thread_struct->reference_count = reference_count;
-                thread_struct->UDN = UDN_copy;
-                thread_struct->servId = servId_copy;
-                thread_struct->headers = headers;
-                thread_struct->propertySet = propertySet;
-                strcpy( thread_struct->sid, finger->sid );
-                thread_struct->eventKey = finger->eventKey++;
-                thread_struct->device_handle = device_handle;
-                //if overflow, wrap to 1
-                if( finger->eventKey < 0 ) {
-                    finger->eventKey = 1;
-                }
-
-                TPJobInit( &job, ( start_routine ) genaNotifyThread,
-                           thread_struct );
-                TPJobSetFreeFunction( &job,
-                                      ( free_routine )
-                                      free_notify_struct );
-                TPJobSetPriority( &job, MED_PRIORITY );
-                if( ( return_code = ThreadPoolAdd( &gSendThreadPool,
-                                                   &job, NULL ) ) != 0 ) {
-                    if( return_code == EOUTOFMEM ) {
-                        return_code = UPNP_E_OUTOF_MEMORY;
-                    }
-                    break;
-                }
-
-                finger = GetNextSubscription( service, finger );
-            }
-        } else
-            return_code = GENA_E_BAD_SERVICE;
-    }
-
-    if( ( *reference_count ) == 0 ) {
-        free( reference_count );
-        free( headers );
-        ixmlFreeDOMString( propertySet );
-        free( UDN_copy );
-        free( servId_copy );
-    }
-
-    HandleUnlock(  );
-
-    return return_code;
-}
-
-/****************************************************************************
-*	Function :	genaNotifyAll
-*
-*	Parameters :
-*		IN UpnpDevice_Handle device_handle : Device handle
-*		IN char *UDN :	Device udn
-*		IN char *servId :	Service ID
-*	    IN char **VarNames : array of varible names
-*	    IN char **VarValues :	array of variable values
-*		IN int var_count	 :	number of variables
-*
-*	Description : 	This function sends a notification to all the subscribed
-*	control points
-*
-*	Return :	int
-*
-*	Note : This function is similar to the genaNotifyAllExt. The only difference
-*			is it takes event variable array instead of xml document.
-****************************************************************************/
-int
-genaNotifyAll( IN UpnpDevice_Handle device_handle,
-               IN char *UDN,
-               IN char *servId,
-               IN char **VarNames,
-               IN char **VarValues,
-               IN int var_count )
-{
-    char *headers = NULL;
-    char *propertySet = NULL;
-    int headers_size;
-    int return_code = GENA_SUCCESS;
-    char *UDN_copy = NULL;
-    char *servId_copy = NULL;
-    int *reference_count = NULL;
-    struct Handle_Info *handle_info;
-    ThreadPoolJob job;
-
-    subscription *finger = NULL;
-
-    notify_thread_struct *thread_struct = NULL;
-
-    service_info *service = NULL;
-
-    reference_count = ( int * )malloc( sizeof( int ) );
-
-    if( reference_count == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    ( *reference_count = 0 );
-
-    UDN_copy = ( char * )malloc( strlen( UDN ) + 1 );
-
-    if( UDN_copy == NULL ) {
-        free( reference_count );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    servId_copy = ( char * )malloc( strlen( servId ) + 1 );
-    if( servId_copy == NULL ) {
-        free( UDN_copy );
-        free( reference_count );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    strcpy( UDN_copy, UDN );
-    strcpy( servId_copy, servId );
-
-    if( ( return_code = GeneratePropertySet( VarNames, VarValues,
-                                             var_count,
-                                             &propertySet ) ) !=
-        XML_SUCCESS ) {
-        free( UDN_copy );
-        free( servId_copy );
-        free( reference_count );
-        return return_code;
-    }
-
-    headers_size = strlen( "CONTENT-TYPE text/xml; charset=UTF-8\r\n" ) +
-        strlen( "CONTENT-LENGTH: \r\n" ) + MAX_CONTENT_LENGTH +
-        strlen( "NT: upnp:event\r\n" ) +
-        strlen( "NTS: upnp:propchange\r\n" ) + 1;
-
-    headers = ( char * )malloc( headers_size );
-    if( headers == NULL ) {
-        free( UDN_copy );
-        free( servId_copy );
-        ixmlFreeDOMString( propertySet );
-        free( reference_count );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    //changed to add null terminator at end of content
-    //content length = (length in bytes of property set) + null char
-    sprintf( headers, "CONTENT-TYPE: text/xml; charset=UTF-8\r\nCONTENT-LENGTH: " "%ld" "\r\nNT:"
-             " upnp:event\r\nNTS: upnp:propchange\r\n",
-             (long) strlen( propertySet ) + 1 );
-
-    HandleLock(  );
-
-    if( GetHandleInfo( device_handle, &handle_info ) != HND_DEVICE ) {
-        return_code = GENA_E_BAD_HANDLE;
-    } else {
-        if( ( service = FindServiceId( &handle_info->ServiceTable,
-                                       servId, UDN ) ) != NULL ) {
-            finger = GetFirstSubscription( service );
-
-            while( finger ) {
-                thread_struct =
-                    ( notify_thread_struct * )
-                    malloc( sizeof( notify_thread_struct ) );
-                if( thread_struct == NULL ) {
-                    return_code = UPNP_E_OUTOF_MEMORY;
-                    break;
-                }
-                ( *reference_count )++;
-                thread_struct->reference_count = reference_count;
-                thread_struct->UDN = UDN_copy;
-                thread_struct->servId = servId_copy;
-                thread_struct->headers = headers;
-                thread_struct->propertySet = propertySet;
-                strcpy( thread_struct->sid, finger->sid );
-                thread_struct->eventKey = finger->eventKey++;
-                thread_struct->device_handle = device_handle;
-                //if overflow, wrap to 1
-                if( finger->eventKey < 0 ) {
-                    finger->eventKey = 1;
-                }
-
-                TPJobInit( &job, ( start_routine ) genaNotifyThread,
-                           thread_struct );
-                TPJobSetFreeFunction( &job,
-                                      ( free_routine )
-                                      free_notify_struct );
-                TPJobSetPriority( &job, MED_PRIORITY );
-
-                if( ( return_code =
-                      ThreadPoolAdd( &gSendThreadPool, &job, NULL ) )
-                    != 0 ) {
-                    if( return_code == EOUTOFMEM ) {
-                        return_code = UPNP_E_OUTOF_MEMORY;
-                        break;
-                    }
-                }
-
-                finger = GetNextSubscription( service, finger );
-
-            }
-        } else {
-            return_code = GENA_E_BAD_SERVICE;
-        }
-    }
-
-    if( ( *reference_count ) == 0 ) {
-        free( reference_count );
-        free( headers );
-        ixmlFreeDOMString( propertySet );
-        free( UDN_copy );
-        free( servId_copy );
-    }
-    HandleUnlock(  );
-
-    return return_code;
-}
-
-/****************************************************************************
-*	Function :	respond_ok
-*
-*	Parameters :
-*			IN SOCKINFO *info :	socket connection of request
-*			IN int time_out : accepted duration
-*			IN subscription *sub : accepted subscription
-*			IN http_message_t* request : http request
-*
-*	Description : Function to return OK message in the case 
-*		of a subscription request.
-*
-*	Return :	static int
-*		returns UPNP_E_SUCCESS if successful else returns appropriate error
-*	Note :
-****************************************************************************/
-static int
-respond_ok( IN SOCKINFO * info,
-            IN int time_out,
-            IN subscription * sub,
-            IN http_message_t * request )
-{
-    int major,
-      minor;
-    membuffer response;
-    int return_code;
-    char timeout_str[100];
-    int upnp_timeout = UPNP_TIMEOUT;
-
-    http_CalcResponseVersion( request->major_version,
-                              request->minor_version, &major, &minor );
-
-    if( time_out >= 0 ) {
-        sprintf( timeout_str, "TIMEOUT: Second-%d", time_out );
-    } else {
-        strcpy( timeout_str, "TIMEOUT: Second-infinite" );
-    }
-
-    membuffer_init( &response );
-    response.size_inc = 30;
-    if( http_MakeMessage( &response, major, minor,
-                          "R" "D" "S" "N" "ssc" "sc" "A" "c",
-                          HTTP_OK, (off_t)0, 
-                          "SID: ", sub->sid, timeout_str, gUserHTTPHeaders ) != 0 ) {
-        membuffer_destroy( &response );
-        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    return_code = http_SendMessage( info, &upnp_timeout, "b",
-                                    response.buf, (size_t)response.length );
-
-    membuffer_destroy( &response );
-
-    return return_code;
-}
-
-/****************************************************************************
-*	Function :	create_url_list
-*
-*	Parameters :
-*				IN memptr* url_list :	
-*				OUT URL_list *out :	
-*
-*	Description :	Function to parse the Callback header value in 
-*		subscription requests takes in a buffer containing URLS delimited by 
-*		'<' and '>'. The entire buffer is copied into dynamic memory
-*		and stored in the URL_list. Pointers to the individual urls within 
-*		this buffer are allocated and stored in the URL_list. Only URLs with 
-*		network addresses are considered(i.e. host:port or domain name)
-*
-*	Return :	int
-*		if successful returns the number of URLs parsed 
-*		else UPNP_E_OUTOF_MEMORY
-*	Note :
-****************************************************************************/
-static int
-create_url_list( IN memptr * url_list,
-                 OUT URL_list * out )
-{
-    int URLcount = 0;
-    int i;
-    int return_code = 0;
-    uri_type temp;
-    token urls;
-    token *URLS;
-
-    urls.buff = url_list->buf;
-    urls.size = url_list->length;
-    URLS = &urls;
-
-    out->size = 0;
-    out->URLs = NULL;
-    out->parsedURLs = NULL;
-
-    for( i = 0; i < URLS->size; i++ ) {
-        if( ( URLS->buff[i] == '<' ) && ( i + 1 < URLS->size ) ) {
-            if( ( ( return_code = parse_uri( &URLS->buff[i + 1],
-                                             URLS->size - i + 1,
-                                             &temp ) ) == HTTP_SUCCESS )
-                && ( temp.hostport.text.size != 0 ) ) {
-                URLcount++;
-            } else {
-                if( return_code == UPNP_E_OUTOF_MEMORY ) {
-                    return return_code;
-                }
-            }
-        }
-    }
-
-    if( URLcount > 0 ) {
-        out->URLs = ( char * )malloc( URLS->size + 1 );
-        out->parsedURLs =
-            ( uri_type * ) malloc( sizeof( uri_type ) * URLcount );
-        if( ( out->URLs == NULL ) || ( out->parsedURLs == NULL ) ) {
-            free( out->URLs );
-            free( out->parsedURLs );
-            out->URLs = NULL;
-            out->parsedURLs = NULL;
-            return UPNP_E_OUTOF_MEMORY;
-        }
-        memcpy( out->URLs, URLS->buff, URLS->size );
-        out->URLs[URLS->size] = 0;
-        URLcount = 0;
-        for( i = 0; i < URLS->size; i++ ) {
-            if( ( URLS->buff[i] == '<' ) && ( i + 1 < URLS->size ) ) {
-                if( ( ( return_code =
-                        parse_uri( &out->URLs[i + 1], URLS->size - i + 1,
-                                   &out->parsedURLs[URLcount] ) ) ==
-                      HTTP_SUCCESS )
-                    && ( out->parsedURLs[URLcount].hostport.text.size !=
-                         0 ) ) {
-                    URLcount++;
-                } else {
-                    if( return_code == UPNP_E_OUTOF_MEMORY ) {
-                        free( out->URLs );
-                        free( out->parsedURLs );
-                        out->URLs = NULL;
-                        out->parsedURLs = NULL;
-                        return return_code;
-                    }
-                }
-            }
-        }
-    }
-    out->size = URLcount;
-
-    return URLcount;
-}
-
-/****************************************************************************
-*	Function :	gena_process_subscription_request
-*
-*	Parameters :
-*			IN SOCKINFO *info :	socket info of the device 
-*			IN http_message_t* request : SUBSCRIPTION request from the control
-*										point
-*
-*	Description :	This function handles a subscription request from a 
-*		ctrl point. The socket is not closed on return.
-*
-*	Return :	void
-*
-*	Note :
-****************************************************************************/
-void
-gena_process_subscription_request( IN SOCKINFO * info,
-                                   IN http_message_t * request )
-{
-    Upnp_SID temp_sid;
-    int return_code = 1;
-    int time_out = 1801;
-    service_info *service;
-    struct Upnp_Subscription_Request request_struct;
-    subscription *sub;
-    uuid_upnp uid;
-    struct Handle_Info *handle_info;
-    void *cookie;
-    Upnp_FunPtr callback_fun;
-    UpnpDevice_Handle device_handle;
-    memptr nt_hdr;
-    char *event_url_path = NULL;
-    memptr callback_hdr;
-    memptr timeout_hdr;
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                         "Subscription Request Received:\n" ) );
-
-    if( httpmsg_find_hdr( request, HDR_NT, &nt_hdr ) == NULL ) {
-        error_respond( info, HTTP_BAD_REQUEST, request );
-        return;
-    }
-
-    // check NT header
-    //Windows Millenium Interoperability:
-    //we accept either upnp:event, or upnp:propchange for the NT header
-    if( memptr_cmp_nocase( &nt_hdr, "upnp:event" ) != 0 ) {
-        error_respond( info, HTTP_PRECONDITION_FAILED, request );
-        return;
-    }
-
-    // if a SID is present then the we have a bad request
-    //  "incompatible headers"
-    if( httpmsg_find_hdr( request, HDR_SID, NULL ) != NULL ) {
-        error_respond( info, HTTP_BAD_REQUEST, request );
-        return;
-    }
-    //look up service by eventURL
-    if( ( event_url_path = str_alloc( request->uri.pathquery.buff,
-                                      request->uri.pathquery.size ) ) ==
-        NULL ) {
-        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
-        return;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                         "SubscriptionRequest for event URL path: %s\n",
-                         event_url_path );
-         )
-
-        HandleLock(  );
-
-    // CURRENTLY, ONLY ONE DEVICE
-    if( GetDeviceHandleInfo( &device_handle, &handle_info ) != HND_DEVICE ) {
-        free( event_url_path );
-        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
-        HandleUnlock(  );
-        return;
-    }
-    service = FindServiceEventURLPath( &handle_info->ServiceTable,
-                                       event_url_path );
-    free( event_url_path );
-
-    if( service == NULL || !service->active ) {
-        error_respond( info, HTTP_NOT_FOUND, request );
-        HandleUnlock(  );
-        return;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                         "Subscription Request: Number of Subscriptions already %d\n "
-                         "Max Subscriptions allowed: %d\n",
-                         service->TotalSubscriptions,
-                         handle_info->MaxSubscriptions ) );
-
-    // too many subscriptions
-    if( handle_info->MaxSubscriptions != -1 &&
-        service->TotalSubscriptions >= handle_info->MaxSubscriptions ) {
-        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
-        HandleUnlock(  );
-        return;
-    }
-    // generate new subscription
-    sub = ( subscription * ) malloc( sizeof( subscription ) );
-    if( sub == NULL ) {
-        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
-        HandleUnlock(  );
-        return;
-    }
-    sub->eventKey = 0;
-    sub->ToSendEventKey = 0;
-    sub->active = 0;
-    sub->next = NULL;
-    sub->DeliveryURLs.size = 0;
-    sub->DeliveryURLs.URLs = NULL;
-    sub->DeliveryURLs.parsedURLs = NULL;
-
-    // check for valid callbacks
-    if( httpmsg_find_hdr( request, HDR_CALLBACK, &callback_hdr ) == NULL ||
-        ( return_code = create_url_list( &callback_hdr,
-                                         &sub->DeliveryURLs ) ) == 0 ) {
-        error_respond( info, HTTP_PRECONDITION_FAILED, request );
-        freeSubscriptionList( sub );
-        HandleUnlock(  );
-        return;
-    }
-    if( return_code == UPNP_E_OUTOF_MEMORY ) {
-        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
-        freeSubscriptionList( sub );
-        HandleUnlock(  );
-        return;
-    }
-    // set the timeout
-    if( httpmsg_find_hdr( request, HDR_TIMEOUT, &timeout_hdr ) != NULL ) {
-        if( matchstr( timeout_hdr.buf, timeout_hdr.length,
-                      "%iSecond-%d%0", &time_out ) == PARSE_OK ) {
-            // nothing
-        } else if( memptr_cmp_nocase( &timeout_hdr, "Second-infinite" ) ==
-                   0 ) {
-            time_out = -1;      // infinite timeout
-        } else {
-            time_out = DEFAULT_TIMEOUT; // default is > 1800 seconds
-        }
-    }
-    // replace infinite timeout with max timeout, if possible
-    if( handle_info->MaxSubscriptionTimeOut != -1 ) {
-        if( time_out == -1 ||
-            time_out > handle_info->MaxSubscriptionTimeOut ) {
-            time_out = handle_info->MaxSubscriptionTimeOut;
-        }
-    }
-    if( time_out >= 0 ) {
-        sub->expireTime = time( NULL ) + time_out;
-    } else {
-        sub->expireTime = 0;    // infinite time
-    }
-
-    //generate SID
-    uuid_create( &uid );
-    uuid_unpack( &uid, temp_sid );
-    sprintf( sub->sid, "uuid:%s", temp_sid );
-
-    // respond OK
-    if( respond_ok( info, time_out, sub, request ) != UPNP_E_SUCCESS ) {
-        freeSubscriptionList( sub );
-        HandleUnlock(  );
-        return;
-    }
-    //add to subscription list
-    sub->next = service->subscriptionList;
-    service->subscriptionList = sub;
-    service->TotalSubscriptions++;
-
-    //finally generate callback for init table dump
-    request_struct.ServiceId = service->serviceId;
-    request_struct.UDN = service->UDN;
-    strcpy( ( char * )request_struct.Sid, sub->sid );
-
-    //copy callback
-    callback_fun = handle_info->Callback;
-    cookie = handle_info->Cookie;
-
-    HandleUnlock(  );
-
-    //make call back with request struct
-    //in the future should find a way of mainting
-    //that the handle is not unregistered in the middle of a 
-    //callback
-
-    callback_fun( UPNP_EVENT_SUBSCRIPTION_REQUEST,
-                  &request_struct, cookie );
-}
-
-/****************************************************************************
-*	Function :	gena_process_subscription_renewal_request
-*
-*	Parameters :
-*		IN SOCKINFO *info :	socket info of the device
-*		IN http_message_t* request : subscription renewal request from the 
-*									control point
-*
-*	Description :	This function handles a subscription renewal request 
-*		from a ctrl point. The connection is not destroyed on return.
-*
-*	Return :	void
-*
-*	Note :
-****************************************************************************/
-void
-gena_process_subscription_renewal_request( IN SOCKINFO * info,
-                                           IN http_message_t * request )
-{
-    Upnp_SID sid;
-    subscription *sub;
-    int time_out = 1801;
-    service_info *service;
-    struct Handle_Info *handle_info;
-    UpnpDevice_Handle device_handle;
-    memptr temp_hdr;
-    membuffer event_url_path;
-    memptr timeout_hdr;
-
-    // if a CALLBACK or NT header is present, then it is an error
-    if( httpmsg_find_hdr( request, HDR_CALLBACK, NULL ) != NULL ||
-        httpmsg_find_hdr( request, HDR_NT, NULL ) != NULL ) {
-        error_respond( info, HTTP_BAD_REQUEST, request );
-        return;
-    }
-    // get SID
-    if( httpmsg_find_hdr( request, HDR_SID, &temp_hdr ) == NULL ||
-        temp_hdr.length > SID_SIZE ) {
-        error_respond( info, HTTP_PRECONDITION_FAILED, request );
-        return;
-    }
-    memcpy( sid, temp_hdr.buf, temp_hdr.length );
-    sid[temp_hdr.length] = '\0';
-
-    // lookup service by eventURL
-    membuffer_init( &event_url_path );
-    if( membuffer_append( &event_url_path, request->uri.pathquery.buff,
-                          request->uri.pathquery.size ) != 0 ) {
-        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
-        return;
-    }
-
-    HandleLock(  );
-
-    // CURRENTLY, ONLY SUPPORT ONE DEVICE
-    if( GetDeviceHandleInfo( &device_handle, &handle_info ) != HND_DEVICE ) {
-        error_respond( info, HTTP_PRECONDITION_FAILED, request );
-        membuffer_destroy( &event_url_path );
-        return;
-    }
-    service = FindServiceEventURLPath( &handle_info->ServiceTable,
-                                       event_url_path.buf );
-    membuffer_destroy( &event_url_path );
-
-    // get subscription
-    if( service == NULL ||
-        !service->active ||
-        ( ( sub = GetSubscriptionSID( sid, service ) ) == NULL ) ) {
-        error_respond( info, HTTP_PRECONDITION_FAILED, request );
-        HandleUnlock(  );
-        return;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
-                         "Renew request: Number of subscriptions already: %d\n "
-                         "Max Subscriptions allowed:%d\n",
-                         service->TotalSubscriptions,
-                         handle_info->MaxSubscriptions );
-         )
-        // too many subscriptions
-        if( handle_info->MaxSubscriptions != -1 &&
-            service->TotalSubscriptions > handle_info->MaxSubscriptions ) {
-        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
-        RemoveSubscriptionSID( sub->sid, service );
-        HandleUnlock(  );
-        return;
-    }
-    // set the timeout
-    if( httpmsg_find_hdr( request, HDR_TIMEOUT, &timeout_hdr ) != NULL ) {
-        if( matchstr( timeout_hdr.buf, timeout_hdr.length,
-                      "%iSecond-%d%0", &time_out ) == PARSE_OK ) {
-
-            //nothing
-
-        } else if( memptr_cmp_nocase( &timeout_hdr, "Second-infinite" ) ==
-                   0 ) {
-
-            time_out = -1;      // inifinite timeout
-
-        } else {
-            time_out = DEFAULT_TIMEOUT; // default is > 1800 seconds
-
-        }
-    }
-
-    // replace infinite timeout with max timeout, if possible
-    if( handle_info->MaxSubscriptionTimeOut != -1 ) {
-        if( time_out == -1 ||
-            time_out > handle_info->MaxSubscriptionTimeOut ) {
-            time_out = handle_info->MaxSubscriptionTimeOut;
-        }
-    }
-
-    if( time_out == -1 ) {
-        sub->expireTime = 0;
-    } else {
-        sub->expireTime = time( NULL ) + time_out;
-    }
-
-    if( respond_ok( info, time_out, sub, request ) != UPNP_E_SUCCESS ) {
-        RemoveSubscriptionSID( sub->sid, service );
-    }
-
-    HandleUnlock(  );
-}
-
-/****************************************************************************
-*	Function :	gena_process_unsubscribe_request
-*
-*	Parameters :
-*			IN SOCKINFO *info :	socket info of the device
-*			IN http_message_t* request : UNSUBSCRIBE request from the control 
-*											point
-*
-*	Description : This function Handles a subscription cancellation request 
-*		from a ctrl point. The connection is not destroyed on return.
-*
-*	Return :	void
-*
-*	Note :
-****************************************************************************/
-void
-gena_process_unsubscribe_request( IN SOCKINFO * info,
-                                  IN http_message_t * request )
-{
-    Upnp_SID sid;
-    service_info *service;
-    struct Handle_Info *handle_info;
-    UpnpDevice_Handle device_handle;
-
-    memptr temp_hdr;
-    membuffer event_url_path;
-
-    // if a CALLBACK or NT header is present, then it is an error
-    if( httpmsg_find_hdr( request, HDR_CALLBACK, NULL ) != NULL ||
-        httpmsg_find_hdr( request, HDR_NT, NULL ) != NULL ) {
-        error_respond( info, HTTP_BAD_REQUEST, request );
-        return;
-    }
-    // get SID
-    if( httpmsg_find_hdr( request, HDR_SID, &temp_hdr ) == NULL ||
-        temp_hdr.length > SID_SIZE ) {
-        error_respond( info, HTTP_PRECONDITION_FAILED, request );
-        return;
-    }
-    memcpy( sid, temp_hdr.buf, temp_hdr.length );
-    sid[temp_hdr.length] = '\0';
-
-    // lookup service by eventURL
-    membuffer_init( &event_url_path );
-    if( membuffer_append( &event_url_path, request->uri.pathquery.buff,
-                          request->uri.pathquery.size ) != 0 ) {
-        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
-        return;
-    }
-
-    HandleLock(  );
-
-    // CURRENTLY, ONLY SUPPORT ONE DEVICE
-    if( GetDeviceHandleInfo( &device_handle, &handle_info ) != HND_DEVICE ) {
-        error_respond( info, HTTP_PRECONDITION_FAILED, request );
-        membuffer_destroy( &event_url_path );
-        HandleUnlock(  );
-        return;
-    }
-    service = FindServiceEventURLPath( &handle_info->ServiceTable,
-                                       event_url_path.buf );
-    membuffer_destroy( &event_url_path );
-
-    // validate service
-    if( service == NULL ||
-        !service->active || GetSubscriptionSID( sid, service ) == NULL )
-        //CheckSubscriptionSID(sid, service) == NULL )
-    {
-        error_respond( info, HTTP_PRECONDITION_FAILED, request );
-        HandleUnlock(  );
-        return;
-    }
-
-    RemoveSubscriptionSID( sid, service );
-    error_respond( info, HTTP_OK, request );    // success
-
-    HandleUnlock(  );
-}
-
-#endif // INCLUDE_DEVICE_APIS
-#endif // EXCLUDE_GENA
diff --git a/tombupnp/upnp/src/genlib/client_table/client_table.c b/tombupnp/upnp/src/genlib/client_table/client_table.c
deleted file mode 100644
index 90ba978..0000000
--- a/tombupnp/upnp/src/genlib/client_table/client_table.c
+++ /dev/null
@@ -1,212 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-/************************************************************************
-* Purpose: This file defines the functions for clients. It defines 
-* functions for adding and removing clients to and from the client table, 
-* adding and accessing subscription and other attributes pertaining to the 
-* client  
-************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-#include "config.h"
-#include "client_table.h"
-
-/************************************************************************
-*	Function :	copy_client_subscription
-*
-*	Parameters :
-*		client_subscription * in ;	- source client subscription
-*		client_subscription * out ;	- destination client subscription
-*
-*	Description :	Make a copy of the client subscription data
-*
-*	Return : int ;
-*		UPNP_E_OUTOF_MEMORY - On Failure to allocate memory
-*		HTTP_SUCCESS - On Success
-*
-*	Note :
-************************************************************************/
-CLIENTONLY( int copy_client_subscription( client_subscription * in,
-                                          client_subscription * out ) {
-            int len = strlen( in->ActualSID ) + 1;
-            int len1 = strlen( in->EventURL ) + 1;
-            memcpy( out->sid, in->sid, SID_SIZE );
-            out->sid[SID_SIZE] = 0;
-            out->ActualSID = ( char * )malloc( len );
-            if( out->ActualSID == NULL )
-                return UPNP_E_OUTOF_MEMORY;
-            out->EventURL = ( char * )malloc( len1 );
-            if( out->EventURL == NULL ) {
-                free(out->ActualSID);
-                return UPNP_E_OUTOF_MEMORY;
-            }
-            memcpy( out->ActualSID, in->ActualSID, len );
-            memcpy( out->EventURL, in->EventURL, len1 );
-            //copies do not get RenewEvent Ids or next
-            out->RenewEventId = -1; out->next = NULL; return HTTP_SUCCESS;}
-
-/************************************************************************
-*	Function :	free_client_subscription
-*
-*	Parameters :
-*		client_subscription * sub ;	- Client subscription to be freed
-*
-*	Description :	Free memory allocated for client subscription data.
-*		Remove timer thread associated with this subscription event.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-            void free_client_subscription( client_subscription * sub ) {
-            upnp_timeout * event; ThreadPoolJob tempJob; if( sub ) {
-            if( sub->ActualSID )
-            free( sub->ActualSID ); if( sub->EventURL )
-            free( sub->EventURL ); if( sub->RenewEventId != -1 )    //do not remove timer event of copy
-            //invalid timer event id
-            {
-            if( TimerThreadRemove
-                ( &gTimerThread, sub->RenewEventId, &tempJob ) == 0 ) {
-            event = ( upnp_timeout * ) tempJob.arg;
-            free_upnp_timeout( event );}
-            }
-
-            sub->RenewEventId = -1;}
-            }
-
-/************************************************************************
-*	Function :	freeClientSubList
-*
-*	Parameters :
-*		client_subscription * list ; Client subscription 
-*
-*	Description :	Free the client subscription table.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-            void freeClientSubList( client_subscription * list ) {
-            client_subscription * next; while( list ) {
-            free_client_subscription( list );
-            next = list->next; free( list ); list = next;}
-            }
-
-/************************************************************************
-*	Function :	RemoveClientSubClientSID
-*
-*	Parameters :
-*		client_subscription **head ; Head of the subscription list	
-*		const Upnp_SID sid ;		 Subscription ID to be mactched
-*
-*	Description :	Remove the client subscription matching the 
-*		subscritpion id represented by the const Upnp_SID sid parameter 
-*		from the table and update the table.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-            void RemoveClientSubClientSID( client_subscription ** head,
-                                           const Upnp_SID sid ) {
-            client_subscription * finger = ( *head );
-            client_subscription * previous = NULL; while( finger ) {
-            if( !( strcmp( sid, finger->sid ) ) ) {
-            if( previous )
-            previous->next = finger->next;
-            else
-            ( *head ) = finger->next;
-            finger->next = NULL;
-            freeClientSubList( finger ); finger = NULL;}
-            else
-            {
-            previous = finger; finger = finger->next;}
-            }
-            }
-
-/************************************************************************
-*	Function :	GetClientSubClientSID
-*
-*	Parameters :
-*		client_subscription *head ; Head of the subscription list	
-*		const Upnp_SID sid ;		Subscription ID to be matched
-*
-*	Description :	Return the client subscription from the client table 
-*		that matches const Upnp_SID sid subscrition id value. 
-*
-*	Return : client_subscription * ; The matching subscription
-*
-*	Note :
-************************************************************************/
-            client_subscription *
-            GetClientSubClientSID( client_subscription * head,
-                                   const Upnp_SID sid ) {
-            client_subscription * next = head; while( next ) {
-            if( !strcmp( next->sid, sid ) )
-            break;
-            else
-            {
-            next = next->next;}
-            }
-            return next;}
-
-/************************************************************************
-*	Function :	GetClientSubActualSID
-*
-*	Parameters :
-*		client_subscription *head ;	Head of the subscription list		
-*		token * sid ;				Subscription ID to be matched
-*
-*	Description :	Returns the client subscription from the client 
-*		subscription table that has the matching token * sid buffer
-*		value.
-*
-*	Return : client_subscription * ; The matching subscription
-*
-*	Note :
-************************************************************************/
-            client_subscription *
-            GetClientSubActualSID( client_subscription * head,
-                                   token * sid ) {
-            client_subscription * next = head; while( next ) {
-
-            if( !memcmp( next->ActualSID, sid->buff, sid->size ) )
-            break;
-            else
-            {
-            next = next->next;}
-            }
-            return next;}
-
- )
diff --git a/tombupnp/upnp/src/genlib/miniserver/miniserver.c b/tombupnp/upnp/src/genlib/miniserver/miniserver.c
deleted file mode 100644
index 12d76e5..0000000
--- a/tombupnp/upnp/src/genlib/miniserver/miniserver.c
+++ /dev/null
@@ -1,967 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/************************************************************************
-* Purpose: This file implements the functionality and utility functions
-* used by the Miniserver module.
-************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#ifndef WIN32
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <sys/socket.h>
- #include <sys/wait.h>
- #include <unistd.h>
- #include <sys/time.h>
-#else
- #include <winsock2.h>
-
- typedef int socklen_t;
- #define EAFNOSUPPORT 97
-#endif
-#include "unixutil.h"
-#include "ithread.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "ssdplib.h"
-
-#include "util.h"
-#include "miniserver.h"
-#include "ThreadPool.h"
-#include "httpreadwrite.h"
-#include "statcodes.h"
-#include "upnp.h"
-#include "upnpapi.h"
-
-#define APPLICATION_LISTENING_PORT 49152
-
-struct mserv_request_t {
-    int connfd;                 // connection handle
-    struct in_addr foreign_ip_addr;
-    unsigned short foreign_ip_port;
-};
-
-typedef enum { MSERV_IDLE, MSERV_RUNNING, MSERV_STOPPING } MiniServerState;
-
-unsigned short miniStopSockPort;
-
-////////////////////////////////////////////////////////////////////////////
-// module vars
-static MiniServerCallback gGetCallback = NULL;
-static MiniServerCallback gSoapCallback = NULL;
-static MiniServerCallback gGenaCallback = NULL;
-static MiniServerState gMServState = MSERV_IDLE;
-
-/************************************************************************
-*	Function :	SetHTTPGetCallback
-*
-*	Parameters :
-*		MiniServerCallback callback ; - HTTP Callback to be invoked 
-*
-*	Description :	Set HTTP Get Callback
-*
-*	Return :	void
-*
-*	Note :
-************************************************************************/
-void
-SetHTTPGetCallback( MiniServerCallback callback )
-{
-    gGetCallback = callback;
-}
-
-/************************************************************************
-*	Function :	SetSoapCallback
-*
-*	Parameters :
-*		MiniServerCallback callback ; - SOAP Callback to be invoked 
-*
-*	Description :	Set SOAP Callback
-*
-*	Return :	void
-*
-*	Note :
-************************************************************************/
-void
-SetSoapCallback( MiniServerCallback callback )
-{
-    gSoapCallback = callback;
-}
-
-/************************************************************************
-*	Function :	SetGenaCallback
-*
-*	Parameters :
-*		MiniServerCallback callback ; - GENA Callback to be invoked
-*
-*	Description :	Set GENA Callback
-*
-*	Return :	void
-*
-*	Note :
-************************************************************************/
-void
-SetGenaCallback( MiniServerCallback callback )
-{
-    gGenaCallback = callback;
-}
-
-/************************************************************************
-*	Function :	dispatch_request
-*
-*	Parameters :
-*		IN SOCKINFO *info ;		 Socket Information object.
-*		http_parser_t* hparser ; HTTP parser object.
-*
-*	Description :	Based on the type pf message, appropriate callback 
-*		is issued
-*
-*	Return : int ;
-*		0 - On Success
-*		HTTP_INTERNAL_SERVER_ERROR - Callback is NULL
-*
-*	Note :
-************************************************************************/
-static int
-dispatch_request( IN SOCKINFO * info,
-                  http_parser_t * hparser )
-{
-    MiniServerCallback callback;
-    int error_code;
-
-    switch ( hparser->msg.method ) {
-            //Soap Call
-        case SOAPMETHOD_POST:
-        case HTTPMETHOD_MPOST:
-            callback = gSoapCallback;
-            break;
-
-            //Gena Call
-        case HTTPMETHOD_NOTIFY:
-        case HTTPMETHOD_SUBSCRIBE:
-        case HTTPMETHOD_UNSUBSCRIBE:
-            DBGONLY( UpnpPrintf
-                     ( UPNP_INFO, MSERV, __FILE__, __LINE__,
-                       "miniserver %d: got GENA msg\n", info->socket );
-                 )
-                callback = gGenaCallback;
-            break;
-
-            //HTTP server call
-        case HTTPMETHOD_GET:
-        case HTTPMETHOD_POST:
-        case HTTPMETHOD_HEAD:
-        case HTTPMETHOD_SIMPLEGET:
-            error_code = fcntl(info->socket, F_SETFL, O_NONBLOCK);
-            if (error_code < 0)
-            {
-                DBGONLY( UpnpPrintf
-                     ( UPNP_INFO, MSERV, __FILE__, __LINE__,
-                       "miniserver %d: setting NONBLOCK mode on socket failed\n", info->socket );
-                 )
-
-            }
-            callback = gGetCallback;
-            break;
-
-        default:
-            callback = NULL;
-    }
-
-    if( callback == NULL ) {
-        return HTTP_INTERNAL_SERVER_ERROR;
-    }
-
-    callback( hparser, &hparser->msg, info );
-    return 0;
-}
-
-/************************************************************************
-*	Function :	handle_error
-*
-*	Parameters :
-*		
-*		IN SOCKINFO *info ;		Socket Inforamtion Object
-*		int http_error_code ;	HTTP Error Code
-*		int major ;				Major Version Number
-*		int minor ;				Minor Version Number
-*
-*	Description :	Send Error Message
-*
-*	Return : void;
-*
-*	Note :
-************************************************************************/
-static XINLINE void
-handle_error( IN SOCKINFO * info,
-              int http_error_code,
-              int major,
-              int minor )
-{
-    http_SendStatusResponse( info, http_error_code, major, minor );
-}
-
-/************************************************************************
-*	Function :	free_handle_request_arg
-*
-*	Parameters :
-*		void *args ; Request Message to be freed
-*
-*	Description :	Free memory assigned for handling request and unitial-
-*	-ize socket functionality
-*
-*	Return :	void
-*
-*	Note :
-************************************************************************/
-static void
-free_handle_request_arg( void *args )
-{
-    struct mserv_request_t *request = ( struct mserv_request_t * )args;
-
-    shutdown( request->connfd, SD_BOTH );
-    UpnpCloseSocket( request->connfd );
-    free( request );
-}
-
-/************************************************************************
-*	Function :	handle_request
-*
-*	Parameters :
-*		void *args ;	Request Message to be handled
-*
-*	Description :	Receive the request and dispatch it for handling
-*
-*	Return :	void
-*
-*	Note :
-************************************************************************/
-static void
-handle_request( void *args )
-{
-    SOCKINFO info;
-    int http_error_code;
-    int ret_code;
-    int major = 1;
-    int minor = 1;
-    http_parser_t parser;
-    http_message_t *hmsg = NULL;
-    int timeout = HTTP_DEFAULT_TIMEOUT;
-    struct mserv_request_t *request = ( struct mserv_request_t * )args;
-    int connfd = request->connfd;
-
-    DBGONLY( UpnpPrintf
-             ( UPNP_INFO, MSERV, __FILE__, __LINE__,
-               "miniserver %d: READING\n", connfd );
-         )
-        //parser_request_init( &parser ); ////LEAK_FIX_MK
-        hmsg = &parser.msg;
-
-    if( sock_init_with_ip( &info, connfd, request->foreign_ip_addr,
-                           request->foreign_ip_port ) != UPNP_E_SUCCESS ) {
-        free( request );
-        httpmsg_destroy( hmsg );
-        return;
-    }
-    // read
-    ret_code = http_RecvMessage( &info, &parser, HTTPMETHOD_UNKNOWN,
-                                 &timeout, &http_error_code );
-    if( ret_code != 0 ) {
-        goto error_handler;
-    }
-
-    DBGONLY( UpnpPrintf
-             ( UPNP_INFO, MSERV, __FILE__, __LINE__,
-               "miniserver %d: PROCESSING...\n", connfd );
-         )
-        // dispatch
-        http_error_code = dispatch_request( &info, &parser );
-    if( http_error_code != 0 ) {
-        goto error_handler;
-    }
-
-    http_error_code = 0;
-
-  error_handler:
-    if( http_error_code > 0 ) {
-        if( hmsg ) {
-            major = hmsg->major_version;
-            minor = hmsg->minor_version;
-        }
-        handle_error( &info, http_error_code, major, minor );
-    }
-
-    DBGONLY( UpnpPrintf
-             ( UPNP_INFO, MSERV, __FILE__, __LINE__,
-               "miniserver %d: COMPLETE\n", connfd );
-         )
-        sock_destroy( &info, SD_BOTH ); //should shutdown completely
-
-    httpmsg_destroy( hmsg );
-    free( request );
-}
-
-/************************************************************************
-*	Function :	schedule_request_job
-*
-*	Parameters :
-*		IN int connfd ;	Socket Descriptor on which connection is accepted
-*		IN struct sockaddr_in* clientAddr ;	Clients Address information
-*
-*	Description :	Initilize the thread pool to handle a request.
-*		Sets priority for the job and adds the job to the thread pool
-*
-*
-*	Return :	void
-*
-*	Note :
-************************************************************************/
-static XINLINE void
-schedule_request_job( IN int connfd,
-                      IN struct sockaddr_in *clientAddr )
-{
-    struct mserv_request_t *request;
-    ThreadPoolJob job;
-
-    request =
-        ( struct mserv_request_t * )
-        malloc( sizeof( struct mserv_request_t ) );
-    if( request == NULL ) {
-        DBGONLY( UpnpPrintf
-                 ( UPNP_INFO, MSERV, __FILE__, __LINE__,
-                   "mserv %d: out of memory\n", connfd );
-             )
-            shutdown( request->connfd, SD_BOTH );
-        UpnpCloseSocket( connfd );
-        return;
-    }
-
-    request->connfd = connfd;
-    request->foreign_ip_addr = clientAddr->sin_addr;
-    request->foreign_ip_port = ntohs( clientAddr->sin_port );
-
-    TPJobInit( &job, ( start_routine ) handle_request, ( void * )request );
-    TPJobSetFreeFunction( &job, free_handle_request_arg );
-    TPJobSetPriority( &job, MED_PRIORITY );
-
-    if( ThreadPoolAdd( &gRecvThreadPool, &job, NULL ) != 0 ) {
-        DBGONLY( UpnpPrintf
-                 ( UPNP_INFO, MSERV, __FILE__, __LINE__,
-                   "mserv %d: cannot schedule request\n", connfd );
-             )
-            free( request );
-        shutdown( connfd, SD_BOTH );
-        UpnpCloseSocket( connfd );
-        return;
-    }
-
-}
-
-/************************************************************************
-*	Function :	RunMiniServer
-*
-*	Parameters :
-*		MiniServerSockArray *miniSock ;	Socket Array
-*
-*	Description :	Function runs the miniserver. The MiniServer accepts a 
-*		new request and schedules a thread to handle the new request.
-*		Checks for socket state and invokes appropriate read and shutdown 
-*		actions for the Miniserver and SSDP sockets 
-*
-*	Return :	void
-*
-*	Note :
-************************************************************************/
-static void
-RunMiniServer( MiniServerSockArray * miniSock )
-{
-    struct sockaddr_in clientAddr;
-    socklen_t clientLen;
-    SOCKET miniServSock,
-      connectHnd;
-    SOCKET miniServStopSock;
-    SOCKET ssdpSock;
-
-    CLIENTONLY( SOCKET ssdpReqSock;
-         )
-
-    fd_set expSet;
-    fd_set rdSet;
-    unsigned int maxMiniSock;
-    int byteReceived;
-    char requestBuf[256];
-
-    miniServSock = miniSock->miniServerSock;
-    miniServStopSock = miniSock->miniServerStopSock;
-
-    ssdpSock = miniSock->ssdpSock;
-
-    CLIENTONLY( ssdpReqSock = miniSock->ssdpReqSock;
-         );
-
-    gMServState = MSERV_RUNNING;
-    maxMiniSock = max( miniServSock, miniServStopSock );
-    maxMiniSock = max( maxMiniSock, ( SOCKET ) ( ssdpSock ) );
-
-    CLIENTONLY( maxMiniSock =
-                max( maxMiniSock, ( SOCKET ) ( ssdpReqSock ) ) );
-
-    ++maxMiniSock;
-
-    while( TRUE ) {
-        FD_ZERO( &rdSet );
-        FD_ZERO( &expSet );
-
-        FD_SET( miniServStopSock, &expSet );
-
-        FD_SET( miniServSock, &rdSet );
-        FD_SET( miniServStopSock, &rdSet );
-        FD_SET( ssdpSock, &rdSet );
-        CLIENTONLY( FD_SET( ssdpReqSock, &rdSet ) );
-
-        if( select( maxMiniSock, &rdSet, NULL, &expSet, NULL ) ==
-            UPNP_SOCKETERROR ) {
-            DBGONLY( UpnpPrintf
-                     ( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
-                       "Error in select call !!!\n" );
-                 )
-                continue;
-        } else {
-
-            if( FD_ISSET( miniServSock, &rdSet ) ) {
-                clientLen = sizeof( struct sockaddr_in );
-                connectHnd = accept( miniServSock,
-                                     ( struct sockaddr * )&clientAddr,
-                                     &clientLen );
-                if( connectHnd == UPNP_INVALID_SOCKET ) {
-                    DBGONLY( UpnpPrintf
-                             ( UPNP_INFO, MSERV, __FILE__, __LINE__,
-                               "miniserver: Error"
-                               " in accepting connection\n" );
-                         )
-                        continue;
-                }
-                schedule_request_job( connectHnd, &clientAddr );
-            }
-            //ssdp
-            CLIENTONLY( if( FD_ISSET( ssdpReqSock, &rdSet ) ) {
-
-                        readFromSSDPSocket( ssdpReqSock );}
-             )
-
-                if( FD_ISSET( ssdpSock, &rdSet ) ) {
-                    readFromSSDPSocket( ssdpSock );
-                }
-
-            if( FD_ISSET( miniServStopSock, &rdSet ) ) {
-
-                clientLen = sizeof( struct sockaddr_in );
-                memset( ( char * )&clientAddr, 0,
-                        sizeof( struct sockaddr_in ) );
-                byteReceived =
-                    recvfrom( miniServStopSock, requestBuf, 25, 0,
-                              ( struct sockaddr * )&clientAddr,
-                              &clientLen );
-                if( byteReceived > 0 ) {
-                    requestBuf[byteReceived] = '\0';
-                    DBGONLY( UpnpPrintf
-                             ( UPNP_INFO, MSERV, __FILE__, __LINE__,
-                               "Received response !!!  %s From host %s \n",
-                               requestBuf,
-                               inet_ntoa( clientAddr.sin_addr ) );
-                         )
-                        DBGONLY( UpnpPrintf
-                                 ( UPNP_PACKET, MSERV, __FILE__, __LINE__,
-                                   "Received multicast packet: \n %s\n",
-                                   requestBuf );
-                         )
-
-                        if( NULL != strstr( requestBuf, "ShutDown" ) )
-                        break;
-                }
-            }
-        }
-
-    }
-
-    shutdown( miniServSock, SD_BOTH );
-    UpnpCloseSocket( miniServSock );
-    shutdown( miniServStopSock, SD_BOTH );
-    UpnpCloseSocket( miniServStopSock );
-    shutdown( ssdpSock, SD_BOTH );
-    UpnpCloseSocket( ssdpSock );
-    CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );
-    CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );
-
-    free( miniSock );
-
-    gMServState = MSERV_IDLE;
-
-    return;
-
-}
-
-/************************************************************************
-*	Function :	get_port
-*
-*	Parameters :
-*		int sockfd ; Socket Descriptor 
-*
-*	Description :	Returns port to which socket, sockfd, is bound.
-*
-*	Return :	int, 
-*		-1 on error; check errno
-*		 > 0 means port number
-*
-*	Note :
-************************************************************************/
-static int
-get_port( int sockfd )
-{
-    struct sockaddr_in sockinfo;
-    socklen_t len;
-    int code;
-    int port;
-
-    len = sizeof( struct sockaddr_in );
-    code = getsockname( sockfd, ( struct sockaddr * )&sockinfo, &len );
-    if( code == -1 ) {
-        return -1;
-    }
-
-    port = ntohs( sockinfo.sin_port );
-    DBGONLY( UpnpPrintf
-             ( UPNP_INFO, MSERV, __FILE__, __LINE__,
-               "sockfd = %d, .... port = %d\n", sockfd, port );
-         )
-
-        return port;
-}
-
-/************************************************************************
-*	Function :	get_miniserver_sockets
-*
-*	Parameters :
-*		MiniServerSockArray *out ;	Socket Array
-*		unsigned short listen_port ; port on which the server is listening 
-*									for incoming connections	
-*
-*	Description :	Creates a STREAM socket, binds to INADDR_ANY and 
-*		listens for incoming connecttions. Returns the actual port which 
-*		the sockets sub-system returned. 
-*		Also creates a DGRAM socket, binds to the loop back address and 
-*		returns the port allocated by the socket sub-system.
-*
-*	Return :	int : 
-*		UPNP_E_OUTOF_SOCKET - Failed to create a socket
-*		UPNP_E_SOCKET_BIND - Bind() failed
-*		UPNP_E_LISTEN	- Listen() failed	
-*		UPNP_E_INTERNAL_ERROR - Port returned by the socket layer is < 0
-*		UPNP_E_SUCCESS	- Success
-*		
-*	Note :
-************************************************************************/
-int
-get_miniserver_sockets( MiniServerSockArray * out,
-                        unsigned short listen_port )
-{
-    struct sockaddr_in serverAddr;
-    int listenfd;
-    int success;
-    unsigned short actual_port;
-    // Jin: we want to use the reuseaddr option so the server stays on
-    // the same port
-    int reuseaddr_on = 1;
-    int sockError = UPNP_E_SUCCESS;
-    int errCode = 0;
-    int miniServerStopSock;
-
-    listenfd = socket( AF_INET, SOCK_STREAM, 0 );
-    if( listenfd < 0 ) {
-        return UPNP_E_OUTOF_SOCKET; // error creating socket
-    }
-
-#if defined (SO_NOSIGPIPE)
-    sockError = setsockopt( listenfd,
-            SOL_SOCKET,
-            SO_NOSIGPIPE,
-            ( const char * )&reuseaddr_on,
-            sizeof( int )
-            );
-
-    if( sockError == UPNP_SOCKETERROR ) {
-        shutdown( listenfd, SD_BOTH );
-        UpnpCloseSocket( listenfd );
-        return UPNP_E_SOCKET_BIND;
-    }
-#endif
-
-
-    // As per the IANA specifications for the use of ports by applications
-    // override the listen port passed in with the first available 
-    
-    // Jin: nothing against IANA, but... :>
-    if( listen_port == 0 )
-    {
-        listen_port = APPLICATION_LISTENING_PORT;
-        reuseaddr_on = 0;
-    }
-
-    memset( &serverAddr, 0, sizeof( serverAddr ) );
-    serverAddr.sin_family = AF_INET;
-    serverAddr.sin_addr.s_addr = htonl( INADDR_ANY );
-
-    // Getting away with implementation of re-using address:port and instead 
-    // choosing to increment port numbers.
-    // Keeping the re-use address code as an optional behaviour that can be 
-    // turned on if necessary. 
-    // TURN ON the reuseaddr_on option to use the option.
-    if( reuseaddr_on ) {
-        //THIS IS ALLOWS US TO BIND AGAIN IMMEDIATELY
-        //AFTER OUR SERVER HAS BEEN CLOSED
-        //THIS MAY CAUSE TCP TO BECOME LESS RELIABLE
-        //HOWEVER IT HAS BEEN SUGESTED FOR TCP SERVERS
-
-        DBGONLY( UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
-                             "mserv start: resuseaddr set\n" );
-             )
-            sockError = setsockopt( listenfd,
-                                    SOL_SOCKET,
-                                    SO_REUSEADDR,
-                                    ( const char * )&reuseaddr_on,
-                                    sizeof( int )
-             );
-
-        if( sockError == UPNP_SOCKETERROR ) {
-            shutdown( listenfd, SD_BOTH );
-            UpnpCloseSocket( listenfd );
-            return UPNP_E_SOCKET_BIND;
-        }
-
-        serverAddr.sin_port = htons( listen_port );
-        
-        sockError = bind( listenfd,
-                          ( struct sockaddr * )&serverAddr,
-                          sizeof( struct sockaddr_in )
-             );
-         DBGONLY( UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
-                             "mserv start: bind returned %s (%d)\n", 
-                             strerror(errno), sockError );
-             )
-    } else {
-        do {
-            serverAddr.sin_port = htons( listen_port++ );
-            sockError = bind( listenfd,
-                              ( struct sockaddr * )&serverAddr,
-                              sizeof( struct sockaddr_in )
-                 );
-            if( sockError == UPNP_SOCKETERROR ) {
-#ifdef WIN32
-				errCode = WSAGetLastError();
-#else
-				errCode = errno; 
-#endif
-                if( errno == EADDRINUSE )
-                    errCode = 1;
-            } else
-                errCode = 0;
-
-        } while( errCode != 0 );
-    }
-
-    if( sockError == UPNP_SOCKETERROR ) {
-        DBGONLY( perror( "mserv start: bind failed" );
-             )
-            shutdown( listenfd, SD_BOTH );
-        UpnpCloseSocket( listenfd );
-        return UPNP_E_SOCKET_BIND;  // bind failed
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
-                         "mserv start: bind success\n" );
-         )
-
-        success = listen( listenfd, SOMAXCONN );
-    if( success == UPNP_SOCKETERROR ) {
-        shutdown( listenfd, SD_BOTH );
-        UpnpCloseSocket( listenfd );
-        return UPNP_E_LISTEN;   // listen failed
-    }
-
-    actual_port = get_port( listenfd );
-    if( actual_port <= 0 ) {
-        shutdown( listenfd, SD_BOTH );
-        UpnpCloseSocket( listenfd );
-        return UPNP_E_INTERNAL_ERROR;
-    }
-
-    out->miniServerPort = actual_port;
-
-    if( ( miniServerStopSock = socket( AF_INET, SOCK_DGRAM, 0 ) ) ==
-        UPNP_INVALID_SOCKET ) {
-        DBGONLY( UpnpPrintf( UPNP_CRITICAL,
-                             MSERV, __FILE__, __LINE__,
-                             "Error in socket operation !!!\n" );
-             )
-            shutdown( listenfd, SD_BOTH );
-        UpnpCloseSocket( listenfd );
-        return UPNP_E_OUTOF_SOCKET;
-    }
-
-    // bind to local socket
-    memset( ( char * )&serverAddr, 0, sizeof( struct sockaddr_in ) );
-    serverAddr.sin_family = AF_INET;
-    serverAddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
-
-    if( bind( miniServerStopSock, ( struct sockaddr * )&serverAddr,
-              sizeof( serverAddr ) ) == UPNP_SOCKETERROR ) {
-
-        DBGONLY( UpnpPrintf( UPNP_CRITICAL,
-                             MSERV, __FILE__, __LINE__,
-                             "Error in binding localhost!!!\n" );
-             )
-            shutdown( listenfd, SD_BOTH );
-        UpnpCloseSocket( listenfd );
-        shutdown( miniServerStopSock, SD_BOTH );
-        UpnpCloseSocket( miniServerStopSock );
-        return UPNP_E_SOCKET_BIND;
-    }
-
-    miniStopSockPort = get_port( miniServerStopSock );
-    if( miniStopSockPort <= 0 ) {
-        shutdown( miniServerStopSock, SD_BOTH );
-        shutdown( listenfd, SD_BOTH );
-        UpnpCloseSocket( miniServerStopSock );
-        UpnpCloseSocket( listenfd );
-        return UPNP_E_INTERNAL_ERROR;
-    }
-
-    out->stopPort = miniStopSockPort;
-
-    out->miniServerSock = listenfd;
-    out->miniServerStopSock = miniServerStopSock;
-
-    return UPNP_E_SUCCESS;
-
-}
-
-/************************************************************************
-*	Function :	StartMiniServer
-*
-*	Parameters :
-*		unsigned short listen_port ; Port on which the server listens for 
-*									incoming connections
-*
-*	Description :	Initialize the sockets functionality for the 
-*		Miniserver. Initialize a thread pool job to run the MiniServer
-*		and the job to the thread pool. If listen port is 0, port is 
-*		dynamically picked
-*
-*		Use timer mechanism to start the MiniServer, failure to meet the 
-*		allowed delay aborts the attempt to launch the MiniServer.
-*
-*	Return : int ;
-*		Actual port socket is bound to - On Success: 
-*		A negative number UPNP_E_XXX - On Error   			
-*	Note :
-************************************************************************/
-int
-StartMiniServer( unsigned short listen_port )
-{
-
-    int success;
-
-    int count;
-    int max_count = 10000;
-
-    MiniServerSockArray *miniSocket;
-    ThreadPoolJob job;
-
-    if( gMServState != MSERV_IDLE ) {
-        return UPNP_E_INTERNAL_ERROR;   // miniserver running
-    }
-
-    miniSocket =
-        ( MiniServerSockArray * ) malloc( sizeof( MiniServerSockArray ) );
-    if( miniSocket == NULL )
-        return UPNP_E_OUTOF_MEMORY;
-
-    if( ( success = get_miniserver_sockets( miniSocket, listen_port ) )
-        != UPNP_E_SUCCESS ) {
-        free( miniSocket );
-        return success;
-    }
-
-    if( ( success = get_ssdp_sockets( miniSocket ) ) != UPNP_E_SUCCESS ) {
-
-        shutdown( miniSocket->miniServerSock, SD_BOTH );
-        UpnpCloseSocket( miniSocket->miniServerSock );
-        shutdown( miniSocket->miniServerStopSock, SD_BOTH );
-        UpnpCloseSocket( miniSocket->miniServerStopSock );
-
-        free( miniSocket );
-
-        return success;
-    }
-
-    TPJobInit( &job, ( start_routine ) RunMiniServer,
-               ( void * )miniSocket );
-    TPJobSetPriority( &job, MED_PRIORITY );
-
-    TPJobSetFreeFunction( &job, ( free_routine ) free );
-
-    success = ThreadPoolAddPersistent( &gRecvThreadPool, &job, NULL );
-
-    if( success < 0 ) {
-        shutdown( miniSocket->miniServerSock, SD_BOTH );
-        shutdown( miniSocket->miniServerStopSock, SD_BOTH );
-        shutdown( miniSocket->ssdpSock, SD_BOTH );
-        CLIENTONLY( shutdown( miniSocket->ssdpReqSock, SD_BOTH ) );
-        UpnpCloseSocket( miniSocket->miniServerSock );
-        UpnpCloseSocket( miniSocket->miniServerStopSock );
-        UpnpCloseSocket( miniSocket->ssdpSock );
-
-        CLIENTONLY( UpnpCloseSocket( miniSocket->ssdpReqSock ) );
-        free(miniSocket);
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    // wait for miniserver to start
-    count = 0;
-    while( gMServState != MSERV_RUNNING && count < max_count ) {
-        usleep( 50 * 1000 );    // 0.05s
-        count++;
-    }
-
-    // taking too long to start that thread
-    if( count >= max_count ) {
-
-        shutdown( miniSocket->miniServerSock, SD_BOTH );
-        shutdown( miniSocket->miniServerStopSock, SD_BOTH );
-        shutdown( miniSocket->ssdpSock, SD_BOTH );
-        CLIENTONLY( shutdown( miniSocket->ssdpReqSock, SD_BOTH ) );
-
-        UpnpCloseSocket( miniSocket->miniServerSock );
-        UpnpCloseSocket( miniSocket->miniServerStopSock );
-        UpnpCloseSocket( miniSocket->ssdpSock );
-        CLIENTONLY( UpnpCloseSocket( miniSocket->ssdpReqSock ) );
-        free(miniSocket);
-        return UPNP_E_INTERNAL_ERROR;
-    }
-
-    return miniSocket->miniServerPort;
-}
-
-/************************************************************************
-*	Function :	StopMiniServer
-*
-*	Parameters :
-*		void ;	
-*
-*	Description :	Stop and Shutdown the MiniServer and free socket 
-*		resources.
-*
-*	Return : int ;
-*		Always returns 0 
-*
-*	Note :
-************************************************************************/
-int
-StopMiniServer( void )
-{
-
-    int socklen = sizeof( struct sockaddr_in ),
-      sock;
-    struct sockaddr_in ssdpAddr;
-    char buf[256] = "ShutDown";
-    int bufLen = strlen( buf );
-
-    if( gMServState == MSERV_RUNNING )
-        gMServState = MSERV_STOPPING;
-    else
-        return 0;
-
-    sock = socket( AF_INET, SOCK_DGRAM, 0 );
-    if( sock == UPNP_INVALID_SOCKET ) {
-        DBGONLY( UpnpPrintf
-                 ( UPNP_INFO, SSDP, __FILE__, __LINE__,
-                   "SSDP_SERVER:StopSSDPServer: Error in socket operation !!!\n" );
-             )
-            return 0;
-    }
-
-    while( gMServState != MSERV_IDLE ) {
-        ssdpAddr.sin_family = AF_INET;
-        ssdpAddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
-        ssdpAddr.sin_port = htons( miniStopSockPort );
-        sendto( sock, buf, bufLen, 0, ( struct sockaddr * )&ssdpAddr,
-                socklen );
-        usleep( 1000 );
-        if( gMServState == MSERV_IDLE )
-            break;
-        isleep( 1 );
-    }
-    shutdown( sock, SD_BOTH );
-    UpnpCloseSocket( sock );
-    return 0;
-}
diff --git a/tombupnp/upnp/src/genlib/net/http/httpparser.c b/tombupnp/upnp/src/genlib/net/http/httpparser.c
deleted file mode 100644
index 7ae5b25..0000000
--- a/tombupnp/upnp/src/genlib/net/http/httpparser.c
+++ /dev/null
@@ -1,2556 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/************************************************************************
-* Purpose: This file contains functions for scanner and parser for http 
-* messages.
-************************************************************************/
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdarg.h>
-#include "strtoofft.h"
-#include "strintmap.h"
-#include "httpparser.h"
-#include "statcodes.h"
-#include "unixutil.h"
-// entity positions
-
-#define NUM_HTTP_METHODS 9
-static str_int_entry Http_Method_Table[NUM_HTTP_METHODS] = {
-    {"GET", HTTPMETHOD_GET},
-    {"HEAD", HTTPMETHOD_HEAD},
-    {"M-POST", HTTPMETHOD_MPOST},
-    {"M-SEARCH", HTTPMETHOD_MSEARCH},
-    {"NOTIFY", HTTPMETHOD_NOTIFY},
-    {"POST", HTTPMETHOD_POST},
-    {"SUBSCRIBE", HTTPMETHOD_SUBSCRIBE},
-    {"UNSUBSCRIBE", HTTPMETHOD_UNSUBSCRIBE},
-    {"POST", SOAPMETHOD_POST},
-
-};
-
-#define NUM_HTTP_HEADER_NAMES 33
-str_int_entry Http_Header_Names[NUM_HTTP_HEADER_NAMES] = {
-    {"ACCEPT", HDR_ACCEPT},
-    {"ACCEPT-CHARSET", HDR_ACCEPT_CHARSET},
-    {"ACCEPT-ENCODING", HDR_ACCEPT_ENCODING},
-    {"ACCEPT-LANGUAGE", HDR_ACCEPT_LANGUAGE},
-    {"ACCEPT-RANGES", HDR_ACCEPT_RANGE},
-    {"CACHE-CONTROL", HDR_CACHE_CONTROL},
-    {"CALLBACK", HDR_CALLBACK},
-    {"CONTENT-ENCODING", HDR_CONTENT_ENCODING},
-    {"CONTENT-LANGUAGE", HDR_CONTENT_LANGUAGE},
-    {"CONTENT-LENGTH", HDR_CONTENT_LENGTH},
-    {"CONTENT-LOCATION", HDR_CONTENT_LOCATION},
-    {"CONTENT-RANGE", HDR_CONTENT_RANGE},
-    {"CONTENT-TYPE", HDR_CONTENT_TYPE},
-    {"DATE", HDR_DATE},
-    {"EXT", HDR_EXT},
-    {"HOST", HDR_HOST},
-    {"IF-RANGE", HDR_IF_RANGE},
-    {"LOCATION", HDR_LOCATION},
-    {"MAN", HDR_MAN},
-    {"MX", HDR_MX},
-    {"NT", HDR_NT},
-    {"NTS", HDR_NTS},
-    {"RANGE", HDR_RANGE},
-    {"SEQ", HDR_SEQ},
-    {"SERVER", HDR_SERVER},
-    {"SID", HDR_SID},
-    {"SOAPACTION", HDR_SOAPACTION},
-    {"ST", HDR_ST},
-    {"TE", HDR_TE},
-    {"TIMEOUT", HDR_TIMEOUT},
-    {"TRANSFER-ENCODING", HDR_TRANSFER_ENCODING},
-    {"USER-AGENT", HDR_USER_AGENT},
-    {"USN", HDR_USN}
-};
-
-/***********************************************************************/
-
-/*************				 scanner					  **************/
-
-/***********************************************************************/
-
-#define TOKCHAR_CR		0xD
-#define TOKCHAR_LF		0xA
-
-/************************************************************************
-*	Function :	scanner_init
-*
-*	Parameters :
-*		OUT scanner_t* scanner ; Scanner Object to be initialized
-*		IN membuffer* bufptr ;	 Buffer to be copied
-*
-*	Description :	Intialize scanner
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-static XINLINE void
-scanner_init( OUT scanner_t * scanner,
-              IN membuffer * bufptr )
-{
-    scanner->cursor = 0;
-    scanner->msg = bufptr;
-    scanner->entire_msg_loaded = FALSE;
-}
-
-/************************************************************************
-*	Function :	is_separator_char
-*
-*	Parameters :
-*		IN char c ;	character to be tested against used separator values
-*
-*	Description :	Finds the separator character.
-*
-*	Return : xboolean ;
-*
-*	Note :
-************************************************************************/
-static XINLINE xboolean
-is_separator_char( IN char c )
-{
-    return strchr( " \t()<>@,;:\\\"/[]?={}", c ) != NULL;
-}
-
-/************************************************************************
-*	Function :	is_identifier_char
-*
-*	Parameters :
-*		IN char c ;	character to be tested for separator values
-*
-*	Description :	Calls the function to indentify separator character 
-*
-*	Return : xboolean ;
-*
-*	Note :
-************************************************************************/
-static XINLINE xboolean
-is_identifier_char( IN char c )
-{
-    return ( c >= 32 && c <= 126 ) && !is_separator_char( c );
-}
-
-/************************************************************************
-*	Function :	is_control_char
-*
-*	Parameters :
-*		IN char c ;	character to be tested for a control character
-*
-*	Description :	Determines if the passed value is a control character
-*
-*	Return : xboolean ;
-*
-*	Note :
-************************************************************************/
-static XINLINE xboolean
-is_control_char( IN signed char c )
-{
-    return ( ( c >= 0 && c <= 31 ) || ( c == 127 ) );
-}
-
-/************************************************************************
-*	Function :	is_qdtext_char
-*
-*	Parameters :
-*		IN char cc ; character to be tested for CR/LF
-*
-*	Description :	Checks to see if the passed in value is CR/LF
-*
-*	Return : xboolean ;
-*
-*	Note :
-************************************************************************/
-static XINLINE xboolean
-is_qdtext_char( IN char cc )
-{
-    unsigned char c = ( unsigned char )cc;
-
-    // we don't check for this; it's checked in get_token()
-    assert( c != '"' );
-
-    if( ( c >= 32 && c != 127 ) ||
-        ( c == TOKCHAR_CR || c == TOKCHAR_LF || c == '\t' )
-         ) {
-        return TRUE;
-    } else {
-        return FALSE;
-    }
-}
-
-/************************************************************************
-*	Function :	scanner_get_token
-*
-*	Parameters :
-*		INOUT scanner_t* scanner ;	Scanner Object
-*		OUT memptr* token ;			Token 
-*		OUT token_type_t* tok_type ; Type of token
-*
-*	Description :	reads next token from the input stream				
-*		note: 0 and is used as a marker, and will not be valid in a quote
-*
-*	Return : parse_status_t ;
-*		PARSE_OK															
-*		PARSE_INCOMPLETE		-- not enuf chars to get a token			
-*		PARSE_FAILURE			-- bad msg format							
-*
-*	Note :
-************************************************************************/
-static parse_status_t
-scanner_get_token( INOUT scanner_t * scanner,
-                   OUT memptr * token,
-                   OUT token_type_t * tok_type )
-{
-    char *cursor;
-    char *null_terminator;      // point to null-terminator in buffer
-    char c;
-    token_type_t token_type;
-    xboolean got_end_quote;
-
-    assert( scanner );
-    assert( token );
-    assert( tok_type );
-
-    // point to next char in buffer
-    cursor = scanner->msg->buf + scanner->cursor;
-    null_terminator = scanner->msg->buf + scanner->msg->length;
-
-    // not enough chars in input to parse
-    if( cursor == null_terminator ) {
-        return PARSE_INCOMPLETE;
-    }
-
-    c = *cursor;
-    if( is_identifier_char( c ) ) {
-        // scan identifier
-
-        token->buf = cursor++;
-        token_type = TT_IDENTIFIER;
-
-        while (cursor < null_terminator && is_identifier_char(*cursor)) {
-            cursor++;
-        }
-
-        if( !scanner->entire_msg_loaded && cursor == null_terminator ) {
-            // possibly more valid chars
-            return PARSE_INCOMPLETE;
-        }
-        // calc token length
-        token->length = cursor - token->buf;
-    } else if( c == ' ' || c == '\t' ) {
-        token->buf = cursor++;
-        token_type = TT_WHITESPACE;
-
-        while (cursor < null_terminator && (*cursor == ' ' || *cursor == '\t')){
-            cursor++;
-        }
-
-        if( !scanner->entire_msg_loaded && cursor == null_terminator ) {
-            // possibly more chars
-            return PARSE_INCOMPLETE;
-        }
-        token->length = cursor - token->buf;
-    } else if( c == TOKCHAR_CR ) {
-        // scan CRLF
-
-        token->buf = cursor++;
-        if( cursor == null_terminator ) {
-            // not enuf info to determine CRLF
-            return PARSE_INCOMPLETE;
-        }
-        if( *cursor != TOKCHAR_LF ) {
-            // couldn't match CRLF; match as CR
-            token_type = TT_CTRL;   // ctrl char
-            token->length = 1;
-        } else {
-            // got CRLF
-            token->length = 2;
-            token_type = TT_CRLF;
-            cursor++;
-        }
-    } else if( c == TOKCHAR_LF )    // accept \n as CRLF
-    {
-        token->buf = cursor++;
-        token->length = 1;
-        token_type = TT_CRLF;
-    } else if( c == '"' ) {
-        // quoted text
-        token->buf = cursor++;
-        token_type = TT_QUOTEDSTRING;
-        got_end_quote = FALSE;
-
-        while( cursor < null_terminator ) {
-            c = *cursor++;
-            if( c == '"' ) {
-                got_end_quote = TRUE;
-                break;
-            } else if( c == '\\' ) {
-                if( cursor < null_terminator ) {
-                    c = *cursor++;
-                    //if ( !(c > 0 && c <= 127) )
-                    if( c == 0 ) {
-                        return PARSE_FAILURE;
-                    }
-                }
-                // else, while loop handles incomplete buf
-            } else if( is_qdtext_char( c ) ) {
-                // just accept char
-            } else {
-                // bad quoted text
-                return PARSE_FAILURE;
-            }
-        }
-        if( got_end_quote ) {
-            token->length = cursor - token->buf;
-        } else                  // incomplete
-        {
-            assert( cursor == null_terminator );
-            return PARSE_INCOMPLETE;
-        }
-    } else if( is_separator_char( c ) ) {
-        // scan separator
-
-        token->buf = cursor++;
-        token_type = TT_SEPARATOR;
-        token->length = 1;
-    } else if( is_control_char( c ) ) {
-        // scan ctrl char
-
-        token->buf = cursor++;
-        token_type = TT_CTRL;
-        token->length = 1;
-    } else {
-        return PARSE_FAILURE;
-    }
-
-    scanner->cursor += token->length;   // move to next token
-    *tok_type = token_type;
-    return PARSE_OK;
-}
-
-/************************************************************************
-*	Function :	scanner_get_str
-*
-*	Parameters :
-*		IN scanner_t* scanner ;	Scanner Object
-*
-*	Description :	returns ptr to next char in string
-*
-*	Return : char* ;
-*
-*	Note :
-************************************************************************/
-static XINLINE char *
-scanner_get_str( IN scanner_t * scanner )
-{
-    return scanner->msg->buf + scanner->cursor;
-}
-
-/************************************************************************
-*	Function :	scanner_pushback
-*
-*	Parameters :
-*		INOUT scanner_t* scanner ;	Scanner Object
-*		IN size_t pushback_bytes ;	Bytes to be moved back
-*
-*	Description :	Move back by a certain number of bytes.				
-*		This is used to put back one or more tokens back into the input		
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-static XINLINE void
-scanner_pushback( INOUT scanner_t * scanner,
-                  IN size_t pushback_bytes )
-{
-    scanner->cursor -= pushback_bytes;
-}
-
-/***********************************************************************/
-
-/*************				end of scanner				  **************/
-
-/***********************************************************************/
-
-/***********************************************************************/
-
-/*************					parser					  **************/
-
-/***********************************************************************/
-
-/***********************************************************************/
-
-/*************				  http_message_t			  **************/
-
-/***********************************************************************/
-
-/************************************************************************
-*	Function :	httpmsg_compare
-*
-*	Parameters :
-*		void* param1 ;	
-*		void* param2 ;	
-*
-*	Description :	Compares name id in the http headers.
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-static int
-httpmsg_compare( void *param1,
-                 void *param2 )
-{
-    assert( param1 != NULL );
-    assert( param2 != NULL );
-
-    return ( ( http_header_t * ) param1 )->name_id ==
-        ( ( http_header_t * ) param2 )->name_id;
-}
-
-/************************************************************************
-*	Function :	httpheader_free
-*
-*	Parameters :
-*		void *msg ;	
-*
-*	Description :	Free memory allocated for the http header
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-static void
-httpheader_free( void *msg )
-{
-    http_header_t *hdr = ( http_header_t * ) msg;
-
-    membuffer_destroy( &hdr->name_buf );
-    membuffer_destroy( &hdr->value );
-    free( hdr );
-}
-
-/************************************************************************
-*	Function :	httpmsg_init
-*
-*	Parameters :
-*		INOUT http_message_t* msg ;	HTTP Message Object
-*
-*	Description :	Initialize and allocate memory for http message
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-httpmsg_init( INOUT http_message_t * msg )
-{
-    msg->initialized = 1;
-    msg->entity.buf = NULL;
-    msg->entity.length = 0;
-    ListInit( &msg->headers, httpmsg_compare, httpheader_free );
-    membuffer_init( &msg->msg );
-    membuffer_init( &msg->status_msg );
-}
-
-/************************************************************************
-*	Function :	httpmsg_destroy
-*
-*	Parameters :
-*		INOUT http_message_t* msg ;	HTTP Message Object
-*
-*	Description :	Free memory allocated for the http message
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-httpmsg_destroy( INOUT http_message_t * msg )
-{
-    assert( msg != NULL );
-
-    if( msg->initialized == 1 ) {
-        ListDestroy( &msg->headers, 1 );
-        membuffer_destroy( &msg->msg );
-        membuffer_destroy( &msg->status_msg );
-        free( msg->urlbuf );
-        msg->initialized = 0;
-    }
-}
-
-/************************************************************************
-*	Function :	httpmsg_find_hdr_str
-*
-*	Parameters :
-*		IN http_message_t* msg ;	HTTP Message Object
-*		IN const char* header_name ; Header name to be compared with	
-*
-*	Description :	Compares the header name with the header names stored 
-*		in	the linked list of messages
-*
-*	Return : http_header_t* - Pointer to a header on success;
-*			 NULL on failure														
-*
-*	Note :
-************************************************************************/
-http_header_t *
-httpmsg_find_hdr_str( IN http_message_t * msg,
-                      IN const char *header_name )
-{
-    http_header_t *header;
-
-    ListNode *node;
-
-    node = ListHead( &msg->headers );
-    while( node != NULL ) {
-
-        header = ( http_header_t * ) node->item;
-
-        if( memptr_cmp_nocase( &header->name, header_name ) == 0 ) {
-            return header;
-        }
-
-        node = ListNext( &msg->headers, node );
-    }
-    return NULL;
-}
-
-/************************************************************************
-*	Function :	httpmsg_find_hdr
-*
-*	Parameters :
-*		IN http_message_t* msg ; HTTP Message Object
-*		IN int header_name_id ;	 Header Name ID to be compared with
-*		OUT memptr* value ;		 Buffer to get the ouput to.
-*
-*	Description :	Finds header from a list, with the given 'name_id'.
-*
-*	Return : http_header_t*  - Pointer to a header on success;										*
-*			 NULL on failure														
-*
-*	Note :
-************************************************************************/
-http_header_t *
-httpmsg_find_hdr( IN http_message_t * msg,
-                  IN int header_name_id,
-                  OUT memptr * value )
-{
-    http_header_t header;       // temp header for searching
-
-    ListNode *node;
-
-    http_header_t *data;
-
-    header.name_id = header_name_id;
-
-    node = ListFind( &msg->headers, NULL, &header );
-
-    if( node == NULL ) {
-        return NULL;
-    }
-
-    data = ( http_header_t * ) node->item;
-
-    if( value != NULL ) {
-        value->buf = data->value.buf;
-        value->length = data->value.length;
-    }
-
-    return data;
-}
-
-/***********************************************************************/
-
-/*************				  http_parser_t				  **************/
-
-/***********************************************************************/
-
-/************************************************************************
-*	Function :	skip_blank_lines
-*
-*	Parameters :
-*		INOUT scanner_t* scanner ;	Scanner Object
-*
-*	Description :	skips blank lines at the start of a msg.
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-static XINLINE int
-skip_blank_lines( INOUT scanner_t * scanner )
-{
-    memptr token;
-    token_type_t tok_type;
-    parse_status_t status;
-
-    // skip ws, crlf
-    do {
-        status = scanner_get_token( scanner, &token, &tok_type );
-    } while( status == PARSE_OK &&
-             ( tok_type == TT_WHITESPACE || tok_type == TT_CRLF ) );
-
-    if( status == PARSE_OK ) {
-        // pushback a non-whitespace token
-        scanner->cursor -= token.length;
-        //scanner_pushback( scanner, token.length );
-    }
-
-    return status;
-}
-
-/************************************************************************
-*	Function :	skip_lws
-*
-*	Parameters :
-*		INOUT scanner_t* scanner ;	Scanner Object
-*
-*	Description :	skip linear whitespace.
-*
-*	Return : int ;
-*		PARSE_OK: (LWS)* removed from input								
-*		PARSE_FAILURE: bad input											
-*		PARSE_INCOMPLETE: incomplete input									
-*
-*	Note :
-************************************************************************/
-static XINLINE int
-skip_lws( INOUT scanner_t * scanner )
-{
-    memptr token;
-    token_type_t tok_type;
-    parse_status_t status;
-    size_t save_pos;
-    xboolean matched;
-
-    do {
-        save_pos = scanner->cursor;
-        matched = FALSE;
-
-        // get CRLF or WS
-        status = scanner_get_token( scanner, &token, &tok_type );
-        if( status == PARSE_OK ) {
-            if( tok_type == TT_CRLF ) {
-                // get WS
-                status = scanner_get_token( scanner, &token, &tok_type );
-            }
-
-            if( status == PARSE_OK && tok_type == TT_WHITESPACE ) {
-                matched = TRUE;
-            } else {
-                // did not match LWS; pushback token(s)
-                scanner->cursor = save_pos;
-            }
-        }
-    } while( matched );
-
-    // if entire msg is loaded, ignore an 'incomplete' warning
-    if( status == PARSE_INCOMPLETE && scanner->entire_msg_loaded ) {
-        status = PARSE_OK;
-    }
-
-    return status;
-}
-
-/************************************************************************
-*	Function :	match_non_ws_string
-*
-*	Parameters :
-*		INOUT scanner_t* scanner ;	Scanner Object
-*		OUT memptr* str ;	Buffer to get the scanner buffer contents.
-*
-*	Description :	Match a string without whitespace or CRLF (%S)
-*
-*	Return : XINLINE parse_status_t ;
-*		PARSE_OK															
-*		PARSE_NO_MATCH														
-*		PARSE_FAILURE														
-*		PARSE_INCOMPLETE													
-*
-*	Note :
-************************************************************************/
-static XINLINE parse_status_t
-match_non_ws_string( INOUT scanner_t * scanner,
-                     OUT memptr * str )
-{
-    memptr token;
-    token_type_t tok_type;
-    parse_status_t status;
-    xboolean done = FALSE;
-    size_t save_cursor;
-
-    save_cursor = scanner->cursor;
-
-    str->length = 0;
-    str->buf = scanner_get_str( scanner );  // point to next char in input
-
-    while( !done ) {
-        status = scanner_get_token( scanner, &token, &tok_type );
-        if( status == PARSE_OK &&
-            tok_type != TT_WHITESPACE && tok_type != TT_CRLF ) {
-            // append non-ws token
-            str->length += token.length;
-        } else {
-            done = TRUE;
-        }
-    }
-
-    if( status == PARSE_OK ) {
-        // last token was WS; push it back in
-        scanner->cursor -= token.length;
-    }
-    // tolerate 'incomplete' msg
-    if( status == PARSE_OK ||
-        ( status == PARSE_INCOMPLETE && scanner->entire_msg_loaded )
-         ) {
-        if( str->length == 0 ) {
-            // no strings found
-            return PARSE_NO_MATCH;
-        } else {
-            return PARSE_OK;
-        }
-    } else {
-        // error -- pushback tokens
-        scanner->cursor = save_cursor;
-        return status;
-    }
-}
-
-/************************************************************************
-*	Function :	match_raw_value
-*
-*	Parameters :
-*		INOUT scanner_t* scanner ;	Scanner Object
-*		OUT memptr* raw_value ;	    Buffer to get the scanner buffer 
-*									contents
-*
-*	Description :	Matches a raw value in a the input; value's length 
-*		can	be 0 or more. Whitespace after value is trimmed. On success,
-*		scanner points the CRLF that ended the value						
-*
-*	Return : parse_status_t ;
-*		PARSE_OK													
-*		PARSE_INCOMPLETE													
-*		PARSE_FAILURE														
-*
-*	Note :
-************************************************************************/
-static XINLINE parse_status_t
-match_raw_value( INOUT scanner_t * scanner,
-                 OUT memptr * raw_value )
-{
-    memptr token;
-    token_type_t tok_type;
-    parse_status_t status;
-    xboolean done = FALSE;
-    xboolean saw_crlf = FALSE;
-    size_t pos_at_crlf = 0;
-    size_t save_pos;
-    char c;
-
-    save_pos = scanner->cursor;
-
-    // value points to start of input
-    raw_value->buf = scanner_get_str( scanner );
-    raw_value->length = 0;
-
-    while( !done ) {
-        status = scanner_get_token( scanner, &token, &tok_type );
-        if( status == PARSE_OK ) {
-            if( !saw_crlf ) {
-                if( tok_type == TT_CRLF ) {
-                    // CRLF could end value
-                    saw_crlf = TRUE;
-
-                    // save input position at start of CRLF
-                    pos_at_crlf = scanner->cursor - token.length;
-                }
-                // keep appending value
-                raw_value->length += token.length;
-            } else              // already seen CRLF
-            {
-                if( tok_type == TT_WHITESPACE ) {
-                    // start again; forget CRLF
-                    saw_crlf = FALSE;
-                    raw_value->length += token.length;
-                } else {
-                    // non-ws means value ended just before CRLF
-                    done = TRUE;
-
-                    // point to the crlf which ended the value
-                    scanner->cursor = pos_at_crlf;
-                }
-            }
-        } else {
-            // some kind of error; restore scanner position
-            scanner->cursor = save_pos;
-            done = TRUE;
-        }
-    }
-
-    if( status == PARSE_OK ) {
-        // trim whitespace on right side of value
-        while( raw_value->length > 0 ) {
-            // get last char
-            c = raw_value->buf[raw_value->length - 1];
-
-            if( c != ' ' && c != '\t' &&
-                c != TOKCHAR_CR && c != TOKCHAR_LF ) {
-                // done; no more whitespace
-                break;
-            }
-            // remove whitespace
-            raw_value->length--;
-        }
-    }
-
-    return status;
-}
-
-/************************************************************************
-* Function: match_int													
-*																		
-* Parameters:															
-*	INOUT scanner_t* scanner ;  Scanner Object											
-*	IN int base :				Base of number in the string; 
-*								valid values: 10 or 16	
-*	OUT int* value ;			Number stored here									
-*																		
-* Description: Matches an unsigned integer value in the input. The		
-*	integer is returned in 'value'. Except for PARSE_OK result, the		
-*	scanner's cursor is moved back to its original position on error.	
-*																		
-* Returns:																
-*   PARSE_OK															
-*   PARSE_NO_MATCH		-- got different kind of token					
-*   PARSE_FAILURE		-- bad input									
-*   PARSE_INCOMPLETE													
-************************************************************************/
-static XINLINE int
-match_int( INOUT scanner_t * scanner,
-           IN int base,
-           OUT int *value )
-{
-    memptr token;
-    token_type_t tok_type;
-    parse_status_t status;
-    long num;
-    char *end_ptr;
-    size_t save_pos;
-
-    save_pos = scanner->cursor;
-
-    status = scanner_get_token( scanner, &token, &tok_type );
-    if( status == PARSE_OK ) {
-        if( tok_type == TT_IDENTIFIER ) {
-            errno = 0;
-
-            num = strtol( token.buf, &end_ptr, base );
-            if( ( num < 0 )
-                // all and only those chars in token should be used for num
-                || ( end_ptr != token.buf + token.length )
-                || ( ( num == LONG_MIN || num == LONG_MAX )
-                     && ( errno == ERANGE ) )
-                 ) {
-                status = PARSE_NO_MATCH;
-            }
-
-            *value = num;       // save result
-        } else {
-            status = PARSE_NO_MATCH;    // token must be an identifier
-        }
-    }
-
-    if( status != PARSE_OK ) {
-        // restore scanner position for bad values
-        scanner->cursor = save_pos;
-    }
-
-    return status;
-}
-
-/************************************************************************
-* Function: read_until_crlf												
-*																		
-* Parameters:															
-*	INOUT scanner_t* scanner ;	Scanner Object											
-*	OUT memptr* str ;			Buffer to copy scanner buffer contents to
-*																		
-* Description: Reads data until end of line; the crlf at the end of		
-*	line is not consumed. On error, scanner is not restored. On			
-*	success, 'str' points to a string that runs until eol				
-*																		
-* Returns:																
-*   PARSE_OK															
-*   PARSE_FAILURE														
-*   PARSE_INCOMPLETE													
-************************************************************************/
-static XINLINE int
-read_until_crlf( INOUT scanner_t * scanner,
-                 OUT memptr * str )
-{
-    memptr token;
-    token_type_t tok_type;
-    parse_status_t status;
-    size_t start_pos;
-
-    start_pos = scanner->cursor;
-    str->buf = scanner_get_str( scanner );
-
-    // read until we hit a crlf
-    do {
-        status = scanner_get_token( scanner, &token, &tok_type );
-    } while( status == PARSE_OK && tok_type != TT_CRLF );
-
-    if( status == PARSE_OK ) {
-        // pushback crlf in stream
-        scanner->cursor -= token.length;
-
-        // str should include all strings except crlf at the end
-        str->length = scanner->cursor - start_pos;
-    }
-
-    return status;
-}
-
-/************************************************************************
-* Function: skip_to_end_of_header										
-*																		
-* Parameters:															
-*	INOUT scanner_t* scanner ; Scanner Object
-*																		
-* Description: Skip to end of header									
-*																		
-* Returns:																
-*   PARSE_OK															
-*   PARSE_FAILURE														
-*   PARSE_INCOMPLETE													
-************************************************************************/
-static XINLINE int
-skip_to_end_of_header( INOUT scanner_t * scanner )
-{
-    memptr dummy_raw_value;
-    parse_status_t status;
-
-    status = match_raw_value( scanner, &dummy_raw_value );
-    return status;
-}
-
-/************************************************************************
-* Function: match_char
-*
-* Parameters:
-*	INOUT scanner_t* scanner ;  Scanner Object
-*	IN char c ;					Character to be compared with
-*	IN xboolean case_sensitive; Flag indicating whether comparison should
-*								be case sensitive
-*
-* Description: Compares a character to the next char in the scanner;
-*	on error, scanner chars are not restored
-*
-* Returns:
-*   PARSE_OK
-*   PARSE_NO_MATCH
-*   PARSE_INCOMPLETE
-************************************************************************/
-static XINLINE parse_status_t
-match_char( INOUT scanner_t * scanner,
-            IN char c,
-            IN xboolean case_sensitive )
-{
-    char scan_char;
-
-    if( scanner->cursor >= scanner->msg->length ) {
-        return PARSE_INCOMPLETE;
-    }
-    // read next char from scanner
-    scan_char = scanner->msg->buf[scanner->cursor++];
-
-    if( case_sensitive ) {
-        return c == scan_char ? PARSE_OK : PARSE_NO_MATCH;
-    } else {
-        return tolower( c ) == tolower( scan_char ) ?
-            PARSE_OK : PARSE_NO_MATCH;
-    }
-}
-
-////////////////////////////////////////////////////////////////////////
-// args for ...
-//   %d,    int *     (31-bit positive integer)
-//   %x,    int *     (31-bit postive number encoded as hex)
-//   %s,    memptr*  (simple identifier)
-//   %q,    memptr*  (quoted string)
-//   %S,    memptr*  (non-whitespace string)
-//   %R,    memptr*  (raw value)
-//   %U,    uri_type* (url)
-//   %L,    memptr*  (string until end of line)
-//   %P,    int * (current index of the string being scanned)
-//
-// no args for
-//   ' '    LWS*
-//   \t     whitespace
-//   "%%"   matches '%'
-//   "% "   matches ' '
-//   %c     matches CRLF
-//   %i     ignore case in literal matching
-//   %n     case-sensitive matching in literals
-//   %w     optional whitespace; (similar to '\t', 
-//                  except whitespace is optional)
-//   %0     (zero) match null-terminator char '\0' 
-//              (can only be used as last char in fmt)
-//              use only in matchstr(), not match()
-//   other chars match literally
-//
-// returns:
-//   PARSE_OK
-//   PARSE_INCOMPLETE
-//   PARSE_FAILURE      -- bad input
-//   PARSE_NO_MATCH     -- input does not match pattern
-
-/************************************************************************
-*	Function :	vfmatch
-*
-*	Parameters :
-*		INOUT scanner_t* scanner ;  Scanner Object	
-*		IN const char* fmt ;		Pattern Format 
-*		va_list argp ;				List of variable arguments
-*
-*	Description :	Extracts variable parameters depending on the passed 
-*		in format parameter. Parses data also based on the passed in 
-*		format parameter.
-*
-*	Return : int ;
-*		PARSE_OK
-*		PARSE_INCOMPLETE
-*		PARSE_FAILURE		- bad input
-*		PARSE_NO_MATCH		- input does not match pattern
-*
-*	Note :
-************************************************************************/
-static int
-vfmatch( INOUT scanner_t * scanner,
-         IN const char *fmt,
-         va_list argp )
-{
-    char c;
-    const char *fmt_ptr = fmt;
-    parse_status_t status;
-    memptr *str_ptr;
-    memptr temp_str;
-    int *int_ptr;
-    uri_type *uri_ptr;
-    size_t save_pos;
-    int stat;
-    xboolean case_sensitive = TRUE;
-    memptr token;
-    token_type_t tok_type;
-    int base;
-
-    assert( scanner != NULL );
-    assert( fmt != NULL );
-
-    // save scanner pos; to aid error recovery
-    save_pos = scanner->cursor;
-
-    status = PARSE_OK;
-    while( ( ( c = *fmt_ptr++ ) != 0 ) && ( status == PARSE_OK )
-         ) {
-        if( c == '%' ) {
-            c = *fmt_ptr++;
-
-            switch ( c ) {
-
-                case 'R':      // raw value
-                    str_ptr = va_arg( argp, memptr * );
-                    assert( str_ptr != NULL );
-                    status = match_raw_value( scanner, str_ptr );
-                    break;
-
-                case 's':      // simple identifier
-                    str_ptr = va_arg( argp, memptr * );
-                    assert( str_ptr != NULL );
-                    status = scanner_get_token( scanner, str_ptr,
-                                                &tok_type );
-                    if( status == PARSE_OK && tok_type != TT_IDENTIFIER ) {
-                        // not an identifier
-                        status = PARSE_NO_MATCH;
-                    }
-                    break;
-
-                case 'c':      // crlf
-                    status = scanner_get_token( scanner,
-                                                &token, &tok_type );
-                    if( status == PARSE_OK && tok_type != TT_CRLF ) {
-                        // not CRLF token
-                        status = PARSE_NO_MATCH;
-                    }
-                    break;
-
-                case 'd':      // integer
-                case 'x':      // hex number
-                    int_ptr = va_arg( argp, int * );
-
-                    assert( int_ptr != NULL );
-                    base = ( c == 'd' ? 10 : 16 );
-                    status = match_int( scanner, base, int_ptr );
-                    break;
-
-                case 'S':      // non-whitespace string
-                case 'U':      // uri
-                    if( c == 'S' ) {
-                        str_ptr = va_arg( argp, memptr * );
-                    } else {
-                        str_ptr = &temp_str;
-                    }
-                    assert( str_ptr != NULL );
-                    status = match_non_ws_string( scanner, str_ptr );
-                    if( c == 'U' && status == PARSE_OK ) {
-                        uri_ptr = va_arg( argp, uri_type * );
-                        assert( uri_ptr != NULL );
-                        stat = parse_uri( str_ptr->buf, str_ptr->length,
-                                          uri_ptr );
-                        if( stat != HTTP_SUCCESS ) {
-                            status = PARSE_NO_MATCH;
-                        }
-                    }
-                    break;
-
-                case 'L':      // string till eol
-                    str_ptr = va_arg( argp, memptr * );
-                    assert( str_ptr != NULL );
-                    status = read_until_crlf( scanner, str_ptr );
-                    break;
-
-                case ' ':      // match space
-                case '%':      // match percentage symbol
-                    status = match_char( scanner, c, case_sensitive );
-                    break;
-
-                case 'n':      // case-sensitive match
-                    case_sensitive = TRUE;
-                    break;
-
-                case 'i':      // ignore case
-                    case_sensitive = FALSE;
-                    break;
-
-                case 'q':      // quoted string
-                    str_ptr = ( memptr * ) va_arg( argp, memptr * );
-                    status =
-                        scanner_get_token( scanner, str_ptr, &tok_type );
-                    if( status == PARSE_OK && tok_type != TT_QUOTEDSTRING ) {
-                        status = PARSE_NO_MATCH;    // not a quoted string
-                    }
-                    break;
-
-                case 'w':      // optional whitespace
-                    status = scanner_get_token( scanner,
-                                                &token, &tok_type );
-                    if( status == PARSE_OK && tok_type != TT_WHITESPACE ) {
-                        // restore non-whitespace token
-                        scanner->cursor -= token.length;
-                    }
-                    break;
-
-                case 'P':      // current pos of scanner
-                    int_ptr = va_arg( argp, int * );
-
-                    assert( int_ptr != NULL );
-                    *int_ptr = scanner->cursor;
-                    break;
-
-                    // valid only in matchstr()
-                case '0':      // end of msg?
-                    // check that we are 1 beyond last char
-                    if( scanner->cursor == scanner->msg->length &&
-                        scanner->msg->buf[scanner->cursor] == '\0' ) {
-                        status = PARSE_OK;
-                    } else {
-                        status = PARSE_NO_MATCH;
-                    }
-                    break;
-
-                default:
-                    assert( 0 );    // unknown option
-            }
-        } else {
-            switch ( c ) {
-                case ' ':      // LWS*
-                    status = skip_lws( scanner );
-                    break;
-
-                case '\t':     // Whitespace
-                    status = scanner_get_token( scanner,
-                                                &token, &tok_type );
-                    if( status == PARSE_OK && tok_type != TT_WHITESPACE ) {
-                        // not whitespace token
-                        status = PARSE_NO_MATCH;
-                    }
-                    break;
-
-                default:       // match characters
-                    {
-                        status = match_char( scanner, c, case_sensitive );
-                    }
-            }
-        }
-    }
-
-    if( status != PARSE_OK ) {
-        // on error, restore original scanner pos
-        scanner->cursor = save_pos;
-    }
-
-    return status;
-}
-
-/************************************************************************
-* Function: match														
-*																		
-* Parameters:															
-*	INOUT scanner_t* scanner ; Scanner Object											
-*	IN const char* fmt;			Pattern format													
-*	...																	
-*																		
-* Description: matches a variable parameter list and takes necessary	
-*	actions based on the data type specified.							
-*																		
-* Returns:																
-*   PARSE_OK															
-*   PARSE_NO_MATCH														
-*   PARSE_INCOMPLETE													
-************************************************************************/
-static int
-match( INOUT scanner_t * scanner,
-       IN const char *fmt,
-       ... )
-{
-    int ret_code;
-    va_list args;
-
-    va_start( args, fmt );
-    ret_code = vfmatch( scanner, fmt, args );
-    va_end( args );
-
-    return ret_code;
-}
-
-/************************************************************************
-* Function: matchstr													
-*																		
-* Parameters:															
-*	IN char *str ;		 String to be matched														
-*	IN size_t slen ;     Length of the string														
-*	IN const char* fmt ; Pattern format												
-*	...																	
-*																		
-* Description: Matches a variable parameter list with a string			
-*	and takes actions based on the data type specified.					
-*																		
-* Returns:																
-*   PARSE_OK															
-*   PARSE_NO_MATCH -- failure to match pattern 'fmt'					
-*   PARSE_FAILURE	-- 'str' is bad input							
-************************************************************************/
-int
-matchstr( IN char *str,
-          IN size_t slen,
-          IN const char *fmt,
-          ... )
-{
-    int ret_code;
-    char save_char;
-    scanner_t scanner;
-    membuffer buf;
-    va_list arg_list;
-
-    // null terminate str
-    save_char = str[slen];
-    str[slen] = '\0';
-
-    membuffer_init( &buf );
-
-    // under no circumstances should this buffer be modifed because its memory
-    //  might have not come from malloc()
-    membuffer_attach( &buf, str, slen );
-
-    scanner_init( &scanner, &buf );
-    scanner.entire_msg_loaded = TRUE;
-
-    va_start( arg_list, fmt );
-    ret_code = vfmatch( &scanner, fmt, arg_list );
-    va_end( arg_list );
-
-    // restore str
-    str[slen] = save_char;
-
-    // don't destroy buf
-
-    return ret_code;
-}
-
-/************************************************************************
-* Function: parser_init													
-*																		
-* Parameters:															
-*	OUT http_parser_t* parser ; HTTP Parser object
-*																		
-* Description: Initializes the parser object.							
-*																		
-* Returns:																
-*	void																
-************************************************************************/
-static XINLINE void
-parser_init( OUT http_parser_t * parser )
-{
-    memset( parser, 0, sizeof( http_parser_t ) );
-
-    parser->http_error_code = HTTP_BAD_REQUEST; // err msg by default
-    parser->ent_position = ENTREAD_DETERMINE_READ_METHOD;
-    parser->valid_ssdp_notify_hack = FALSE;
-
-    httpmsg_init( &parser->msg );
-    scanner_init( &parser->scanner, &parser->msg.msg );
-}
-
-/************************************************************************
-* Function: parser_parse_requestline									
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser ; HTTP Parser  object						
-*																		
-* Description: Get HTTP Method, URL location and version information.	
-*																		
-* Returns:																
-*	PARSE_OK															
-*	PARSE_SUCCESS														
-*	PARSE_FAILURE														
-************************************************************************/
-static parse_status_t
-parser_parse_requestline( INOUT http_parser_t * parser )
-{
-    parse_status_t status;
-    http_message_t *hmsg = &parser->msg;
-    memptr method_str;
-    memptr version_str;
-    int index;
-    char save_char;
-    int num_scanned;
-    memptr url_str;
-
-    assert( parser->position == POS_REQUEST_LINE );
-
-    status = skip_blank_lines( &parser->scanner );
-    if( status != PARSE_OK ) {
-        return status;
-    }
-    //simple get http 0.9 as described in http 1.0 spec
-
-    status =
-        match( &parser->scanner, "%s\t%S%w%c", &method_str, &url_str );
-
-    if( status == PARSE_OK ) {
-
-        index =
-            map_str_to_int( method_str.buf, method_str.length,
-                            Http_Method_Table, NUM_HTTP_METHODS, TRUE );
-
-        if( index < 0 ) {
-            // error; method not found
-            parser->http_error_code = HTTP_NOT_IMPLEMENTED;
-            return PARSE_FAILURE;
-        }
-
-        if( Http_Method_Table[index].id != HTTPMETHOD_GET ) {
-            parser->http_error_code = HTTP_BAD_REQUEST;
-            return PARSE_FAILURE;
-        }
-
-        hmsg->method = HTTPMETHOD_SIMPLEGET;
-
-        // store url
-        hmsg->urlbuf = str_alloc( url_str.buf, url_str.length );
-        if( hmsg->urlbuf == NULL ) {
-            // out of mem
-            parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
-            return PARSE_FAILURE;
-        }
-        if( parse_uri( hmsg->urlbuf, url_str.length, &hmsg->uri ) !=
-            HTTP_SUCCESS ) {
-            return PARSE_FAILURE;
-        }
-
-        parser->position = POS_COMPLETE;    // move to headers
-
-        return PARSE_SUCCESS;
-    }
-
-    status = match( &parser->scanner,
-                    "%s\t%S\t%ihttp%w/%w%L%c", &method_str, &url_str,
-                    &version_str );
-    if( status != PARSE_OK ) {
-        return status;
-    }
-    // store url
-    hmsg->urlbuf = str_alloc( url_str.buf, url_str.length );
-    if( hmsg->urlbuf == NULL ) {
-        // out of mem
-        parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
-        return PARSE_FAILURE;
-    }
-    if( parse_uri( hmsg->urlbuf, url_str.length, &hmsg->uri ) !=
-        HTTP_SUCCESS ) {
-        return PARSE_FAILURE;
-    }
-    // scan version
-    save_char = version_str.buf[version_str.length];
-    version_str.buf[version_str.length] = '\0'; // null-terminate
-    num_scanned = sscanf( version_str.buf, "%d . %d",
-                          &hmsg->major_version, &hmsg->minor_version );
-    version_str.buf[version_str.length] = save_char;    // restore
-    if( num_scanned != 2 ||
-        hmsg->major_version < 0 || hmsg->minor_version < 0 ) {
-        // error; bad http version
-        return PARSE_FAILURE;
-    }
-
-    index =
-        map_str_to_int( method_str.buf, method_str.length,
-                        Http_Method_Table, NUM_HTTP_METHODS, TRUE );
-    if( index < 0 ) {
-        // error; method not found
-        parser->http_error_code = HTTP_NOT_IMPLEMENTED;
-        return PARSE_FAILURE;
-    }
-
-    hmsg->method = Http_Method_Table[index].id;
-    parser->position = POS_HEADERS; // move to headers
-
-    return PARSE_OK;
-}
-
-/************************************************************************
-* Function: parser_parse_responseline									
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser	; HTTP Parser object					
-*																		
-* Description: Get HTTP Method, URL location and version information.	
-*																		
-* Returns:																
-*	PARSE_OK															
-*	PARSE_SUCCESS														
-*	PARSE_FAILURE														
-************************************************************************/
-parse_status_t
-parser_parse_responseline( INOUT http_parser_t * parser )
-{
-    parse_status_t status;
-    http_message_t *hmsg = &parser->msg;
-    memptr line;
-    char save_char;
-    int num_scanned;
-    int i;
-    char *p;
-
-    assert( parser->position == POS_RESPONSE_LINE );
-
-    status = skip_blank_lines( &parser->scanner );
-    if( status != PARSE_OK ) {
-        return status;
-    }
-    // response line
-    //status = match( &parser->scanner, "%ihttp%w/%w%d\t.\t%d\t%d\t%L%c",
-    //  &hmsg->major_version, &hmsg->minor_version,
-    //  &hmsg->status_code, &hmsg->status_msg );
-
-    status = match( &parser->scanner, "%ihttp%w/%w%L%c", &line );
-    if( status != PARSE_OK ) {
-        return status;
-    }
-
-    save_char = line.buf[line.length];
-    line.buf[line.length] = '\0';   // null-terminate
-
-    // scan http version and ret code
-    num_scanned = sscanf( line.buf, "%d . %d %d",
-                          &hmsg->major_version, &hmsg->minor_version,
-                          &hmsg->status_code );
-
-    line.buf[line.length] = save_char;  // restore
-
-    if( num_scanned != 3 ||
-        hmsg->major_version < 0 ||
-        hmsg->minor_version < 0 || hmsg->status_code < 0 ) {
-        // bad response line
-        return PARSE_FAILURE;
-    }
-    //
-    // point to status msg
-    //
-
-    p = line.buf;
-
-    // skip 3 ints
-    for( i = 0; i < 3; i++ ) {
-        // go to start of num
-        while( !isdigit( *p ) ) {
-            p++;
-        }
-
-        // skip int
-        while( isdigit( *p ) ) {
-            p++;
-        }
-    }
-
-    // whitespace must exist after status code
-    if( *p != ' ' && *p != '\t' ) {
-        return PARSE_FAILURE;
-    }
-    // skip whitespace
-    while( *p == ' ' || *p == '\t' ) {
-        p++;
-    }
-
-    // now, p is at start of status msg
-    if( membuffer_assign( &hmsg->status_msg, p,
-                          line.length - ( p - line.buf ) ) != 0 ) {
-        // out of mem
-        parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
-        return PARSE_FAILURE;
-    }
-
-    parser->position = POS_HEADERS; // move to headers
-
-    return PARSE_OK;
-}
-
-/************************************************************************
-* Function: parser_parse_headers									
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser	; HTTP Parser object										
-*													
-* Description: Get HTTP Method, URL location and version information.	
-*																		
-* Returns:																
-*	PARSE_OK															
-*	PARSE_SUCCESS														
-*	PARSE_FAILURE														
-************************************************************************/
-parse_status_t
-parser_parse_headers( INOUT http_parser_t * parser )
-{
-    parse_status_t status;
-    memptr token;
-    memptr hdr_value;
-    token_type_t tok_type;
-    scanner_t *scanner = &parser->scanner;
-    size_t save_pos;
-    http_header_t *header;
-    int header_id;
-    int ret = 0;
-    int index;
-    http_header_t *orig_header;
-    char save_char;
-    int ret2;
-
-    assert( parser->position == POS_HEADERS ||
-            parser->ent_position == ENTREAD_CHUNKY_HEADERS );
-
-    while( TRUE ) {
-        save_pos = scanner->cursor;
-
-        //
-        // check end of headers
-        //
-        status = scanner_get_token( scanner, &token, &tok_type );
-        if( status != PARSE_OK ) {
-            return status;
-        }
-
-        if( tok_type == TT_CRLF ) {
-
-            // end of headers
-            if( ( parser->msg.is_request )
-                && ( parser->msg.method == HTTPMETHOD_POST ) ) {
-                parser->position = POS_COMPLETE;    //post entity parsing
-                //is handled separately 
-                return PARSE_SUCCESS;
-            }
-
-            parser->position = POS_ENTITY;  // read entity next
-            return PARSE_OK;
-        }
-        //
-        // not end; read header
-        //
-        if( tok_type != TT_IDENTIFIER ) {
-            return PARSE_FAILURE;   // didn't see header name
-        }
-
-        status = match( scanner, " : %R%c", &hdr_value );
-        if( status != PARSE_OK ) {
-            // pushback tokens; useful only on INCOMPLETE error
-            scanner->cursor = save_pos;
-            return status;
-        }
-        //
-        // add header
-        //
-
-        // find header
-        index = map_str_to_int( token.buf, token.length, Http_Header_Names,
-                                NUM_HTTP_HEADER_NAMES, FALSE );
-        if( index != -1 ) {
-
-            //Check if it is a soap header
-            if( Http_Header_Names[index].id == HDR_SOAPACTION ) {
-                parser->msg.method = SOAPMETHOD_POST;
-            }
-
-            header_id = Http_Header_Names[index].id;
-            orig_header =
-                httpmsg_find_hdr( &parser->msg, header_id, NULL );
-        } else {
-            header_id = HDR_UNKNOWN;
-
-            save_char = token.buf[token.length];
-            token.buf[token.length] = '\0';
-
-            orig_header = httpmsg_find_hdr_str( &parser->msg, token.buf );
-
-            token.buf[token.length] = save_char;    // restore
-        }
-
-        if( orig_header == NULL ) {
-            //
-            // add new header
-            //
-
-            header = ( http_header_t * ) malloc( sizeof( http_header_t ) );
-            if( header == NULL ) {
-                parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
-                return PARSE_FAILURE;
-            }
-            membuffer_init( &header->name_buf );
-            membuffer_init( &header->value );
-
-            // value can be 0 length
-            if( hdr_value.length == 0 ) {
-                hdr_value.buf = "\0";
-                hdr_value.length = 1;
-            }
-            // save in header in buffers
-            if( membuffer_assign
-                ( &header->name_buf, token.buf, token.length ) != 0
-                || membuffer_assign( &header->value, hdr_value.buf,
-                                     hdr_value.length ) != 0 ) {
-                // not enuf mem
-		free (header);
-                parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
-                return PARSE_FAILURE;
-            }
-
-            header->name.buf = header->name_buf.buf;
-            header->name.length = header->name_buf.length;
-            header->name_id = header_id;
-
-            ListAddTail( &parser->msg.headers, header );
-
-            //NNS:          ret = dlist_append( &parser->msg.headers, header );
-/** TODO: remove that? */
-            if( ret == UPNP_E_OUTOF_MEMORY ) {
-                parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
-                return PARSE_FAILURE;
-            }
-/** end of remove that? */
-        } else if( hdr_value.length > 0 ) {
-            //
-            // append value to existing header
-            //
-
-            // append space
-            ret = membuffer_append_str( &orig_header->value, ", " );
-
-            // append continuation of header value
-            ret2 = membuffer_append( &orig_header->value,
-                                     hdr_value.buf, hdr_value.length );
-
-            if( ret == UPNP_E_OUTOF_MEMORY || ret2 == UPNP_E_OUTOF_MEMORY ) {
-                // not enuf mem
-                parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
-                return PARSE_FAILURE;
-            }
-        }
-    }                           // end while
-
-}
-
-////////////////////////////////////////////////////////////////////////
-#ifdef HIGHLY_UNLIKELY
-// **************
-static parse_status_t
-parser_parse_headers_old( INOUT http_parser_t * parser )
-{
-    parse_status_t status;
-    memptr token;
-    memptr hdr_value;
-    token_type_t tok_type;
-    scanner_t *scanner = &parser->scanner;
-    size_t save_pos;
-    http_header_t *header;
-    int header_id;
-    int ret = 0;
-    int index;
-    http_header_t *orig_header;
-    char save_char;
-    int ret2,
-      ret3;
-
-    assert( parser->position == POS_HEADERS ||
-            parser->ent_position == ENTREAD_CHUNKY_HEADERS );
-
-    while( TRUE ) {
-        save_pos = scanner->cursor;
-
-        //
-        // check end of headers
-        //
-        status = scanner_get_token( scanner, &token, &tok_type );
-        if( status != PARSE_OK ) {
-            return status;
-        }
-
-        if( tok_type == TT_CRLF ) {
-            // end of headers
-            parser->position = POS_ENTITY;  // read entity next
-            return PARSE_OK;
-        }
-        //
-        // not end; read header
-        //
-        if( tok_type != TT_IDENTIFIER ) {
-            return PARSE_FAILURE;   // didn't see header name
-        }
-
-        status = match( scanner, " : %R%c", &hdr_value );
-        if( status != PARSE_OK ) {
-            // pushback tokens; useful only on INCOMPLETE error
-            scanner->cursor = save_pos;
-            return status;
-        }
-
-        //
-        // add header
-        //
-
-        // find header
-        index = map_str_to_int( token.buf, token.length, Http_Header_Names,
-                                NUM_HTTP_HEADER_NAMES, FALSE );
-        if( index != -1 ) {
-            header_id = Http_Header_Names[index].id;
-
-            orig_header =
-                httpmsg_find_hdr( &parser->msg, header_id, NULL );
-        } else {
-            header_id = HDR_UNKNOWN;
-
-            save_char = token.buf[token.length];
-            token.buf[token.length] = '\0';
-
-            orig_header = httpmsg_find_hdr_str( &parser->msg, token.buf );
-
-            token.buf[token.length] = save_char;    // restore
-        }
-
-        if( orig_header == NULL ) {
-            //
-            // add new header
-            //
-
-            header = ( http_header_t * ) malloc( sizeof( http_header_t ) );
-            if( header == NULL ) {
-                parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
-                return PARSE_FAILURE;
-            }
-            membuffer_init( &header->multi_hdr_buf );
-
-            header->name = token;
-            header->value = hdr_value;
-            header->name_id = header_id;
-
-            ret = dlist_append( &parser->msg.headers, header );
-            if( ret == UPNP_E_OUTOF_MEMORY ) {
-                parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
-                return PARSE_FAILURE;
-            }
-        } else if( hdr_value.length > 0 ) {
-            //
-            // append value to existing header
-            //
-
-            if( orig_header->multi_hdr_buf.buf == NULL ) {
-                // store in buffer
-                ret = membuffer_append( &orig_header->multi_hdr_buf,
-                                        orig_header->value.buf,
-                                        orig_header->value.length );
-            }
-            // append space
-            ret2 =
-                membuffer_append( &orig_header->multi_hdr_buf, ", ", 2 );
-
-            // append continuation of header value
-            ret3 = membuffer_append( &orig_header->multi_hdr_buf,
-                                     hdr_value.buf, hdr_value.length );
-
-            if( ret == UPNP_E_OUTOF_MEMORY ||
-                ret2 == UPNP_E_OUTOF_MEMORY ||
-                ret3 == UPNP_E_OUTOF_MEMORY ) {
-                // not enuf mem
-                parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
-                return PARSE_FAILURE;
-            }
-            // header value points to allocated buf
-            orig_header->value.buf = orig_header->multi_hdr_buf.buf;
-            orig_header->value.length = orig_header->multi_hdr_buf.length;
-        }
-    }                           // end while
-
-}
-#endif
-// ******************************
-
-/************************************************************************
-* Function: parser_parse_entity_using_clen								
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser ; HTTP Parser object
-*																		
-* Description: reads entity using content-length						
-*																		
-* Returns:																
-*	 PARSE_INCOMPLETE													
-*	 PARSE_FAILURE -- entity length > content-length value				
-*	 PARSE_SUCCESS														
-************************************************************************/
-static XINLINE parse_status_t
-parser_parse_entity_using_clen( INOUT http_parser_t * parser )
-{
-    //int entity_length;
-
-    assert( parser->ent_position == ENTREAD_USING_CLEN );
-
-    // determine entity (i.e. body) length so far
-    //entity_length = parser->msg.msg.length - parser->entity_start_position;
-    parser->msg.entity.length =
-        parser->msg.msg.length - parser->entity_start_position;
-
-    if( parser->msg.entity.length < parser->content_length ) {
-        // more data to be read
-        return PARSE_INCOMPLETE;
-    } else {
-        if( parser->msg.entity.length > parser->content_length ) {
-            // silently discard extra data
-            parser->msg.msg.buf[parser->entity_start_position +
-                                parser->content_length] = '\0';
-        }
-        // save entity length
-        parser->msg.entity.length = parser->content_length;
-
-        // save entity start ptr; (the very last thing to do)
-        parser->msg.entity.buf = parser->msg.msg.buf +
-            parser->entity_start_position;
-
-        // done reading entity
-        parser->position = POS_COMPLETE;
-        return PARSE_SUCCESS;
-    }
-}
-
-/************************************************************************
-* Function: parser_parse_chunky_body									
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser	; HTTP Parser object
-*																		
-* Description: Read data in the chunks									
-*																		
-* Returns:																
-*	 PARSE_INCOMPLETE													
-*	 PARSE_FAILURE -- entity length > content-length value				
-*	 PARSE_SUCCESS														
-************************************************************************/
-static XINLINE parse_status_t
-parser_parse_chunky_body( INOUT http_parser_t * parser )
-{
-    parse_status_t status;
-    size_t save_pos;
-
-    // if 'chunk_size' of bytes have been read; read next chunk
-    if( ( int )( parser->msg.msg.length - parser->scanner.cursor ) >=
-        parser->chunk_size ) {
-        // move to next chunk
-        parser->scanner.cursor += parser->chunk_size;
-        save_pos = parser->scanner.cursor;
-
-        //discard CRLF
-        status = match( &parser->scanner, "%c" );
-        if( status != PARSE_OK ) {
-            parser->scanner.cursor -= parser->chunk_size;   //move back
-            //parser->scanner.cursor = save_pos;
-            return status;
-        }
-
-        membuffer_delete( &parser->msg.msg, save_pos,
-                          ( parser->scanner.cursor - save_pos ) );
-        parser->scanner.cursor = save_pos;
-        parser->msg.entity.length += parser->chunk_size;    //update temp 
-        parser->ent_position = ENTREAD_USING_CHUNKED;
-        return PARSE_CONTINUE_1;
-    } else {
-        return PARSE_INCOMPLETE;    // need more data for chunk
-    }
-}
-
-/************************************************************************
-* Function: parser_parse_chunky_headers									
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser	; HTTP Parser object						
-*																		
-* Description: Read headers at the end of the chunked entity			
-*																		
-* Returns:																
-*	 PARSE_INCOMPLETE													
-*	 PARSE_FAILURE -- entity length > content-length value				
-*	 PARSE_SUCCESS														
-************************************************************************/
-static XINLINE parse_status_t
-parser_parse_chunky_headers( INOUT http_parser_t * parser )
-{
-    parse_status_t status;
-    size_t save_pos;
-
-    save_pos = parser->scanner.cursor;
-    status = parser_parse_headers( parser );
-    if( status == PARSE_OK ) {
-        // finally, done with the whole msg
-        parser->position = POS_COMPLETE;
-
-        membuffer_delete( &parser->msg.msg, save_pos,
-                          ( parser->scanner.cursor - save_pos ) );
-        parser->scanner.cursor = save_pos;
-
-        // save entity start ptr as the very last thing to do
-        parser->msg.entity.buf = parser->msg.msg.buf +
-            parser->entity_start_position;
-
-        return PARSE_SUCCESS;
-    } else {
-        return status;
-    }
-}
-
-/************************************************************************
-* Function: parser_parse_chunky_entity									
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser	- HTTP Parser Object									
-*																		
-* Description: Read headers at the end of the chunked entity			
-*																		
-* Returns:																
-*	 PARSE_INCOMPLETE													
-*	 PARSE_FAILURE -- entity length > content-length value				
-*	 PARSE_SUCCESS														
-*	 PARSE_CONTINUE_1													
-************************************************************************/
-static XINLINE parse_status_t
-parser_parse_chunky_entity( INOUT http_parser_t * parser )
-{
-    scanner_t *scanner = &parser->scanner;
-    parse_status_t status;
-    size_t save_pos;
-    memptr dummy;
-
-    assert( parser->ent_position == ENTREAD_USING_CHUNKED );
-
-    save_pos = scanner->cursor;
-
-    // get size of chunk, discard extension, discard CRLF
-    status = match( scanner, "%x%L%c", &parser->chunk_size, &dummy );
-    if( status != PARSE_OK ) {
-        scanner->cursor = save_pos;
-        DBGONLY( UpnpPrintf
-                 ( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                   "CHUNK COULD NOT BE PARSED\n" ); )
-            return status;
-    }
-    // remove chunk info just matched; just retain data
-    membuffer_delete( &parser->msg.msg, save_pos,
-                      ( scanner->cursor - save_pos ) );
-    scanner->cursor = save_pos; // adjust scanner too
-
-    if( parser->chunk_size == 0 ) {
-        // done reading entity; determine length of entity
-        parser->msg.entity.length = parser->scanner.cursor -
-            parser->entity_start_position;
-
-        // read entity headers
-        parser->ent_position = ENTREAD_CHUNKY_HEADERS;
-    } else {
-        // read chunk body
-        parser->ent_position = ENTREAD_CHUNKY_BODY;
-    }
-
-    return PARSE_CONTINUE_1;    // continue to reading body
-}
-
-/************************************************************************
-* Function: parser_parse_entity_until_close								
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser	; HTTP Parser object
-*																		
-* Description: Read headers at the end of the chunked entity			
-*																		
-* Returns:																
-*	 PARSE_INCOMPLETE_ENTITY											
-************************************************************************/
-static XINLINE parse_status_t
-parser_parse_entity_until_close( INOUT http_parser_t * parser )
-{
-    size_t cursor;
-
-    assert( parser->ent_position == ENTREAD_UNTIL_CLOSE );
-
-    // eat any and all data
-    cursor = parser->msg.msg.length;
-
-    // update entity length
-    parser->msg.entity.length = cursor - parser->entity_start_position;
-
-    // update pointer
-    parser->msg.entity.buf =
-        parser->msg.msg.buf + parser->entity_start_position;
-
-    parser->scanner.cursor = cursor;
-
-    return PARSE_INCOMPLETE_ENTITY; // add anything
-}
-
-/************************************************************************
-* Function: parser_get_entity_read_method								
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser	; HTTP Parser object					
-*																		
-* Description: Determines method to read entity							
-*																		
-* Returns:																
-*	 PARSE_OK															
-* 	 PARSE_FAILURE														
-*	 PARSE_COMPLETE	-- no more reading to do							
-************************************************************************/
-XINLINE parse_status_t
-parser_get_entity_read_method( INOUT http_parser_t * parser )
-{
-    http_message_t *hmsg = &parser->msg;
-    int response_code;
-    memptr hdr_value;
-
-    assert( parser->ent_position == ENTREAD_DETERMINE_READ_METHOD );
-
-    // entity points to start of msg body
-    parser->msg.entity.buf = scanner_get_str( &parser->scanner );
-    parser->msg.entity.length = 0;
-
-    // remember start of body
-    parser->entity_start_position = parser->scanner.cursor;
-
-    // std http rules for determining content length
-
-    // * no body for 1xx, 204, 304 and HEAD, GET,
-    //      SUBSCRIBE, UNSUBSCRIBE
-    if( hmsg->is_request ) {
-        switch ( hmsg->method ) {
-            case HTTPMETHOD_HEAD:
-            case HTTPMETHOD_GET:
-                //case HTTPMETHOD_POST:
-            case HTTPMETHOD_SUBSCRIBE:
-            case HTTPMETHOD_UNSUBSCRIBE:
-            case HTTPMETHOD_MSEARCH:
-                // no body; mark as done
-                parser->position = POS_COMPLETE;
-                return PARSE_SUCCESS;
-                break;
-
-            default:
-                ;               // do nothing
-        }
-    } else                      // response
-    {
-        response_code = hmsg->status_code;
-
-        if( response_code == 204 ||
-            response_code == 304 ||
-            ( response_code >= 100 && response_code <= 199 ) ||
-            hmsg->request_method == HTTPMETHOD_HEAD ||
-            hmsg->request_method == HTTPMETHOD_MSEARCH ||
-            hmsg->request_method == HTTPMETHOD_SUBSCRIBE ||
-            hmsg->request_method == HTTPMETHOD_UNSUBSCRIBE ||
-            hmsg->request_method == HTTPMETHOD_NOTIFY ) {
-            parser->position = POS_COMPLETE;
-            return PARSE_SUCCESS;
-        }
-    }
-
-    // * transfer-encoding -- used to indicate chunked data
-    if( httpmsg_find_hdr( hmsg, HDR_TRANSFER_ENCODING, &hdr_value ) ) {
-        if( raw_find_str( &hdr_value, "chunked" ) >= 0 ) {
-            // read method to use chunked transfer encoding
-            parser->ent_position = ENTREAD_USING_CHUNKED;
-            DBGONLY( UpnpPrintf
-                     ( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                       "Found Chunked Encoding ....\n" ); )
-
-                return PARSE_CONTINUE_1;
-        }
-    }
-    // * use content length
-    if( httpmsg_find_hdr( hmsg, HDR_CONTENT_LENGTH, &hdr_value ) ) {
-        parser->content_length = raw_to_int( &hdr_value, 10 );
-        if( parser->content_length < 0 ) {
-            // bad content-length
-            return PARSE_FAILURE;
-        }
-        parser->ent_position = ENTREAD_USING_CLEN;
-        return PARSE_CONTINUE_1;
-    }
-    // * multi-part/byteranges not supported (yet)
-
-    // * read until connection is closed
-    if( hmsg->is_request ) {
-        // set hack flag for NOTIFY methods; if set to true this is
-        //  a valid SSDP notify msg
-        if( hmsg->method == HTTPMETHOD_NOTIFY ) {
-            parser->valid_ssdp_notify_hack = TRUE;
-        }
-
-        parser->http_error_code = HTTP_LENGTH_REQUIRED;
-        return PARSE_FAILURE;
-    }
-
-    parser->ent_position = ENTREAD_UNTIL_CLOSE;
-    return PARSE_CONTINUE_1;
-}
-
-/************************************************************************
-* Function: parser_parse_entity											
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser	; HTTP Parser object					
-*																		
-* Description: Determines method to read entity							
-*																		
-* Returns:																
-*	 PARSE_OK															
-* 	 PARSE_FAILURE														
-*	 PARSE_COMPLETE	-- no more reading to do							
-************************************************************************/
-XINLINE parse_status_t
-parser_parse_entity( INOUT http_parser_t * parser )
-{
-    parse_status_t status = PARSE_OK;
-
-    assert( parser->position == POS_ENTITY );
-
-    do {
-        switch ( parser->ent_position ) {
-            case ENTREAD_USING_CLEN:
-                status = parser_parse_entity_using_clen( parser );
-                break;
-
-            case ENTREAD_USING_CHUNKED:
-                status = parser_parse_chunky_entity( parser );
-                break;
-
-            case ENTREAD_CHUNKY_BODY:
-                status = parser_parse_chunky_body( parser );
-                break;
-
-            case ENTREAD_CHUNKY_HEADERS:
-                status = parser_parse_chunky_headers( parser );
-                break;
-
-            case ENTREAD_UNTIL_CLOSE:
-                status = parser_parse_entity_until_close( parser );
-                break;
-
-            case ENTREAD_DETERMINE_READ_METHOD:
-                status = parser_get_entity_read_method( parser );
-                break;
-
-            default:
-                assert( 0 );
-        }
-
-    } while( status == PARSE_CONTINUE_1 );
-
-    return status;
-}
-
-/************************************************************************
-* Function: parser_request_init											
-*																		
-* Parameters:															
-*	OUT http_parser_t* parser ; HTTP Parser object									
-*																
-* Description: Initializes parser object for a request					
-*																		
-* Returns:																
-*	 void																
-************************************************************************/
-void
-parser_request_init( OUT http_parser_t * parser )
-{
-    parser_init( parser );
-    parser->msg.is_request = TRUE;
-    parser->position = POS_REQUEST_LINE;
-}
-
-/************************************************************************
-* Function: parser_response_init										
-*																		
-* Parameters:															
-*	OUT http_parser_t* parser	;	  HTTP Parser object
-*	IN http_method_t request_method	; Request method 					
-*																		
-* Description: Initializes parser object for a response					
-*																		
-* Returns:																
-*	 void																
-************************************************************************/
-void
-parser_response_init( OUT http_parser_t * parser,
-                      IN http_method_t request_method )
-{
-    parser_init( parser );
-    parser->msg.is_request = FALSE;
-    parser->msg.request_method = request_method;
-    parser->position = POS_RESPONSE_LINE;
-}
-
-/************************************************************************
-* Function: parser_parse												
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser ; HTTP Parser object					
-*																		
-* Description: The parser function. Depending on the position of the 	
-*	parser object the actual parsing function is invoked				
-*																		
-* Returns:																
-*	 void																
-************************************************************************/
-parse_status_t
-parser_parse( INOUT http_parser_t * parser )
-{
-    parse_status_t status;
-
-    //takes an http_parser_t with memory already allocated 
-    //in the message 
-    assert( parser != NULL );
-
-    do {
-        switch ( parser->position ) {
-            case POS_ENTITY:
-                status = parser_parse_entity( parser );
-
-                break;
-
-            case POS_HEADERS:
-                status = parser_parse_headers( parser );
-
-                break;
-
-            case POS_REQUEST_LINE:
-                status = parser_parse_requestline( parser );
-
-                break;
-
-            case POS_RESPONSE_LINE:
-                status = parser_parse_responseline( parser );
-
-                break;
-
-            default:
-                {
-                    status = PARSE_FAILURE;
-                    assert( 0 );
-                }
-        }
-
-    } while( status == PARSE_OK );
-
-    return status;
-
-}
-
-/************************************************************************
-* Function: parser_append												
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser ;	HTTP Parser Object					
-*	IN const char* buf	;			buffer to be appended to the parser 
-*									buffer							
-*	IN size_t buf_length ;			Size of the buffer												
-*																		
-* Description: The parser function. Depending on the position of the 	
-*	parser object the actual parsing function is invoked				
-*																		
-* Returns:																
-*	 void																
-************************************************************************/
-parse_status_t
-parser_append( INOUT http_parser_t * parser,
-               IN const char *buf,
-               IN size_t buf_length )
-{
-    int ret_code;
-
-    assert( parser != NULL );
-    assert( buf != NULL );
-
-    // append data to buffer
-    ret_code = membuffer_append( &parser->msg.msg, buf, buf_length );
-    if( ret_code != 0 ) {
-        // set failure status
-        parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
-        return PARSE_FAILURE;
-    }
-
-    return parser_parse( parser );
-}
-
-/************************************************************************
-**********					end of parser					  ***********
-************************************************************************/
-
-/************************************************************************
-* Function: raw_to_int													
-*																		
-* Parameters:															
-*	IN memptr* raw_value ;	Buffer to be converted 					
-*	IN int base ;			Base  to use for conversion
-*																		
-* Description: Converts raw character data to long-integer value					
-*																		
-* Returns:																
-*	 int																
-************************************************************************/
-off_t
-raw_to_int( IN memptr * raw_value,
-            IN int base )
-{
-    off_t num;
-    char *end_ptr;
-
-    if( raw_value->length == 0 ) {
-        return -1;
-    }
-
-    errno = 0;
-#if SIZEOF_OFF_T > 4
-        num = strtoll( raw_value->buf, &end_ptr, base );
-        if( ( num < 0 )
-                // all and only those chars in token should be used for num
-                || ( end_ptr != raw_value->buf + raw_value->length )
-                || ( ( num == LLONG_MIN || num == LLONG_MAX )
-                    && ( errno == ERANGE ) )
-          ) {
-            return -1;
-        }
-#else
-        num = strtol( raw_value->buf, &end_ptr, base );
-        if( ( num < 0 )
-                // all and only those chars in token should be used for num
-                || ( end_ptr != raw_value->buf + raw_value->length )
-                || ( ( num == LONG_MIN || num == LONG_MAX )
-                    && ( errno == ERANGE ) )
-          ) {
-            return -1;
-        }
-#endif
-    return num;
-
-}
-
-/************************************************************************
-* Function: raw_find_str												
-*																		
-* Parameters:															
-*	IN memptr* raw_value ; Buffer containg the string												
-*	IN const char* str ;	Substring to be found													
-*																		
-* Description: Find a substring from raw character string buffer					
-*																		
-* Returns:																
-*	 int - index at which the substring is found.						
-************************************************************************/
-int
-raw_find_str( IN memptr * raw_value,
-              IN const char *str )
-{
-    char c;
-    char *ptr;
-
-    c = raw_value->buf[raw_value->length];  // save
-    raw_value->buf[raw_value->length] = 0;  // null-terminate
-
-    ptr = strstr( raw_value->buf, str );
-
-    raw_value->buf[raw_value->length] = c;  // restore
-
-    if( ptr == 0 ) {
-        return -1;
-    }
-
-    return ptr - raw_value->buf;    // return index
-}
-
-/************************************************************************
-* Function: method_to_str												
-*																		
-* Parameters:															
-* IN http_method_t method ; HTTP method						
-*																		
-* Description: A wrapper function that maps a method id to a method		
-*	nameConverts a http_method id stored in the HTTP Method				
-*																		
-* Returns:																
-*	 const char* ptr - Ptr to the HTTP Method																							*
-************************************************************************/
-const char *
-method_to_str( IN http_method_t method )
-{
-    int index;
-
-    index = map_int_to_str( method, Http_Method_Table, NUM_HTTP_METHODS );
-
-    assert( index != -1 );
-
-    return index == -1 ? NULL : Http_Method_Table[index].name;
-}
-
-/************************************************************************
-* Function: print_http_headers											
-*																		
-* Parameters:															
-*	http_message_t* hmsg ; HTTP Message object									
-*																		
-* Description:															
-*																		
-* Returns:																
-*	 void																
-************************************************************************/
-void
-print_http_headers( http_message_t * hmsg )
-{
-
-    ListNode *node;
-
-    //NNS:  dlist_node *node;
-    //http_header_t *header;
-
-    // print start line
-    if( hmsg->is_request ) {
-        //printf( "method = %d, version = %d.%d, url = %.*s\n", 
-        //  hmsg->method, hmsg->major_version, hmsg->minor_version,
-        //  hmsg->uri.pathquery.size, hmsg->uri.pathquery.buff);
-    } else {
-        //  printf( "resp status = %d, version = %d.%d, status msg = %.*s\n",
-        //  hmsg->status_code, hmsg->major_version, hmsg->minor_version,
-        //  (int)hmsg->status_msg.length, hmsg->status_msg.buf);
-    }
-
-    // print headers
-
-    node = ListHead( &hmsg->headers );
-    //NNS: node = dlist_first_node( &hmsg->headers );
-    while( node != NULL ) {
-
-        //header = ( http_header_t * ) node->item;
-        //NNS: header = (http_header_t *)node->data;
-        //printf( "hdr name: %.*s, value: %.*s\n", 
-        //  (int)header->name.length, header->name.buf,
-        //  (int)header->value.length, header->value.buf );
-
-        node = ListNext( &hmsg->headers, node );
-
-        //NNS: node = dlist_next( &hmsg->headers, node );
-    }
-}
diff --git a/tombupnp/upnp/src/genlib/net/http/httpreadwrite.c b/tombupnp/upnp/src/genlib/net/http/httpreadwrite.c
deleted file mode 100644
index 37ed950..0000000
--- a/tombupnp/upnp/src/genlib/net/http/httpreadwrite.c
+++ /dev/null
@@ -1,2520 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/************************************************************************
-* Purpose: This file defines the functionality making use of the http 
-* It defines functions to receive messages, process messages, send 
-* messages
-************************************************************************/
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdarg.h>
-#include <stdio.h>
-
-#ifndef WIN32
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <sys/wait.h>
- #include <unistd.h>
- #include <sys/utsname.h>
- #include <fcntl.h>
- #include <inttypes.h>
-#else
- #include <winsock2.h>
- #include <malloc.h>
-#endif
-#include "unixutil.h"
-#include "upnp.h"
-#include "upnpapi.h"
-#include "membuffer.h"
-#include "uri.h"
-#include "statcodes.h"
-#include "httpreadwrite.h"
-#include "sock.h"
-#include "webserver.h"
-
-#define DOSOCKET_READ	1
-#define DOSOCKET_WRITE	0
-
-/************************************************************************
-* Function: http_FixUrl													
-*																		
-* Parameters:															
-*	IN uri_type* url ;			URL to be validated and fixed
-*	OUT uri_type* fixed_url ;	URL after being fixed.
-*																		
-* Description: Validates URL											
-*																		
-* Returns:																
-*	 UPNP_E_INVALID_URL													
-* 	 UPNP_E_SUCCESS														
-************************************************************************/
-int
-http_FixUrl( IN uri_type * url,
-             OUT uri_type * fixed_url )
-{
-    char *temp_path = "/";
-
-    *fixed_url = *url;
-
-    if( token_string_casecmp( &fixed_url->scheme, "http" ) != 0 ) {
-        return UPNP_E_INVALID_URL;
-    }
-
-    if( fixed_url->hostport.text.size == 0 ) {
-        return UPNP_E_INVALID_URL;
-    }
-    // set pathquery to "/" if it is empty
-    if( fixed_url->pathquery.size == 0 ) {
-        fixed_url->pathquery.buff = temp_path;
-        fixed_url->pathquery.size = 1;
-    }
-
-    return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-* Function: http_FixStrUrl												
-*																		
-* Parameters:															
-*	IN char* urlstr ; 			Character string as a URL											
-*	IN int urlstrlen ; 			Length of the character string								
-*	OUT uri_type* fixed_url	;	Fixed and corrected URL
-*																		
-* Description: Parses URL and then validates URL						
-*																		
-* Returns:																
-*	 UPNP_E_INVALID_URL													
-* 	 UPNP_E_SUCCESS														
-************************************************************************/
-int
-http_FixStrUrl( IN char *urlstr,
-                IN int urlstrlen,
-                OUT uri_type * fixed_url )
-{
-    uri_type url;
-
-    if( parse_uri( urlstr, urlstrlen, &url ) != HTTP_SUCCESS ) {
-        return UPNP_E_INVALID_URL;
-    }
-
-    return http_FixUrl( &url, fixed_url );
-}
-
-/************************************************************************
-* Function: http_Connect												
-*																		
-* Parameters:															
-*	IN uri_type* destination_url ; URL containing destination information					
-*	OUT uri_type *url ;			   Fixed and corrected URL
-*																		
-* Description: Gets destination address from URL and then connects to the 
-*	remote end
-*																		
-* Returns:																
-*	socket descriptor on sucess											
-*	UPNP_E_OUTOF_SOCKET													
-*	UPNP_E_SOCKET_CONNECT on error										
-************************************************************************/
-int
-http_Connect( IN uri_type * destination_url,
-              OUT uri_type * url )
-{
-    int connfd;
-
-    http_FixUrl( destination_url, url );
-
-    connfd = socket( AF_INET, SOCK_STREAM, 0 );
-    if( connfd == -1 ) {
-        return UPNP_E_OUTOF_SOCKET;
-    }
-
-    if( connect( connfd, ( struct sockaddr * )&url->hostport.IPv4address,
-                 sizeof( struct sockaddr_in ) ) == -1 ) {
-#ifdef WIN32
-		DBGONLY(
-			UpnpPrintf(UPNP_CRITICAL, HTTP, __FILE__, __LINE__,
-			"connect error: %d\n", WSAGetLastError());
-		)
-#endif
-        shutdown( connfd, SD_BOTH );
-        UpnpCloseSocket( connfd );
-        return UPNP_E_SOCKET_CONNECT;
-    }
-
-    return connfd;
-}
-
-/************************************************************************
-* Function: http_RecvMessage											
-*																		
-* Parameters:															
-*	IN SOCKINFO *info ;					Socket information object
-*	OUT http_parser_t* parser,			HTTP parser object
-*	IN http_method_t request_method ;	HTTP request method					
-*	IN OUT int* timeout_secs ;			time out											
-*	OUT int* http_error_code ;			HTTP error code returned
-*																		
-* Description: Get the data on the socket and take actions based on the 
-*	read data to modify the parser objects buffer. If an error is reported 
-*	while parsing the data, the error code is passed in the http_errr_code 
-*	parameter
-*																		
-* Returns:																
-*	 UPNP_E_BAD_HTTPMSG													
-* 	 UPNP_E_SUCCESS														
-************************************************************************/
-int
-http_RecvMessage( IN SOCKINFO * info,
-                  OUT http_parser_t * parser,
-                  IN http_method_t request_method,
-                  IN OUT int *timeout_secs,
-                  OUT int *http_error_code )
-{
-    parse_status_t status;
-    int num_read;
-    xboolean ok_on_close = FALSE;
-    char buf[2 * 1024];
-
-    if( request_method == HTTPMETHOD_UNKNOWN ) {
-        parser_request_init( parser );
-    } else {
-        parser_response_init( parser, request_method );
-    }
-
-    while( TRUE ) {
-        num_read = sock_read( info, buf, sizeof( buf ), timeout_secs );
-        if( num_read > 0 ) {
-            // got data
-            status = parser_append( parser, buf, num_read );
-
-            if( status == PARSE_SUCCESS ) {
-                DBGONLY( UpnpPrintf
-                         ( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                           "<<< (RECVD) <<<\n%s\n-----------------\n",
-                           parser->msg.msg.buf );
-                         //print_http_headers( &parser->msg );
-                     )
-
-                    if( parser->content_length > g_maxContentLength ) {
-                    *http_error_code = HTTP_REQ_ENTITY_TOO_LARGE;
-                    return UPNP_E_OUTOF_BOUNDS;
-                }
-
-                return 0;
-            } else if((status == PARSE_FAILURE ) || (status == PARSE_NO_MATCH)){
-                *http_error_code = parser->http_error_code;
-                return UPNP_E_BAD_HTTPMSG;
-            } else if( status == PARSE_INCOMPLETE_ENTITY ) {
-                // read until close
-                ok_on_close = TRUE;
-            } else if( status == PARSE_CONTINUE_1 ) //Web post request. murari
-            {
-                return PARSE_SUCCESS;
-            }
-        } else if( num_read == 0 ) {
-            if( ok_on_close ) {
-                DBGONLY( UpnpPrintf
-                         ( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                           "<<< (RECVD) <<<\n%s\n-----------------\n",
-                           parser->msg.msg.buf );
-                         //print_http_headers( &parser->msg );
-                     )
-
-                    return 0;
-            } else {
-                // partial msg
-                *http_error_code = HTTP_BAD_REQUEST;    // or response
-                return UPNP_E_BAD_HTTPMSG;
-            }
-        } else {
-            *http_error_code = parser->http_error_code;
-            return num_read;
-        }
-    }
-}
-
-/************************************************************************
-* Function: http_SendMessage											
-*																		
-* Parameters:															
-*	IN SOCKINFO *info ;		Socket information object
-*	IN OUT int * TimeOut ; 	time out value											
-*	IN const char* fmt, ...	 Pattern format to take actions upon								
-*																		
-* Description: Sends a message to the destination based on the			
-*	IN const char* fmt parameter										
-*	fmt types:															
-*		'f':	arg = const char * file name							
-*		'b':	arg1 = const char * mem_buffer; arg2= size_t buf_length	
-*	E.g.:																
-*		char *buf = "POST /xyz.cgi http/1.1\r\n\r\n";					
-*		char *filename = "foo.dat";										
-*		int status = http_SendMessage( tcpsock, "mf",					
-*					buf, strlen(buf),	// args for memory buffer		
-*					filename );			// arg for file					
-*																		
-* Returns:																
-*	UPNP_E_OUTOF_MEMORY													
-* 	UPNP_E_FILE_READ_ERROR												
-*	UPNP_E_SUCCESS														
-************************************************************************/
-int
-http_SendMessage( IN SOCKINFO * info,
-                  IN OUT int *TimeOut,
-                  IN const char *fmt,
-                  ... )
-{
-#define CHUNK_HEADER_SIZE 10
-#define CHUNK_TAIL_SIZE 10
-
-    char c;
-    char *buf = NULL;
-    size_t buf_length;
-    char *filename = NULL;
-    UpnpWebFileHandle *Fh = NULL;
-    FILE *Fp = NULL;
-    off_t num_read = -1,
-      num_written,
-      amount_to_be_read = 0;
-    va_list argp;
-    char *file_buf = NULL,
-     *ChunkBuf = NULL;
-    struct SendInstruction *Instr = NULL;
-    char Chunk_Header[10];
-    int RetVal = 0;
-
-    // 10 byte allocated for chunk header.
-    off_t Data_Buf_Size = WEB_SERVER_BUF_SIZE;
-
-    va_start( argp, fmt );
-
-    while( ( c = *fmt++ ) != 0 ) {
-        if( c == 'I' ) {
-            Instr = ( struct SendInstruction * )
-                va_arg( argp, struct SendInstruction * );
-
-            assert( Instr );
-
-            if( Instr->ReadSendSize >= 0 )
-                amount_to_be_read = Instr->ReadSendSize;
-            else
-                amount_to_be_read = Data_Buf_Size;
-
-            if( amount_to_be_read < WEB_SERVER_BUF_SIZE )
-                Data_Buf_Size = amount_to_be_read;
-
-            ChunkBuf = ( char * )malloc( Data_Buf_Size +
-                                         CHUNK_HEADER_SIZE +
-                                         CHUNK_TAIL_SIZE );
-            if( !ChunkBuf )
-                return UPNP_E_OUTOF_MEMORY;
-
-            file_buf = ChunkBuf + 10;
-        }
-
-        if( c == 'f' ) {        // file name
-
-            filename = ( char * )va_arg( argp, char * );
-            Fh = (  UpnpWebFileHandle *)va_arg( argp, UpnpWebFileHandle *);
-
-            if( !(Instr && Instr->IsVirtualFile) )
-//            if( Instr && Instr->IsVirtualFile )
-//              Fh = (  UpnpWebFileHandle *)va_arg( argp, UpnpWebFileHandle *);
-                //Fp = virtualDirCallback.open( filename, UPNP_READ );
-//            else
-                Fp = fopen( filename, "rb" );
-
-            if( (Fp == NULL) && (Fh == NULL) ){
-                free( ChunkBuf );
-                return UPNP_E_FILE_READ_ERROR;
-            }
-
-//            assert( Fp );
-
-            if( Instr && Instr->IsRangeActive && Instr->IsVirtualFile ) {
-                if( virtualDirCallback.seek( Fh, Instr->RangeOffset,
-                                             SEEK_CUR ) != 0 ) {
-                    free( ChunkBuf );
-                    return UPNP_E_FILE_READ_ERROR;
-                }
-            } else if( Instr && Instr->IsRangeActive ) {
-                if( fseeko( Fp, Instr->RangeOffset, SEEK_CUR ) != 0 ) {
-                    free( ChunkBuf );
-                    return UPNP_E_FILE_READ_ERROR;
-                }
-            }
-
-            while( amount_to_be_read ) {
-                if( Instr ) {
-                    if( amount_to_be_read >= Data_Buf_Size ) {
-                        if( Instr->IsVirtualFile )
-                            num_read = virtualDirCallback.read( Fh,
-                                                                file_buf,
-                                                                Data_Buf_Size );
-                        else
-                            num_read = fread( file_buf, 1, Data_Buf_Size,
-                                              Fp );
-                    } else {
-                        if( Instr->IsVirtualFile )
-                            num_read = virtualDirCallback.read( Fh,
-                                                                file_buf,
-                                                                amount_to_be_read );
-                        else
-                            num_read = fread( file_buf, 1,
-                                              amount_to_be_read, Fp );
-                    }
-                    // HACK: we don't want a read that will block
-                    // indefinetely, so we will return -666 in the callback
-                    // to indicate that this code should not write to the
-                    // socket but just check if the socket is still ok and
-                    // then read again
-                    if (num_read < 0)
-                    {
-                        if ((Instr->IsVirtualFile) && (num_read == -666))
-                        {
-                            if (sock_check_w(info) == 1)
-                            {
-//                                printf("SOCKET IS OK!\n");
-                                continue;
-                            }
-                        
-//                            printf("SOCKET IS NOT OK!\n");
-                        }
-                        RetVal = UPNP_E_FILE_READ_ERROR; 
-                        goto Cleanup_File;
-                    }
-                    amount_to_be_read = amount_to_be_read - num_read;
-
-                    if( Instr->ReadSendSize < 0 ) {
-                        //read until close
-                        amount_to_be_read = Data_Buf_Size;
-                    }
-                } else {
-                    num_read = fread( file_buf, 1, Data_Buf_Size, Fp );
-                }
-
-                if( num_read == 0 ) // EOF so no more to send.
-                {
-                    if( Instr && Instr->IsChunkActive ) {
-                        num_written = sock_write( info, "0\r\n\r\n",
-                                                  strlen( "0\r\n\r\n" ),
-                                                  TimeOut );
-                    } else {
-                        RetVal = UPNP_E_FILE_READ_ERROR;
-                    }
-                    goto Cleanup_File;
-                }
-                // Create chunk for the current buffer.
-                if( Instr && Instr->IsChunkActive ) {
-                    //Copy CRLF at the end of the chunk
-                    memcpy( file_buf + num_read, "\r\n", 2 );
-
-                    //Hex length for the chunk size.
-                    sprintf( Chunk_Header, "%"PRIx64, (int64_t)num_read );
-
-                    //itoa(num_read,Chunk_Header,16); 
-                    strcat( Chunk_Header, "\r\n" );
-
-                    //Copy the chunk size header 
-                    memcpy( file_buf - strlen( Chunk_Header ),
-                            Chunk_Header, strlen( Chunk_Header ) );
-
-                    // on the top of the buffer.
-                    //file_buf[num_read+strlen(Chunk_Header)] = NULL;
-                    //printf("Sending %s\n",file_buf-strlen(Chunk_Header));
-                    num_written = sock_write( info,
-                                              file_buf -
-                                              strlen( Chunk_Header ),
-                                              num_read +
-                                              strlen( Chunk_Header ) + 2,
-                                              TimeOut );
-
-                    if( num_written !=
-                        num_read + ( int )strlen( Chunk_Header )
-                        + 2 ) {
-                        goto Cleanup_File;  //Send error nothing we can do.
-                    }
-                } else {
-                    // write data
-                    num_written = sock_write( info, file_buf, num_read,
-                                              TimeOut );
-
-                    DBGONLY( UpnpPrintf
-                             ( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                               ">>> (SENT) >>>\n%.*s\n------------\n",
-                               ( int )num_written, file_buf );
-                         )
-
-                        //Send error nothing we can do
-                        if( num_written != num_read ) {
-                        goto Cleanup_File;
-                    }
-                }
-            }                   //While
-            // patch from the maemo forums
-            // https://garage.maemo.org/tracker/index.php?func=detail&aid=88&group_id=74&atid=341
-            if( num_read != 0 ) // not really necessary
-            {
-                if( Instr && Instr->IsChunkActive) {
-                    num_written = sock_write( info,
-                                              "0\r\n\r\n",
-                                              strlen("0\r\n\r\n"),
-                                              TimeOut );
-                } else {
-                    RetVal = UPNP_E_FILE_READ_ERROR;
-                }
-            }
-            // --            
-          Cleanup_File:
-            va_end( argp );
-            if( Instr && Instr->IsVirtualFile )
-                virtualDirCallback.close( Fh );
-            else
-                fclose( Fp );
-            free( ChunkBuf );
-            return RetVal;
-
-        } else if( c == 'b' ) { // memory buffer
-
-            buf = ( char * )va_arg( argp, char * );
-
-            buf_length = ( size_t ) va_arg( argp, size_t );
-            if( buf_length > 0 ) {
-                num_written = sock_write( info, buf, buf_length, TimeOut );
-                if( ( size_t ) num_written != buf_length )
-                    goto end;
-                DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                                     ">>> (SENT) >>>\n%.*s\n------------\n",
-                                     ( int )buf_length, buf );
-                     )
-            }
-        }
-    }
-
-  end:
-    va_end( argp );
-    free( ChunkBuf );
-    return 0;
-}
-
-/************************************************************************
-* Function: http_RequestAndResponse										
-*																		
-* Parameters:															
-*	IN uri_type* destination ;		Destination URI object which contains 
-*									remote IP address among other elements
-*	IN const char* request ;		Request to be sent
-*	IN size_t request_length ;		Length of the request
-*	IN http_method_t req_method ;	HTTP Request method
-*	IN int timeout_secs ;			time out value
-*	OUT http_parser_t* response	;	Parser object to receive the repsonse
-*																		
-* Description: Initiates socket, connects to the destination, sends a	
-*	request and waits for the response from the remote end				
-*																		
-* Returns:																
-*	UPNP_E_SOCKET_ERROR													
-* 	UPNP_E_SOCKET_CONNECT												
-*	Error Codes returned by http_SendMessage							
-*	Error Codes returned by http_RecvMessage							
-************************************************************************/
-int
-http_RequestAndResponse( IN uri_type * destination,
-                         IN const char *request,
-                         IN size_t request_length,
-                         IN http_method_t req_method,
-                         IN int timeout_secs,
-                         OUT http_parser_t * response )
-{
-    int tcp_connection;
-    int ret_code;
-    int http_error_code;
-    SOCKINFO info;
-
-    tcp_connection = socket( AF_INET, SOCK_STREAM, 0 );
-    if( tcp_connection == -1 ) {
-        parser_response_init( response, req_method );
-        return UPNP_E_SOCKET_ERROR;
-    }
-    if( sock_init( &info, tcp_connection ) != UPNP_E_SUCCESS )
-    {
-        sock_destroy( &info, SD_BOTH );
-        parser_response_init( response, req_method );
-        return UPNP_E_SOCKET_ERROR;
-    }
-    // connect
-    ret_code = connect( info.socket,
-                        ( struct sockaddr * )&destination->hostport.
-                        IPv4address, sizeof( struct sockaddr_in ) );
-
-    if( ret_code == -1 ) {
-        sock_destroy( &info, SD_BOTH );
-        parser_response_init( response, req_method );
-        return UPNP_E_SOCKET_CONNECT;
-    }
-    // send request
-    ret_code = http_SendMessage( &info, &timeout_secs, "b",
-                                 request, (size_t)request_length );
-    if( ret_code != 0 ) {
-        sock_destroy( &info, SD_BOTH );
-        parser_response_init( response, req_method );
-        return ret_code;
-    }
-    // recv response
-    ret_code = http_RecvMessage( &info, response, req_method,
-                                 &timeout_secs, &http_error_code );
-
-    sock_destroy( &info, SD_BOTH ); //should shutdown completely
-
-    return ret_code;
-}
-
-/************************************************************************
-*	Function :	http_Download
-*
-*	Parameters :
-*		IN const char* url_str :	String as a URL
-*		IN int timeout_secs :		time out value
-*		OUT char** document :		buffer to store the document extracted
-*									from the donloaded message.
-*		OUT int* doc_length :		length of the extracted document
-*	    OUT char* content_type :	Type of content
-*
-*	Description :	Download the document message and extract the document 
-*		from the message.
-*
-*	Return : int;
-*		UPNP_E_SUCCESS;
-*		UPNP_E_INVALID_URL;
-*			
-*
-*	Note :
-************************************************************************/
-int
-http_Download( IN const char *url_str,
-               IN int timeout_secs,
-               OUT char **document,
-               OUT int *doc_length,
-               OUT char *content_type )
-{
-    int ret_code;
-    uri_type url;
-    char *msg_start,
-     *entity_start,
-     *hoststr,
-     *temp;
-    http_parser_t response;
-    size_t hostlen;
-    memptr ctype;
-    size_t copy_len;
-    membuffer request;
-    char *urlPath = alloca( strlen( url_str ) + 1 );
-
-    //ret_code = parse_uri( (char*)url_str, strlen(url_str), &url );
-    DBGONLY( UpnpPrintf
-             ( UPNP_INFO, HTTP, __FILE__, __LINE__, "DOWNLOAD URL : %s\n",
-               url_str );
-         )
-        ret_code =
-        http_FixStrUrl( ( char * )url_str, strlen( url_str ), &url );
-    if( ret_code != UPNP_E_SUCCESS ) {
-        return ret_code;
-    }
-    // make msg
-    membuffer_init( &request );
-
-    strcpy( urlPath, url_str );
-    hoststr = strstr( urlPath, "//" );
-    if( hoststr == NULL ) {
-        return UPNP_E_INVALID_URL;
-    }
-
-    hoststr += 2;
-    temp = strchr( hoststr, '/' );
-    if( temp == NULL ) {
-        return UPNP_E_INVALID_URL;
-    }
-
-    *temp = '\0';
-    hostlen = strlen( hoststr );
-    *temp = '/';
-    DBGONLY( UpnpPrintf
-             ( UPNP_INFO, HTTP, __FILE__, __LINE__,
-               "HOSTNAME : %s Length : %zu\n", hoststr, hostlen );
-         )
-
-        ret_code = http_MakeMessage( &request, 1, 1, "QsbcDCUc",
-                                     HTTPMETHOD_GET, url.pathquery.buff,
-                                     (size_t)url.pathquery.size, "HOST: ", 
-                                     hoststr, (size_t)hostlen );
-    if( ret_code != 0 ) {
-        DBGONLY( UpnpPrintf
-                 ( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                   "HTTP Makemessage failed\n" );
-             )
-            membuffer_destroy( &request );
-        return ret_code;
-    }
-
-    DBGONLY( UpnpPrintf
-             ( UPNP_INFO, HTTP, __FILE__, __LINE__,
-               "HTTP Buffer:\n %s\n----------END--------\n", request.buf );
-         )
-        // get doc msg
-        ret_code =
-        http_RequestAndResponse( &url, request.buf, request.length,
-                                 HTTPMETHOD_GET, timeout_secs, &response );
-
-    if( ret_code != 0 ) {
-        httpmsg_destroy( &response.msg );
-        membuffer_destroy( &request );
-        return ret_code;
-    }
-
-    DBGONLY( UpnpPrintf
-             ( UPNP_INFO, HTTP, __FILE__, __LINE__, "Response\n" );
-         )
-        DBGONLY( print_http_headers( &response.msg );
-         )
-
-        // optional content-type
-        if( content_type ) {
-        if( httpmsg_find_hdr( &response.msg, HDR_CONTENT_TYPE, &ctype ) ==
-            NULL ) {
-            *content_type = '\0';   // no content-type
-        } else {
-            // safety
-            copy_len = ctype.length < LINE_SIZE - 1 ?
-                ctype.length : LINE_SIZE - 1;
-
-            memcpy( content_type, ctype.buf, copy_len );
-            content_type[copy_len] = '\0';
-        }
-    }
-    //
-    // extract doc from msg
-    //
-
-    if( ( *doc_length = ( int )response.msg.entity.length ) == 0 ) {
-        // 0-length msg
-        *document = NULL;
-    } else if( response.msg.status_code == HTTP_OK )    //LEAK_FIX_MK
-    {
-        // copy entity
-        entity_start = response.msg.entity.buf; // what we want
-        msg_start = membuffer_detach( &response.msg.msg );  // whole msg
-
-        // move entity to the start; copy null-terminator too
-        memmove( msg_start, entity_start, *doc_length + 1 );
-
-        // save mem for body only
-        *document = realloc( msg_start, *doc_length + 1 );  //LEAK_FIX_MK
-
-        // shrink can't fail
-        assert( *document != NULL );
-    }
-
-    if( response.msg.status_code == HTTP_OK ) {
-        ret_code = 0;           // success
-    } else {
-        // server sent error msg (not requested doc)
-        ret_code = response.msg.status_code;
-    }
-
-    httpmsg_destroy( &response.msg );
-    membuffer_destroy( &request );
-
-    return ret_code;
-}
-
-typedef struct HTTPPOSTHANDLE {
-    SOCKINFO sock_info;
-    int contentLength;
-} http_post_handle_t;
-
-/************************************************************************
-* Function: MakePostMessage												
-*																		
-* Parameters:															
-*	const char *url_str ;		String as a URL
-*	membuffer *request ;		Buffer containing the request									
-*	uri_type *url ; 			URI object containing the scheme, path 
-*								query token, etc.
-*	off_t contentLength ;			length of content
-*	const char *contentType	;	Type of content
-*																		
-* Description: Makes the message for the HTTP POST message				
-*																		
-* Returns:																
-*	UPNP_E_INVALID_URL													
-* 	UPNP_E_INVALID_PARAM												
-*	UPNP_E_SUCCESS														
-************************************************************************/
-int
-MakePostMessage( const char *url_str,
-                 membuffer * request,
-                 uri_type * url,
-                 off_t contentLength,
-                 const char *contentType )
-{
-    int ret_code = 0;
-    char *urlPath = alloca( strlen( url_str ) + 1 );
-    int hostlen = 0;
-    char *hoststr,
-     *temp;
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                         "DOWNLOAD URL : %s\n", url_str );
-         )
-
-        ret_code =
-        http_FixStrUrl( ( char * )url_str, strlen( url_str ), url );
-
-    if( ret_code != UPNP_E_SUCCESS ) {
-        return ret_code;
-    }
-    // make msg
-    membuffer_init( request );
-
-    strcpy( urlPath, url_str );
-    hoststr = strstr( urlPath, "//" );
-    if( hoststr == NULL ) {
-        return UPNP_E_INVALID_URL;
-    }
-
-    hoststr += 2;
-    temp = strchr( hoststr, '/' );
-    if( temp == NULL ) {
-        return UPNP_E_INVALID_URL;
-    }
-
-    *temp = '\0';
-    hostlen = strlen( hoststr );
-    *temp = '/';
-    DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                         "HOSTNAME : %s Length : %d\n", hoststr, hostlen );
-         )
-
-        if( contentLength >= 0 ) {
-        ret_code = http_MakeMessage( request, 1, 1, "QsbcDCUTNc",
-                                     HTTPMETHOD_POST, url->pathquery.buff,
-                                     (size_t)(url->pathquery.size), "HOST: ",
-                                     hoststr, (size_t)hostlen, contentType,
-                                     contentLength );
-    } else if( contentLength == UPNP_USING_CHUNKED ) {
-        ret_code = http_MakeMessage( request, 1, 1, "QsbcDCUTKc",
-                                     HTTPMETHOD_POST, url->pathquery.buff,
-                                     (size_t)(url->pathquery.size), "HOST: ",
-                                     hoststr, (size_t)hostlen, contentType );
-    } else if( contentLength == UPNP_UNTIL_CLOSE ) {
-        ret_code = http_MakeMessage( request, 1, 1, "QsbcDCUTc",
-                                     HTTPMETHOD_POST, url->pathquery.buff,
-                                     (size_t)(url->pathquery.size), "HOST: ",
-                                     hoststr, (size_t)hostlen, contentType );
-    } else {
-        ret_code = UPNP_E_INVALID_PARAM;
-    }
-
-    if( ret_code != 0 ) {
-        DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                             "HTTP Makemessage failed\n" );
-             )
-            membuffer_destroy( request );
-        return ret_code;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                         "HTTP Buffer:\n %s\n" "----------END--------\n",
-                         request->buf );
-         )
-
-        return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-*	Function :	http_WriteHttpPost
-*
-*	Parameters :
-*		IN void *Handle :		Handle to the http post object
-*		IN char *buf :			Buffer to send to peer, if format used
-*								is not UPNP_USING_CHUNKED, 
-*		IN off_t *size :	Size of the data to be sent.
-*		IN int timeout :		time out value
-*
-*	Description :	Formats data if format used is UPNP_USING_CHUNKED.
-*		Writes data on the socket connected to the peer.
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Success
-*		UPNP_E_INVALID_PARAM - Invalid Parameter
-*		-1 - On Socket Error.
-*
-*	Note :
-************************************************************************/
-int
-http_WriteHttpPost( IN void *Handle,
-                    IN char *buf,
-                    IN off_t *size,
-                    IN int timeout )
-{
-    http_post_handle_t *handle = ( http_post_handle_t * ) Handle;
-    char *tempbuf = NULL;
-    int tempbufSize = 0;
-    int freeTempbuf = 0;
-    int numWritten = 0;
-
-    if( ( !handle ) || ( !size ) || ( ( ( *size ) > 0 ) && !buf )
-        || ( ( *size ) < 0 ) ) {
-        if(size) ( *size ) = 0;
-        return UPNP_E_INVALID_PARAM;
-    }
-    if( handle->contentLength == UPNP_USING_CHUNKED ) {
-        if( ( *size ) ) {
-            int tempSize = 0;
-
-            tempbuf =
-                ( char * )malloc( ( *size ) + CHUNK_HEADER_SIZE +
-                                  CHUNK_TAIL_SIZE );
-
-            if ( tempbuf == NULL) return UPNP_E_OUTOF_MEMORY;
-
-            sprintf( tempbuf, "%"PRIx64 "\r\n", (int64_t)( *size ) );    //begin chunk
-            tempSize = strlen( tempbuf );
-            memcpy( tempbuf + tempSize, buf, ( *size ) );
-            memcpy( tempbuf + tempSize + ( *size ), "\r\n", 2 );    //end of chunk
-            tempbufSize = tempSize + ( *size ) + 2;
-            freeTempbuf = 1;
-        }
-    } else {
-        tempbuf = buf;
-        tempbufSize = ( *size );
-    }
-
-    numWritten =
-        sock_write( &handle->sock_info, tempbuf, tempbufSize, &timeout );
-    //(*size) = sock_write(&handle->sock_info,tempbuf,tempbufSize,&timeout);
-
-    if( freeTempbuf ) {
-        free( tempbuf );
-    }
-    if( numWritten < 0 ) {
-        ( *size ) = 0;
-        return numWritten;
-    } else {
-        ( *size ) = numWritten;
-        return UPNP_E_SUCCESS;
-    }
-}
-
-/************************************************************************
-*	Function :	http_CloseHttpPost
-*
-*	Parameters :
-*		IN void *Handle :			Handle to the http post object
-*		IN OUT int *httpStatus :	HTTP status returned on receiving a
-*									response message
-*		IN int timeout :			time out value
-*
-*	Description :	Sends remaining data if using  UPNP_USING_CHUNKED 
-*		format. Receives any more messages. Destroys socket and any socket
-*		associated memory. Frees handle associated with the HTTP POST msg.
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Sucess ;
-*		UPNP_E_INVALID_PARAM  - Invalid Parameter;
-*
-*	Note :
-************************************************************************/
-int
-http_CloseHttpPost( IN void *Handle,
-                    IN OUT int *httpStatus,
-                    IN int timeout )
-{
-    int retc = 0;
-    http_parser_t response;
-    int http_error_code;
-
-    http_post_handle_t *handle = Handle;
-
-    if( ( !handle ) || ( !httpStatus ) ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    if( handle->contentLength == UPNP_USING_CHUNKED ) {
-        retc = sock_write( &handle->sock_info, "0\r\n\r\n", strlen( "0\r\n\r\n" ), &timeout );  //send last chunk
-    }
-    //read response
-    parser_response_init( &response, HTTPMETHOD_POST );
-
-    retc =
-        http_RecvMessage( &handle->sock_info, &response, HTTPMETHOD_POST,
-                          &timeout, &http_error_code );
-
-    ( *httpStatus ) = http_error_code;
-
-    sock_destroy( &handle->sock_info, SD_BOTH );    //should shutdown completely
-
-    httpmsg_destroy( &response.msg );
-    free( handle );
-
-    return retc;
-}
-
-/************************************************************************
-*	Function :	http_OpenHttpPost
-*
-*	Parameters :
-*		IN const char *url_str :		String as a URL	
-*		IN OUT void **Handle :			Pointer to buffer to store HTTP
-*										post handle
-*		IN const char *contentType :	Type of content
-*		IN off_t contentLength :			length of content
-*		IN int timeout :				time out value
-*
-*	Description :	Makes the HTTP POST message, connects to the peer, 
-*		sends the HTTP POST request. Adds the post handle to buffer of 
-*		such handles
-*
-*	Return : int;
-*		UPNP_E_SUCCESS - On Sucess ;
-*		UPNP_E_INVALID_PARAM - Invalid Paramter ;
-*		UPNP_E_OUTOF_MEMORY ;
-*		UPNP_E_SOCKET_ERROR ;
-*		UPNP_E_SOCKET_CONNECT ;
-*
-*	Note :
-************************************************************************/
-int
-http_OpenHttpPost( IN const char *url_str,
-                   IN OUT void **Handle,
-                   IN const char *contentType,
-                   IN off_t contentLength,
-                   IN int timeout )
-{
-    int ret_code;
-    int tcp_connection;
-    membuffer request;
-    http_post_handle_t *handle = NULL;
-    uri_type url;
-
-    if( ( !url_str ) || ( !Handle ) || ( !contentType ) ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    ( *Handle ) = handle;
-
-    if( ( ret_code =
-          MakePostMessage( url_str, &request, &url, contentLength,
-                           contentType ) ) != UPNP_E_SUCCESS ) {
-        return ret_code;
-    }
-
-    handle =
-        ( http_post_handle_t * ) malloc( sizeof( http_post_handle_t ) );
-
-    if( handle == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    handle->contentLength = contentLength;
-
-    tcp_connection = socket( AF_INET, SOCK_STREAM, 0 );
-    if( tcp_connection == -1 ) {
-        ret_code = UPNP_E_SOCKET_ERROR;
-        goto errorHandler;
-    }
-
-    if( sock_init( &handle->sock_info, tcp_connection ) != UPNP_E_SUCCESS )
-    {
-        sock_destroy( &handle->sock_info, SD_BOTH );
-        ret_code = UPNP_E_SOCKET_ERROR;
-        goto errorHandler;
-    }
-
-    ret_code = connect( handle->sock_info.socket,
-                        ( struct sockaddr * )&url.hostport.IPv4address,
-                        sizeof( struct sockaddr_in ) );
-
-    if( ret_code == -1 ) {
-        sock_destroy( &handle->sock_info, SD_BOTH );
-        ret_code = UPNP_E_SOCKET_CONNECT;
-        goto errorHandler;
-    }
-    // send request
-    ret_code = http_SendMessage( &handle->sock_info, &timeout, "b",
-                                 request.buf, (size_t)request.length );
-    if( ret_code != 0 ) {
-        sock_destroy( &handle->sock_info, SD_BOTH );
-    }
-
-  errorHandler:
-    membuffer_destroy( &request );
-    ( *Handle ) = handle;
-    return ret_code;
-}
-
-typedef struct HTTPGETHANDLE {
-    http_parser_t response;
-    SOCKINFO sock_info;
-    int entity_offset;
-    int cancel;
-} http_get_handle_t;
-
-/************************************************************************
-* Function: MakeGetMessage												
-*																		
-* Parameters:															
-*	const char *url_str ;	String as a URL
-*	const char *proxy_str ;	String as a URL of proxy to use
-*	membuffer *request ;	Buffer containing the request									
-*	uri_type *url ; 		URI object containing the scheme, path 
-*							query token, etc.
-*																		
-* Description: Makes the message for the HTTP GET method				
-*																		
-* Returns:																
-*	UPNP_E_INVALID_URL													
-* 	Error Codes returned by http_MakeMessage							
-*	UPNP_E_SUCCESS														
-************************************************************************/
-int
-MakeGetMessage( const char *url_str,
-                const char *proxy_str,
-                membuffer * request,
-                uri_type * url )
-{
-    int ret_code;
-    char *urlPath = alloca( strlen( url_str ) + 1 );
-    int querylen = 0;
-    const char *querystr;
-    int hostlen = 0;
-    char *hoststr,
-     *temp;
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                         "DOWNLOAD URL : %s\n", url_str );
-         )
-
-        ret_code =
-        http_FixStrUrl( ( char * )url_str, strlen( url_str ), url );
-
-    if( ret_code != UPNP_E_SUCCESS ) {
-        return ret_code;
-    }
-    // make msg
-    membuffer_init( request );
-
-    strcpy( urlPath, url_str );
-    hoststr = strstr( urlPath, "//" );
-    if( hoststr == NULL ) {
-        return UPNP_E_INVALID_URL;
-    }
-
-    hoststr += 2;
-    temp = strchr( hoststr, '/' );
-    if( temp == NULL ) {
-        return UPNP_E_INVALID_URL;
-    }
-
-    *temp = '\0';
-    hostlen = strlen( hoststr );
-    *temp = '/';
-    DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                         "HOSTNAME : %s Length : %d\n", hoststr, hostlen );
-         )
-
-    if( proxy_str ) {
-        querystr = url_str;
-        querylen = strlen( querystr );
-    } else {
-        querystr = url->pathquery.buff;
-        querylen = url->pathquery.size;
-    }
-
-    ret_code = http_MakeMessage( request, 1, 1, "QsbcDCUc",
-                                 HTTPMETHOD_GET, querystr, (size_t)querylen,
-                                 "HOST: ", hoststr, (size_t)hostlen );
-
-    if( ret_code != 0 ) {
-        DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                             "HTTP Makemessage failed\n" );
-             )
-            membuffer_destroy( request );
-        return ret_code;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                         "HTTP Buffer:\n %s\n" "----------END--------\n",
-                         request->buf );
-         )
-
-        return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-*	Function :	ReadResponseLineAndHeaders
-*
-*	Parameters :
-*		IN SOCKINFO *info ;				Socket information object
-*		IN OUT http_parser_t *parser ;	HTTP Parser object
-*		IN OUT int *timeout_secs ;		time out value
-*		IN OUT int *http_error_code ;	HTTP errror code returned
-*
-*	Description : Parses already exiting data. If not complete reads more 
-*		data on the connected socket. The read data is then parsed. The 
-*		same methid is carried out for headers.
-*
-*	Return : int ;
-*		PARSE_OK - On Success
-*		PARSE_FAILURE - Failure to parse data correctly
-*		UPNP_E_BAD_HTTPMSG - Socker read() returns an error
-*
-*	Note :
-************************************************************************/
-int
-ReadResponseLineAndHeaders( IN SOCKINFO * info,
-                            IN OUT http_parser_t * parser,
-                            IN OUT int *timeout_secs,
-                            IN OUT int *http_error_code )
-{
-    parse_status_t status;
-    int num_read;
-    char buf[2 * 1024];
-    int done = 0;
-    int ret_code = 0;
-
-    //read response line
-
-    status = parser_parse_responseline( parser );
-    if( status == PARSE_OK ) {
-        done = 1;
-    } else if( status == PARSE_INCOMPLETE ) {
-        done = 0;
-    } else {
-        //error
-        return status;
-    }
-
-    while( !done ) {
-        num_read = sock_read( info, buf, sizeof( buf ), timeout_secs );
-        if( num_read > 0 ) {
-            // append data to buffer
-            ret_code = membuffer_append( &parser->msg.msg, buf, (size_t)num_read );
-            if( ret_code != 0 ) {
-                // set failure status
-                parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
-                return PARSE_FAILURE;
-            }
-            status = parser_parse_responseline( parser );
-            if( status == PARSE_OK ) {
-                done = 1;
-            } else if( status == PARSE_INCOMPLETE ) {
-                done = 0;
-            } else {
-                //error
-                return status;
-            }
-        } else if( num_read == 0 ) {
-
-            // partial msg
-            *http_error_code = HTTP_BAD_REQUEST;    // or response
-            return UPNP_E_BAD_HTTPMSG;
-
-        } else {
-            *http_error_code = parser->http_error_code;
-            return num_read;
-        }
-    }
-
-    done = 0;
-
-    status = parser_parse_headers( parser );
-    if( ( status == PARSE_OK ) && ( parser->position == POS_ENTITY ) ) {
-
-        done = 1;
-    } else if( status == PARSE_INCOMPLETE ) {
-        done = 0;
-    } else {
-        //error
-        return status;
-    }
-
-    //read headers
-    while( !done ) {
-        num_read = sock_read( info, buf, sizeof( buf ), timeout_secs );
-        if( num_read > 0 ) {
-            // append data to buffer
-            ret_code = membuffer_append( &parser->msg.msg, buf, (size_t)num_read );
-            if( ret_code != 0 ) {
-                // set failure status
-                parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
-                return PARSE_FAILURE;
-            }
-            status = parser_parse_headers( parser );
-            if( ( status == PARSE_OK )
-                && ( parser->position == POS_ENTITY ) ) {
-
-                done = 1;
-            } else if( status == PARSE_INCOMPLETE ) {
-                done = 0;
-            } else {
-                //error
-                return status;
-            }
-        } else if( num_read == 0 ) {
-
-            // partial msg
-            *http_error_code = HTTP_BAD_REQUEST;    // or response
-            return UPNP_E_BAD_HTTPMSG;
-
-        } else {
-            *http_error_code = parser->http_error_code;
-            return num_read;
-        }
-    }
-
-    return PARSE_OK;
-}
-
-/************************************************************************
-*	Function :	http_ReadHttpGet
-*
-*	Parameters :
-*		IN void *Handle :			Handle to the HTTP get object
-*		IN OUT char *buf :			Buffer to get the read and parsed data
-*		IN OUT off_t *size :	Size of the buffer passed
-*		IN int timeout :			time out value
-*
-*	Description :	Parses already existing data, then gets new data.
-*		Parses and extracts information from the new data.
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Sucess ;
-*		UPNP_E_INVALID_PARAM  - Invalid Parameter;
-*		UPNP_E_BAD_RESPONSE ;
-*		UPNP_E_BAD_HTTPMSG ;
-*		UPNP_E_CANCELED ;
-*
-*	Note :
-************************************************************************/
-int
-http_ReadHttpGet( IN void *Handle,
-                  IN OUT char *buf,
-                  IN OUT off_t *size,
-                  IN int timeout )
-{
-    http_get_handle_t *handle = Handle;
-
-    parse_status_t status;
-    int num_read;
-    xboolean ok_on_close = FALSE;
-    char tempbuf[2 * 1024];
-
-    int ret_code = 0;
-
-    if( ( !handle ) || ( !size ) || ( ( ( *size ) > 0 ) && !buf )
-        || ( ( *size ) < 0 ) ) {
-        if(size) ( *size ) = 0;
-        return UPNP_E_INVALID_PARAM;
-    }
-    //first parse what has already been gotten
-    if( handle->response.position != POS_COMPLETE ) {
-        status = parser_parse_entity( &handle->response );
-    } else {
-        status = PARSE_SUCCESS;
-    }
-
-    if( status == PARSE_INCOMPLETE_ENTITY ) {
-        // read until close
-        ok_on_close = TRUE;
-    } else if( ( status != PARSE_SUCCESS )
-               && ( status != PARSE_CONTINUE_1 )
-               && ( status != PARSE_INCOMPLETE ) ) {
-        //error
-        ( *size ) = 0;
-        return UPNP_E_BAD_RESPONSE;
-    }
-    //read more if necessary entity
-    while( ( ( handle->entity_offset + ( *size ) ) >
-             handle->response.msg.entity.length )
-           && ( ! handle->cancel )
-           && ( handle->response.position != POS_COMPLETE ) ) {
-        num_read =
-            sock_read( &handle->sock_info, tempbuf, sizeof( tempbuf ),
-                       &timeout );
-        if( num_read > 0 ) {
-            // append data to buffer
-            ret_code = membuffer_append( &handle->response.msg.msg,
-                                         tempbuf, (size_t)num_read );
-            if( ret_code != 0 ) {
-                // set failure status
-                handle->response.http_error_code =
-                    HTTP_INTERNAL_SERVER_ERROR;
-                ( *size ) = 0;
-                return PARSE_FAILURE;
-            }
-            status = parser_parse_entity( &handle->response );
-            if( status == PARSE_INCOMPLETE_ENTITY ) {
-                // read until close
-                ok_on_close = TRUE;
-            } else if( ( status != PARSE_SUCCESS )
-                       && ( status != PARSE_CONTINUE_1 )
-                       && ( status != PARSE_INCOMPLETE ) ) {
-                //error
-                ( *size ) = 0;
-                return UPNP_E_BAD_RESPONSE;
-            }
-        } else if( num_read == 0 ) {
-            if( ok_on_close ) {
-                DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                                     "<<< (RECVD) <<<\n%s\n-----------------\n",
-                                     handle->response.msg.msg.buf );
-                         //print_http_headers( &parser->msg );
-                     )
-                    handle->response.position = POS_COMPLETE;
-            } else {
-                // partial msg
-                ( *size ) = 0;
-                handle->response.http_error_code = HTTP_BAD_REQUEST;    // or response
-                return UPNP_E_BAD_HTTPMSG;
-            }
-        } else {
-            ( *size ) = 0;
-            return num_read;
-        }
-    }
-
-    if( ( handle->entity_offset + ( *size ) ) >
-        handle->response.msg.entity.length ) {
-        ( *size ) =
-            handle->response.msg.entity.length - handle->entity_offset;
-    }
-
-    memcpy( buf,
-            &handle->response.msg.msg.buf[handle->
-                                          response.entity_start_position +
-                                          handle->entity_offset],
-            ( *size ) );
-    handle->entity_offset += ( *size );
-
-    if ( handle->cancel )
-        return UPNP_E_CANCELED;
-
-    return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-*	Function :	http_HttpGetProgress
-*
-*	Parameters :
-*		IN void *Handle :			Handle to the HTTP get object
-*		OUT off_t *length :	Buffer to get the read and parsed data
-*		OUT off_t *total :	Size of tge buffer passed
-*
-*	Description :	Extracts information from the Handle to the HTTP get
-*					object.
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Sucess ;
-*		UPNP_E_INVALID_PARAM  - Invalid Parameter;
-*
-*	Note :
-************************************************************************/
-int http_HttpGetProgress( IN void *Handle, 
-                      OUT off_t *length,
-                      OUT off_t *total )
-{
-    http_get_handle_t *handle = Handle;
-
-    if( ( !handle ) || ( !length ) || ( !total ) ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-    *length = handle->response.msg.entity.length;
-    *total = handle->response.content_length;
-    return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-*	Function :	http_CancelHttpGet
-*
-*	Parameters :
-*		IN void *Handle ;	Handle to HTTP get object
-*
-*	Description :	Set the cancel flag of the HttpGet handle
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Success
-*		UPNP_E_INVALID_PARAM - Invalid Parameter
-*
-*	Note :
-************************************************************************/
-int
-http_CancelHttpGet( IN void *Handle )
-{
-    http_get_handle_t *handle = Handle;
-
-    if( !handle ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    handle->cancel = 1;
-
-    return UPNP_E_SUCCESS;
-}
-
-
-/************************************************************************
-*	Function :	http_CloseHttpGet
-*
-*	Parameters :
-*		IN void *Handle ;	Handle to HTTP get object
-*
-*	Description :	Clears the handle allocated for the HTTP GET operation
-*		Clears socket states and memory allocated for socket operations. 
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Success
-*		UPNP_E_INVALID_PARAM - Invalid Parameter
-*
-*	Note :
-************************************************************************/
-int
-http_CloseHttpGet( IN void *Handle )
-{
-    http_get_handle_t *handle = Handle;
-
-    if( !handle ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    sock_destroy( &handle->sock_info, SD_BOTH );    //should shutdown completely
-    httpmsg_destroy( &handle->response.msg );
-    handle->entity_offset = 0;
-    free( handle );
-    return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-*	Function :	http_OpenHttpGet
-*
-*	Parameters :
-*		IN const char *url_str :	String as a URL
-*		IN OUT void **Handle :		Pointer to buffer to store HTTP
-*									post handle
-*		IN OUT char **contentType :	Type of content
-*		OUT off_t *contentLength :	length of content
-*		OUT int *httpStatus :		HTTP status returned on receiving a
-*									response message
-*		IN int timeout :			time out value
-*
-*	Description :	Makes the HTTP GET message, connects to the peer, 
-*		sends the HTTP GET request, gets the response and parses the 
-*		response.
-*
-*	Return : int;
-*		UPNP_E_SUCCESS - On Success ;
-*		UPNP_E_INVALID_PARAM - Invalid Paramters ;
-*		UPNP_E_OUTOF_MEMORY ;
-*		UPNP_E_SOCKET_ERROR ;
-*		UPNP_E_BAD_RESPONSE ;
-*
-*	Note :
-*
-************************************************************************/
-int
-http_OpenHttpGet( IN const char *url_str,
-                  IN OUT void **Handle,
-                  IN OUT char **contentType,
-                  OUT off_t *contentLength,
-                  OUT int *httpStatus,
-                  IN int timeout )
-{
-    return http_OpenHttpGetProxy(url_str, NULL, Handle, contentType, contentLength, httpStatus, timeout);
-}
-
-/************************************************************************
-*	Function :	http_OpenHttpGetProxy
-*
-*	Parameters :
-*		IN const char *url_str :	String as a URL
-*		IN const char *proxy_str :	String as a URL
-*		IN OUT void **Handle :		Pointer to buffer to store HTTP
-*									post handle
-*		IN OUT char **contentType :	Type of content
-*		OUT off_t *contentLength :	length of content
-*		OUT int *httpStatus :		HTTP status returned on receiving a
-*									response message
-*		IN int timeout :			time out value
-*
-*	Description :	Makes the HTTP GET message, connects to the peer, 
-*		sends the HTTP GET request, gets the response and parses the 
-*		response.
-*		If a proxy URL is defined then the connection is made there.
-*
-*	Return : int;
-*		UPNP_E_SUCCESS - On Success ;
-*		UPNP_E_INVALID_PARAM - Invalid Paramters ;
-*		UPNP_E_OUTOF_MEMORY ;
-*		UPNP_E_SOCKET_ERROR ;
-*		UPNP_E_BAD_RESPONSE ;
-*
-*	Note :
-*
-************************************************************************/
-int
-http_OpenHttpGetProxy( IN const char *url_str,
-                  IN const char *proxy_str,
-                  IN OUT void **Handle,
-                  IN OUT char **contentType,
-                  OUT off_t *contentLength,
-                  OUT int *httpStatus,
-                  IN int timeout )
-{
-    int ret_code;
-    int http_error_code;
-    memptr ctype;
-    int tcp_connection;
-    membuffer request;
-    http_get_handle_t *handle = NULL;
-    uri_type url;
-    uri_type proxy;
-    uri_type *peer;
-    parse_status_t status;
-
-    if( ( !url_str ) || ( !Handle ) || ( !contentType )
-        || ( !httpStatus ) ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    ( *httpStatus ) = 0;
-    ( *Handle ) = handle;
-    ( *contentType ) = NULL;
-    ( *contentLength ) = 0;
-
-    if( ( ret_code =
-          MakeGetMessage( url_str, proxy_str, &request, &url ) ) != UPNP_E_SUCCESS ) {
-        return ret_code;
-    }
-    if( proxy_str ) {
-        ret_code = http_FixStrUrl( ( char * )proxy_str, strlen( proxy_str ), &proxy );
-        peer = &proxy;
-    } else {
-        peer = &url;
-    }
-
-    handle = ( http_get_handle_t * ) malloc( sizeof( http_get_handle_t ) );
-
-    if( handle == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    handle->entity_offset = 0;
-    handle->cancel = 0;
-    parser_response_init( &handle->response, HTTPMETHOD_GET );
-
-    tcp_connection = socket( AF_INET, SOCK_STREAM, 0 );
-    if( tcp_connection == -1 ) {
-        ret_code = UPNP_E_SOCKET_ERROR;
-        goto errorHandler;
-    }
-
-    if( sock_init( &handle->sock_info, tcp_connection ) != UPNP_E_SUCCESS )
-    {
-        sock_destroy( &handle->sock_info, SD_BOTH );
-        ret_code = UPNP_E_SOCKET_ERROR;
-        goto errorHandler;
-    }
-
-    ret_code = connect( handle->sock_info.socket,
-                        ( struct sockaddr * )&peer->hostport.IPv4address,
-                        sizeof( struct sockaddr_in ) );
-
-    if( ret_code == -1 ) {
-        sock_destroy( &handle->sock_info, SD_BOTH );
-        ret_code = UPNP_E_SOCKET_CONNECT;
-        goto errorHandler;
-    }
-    // send request
-    ret_code = http_SendMessage( &handle->sock_info, &timeout, "b",
-                                 request.buf, (size_t)request.length );
-    if( ret_code != 0 ) {
-        sock_destroy( &handle->sock_info, SD_BOTH );
-        goto errorHandler;
-    }
-
-    status =
-        ReadResponseLineAndHeaders( &handle->sock_info, &handle->response,
-                                    &timeout, &http_error_code );
-
-    if( status != PARSE_OK ) {
-        ret_code = UPNP_E_BAD_RESPONSE;
-        goto errorHandler;
-    }
-
-    status = parser_get_entity_read_method( &handle->response );
-
-    if( ( status != PARSE_CONTINUE_1 ) && ( status != PARSE_SUCCESS ) ) {
-        ret_code = UPNP_E_BAD_RESPONSE;
-        goto errorHandler;
-    }
-
-    ( *httpStatus ) = handle->response.msg.status_code;
-    ret_code = UPNP_E_SUCCESS;
-
-    if( httpmsg_find_hdr( &handle->response.msg, HDR_CONTENT_TYPE, &ctype )
-        == NULL ) {
-        *contentType = NULL;    // no content-type
-    } else {
-        *contentType = ctype.buf;
-    }
-
-    if( handle->response.position == POS_COMPLETE ) {
-        ( *contentLength ) = 0;
-    } else if( handle->response.ent_position == ENTREAD_USING_CHUNKED ) {
-        ( *contentLength ) = UPNP_USING_CHUNKED;
-    } else if( handle->response.ent_position == ENTREAD_USING_CLEN ) {
-        ( *contentLength ) = handle->response.content_length;
-    } else if( handle->response.ent_position == ENTREAD_UNTIL_CLOSE ) {
-        ( *contentLength ) = UPNP_UNTIL_CLOSE;
-    }
-
-  errorHandler:
-
-    ( *Handle ) = handle;
-
-    membuffer_destroy( &request );
-
-    if( ret_code != UPNP_E_SUCCESS ) {
-        httpmsg_destroy( &handle->response.msg );
-    }
-    return ret_code;
-}
-
-/************************************************************************
-*	Function :	http_SendStatusResponse
-*
-*	Parameters :
-*		IN SOCKINFO *info :				Socket information object
-*		IN int http_status_code :		error code returned while making 
-*										or sending the response message
-*		IN int request_major_version :	request major version
-*		IN int request_minor_version :	request minor version
-*
-*	Description :	Generate a response message for the status query and
-*		send the status response.
-*
-*	Return : int;
-*		0 -- success
-*		UPNP_E_OUTOF_MEMORY
-*		UPNP_E_SOCKET_WRITE
-*		UPNP_E_TIMEDOUT
-*
-*	Note :
-************************************************************************/
-int
-http_SendStatusResponse( IN SOCKINFO * info,
-                         IN int http_status_code,
-                         IN int request_major_version,
-                         IN int request_minor_version )
-{
-    int response_major,
-      response_minor;
-    membuffer membuf;
-    int ret;
-    int timeout;
-
-    http_CalcResponseVersion( request_major_version, request_minor_version,
-                              &response_major, &response_minor );
-
-    membuffer_init( &membuf );
-    membuf.size_inc = 70;
-
-    ret = http_MakeMessage( &membuf, response_major, response_minor, "RSCB", http_status_code,  // response start line
-                            http_status_code ); // body
-
-    if( ret == 0 ) {
-        timeout = HTTP_DEFAULT_TIMEOUT;
-        ret = http_SendMessage( info, &timeout, "b",
-                                membuf.buf, (size_t)membuf.length );
-    }
-
-    membuffer_destroy( &membuf );
-
-    return ret;
-}
-
-/************************************************************************
-*	Function :	http_MakeMessage
-*
-*	Parameters :
-*		INOUT membuffer* buf :		buffer with the contents of the 
-*									message
-*		IN int http_major_version :	HTTP major version
-*		IN int http_minor_version :	HTTP minor version
-*		IN const char* fmt :		Pattern format 
-*		... :	
-*
-*	Description :	Generate an HTTP message based on the format that is 
-*		specified in the input parameters.
-*
-*		fmt types:
-*		's':	arg = const char* C_string
-*		'b':	arg1 = const char* buf; arg2 = size_t buf_length 
-*				memory ptr
-*		'c':	(no args) appends CRLF "\r\n"
-*		'd':	arg = int number		// appends decimal number
-*		'h':	arg = off_t number		// appends off_t number
-*		't':	arg = time_t * gmt_time	// appends time in RFC 1123 fmt
-*		'D':	(no args) appends HTTP DATE: header
-*		'S':	(no args) appends HTTP SERVER: header
-*		'U':	(no args) appends HTTP USER-AGENT: header
-*		'C':	(no args) appends a HTTP CONNECTION: close header 
-*				depending on major,minor version
-*		'N':	arg1 = off_t content_length	// content-length header
-*		'Q':	arg1 = http_method_t; arg2 = char* url; 
-*				arg3 = int url_length // start line of request
-*		'R':	arg = int status_code // adds a response start line
-*		'B':	arg = int status_code 
-*				appends content-length, content-type and HTML body for given code
-*		'T':	arg = char * content_type; format e.g: "text/html";	
-*				 content-type header
-*       'H':    arg = *userHTTPHeaderList
-*       'A':    arg = const char* C_string
-*               adds a custom HTTP header to a specific response (filled out
-*               by the user in the File_Info struct), may be NULL
-
-*
-*	Return : int;
-*		0 - On Success
-*		UPNP_E_OUTOF_MEMORY
-*		UPNP_E_INVALID_URL;
-*
-*	Note :
-************************************************************************/
-int
-http_MakeMessage( INOUT membuffer * buf,
-                  IN int http_major_version,
-                  IN int http_minor_version,
-                  IN const char *fmt,
-                  ... )
-{
-    char c;
-    char *s = NULL;
-    size_t num;
-    off_t bignum;
-    size_t length;
-    time_t *loc_time;
-    time_t curr_time;
-    struct tm *date;
-    char *start_str,
-     *end_str;
-    int status_code;
-    const char *status_msg;
-    http_method_t method;
-    const char *method_str;
-    const char *url_str;
-    const char *temp_str;
-    uri_type url;
-    uri_type *uri_ptr;
-    int error_code = UPNP_E_OUTOF_MEMORY;
-    userHTTPHeaderList *pCurUserHTTPHeaderList;
-
-    va_list argp;
-    char tempbuf[200];
-    const char *weekday_str = "Sun\0Mon\0Tue\0Wed\0Thu\0Fri\0Sat";
-    const char *month_str = "Jan\0Feb\0Mar\0Apr\0May\0Jun\0"
-        "Jul\0Aug\0Sep\0Oct\0Nov\0Dec";
-
-    va_start( argp, fmt );
-
-    while( ( c = *fmt++ ) != 0 ) {
-
-        if( c == 's' )          // C string
-        {
-            s = ( char * )va_arg( argp, char * );
-
-            assert( s );
-
-            //DBGONLY(UpnpPrintf(UPNP_ALL,HTTP,__FILE__,__LINE__,"Adding a string : %s\n", s);) 
-            if( membuffer_append( buf, s, strlen( s ) ) != 0 ) {
-                goto error_handler;
-            }
-        } 
-        else if( c == 'A' )          // C string
-        {
-            s = ( char * )va_arg( argp, char * );
-
-            if (s)
-            {
-                //DBGONLY(UpnpPrintf(UPNP_ALL,HTTP,__FILE__,__LINE__,"Adding a string : %s\n", s);) 
-                if( membuffer_append( buf, s, strlen( s ) ) != 0 ) 
-                {
-                    goto error_handler;
-                }
-                if( membuffer_append( buf, "\r\n", 2 ) != 0 ) 
-                {
-                    goto error_handler;
-                }
-
-            }
-        }
-        else if( c == 'K' )   // Add Chunky header
-        {
-            if( membuffer_append
-                ( buf, "TRANSFER-ENCODING: chunked\r\n",
-                  strlen( "Transfer-Encoding: chunked\r\n" ) ) != 0 ) {
-                goto error_handler;
-            }
-        } else if( c == 'G' )   // Add Range header
-        {
-            struct SendInstruction *RespInstr;
-            RespInstr =
-                ( struct SendInstruction * )va_arg( argp,
-                                                    struct SendInstruction
-                                                    * );
-            assert( RespInstr );
-            // connection header
-            if( membuffer_append
-                ( buf, RespInstr->RangeHeader,
-                  strlen( RespInstr->RangeHeader ) ) != 0 ) {
-                goto error_handler;
-            }
-
-        } else if( c == 'b' )   // mem buffer
-        {
-            s = ( char * )va_arg( argp, char * );
-
-            //DBGONLY(UpnpPrintf(UPNP_ALL,HTTP,__FILE__,__LINE__,"Adding a char Buffer starting with: %c\n", s[0]);)
-            assert( s );
-            length = ( size_t ) va_arg( argp, size_t );
-            if( membuffer_append( buf, s, length ) != 0 ) {
-                goto error_handler;
-            }
-        }
-
-        else if( c == 'c' )     // crlf
-        {
-            if( membuffer_append( buf, "\r\n", 2 ) != 0 ) {
-                goto error_handler;
-            }
-        }
-
-        else if( c == 'd' )     // integer
-        {
-            num = ( int )va_arg( argp, int );
-
-            sprintf( tempbuf, "%d", (int)num );
-            if( membuffer_append( buf, tempbuf, strlen( tempbuf ) ) != 0 ) {
-                goto error_handler;
-            }
-        }
-
-        else if( c == 'h' )     // off_t
-        {
-            bignum = ( off_t )va_arg( argp, off_t );
-
-            sprintf( tempbuf, "%"PRId64, (int64_t)bignum );
-
-            if( membuffer_append( buf, tempbuf, strlen( tempbuf ) ) != 0 ) {
-                goto error_handler;
-            }
-        }
-
-        else if( c == 't' || c == 'D' ) // date
-        {
-            if( c == 'D' ) {
-                // header
-                start_str = "DATE: ";
-                end_str = "\r\n";
-                curr_time = time( NULL );
-                date = gmtime( &curr_time );
-            } else {
-                // date value only
-                start_str = end_str = "";
-                loc_time = ( time_t * ) va_arg( argp, time_t * );
-                assert( loc_time );
-                date = gmtime( loc_time );
-            }
-
-            sprintf( tempbuf, "%s%s, %02d %s %d %02d:%02d:%02d GMT%s",
-                     start_str,
-                     &weekday_str[date->tm_wday * 4], date->tm_mday,
-                     &month_str[date->tm_mon * 4], date->tm_year + 1900,
-                     date->tm_hour, date->tm_min, date->tm_sec, end_str );
-
-            if( membuffer_append( buf, tempbuf, strlen( tempbuf ) ) != 0 ) {
-                goto error_handler;
-            }
-        }
-
-        else if( c == 'C' ) {
-            if( ( http_major_version > 1 ) ||
-                ( http_major_version == 1 && http_minor_version == 1 )
-                 ) {
-                // connection header
-                if( membuffer_append_str( buf, "CONNECTION: close\r\n" ) !=
-                    0 ) {
-                    goto error_handler;
-                }
-            }
-        }
-
-        else if( c == 'N' ) {
-            // content-length header
-            bignum = ( off_t )va_arg( argp, off_t );
-
-            assert( bignum >= 0 );
-            if( http_MakeMessage
-                ( buf, http_major_version, http_minor_version, "shc",
-                  "CONTENT-LENGTH: ", bignum ) != 0 ) {
-                goto error_handler;
-            }
-        }
-
-        else if( c == 'S' || c == 'U' ) {
-            // SERVER or USER-AGENT header
-
-            temp_str = ( c == 'S' ) ? "SERVER: " : "USER-AGENT: ";
-            get_sdk_info( tempbuf );
-            if( http_MakeMessage
-                ( buf, http_major_version, http_minor_version, "ss",
-                  temp_str, tempbuf ) != 0 ) {
-                goto error_handler;
-            }
-        }
-
-	else if( c == 'H' )          // header list 
-        {
-            pCurUserHTTPHeaderList = 
-                ( userHTTPHeaderList * )va_arg( argp, userHTTPHeaderList * );
-
-            if (pCurUserHTTPHeaderList != NULL)
-            {
-                while (pCurUserHTTPHeaderList != NULL)
-                {
-                    if( membuffer_append
-                        ( buf, pCurUserHTTPHeaderList->header, 
-                          strlen( pCurUserHTTPHeaderList->header) ) != 0 ) 
-                    {
-                        goto error_handler;
-                    }
-
-                    if( membuffer_append( buf, "\r\n", 2 ) != 0 ) 
-                    {
-                        goto error_handler;
-                    }
-
-                    pCurUserHTTPHeaderList = pCurUserHTTPHeaderList->next;
-                }
-            }
-        }
-        else if( c == 'R' ) {
-            // response start line
-            //   e.g.: 'HTTP/1.1 200 OK'
-            //
-
-            // code
-            status_code = ( int )va_arg( argp, int );
-
-            assert( status_code > 0 );
-            sprintf( tempbuf, "HTTP/%d.%d %d ",
-                     http_major_version, http_minor_version, status_code );
-
-            // str
-            status_msg = http_get_code_text( status_code );
-            if( http_MakeMessage
-                ( buf, http_major_version, http_minor_version, "ssc",
-                  tempbuf, status_msg ) != 0 ) {
-                goto error_handler;
-            }
-        }
-
-        else if( c == 'B' ) {
-            // body of a simple reply
-            // 
-
-            status_code = ( int )va_arg( argp, int );
-
-            sprintf( tempbuf, "%s%d %s%s",
-                     "<html><body><h1>",
-                     status_code, http_get_code_text( status_code ),
-                     "</h1></body></html>" );
-            num = strlen( tempbuf );
-
-            if( http_MakeMessage( buf, http_major_version, http_minor_version, "NTAcs", (off_t)num, // content-length
-                                  "text/html; charset=UTF-8",  // content-type
-                                  gUserHTTPHeaders.buf,
-                                  tempbuf ) != 0 )  // body
-            {
-                goto error_handler;
-            }
-        }
-
-        else if( c == 'Q' ) {
-            // request start line
-            // GET /foo/bar.html HTTP/1.1\r\n
-            //
-
-            method = ( http_method_t ) va_arg( argp, http_method_t );
-            method_str = method_to_str( method );
-            url_str = ( const char * )va_arg( argp, const char * );
-            num = ( size_t )va_arg( argp, size_t );   // length of url_str
-
-            if( http_MakeMessage( buf, http_major_version, http_minor_version, "ssbsdsdc", method_str,  // method
-                                  " ", url_str, (size_t)num,    // url
-                                  " HTTP/", http_major_version, ".",
-                                  http_minor_version ) != 0 ) {
-                goto error_handler;
-            }
-        }
-
-        else if( c == 'q' ) {
-            // request start line and HOST header
-
-            method = ( http_method_t ) va_arg( argp, http_method_t );
-
-            uri_ptr = ( uri_type * ) va_arg( argp, uri_type * );
-            assert( uri_ptr );
-            if( http_FixUrl( uri_ptr, &url ) != 0 ) {
-                error_code = UPNP_E_INVALID_URL;
-                goto error_handler;
-            }
-
-            if( http_MakeMessage
-                ( buf, http_major_version, http_minor_version, "Q" "sbc",
-                  method, url.pathquery.buff, (size_t)url.pathquery.size, "HOST: ",
-                  url.hostport.text.buff, (size_t)(url.hostport.text.size) ) != 0 ) {
-                goto error_handler;
-            }
-        }
-
-        else if( c == 'T' ) {
-            // content type header
-            temp_str = ( const char * )va_arg( argp, const char * );    // type/subtype format
-
-            if( http_MakeMessage
-                ( buf, http_major_version, http_minor_version, "ssc",
-                  "CONTENT-TYPE: ", temp_str ) != 0 ) {
-                goto error_handler;
-            }
-        }
-        else {
-            assert( 0 );
-        }
-    }
-
-    return 0;
-
-  error_handler:
-    va_end( argp );
-    membuffer_destroy( buf );
-    return error_code;
-}
-
-/************************************************************************
-*	Function :	http_CalcResponseVersion
-*
-*	Parameters :
-*		IN int request_major_vers :		Request major version
-*		IN int request_minor_vers :		Request minor version
-*		OUT int* response_major_vers :	Response mojor version
-*		OUT int* response_minor_vers :	Response minor version
-*
-*	Description :	Calculate HTTP response versions based on the request
-*		versions.
-*
-*	Return :	void
-*
-*	Note :
-************************************************************************/
-void
-http_CalcResponseVersion( IN int request_major_vers,
-                          IN int request_minor_vers,
-                          OUT int *response_major_vers,
-                          OUT int *response_minor_vers )
-{
-    if( ( request_major_vers > 1 ) ||
-        ( request_major_vers == 1 && request_minor_vers >= 1 )
-         ) {
-        *response_major_vers = 1;
-        *response_minor_vers = 1;
-    } else {
-        *response_major_vers = request_major_vers;
-        *response_minor_vers = request_minor_vers;
-    }
-}
-
-/************************************************************************
-* Function: MakeGetMessageEx												
-*																		
-* Parameters:															
-*	const char *url_str ;	String as a URL
-*	membuffer *request ;	Buffer containing the request									
-*	uri_type *url ; 		URI object containing the scheme, path 
-*							query token, etc.
-*																		
-* Description: Makes the message for the HTTP GET method				
-*																		
-* Returns:																
-*	UPNP_E_INVALID_URL													
-* 	Error Codes returned by http_MakeMessage							
-*	UPNP_E_SUCCESS														
-************************************************************************/
-int
-MakeGetMessageEx( const char *url_str,
-                  membuffer * request,
-                  uri_type * url,
-                  struct SendInstruction *pRangeSpecifier )
-{
-    int errCode = UPNP_E_SUCCESS;
-    char *urlPath = NULL;
-    int hostlen = 0;
-    char *hoststr,
-     *temp;
-
-    do {
-        DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                             "DOWNLOAD URL : %s\n", url_str );
-             )
-
-            if( ( errCode = http_FixStrUrl( ( char * )url_str,
-                                            strlen( url_str ),
-                                            url ) ) != UPNP_E_SUCCESS ) {
-            break;
-        }
-        // make msg
-        membuffer_init( request );
-
-        urlPath = alloca( strlen( url_str ) + 1 );
-        if( !urlPath ) {
-            errCode = UPNP_E_OUTOF_MEMORY;
-            break;
-        }
-
-        memset( urlPath, 0, strlen( url_str ) + 1 );
-
-        strcpy( urlPath, url_str );
-
-        hoststr = strstr( urlPath, "//" );
-        if( hoststr == NULL ) {
-            errCode = UPNP_E_INVALID_URL;
-            break;
-        }
-
-        hoststr += 2;
-        temp = strchr( hoststr, '/' );
-        if( temp == NULL ) {
-            errCode = UPNP_E_INVALID_URL;
-            break;
-        }
-
-        *temp = '\0';
-        hostlen = strlen( hoststr );
-        *temp = '/';
-
-        DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                             "HOSTNAME : %s Length : %d\n", hoststr,
-                             hostlen );
-             )
-
-            errCode = http_MakeMessage( request,
-                                        1,
-                                        1,
-                                        "QsbcGDCUc",
-                                        HTTPMETHOD_GET,
-                                        url->pathquery.buff,
-                                        (size_t)(url->pathquery.size),
-                                        "HOST: ",
-                                        hoststr,
-                                        (size_t)hostlen, pRangeSpecifier );
-
-        if( errCode != 0 ) {
-            DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                                 "HTTP Makemessage failed\n" );
-                 )
-                membuffer_destroy( request );
-            return errCode;
-        }
-    } while( 0 );
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                         "HTTP Buffer:\n %s\n" "----------END--------\n",
-                         request->buf );
-         )
-
-        return errCode;
-}
-
-#define SIZE_RANGE_BUFFER 50
-
-/************************************************************************
-*	Function :	http_OpenHttpGetEx
-*
-*	Parameters :
-*		IN const char *url_str :	String as a URL
-*		IN OUT void **Handle :		Pointer to buffer to store HTTP
-*									post handle
-*		IN OUT char **contentType :	Type of content
-*		OUT off_t *contentLength :	length of content
-*		OUT int *httpStatus :		HTTP status returned on receiving a
-*									response message
-*		IN int timeout :			time out value
-*
-*	Description :	Makes the HTTP GET message, connects to the peer, 
-*		sends the HTTP GET request, gets the response and parses the 
-*		response.
-*
-*	Return : int;
-*		UPNP_E_SUCCESS - On Success ;
-*		UPNP_E_INVALID_PARAM - Invalid Paramters ;
-*		UPNP_E_OUTOF_MEMORY ;
-*		UPNP_E_SOCKET_ERROR ;
-*		UPNP_E_BAD_RESPONSE ;
-*
-*	Note :
-*
-************************************************************************/
-int
-http_OpenHttpGetEx( IN const char *url_str,
-                    IN OUT void **Handle,
-                    IN OUT char **contentType,
-                    OUT off_t *contentLength,
-                    OUT int *httpStatus,
-                    IN int lowRange,
-                    IN int highRange,
-                    IN int timeout )
-{
-    int http_error_code;
-    memptr ctype;
-    int tcp_connection;
-    membuffer request;
-    http_get_handle_t *handle = NULL;
-    uri_type url;
-    parse_status_t status;
-    int errCode = UPNP_E_SUCCESS;
-
-    //  char rangeBuf[SIZE_RANGE_BUFFER];
-    struct SendInstruction rangeBuf;
-
-    do {
-        // Checking Input parameters
-        if( ( !url_str ) || ( !Handle ) ||
-            ( !contentType ) || ( !httpStatus ) ) {
-            errCode = UPNP_E_INVALID_PARAM;
-            break;
-        }
-        // Initialize output parameters
-        ( *httpStatus ) = 0;
-        ( *Handle ) = handle;
-        ( *contentType ) = NULL;
-        ( *contentLength ) = 0;
-
-        if( lowRange > highRange ) {
-            errCode = UPNP_E_INTERNAL_ERROR;
-            break;
-        }
-
-        memset( &rangeBuf, 0, sizeof( rangeBuf ) );
-        sprintf( rangeBuf.RangeHeader, "Range: bytes=%d-%d\r\n",
-                 lowRange, highRange );
-
-        membuffer_init( &request );
-
-        if( ( errCode = MakeGetMessageEx( url_str,
-                                          &request, &url, &rangeBuf ) )
-            != UPNP_E_SUCCESS ) {
-            break;
-        }
-
-        handle =
-            ( http_get_handle_t * ) malloc( sizeof( http_get_handle_t ) );
-        if( handle == NULL ) {
-            errCode = UPNP_E_OUTOF_MEMORY;
-            break;
-        }
-
-        memset( handle, 0, sizeof( *handle ) );
-
-        handle->entity_offset = 0;
-        parser_response_init( &handle->response, HTTPMETHOD_GET );
-
-        tcp_connection = socket( AF_INET, SOCK_STREAM, 0 );
-        if( tcp_connection == -1 ) {
-            errCode = UPNP_E_SOCKET_ERROR;
-            free( handle );
-            break;
-        }
-
-        if( sock_init( &handle->sock_info, tcp_connection ) !=
-            UPNP_E_SUCCESS ) {
-            sock_destroy( &handle->sock_info, SD_BOTH );
-            errCode = UPNP_E_SOCKET_ERROR;
-            free( handle );
-            break;
-        }
-
-        errCode = connect( handle->sock_info.socket,
-                           ( struct sockaddr * )&url.hostport.IPv4address,
-                           sizeof( struct sockaddr_in ) );
-        if( errCode == -1 ) {
-            sock_destroy( &handle->sock_info, SD_BOTH );
-            errCode = UPNP_E_SOCKET_CONNECT;
-            free( handle );
-            break;
-        }
-        // send request
-        errCode = http_SendMessage( &handle->sock_info,
-                                    &timeout,
-                                    "b", request.buf, (size_t)request.length );
-
-        if( errCode != UPNP_E_SUCCESS ) {
-            sock_destroy( &handle->sock_info, SD_BOTH );
-            free( handle );
-            break;
-        }
-
-        status = ReadResponseLineAndHeaders( &handle->sock_info,
-                                             &handle->response,
-                                             &timeout, &http_error_code );
-
-        if( status != PARSE_OK ) {
-            errCode = UPNP_E_BAD_RESPONSE;
-            free( handle );
-            break;
-        }
-
-        status = parser_get_entity_read_method( &handle->response );
-        if( ( status != PARSE_CONTINUE_1 ) && ( status != PARSE_SUCCESS ) ) {
-            errCode = UPNP_E_BAD_RESPONSE;
-            free( handle );
-            break;
-        }
-
-        ( *httpStatus ) = handle->response.msg.status_code;
-        errCode = UPNP_E_SUCCESS;
-
-        if( httpmsg_find_hdr( &handle->response.msg,
-                              HDR_CONTENT_TYPE, &ctype ) == NULL ) {
-            *contentType = NULL;    // no content-type
-        } else {
-            *contentType = ctype.buf;
-        }
-
-        if( handle->response.position == POS_COMPLETE ) {
-            ( *contentLength ) = 0;
-        } else if( handle->response.ent_position == ENTREAD_USING_CHUNKED ) {
-            ( *contentLength ) = UPNP_USING_CHUNKED;
-        } else if( handle->response.ent_position == ENTREAD_USING_CLEN ) {
-            ( *contentLength ) = handle->response.content_length;
-        } else if( handle->response.ent_position == ENTREAD_UNTIL_CLOSE ) {
-            ( *contentLength ) = UPNP_UNTIL_CLOSE;
-        }
-
-        ( *Handle ) = handle;
-
-    } while( 0 );
-
-    membuffer_destroy( &request );
-
-    return errCode;
-}
-
-/************************************************************************
-*	Function :	get_sdk_info
-*
-*	Parameters :
-*		OUT char *info :	buffer to store the operating system 
-*							information
-*
-*	Description :	Returns the server information for the operating 
-*		system
-*
-*	Return :	XINLINE void
-*
-*	Note :
-************************************************************************/
-// 'info' should have a size of at least 100 bytes
-void
-get_sdk_info( OUT char *info )
-{
-#ifdef WIN32
- 	OSVERSIONINFO versioninfo;
- 	versioninfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
- 	if (GetVersionEx(&versioninfo)!=0)
- 		sprintf( info, "%d.%d.%d %d/%s, UPnP/1.0, Portable SDK for UPnP devices/"PACKAGE_VERSION"\r\n",
- 				versioninfo.dwMajorVersion, versioninfo.dwMinorVersion, versioninfo.dwBuildNumber, versioninfo.dwPlatformId, versioninfo.szCSDVersion );
- 	else
-     *info = '\0';
-#else
-    int ret_code;
-    struct utsname sys_info;
-
-    ret_code = uname( &sys_info );
-    if( ret_code == -1 ) {
-        *info = '\0';
-    }
-
-    sprintf( info, "%s/%s, UPnP/1.0, " PACKAGE_NAME "/"
-	     PACKAGE_VERSION "\r\n",
-             sys_info.sysname, sys_info.release );
-#endif
-}
diff --git a/tombupnp/upnp/src/genlib/net/http/parsetools.c b/tombupnp/upnp/src/genlib/net/http/parsetools.c
deleted file mode 100644
index 49f5aa1..0000000
--- a/tombupnp/upnp/src/genlib/net/http/parsetools.c
+++ /dev/null
@@ -1,76 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-/************************************************************************
-* Purpose: This file a function to extract the header information from	*
-* an http message and then matches the data with XML data.				*
-************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#include <assert.h>
-#include "util.h"
-#include "membuffer.h"
-#include "httpparser.h"
-#include "statcodes.h"
-#include "parsetools.h"
-
-/************************************************************************
-* Function: has_xml_content_type										
-*																		
-* Parameters:															
-*	IN http_message_t* hmsg	; HTTP Message object
-*																		
-* Description: Find the header from the HTTP message and match the		
-*	header for xml data.												
-*																		
-* Returns:																
-*	 BOOLEAN															
-************************************************************************/
-xboolean
-has_xml_content_type( IN http_message_t * hmsg )
-{
-    memptr hdr_value;
-
-    assert( hmsg );
-
-    // find 'content-type' header which must have text/xml
-    if( httpmsg_find_hdr( hmsg, HDR_CONTENT_TYPE, &hdr_value ) != NULL &&
-        matchstr( hdr_value.buf, hdr_value.length,
-                  "%itext%w/%wxml" ) == PARSE_OK ) {
-        return TRUE;
-    }
-    return FALSE;
-}
diff --git a/tombupnp/upnp/src/genlib/net/http/statcodes.c b/tombupnp/upnp/src/genlib/net/http/statcodes.c
deleted file mode 100644
index a3e56b9..0000000
--- a/tombupnp/upnp/src/genlib/net/http/statcodes.c
+++ /dev/null
@@ -1,214 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-/************************************************************************
-* Purpose: This file defines status codes, buffers to store the status	*
-* messages and functions to manipulate those buffers					*
-************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include "config.h"
-#include <stdio.h>
-#include <string.h>
-#include "util.h"
-#include "statcodes.h"
-
-#ifdef WIN32
- #include "unixutil.h"
-#endif
-
-#define NUM_1XX_CODES   2
-static const char *Http1xxCodes[NUM_1XX_CODES];
-static const char *Http1xxStr = "Continue\0" "Switching Protocols\0";
-
-#define NUM_2XX_CODES   7
-static const char *Http2xxCodes[NUM_2XX_CODES];
-static const char *Http2xxStr =
-    "OK\0"
-    "Created\0"
-    "Accepted\0"
-    "Non-Authoratative Information\0"
-    "No Content\0" "Reset Content\0" "Partial Content\0";
-
-#define NUM_3XX_CODES   8
-static const char *Http3xxCodes[NUM_3XX_CODES];
-static const char *Http3xxStr =
-    "Multiple Choices\0"
-    "Moved Permanently\0"
-    "Found\0"
-    "See Other\0"
-    "Not Modified\0" "Use Proxy\0" "\0" "Temporary Redirect\0";
-
-#define NUM_4XX_CODES   18
-static const char *Http4xxCodes[NUM_4XX_CODES];
-static const char *Http4xxStr =
-    "Bad Request\0"
-    "Unauthorized\0"
-    "Payment Required\0"
-    "Forbidden\0"
-    "Not Found\0"
-    "Method Not Allowed\0"
-    "Not Acceptable\0"
-    "Proxy Authentication Required\0"
-    "Request Timeout\0"
-    "Conflict\0"
-    "Gone\0"
-    "Length Required\0"
-    "Precondition Failed\0"
-    "Request Entity Too Large\0"
-    "Request-URI Too Long\0"
-    "Unsupported Media Type\0"
-    "Requested Range Not Satisfiable\0" "Expectation Failed\0";
-
-#define NUM_5XX_CODES   6
-static const char *Http5xxCodes[NUM_5XX_CODES];
-static const char *Http5xxStr =
-    "Internal Server Error\0"
-    "Not Implemented\0"
-    "Bad Gateway\0"
-    "Service Unavailable\0"
-    "Gateway Timeout\0" "HTTP Version Not Supported\0";
-
-static xboolean gInitialized = FALSE;
-
-/************************************************************************
-************************* Functions *************************************
-************************************************************************/
-
-/************************************************************************
-* Function: init_table													
-*																		
-* Parameters:															
-*	IN const char* encoded_str ; status code encoded string 			
-*	OUT const char *table[] ; table to store the encoded status code 
-*							  strings 
-*	IN int tbl_size ;	size of the table														
-*																		
-* Description: Initializing table representing an array of string		
-*	pointers with the individual strings that are comprised in the		
-*	input const char* encoded_str parameter.							
-*																		
-* Returns:																
-*	 void																
-************************************************************************/
-static XINLINE void
-init_table( IN const char *encoded_str,
-            OUT const char *table[],
-            IN int tbl_size )
-{
-    int i;
-    const char *s = encoded_str;
-
-    for( i = 0; i < tbl_size; i++ ) {
-        table[i] = s;
-        s += strlen( s ) + 1;   // next entry
-    }
-}
-
-/************************************************************************
-* Function: init_tables													
-*																		
-* Parameters:															
-*	none																
-*																		
-* Description: Initializing tables with HTTP strings and different HTTP 
-* codes.																
-*																		
-* Returns:																
-*	 void																
-************************************************************************/
-static XINLINE void
-init_tables( void )
-{
-    init_table( Http1xxStr, Http1xxCodes, NUM_1XX_CODES );
-    init_table( Http2xxStr, Http2xxCodes, NUM_2XX_CODES );
-    init_table( Http3xxStr, Http3xxCodes, NUM_3XX_CODES );
-    init_table( Http4xxStr, Http4xxCodes, NUM_4XX_CODES );
-    init_table( Http5xxStr, Http5xxCodes, NUM_5XX_CODES );
-
-    gInitialized = TRUE;        // mark only after complete
-}
-
-/************************************************************************
-* Function: http_get_code_text											
-*																		
-* Parameters:															
-*	int statusCode ; Status code based on which the status table and 
-*					status message is returned 							
-*																		
-* Description: Return the right status message based on the passed in	
-*	int statusCode input parameter										
-*																		
-* Returns:																
-*	 const char* ptr - pointer to the status message string				
-************************************************************************/
-const char *
-http_get_code_text( int statusCode )
-{
-    int index;
-    int table_num;
-
-    if( !gInitialized ) {
-        init_tables(  );
-    }
-
-    if( statusCode < 100 && statusCode >= 600 ) {
-        return NULL;
-    }
-
-    index = statusCode % 100;
-    table_num = statusCode / 100;
-
-    if( table_num == 1 && index < NUM_1XX_CODES ) {
-        return Http1xxCodes[index];
-    }
-
-    if( table_num == 2 && index < NUM_2XX_CODES ) {
-        return Http2xxCodes[index];
-    }
-
-    if( table_num == 3 && index < NUM_3XX_CODES ) {
-        return Http3xxCodes[index];
-    }
-
-    if( table_num == 4 && index < NUM_4XX_CODES ) {
-        return Http4xxCodes[index];
-    }
-
-    if( table_num == 5 && index < NUM_5XX_CODES ) {
-        return Http5xxCodes[index];
-    }
-
-    return NULL;
-}
diff --git a/tombupnp/upnp/src/genlib/net/http/webserver.c b/tombupnp/upnp/src/genlib/net/http/webserver.c
deleted file mode 100644
index 7b3ad90..0000000
--- a/tombupnp/upnp/src/genlib/net/http/webserver.c
+++ /dev/null
@@ -1,1864 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-/************************************************************************
-* Purpose: This file defines the Web Server and has functions to carry out 
-* operations of the Web Server.										
-************************************************************************/
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#include <assert.h>
-#include <fcntl.h>
-#include "util.h"
-#include "strintmap.h"
-#include "membuffer.h"
-#include "httpparser.h"
-#include "httpreadwrite.h"
-#include "statcodes.h"
-#include "webserver.h"
-#include "upnp.h"
-#include "upnpapi.h"
-#include "ssdplib.h"
-
-#ifndef WIN32
- #include <unistd.h>
- #include <inttypes.h>
-#endif
-#include <sys/stat.h>
-#include "ithread.h"
-#include "unixutil.h"
-
-/*
-   Response Types 
- */
-enum resp_type { RESP_FILEDOC, RESP_XMLDOC, RESP_HEADERS, RESP_WEBDOC,
-        RESP_POST };
-
-// mapping of file extension to content-type of document
-struct document_type_t {
-    const char *file_ext;
-    const char *content_type;
-    const char *content_subtype;
-};
-
-struct xml_alias_t {
-    membuffer name;             // name of DOC from root; e.g.: /foo/bar/mydesc.xml
-    membuffer doc;              // the XML document contents
-    time_t last_modified;
-    int *ct;
-};
-
-static const char *gMediaTypes[] = {
-    NULL,                       // 0
-    "audio",                    // 1
-    "video",                    // 2
-    "image",                    // 3
-    "application",              // 4
-    "text"                      // 5
-};
-
-/*
-   Defines 
- */
-
-// index into 'gMediaTypes'
-#define AUDIO_STR		"\1"
-#define VIDEO_STR		"\2"
-#define IMAGE_STR		"\3"
-#define APPLICATION_STR "\4"
-#define TEXT_STR		"\5"
-
-// int index
-#define APPLICATION_INDEX	4
-#define TEXT_INDEX			5
-
-// general
-#define NUM_MEDIA_TYPES 70
-#define NUM_HTTP_HEADER_NAMES 33
-
-// sorted by file extension; must have 'NUM_MEDIA_TYPES' extensions
-static const char *gEncodedMediaTypes =
-    "aif\0" AUDIO_STR "aiff\0"
-    "aifc\0" AUDIO_STR "aiff\0"
-    "aiff\0" AUDIO_STR "aiff\0"
-    "asf\0" VIDEO_STR "x-ms-asf\0"
-    "asx\0" VIDEO_STR "x-ms-asf\0"
-    "au\0" AUDIO_STR "basic\0"
-    "avi\0" VIDEO_STR "msvideo\0"
-    "bmp\0" IMAGE_STR "bmp\0"
-    "css\0" TEXT_STR "css\0"
-    "dcr\0" APPLICATION_STR "x-director\0"
-    "dib\0" IMAGE_STR "bmp\0"
-    "dir\0" APPLICATION_STR "x-director\0"
-    "dxr\0" APPLICATION_STR "x-director\0"
-    "gif\0" IMAGE_STR "gif\0"
-    "hta\0" TEXT_STR "hta\0"
-    "htm\0" TEXT_STR "html\0"
-    "html\0" TEXT_STR "html\0"
-    "jar\0" APPLICATION_STR "java-archive\0"
-    "jfif\0" IMAGE_STR "pjpeg\0"
-    "jpe\0" IMAGE_STR "jpeg\0"
-    "jpeg\0" IMAGE_STR "jpeg\0"
-    "jpg\0" IMAGE_STR "jpeg\0"
-    "js\0" APPLICATION_STR "x-javascript\0"
-    "kar\0" AUDIO_STR "midi\0"
-    "m3u\0" AUDIO_STR "mpegurl\0"
-    "mid\0" AUDIO_STR "midi\0"
-    "midi\0" AUDIO_STR "midi\0"
-    "mov\0" VIDEO_STR "quicktime\0"
-    "mp2v\0" VIDEO_STR "x-mpeg2\0"
-    "mp3\0" AUDIO_STR "mpeg\0"
-    "mpe\0" VIDEO_STR "mpeg\0"
-    "mpeg\0" VIDEO_STR "mpeg\0"
-    "mpg\0" VIDEO_STR "mpeg\0"
-    "mpv\0" VIDEO_STR "mpeg\0"
-    "mpv2\0" VIDEO_STR "x-mpeg2\0"
-    "pdf\0" APPLICATION_STR "pdf\0"
-    "pjp\0" IMAGE_STR "jpeg\0"
-    "pjpeg\0" IMAGE_STR "jpeg\0"
-    "plg\0" TEXT_STR "html\0"
-    "pls\0" AUDIO_STR "scpls\0"
-    "png\0" IMAGE_STR "png\0"
-    "qt\0" VIDEO_STR "quicktime\0"
-    "ram\0" AUDIO_STR "x-pn-realaudio\0"
-    "rmi\0" AUDIO_STR "mid\0"
-    "rmm\0" AUDIO_STR "x-pn-realaudio\0"
-    "rtf\0" APPLICATION_STR "rtf\0"
-    "shtml\0" TEXT_STR "html\0"
-    "smf\0" AUDIO_STR "midi\0"
-    "snd\0" AUDIO_STR "basic\0"
-    "spl\0" APPLICATION_STR "futuresplash\0"
-    "ssm\0" APPLICATION_STR "streamingmedia\0"
-    "swf\0" APPLICATION_STR "x-shockwave-flash\0"
-    "tar\0" APPLICATION_STR "tar\0"
-    "tcl\0" APPLICATION_STR "x-tcl\0"
-    "text\0" TEXT_STR "plain\0"
-    "tif\0" IMAGE_STR "tiff\0"
-    "tiff\0" IMAGE_STR "tiff\0"
-    "txt\0" TEXT_STR "plain\0"
-    "ulw\0" AUDIO_STR "basic\0"
-    "wav\0" AUDIO_STR "wav\0"
-    "wax\0" AUDIO_STR "x-ms-wax\0"
-    "wm\0" VIDEO_STR "x-ms-wm\0"
-    "wma\0" AUDIO_STR "x-ms-wma\0"
-    "wmv\0" VIDEO_STR "x-ms-wmv\0"
-    "wvx\0" VIDEO_STR "x-ms-wvx\0"
-    "xbm\0" IMAGE_STR "x-xbitmap\0"
-    "xml\0" TEXT_STR "xml\0"
-    "xsl\0" TEXT_STR "xml\0"
-    "z\0" APPLICATION_STR "x-compress\0"
-    "zip\0" APPLICATION_STR "zip\0" "\0";
-    // *** end ***
-
-/***********************************************************************/
-/*
-   module variables - Globals, static and externs                      
- */
-
-/***********************************************************************/
-static struct document_type_t gMediaTypeList[NUM_MEDIA_TYPES];
-membuffer gDocumentRootDir;     // a local dir which serves as webserver root
-static struct xml_alias_t gAliasDoc;    // XML document
-static ithread_mutex_t gWebMutex;
-extern str_int_entry Http_Header_Names[NUM_HTTP_HEADER_NAMES];
-
-/************************************************************************
-* Function: has_xml_content_type										
-*																		
-* Parameters:															
-*	none																
-*																		
-* Description: decodes list and stores it in gMediaTypeList				
-*																		
-* Returns:																
-*	 void																
-************************************************************************/
-static XINLINE void
-media_list_init( void )
-{
-    int i;
-    const char *s = gEncodedMediaTypes;
-    struct document_type_t *doc_type;
-
-    for( i = 0; *s != '\0'; i++ ) {
-        doc_type = &gMediaTypeList[i];
-
-        doc_type->file_ext = s;
-
-        s += strlen( s ) + 1;   // point to type
-        doc_type->content_type = gMediaTypes[( int )*s];    // set cont-type
-
-        s++;                    // point to subtype
-        doc_type->content_subtype = s;
-
-        s += strlen( s ) + 1;   // next entry
-    }
-    assert( i == NUM_MEDIA_TYPES );
-}
-
-/************************************************************************
-* Function: has_xml_content_type										
-*																		
-* Parameters:															
-*	IN const char* extension ; 											
-*	OUT const char** con_type,											
-*	OUT const char** con_subtype										
-*																		
-* Description: Based on the extension, returns the content type and 	
-*	content subtype														
-*																		
-* Returns:																
-*	 0 on success;														
-*	-1 on error															
-************************************************************************/
-static XINLINE int
-search_extension( IN const char *extension,
-                  OUT const char **con_type,
-                  OUT const char **con_subtype )
-{
-    int top,
-      mid,
-      bot;
-    int cmp;
-
-    top = 0;
-    bot = NUM_MEDIA_TYPES - 1;
-
-    while( top <= bot ) {
-        mid = ( top + bot ) / 2;
-        cmp = strcasecmp( extension, gMediaTypeList[mid].file_ext );
-
-        if( cmp > 0 ) {
-            top = mid + 1;      // look below mid
-        } else if( cmp < 0 ) {
-            bot = mid - 1;      // look above mid
-        } else                  // cmp == 0
-        {
-            *con_type = gMediaTypeList[mid].content_type;
-            *con_subtype = gMediaTypeList[mid].content_subtype;
-            return 0;
-        }
-    }
-
-    return -1;
-}
-
-/************************************************************************
-* Function: get_content_type											
-*																		
-* Parameters:															
-*	IN const char* filename,											
-*	OUT DOMString* content_type											
-*																		
-* Description: Based on the extension, clones an XML string based on	
-*	type and content subtype. If content type and sub type are not		
-*	found, unknown types are used										
-*																		
-* Returns:																
-*	 0 - On Sucess														
-*	 UPNP_E_OUTOF_MEMORY - on memory allocation failures				
-************************************************************************/
-int
-get_content_type( IN const char *filename,
-                  OUT DOMString * content_type )
-{
-    const char *extension;
-    const char *type,
-     *subtype;
-    xboolean ctype_found = FALSE;
-    char *temp = NULL;
-    int length = 0;
-
-    ( *content_type ) = NULL;
-
-    // get ext
-    extension = strrchr( filename, '.' );
-    if( extension != NULL ) {
-        if( search_extension( extension + 1, &type, &subtype ) == 0 ) {
-            ctype_found = TRUE;
-        }
-    }
-
-    if( !ctype_found ) {
-        // unknown content type
-        type = gMediaTypes[APPLICATION_INDEX];
-        subtype = "octet-stream";
-    }
-
-    length = strlen( type ) + strlen( "/" ) + strlen( subtype ) + 1;
-    temp = ( char * )malloc( length );
-
-    if( !temp ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    sprintf( temp, "%s/%s", type, subtype );
-    ( *content_type ) = ixmlCloneDOMString( temp );
-
-    free( temp );
-
-    if( !content_type ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    return 0;
-}
-
-/************************************************************************
-* Function: glob_alias_init												
-*																		
-* Parameters:															
-*	none																
-*																		
-* Description: Initialize the global XML document. Allocate buffers		
-*	for the XML document												
-*																		
-* Returns:																
-*	 void																
-************************************************************************/
-static XINLINE void
-glob_alias_init( void )
-{
-    struct xml_alias_t *alias = &gAliasDoc;
-
-    membuffer_init( &alias->doc );
-    membuffer_init( &alias->name );
-    alias->ct = NULL;
-    alias->last_modified = 0;
-}
-
-/************************************************************************
-* Function: is_valid_alias												
-*																		
-* Parameters:															
-*	IN const struct xml_alias_t* alias ; XML alias object				
-*																		
-* Description: Check for the validity of the XML object buffer													
-*																		
-* Returns:																
-*	 BOOLEAN															
-************************************************************************/
-static XINLINE xboolean
-is_valid_alias( IN const struct xml_alias_t *alias )
-{
-    return alias->doc.buf != NULL;
-}
-
-/************************************************************************
-* Function: alias_grab													
-*																		
-* Parameters:															
-*	OUT struct xml_alias_t* alias ; XML alias object										
-*																		
-* Description: Copy the contents of the global XML document into the	
-*	local OUT parameter																							
-*																		
-* Returns:																
-*	 void																
-************************************************************************/
-static void
-alias_grab( OUT struct xml_alias_t *alias )
-{
-    ithread_mutex_lock( &gWebMutex );
-
-    assert( is_valid_alias( &gAliasDoc ) );
-
-    memcpy( alias, &gAliasDoc, sizeof( struct xml_alias_t ) );
-    *alias->ct = *alias->ct + 1;
-
-    ithread_mutex_unlock( &gWebMutex );
-}
-
-/************************************************************************
-* Function: alias_release												
-*																		
-* Parameters:															
-*	IN struct xml_alias_t* alias ; XML alias object										
-*																		
-* Description: Release the XML document referred to by the IN parameter 
-*	Free the allocated buffers associated with this object				
-*																		
-* Returns:																
-*	void																
-************************************************************************/
-static void
-alias_release( IN struct xml_alias_t *alias )
-{
-    ithread_mutex_lock( &gWebMutex );
-
-    // ignore invalid alias
-    if( !is_valid_alias( alias ) ) {
-        ithread_mutex_unlock( &gWebMutex );
-        return;
-    }
-
-    assert( alias->ct > 0 );
-
-    *alias->ct = *alias->ct - 1;
-    if( *alias->ct <= 0 ) {
-        membuffer_destroy( &alias->doc );
-        membuffer_destroy( &alias->name );
-        free( alias->ct );
-    }
-    ithread_mutex_unlock( &gWebMutex );
-}
-
-/************************************************************************
-* Function: web_server_set_alias										
-*																		
-* Parameters:															
-*	alias_name: webserver name of alias; created by caller and freed by 
-*				caller (doesn't even have to be malloc()d .)					
-*	alias_content:	the xml doc; this is allocated by the caller; and	
-*					freed by the web server											
-*	alias_content_length: length of alias body in bytes					
-*	last_modified:	time when the contents of alias were last			
-*					changed (local time)											
-*																		
-* Description: Replaces current alias with the given alias. To remove	
-*	the current alias, set alias_name to NULL.							
-*																		
-* Returns:																
-*	0 - OK																
-*	UPNP_E_OUTOF_MEMORY: note: alias_content is not freed here			
-************************************************************************/
-int
-web_server_set_alias( IN const char *alias_name,
-                      IN const char *alias_content,
-                      IN size_t alias_content_length,
-                      IN time_t last_modified )
-{
-    int ret_code;
-    struct xml_alias_t alias;
-
-    alias_release( &gAliasDoc );
-
-    if( alias_name == NULL ) {
-        // don't serve aliased doc anymore
-        return 0;
-    }
-
-    assert( alias_content != NULL );
-
-    membuffer_init( &alias.doc );
-    membuffer_init( &alias.name );
-    alias.ct = NULL;
-
-    do {
-        // insert leading /, if missing
-        if( *alias_name != '/' ) {
-            if( membuffer_assign_str( &alias.name, "/" ) != 0 ) {
-                break;          // error; out of mem
-            }
-        }
-
-        ret_code = membuffer_append_str( &alias.name, alias_name );
-        if( ret_code != 0 ) {
-            break;              // error
-        }
-
-        if( ( alias.ct = ( int * )malloc( sizeof( int ) ) ) == NULL ) {
-            break;              // error
-        }
-        *alias.ct = 1;
-        membuffer_attach( &alias.doc, ( char * )alias_content,
-                          alias_content_length );
-
-        alias.last_modified = last_modified;
-
-        // save in module var
-        ithread_mutex_lock( &gWebMutex );
-        gAliasDoc = alias;
-        ithread_mutex_unlock( &gWebMutex );
-
-        return 0;
-    } while( FALSE );
-
-    // error handler
-
-    // free temp alias
-    membuffer_destroy( &alias.name );
-    membuffer_destroy( &alias.doc );
-    free( alias.ct );
-    return UPNP_E_OUTOF_MEMORY;
-}
-
-/************************************************************************
-* Function: web_server_init												
-*																		
-* Parameters:															
-*	none																
-*																		
-* Description: Initilialize the different documents. Initialize the		
-*	memory for root directory for web server. Call to initialize global 
-*	XML document. Sets bWebServerState to WEB_SERVER_ENABLED			
-*																		
-* Returns:																
-*	0 - OK																
-*	UPNP_E_OUTOF_MEMORY: note: alias_content is not freed here			
-************************************************************************/
-int
-web_server_init( void )
-{
-    int ret_code;
-
-    if( bWebServerState == WEB_SERVER_DISABLED ) {
-        media_list_init(  );    // decode media list
-        membuffer_init( &gDocumentRootDir );
-        glob_alias_init(  );
-
-        pVirtualDirList = NULL;
-        pUserHTTPHeaderList = NULL;
-
-        ret_code = ithread_mutex_init( &gWebMutex, NULL );
-        if( ret_code == -1 ) {
-            return UPNP_E_OUTOF_MEMORY;
-        }
-        bWebServerState = WEB_SERVER_ENABLED;
-    }
-
-    return 0;
-}
-
-/************************************************************************
-* Function: web_server_destroy											
-*																		
-* Parameters:															
-*	none																
-*																		
-* Description: Release memory allocated for the global web server root	
-*	directory and the global XML document								
-*	Resets the flag bWebServerState to WEB_SERVER_DISABLED				
-*																		
-* Returns:																
-*	void																
-************************************************************************/
-void
-web_server_destroy( void )
-{
-    if( bWebServerState == WEB_SERVER_ENABLED ) {
-        membuffer_destroy( &gDocumentRootDir );
-       
-        alias_release( &gAliasDoc );
-
-        ithread_mutex_lock( &gWebMutex );
-        memset( &gAliasDoc, 0, sizeof( struct xml_alias_t ) );
-        ithread_mutex_unlock( &gWebMutex );
-
-        ithread_mutex_destroy( &gWebMutex );
-        bWebServerState = WEB_SERVER_DISABLED;
-    }
-}
-
-/************************************************************************
-* Function: get_file_info												
-*																		
-* Parameters:															
-*	IN const char* filename ; 	Filename having the description document
-*	OUT struct File_Info * info ; File information object having file 
-*								  attributes such as filelength, when was 
-*								  the file last modified, whether a file 
-*								  or a directory and whether the file or
-*								  directory is readable. 
-*																		
-* Description: Release memory allocated for the global web server root	
-*	directory and the global XML document								
-*	Resets the flag bWebServerState to WEB_SERVER_DISABLED				
-*																		
-* Returns:																
-*	int																	
-************************************************************************/
-static int
-get_file_info( IN const char *filename,
-               OUT struct File_Info *info )
-{
-    int code;
-    struct stat s;
-    FILE *fp;
-    int rc = 0;
-
-    info->content_type = NULL;
-    info->force_chunked = FALSE;
-
-    code = stat( filename, &s );
-    if( code == -1 ) {
-        return -1;
-    }
-
-    if( S_ISDIR( s.st_mode ) ) {
-        info->is_directory = TRUE;
-    } else if( S_ISREG( s.st_mode ) ) {
-        info->is_directory = FALSE;
-    } else {
-        return -1;
-    }
-
-    // check readable
-    fp = fopen( filename, "r" );
-    info->is_readable = ( fp != NULL );
-    if( fp ) {
-        fclose( fp );
-    }
-
-    info->file_length = s.st_size;
-    info->last_modified = s.st_mtime;
-
-    rc = get_content_type( filename, &info->content_type );
-
-    info->http_header = NULL;
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                         "file info: %s, length: " "%"PRIx64 ", last_mod=%s readable=%d\n",
-                         filename, (int64_t)info->file_length,
-                         asctime( gmtime( &info->last_modified ) ),
-                         info->is_readable ); )
-
-        return rc;
-}
-
-/************************************************************************
-* Function: web_server_set_root_dir										
-*																		
-* Parameters:															
-*	IN const char* root_dir ; String having the root directory for the 
-*								document		 						
-*																		
-* Description: Assign the path specfied by the IN const char* root_dir	
-*	parameter to the global Document root directory. Also check for		
-*	path names ending in '/'											
-*																		
-* Returns:																
-*	int																	
-************************************************************************/
-int
-web_server_set_root_dir( IN const char *root_dir )
-{
-    int index;
-    int ret;
-
-    ret = membuffer_assign_str( &gDocumentRootDir, root_dir );
-    if( ret != 0 ) {
-        return ret;
-    }
-    // remove trailing '/', if any
-    if( gDocumentRootDir.length > 0 ) {
-        index = gDocumentRootDir.length - 1;    // last char
-        if( gDocumentRootDir.buf[index] == '/' ) {
-            membuffer_delete( &gDocumentRootDir, index, 1 );
-        }
-    }
-
-    return 0;
-}
-
-/************************************************************************
-* Function: get_alias													
-*																		
-* Parameters:															
-*	IN const char* request_file ; request file passed in to be compared with
-*	OUT struct xml_alias_t* alias ; xml alias object which has a file name 
-*									stored										
-*   OUT struct File_Info * info	 ; File information object which will be 
-*									filled up if the file comparison 
-*									succeeds										
-*																		
-* Description: Compare the files names between the one on the XML alias 
-*	the one passed in as the input parameter. If equal extract file 
-*	information
-*																		
-* Returns:																
-*	TRUE - On Success													
-*	FALSE if request is not an alias									
-************************************************************************/
-static XINLINE xboolean
-get_alias( IN const char *request_file,
-           OUT struct xml_alias_t *alias,
-           OUT struct File_Info *info )
-{
-    int cmp;
-
-    cmp = strcmp( alias->name.buf, request_file );
-    if( cmp == 0 ) {
-        // fill up info
-        info->file_length = alias->doc.length;
-        info->is_readable = TRUE;
-        info->is_directory = FALSE;
-        info->force_chunked = FALSE;
-        info->last_modified = alias->last_modified;
-        info->http_header = NULL;
-    }
-
-    return cmp == 0;
-}
-
-/************************************************************************
-* Function: isFileInVirtualDir											
-*																		
-* Parameters:															
-*	IN char *filePath ; directory path to be tested for virtual directory
-*																		
-* Description: Compares filePath with paths from the list of virtual
-*				directory lists
-*																		
-* Returns:																
-*	BOOLEAN																
-************************************************************************/
-int
-isFileInVirtualDir( IN char *filePath )
-{
-    virtualDirList *pCurVirtualDir;
-    int webDirLen;
-
-    pCurVirtualDir = pVirtualDirList;
-    while( pCurVirtualDir != NULL ) {
-        webDirLen = strlen( pCurVirtualDir->dirName );
-        if( pCurVirtualDir->dirName[webDirLen - 1] == '/' ) {
-            if( strncmp( pCurVirtualDir->dirName, filePath, webDirLen ) ==
-                0 )
-                return TRUE;
-        } else {
-            if( ( strncmp( pCurVirtualDir->dirName, filePath, webDirLen )
-                  == 0 ) && ( filePath[webDirLen] == '/' ) )
-                return TRUE;
-        }
-
-        pCurVirtualDir = pCurVirtualDir->next;
-    }
-
-    return FALSE;
-}
-
-/************************************************************************
-* Function: ToUpperCase
-*
-* Parameters:
-*	INOUT char * Str ; Input string to be converted
-*
-* Description: Converts input string to upper case
-*
-* Returns:
-*	int
-************************************************************************/
-int
-ToUpperCase( char *Str )
-{
-    int i;
-
-    for( i = 0; i < ( int )strlen( Str ); i++ )
-        Str[i] = toupper( Str[i] );
-    return 1;
-
-}
-
-/************************************************************************
-* Function: StrStr
-*
-* Parameters:
-*	IN char * S1 ; Input string
-*	IN char * S2 ; Input sub-string
-*
-* Description: Finds a substring from a string
-*
-* Returns:
-*	char * ptr - pointer to the first occurence of S2 in S1				
-************************************************************************/
-char *
-StrStr( char *S1,
-        char *S2 )
-{
-    char *Str1,
-     *Str2;
-    char *Ptr,
-     *Ret;
-    int Pos;
-
-    Str1 = ( char * )malloc( strlen( S1 ) + 2 );
-    if(!Str1) return NULL;
-    Str2 = ( char * )malloc( strlen( S2 ) + 2 );
-    if (!Str2)
-       {
-       free(Str1);
-       return NULL;
-       }
-
-    strcpy( Str1, S1 );
-    strcpy( Str2, S2 );
-
-    ToUpperCase( Str1 );
-    ToUpperCase( Str2 );
-    Ptr = strstr( Str1, Str2 );
-    if( Ptr == NULL )
-        return NULL;
-
-    Pos = Ptr - Str1;
-
-    Ret = S1 + Pos;
-
-    free( Str1 );
-    free( Str2 );
-    return Ret;
-
-}
-
-/************************************************************************
-* Function: StrTok														
-*																		
-* Parameters:															
-*	IN char ** Src ; String containing the token													
-*	IN char * del ; Set of delimiter characters														
-*																		
-* Description: Finds next token in a string							
-*																		
-* Returns:																
-*	char * ptr - pointer to the first occurence of S2 in S1				
-************************************************************************/
-char *
-StrTok( char **Src,
-        char *Del )
-{
-    char *TmpPtr,
-     *RetPtr;
-
-    if( *Src != NULL ) {
-        RetPtr = *Src;
-        TmpPtr = strstr( *Src, Del );
-        if( TmpPtr != NULL ) {
-            *TmpPtr = '\0';
-            *Src = TmpPtr + strlen( Del );
-        } else
-            *Src = NULL;
-
-        return RetPtr;
-    }
-
-    return NULL;
-}
-
-/************************************************************************
-* Function: GetNextRange												
-*																		
-* Parameters:															
-*	IN char ** SrcRangeStr ; string containing the token / range										
-*	OUT int * FirstByte ;	 gets the first byte of the token												
-*	OUT int * LastByte	; gets the last byte of the token												
-*																		
-* Description: Returns a range of integers from a sring					
-*																		
-* Returns: int	;
-*	always returns 1;				
-************************************************************************/
-int
-GetNextRange( char **SrcRangeStr,
-              off_t *FirstByte,
-              off_t *LastByte )
-{
-    char *Ptr,
-     *Tok;
-    int i;
-    int64_t F = -1;
-    int64_t L = -1;
-    off_t Is_Suffix_byte_Range = 1;
-
-    if( *SrcRangeStr == NULL )
-        return -1;
-
-    Tok = StrTok( SrcRangeStr, "," );
-
-    if( ( Ptr = strstr( Tok, "-" ) ) == NULL )
-        return -1;
-    *Ptr = ' ';
-    sscanf( Tok, "%"SCNd64"%"SCNd64, &F, &L );
-
-    if( F == -1 || L == -1 ) {
-        *Ptr = '-';
-        for( i = 0; i < ( int )strlen( Tok ); i++ ) {
-            if( Tok[i] == '-' ) {
-                break;
-            } else if( isdigit( Tok[i] ) ) {
-                Is_Suffix_byte_Range = 0;
-                break;
-            }
-
-        }
-
-        if( Is_Suffix_byte_Range ) {
-            *FirstByte = (off_t)L;
-            *LastByte = (off_t)F;
-            return 1;
-        }
-    }
-
-    *FirstByte = (off_t)F;
-    *LastByte = (off_t)L;
-    return 1;
-
-}
-
-/************************************************************************
-* Function: CreateHTTPRangeResponseHeader								
-*																		
-* Parameters:															
-*	char * ByteRangeSpecifier ; String containing the range 	
-*	File_Info FileInfo ; Structure containing information about the file
-*                        length and if it is known or not
-*	OUT struct SendInstruction * Instr ; SendInstruction object	where the 
-*										range operations will be stored
-*																		
-* Description: Fills in the Offset, read size and contents to send out	
-*	as an HTTP Range Response											
-*																		
-* Returns:																
-*	HTTP_BAD_REQUEST													
-*	UPNP_E_OUTOF_MEMORY													
-*	HTTP_REQUEST_RANGE_NOT_SATISFIABLE									
-*	HTTP_OK																
-************************************************************************/
-int
-CreateHTTPRangeResponseHeader( char *ByteRangeSpecifier,
-                               off_t FileLength,
-                               OUT struct SendInstruction *Instr )
-{
-
-    off_t FirstByte, LastByte;
-    char *RangeInput, *Ptr;
-    int ret;
-
-    Instr->IsRangeActive = 1;
-    Instr->ReadSendSize = FileLength;
-
-    if( !ByteRangeSpecifier )
-        return HTTP_BAD_REQUEST;
-
-    RangeInput = malloc( strlen( ByteRangeSpecifier ) + 1 );
-    if( !RangeInput )
-        return UPNP_E_OUTOF_MEMORY;
-    strcpy( RangeInput, ByteRangeSpecifier );
-
-    //CONTENT-RANGE: bytes 222-3333/4000  HTTP_PARTIAL_CONTENT
-    if( StrStr( RangeInput, "bytes" ) == NULL ||
-        ( Ptr = StrStr( RangeInput, "=" ) ) == NULL ) {
-        free( RangeInput );
-        Instr->IsRangeActive = 0;
-        return HTTP_BAD_REQUEST;
-    }
-    //Jump =
-    Ptr = Ptr + 1;
-
-    if( FileLength < 0 ) {
-        if ((*Ptr == '0') && (*(Ptr+1) == '-') && (*(Ptr+2) == '\0'))
-        {
-            Instr->IsRangeActive = 0;
-            ret = HTTP_OK;
-        }
-        else
-            ret = HTTP_REQUEST_RANGE_NOT_SATISFIABLE;
-        free( RangeInput );
-        return ret;
-    }
-
-    if( GetNextRange( &Ptr, &FirstByte, &LastByte ) != -1 ) {
-
-        if( FileLength < FirstByte ) {
-            free( RangeInput );
-            return HTTP_REQUEST_RANGE_NOT_SATISFIABLE;
-        }
-
-        if( FirstByte >= 0 && LastByte >= 0 && LastByte >= FirstByte ) {
-            if( LastByte >= FileLength )
-                LastByte = FileLength - 1;
-
-            Instr->RangeOffset = FirstByte;
-            Instr->ReadSendSize = LastByte - FirstByte + 1;
-            sprintf( Instr->RangeHeader, "CONTENT-RANGE: bytes " 
-                                          "%"PRId64 "-" 
-                                          "%"PRId64 "/" 
-                                          "%"PRId64 "\r\n", 
-                                          (int64_t)FirstByte, 
-                                          (int64_t)LastByte, 
-                                          (int64_t)FileLength );   //Data between two range.
-        } else if( FirstByte >= 0 && LastByte == -1
-                   && FirstByte < FileLength ) {
-            Instr->RangeOffset = FirstByte;
-            Instr->ReadSendSize = FileLength - FirstByte;
-            sprintf( Instr->RangeHeader,
-                     "CONTENT-RANGE: bytes " 
-                     "%"PRId64 "-"
-                     "%"PRId64 "/"
-                     "%"PRId64 "\r\n", (int64_t)FirstByte,
-                     (int64_t)(FileLength - 1), (int64_t)FileLength );
-        } else if( FirstByte == -1 && LastByte > 0 ) {
-            if( LastByte >= FileLength ) {
-                Instr->RangeOffset = 0;
-                Instr->ReadSendSize = FileLength;
-                sprintf( Instr->RangeHeader,
-                         "CONTENT-RANGE: bytes 0-"
-                         "%"PRId64 "/"
-                         "%"PRId64 "\r\n",
-                         (int64_t)(FileLength - 1), (int64_t)FileLength );
-            } else {
-                Instr->RangeOffset = FileLength - LastByte;
-                Instr->ReadSendSize = LastByte;
-                sprintf( Instr->RangeHeader,
-                         "CONTENT-RANGE: bytes "
-                         "%"PRId64 "-"
-                         "%"PRId64 "/"
-                         "%"PRId64 "\r\n",
-                         (int64_t)(FileLength - LastByte), 
-                         (int64_t)FileLength - 1,
-                         (int64_t)FileLength );
-            }
-        } else {
-            free( RangeInput );
-            return HTTP_REQUEST_RANGE_NOT_SATISFIABLE;
-        }
-    } else {
-        free( RangeInput );
-        return HTTP_REQUEST_RANGE_NOT_SATISFIABLE;
-    }
-
-    free( RangeInput );
-    return HTTP_OK;
-}
-
-/************************************************************************
-* Function: CheckOtherHTTPHeaders										
-*																		
-* Parameters:															
-*	IN http_message_t * Req ;  HTTP Request message
-*	OUT struct SendInstruction * RespInstr ; Send Instruction object to 
-*							data for the response
-*	int FileSize ;	Size of the file containing the request document
-*																		
-* Description: Get header id from the request parameter and take		
-*	appropriate action based on the ids.								
-*	as an HTTP Range Response											
-*																		
-* Returns:																
-*	HTTP_BAD_REQUEST													
-*	UPNP_E_OUTOF_MEMORY													
-*	HTTP_REQUEST_RANGE_NOT_SATISFIABLE									
-*	HTTP_OK																
-************************************************************************/
-int
-CheckOtherHTTPHeaders( IN http_message_t * Req,
-                       OUT struct SendInstruction *RespInstr,
-                       off_t FileSize )
-{
-    http_header_t *header;
-    ListNode *node;
-
-    //NNS: dlist_node* node;
-    int index,
-      RetCode = HTTP_OK;
-    char *TmpBuf;
-
-    TmpBuf = ( char * )malloc( LINE_SIZE );
-    if( !TmpBuf )
-        return UPNP_E_OUTOF_MEMORY;
-
-    node = ListHead( &Req->headers );
-
-    while( node != NULL ) {
-        header = ( http_header_t * ) node->item;
-
-        // find header type.
-        index = map_str_to_int( ( const char * )header->name.buf,
-                                header->name.length, Http_Header_Names,
-                                NUM_HTTP_HEADER_NAMES, FALSE );
-
-        if( header->value.length >= LINE_SIZE ) {
-            free( TmpBuf );
-            TmpBuf = ( char * )malloc( header->value.length + 1 );
-            if( !TmpBuf )
-                return UPNP_E_OUTOF_MEMORY;
-        }
-
-        memcpy( TmpBuf, header->value.buf, header->value.length );
-        TmpBuf[header->value.length] = '\0';
-        if( index >= 0 )
-            switch ( Http_Header_Names[index].id ) {
-                case HDR_TE:   //Request
-                    {
-                        RespInstr->IsChunkActive = 1;
-
-                        if( strlen( TmpBuf ) > strlen( "gzip" ) ) {
-                            if( StrStr( TmpBuf, "trailers" ) != NULL ) {    //means client will accept trailer
-                                RespInstr->IsTrailers = 1;
-                            }
-                        }
-                    }
-                    break;
-
-                case HDR_CONTENT_LENGTH:
-                    {
-                        RespInstr->RecvWriteSize = atoi( TmpBuf );
-                        break;
-                    }
-
-                case HDR_RANGE:
-                    if( ( RetCode = CreateHTTPRangeResponseHeader( TmpBuf,
-                                                                   FileSize,
-                                                                   RespInstr ) )
-                        != HTTP_OK ) {
-                        free( TmpBuf );
-                        return RetCode;
-                    }
-                    break;
-                default:
-                    /*
-                       TODO 
-                     */
-                    /*
-                       header.value is the value. 
-                     */
-                    /*
-                       case HDR_CONTENT_TYPE: //return 1;
-                       case HDR_CONTENT_LANGUAGE://return 1;
-                       case HDR_LOCATION: //return 1;
-                       case HDR_CONTENT_LOCATION://return 1;
-                       case HDR_ACCEPT: //return 1;
-                       case HDR_ACCEPT_CHARSET://return 1;
-                       case HDR_ACCEPT_LANGUAGE://return 1;
-                       case HDR_USER_AGENT: break;//return 1;
-                     */
-
-                    //Header check for encoding 
-                    /*
-                       case HDR_ACCEPT_RANGE: //Server capability.
-                       case HDR_CONTENT_RANGE://Response.
-                       case HDR_IF_RANGE:
-                     */
-
-                    //Header check for encoding 
-                    /*
-                       case HDR_ACCEPT_ENCODING:
-                       if(StrStr(TmpBuf, "identity"))
-                       {
-                       break;
-                       }
-                       else return -1;
-                       case HDR_CONTENT_ENCODING:
-                       case HDR_TRANSFER_ENCODING: //Response
-                     */
-                    break;
-            }
-
-        node = ListNext( &Req->headers, node );
-
-    }
-
-    free( TmpBuf );
-    return RetCode;
-}
-
-/************************************************************************
-* Function: process_request												
-*																		
-* Parameters:															
-*	IN http_message_t *req ; HTTP Request message												
-*	OUT enum resp_type *rtype ; Tpye of response											
-*	OUT membuffer *headers ; 												
-*	OUT membuffer *filename ; Get filename from request document
-*	OUT struct xml_alias_t *alias ; Xml alias document from the 
-*									request document,										
-*	OUT struct SendInstruction * RespInstr ; Send Instruction object 
-*					where the response is set up.										
-*																		
-* Description: Processes the request and returns the result in the OUT	
-*	parameters															
-*																		
-* Returns:																
-*	HTTP_BAD_REQUEST													
-*	UPNP_E_OUTOF_MEMORY													
-*	HTTP_REQUEST_RANGE_NOT_SATISFIABLE									
-*	HTTP_OK																
-************************************************************************/
-static int
-process_request( IN http_message_t * req,
-                 OUT enum resp_type *rtype,
-                 OUT membuffer * headers,
-                 OUT membuffer * filename,
-                 OUT struct xml_alias_t *alias,
-                 OUT struct SendInstruction *RespInstr,
-                 OUT UpnpWebFileHandle* Fp)
-{
-    int code;
-    int err_code;
-
-    //membuffer content_type;
-    char *request_doc;
-    struct File_Info finfo;
-    xboolean using_alias;
-    xboolean using_virtual_dir;
-    uri_type *url;
-    char *temp_str;
-    int resp_major,
-      resp_minor;
-    xboolean alias_grabbed;
-    int dummy;
-    struct UpnpVirtualDirCallbacks *pVirtualDirCallback;
-
-    print_http_headers( req );
-
-    url = &req->uri;
-    assert( req->method == HTTPMETHOD_GET ||
-            req->method == HTTPMETHOD_HEAD
-            || req->method == HTTPMETHOD_POST
-            || req->method == HTTPMETHOD_SIMPLEGET );
-
-    // init
-    request_doc = NULL;
-    finfo.content_type = NULL;
-    finfo.http_header = NULL;
-    finfo.force_chunked = FALSE;
-    *Fp = NULL;
-    //membuffer_init( &content_type );
-    alias_grabbed = FALSE;
-    err_code = HTTP_INTERNAL_SERVER_ERROR;  // default error
-    using_virtual_dir = FALSE;
-    using_alias = FALSE;
-
-    http_CalcResponseVersion( req->major_version, req->minor_version,
-                              &resp_major, &resp_minor );
-
-    if( req->method == HTTPMETHOD_GET ) {
-      if( ( req->major_version == 1 ) && ( req->minor_version == 0 ) ) {
-        resp_major = 1;
-        resp_minor = 1;
-      }
-    }
-
-    //
-    // remove dots
-    //
-    request_doc = malloc( url->pathquery.size + 1 );
-    if( request_doc == NULL ) {
-        goto error_handler;     // out of mem
-    }
-    memcpy( request_doc, url->pathquery.buff, url->pathquery.size );
-    request_doc[url->pathquery.size] = '\0';
-    dummy = url->pathquery.size;
-    remove_escaped_chars( request_doc, &dummy );
-    code = remove_dots( request_doc, url->pathquery.size );
-    if( code != 0 ) {
-        err_code = HTTP_FORBIDDEN;
-        goto error_handler;
-    }
-
-    if( *request_doc != '/' ) {
-        // no slash
-        err_code = HTTP_BAD_REQUEST;
-        goto error_handler;
-    }
-
-    if( isFileInVirtualDir( request_doc ) ) {
-        using_virtual_dir = TRUE;
-        RespInstr->IsVirtualFile = 1;
-        if( membuffer_assign_str( filename, request_doc ) != 0 ) {
-            goto error_handler;
-        }
-
-    } else {
-        //
-        // try using alias
-        //
-        if( is_valid_alias( &gAliasDoc ) ) {
-            alias_grab( alias );
-            alias_grabbed = TRUE;
-
-            using_alias = get_alias( request_doc, alias, &finfo );
-            if( using_alias == TRUE ) {
-                finfo.content_type = ixmlCloneDOMString( "text/xml; charset=UTF-8" );
-
-                if( finfo.content_type == NULL ) {
-                    goto error_handler;
-                }
-            }
-        }
-    }
-
-    if( using_virtual_dir ) {
-        if( req->method != HTTPMETHOD_POST ) {
-            // get file info
-            pVirtualDirCallback = &virtualDirCallback;
-            if( req->method == HTTPMETHOD_GET ) 
-            {
-                // use urlbuf instead of filename, because the filename 
-                // is already unescaped, but we want the escaped version
-                *Fp = pVirtualDirCallback->open( req->urlbuf, req->msg.buf, &finfo, UPNP_READ );
-                if( *Fp == NULL )
-                {
-                    err_code = HTTP_NOT_FOUND;
-                    goto error_handler;
-                }
-            }
-            else
-            {
-                // use urlbuf instead of filename, because the filename 
-                // is already unescaped, but we want the escaped version
-
-                if( pVirtualDirCallback->get_info( req->urlbuf, req->msg.buf, &finfo ) !=
-                        0 ) {
-                    err_code = HTTP_NOT_FOUND;
-                    goto error_handler;
-                }
-            }
-            // try index.html if req is a dir
-            if( finfo.is_directory ) {
-                if (*Fp != NULL)
-                {
-                    pVirtualDirCallback->close(*Fp);
-                }
-                if( filename->buf[filename->length - 1] == '/' ) {
-                    temp_str = "index.html";
-                } else {
-                    temp_str = "/index.html";
-                }
-                if( membuffer_append_str( filename, temp_str ) != 0 ) {
-                    goto error_handler;
-                }
-                // get info
-                *Fp = pVirtualDirCallback->open( req->urlbuf, req->msg.buf, &finfo, UPNP_READ );
-                if( (*Fp == NULL) || finfo.is_directory ) {
-                    err_code = HTTP_NOT_FOUND;
-                    goto error_handler;
-                }
-            }
-            // not readable
-            if( !finfo.is_readable ) {
-                if (*Fp != NULL)
-                {
-                    pVirtualDirCallback->close(*Fp);
-                    *Fp = NULL;
-                }
-                err_code = HTTP_FORBIDDEN;
-                goto error_handler;
-            }
-            // finally, get content type
-            // if ( get_content_type(filename->buf, &content_type) != 0 )
-            //{
-            //  goto error_handler;
-            // }
-        }
-    } else if( !using_alias ) {
-        if( gDocumentRootDir.length == 0 ) {
-            goto error_handler;
-        }
-        //
-        // get file name
-        //
-
-        // filename str
-        if( membuffer_assign_str( filename, gDocumentRootDir.buf ) != 0 ||
-            membuffer_append_str( filename, request_doc ) != 0 ) {
-            goto error_handler; // out of mem
-        }
-        // remove trailing slashes
-        while( filename->length > 0 &&
-               filename->buf[filename->length - 1] == '/' ) {
-            membuffer_delete( filename, filename->length - 1, 1 );
-        }
-
-        if( req->method != HTTPMETHOD_POST ) {
-            // get info on file
-            if( get_file_info( filename->buf, &finfo ) != 0 ) {
-                err_code = HTTP_NOT_FOUND;
-                goto error_handler;
-            }
-            // try index.html if req is a dir
-            if( finfo.is_directory ) {
-                if( filename->buf[filename->length - 1] == '/' ) {
-                    temp_str = "index.html";
-                } else {
-                    temp_str = "/index.html";
-                }
-                if( membuffer_append_str( filename, temp_str ) != 0 ) {
-                    goto error_handler;
-                }
-                // get info
-                if( get_file_info( filename->buf, &finfo ) != 0 ||
-                    finfo.is_directory ) {
-                    err_code = HTTP_NOT_FOUND;
-                    goto error_handler;
-                }
-            }
-            // not readable
-            if( !finfo.is_readable ) {
-                err_code = HTTP_FORBIDDEN;
-                goto error_handler;
-            }
-
-        }
-        // finally, get content type
-        //      if ( get_content_type(filename->buf, &content_type) != 0 )
-        //      {
-        //          goto error_handler;
-        //      }
-    }
-
-    RespInstr->ReadSendSize = finfo.file_length;
-    if (finfo.force_chunked == TRUE)
-        RespInstr->IsChunkActive = TRUE;
-
-    //Check other header field.
-    if( ( err_code =
-          CheckOtherHTTPHeaders( req, RespInstr,
-                                 finfo.file_length ) ) != HTTP_OK ) {
-        if (using_virtual_dir && (req->method != HTTPMETHOD_POST) &&
-           (*Fp != NULL))
-        {
-            pVirtualDirCallback->close(*Fp);
-            *Fp = NULL;
-        }
-        goto error_handler;
-    }
-
-    if( req->method == HTTPMETHOD_POST ) {
-        *rtype = RESP_POST;
-        err_code = UPNP_E_SUCCESS;
-        goto error_handler;
-    }
-
-    if( RespInstr->IsRangeActive && RespInstr->IsChunkActive ) {
-                //Content-Range: bytes 222-3333/4000  HTTP_PARTIAL_CONTENT
-        //Transfer-Encoding: chunked
-        // K means add chunky header ang G means range header.
-        if( http_MakeMessage( headers, resp_major, resp_minor, "RTGKDstcSCAAc", HTTP_PARTIAL_CONTENT, // status code
-                              // RespInstr->ReadSendSize,// content length
-                              finfo.content_type,
-                              //     content_type.buf,            // content type
-                              RespInstr,    // Range
-                              "LAST-MODIFIED: ",
-                              &finfo.last_modified,
-                              finfo.http_header,
-                              gUserHTTPHeaders.buf
-                              ) != 0 ) {
-            goto error_handler;
-        }
-
-    } else if( RespInstr->IsRangeActive && !RespInstr->IsChunkActive ) {
-
-        //Content-Range: bytes 222-3333/4000  HTTP_PARTIAL_CONTENT
-        //Transfer-Encoding: chunked
-        // K means add chunky header ang G means range header.
-        if( http_MakeMessage( headers, resp_major, resp_minor, "RNTGDstcSCAAc", HTTP_PARTIAL_CONTENT, // status code
-                              RespInstr->ReadSendSize,  // content length
-                              finfo.content_type,
-                              //content_type.buf,            // content type
-                              RespInstr,    //Range Info
-                              "LAST-MODIFIED: ",
-                              &finfo.last_modified,
-                              finfo.http_header,
-                              gUserHTTPHeaders.buf
-                              ) != 0 ) {
-            goto error_handler;
-        }
-
-    } else if( !RespInstr->IsRangeActive && RespInstr->IsChunkActive ) {
-
-        //Content-Range: bytes 222-3333/4000  HTTP_PARTIAL_CONTENT
-        //Transfer-Encoding: chunked
-        // K means add chunky header ang G means range header.
-        if( http_MakeMessage( headers, resp_major, resp_minor, "RKTDstcSCAAc", HTTP_OK,   // status code
-                              //RespInstr->ReadSendSize,// content length
-                              finfo.content_type,
-                              // content_type.buf,            // content type
-                              "LAST-MODIFIED: ",
-                              &finfo.last_modified,
-                              finfo.http_header,
-                              gUserHTTPHeaders.buf
-                              ) != 0 ) {
-            goto error_handler;
-        }
-
-    } else {
-        if( RespInstr->ReadSendSize >= 0 ) {
-            //Content-Range: bytes 222-3333/4000  HTTP_PARTIAL_CONTENT
-            //Transfer-Encoding: chunked
-            // K means add chunky header ang G means range header.
-            if( http_MakeMessage( headers, resp_major, resp_minor, "RNTDstcSCAAc", HTTP_OK,   // status code
-                                  RespInstr->ReadSendSize,  // content length
-                                  finfo.content_type,
-                                  //content_type.buf,          // content type
-                                  "LAST-MODIFIED: ",
-                                  &finfo.last_modified,
-                                  finfo.http_header,
-                                  gUserHTTPHeaders.buf
-                                  ) != 0 ) {
-                goto error_handler;
-            }
-        } else {
-            //Content-Range: bytes 222-3333/4000  HTTP_PARTIAL_CONTENT
-            //Transfer-Encoding: chunked
-            // K means add chunky header ang G means range header.
-            if( http_MakeMessage( headers, resp_major, resp_minor, "RTDstcSCAAc", HTTP_OK,    // status code
-                                  //RespInstr->ReadSendSize,// content length
-                                  finfo.content_type,
-                                  //content_type.buf,          // content type
-                                  "LAST-MODIFIED: ",
-                                  &finfo.last_modified,
-                                  finfo.http_header,
-                                  gUserHTTPHeaders.buf
-                                  ) != 0 ) {
-                goto error_handler;
-            }
-        }
-    }
-
-    if( req->method == HTTPMETHOD_HEAD ) {
-        *rtype = RESP_HEADERS;
-    } else if( using_alias ) {
-        // GET xml
-        *rtype = RESP_XMLDOC;
-    } else if( using_virtual_dir ) {
-        *rtype = RESP_WEBDOC;
-    } else {
-        // GET filename
-        *rtype = RESP_FILEDOC;
-    }
-
-    //simple get http 0.9 as specified in http 1.0
-    //don't send headers
-    if( req->method == HTTPMETHOD_SIMPLEGET ) {
-        membuffer_destroy( headers );
-    }
-
-    err_code = UPNP_E_SUCCESS;
-
-  error_handler:
-    free( request_doc );
-    ixmlFreeDOMString( finfo.content_type );
-    if (finfo.http_header)
-        ixmlFreeDOMString( finfo.http_header);
-    //  membuffer_destroy( &content_type );
-    if( err_code != UPNP_E_SUCCESS && alias_grabbed ) {
-        alias_release( alias );
-    }
-
-    return err_code;
-}
-
-/************************************************************************
-* Function: http_RecvPostMessage										
-*																		
-* Parameters:															
-*	http_parser_t* parser ; HTTP Parser object							
-*	IN SOCKINFO *info ; Socket Information object													
-*	char * filename ; 	File where received data is copied to
-*	struct SendInstruction * Instr	; Send Instruction object which gives
-*			information whether the file is a virtual file or not.
-*																		
-* Description: Receives the HTTP post message														
-*																		
-* Returns:																
-*	HTTP_INTERNAL_SERVER_ERROR											
-*	HTTP_UNAUTHORIZED													
-*	HTTP_REQUEST_RANGE_NOT_SATISFIABLE									
-*	HTTP_OK																
-************************************************************************/
-int
-http_RecvPostMessage( http_parser_t * parser,
-                      IN SOCKINFO * info,
-                      char *filename,
-                      struct SendInstruction *Instr )
-{
-
-    unsigned int Data_Buf_Size = 1024;
-    char Buf[1024];
-    int Timeout = 0;
-    long Num_Write = 0;
-    FILE *Fp;
-    struct File_Info *finfo = NULL;
-    parse_status_t status = PARSE_OK;
-    xboolean ok_on_close = FALSE;
-    unsigned int entity_offset = 0;
-    int num_read = 0;
-    int ret_code = 0;
-
-    if( Instr && Instr->IsVirtualFile ) {
-
-        Fp = virtualDirCallback.open( filename, parser->msg.msg.buf, finfo, UPNP_WRITE );
-        if( Fp == NULL ) {
-            return HTTP_INTERNAL_SERVER_ERROR;
-        }
-
-    } else {
-        Fp = fopen( filename, "wb" );
-        if( Fp == NULL ) {
-            return HTTP_UNAUTHORIZED;
-        }
-    }
-
-    parser->position = POS_ENTITY;
-
-    do {
-        //first parse what has already been gotten
-        if( parser->position != POS_COMPLETE ) {
-            status = parser_parse_entity( parser );
-        }
-
-        if( status == PARSE_INCOMPLETE_ENTITY ) {
-            // read until close
-            ok_on_close = TRUE;
-        } else if( ( status != PARSE_SUCCESS )
-                   && ( status != PARSE_CONTINUE_1 )
-                   && ( status != PARSE_INCOMPLETE ) ) {
-            //error
-            fclose( Fp );
-            return HTTP_BAD_REQUEST;
-        }
-        //read more if necessary entity
-        while( ( ( entity_offset + Data_Buf_Size ) >
-                 parser->msg.entity.length )
-               && ( parser->position != POS_COMPLETE ) ) {
-            num_read = sock_read( info, Buf, sizeof( Buf ), &Timeout );
-            if( num_read > 0 ) {
-                // append data to buffer
-                ret_code = membuffer_append( &parser->msg.msg,
-                                             Buf, num_read );
-                if( ret_code != 0 ) {
-                    // set failure status
-                    parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
-                    return HTTP_INTERNAL_SERVER_ERROR;
-                }
-                status = parser_parse_entity( parser );
-                if( status == PARSE_INCOMPLETE_ENTITY ) {
-                    // read until close
-                    ok_on_close = TRUE;
-                } else if( ( status != PARSE_SUCCESS )
-                           && ( status != PARSE_CONTINUE_1 )
-                           && ( status != PARSE_INCOMPLETE ) ) {
-                    return HTTP_BAD_REQUEST;
-                }
-            } else if( num_read == 0 ) {
-                if( ok_on_close ) {
-                    DBGONLY( UpnpPrintf
-                             ( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                               "<<< (RECVD) <<<\n%s\n-----------------\n",
-                               parser->msg.msg.buf );
-                             //print_http_headers( &parser->msg );
-                         )
-
-                        parser->position = POS_COMPLETE;
-                } else {
-                    // partial msg
-                    parser->http_error_code = HTTP_BAD_REQUEST; // or response
-                    return HTTP_BAD_REQUEST;
-                }
-            } else {
-                return num_read;
-            }
-        }
-
-        if( ( entity_offset + Data_Buf_Size ) > parser->msg.entity.length ) {
-            Data_Buf_Size = parser->msg.entity.length - entity_offset;
-        }
-
-        memcpy( Buf, &parser->msg.msg.buf[parser->entity_start_position
-                                          + entity_offset],
-                Data_Buf_Size );
-        entity_offset += Data_Buf_Size;
-
-        if( Instr && Instr->IsVirtualFile ) {
-            Num_Write = virtualDirCallback.write( Fp, Buf, Data_Buf_Size );
-            if( Num_Write < 0 ) {
-                virtualDirCallback.close( Fp );
-                return HTTP_INTERNAL_SERVER_ERROR;
-            }
-        } else {
-            Num_Write = fwrite( Buf, 1, Data_Buf_Size, Fp );
-            if( Num_Write < 0 ) {
-                fclose( Fp );
-                return HTTP_INTERNAL_SERVER_ERROR;
-            }
-        }
-
-    } while( ( parser->position != POS_COMPLETE )
-             || ( entity_offset != parser->msg.entity.length ) );
-
-    if( Instr && Instr->IsVirtualFile ) {
-        virtualDirCallback.close( Fp );
-    } else {
-        fclose( Fp );
-    }
-
-    /*
-       while(TotalByteReceived < Instr->RecvWriteSize &&
-       (NumReceived = sock_read(info,Buf, Data_Buf_Size,&Timeout) ) > 0 ) 
-       {
-       TotalByteReceived = TotalByteReceived + NumReceived;
-       Num_Write = virtualDirCallback.write(Fp, Buf, NumReceived);
-       if (ferror(Fp))
-       {
-       virtualDirCallback.close(Fp);
-       return HTTP_INTERNAL_SERVER_ERROR;
-       }
-       }
-
-       if(TotalByteReceived < Instr->RecvWriteSize)
-       {
-       return HTTP_INTERNAL_SERVER_ERROR;
-       }
-
-       virtualDirCallback.close(Fp);
-       }
-     */
-    return HTTP_OK;
-}
-
-/************************************************************************
-* Function: web_server_callback											
-*																		
-* Parameters:															
-*	IN http_parser_t *parser ; HTTP Parser Object						
-*	INOUT http_message_t* req ; HTTP Message request										
-*	IN SOCKINFO *info ;			Socket information object													
-*																		
-* Description: main entry point into web server;						
-*	handles HTTP GET and HEAD requests									
-*																		
-* Returns:																
-*	void																
-************************************************************************/
-void
-web_server_callback( IN http_parser_t * parser,
-                     INOUT http_message_t * req,
-                     IN SOCKINFO * info )
-{
-    int ret;
-    int timeout = 0;
-    enum resp_type rtype = 0;
-    membuffer headers;
-    membuffer filename;
-    struct xml_alias_t xmldoc;
-    struct SendInstruction RespInstr;
-
-    UpnpWebFileHandle Fp = NULL;
-    //Initialize instruction header.
-    RespInstr.IsVirtualFile = 0;
-    RespInstr.IsChunkActive = 0;
-    RespInstr.IsRangeActive = 0;
-    RespInstr.IsTrailers = 0;
-    // init
-    membuffer_init( &headers );
-    membuffer_init( &filename );
-
-    //Process request should create the different kind of header depending on the
-    //the type of request.
-    ret =
-        process_request( req, &rtype, &headers, &filename, &xmldoc,
-                         &RespInstr, &Fp);
-    if( ret != UPNP_E_SUCCESS ) {
-        // send error code
-        http_SendStatusResponse( info, ret, req->major_version,
-                                 req->minor_version );
-    } else {
-        //
-        // send response
-        switch ( rtype ) {
-            case RESP_FILEDOC: // send file, I = further instruction to send data.
-                http_SendMessage( info, &timeout, "Ibf", &RespInstr,
-                                  headers.buf, (size_t)headers.length,
-                                  filename.buf );
-                break;
-
-            case RESP_XMLDOC:  // send xmldoc , I = further instruction to send data.
-                http_SendMessage( info, &timeout, "Ibb", &RespInstr,
-                                  headers.buf, (size_t)headers.length,
-                                  xmldoc.doc.buf, xmldoc.doc.length );
-                alias_release( &xmldoc );
-                break;
-
-            case RESP_WEBDOC:  //, I = further instruction to send data.
-                /*
-                   http_SendVirtualDirDoc( info, &timeout, "Ibf",&RespInstr,
-                   headers.buf, headers.length,
-                   filename.buf );  
-                 */
-                http_SendMessage( info, &timeout, "Ibf", &RespInstr,
-                                  headers.buf, (size_t)headers.length,
-                                  filename.buf, Fp );
-                break;
-
-            case RESP_HEADERS: // headers only
-                http_SendMessage( info, &timeout, "b",
-                                  headers.buf, (size_t)headers.length );
-
-                break;
-            case RESP_POST:    // headers only
-                ret =
-                    http_RecvPostMessage( parser, info, filename.buf,
-                                          &RespInstr );
-                //Send response.
-
-                http_MakeMessage( &headers, 1, 1, "RTDSCAc", ret,
-                                  "text/html", gUserHTTPHeaders );
-
-                http_SendMessage( info, &timeout, "b", headers.buf,
-                                  (size_t)headers.length );
-                break;
-
-            default:
-                assert( 0 );
-        }
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
-                         "webserver: request processed...\n" );
-         )
-
-        membuffer_destroy( &headers );
-    membuffer_destroy( &filename );
-}
diff --git a/tombupnp/upnp/src/genlib/net/sock.c b/tombupnp/upnp/src/genlib/net/sock.c
deleted file mode 100644
index 9ebba01..0000000
--- a/tombupnp/upnp/src/genlib/net/sock.c
+++ /dev/null
@@ -1,551 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/************************************************************************
-* Purpose: This file implements the sockets functionality 
-************************************************************************/
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include "config.h"
-#include <assert.h>
-#include <errno.h>
-#include <time.h>
-#include <string.h>
-#include <poll.h>
-
-#include "sock.h"
-#include "upnp.h"
-#include "upnpapi.h"
-
-#ifndef WIN32
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <unistd.h>
-#else
- #include <winsock2.h>
-#endif
-#include "unixutil.h"
-
-#ifndef MSG_NOSIGNAL
- #define MSG_NOSIGNAL 0
-#endif
-
-/************************************************************************
-*	Function :	sock_init
-*
-*	Parameters :
-*		OUT SOCKINFO* info ;	Socket Information Object
-*		IN int sockfd ;			Socket Descriptor
-*
-*	Description :	Assign the passed in socket descriptor to socket 
-*		descriptor in the SOCKINFO structure.
-*
-*	Return : int;
-*		UPNP_E_SUCCESS	
-*		UPNP_E_OUTOF_MEMORY
-*		UPNP_E_SOCKET_ERROR
-*
-*	Note :
-************************************************************************/
-int
-sock_init( OUT SOCKINFO * info,
-           IN int sockfd )
-{
-    assert( info );
-
-    memset( info, 0, sizeof( SOCKINFO ) );
-
-    info->socket = sockfd;
-
-    return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-*	Function :	sock_init_with_ip
-*
-*	Parameters :
-*		OUT SOCKINFO* info ;				Socket Information Object
-*		IN int sockfd ;						Socket Descriptor
-*		IN struct in_addr foreign_ip_addr ;	Remote IP Address
-*		IN unsigned short foreign_ip_port ;	Remote Port number
-*
-*	Description :	Calls the sock_init function and assigns the passed in
-*		IP address and port to the IP address and port in the SOCKINFO
-*		structure.
-*
-*	Return : int;
-*		UPNP_E_SUCCESS	
-*		UPNP_E_OUTOF_MEMORY
-*		UPNP_E_SOCKET_ERROR
-*
-*	Note :
-************************************************************************/
-int
-sock_init_with_ip( OUT SOCKINFO * info,
-                   IN int sockfd,
-                   IN struct in_addr foreign_ip_addr,
-                   IN unsigned short foreign_ip_port )
-{
-    int ret;
-
-    ret = sock_init( info, sockfd );
-    if( ret != UPNP_E_SUCCESS ) {
-        return ret;
-    }
-
-    info->foreign_ip_addr = foreign_ip_addr;
-    info->foreign_ip_port = foreign_ip_port;
-
-    return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-*	Function :	sock_destroy
-*
-*	Parameters :
-*		INOUT SOCKINFO* info ;	Socket Information Object
-*		int ShutdownMethod ;	How to shutdown the socket. Used by  
-*								sockets's shutdown() 
-*
-*	Description :	Shutsdown the socket using the ShutdownMethod to 
-*		indicate whether sends and receives on the socket will be 
-*		dis-allowed. After shutting down the socket, closesocket is called
-*		to release system resources used by the socket calls.
-*
-*	Return : int;
-*		UPNP_E_SOCKET_ERROR on failure
-*		UPNP_E_SUCCESS on success
-*
-*	Note :
-************************************************************************/
-int
-sock_destroy( INOUT SOCKINFO * info,
-              int ShutdownMethod )
-{
-    shutdown( info->socket, ShutdownMethod );
-    if( UpnpCloseSocket( info->socket ) == -1 ) {
-        return UPNP_E_SOCKET_ERROR;
-    }
-
-    return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-*	Function :	sock_read_write
-*
-*	Parameters :
-*		IN SOCKINFO *info ;	Socket Information Object
-*		OUT char* buffer ;	Buffer to get data to or send data from 
-*		IN size_t bufsize ;	Size of the buffer
-*	    IN int *timeoutSecs ;	timeout value
-*		IN xboolean bRead ;	Boolean value specifying read or write option
-*
-*	Description :	Receives or sends data. Also returns the time taken
-*		to receive or send data.
-*
-*	Return :int ;
-*		numBytes - On Success, no of bytes received or sent		
-*		UPNP_E_TIMEDOUT - Timeout
-*		UPNP_E_SOCKET_ERROR - Error on socket calls
-*
-*	Note :
-************************************************************************/
-#if 0
-static int
-sock_read_write( IN SOCKINFO * info,
-                 OUT char *buffer,
-                 IN size_t bufsize,
-                 IN int *timeoutSecs,
-                 IN xboolean bRead )
-{
-    int retCode;
-    fd_set readSet;
-    fd_set writeSet;
-    struct timeval timeout;
-    int numBytes;
-    time_t start_time = time( NULL );
-    int sockfd = info->socket;
-    long bytes_sent = 0,
-      byte_left = 0,
-      num_written;
-
-    if( *timeoutSecs < 0 ) {
-        return UPNP_E_TIMEDOUT;
-    }
-
-    FD_ZERO( &readSet );
-    FD_ZERO( &writeSet );
-    if( bRead ) {
-        FD_SET( ( unsigned )sockfd, &readSet );
-    } else {
-        FD_SET( ( unsigned )sockfd, &writeSet );
-    }
-
-    timeout.tv_sec = *timeoutSecs;
-    timeout.tv_usec = 0;
-
-    while( TRUE ) {
-        if( *timeoutSecs == 0 ) {
-            retCode =
-                select( sockfd + 1, &readSet, &writeSet, NULL, NULL );
-        } else {
-            retCode =
-                select( sockfd + 1, &readSet, &writeSet, NULL, &timeout );
-        }
-
-        if( retCode == 0 ) {
-            return UPNP_E_TIMEDOUT;
-        }
-        if( retCode == -1 ) {
-            if( errno == EINTR )
-                continue;
-            return UPNP_E_SOCKET_ERROR; // error
-        } else {
-            break;              // read or write
-        }
-    }
-
-    if( bRead ) {
-        // read data
-        numBytes = recv( sockfd, buffer, bufsize,MSG_NOSIGNAL);
-    } else {
-        byte_left = bufsize;
-        bytes_sent = 0;
-        while( byte_left > 0 ) {
-            // write data
-            num_written =
-                send( sockfd, buffer + bytes_sent, byte_left,
-                      MSG_DONTROUTE|MSG_NOSIGNAL);
-            if( num_written == -1 ) {
-                return num_written;
-            }
-
-            byte_left = byte_left - num_written;
-            bytes_sent += num_written;
-        }
-
-        numBytes = bytes_sent;
-    }
-
-    if( numBytes < 0 ) {
-        return UPNP_E_SOCKET_ERROR;
-    }
-    // subtract time used for reading/writing
-    if( *timeoutSecs != 0 ) {
-        *timeoutSecs -= time( NULL ) - start_time;
-    }
-
-    return numBytes;
-}
-#endif
-
-/************************************************************************
-*	Function :	sock_read
-*
-*	Parameters :
-*		IN SOCKINFO *info ;	Socket Information Object
-*		OUT char* buffer ;	Buffer to get data to  
-*		IN size_t bufsize ;	Size of the buffer
-*	    IN int *timeoutSecs ;	timeout value
-*
-*	Description :	Calls sock_read_write() for reading data on the 
-*		socket
-*
-*	Return : int;
-*		Values returned by sock_read_write() 
-*
-*	Note :
-************************************************************************/
-int
-sock_read( IN SOCKINFO * info,
-           OUT char *buffer,
-           IN size_t bufsize,
-           INOUT int *timeoutSecs )
-{
-//    return sock_read_write( info, buffer, bufsize, timeoutSecs, TRUE );
-    int sockfd = info->socket; 
-    int retCode;
-    fd_set readSet;
-    struct timeval timeout;
-    ssize_t bytes_received = 0;
-    int num_bytes = 0;
-    char* p_buffer = buffer;
-    int no_timeout = 0; // detect end of data
-
-    if (*timeoutSecs < 0)
-    {
-        return UPNP_E_TIMEDOUT;
-    }
-
-    FD_ZERO(&readSet);
-    FD_SET(sockfd, &readSet);
-
-    timeout.tv_sec = *timeoutSecs;
-    timeout.tv_usec = 0;
-       
-    while (TRUE)
-    {
-        if (*timeoutSecs == 0)
-        {
-            retCode = select(sockfd + 1, &readSet, NULL, NULL, NULL);
-        }
-        else
-        {
-            retCode = select(sockfd + 1, &readSet, NULL, NULL, &timeout);
-        }
-
-        if (retCode == -1)
-        {
-            if(errno == EINTR)
-                continue;
-
-            return UPNP_E_SOCKET_ERROR;
-        }
-        
-        if (retCode == 0)
-        {
-            if (no_timeout)
-                return num_bytes;
-            else
-                return UPNP_E_TIMEDOUT;
-        }
-
-        if (FD_ISSET(sockfd, &readSet))
-        {
-            // we use this to detect "end of data" so we do not block
-            // when it may not be needed
-            // only the first select will wait for a timeout (in case a
-            // timeout was specified)
-            timeout.tv_sec = 0; 
-            timeout.tv_usec = 0;
-            if (*timeoutSecs)
-                no_timeout = 1;
-
-            bytes_received = recv(sockfd, p_buffer, bufsize, MSG_NOSIGNAL);
-
-            // nothing more to read
-            if (bytes_received == 0)
-                break;
-
-            // error
-            if (bytes_received < 0)
-                return UPNP_E_SOCKET_ERROR;
-
-            num_bytes = num_bytes + bytes_received;
-            bufsize = bufsize - bytes_received;
-
-            // no space left in buffer
-            if (bufsize <= 0)
-                break;
-
-            p_buffer = buffer + num_bytes;
-        }
-    }
-
-    if (num_bytes < 0)  
-    {
-        return UPNP_E_SOCKET_ERROR;
-    }
-
-    return num_bytes;
-}
-
-// checks if writing to the socket is possible
-int
-sock_check_w( IN SOCKINFO * info )
-{
-    fd_set readSet;
-    fd_set exceptSet;
-    struct timeval timeout;
-
-    int retCode;
-    int sockfd = info->socket;
-
-    FD_ZERO(&readSet);
-    FD_ZERO(&exceptSet);
-    FD_SET(sockfd, &readSet);
-    FD_SET(sockfd, &exceptSet);
-
-    timeout.tv_sec = 1; // 1 second select, we do not care if it times out
-                        // we only look for an error
-    timeout.tv_usec = 0;
-
-    retCode = select(sockfd + 1, &readSet, NULL, &exceptSet, &timeout);
-    
-    if (FD_ISSET(sockfd, &readSet) || FD_ISSET(sockfd, &exceptSet))
-    {
-        return 0;
-    }
-
-    if (retCode >= 0) // timeout or fd ready for writing
-        return 1;
-
-    if (retCode == -1)
-    {
-        if(errno == EINTR)
-            return 1;
-    }
-
-    return 0;
-}
-
-/************************************************************************
-*	Function :	sock_write
-*
-*	Parameters :
-*		IN SOCKINFO *info ;	Socket Information Object
-*		IN char* buffer ;	Buffer to send data from 
-*		IN size_t bufsize ;	Size of the buffer
-*	    IN int *timeoutSecs ;	timeout value
-*
-*	Description :	Calls sock_read_write() for writing data on the 
-*		socket
-*
-*	Return : int;
-*		sock_read_write()
-*
-*	Note :
-************************************************************************/
-int
-sock_write( IN SOCKINFO * info,
-            IN char *buffer,
-            IN size_t bufsize,
-            INOUT int *timeoutSecs )
-{
-//    return sock_read_write( info, buffer, bufsize, timeoutSecs, FALSE );
-    int sockfd = info->socket;
-    int retCode;
-    fd_set writeSet;
-    struct timeval timeout;
-    ssize_t bytes_sent = 0;
-    int num_bytes = 0;
-    char* p_buffer = buffer;
-    int retry = 0;
-
-    if (*timeoutSecs < 0)
-    {
-        return UPNP_E_TIMEDOUT;
-    }
-
-    while (TRUE)
-    {
-        FD_ZERO(&writeSet);
-        FD_SET(sockfd, &writeSet);
-
-        timeout.tv_sec = *timeoutSecs;
-        timeout.tv_usec = 0;
-
-        if (*timeoutSecs == 0)
-        {
-            timeout.tv_sec = WEB_SERVER_BLOCK_TIMEOUT;
-        }
-        
-        retCode = select(sockfd + 1, NULL, &writeSet, NULL, &timeout);
-
-        if (gUpnpSdkShutdown)
-            return UPNP_E_TIMEDOUT;
-
-        if (retCode == 0)
-        {
-            if (*timeoutSecs != 0)
-                return UPNP_E_TIMEDOUT;
-
-            if (gMaxHTTPTimeoutRetries > 0)
-            {
-                retry++;
-                if (retry >= gMaxHTTPTimeoutRetries)
-                    return UPNP_E_TIMEDOUT;
-            }
-
-            continue;
-        }
-
-        if (retCode == -1)
-        {
-            if(errno == EINTR)
-                continue;
-
-            return UPNP_E_SOCKET_ERROR;
-        }
-
-        if (FD_ISSET(sockfd, &writeSet))
-        {
-            bytes_sent = send(sockfd, p_buffer, bufsize, MSG_DONTROUTE|MSG_NOSIGNAL);
-            if (bytes_sent < 0)
-            {
-                //return -1;
-                return UPNP_E_SOCKET_ERROR;
-            }
-
-            num_bytes = num_bytes + bytes_sent;
-            bufsize = bufsize - bytes_sent;
-
-            // all sent out 
-            if (bufsize <= 0)
-                break;
-
-            p_buffer = buffer + num_bytes;
-        }
-    }
-
-    if (num_bytes < 0) 
-    {
-        return UPNP_E_SOCKET_ERROR;
-    }
-
-    return num_bytes;
-}
diff --git a/tombupnp/upnp/src/genlib/net/uri/uri.c b/tombupnp/upnp/src/genlib/net/uri/uri.c
deleted file mode 100644
index 071309b..0000000
--- a/tombupnp/upnp/src/genlib/net/uri/uri.c
+++ /dev/null
@@ -1,1119 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-/************************************************************************
-* Purpose: This file contains functions for uri, url parsing utility. 
-************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include "config.h"
-#include "uri.h"
-
-#if defined(__FreeBSD__) || defined(__NetBSD__)
-    #ifdef HAVE_LWRES_NETDB_H
-        #include <lwres/netdb.h>
-    #endif
-#endif
-
-#ifdef WIN32
- #include "inet_pton.h"
-#endif
-
-
-/************************************************************************
-*	Function :	is_reserved
-*
-*	Parameters :
-*		char in ;	char to be matched for RESERVED characters 
-*
-*	Description : Returns a 1 if a char is a RESERVED char as defined in 
-*		http://www.ietf.org/rfc/rfc2396.txt RFC explaining URIs)
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-is_reserved( char in )
-{
-    if( strchr( RESERVED, in ) )
-        return 1;
-    else
-        return 0;
-}
-
-/************************************************************************
-*	Function :	is_mark
-*
-*	Parameters :
-*		char in ; character to be matched for MARKED characters
-*
-*	Description : Returns a 1 if a char is a MARK char as defined in 
-*		http://www.ietf.org/rfc/rfc2396.txt (RFC explaining URIs)
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-is_mark( char in )
-{
-    if( strchr( MARK, in ) )
-        return 1;
-    else
-        return 0;
-}
-
-/************************************************************************
-*	Function :	is_unreserved
-*
-*	Parameters :
-*		char in ;	character to be matched for UNRESERVED characters
-*
-*	Description : Returns a 1 if a char is an unreserved char as defined in 
-*		http://www.ietf.org/rfc/rfc2396.txt (RFC explaining URIs)	
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-is_unreserved( char in )
-{
-    if( isalnum( in ) || ( is_mark( in ) ) )
-        return 1;
-    else
-        return 0;
-}
-
-/************************************************************************
-*	Function :	is_escaped
-*
-*	Parameters :
-*		char * in ;	character to be matched for ESCAPED characters
-*
-*	Description : Returns a 1 if a char[3] sequence is escaped as defined 
-*		in http://www.ietf.org/rfc/rfc2396.txt (RFC explaining URIs)
-*               size of array is NOT checked (MUST be checked by caller)	
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-is_escaped( const char *in )
-{
-
-    if( ( in[0] == '%' ) && ( isxdigit( in[1] ) ) && isxdigit( in[2] ) ) {
-
-        return 1;
-    } else
-        return 0;
-}
-
-/************************************************************************
-*	Function :	replace_escaped
-*
-*	Parameters :
-*		char * in ;	string of characters
-*		int index ;	index at which to start checking the characters
-*		int *max ;	
-*
-*	Description : Replaces an escaped sequence with its unescaped version 
-*		as in http://www.ietf.org/rfc/rfc2396.txt  (RFC explaining URIs)
-*       Size of array is NOT checked (MUST be checked by caller)
-*
-*	Return : int ;
-*
-*	Note : This function modifies the string. If the sequence is an 
-*		escaped sequence it is replaced, the other characters in the 
-*		string are shifted over, and NULL characters are placed at the 
-*		end of the string.
-************************************************************************/
-int
-replace_escaped( char *in,
-                 int index,
-                 int *max )
-{
-    int tempInt = 0;
-    char tempChar = 0;
-    int i = 0;
-    int j = 0;
-
-    if( ( in[index] == '%' ) && ( isxdigit( in[index + 1] ) )
-        && isxdigit( in[index + 2] ) ) {
-        //Note the "%2x", makes sure that we convert a maximum of two
-        //characters.
-        if( sscanf( &in[index + 1], "%2x", &tempInt ) != 1 )
-            return 0;
-
-        tempChar = ( char )tempInt;
-
-        for( i = index + 3, j = index; j < ( *max ); i++, j++ ) {
-            in[j] = tempChar;
-            if( i < ( *max ) )
-                tempChar = in[i];
-            else
-                tempChar = 0;
-        }
-        ( *max ) -= 2;
-        return 1;
-    } else
-        return 0;
-}
-
-/************************************************************************
-*	Function :	parse_uric
-*
-*	Parameters :
-*		char *in ;	string of characters
-*		int max ;	maximum limit
-*		token *out ; token object where the string of characters is 
-*					 copied
-*
-*	Description : Parses a string of uric characters starting at in[0]
-*		as defined in http://www.ietf.org/rfc/rfc2396.txt (RFC explaining 
-*		URIs)	
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-parse_uric( const char *in,
-            int max,
-            token * out )
-{
-    int i = 0;
-
-    while( ( i < max )
-           && ( ( is_unreserved( in[i] ) ) || ( is_reserved( in[i] ) )
-                || ( ( i + 2 < max ) && ( is_escaped( &in[i] ) ) ) ) ) {
-        i++;
-    }
-
-    out->size = i;
-    out->buff = in;
-    return i;
-}
-
-/************************************************************************
-*	Function :	copy_sockaddr_in
-*
-*	Parameters :
-*		const struct sockaddr_in *in ;	Source socket address object
-*		struct sockaddr_in *out ;		Destination socket address object
-*
-*	Description : Copies one socket address into another
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-copy_sockaddr_in( const struct sockaddr_in *in,
-                  struct sockaddr_in *out )
-{
-    memset( out->sin_zero, 0, 8 );
-    out->sin_family = in->sin_family;
-    out->sin_port = in->sin_port;
-    out->sin_addr.s_addr = in->sin_addr.s_addr;
-}
-
-/************************************************************************
-*	Function :	copy_token
-*
-*	Parameters :
-*		const token *in ;		source token	
-*		const char * in_base ;	
-*		token * out ;			destination token
-*		char * out_base ;	
-*
-*	Description : Tokens are generally pointers into other strings
-*		this copies the offset and size from a token (in) relative to 
-*		one string (in_base) into a token (out) relative to another 
-*		string (out_base)
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-static void
-copy_token( const token * in,
-            const char *in_base,
-            token * out,
-            char *out_base )
-{
-    out->size = in->size;
-    out->buff = out_base + ( in->buff - in_base );
-}
-
-/************************************************************************
-*	Function :	copy_URL_list
-*
-*	Parameters :
-*		URL_list *in ;	Source URL list
-*		URL_list *out ;	Destination URL list
-*
-*	Description : Copies one URL_list into another. This includes 
-*		dynamically allocating the out->URLs field (the full string),
-*       and the structures used to hold the parsedURLs. This memory MUST 
-*		be freed by the caller through: free_URL_list(&out)
-*
-*	Return : int ;
-*		HTTP_SUCCESS - On Success
-*		UPNP_E_OUTOF_MEMORY - On Failure to allocate memory
-*
-*	Note :
-************************************************************************/
-int
-copy_URL_list( URL_list * in,
-               URL_list * out )
-{
-    int len = strlen( in->URLs ) + 1;
-    int i = 0;
-
-    out->URLs = NULL;
-    out->parsedURLs = NULL;
-    out->size = 0;
-
-    out->URLs = ( char * )malloc( len );
-    out->parsedURLs =
-        ( uri_type * ) malloc( sizeof( uri_type ) * in->size );
-
-    if( ( out->URLs == NULL ) || ( out->parsedURLs == NULL ) )
-        return UPNP_E_OUTOF_MEMORY;
-
-    memcpy( out->URLs, in->URLs, len );
-
-    for( i = 0; i < in->size; i++ ) {
-        //copy the parsed uri
-        out->parsedURLs[i].type = in->parsedURLs[i].type;
-        copy_token( &in->parsedURLs[i].scheme, in->URLs,
-                    &out->parsedURLs[i].scheme, out->URLs );
-
-        out->parsedURLs[i].path_type = in->parsedURLs[i].path_type;
-        copy_token( &in->parsedURLs[i].pathquery, in->URLs,
-                    &out->parsedURLs[i].pathquery, out->URLs );
-        copy_token( &in->parsedURLs[i].fragment, in->URLs,
-                    &out->parsedURLs[i].fragment, out->URLs );
-        copy_token( &in->parsedURLs[i].hostport.text,
-                    in->URLs, &out->parsedURLs[i].hostport.text,
-                    out->URLs );
-
-        copy_sockaddr_in( &in->parsedURLs[i].hostport.IPv4address,
-                          &out->parsedURLs[i].hostport.IPv4address );
-    }
-    out->size = in->size;
-    return HTTP_SUCCESS;
-
-}
-
-/************************************************************************
-*	Function :	free_URL_list
-*
-*	Parameters :
-*		URL_list * list ;	URL List object
-*
-*	Description : Frees the memory associated with a URL_list. Frees the 
-*		dynamically allocated members of of list. Does NOT free the 
-*		pointer to the list itself ( i.e. does NOT free(list))
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-free_URL_list( URL_list * list )
-{
-    if( list->URLs )
-        free( list->URLs );
-    if( list->parsedURLs )
-        free( list->parsedURLs );
-    list->size = 0;
-}
-
-/************************************************************************
-*	Function :	print_uri
-*
-*	Parameters :
-*		uri_type *in ;	URI object
-*
-*	Description : Function useful in debugging for printing a parsed uri.
-*		Compiled out with DBGONLY macro. 
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-DBGONLY( void print_uri( uri_type * in ) {
-         print_token( &in->scheme );
-         print_token( &in->hostport.text );
-         print_token( &in->pathquery ); print_token( &in->fragment );} )
-
-/************************************************************************
-*	Function :	print_token
-*
-*	Parameters :
-*		token * in ;	token
-*
-*	Description : Function useful in debugging for printing a token.
-*		Compiled out with DBGONLY macro. 
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-DBGONLY( void print_token( token * in ) {
-         int i = 0;
-         printf( "Token Size : %d\n\'", in->size );
-         for( i = 0; i < in->size; i++ ) {
-         putchar( in->buff[i] );}
-         putchar( '\'' ); putchar( '\n' );}
-
- )
-
-/************************************************************************
-*	Function :	token_string_casecmp
-*
-*	Parameters :
-*		token * in1 ;	Token object whose buffer is to be compared
-*		char * in2 ;	string of characters to compare with
-*
-*	Description :	Compares buffer in the token object with the buffer 
-*		in in2
-*
-*	Return : int ;
-*		< 0 string1 less than string2 
-*		0 string1 identical to string2 
-*		> 0 string1 greater than string2 
-*
-*	Note :
-************************************************************************/
-    int token_string_casecmp( token * in1,
-                              char *in2 ) {
-    int in2_length = strlen( in2 );
-
-    if( in1->size != in2_length )
-        return 1;
-    else
-        return strncasecmp( in1->buff, in2, in1->size );
-}
-
-/************************************************************************
-*	Function :	token_string_cmp
-*
-*	Parameters :
-*		token * in1 ;	Token object whose buffer is to be compared
-*		char * in2 ;	string of characters to compare with
-*
-*	Description : Compares a null terminated string to a token (exact)	
-*
-*	Return : int ;
-*		< 0 string1 less than string2 
-*		0 string1 identical to string2 
-*		> 0 string1 greater than string2 
-*
-*	Note :
-************************************************************************/
-int
-token_string_cmp( token * in1,
-                  char *in2 )
-{
-    int in2_length = strlen( in2 );
-
-    if( in1->size != in2_length )
-        return 1;
-    else
-        return strncmp( in1->buff, in2, in1->size );
-}
-
-/************************************************************************
-*	Function :	token_cmp
-*
-*	Parameters :
-*		token *in1 ;	First token object whose buffer is to be compared
-*		token *in2 ;	Second token object used for the comparison
-*
-*	Description : Compares two tokens	
-*
-*	Return : int ;
-*		< 0 string1 less than string2 
-*		0 string1 identical to string2 
-*		> 0 string1 greater than string2 
-*
-*	Note :
-************************************************************************/
-int
-token_cmp( token * in1,
-           token * in2 )
-{
-    if( in1->size != in2->size )
-        return 1;
-    else
-        return memcmp( in1->buff, in2->buff, in1->size );
-}
-
-/************************************************************************
-*	Function :	parse_port
-*
-*	Parameters :
-*		int max ;	sets a maximum limit
-*		char * port ;	port to be parsed.
-*		unsigned short * out ;	 out parameter where the port is parsed 
-*							and converted into network format
-*
-*	Description : parses a port (i.e. '4000') and converts it into a 
-*		network ordered unsigned short int.
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-parse_port( int max,
-            const char *port,
-            unsigned short *out )
-{
-
-    const char *finger = port;
-    const char *max_ptr = finger + max;
-    unsigned short temp = 0;
-
-    while( ( finger < max_ptr ) && ( isdigit( *finger ) ) ) {
-        temp = temp * 10;
-        temp += ( *finger ) - '0';
-        finger++;
-    }
-
-    *out = htons( temp );
-    return finger - port;
-}
-
-/************************************************************************
-*	Function :	parse_hostport
-*
-*	Parameters :
-*		char *in ;	string of characters representing host and port
-*		int max ;	sets a maximum limit
-*		hostport_type *out ;	out parameter where the host and port
-*					are represented as an internet address
-*
-*	Description : Parses a string representing a host and port
-*		(e.g. "127.127.0.1:80" or "localhost") and fills out a 
-*		hostport_type struct with internet address and a token 
-*		representing the full host and port.  uses gethostbyname.
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-parse_hostport( const char *in,
-                int max,
-                hostport_type * out )
-{
-#define BUFFER_SIZE 8192
-
-    int i = 0;
-    int begin_port;
-    int hostport_size = 0;
-    int host_size = 0;
-#ifndef WIN32
-    char temp_hostbyname_buff[BUFFER_SIZE];
-    struct hostent h_buf;
-#endif
-    struct hostent *h = NULL;
-    int errcode = 0;
-    char *temp_host_name = NULL;
-    int last_dot = -1;
-
-    out->text.size = 0;
-    out->text.buff = NULL;
-
-    out->IPv4address.sin_port = htons( 80 );    //default port is 80
-    memset( &out->IPv4address.sin_zero, 0, 8 );
-
-    while( ( i < max ) && ( in[i] != ':' ) && ( in[i] != '/' )
-           && ( ( isalnum( in[i] ) ) || ( in[i] == '.' )
-                || ( in[i] == '-' ) ) ) {
-        i++;
-        if( in[i] == '.' ) {
-            last_dot = i;
-        }
-    }
-
-    host_size = i;
-
-    if( ( i < max ) && ( in[i] == ':' ) ) {
-        begin_port = i + 1;
-        //convert port
-        if( !( hostport_size = parse_port( max - begin_port,
-                                           &in[begin_port],
-                                           &out->IPv4address.sin_port ) ) )
-        {
-            return UPNP_E_INVALID_URL;
-        }
-        hostport_size += begin_port;
-    } else
-        hostport_size = host_size;
-
-    //convert to temporary null terminated string
-    temp_host_name = ( char * )malloc( host_size + 1 );
-
-    if( temp_host_name == NULL )
-        return UPNP_E_OUTOF_MEMORY;
-
-    memcpy( temp_host_name, in, host_size );
-    temp_host_name[host_size] = '\0';
-
-    //check to see if host name is an ipv4 address
-    if( ( last_dot != -1 ) && ( last_dot + 1 < host_size )
-        && ( isdigit( temp_host_name[last_dot + 1] ) ) ) {
-        //must be ipv4 address
-
-        errcode = inet_pton( AF_INET,
-                             temp_host_name, &out->IPv4address.sin_addr );
-        if( errcode == 1 ) {
-            out->IPv4address.sin_family = AF_INET;
-        } else {
-            out->IPv4address.sin_addr.s_addr = 0;
-            out->IPv4address.sin_family = AF_INET;
-            free( temp_host_name );
-            temp_host_name = NULL;
-            return UPNP_E_INVALID_URL;
-        }
-    } else {
-        int errCode = 0;
-
-        //call gethostbyname_r (reentrant form of gethostbyname)
-#if defined(WIN32) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__OpenBSD__)
-        h=gethostbyname(temp_host_name);
-#elif defined(SOLARIS)
-        h = gethostbyname_r( temp_host_name,
-                                   &h_buf,
-                                   temp_hostbyname_buff,
-                                   BUFFER_SIZE, &errcode );
-        if ( h == NULL ) {
-            errCode = 1;
-        }
-#elif defined(HAVE_LIBLWRES)
-        h = lwres_gethostbyname_r( temp_host_name,
-                                   &h_buf,
-                                   temp_hostbyname_buff,
-                                   BUFFER_SIZE, &errcode );
-        if ( h == NULL ) {
-            errCode = 1;
-        }
-#else
-        errCode = gethostbyname_r( temp_host_name,
-                                   &h_buf,
-                                   temp_hostbyname_buff,
-                                   BUFFER_SIZE, &h, &errcode );
-#endif 
-
-        if( errCode == 0 ) {
-            if( h ) {
-                if( ( h->h_addrtype == AF_INET ) && ( h->h_length == 4 ) ) {
-                    out->IPv4address.sin_addr =
-                        ( *( struct in_addr * )h->h_addr );
-                    out->IPv4address.sin_family = AF_INET;
-
-                }
-            }
-        } else {
-            out->IPv4address.sin_addr.s_addr = 0;
-            out->IPv4address.sin_family = AF_INET;
-            free( temp_host_name );
-            temp_host_name = NULL;
-            return UPNP_E_INVALID_URL;
-        }
-    }
-
-    if( temp_host_name ) {
-        free( temp_host_name );
-        temp_host_name = NULL;
-    }
-
-    out->text.size = hostport_size;
-    out->text.buff = in;
-    return hostport_size;
-
-}
-
-/************************************************************************
-*	Function :	parse_scheme
-*
-*	Parameters :
-*		char * in ;	string of characters representing a scheme
-*		int max ;	maximum number of characters
-*		token * out ;	output parameter whose buffer is filled in with 
-*					the scheme
-*
-*	Description : parses a uri scheme starting at in[0] as defined in 
-*		http://www.ietf.org/rfc/rfc2396.txt (RFC explaining URIs)
-*		(e.g. "http:" -> scheme= "http"). 
-*		Note, string MUST include ':' within the max charcters
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-parse_scheme( const char *in,
-              int max,
-              token * out )
-{
-    int i = 0;
-
-    out->size = 0;
-    out->buff = NULL;
-
-    if( ( max == 0 ) || ( !isalpha( in[0] ) ) )
-        return FALSE;
-
-    i++;
-    while( ( i < max ) && ( in[i] != ':' ) ) {
-
-        if( !( isalnum( in[i] ) || ( in[i] == '+' ) || ( in[i] == '-' )
-               || ( in[i] == '.' ) ) )
-            return FALSE;
-
-        i++;
-    }
-    if( i < max ) {
-        out->size = i;
-        out->buff = &in[0];
-        return i;
-    }
-
-    return FALSE;
-
-}
-
-/************************************************************************
-*	Function :	remove_escaped_chars
-*
-*	Parameters :
-*		INOUT char *in ;	string of characters to be modified
-*		INOUT int *size ;	size limit for the number of characters
-*
-*	Description : removes http escaped characters such as: "%20" and 
-*		replaces them with their character representation. i.e. 
-*		"hello%20foo" -> "hello foo". The input IS MODIFIED in place. 
-*		(shortened). Extra characters are replaced with NULL.
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS
-*
-*	Note :
-************************************************************************/
-int
-remove_escaped_chars( INOUT char *in,
-                      INOUT int *size )
-{
-    int i = 0;
-
-    for( i = 0; i < *size; i++ ) {
-        replace_escaped( in, i, size );
-    }
-    return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-*	Function :	remove_dots
-*
-*	Parameters :
-*		char *in ;	string of characters from which "dots" have to be 
-*					removed
-*		int size ;	size limit for the number of characters
-*
-*	Description : Removes ".", and ".." from a path. If a ".." can not
-*		be resolved (i.e. the .. would go past the root of the path) an 
-*		error is returned. The input IS modified in place.)
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Success
-*		UPNP_E_OUTOF_MEMORY - On failure to allocate memory
-*		UPNP_E_INVALID_URL - Failure to resolve URL
-*
-*	Note :
-*		Examples
-*       char path[30]="/../hello";
-*       remove_dots(path, strlen(path)) -> UPNP_E_INVALID_URL
-*       char path[30]="/./hello";
-*       remove_dots(path, strlen(path)) -> UPNP_E_SUCCESS, 
-*       in = "/hello"
-*       char path[30]="/./hello/foo/../goodbye" -> 
-*       UPNP_E_SUCCESS, in = "/hello/goodbye"
-
-************************************************************************/
-int
-remove_dots( char *in,
-             int size )
-{
-    char *copyTo = in;
-    char *copyFrom = in;
-    char *max = in + size;
-    char **Segments = NULL;
-    int lastSegment = -1;
-
-    Segments = malloc( sizeof( char * ) * size );
-
-    if( Segments == NULL )
-        return UPNP_E_OUTOF_MEMORY;
-
-    Segments[0] = NULL;
-    DBGONLY( UpnpPrintf
-             ( UPNP_ALL, API, __FILE__, __LINE__,
-               "REMOVE_DOTS: before: %s\n", in ) );
-    while( ( copyFrom < max ) && ( *copyFrom != '?' )
-           && ( *copyFrom != '#' ) ) {
-
-        if( ( ( *copyFrom ) == '.' )
-            && ( ( copyFrom == in ) || ( *( copyFrom - 1 ) == '/' ) ) ) {
-            if( ( copyFrom + 1 == max )
-                || ( *( copyFrom + 1 ) == '/' ) ) {
-
-                copyFrom += 2;
-                continue;
-            } else if( ( *( copyFrom + 1 ) == '.' )
-                       && ( ( copyFrom + 2 == max )
-                            || ( *( copyFrom + 2 ) == '/' ) ) ) {
-                copyFrom += 3;
-
-                if( lastSegment > 0 ) {
-                    copyTo = Segments[--lastSegment];
-                } else {
-                    free( Segments );
-                    //TRACE("ERROR RESOLVING URL, ../ at ROOT");
-                    return UPNP_E_INVALID_URL;
-                }
-                continue;
-            }
-        }
-
-        if( ( *copyFrom ) == '/' ) {
-
-            lastSegment++;
-            Segments[lastSegment] = copyTo + 1;
-        }
-        ( *copyTo ) = ( *copyFrom );
-        copyTo++;
-        copyFrom++;
-    }
-    if( copyFrom < max ) {
-        while( copyFrom < max ) {
-            ( *copyTo ) = ( *copyFrom );
-            copyTo++;
-            copyFrom++;
-        }
-    }
-    ( *copyTo ) = 0;
-    free( Segments );
-    DBGONLY( UpnpPrintf
-             ( UPNP_ALL, API, __FILE__, __LINE__,
-               "REMOVE_DOTS: after: %s\n", in ) );
-    return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-*	Function :	resolve_rel_url
-*
-*	Parameters :
-*		char * base_url ;	Base URL
-*		char * rel_url ;	Relative URL
-*
-*	Description : resolves a relative url with a base url returning a NEW 
-*		(dynamically allocated with malloc) full url. If the base_url is 
-*		NULL, then a copy of the  rel_url is passed back if the rel_url 
-*		is absolute then a copy of the rel_url is passed back if neither 
-*		the base nor the rel_url are Absolute then NULL is returned.
-*		otherwise it tries and resolves the relative url with the base 
-*		as described in: http://www.ietf.org/rfc/rfc2396.txt (RFCs 
-*		explaining URIs) 
-*       : resolution of '..' is NOT implemented, but '.' is resolved 
-*
-*	Return : char * ;
-*
-*	Note :
-************************************************************************/
-char *
-resolve_rel_url( char *base_url,
-                 char *rel_url )
-{
-    uri_type base;
-    uri_type rel;
-    char temp_path = '/';
-
-    int i = 0;
-    char *finger = NULL;
-
-    char *last_slash = NULL;
-
-    char *out = NULL;
-    char *out_finger = NULL;
-
-    if( base_url && rel_url ) {
-        out =
-            ( char * )malloc( strlen( base_url ) + strlen( rel_url ) + 2 );
-        out_finger = out;
-    } else {
-        if( rel_url )
-            return strdup( rel_url );
-        else
-            return NULL;
-    }
-
-    if( out == NULL ) {
-        return NULL;
-    }
-
-    if( ( parse_uri( rel_url, strlen( rel_url ), &rel ) ) == HTTP_SUCCESS ) {
-
-        if( rel.type == ABSOLUTE ) {
-
-            strcpy( out, rel_url );
-        } else {
-
-            if( ( parse_uri( base_url, strlen( base_url ), &base ) ==
-                  HTTP_SUCCESS )
-                && ( base.type == ABSOLUTE ) ) {
-
-                if( strlen( rel_url ) == 0 ) {
-                    strcpy( out, base_url );
-                } else {
-                    memcpy( out, base.scheme.buff, base.scheme.size );
-                    out_finger += base.scheme.size;
-                    ( *out_finger ) = ':';
-                    out_finger++;
-
-                    if( rel.hostport.text.size > 0 ) {
-                        sprintf( out_finger, "%s", rel_url );
-                    } else {
-                        if( base.hostport.text.size > 0 ) {
-                            memcpy( out_finger, "//", 2 );
-                            out_finger += 2;
-                            memcpy( out_finger, base.hostport.text.buff,
-                                    base.hostport.text.size );
-                            out_finger += base.hostport.text.size;
-                        }
-
-                        if( rel.path_type == ABS_PATH ) {
-                            strcpy( out_finger, rel_url );
-
-                        } else {
-
-                            if( base.pathquery.size == 0 ) {
-                                base.pathquery.size = 1;
-                                base.pathquery.buff = &temp_path;
-                            }
-
-                            finger = out_finger;
-                            last_slash = finger;
-                            i = 0;
-
-                            while( ( i < base.pathquery.size ) &&
-                                   ( base.pathquery.buff[i] != '?' ) ) {
-                                ( *finger ) = base.pathquery.buff[i];
-                                if( base.pathquery.buff[i] == '/' )
-                                    last_slash = finger + 1;
-                                i++;
-                                finger++;
-
-                            }
-                            i = 0;
-                            strcpy( last_slash, rel_url );
-                            if( remove_dots( out_finger,
-                                             strlen( out_finger ) ) !=
-                                UPNP_E_SUCCESS ) {
-                                free( out );
-                                //free(rel_url);
-                                return NULL;
-                            }
-                        }
-
-                    }
-                }
-            } else {
-                free( out );
-                //free(rel_url);
-                return NULL;
-            }
-        }
-    } else {
-        free( out );
-        //free(rel_url);            
-        return NULL;
-    }
-
-    //free(rel_url);
-    return out;
-}
-
-/************************************************************************
-*	Function :	parse_uri
-*
-*	Parameters :
-*		char * in ;	character string containing uri information to be 
-*					parsed
-*		int max ;	maximum limit on the number of characters
-*		uri_type * out ; out parameter which will have the parsed uri
-*					information	
-*
-*	Description : parses a uri as defined in http://www.ietf.org/rfc/
-*		rfc2396.txt (RFC explaining URIs)
-*		Handles absolute, relative, and opaque uris. Parses into the 
-*		following pieces: scheme, hostport, pathquery, fragment (path and
-*		query are treated as one token)
-*       Caller should check for the pieces they require.
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-parse_uri( const char *in,
-           int max,
-           uri_type * out )
-{
-    int begin_path = 0;
-    int begin_hostport = 0;
-    int begin_fragment = 0;
-
-    if( ( begin_hostport = parse_scheme( in, max, &out->scheme ) ) ) {
-        out->type = ABSOLUTE;
-        out->path_type = OPAQUE_PART;
-        begin_hostport++;
-    } else {
-        out->type = RELATIVE;
-        out->path_type = REL_PATH;
-    }
-
-    //parse hostport only if scheme was found
-    if( ( begin_hostport > 0 ) && ( ( begin_hostport + 1 ) < max ) && ( in[begin_hostport] == '/' )
-        && ( in[begin_hostport + 1] == '/' ) ) {
-        begin_hostport += 2;
-
-        if( ( begin_path = parse_hostport( &in[begin_hostport],
-                                           max - begin_hostport,
-                                           &out->hostport ) ) >= 0 ) {
-            begin_path += begin_hostport;
-        } else
-            return begin_path;
-
-    } else {
-        out->hostport.IPv4address.sin_port = 0;
-        out->hostport.IPv4address.sin_addr.s_addr = 0;
-        out->hostport.text.size = 0;
-        out->hostport.text.buff = 0;
-        begin_path = begin_hostport;
-
-        //remove excessive leading slashes (fix for Samsung Smart TV 2012)
-        while( ( ( begin_path + 1 ) < max ) && ( in[begin_path] == '/' ) && ( in[begin_path + 1] == '/') ) {
-            begin_path++;
-        }
-
-    }
-
-    begin_fragment =
-        parse_uric( &in[begin_path], max - begin_path,
-                    &out->pathquery ) + begin_path;
-
-    if( ( out->pathquery.size ) && ( out->pathquery.buff[0] == '/' ) ) {
-        out->path_type = ABS_PATH;
-    }
-
-    if( ( begin_fragment < max ) && ( in[begin_fragment] == '#' ) ) {
-        begin_fragment++;
-        parse_uric( &in[begin_fragment], max - begin_fragment,
-                    &out->fragment );
-    } else {
-        out->fragment.buff = NULL;
-        out->fragment.size = 0;
-    }
-    return HTTP_SUCCESS;
-}
-
-/************************************************************************
-*	Function :	parse_uri_and_unescape
-*
-*	Parameters :
-*		char * in ;	
-*		int max ;	
-*		uri_type * out ;	
-*
-*	Description : Same as parse_uri, except that all strings are 
-*		unescaped (%XX replaced by chars)
-*
-*	Return : int ;
-*
-*	Note: This modifies 'pathquery' and 'fragment' parts of the input
-************************************************************************/
-int
-parse_uri_and_unescape( char *in,
-                        int max,
-                        uri_type * out )
-{
-    int ret;
-
-    if( ( ret = parse_uri( in, max, out ) ) != HTTP_SUCCESS )
-        return ret;
-    if( out->pathquery.size > 0 )
-        remove_escaped_chars( (char *)out->pathquery.buff, &out->pathquery.size );
-    if( out->fragment.size > 0 )
-        remove_escaped_chars( (char *)out->fragment.buff, &out->fragment.size );
-    return HTTP_SUCCESS;
-}
diff --git a/tombupnp/upnp/src/genlib/service_table/service_table.c b/tombupnp/upnp/src/genlib/service_table/service_table.c
deleted file mode 100644
index cc2116d..0000000
--- a/tombupnp/upnp/src/genlib/service_table/service_table.c
+++ /dev/null
@@ -1,1143 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-/************************************************************************
-* Purpose: This file defines the functions for services. It defines 
-* functions for adding and removing services to and from the service table, 
-* adding and accessing subscription and other attributes pertaining to the 
-* service 
-************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include "config.h"
-#include "service_table.h"
-
-#ifdef INCLUDE_DEVICE_APIS
-
-/************************************************************************
-*	Function :	copy_subscription
-*
-*	Parameters :
-*		subscription *in ;	Source subscription
-*		subscription *out ;	Destination subscription
-*
-*	Description :	Makes a copy of the subscription
-*
-*	Return : int ;
-*		HTTP_SUCCESS - On Sucess
-*
-*	Note :
-************************************************************************/
-int
-copy_subscription( subscription * in,
-                   subscription * out )
-{
-    int return_code = HTTP_SUCCESS;
-
-    memcpy( out->sid, in->sid, SID_SIZE );
-    out->sid[SID_SIZE] = 0;
-    out->eventKey = in->eventKey;
-    out->ToSendEventKey = in->ToSendEventKey;
-    out->expireTime = in->expireTime;
-    out->active = in->active;
-    if( ( return_code =
-          copy_URL_list( &in->DeliveryURLs, &out->DeliveryURLs ) )
-        != HTTP_SUCCESS )
-        return return_code;
-    out->next = NULL;
-    return HTTP_SUCCESS;
-}
-
-/************************************************************************
-*	Function :	RemoveSubscriptionSID
-*
-*	Parameters :
-*		Upnp_SID sid ;	subscription ID
-*		service_info * service ;	service object providing the list of
-*						subscriptions
-*
-*	Description :	Remove the subscription represented by the
-*		const Upnp_SID sid parameter from the service table and update 
-*		the service table.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-RemoveSubscriptionSID( Upnp_SID sid,
-                       service_info * service )
-{
-    subscription *finger = service->subscriptionList;
-    subscription *previous = NULL;
-
-    while( finger ) {
-        if( !( strcmp( sid, finger->sid ) ) ) {
-            if( previous )
-                previous->next = finger->next;
-            else
-                service->subscriptionList = finger->next;
-            finger->next = NULL;
-            freeSubscriptionList( finger );
-            finger = NULL;
-            service->TotalSubscriptions--;
-        } else {
-            previous = finger;
-            finger = finger->next;
-        }
-    }
-
-}
-
-/************************************************************************
-*	Function :	GetSubscriptionSID
-*
-*	Parameters :
-*		Upnp_SID sid ;	subscription ID
-*		service_info * service ;	service object providing the list of
-*						subscriptions
-*
-*	Description :	Return the subscription from the service table 
-*		that matches const Upnp_SID sid value. 
-*
-*	Return : subscription * - Pointer to the matching subscription 
-*		node;
-*
-*	Note :
-************************************************************************/
-subscription *
-GetSubscriptionSID( Upnp_SID sid,
-                    service_info * service )
-{
-    subscription *next = service->subscriptionList;
-    subscription *previous = NULL;
-    subscription *found = NULL;
-
-    time_t current_time;
-
-    while( ( next ) && ( found == NULL ) ) {
-        if( !strcmp( next->sid, sid ) )
-            found = next;
-        else {
-            previous = next;
-            next = next->next;
-        }
-    }
-    if( found ) {
-        //get the current_time
-        time( &current_time );
-        if( ( found->expireTime != 0 )
-            && ( found->expireTime < current_time ) ) {
-            if( previous )
-                previous->next = found->next;
-            else
-                service->subscriptionList = found->next;
-            found->next = NULL;
-            freeSubscriptionList( found );
-            found = NULL;
-            service->TotalSubscriptions--;
-        }
-    }
-    return found;
-
-}
-
-/************************************************************************
-*	Function :	GetNextSubscription
-*
-*	Parameters :
-*		service_info * service ; service object providing the list of
-*						subscriptions
-*		subscription *current ;	current subscription object
-*
-*	Description :	Get current and valid subscription from the service 
-*		table.
-*
-*	Return : subscription * - Pointer to the next subscription node;
-*
-*	Note :
-************************************************************************/
-subscription *
-GetNextSubscription( service_info * service,
-                     subscription * current )
-{
-    time_t current_time;
-    subscription *next = NULL;
-    subscription *previous = NULL;
-    int notDone = 1;
-
-    //get the current_time
-    time( &current_time );
-    while( ( notDone ) && ( current ) ) {
-        previous = current;
-        current = current->next;
-
-        if( current == NULL ) {
-            notDone = 0;
-            next = current;
-        } else
-            if( ( current->expireTime != 0 )
-                && ( current->expireTime < current_time ) ) {
-            previous->next = current->next;
-            current->next = NULL;
-            freeSubscriptionList( current );
-            current = previous;
-            service->TotalSubscriptions--;
-        } else if( current->active ) {
-            notDone = 0;
-            next = current;
-        }
-    }
-    return next;
-}
-
-/************************************************************************
-*	Function :	GetFirstSubscription
-*
-*	Parameters :
-*		service_info *service ;	service object providing the list of
-*						subscriptions
-*
-*	Description :	Gets pointer to the first subscription node in the 
-*		service table.
-*
-*	Return : subscription * - pointer to the first subscription node ;
-*
-*	Note :
-************************************************************************/
-subscription *
-GetFirstSubscription( service_info * service )
-{
-    subscription temp;
-    subscription *next = NULL;
-
-    temp.next = service->subscriptionList;
-    next = GetNextSubscription( service, &temp );
-    service->subscriptionList = temp.next;
-    //  service->subscriptionList=next;
-    return next;
-}
-
-/************************************************************************
-*	Function :	freeSubscription
-*
-*	Parameters :
-*		subscription * sub ;	subscription to be freed
-*
-*	Description :	Free's the memory allocated for storing the URL of 
-*		the subscription.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-freeSubscription( subscription * sub )
-{
-    if( sub ) {
-        free_URL_list( &sub->DeliveryURLs );
-    }
-}
-
-/************************************************************************
-*	Function :	freeSubscriptionList
-*
-*	Parameters :
-*		subscription * head ;	head of the subscription list
-*
-*	Description :	Free's memory allocated for all the subscriptions 
-*		in the service table. 
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-freeSubscriptionList( subscription * head )
-{
-    subscription *next = NULL;
-
-    while( head ) {
-        next = head->next;
-        freeSubscription( head );
-        free( head );
-        head = next;
-    }
-}
-
-/************************************************************************
-*	Function :	FindServiceId
-*
-*	Parameters :
-*		service_table *table ;	service table
-*		const char * serviceId ;string representing the service id 
-*								to be found among those in the table	
-*		const char * UDN ;		string representing the UDN 
-*								to be found among those in the table	
-*
-*	Description :	Traverses through the service table and returns a 
-*		pointer to the service node that matches a known service  id 
-*		and a known UDN
-*
-*	Return : service_info * - pointer to the matching service_info node;
-*
-*	Note :
-************************************************************************/
-service_info *
-FindServiceId( service_table * table,
-               const char *serviceId,
-               const char *UDN )
-{
-    service_info *finger = NULL;
-
-    if( table ) {
-        finger = table->serviceList;
-        while( finger ) {
-            if( ( !strcmp( serviceId, finger->serviceId ) ) &&
-                ( !strcmp( UDN, finger->UDN ) ) ) {
-                return finger;
-            }
-            finger = finger->next;
-        }
-    }
-
-    return NULL;
-}
-
-/************************************************************************
-*	Function :	FindServiceEventURLPath
-*
-*	Parameters :
-*		service_table *table ;	service table
-*		char * eventURLPath ;	event URL path used to find a service 
-*								from the table  
-*
-*	Description :	Traverses the service table and finds the node whose
-*		event URL Path matches a know value 
-*
-*	Return : service_info * - pointer to the service list node from the 
-*		service table whose event URL matches a known event URL;
-*
-*	Note :
-************************************************************************/
-service_info *
-FindServiceEventURLPath( service_table * table,
-                         char *eventURLPath )
-{
-    service_info *finger = NULL;
-    uri_type parsed_url;
-    uri_type parsed_url_in;
-
-    if( ( table )
-        &&
-        ( parse_uri
-          ( eventURLPath, strlen( eventURLPath ), &parsed_url_in ) ) ) {
-
-        finger = table->serviceList;
-        while( finger ) {
-            if( finger->eventURL )
-                if( ( parse_uri
-                      ( finger->eventURL, strlen( finger->eventURL ),
-                        &parsed_url ) ) ) {
-
-                    if( !token_cmp
-                        ( &parsed_url.pathquery,
-                          &parsed_url_in.pathquery ) )
-                        return finger;
-
-                }
-            finger = finger->next;
-        }
-    }
-
-    return NULL;
-}
-
-/************************************************************************
-*	Function :	FindServiceControlURLPath
-*
-*	Parameters :
-*		service_table * table ;	service table
-*		char * controlURLPath ;	control URL path used to find a service 
-*								from the table  
-*
-*	Description :	Traverses the service table and finds the node whose
-*		control URL Path matches a know value 
-*
-*	Return : service_info * - pointer to the service list node from the 
-*		service table whose control URL Path matches a known value;
-*
-*	Note :
-************************************************************************/
-service_info *
-FindServiceControlURLPath( service_table * table,
-                           const char *controlURLPath )
-{
-    service_info *finger = NULL;
-    uri_type parsed_url;
-    uri_type parsed_url_in;
-
-    if( ( table )
-        &&
-        ( parse_uri
-          ( controlURLPath, strlen( controlURLPath ),
-            &parsed_url_in ) ) ) {
-        finger = table->serviceList;
-        while( finger ) {
-            if( finger->controlURL )
-                if( ( parse_uri
-                      ( finger->controlURL, strlen( finger->controlURL ),
-                        &parsed_url ) ) ) {
-                    if( !token_cmp
-                        ( &parsed_url.pathquery,
-                          &parsed_url_in.pathquery ) )
-                        return finger;
-                }
-            finger = finger->next;
-        }
-    }
-
-    return NULL;
-
-}
-
-/************************************************************************
-*	Function :	printService
-*
-*	Parameters :
-*		service_info *service ;Service whose information is to be printed
-*		Dbg_Level level ; Debug level specified to the print function
-*		Dbg_Module module ;	Debug module specified to the print function
-*
-*	Description :	For debugging purposes prints information from the 
-*		service passed into the function.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-DBGONLY( void printService( service_info * service, Dbg_Level level,
-                            Dbg_Module module ) {
-         if( service ) {
-         if( service->serviceType )
-         UpnpPrintf( level, module, __FILE__, __LINE__,
-                     "serviceType: %s\n", service->serviceType );
-         if( service->serviceId )
-         UpnpPrintf( level, module, __FILE__, __LINE__, "serviceId: %s\n",
-                     service->serviceId ); if( service->SCPDURL )
-         UpnpPrintf( level, module, __FILE__, __LINE__, "SCPDURL: %s\n",
-                     service->SCPDURL ); if( service->controlURL )
-         UpnpPrintf( level, module, __FILE__, __LINE__, "controlURL: %s\n",
-                     service->controlURL ); if( service->eventURL )
-         UpnpPrintf( level, module, __FILE__, __LINE__, "eventURL: %s\n",
-                     service->eventURL ); if( service->UDN )
-         UpnpPrintf( level, module, __FILE__, __LINE__, "UDN: %s\n\n",
-                     service->UDN ); if( service->active )
-         UpnpPrintf( level, module, __FILE__, __LINE__,
-                     "Service is active\n" );
-         else
-         UpnpPrintf( level, module, __FILE__, __LINE__,
-                     "Service is inactive\n" );}
-         }
-
- )
-
-/************************************************************************
-*	Function :	printServiceList
-*
-*	Parameters :
-*		service_info *service ;	Service whose information is to be printed
-*		Dbg_Level level ;	Debug level specified to the print function
-*		Dbg_Module module ;	Debug module specified to the print function
-*
-*	Description :	For debugging purposes prints information of each 
-*		service from the service table passed into the function.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-    DBGONLY( void printServiceList( service_info * service,
-                                    Dbg_Level level,
-                                    Dbg_Module module ) {
-             while( service ) {
-             if( service->serviceType )
-             UpnpPrintf( level, module, __FILE__, __LINE__,
-                         "serviceType: %s\n", service->serviceType );
-             if( service->serviceId )
-             UpnpPrintf( level, module, __FILE__, __LINE__,
-                         "serviceId: %s\n", service->serviceId );
-             if( service->SCPDURL )
-             UpnpPrintf( level, module, __FILE__, __LINE__,
-                         "SCPDURL: %s\n", service->SCPDURL );
-             if( service->controlURL )
-             UpnpPrintf( level, module, __FILE__, __LINE__,
-                         "controlURL: %s\n", service->controlURL );
-             if( service->eventURL )
-             UpnpPrintf( level, module, __FILE__, __LINE__,
-                         "eventURL: %s\n", service->eventURL );
-             if( service->UDN )
-             UpnpPrintf( level, module, __FILE__, __LINE__, "UDN: %s\n\n",
-                         service->UDN ); if( service->active )
-             UpnpPrintf( level, module, __FILE__, __LINE__,
-                         "Service is active\n" );
-             else
-             UpnpPrintf( level, module, __FILE__, __LINE__,
-                         "Service is inactive\n" );
-             service = service->next;}
-             }
- )
-
-/************************************************************************
-*	Function :	printServiceTable
-*
-*	Parameters :
-*		service_table * table ;	Service table to be printed
-*		Dbg_Level level ;	Debug level specified to the print function
-*		Dbg_Module module ;	Debug module specified to the print function
-*
-*	Description :	For debugging purposes prints the URL base of the table
-*		and information of each service from the service table passed into 
-*		the function.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-    DBGONLY( void printServiceTable( service_table * table,
-                                     Dbg_Level level,
-                                     Dbg_Module module ) {
-             UpnpPrintf( level, module, __FILE__, __LINE__,
-                         "URL_BASE: %s\n", table->URLBase );
-             UpnpPrintf( level, module, __FILE__, __LINE__,
-                         "Services: \n" );
-             printServiceList( table->serviceList, level, module );}
- )
-
-/************************************************************************
-*	Function :	freeService
-*
-*	Parameters :
-*		service_info *in ;	service information that is to be freed
-*
-*	Description :	Free's memory allocated for the various components 
-*		of the service entry in the service table.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-     void freeService( service_info * in )
-{
-    if( in ) {
-        if( in->serviceType )
-            ixmlFreeDOMString( in->serviceType );
-
-        if( in->serviceId )
-            ixmlFreeDOMString( in->serviceId );
-
-        if( in->SCPDURL )
-            free( in->SCPDURL );
-
-        if( in->controlURL )
-            free( in->controlURL );
-
-        if( in->eventURL )
-            free( in->eventURL );
-
-        if( in->UDN )
-            ixmlFreeDOMString( in->UDN );
-
-        if( in->subscriptionList )
-            freeSubscriptionList( in->subscriptionList );
-
-        in->TotalSubscriptions = 0;
-        free( in );
-    }
-}
-
-/************************************************************************
-*	Function :	freeServiceList
-*
-*	Parameters :
-*		service_info * head ;	Head of the service list to be freed
-*
-*	Description :	Free's memory allocated for the various components 
-*		of each service entry in the service table.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-freeServiceList( service_info * head )
-{
-    service_info *next = NULL;
-
-    while( head ) {
-        if( head->serviceType )
-            ixmlFreeDOMString( head->serviceType );
-        if( head->serviceId )
-            ixmlFreeDOMString( head->serviceId );
-        if( head->SCPDURL )
-            free( head->SCPDURL );
-        if( head->controlURL )
-            free( head->controlURL );
-        if( head->eventURL )
-            free( head->eventURL );
-        if( head->UDN )
-            ixmlFreeDOMString( head->UDN );
-        if( head->subscriptionList )
-            freeSubscriptionList( head->subscriptionList );
-
-        head->TotalSubscriptions = 0;
-        next = head->next;
-        free( head );
-        head = next;
-    }
-}
-
-/************************************************************************
-*	Function :	freeServiceTable
-*
-*	Parameters :
-*		service_table * table ;	Service table whose memory needs to be 
-*								freed
-*
-*	Description : Free's dynamic memory in table.
-*		(does not free table, only memory within the structure)
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-freeServiceTable( service_table * table )
-{
-    ixmlFreeDOMString( table->URLBase );
-    freeServiceList( table->serviceList );
-    table->serviceList = NULL;
-    table->endServiceList = NULL;
-}
-
-/************************************************************************
-*	Function :	getElementValue
-*
-*	Parameters :
-*		IXML_Node *node ;	Input node which provides the list of child 
-*							nodes
-*
-*	Description :	Returns the clone of the element value
-*
-*	Return : DOMString ;
-*
-*	Note : value must be freed with DOMString_free
-************************************************************************/
-DOMString
-getElementValue( IXML_Node * node )
-{
-    IXML_Node *child = ( IXML_Node * ) ixmlNode_getFirstChild( node );
-    const DOMString temp = NULL;
-
-    if( ( child != 0 ) && ( ixmlNode_getNodeType( child ) == eTEXT_NODE ) ) {
-        temp = ixmlNode_getNodeValue( child );
-        return ixmlCloneDOMString( temp );
-    } else {
-        return NULL;
-    }
-}
-
-/************************************************************************
-*	Function :	getSubElement
-*
-*	Parameters :
-*		const char *element_name ;	sub element name to be searched for
-*		IXML_Node *node ;	Input node which provides the list of child 
-*							nodes
-*		IXML_Node **out ;	Ouput node to which the matched child node is
-*							returned.
-*
-*	Description :	Traverses through a list of XML nodes to find the 
-*		node with the known element name.
-*
-*	Return : int ;
-*		1 - On Success
-*		0 - On Failure
-*
-*	Note :
-************************************************************************/
-int
-getSubElement( const char *element_name,
-               IXML_Node * node,
-               IXML_Node ** out )
-{
-
-    const DOMString NodeName = NULL;
-    int found = 0;
-
-    IXML_Node *child = ( IXML_Node * ) ixmlNode_getFirstChild( node );
-
-    ( *out ) = NULL;
-
-    while( ( child != NULL ) && ( !found ) ) {
-
-        switch ( ixmlNode_getNodeType( child ) ) {
-            case eELEMENT_NODE:
-
-                NodeName = ixmlNode_getNodeName( child );
-                if( !strcmp( NodeName, element_name ) ) {
-                    ( *out ) = child;
-                    found = 1;
-                    return found;
-                }
-                break;
-
-            default:
-                break;
-        }
-
-        child = ( IXML_Node * ) ixmlNode_getNextSibling( child );
-    }
-
-    return found;
-}
-
-/************************************************************************
-*	Function :	getServiceList
-*
-*	Parameters :
-*		IXML_Node *node ;	XML node information
-*		service_info **end ; service added is returned to the output
-*							parameter
-*		char * URLBase ;	provides Base URL to resolve relative URL 
-*
-*	Description :	Returns pointer to service info after getting the 
-*		sub-elements of the service info. 
-*
-*	Return : service_info * - pointer to the service info node ;
-*
-*	Note :
-************************************************************************/
-service_info *
-getServiceList( IXML_Node * node,
-                service_info ** end,
-                char *URLBase )
-{
-    IXML_Node *serviceList = NULL;
-    IXML_Node *current_service = NULL;
-    IXML_Node *UDN = NULL;
-
-    IXML_Node *serviceType = NULL;
-    IXML_Node *serviceId = NULL;
-    IXML_Node *SCPDURL = NULL;
-    IXML_Node *controlURL = NULL;
-    IXML_Node *eventURL = NULL;
-    DOMString tempDOMString = NULL;
-    service_info *head = NULL;
-    service_info *current = NULL;
-    service_info *previous = NULL;
-    IXML_NodeList *serviceNodeList = NULL;
-    int NumOfServices = 0;
-    int i = 0;
-    int fail = 0;
-
-    if( getSubElement( "UDN", node, &UDN ) &&
-        getSubElement( "serviceList", node, &serviceList ) ) {
-
-        serviceNodeList = ixmlElement_getElementsByTagName( ( IXML_Element
-                                                              * )
-                                                            serviceList,
-                                                            "service" );
-
-        if( serviceNodeList != NULL ) {
-            NumOfServices = ixmlNodeList_length( serviceNodeList );
-            for( i = 0; i < NumOfServices; i++ ) {
-                current_service = ixmlNodeList_item( serviceNodeList, i );
-                fail = 0;
-
-                if( current ) {
-                    current->next =
-                        ( service_info * )
-                        malloc( sizeof( service_info ) );
-
-                    previous = current;
-                    current = current->next;
-                } else {
-                    head =
-                        ( service_info * )
-                        malloc( sizeof( service_info ) );
-                    current = head;
-                }
-
-                if( !current ) {
-                    freeServiceList( head );
-                    return NULL;
-                }
-
-                current->next = NULL;
-                current->controlURL = NULL;
-                current->eventURL = NULL;
-                current->serviceType = NULL;
-                current->serviceId = NULL;
-                current->SCPDURL = NULL;
-                current->active = 1;
-                current->subscriptionList = NULL;
-                current->TotalSubscriptions = 0;
-
-                if( !( current->UDN = getElementValue( UDN ) ) )
-                    fail = 1;
-
-                if( ( !getSubElement( "serviceType", current_service,
-                                      &serviceType ) ) ||
-                    ( !( current->serviceType =
-                         getElementValue( serviceType ) ) ) )
-                    fail = 1;
-
-                if( ( !getSubElement( "serviceId", current_service,
-                                      &serviceId ) ) ||
-                    ( !
-                      ( current->serviceId =
-                        getElementValue( serviceId ) ) ) )
-                    fail = 1;
-
-                if( ( !
-                      ( getSubElement
-                        ( "SCPDURL", current_service, &SCPDURL ) ) )
-                    || ( !( tempDOMString = getElementValue( SCPDURL ) ) )
-                    ||
-                    ( !
-                      ( current->SCPDURL =
-                        resolve_rel_url( URLBase, tempDOMString ) ) ) )
-                    fail = 1;
-
-                ixmlFreeDOMString( tempDOMString );
-                tempDOMString = NULL;
-
-                if( ( !
-                      ( getSubElement
-                        ( "controlURL", current_service, &controlURL ) ) )
-                    ||
-                    ( !( tempDOMString = getElementValue( controlURL ) ) )
-                    ||
-                    ( !
-                      ( current->controlURL =
-                        resolve_rel_url( URLBase, tempDOMString ) ) ) ) {
-                    DBGONLY( UpnpPrintf
-                             ( UPNP_INFO, GENA, __FILE__, __LINE__,
-                               "BAD OR MISSING CONTROL URL" ) );
-                    DBGONLY( UpnpPrintf
-                             ( UPNP_INFO, GENA, __FILE__, __LINE__,
-                               "CONTROL URL SET TO NULL IN SERVICE INFO" ) );
-                    current->controlURL = NULL;
-                    fail = 0;
-                }
-
-                ixmlFreeDOMString( tempDOMString );
-                tempDOMString = NULL;
-
-                if( ( !
-                      ( getSubElement
-                        ( "eventSubURL", current_service, &eventURL ) ) )
-                    || ( !( tempDOMString = getElementValue( eventURL ) ) )
-                    ||
-                    ( !
-                      ( current->eventURL =
-                        resolve_rel_url( URLBase, tempDOMString ) ) ) ) {
-                    DBGONLY( UpnpPrintf
-                             ( UPNP_INFO, GENA, __FILE__, __LINE__,
-                               "BAD OR MISSING EVENT URL" ) );
-                    DBGONLY( UpnpPrintf
-                             ( UPNP_INFO, GENA, __FILE__, __LINE__,
-                               "EVENT URL SET TO NULL IN SERVICE INFO" ) );
-                    current->eventURL = NULL;
-                    fail = 0;
-                }
-
-                ixmlFreeDOMString( tempDOMString );
-                tempDOMString = NULL;
-
-                if( fail ) {
-                    freeServiceList( current );
-
-                    if( previous )
-                        previous->next = NULL;
-                    else
-                        head = NULL;
-
-                    current = previous;
-                }
-
-            }
-
-            ixmlNodeList_free( serviceNodeList );
-        }
-
-        ( *end ) = current;
-
-        return head;
-    } else
-        return NULL;
-
-}
-
-/************************************************************************
-*	Function :	getAllServiceList
-*
-*	Parameters :
-*		IXML_Node *node ;	XML node information
-*		char * URLBase ;	provides Base URL to resolve relative URL 
-*		service_info **out_end ; service added is returned to the output
-*							parameter
-*
-*	Description :	Returns pointer to service info after getting the 
-*		sub-elements of the service info. 
-*
-*	Return : service_info * ;
-*
-*	Note :
-************************************************************************/
-service_info *
-getAllServiceList( IXML_Node * node,
-                   char *URLBase,
-                   service_info ** out_end )
-{
-    service_info *head = NULL;
-    service_info *end = NULL;
-    service_info *next_end = NULL;
-    IXML_NodeList *deviceList = NULL;
-    IXML_Node *currentDevice = NULL;
-
-    int NumOfDevices = 0;
-    int i = 0;
-
-    ( *out_end ) = NULL;
-
-    deviceList =
-        ixmlElement_getElementsByTagName( ( IXML_Element * ) node,
-                                          "device" );
-    if( deviceList != NULL ) {
-        NumOfDevices = ixmlNodeList_length( deviceList );
-        for( i = 0; i < NumOfDevices; i++ ) {
-            currentDevice = ixmlNodeList_item( deviceList, i );
-            if( head ) {
-                end->next =
-                    getServiceList( currentDevice, &next_end, URLBase );
-                end = next_end;
-            } else
-                head = getServiceList( currentDevice, &end, URLBase );
-
-        }
-
-        ixmlNodeList_free( deviceList );
-    }
-
-    ( *out_end ) = end;
-    return head;
-}
-
-/************************************************************************
-*	Function :	removeServiceTable
-*
-*	Parameters :
-*		IXML_Node *node ;	XML node information
-*		service_table *in ;	service table from which services will be 
-*							removed
-*
-*	Description :	This function assumes that services for a particular 
-*		root device are placed linearly in the service table, and in the 
-*		order in which they are found in the description document
-*		all services for this root device are removed from the list
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-removeServiceTable( IXML_Node * node,
-                    service_table * in )
-{
-    IXML_Node *root = NULL;
-    IXML_Node *currentUDN = NULL;
-    DOMString UDN = NULL;
-    IXML_NodeList *deviceList = NULL;
-    service_info *current_service = NULL;
-    service_info *start_search = NULL;
-    service_info *prev_service = NULL;
-    int NumOfDevices = 0;
-    int i = 0;
-
-    if( getSubElement( "root", node, &root ) ) {
-        current_service = in->serviceList;
-        start_search = in->serviceList;
-        deviceList =
-            ixmlElement_getElementsByTagName( ( IXML_Element * ) root,
-                                              "device" );
-        if( deviceList != NULL ) {
-            NumOfDevices = ixmlNodeList_length( deviceList );
-            for( i = 0; i < NumOfDevices; i++ ) {
-                ixmlNodeList_item( deviceList, i );
-                if( ( start_search )
-                    && ( ( getSubElement( "UDN", node, &currentUDN ) )
-                         && ( UDN = getElementValue( currentUDN ) ) ) ) {
-                    current_service = start_search;
-                    //Services are put in the service table in the order in which they appear in the 
-                    //description document, therefore we go through the list only once to remove a particular
-                    //root device
-                    while( ( current_service )
-                           && ( strcmp( current_service->UDN, UDN ) ) ) {
-                        current_service = current_service->next;
-                        prev_service = current_service->next;
-                    }
-                    while( ( current_service )
-                           && ( !strcmp( current_service->UDN, UDN ) ) ) {
-                        if( prev_service ) {
-                            prev_service->next = current_service->next;
-                        } else {
-                            in->serviceList = current_service->next;
-                        }
-                        if( current_service == in->endServiceList )
-                            in->endServiceList = prev_service;
-                        start_search = current_service->next;
-                        freeService( current_service );
-                        current_service = start_search;
-                    }
-                }
-            }
-
-            ixmlNodeList_free( deviceList );
-        }
-    }
-    return 1;
-}
-
-/************************************************************************
-*	Function :	addServiceTable
-*
-*	Parameters :
-*		IXML_Node *node ;	XML node information 
-*		service_table *in ;	service table that will be initialized with 
-*							services
-*		const char *DefaultURLBase ; Default base URL on which the URL 
-*							will be returned to the service list.
-*
-*	Description :	Add Service to the table.
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-addServiceTable( IXML_Node * node,
-                 service_table * in,
-                 const char *DefaultURLBase )
-{
-    IXML_Node *root = NULL;
-    IXML_Node *URLBase = NULL;
-
-    service_info *tempEnd = NULL;
-
-    if( in->URLBase ) {
-        free( in->URLBase );
-        in->URLBase = NULL;
-    }
-
-    if( getSubElement( "root", node, &root ) ) {
-        if( getSubElement( "URLBase", root, &URLBase ) ) {
-            in->URLBase = getElementValue( URLBase );
-        } else {
-            if( DefaultURLBase ) {
-                in->URLBase = ixmlCloneDOMString( DefaultURLBase );
-            } else {
-                in->URLBase = ixmlCloneDOMString( "" );
-            }
-        }
-
-        if( ( in->endServiceList->next =
-              getAllServiceList( root, in->URLBase, &tempEnd ) ) ) {
-            in->endServiceList = tempEnd;
-            return 1;
-        }
-
-    }
-
-    return 0;
-}
-
-/************************************************************************
-*	Function :	getServiceTable
-*
-*	Parameters :
-*		IXML_Node *node ;	XML node information
-*		service_table *out ;	output parameter which will contain the 
-*							service list and URL 
-*		const char *DefaultURLBase ; Default base URL on which the URL 
-*							will be returned.
-*
-*	Description :	Retrieve service from the table
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-getServiceTable( IXML_Node * node,
-                 service_table * out,
-                 const char *DefaultURLBase )
-{
-    IXML_Node *root = NULL;
-    IXML_Node *URLBase = NULL;
-
-    if( getSubElement( "root", node, &root ) ) {
-        if( getSubElement( "URLBase", root, &URLBase ) ) {
-            out->URLBase = getElementValue( URLBase );
-        } else {
-            if( DefaultURLBase ) {
-                out->URLBase = ixmlCloneDOMString( DefaultURLBase );
-            } else {
-                out->URLBase = ixmlCloneDOMString( "" );
-            }
-        }
-
-        if( ( out->serviceList = getAllServiceList( root, out->URLBase,
-                                                    &out->
-                                                    endServiceList ) ) ) {
-            return 1;
-        }
-
-    }
-
-    return 0;
-}
-
-#endif // INCLUDE_DEVICE_APIS
diff --git a/tombupnp/upnp/src/genlib/util/membuffer.c b/tombupnp/upnp/src/genlib/util/membuffer.c
deleted file mode 100644
index a938e5b..0000000
--- a/tombupnp/upnp/src/genlib/util/membuffer.c
+++ /dev/null
@@ -1,580 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-/************************************************************************
-* Purpose: This file contains functions that operate on memory and 
-*	buffers, allocation, re-allocation, and modification of the memory 
-************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include "config.h"
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <membuffer.h>
-#include "upnp.h"
-#include "unixutil.h"
-
-/************************************************************************
-*								 string									*
-************************************************************************/
-
-/************************************************************************
-*	Function :	str_alloc
-*
-*	Parameters :
-*		IN const char* str ;	input string object
-*		IN size_t str_len ;		input string length
-*
-*	Description :	Allocate memory and copy information from the input 
-*		string to the newly allocated memory.
-*
-*	Return : char* ;
-*		Pointer to the newly allocated memory.
-*		NULL if memory cannot be allocated.
-*
-*	Note :
-************************************************************************/
-char *
-str_alloc( IN const char *str,
-           IN size_t str_len )
-{
-    char *s;
-
-    s = ( char * )malloc( str_len + 1 );
-    if( s == NULL ) {
-        return NULL;            // no mem
-    }
-
-    memcpy( s, str, str_len );
-    s[str_len] = '\0';
-
-    return s;
-}
-
-/************************************************************************
-*								memptr									*
-************************************************************************/
-
-/************************************************************************
-*	Function :	memptr_cmp
-*
-*	Parameters :
-*		IN memptr* m ;	input memory object
-*		IN const char* s ;	constatnt string for the memory object to be 
-*					compared with
-*
-*	Description : Compares characters of strings passed for number of 
-*		bytes. If equal for the number of bytes, the length of the bytes 
-*		determines which buffer is shorter.
-*
-*	Return : int ;
-*		< 0 string1 substring less than string2 substring 
-*		0 string1 substring identical to string2 substring 
-*		> 0 string1 substring greater than string2 substring 
-*
-*	Note :
-************************************************************************/
-int
-memptr_cmp( IN memptr * m,
-            IN const char *s )
-{
-    int cmp;
-
-    cmp = strncmp( m->buf, s, m->length );
-
-    if( cmp == 0 && m->length < strlen( s ) ) {
-        // both strings equal for 'm->length' chars
-        //  if m is shorter than s, then s is greater
-        return -1;
-    }
-
-    return cmp;
-}
-
-/************************************************************************
-*	Function :	memptr_cmp_nocase
-*
-*	Parameters :
-*		IN memptr* m ;	input memory object
-*		IN const char* s ;	constatnt string for the memory object to be 
-*					compared with
-*
-*	Description : Compares characters of 2 strings irrespective of the 
-*		case for a specific count of bytes  If the character comparison 
-*		is the same the length of the 2 srings determines the shorter 
-*		of the 2 strings.
-*
-*	Return : int ;
-*		< 0 string1 substring less than string2 substring 
-*		0 string1 substring identical to string2 substring 
-*		> 0 string1 substring greater than string2 substring 
-*  
-*	Note :
-************************************************************************/
-int
-memptr_cmp_nocase( IN memptr * m,
-                   IN const char *s )
-{
-    int cmp;
-
-    cmp = strncasecmp( m->buf, s, m->length );
-    if( cmp == 0 && m->length < strlen( s ) ) {
-        // both strings equal for 'm->length' chars
-        //  if m is shorter than s, then s is greater
-        return -1;
-    }
-
-    return cmp;
-}
-
-/************************************************************************
-*							 membuffer									*
-************************************************************************/
-
-/************************************************************************
-*	Function :	membuffer_initialize
-*
-*	Parameters :
-*		INOUT membuffer* m ;	buffer to be initialized
-*
-*	Description :	Initialize the buffer
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-static XINLINE void
-membuffer_initialize( INOUT membuffer * m )
-{
-    m->buf = NULL;
-    m->length = 0;
-    m->capacity = 0;
-}
-
-/************************************************************************
-*	Function :	membuffer_set_size
-*
-*	Parameters :
-*		INOUT membuffer* m ;	buffer whose size is to be modified
-*		IN size_t new_length ;	new size to which the buffer will be 
-*					modified
-*
-*	Description : Increases or decreases buffer cap so that at least
-*	   'new_length' bytes can be stored
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Success
-*		UPNP_E_OUTOF_MEMORY - On failure to allocate memory.
-*
-*	Note :
-************************************************************************/
-int
-membuffer_set_size( INOUT membuffer * m,
-                    IN size_t new_length )
-{
-    size_t diff;
-    size_t alloc_len;
-    char *temp_buf;
-
-    if( new_length >= m->length )   // increase length
-    {
-        // need more mem?
-        if( new_length <= m->capacity ) {
-            return 0;           // have enough mem; done
-        }
-
-        diff = new_length - m->length;
-        alloc_len = MAXVAL( m->size_inc, diff ) + m->capacity;
-    } else                      // decrease length
-    {
-        assert( new_length <= m->length );
-
-        // if diff is 0..m->size_inc, don't free
-        if( ( m->capacity - new_length ) <= m->size_inc ) {
-            return 0;
-        }
-
-        alloc_len = new_length + m->size_inc;
-    }
-
-    assert( alloc_len >= new_length );
-
-    temp_buf = realloc( m->buf, alloc_len + 1 );    //LEAK_FIX_MK
-
-    //temp_buf = Realloc( m->buf,m->length, alloc_len + 1 );//LEAK_FIX_MK
-
-    if( temp_buf == NULL ) {
-        // try smaller size
-        alloc_len = new_length;
-        temp_buf = realloc( m->buf, alloc_len + 1 );    //LEAK_FIX_MK
-        //temp_buf = Realloc( m->buf,m->length, alloc_len + 1 );//LEAK_FIX_MK
-
-        if( temp_buf == NULL ) {
-            return UPNP_E_OUTOF_MEMORY;
-        }
-    }
-    // save
-    m->buf = temp_buf;
-    m->capacity = alloc_len;
-    return 0;
-}
-
-/************************************************************************
-*	Function :	membuffer_init
-*
-*	Parameters :
-*		INOUT membuffer* m ; buffer	to be initialized
-*
-*	Description : Wrapper to membuffer_initialize().
-*		Set the size of the buffer to MEMBUF_DEF_SIZE_INC
-*		Initializes m->buf to NULL, length=0
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-membuffer_init( INOUT membuffer * m )
-{
-    assert( m != NULL );
-
-    m->size_inc = MEMBUF_DEF_SIZE_INC;
-    membuffer_initialize( m );
-}
-
-/************************************************************************
-*	Function :	membuffer_destroy
-*
-*	Parameters :
-*		INOUT membuffer* m ;	buffer to be destroyed
-*
-*	Description : Free's memory allocated for membuffer* m.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-membuffer_destroy( INOUT membuffer * m )
-{
-    if( m == NULL ) {
-        return;
-    }
-
-    free( m->buf );
-    membuffer_init( m );
-}
-
-/************************************************************************
-*	Function :	membuffer_assign
-*
-*	Parameters :
-*		INOUT membuffer* m ; buffer whose memory is to be allocated and 
-*					assigned.
-*		IN const void* buf ; source buffer whose contents will be copied
-*		IN size_t buf_len ;	 length of the source buffer
-*
-*	Description : Allocate memory to membuffer* m and copy the contents 
-*		of the in parameter IN const void* buf.
-*
-*	Return : int ;
-*	 UPNP_E_SUCCESS
-*	 UPNP_E_OUTOF_MEMORY
-*
-*	Note :
-************************************************************************/
-int
-membuffer_assign( INOUT membuffer * m,
-                  IN const void *buf,
-                  IN size_t buf_len )
-{
-    int return_code;
-
-    assert( m != NULL );
-
-    // set value to null
-    if( buf == NULL ) {
-        membuffer_destroy( m );
-        return 0;
-    }
-    // alloc mem
-    return_code = membuffer_set_size( m, buf_len );
-    if( return_code != 0 ) {
-        return return_code;
-    }
-    // copy
-    if( buf_len ) {
-        memcpy( m->buf, buf, buf_len );
-        m->buf[buf_len] = 0;        // null-terminate
-    }
-    m->length = buf_len;
-
-    return 0;
-}
-
-/************************************************************************
-*	Function :	membuffer_assign_str
-*
-*	Parameters :
-*		INOUT membuffer* m ;	buffer to be allocated and assigned
-*		IN const char* c_str ;	source buffer whose contents will be 
-*					copied
-*
-*	Description : Wrapper function for membuffer_assign()
-*
-*	Return : int ;
-*	 UPNP_E_SUCCESS
-*	 UPNP_E_OUTOF_MEMORY
-*
-*	Note :
-************************************************************************/
-int
-membuffer_assign_str( INOUT membuffer * m,
-                      IN const char *c_str )
-{
-    return membuffer_assign( m, c_str, strlen( c_str ) );
-}
-
-/************************************************************************
-*	Function :	membuffer_append
-*
-*	Parameters :
-*		INOUT membuffer* m ; buffer whose memory is to be appended.
-*		IN const void* buf ; source buffer whose contents will be 
-*					copied
-*		IN size_t buf_len ;	length of the source buffer
-*
-*	Description : Invokes function to appends data from a constant buffer 
-*		to the buffer 
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-membuffer_append( INOUT membuffer * m,
-                  IN const void *buf,
-                  IN size_t buf_len )
-{
-    assert( m != NULL );
-
-    return membuffer_insert( m, buf, buf_len, m->length );
-}
-
-/************************************************************************
-*	Function :	membuffer_append_str
-*
-*	Parameters :
-*		INOUT membuffer* m ;	buffer whose memory is to be appended.
-*		IN const char* c_str ;	source buffer whose contents will be 
-*					copied
-*
-*	Description : Invokes function to appends data from a constant string 
-*		to the buffer 	
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-membuffer_append_str( INOUT membuffer * m,
-                      IN const char *c_str )
-{
-    return membuffer_insert( m, c_str, strlen( c_str ), m->length );
-}
-
-/************************************************************************
-*	Function :	membuffer_insert
-*
-*	Parameters :
-*		INOUT membuffer* m ; buffer whose memory size is to be increased  
-*					and appended.
-*		IN const void* buf ; source buffer whose contents will be 
-*					copied
-*		 IN size_t buf_len ; size of the source buffer
-*		int index ;	index to determine the bounds while movinf the data
-*
-*	Description : Allocates memory for the new data to be inserted. Does
-*		memory management by moving the data from the existing memory to 
-*		the newly allocated memory and then appending the new data.
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-membuffer_insert( INOUT membuffer * m,
-                  IN const void *buf,
-                  IN size_t buf_len,
-                  int index )
-{
-    int return_code;
-
-    assert( m != NULL );
-
-    if( index < 0 || index > ( int )m->length )
-        return UPNP_E_OUTOF_BOUNDS;
-
-    if( buf == NULL || buf_len == 0 ) {
-        return 0;
-    }
-    // alloc mem
-    return_code = membuffer_set_size( m, m->length + buf_len );
-    if( return_code != 0 ) {
-        return return_code;
-    }
-    // insert data
-
-    // move data to right of insertion point
-    memmove( m->buf + index + buf_len, m->buf + index, m->length - index );
-    memcpy( m->buf + index, buf, buf_len );
-    m->length += buf_len;
-    m->buf[m->length] = 0;      // null-terminate
-
-    return 0;
-}
-
-/************************************************************************
-*	Function :	membuffer_delete
-*
-*	Parameters :
-*		INOUT membuffer* m ; buffer whose memory size is to be decreased
-*					and copied to the odified location
-*		IN int index ;	index to determine bounds while moving data
-*		IN size_t num_bytes ;	number of bytes that the data needs to 
-*					shrink by
-*
-*	Description : Shrink the size of the buffer depending on the current 
-*		size of the bufer and te input parameters. Move contents from the 
-*		old buffer to the new sized buffer.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-membuffer_delete( INOUT membuffer * m,
-                  IN int index,
-                  IN size_t num_bytes )
-{
-    int new_length;
-    size_t copy_len;
-
-    assert( m != NULL );
-
-    if( m->length == 0 ) {
-        return;
-    }
-
-    assert( index >= 0 && index < ( int )m->length );
-
-    // shrink count if it goes beyond buffer
-    if( index + num_bytes > m->length ) {
-        num_bytes = m->length - ( size_t ) index;
-        copy_len = 0;           // every thing at and after index purged
-    } else {
-        // calc num bytes after deleted string
-        copy_len = m->length - ( index + num_bytes );
-    }
-
-    memmove( m->buf + index, m->buf + index + num_bytes, copy_len );
-
-    new_length = m->length - num_bytes;
-    membuffer_set_size( m, new_length ); // trim buffer
-
-    // don't modify until buffer is set
-    m->length = new_length;
-    m->buf[new_length] = 0;
-}
-
-/************************************************************************
-*	Function :	membuffer_detach
-*
-*	Parameters :
-*		INOUT membuffer* m ; buffer to be returned and updated.	
-*
-*	Description : Detaches current buffer and returns it. The caller
-*		must free the returned buffer using free().
-*		After this call, length becomes 0.
-*
-*	Return : char* ;
-*		a pointer to the current buffer
-*
-*	Note :
-************************************************************************/
-char *
-membuffer_detach( INOUT membuffer * m )
-{
-    char *buf;
-
-    assert( m != NULL );
-
-    buf = m->buf;
-
-    // free all
-    membuffer_initialize( m );
-
-    return buf;
-}
-
-/************************************************************************
-*	Function :	membuffer_attach
-*
-*	Parameters :
-*		INOUT membuffer* m ;	buffer to be updated
-*		IN char* new_buf ;	 source buffer which will be assigned to the 
-*					buffer to be updated
-*		IN size_t buf_len ;	length of the source buffer 
-*
-*	Description : Free existing memory in membuffer and assign the new 
-*		buffer in its place.
-*
-*	Return : void ;
-*
-*	Note : 'new_buf' must be allocted using malloc or realloc so
-*		that it can be freed using free()
-************************************************************************/
-void
-membuffer_attach( INOUT membuffer * m,
-                  IN char *new_buf,
-                  IN size_t buf_len )
-{
-    assert( m != NULL );
-
-    membuffer_destroy( m );
-    m->buf = new_buf;
-    m->length = buf_len;
-    m->capacity = buf_len;
-}
diff --git a/tombupnp/upnp/src/genlib/util/strintmap.c b/tombupnp/upnp/src/genlib/util/strintmap.c
deleted file mode 100644
index a29d5d1..0000000
--- a/tombupnp/upnp/src/genlib/util/strintmap.c
+++ /dev/null
@@ -1,138 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-/************************************************************************
-* Purpose: This file contains string to integer and integer to string 
-*	conversion functions 
-************************************************************************/
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include "config.h"
-#include "strintmap.h"
-#include "membuffer.h"
-
-/************************************************************************
-*	Function :	map_str_to_int
-*
-*	Parameters :
-*		IN const char* name ;	string containing the name to be matched
-*		IN size_t name_len ;	size of the string to be matched
-*		IN str_int_entry* table ;	table of entries that need to be 
-*					matched.
-*		IN int num_entries ; number of entries in the table that need 
-*					to be searched.
-*		IN xboolean case_sensitive ; whether the case should be case
-*					sensitive or not
-*
-*	Description : Match the given name with names from the entries in the 
-*		table. Returns the index of the table when the entry is found.
-*
-*	Return : int ;
-*		index - On Success
-*		-1 - On failure
-*
-*	Note :
-************************************************************************/
-int
-map_str_to_int( IN const char *name,
-                IN size_t name_len,
-                IN str_int_entry * table,
-                IN int num_entries,
-                IN xboolean case_sensitive )
-{
-    int top,
-      mid,
-      bot;
-    int cmp;
-    memptr name_ptr;
-
-    name_ptr.buf = ( char * )name;
-    name_ptr.length = name_len;
-
-    top = 0;
-    bot = num_entries - 1;
-
-    while( top <= bot ) {
-        mid = ( top + bot ) / 2;
-        if( case_sensitive ) {
-            //cmp = strcmp( name, table[mid].name );
-            cmp = memptr_cmp( &name_ptr, table[mid].name );
-        } else {
-            //cmp = strcasecmp( name, table[mid].name );
-            cmp = memptr_cmp_nocase( &name_ptr, table[mid].name );
-        }
-
-        if( cmp > 0 ) {
-            top = mid + 1;      // look below mid
-        } else if( cmp < 0 ) {
-            bot = mid - 1;      // look above mid
-        } else                  // cmp == 0
-        {
-            return mid;         // match; return table index
-        }
-    }
-
-    return -1;                  // header name not found
-}
-
-/************************************************************************
-*	Function :	map_int_to_str
-*
-*	Parameters :
-*		IN int id ;	ID to be matched
-*		IN str_int_entry* table ;	table of entries that need to be 
-*					matched.
-*		IN int num_entries ; number of entries in the table that need 
-*					to be searched.
-*
-*	Description : Returns the index from the table where the id matches 
-*		the entry from the table.
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int
-map_int_to_str( IN int id,
-                IN str_int_entry * table,
-                IN int num_entries )
-{
-    int i;
-
-    for( i = 0; i < num_entries; i++ ) {
-        if( table[i].id == id ) {
-            return i;
-        }
-    }
-    return -1;
-}
diff --git a/tombupnp/upnp/src/genlib/util/strtoofft.c b/tombupnp/upnp/src/genlib/util/strtoofft.c
deleted file mode 100644
index 04c022a..0000000
--- a/tombupnp/upnp/src/genlib/util/strtoofft.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id: strtoofft.c,v 1.9 2006/01/09 13:17:14 bagder Exp $
- ***************************************************************************/
-
-/* This code has been adapted for libupnp 
- * by Sergey 'Jin' Bostandzhyan <jin at mediatomb.org> 
- */
-
-
-#include "strtoofft.h"
-
-/*
- * NOTE:
- *
- * In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we
- * could use in case strtoll() doesn't exist...  See
- * http://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html
- */
-
-#ifdef NEED_UPNP_STRTOLL
-#include <stdlib.h>
-#include <ctype.h>
-#include <errno.h>
-
-static int get_char(char c, int base);
-
-/**
- * Emulated version of the strtoll function.  This extracts a long long
- * value from the given input string and returns it.
- */
-long long
-upnp_strtoll(const char *nptr, char **endptr, int base)
-{
-  char *end;
-  int is_negative = 0;
-  int overflow;
-  int i;
-  long long value = 0;
-  long long newval;
-
-  /* Skip leading whitespace. */
-  end = (char *)nptr;
-  while (isspace((int)end[0])) {
-    end++;
-  }
-
-  /* Handle the sign, if any. */
-  if (end[0] == '-') {
-    is_negative = 1;
-    end++;
-  }
-  else if (end[0] == '+') {
-    end++;
-  }
-  else if (end[0] == '\0') {
-    /* We had nothing but perhaps some whitespace -- there was no number. */
-    if (endptr) {
-      *endptr = end;
-    }
-    return 0;
-  }
-
-  /* Handle special beginnings, if present and allowed. */
-  if (end[0] == '0' && end[1] == 'x') {
-    if (base == 16 || base == 0) {
-      end += 2;
-      base = 16;
-    }
-  }
-  else if (end[0] == '0') {
-    if (base == 8 || base == 0) {
-      end++;
-      base = 8;
-    }
-  }
-
-  /* Matching strtol, if the base is 0 and it doesn't look like
-   * the number is octal or hex, we assume it's base 10.
-   */
-  if (base == 0) {
-    base = 10;
-  }
-
-  /* Loop handling digits. */
-  value = 0;
-  overflow = 0;
-  for (i = get_char(end[0], base);
-       i != -1;
-       end++, i = get_char(end[0], base)) {
-    newval = base * value + i;
-    if (newval < value) {
-      /* We've overflowed. */
-      overflow = 1;
-      break;
-    }
-    else
-      value = newval;
-  }
-
-  if (!overflow) {
-    if (is_negative) {
-      /* Fix the sign. */
-      value *= -1;
-    }
-  }
-  else {
-    if (is_negative)
-      value = LLONG_MIN;
-    else
-      value = LLONG_MAX;
-
-    errno = ERANGE;
-  }
-
-  if (endptr)
-    *endptr = end;
-
-  return value;
-}
-
-/**
- * Returns the value of c in the given base, or -1 if c cannot
- * be interpreted properly in that base (i.e., is out of range,
- * is a null, etc.).
- *
- * @param c     the character to interpret according to base
- * @param base  the base in which to interpret c
- *
- * @return  the value of c in base, or -1 if c isn't in range
- */
-static int get_char(char c, int base)
-{
-  int value = -1;
-  if (c <= '9' && c >= '0') {
-    value = c - '0';
-  }
-  else if (c <= 'Z' && c >= 'A') {
-    value = c - 'A' + 10;
-  }
-  else if (c <= 'z' && c >= 'a') {
-    value = c - 'a' + 10;
-  }
-
-  if (value >= base) {
-    value = -1;
-  }
-
-  return value;
-}
-#endif  /* Only present if we need strtoll, but don't have it. */
diff --git a/tombupnp/upnp/src/genlib/util/upnp_timeout.c b/tombupnp/upnp/src/genlib/util/upnp_timeout.c
deleted file mode 100644
index d586f40..0000000
--- a/tombupnp/upnp/src/genlib/util/upnp_timeout.c
+++ /dev/null
@@ -1,69 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-/************************************************************************
-* Purpose: This file contains a function for freeing the memory associated
-*		wuth a upnp time out event.
-************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-#include "config.h"
-#include "upnp_timeout.h"
-
-#include <stdlib.h>
-
-/************************************************************************
-*	Function :	free_upnp_timeout
-*
-*	Parameters :
-*		upnp_timeout *event ;	Event which needs to be freed
-*
-*	Description : Free memory associated with event and memory for any 
-*		sub-elements 
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-free_upnp_timeout( upnp_timeout * event )
-{
-
-    if( event ) {
-        if( event->Event )
-            free( event->Event );
-        free( event );
-
-    }
-}
diff --git a/tombupnp/upnp/src/genlib/util/util.c b/tombupnp/upnp/src/genlib/util/util.c
deleted file mode 100644
index 978fead..0000000
--- a/tombupnp/upnp/src/genlib/util/util.c
+++ /dev/null
@@ -1,118 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-/************************************************************************
-* Purpose: This file contains functions for copying strings based on 
-* different options.
-************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#include "upnp.h"
-#include "util.h"
-
-/************************************************************************
-*	Function :	linecopy
-*
-*	Parameters :
-*		OUT char dest[LINE_SIZE] ;	output buffer
-*		IN const char* src ;	input buffer
-*
-*	Description : Copy no of bytes spcified by the LINE_SIZE constant, 
-*		from the source buffer. Null terminate the destination buffer
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-linecopy( OUT char dest[LINE_SIZE],
-          IN const char *src )
-{
-    strncpy( dest, src, LINE_SIZE - 1 );
-    dest[LINE_SIZE - 1] = '\0'; // null-terminate if len(src) >= LINE_SIZE
-}
-
-/************************************************************************
-*	Function :	namecopy
-*
-*	Parameters :
-*		OUT char dest[NAME_SIZE] ;	output buffer
-*		IN const char* src ;	input buffer
-*
-*	Description : Copy no of bytes spcified by the NAME_SIZE constant, 
-*		from the source buffer. Null terminate the destination buffer
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-namecopy( OUT char dest[NAME_SIZE],
-          IN const char *src )
-{
-    strncpy( dest, src, NAME_SIZE - 1 );
-    dest[NAME_SIZE - 1] = '\0'; // null-terminate if len(src) >= NAME_SIZE
-}
-
-/************************************************************************
-*	Function :	linecopylen
-*
-*	Parameters :
-*		OUT char dest[LINE_SIZE] ;	output buffer
-*		IN const char* src ;	input buffer
-*		IN size_t srclen ;	bytes to be copied.
-*
-*	Description : Determine if the srclen passed in paramter is less than 
-*		the permitted LINE_SIZE. If it is use the passed parameter, if not
-*		use the permitted LINE_SIZE as the length parameter
-*		Copy no of bytes spcified by the LINE_SIZE constant, 
-*		from the source buffer. Null terminate the destination buffer
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void
-linecopylen( OUT char dest[LINE_SIZE],
-             IN const char *src,
-             IN size_t srclen )
-{
-    int len;
-
-    len = srclen < ( LINE_SIZE - 1 ) ? srclen : ( LINE_SIZE - 1 );
-    strncpy( dest, src, len );
-    dest[len] = '\0';
-}
diff --git a/tombupnp/upnp/src/inc/client_table.h b/tombupnp/upnp/src/inc/client_table.h
deleted file mode 100644
index 5dbe4ff..0000000
--- a/tombupnp/upnp/src/inc/client_table.h
+++ /dev/null
@@ -1,166 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef _CLIENT_TABLE
-#define _CLIENT_TABLE
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "upnp.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include "uri.h"
-#include "service_table.h"
-
-#include "TimerThread.h"
-#include "upnp_timeout.h"
-
-extern TimerThread gTimerThread;
-
-CLIENTONLY(
-typedef struct CLIENT_SUBSCRIPTION {
-  Upnp_SID sid;
-  char * ActualSID;
-  char * EventURL;
-  int RenewEventId;
-  struct CLIENT_SUBSCRIPTION * next;
-} client_subscription;
-
-/************************************************************************
-*	Function :	copy_client_subscription
-*
-*	Parameters :
-*		client_subscription * in ;	- source client subscription
-*		client_subscription * out ;	- destination client subscription
-*
-*	Description :	Make a copy of the client subscription data
-*
-*	Return : int ;
-*		UPNP_E_OUTOF_MEMORY - On Failure to allocate memory
-*		HTTP_SUCCESS - On Success
-*
-*	Note :
-************************************************************************/
-int copy_client_subscription(client_subscription * in, client_subscription * out);
-
-/************************************************************************
-*	Function :	free_client_subscription
-*
-*	Parameters :
-*		client_subscription * sub ;	- Client subscription to be freed
-*
-*	Description :	Free memory allocated for client subscription data.
-*		Remove timer thread associated with this subscription event.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void free_client_subscription(client_subscription * sub);
-
-
-/************************************************************************
-*	Function :	freeClientSubList
-*
-*	Parameters :
-*		client_subscription * list ; Client subscription 
-*
-*	Description :	Free the client subscription table.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void freeClientSubList(client_subscription * list);
-
-/************************************************************************
-*	Function :	RemoveClientSubClientSID
-*
-*	Parameters :
-*		client_subscription **head ; Head of the subscription list	
-*		const Upnp_SID sid ;		 Subscription ID to be mactched
-*
-*	Description :	Remove the client subscription matching the 
-*		subscritpion id represented by the const Upnp_SID sid parameter 
-*		from the table and update the table.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void RemoveClientSubClientSID(client_subscription **head, 
-				       const Upnp_SID sid);
-
-/************************************************************************
-*	Function :	GetClientSubClientSID
-*
-*	Parameters :
-*		client_subscription *head ; Head of the subscription list	
-*		const Upnp_SID sid ;		Subscription ID to be matched
-*
-*	Description :	Return the client subscription from the client table 
-*		that matches const Upnp_SID sid subscrition id value. 
-*
-*	Return : client_subscription * ; The matching subscription
-*
-*	Note :
-************************************************************************/
-client_subscription * GetClientSubClientSID(client_subscription *head
-						     , const Upnp_SID sid);
-
-/************************************************************************
-*	Function :	GetClientSubActualSID
-*
-*	Parameters :
-*		client_subscription *head ;	Head of the subscription list		
-*		token * sid ;				Subscription ID to be matched
-*
-*	Description :	Returns the client subscription from the client 
-*		subscription table that has the matching token * sid buffer
-*		value.
-*
-*	Return : client_subscription * ; The matching subscription
-*
-*	Note :
-************************************************************************/
-client_subscription * GetClientSubActualSID(client_subscription *head
-						     , token * sid);
-)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*	_CLIENT_TABLE */
diff --git a/tombupnp/upnp/src/inc/config.h b/tombupnp/upnp/src/inc/config.h
deleted file mode 100644
index a671f8d..0000000
--- a/tombupnp/upnp/src/inc/config.h
+++ /dev/null
@@ -1,401 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-#ifndef INTERNAL_CONFIG_H
-#define INTERNAL_CONFIG_H 
-
-/** @name Compile time configuration options
- *  The Linux SDK for UPnP Devices contains some compile-time parameters 
- *  that effect the behavior of the SDK.  All configuration options are 
- *  located in {\tt src/inc/config.h}.
- */
- 
-//@{
-
-/** @name THREAD_IDLE_TIME
- *  The {\tt THREAD_IDLE_TIME} constant determines when a thread will be
- *  removed from the thread pool and returned to the operating system. When 
- *  a thread in the thread pool has been idle for this number of milliseconds
- *  the thread will be released from the thread pool.  The default value is
- *  5000 milliseconds (5 seconds).
- */
-
-//@{
-#define THREAD_IDLE_TIME 30000
-//@}
-
-/** @name JOBS_PER_THREAD
- *  The {\tt JOBS_PER_THREAD} constant determines when a new thread will be
- *  allocated to the thread pool inside the  SDK. The thread pool will
- *  try and maintain this jobs/thread ratio. When the jobs/thread ratio 
- *  becomes greater than this, then a new thread (up to the max) will be 
- *  allocated to the thread pool.  The default ratio is 10 jobs/thread.
- */
-
-//@{
-#define JOBS_PER_THREAD 1
-//@}
-
-/** @name MIN_THREADS
- *  The {\tt MIN_THREADS} constant defines the minimum number of threads the
- *  thread pool inside the SDK will create.  The thread pool will
- *  always have this number of threads. These threads are used
- *  for both callbacks into applications built on top of the SDK and also
- *  for making connections to other control points and devices. This number
- *  includes persistent threads.  The default value is two threads.
- */
-
-//@{
-#define MIN_THREADS 2 
-//@}
-
-/** @name MAX_THREADS
- *  The {\tt MAX_THREADS} constant defines the maximum number of threads the
- *  thread pool inside the SDK will create.  These threads are used
- *  for both callbacks into applications built on top of the library and also 
- *  for making connections to other control points and devices.  It is not 
- *  recommended that this value be below 10, since the threads are 
- *  necessary for correct operation.  This value can be increased for greater
- *  performance in operation at the expense of greater memory overhead.  The 
- *  default value is 12.
- */
-
-//@{
-#define MAX_THREADS 12 
-//@}
-
-/** @name MAX_JOBS_TOTAL
- *  The {\tt MAX_JOBS_TOTAL} constant determines the maximum number of jobs
- *  that can be queued. If this limit is reached further jobs will be thrown
- *  to avoid memory exhaustion. The default value 100.
- *  (Added by Axis.)
- */
-
-//@{
-#define MAX_JOBS_TOTAL 100
-//@}
-
-/** @name DEFAULT_SOAP_CONTENT_LENGTH
- * SOAP messages will read at most {\tt DEFAULT_SOAP_CONTENT_LENGTH} bytes.  
- * This prevents devices that have a misbehaving web server to send 
- * a large amount of data to the control point causing it to crash.  
- * This can be adjusted dynamically with {\tt UpnpSetMaxContentLength}.
- */
-//@{
-#define DEFAULT_SOAP_CONTENT_LENGTH 16000
-//@}
-
-/** @name NUM_SSDP_COPY
- * This configuration parameter determines how many copies of each SSDP 
- * advertisement and search packets will be sent. By default it will send two 
- * copies of every packet.  
- */
-//@{
-#define NUM_SSDP_COPY  2
-//@}
-
-/** @name SSDP_PAUSE
- * This configuration parameter determines the pause between identical SSDP 
- * advertisement and search packets. The pause is measured in milliseconds
- * and defaults to 100.
- */
-//@{
-#define SSDP_PAUSE  100
-//@}
-
-/** @name WEB_SERVER_BUF_SIZE 
- * This configuration parameter sets the maximum buffer size for the 
- * webserver.  The default value is 1MB.
- */
-//@{
-#define WEB_SERVER_BUF_SIZE  (1024*1024)
-//@}
-
-/** @name AUTO_RENEW_TIME
- * The {\tt AUTO_RENEW_TIME} is the time, in seconds, before a subscription
- * expires that the SDK automatically resubscribes.  The default 
- * value is 10 seconds.  Setting this value too low can result in the 
- * subscription renewal not making it to the device in time, causing the 
- * subscription to timeout. In order to avoid continually resubscribing
- * the minimum subscription time is five seconds more than the auto renew
- * time.
- */
-
-//@{
-#define AUTO_RENEW_TIME 10
-//@}
-
-/** @name CP_MINIMUM_SUBSCRIPTION_TIME 
- * The {\tt CP_MINIMUM_SUBSCRIPTION_TIME} is the minimum subscription time
- * allowed for a control point using the SDK. Subscribing for less than
- * this time automatically results in a subscription for this amount.  The 
- * default value is 5 seconds more than the {\tt AUTO_RENEW_TIME}, or 15
- * seconds.
- */
-
-//@{
-#define CP_MINIMUM_SUBSCRIPTION_TIME (AUTO_RENEW_TIME + 5)
-//@}
-
-/** @name MAX_SEARCH_TIME 
- * The {\tt MAX_SEARCH_TIME} is the maximum time
- * allowed for an SSDP search by a control point. Searching for greater than
- * this time automatically results in a search for this amount.  The default 
- * value is 80 seconds.
- */
-
-//@{
-#define MAX_SEARCH_TIME 80
-//@}
-
-/** @name MIN_SEARCH_TIME 
- * The {\tt MIN_SEARCH_TIME} is the minimumm time
- * allowed for an SSDP search by a control point. Searching for less than
- * this time automatically results in a search for this amount.  The default 
- * value is 2 seconds.
- */
-
-//@{
-#define MIN_SEARCH_TIME 2
-//@}
-
-
-/** @name AUTO_ADVERTISEMENT_TIME
- *  The {\tt AUTO_ADVERTISEMENT_TIME} is the time, in seconds, before an
- *  device advertisements expires before a renewed advertisement is sent.
- *  The default time is 30 seconds.
- */
-
-//@{
-#define AUTO_ADVERTISEMENT_TIME 30
-//@}
-
-/** @name SSDP_PACKET_DISTRIBUTE
- *  The {\tt SSDP_PACKET_DISTRIBUTE} enables the SSDP packets to be sent
- *  at an interval equal to half of the expiration time of SSDP packets
- *  minus the AUTO_ADVERTISEMENT_TIME. This is used to increase
- *  the probability of SSDP packets reaching to control points.
- *  It is recommended that this flag be turned on for embedded wireless 
- *  devices.
- */
-
-//@{
-#define SSDP_PACKET_DISTRIBUTE 1
-//@}
-
-
-/** @name WEB_SERVER_BLOCK_TIMEOUT
- *  When requewsting a blocking select we still will not fully block but
- *  timeout on {\tt WEB_SERVER_BLOCK_TIMEOUT} and check if the global
- *  shutdown flag was set. This ensures that we can always cleanly
- *  shutdown the server, and that UpnpFinish() will never hang waiting for
- *  threads which may be blocked by select()
- *  The default time is 3 seconds.
- */
-
-//@{
-#define WEB_SERVER_BLOCK_TIMEOUT 3
-//@}
-
-/** @name Module Exclusion
- *  Depending on the requirements, the user can selectively discard any of 
- *  the major modules like SOAP, GENA, SSDP or the Internal web server. By 
- *  default everything is included inside the SDK.  By setting any of
- *  the values below to 0, that component will not be included in the final
- *  SDK.
- *  \begin{itemize}
- *    \item {\tt EXCLUDE_SOAP[0,1]}
- *    \item {\tt EXCLUDE_GENA[0,1]}
- *    \item {\tt EXCLUDE_SSDP[0,1]}
- *    \item {\tt EXCLUDE_DOM [0,1]}
- *    \item {\tt EXCLUDE_MINISERVER[0,1]}
- *    \item {\tt EXCLUDE_WEB_SERVER[0,1]}
- *    \item {\tt EXCLUDE_JNI[0,1]}
- *  \end{itemize}
- *
- */
-
-//@{
-#define EXCLUDE_SSDP 0
-#define EXCLUDE_SOAP 0
-#define EXCLUDE_GENA 0
-#define EXCLUDE_DOM  0
-#define EXCLUDE_MINISERVER 0
-#define EXCLUDE_WEB_SERVER 0
-#ifdef USE_JNI
-#	define EXCLUDE_JNI 0
-#else
-#	define EXCLUDE_JNI 1
-#endif
-//@}
-
-    
-/** @name DEBUG_TARGET
- *  The user has the option to redirect the library output debug messages 
- *  to either the screen or to a log file.  All the output messages with 
- *  debug level 0 will go to {\tt upnp.err} and messages with debug level 
- *  greater than zero will be redirected to {\tt upnp.out}.
- */
-
-//@{
-#define DEBUG_TARGET		1   
-//@}
-
-
-/** @name Other debugging features
-          The UPnP SDK contains other features to aid in debugging:
-	  see <upnp/upnpdebug.h>
- */
-
-#define DEBUG_ALL		1   
-#define DEBUG_SSDP		0    
-#define DEBUG_SOAP		0    
-#define DEBUG_GENA		0    
-#define DEBUG_TPOOL		0     
-#define DEBUG_MSERV		0
-#define DEBUG_DOM		0
-#define DEBUG_HTTP		0
-#define DEBUG_API		0    
-
-//@} // Compile time configuration options
-
-
-/***************************************************************************
- * Do not change, Internal purpose only!!! 
- ***************************************************************************/ 
-
-//@{
-
-/*
- * Set additional defines based on requested configuration 
- */
-
-// configure --enable-client
-#if UPNP_HAVE_CLIENT
-#	define INCLUDE_CLIENT_APIS	1
-#endif
-
-// configure --enable-device
-#if UPNP_HAVE_DEVICE
-#	define INCLUDE_DEVICE_APIS	1
-#endif
-
-// configure --enable-webserver --enable-device
-#if UPNP_HAVE_WEBSERVER
-#	define INTERNAL_WEB_SERVER	1
-#endif
-
-
-
-/** @name DBGONLY
-          The {\bf DBGONLY} macro allows code to be marked so that it 
-          is only included in the DEBUG build and not the release.  To
-          use this macro, put the code inside of the parentheses:
-
-          {\tt DBGONLY(int i;)}
-
-          This will cause a declaration of the integer {\tt i} only
-          in the debug build.
-  */
-
-//@{
-#ifdef DEBUG
-#	define DBGONLY(x) x
-#else
-#	define DBGONLY(x)  
-#endif
-//@}
-
-
-
-#undef  EXCLUDE_WEB_SERVER 
-#undef  EXCLUDE_MINISERVER 
-#ifdef  INTERNAL_WEB_SERVER
-#	define EXCLUDE_WEB_SERVER 0
-#	define EXCLUDE_MINISERVER 0
-#else
-#	define EXCLUDE_WEB_SERVER 1
-#	define EXCLUDE_MINISERVER 1
-#endif
-
-#if EXCLUDE_GENA == 1 && EXCLUDE_SOAP == 1 && EXCLUDE_WEB_SERVER == 1
-#	undef  EXCLUDE_MINISERVER 
-#	define EXCLUDE_MINISERVER 1
-#	if INTERNAL_WEB_SERVER
-#		error "conflicting settings: use configure --disable-webserver"
-#	endif
-#endif
-
-#if EXCLUDE_GENA == 0 || EXCLUDE_SOAP == 0 || EXCLUDE_WEB_SERVER == 0
-#	undef  EXCLUDE_MINISERVER 
-#	define EXCLUDE_MINISERVER 0
-#	if EXCLUDE_WEB_SERVER == 0 && !defined INTERNAL_WEB_SERVER
-#		error "conflicting settings : use configure --enable-webserver"
-#	endif
-#endif
-
-
-
-#ifdef INCLUDE_CLIENT_APIS
-#	define CLIENTONLY(x) x
-#else 
-#	define CLIENTONLY(x)
-#endif
-
-#ifdef INCLUDE_DEVICE_APIS
-#	define DEVICEONLY(x) x
-#else 
-#	define DEVICEONLY(x) 
-#endif
-
-//@}
-#endif
diff --git a/tombupnp/upnp/src/inc/gena.h b/tombupnp/upnp/src/inc/gena.h
deleted file mode 100644
index 1307665..0000000
--- a/tombupnp/upnp/src/inc/gena.h
+++ /dev/null
@@ -1,372 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef _GENA_
-#define _GENA_
-#include "config.h"
-#include "service_table.h"
-#include "miniserver.h"
-#include "uri.h"
-#include "upnp.h"
-
-#include <time.h>
-#include "ThreadPool.h"
-#include <string.h>
-#include "client_table.h"
-#include "httpparser.h"
-#include "sock.h"
-
-#ifdef __cplusplus
-#define EXTERN_C extern "C"
-#else 
-#ifndef EXTERN_C
- #define EXTERN_C 
-#endif
-#endif
-
-#define XML_VERSION "<?xml version='1.0' encoding='ISO-8859-1' ?>\n"
-#define XML_PROPERTYSET_HEADER \
-		"<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\">\n"
-
-#define UNABLE_MEMORY "HTTP/1.1 500 Internal Server Error\r\n\r\n"
-#define UNABLE_SERVICE_UNKNOWN "HTTP/1.1 404 Not Found\r\n\r\n"
-#define UNABLE_SERVICE_NOT_ACCEPT \
-			"HTTP/1.1 503 Service Not Available\r\n\r\n"
-
-
-#define NOT_IMPLEMENTED "HTTP/1.1 501 Not Implemented\r\n\r\n"
-#define BAD_REQUEST "HTTP/1.1 400 Bad Request\r\n\r\n"
-#define INVALID_NT BAD_CALLBACK
-#define BAD_CALLBACK "HTTP/1.1 412 Precondition Failed\r\n\r\n" 
-#define HTTP_OK_CRLF "HTTP/1.1 200 OK\r\n\r\n"
-#define HTTP_OK_STR "HTTP/1.1 200 OK\r\n"
-#define INVALID_SID BAD_CALLBACK
-#define MISSING_SID BAD_CALLBACK
-#define MAX_CONTENT_LENGTH 20
-#define MAX_SECONDS 10
-#define MAX_EVENTS 20
-#define MAX_PORT_SIZE 10
-#define GENA_E_BAD_RESPONSE UPNP_E_BAD_RESPONSE
-#define GENA_E_BAD_SERVICE UPNP_E_INVALID_SERVICE
-#define GENA_E_SUBSCRIPTION_UNACCEPTED UPNP_E_SUBSCRIBE_UNACCEPTED
-#define GENA_E_BAD_SID UPNP_E_INVALID_SID
-#define GENA_E_UNSUBSCRIBE_UNACCEPTED UPNP_E_UNSUBSCRIBE_UNACCEPTED
-#define GENA_E_NOTIFY_UNACCEPTED UPNP_E_NOTIFY_UNACCEPTED
-#define GENA_E_NOTIFY_UNACCEPTED_REMOVE_SUB -9
-#define GENA_E_BAD_HANDLE UPNP_E_INVALID_HANDLE
-#define XML_ERROR -5
-#define XML_SUCCESS UPNP_E_SUCCESS
-#define GENA_SUCCESS UPNP_E_SUCCESS
-#define CALLBACK_SUCCESS 0
-#define DEFAULT_TIMEOUT 1801
-
-
-
-extern ithread_mutex_t GlobalClientSubscribeMutex;
-
-//Lock the subscription
-#define SubscribeLock() \
-	DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__, \
-	"Trying Subscribe Lock"));  \
-	ithread_mutex_lock(&GlobalClientSubscribeMutex); \
-	DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__,"Subscribe Lock");)
-
-//Unlock the subscription
-#define SubscribeUnlock() \
-	DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__, \
-		"Trying Subscribe UnLock")); \
-	ithread_mutex_unlock(&GlobalClientSubscribeMutex); \
-	DBGONLY(UpnpPrintf(UPNP_INFO,GENA,__FILE__,__LINE__,"Subscribe UnLock");)
-
-
-//Structure to send NOTIFY message to all subscribed control points
-typedef struct NOTIFY_THREAD_STRUCT {
-  char * headers;
-  DOMString propertySet;
-  char * servId;
-  char * UDN;
-  Upnp_SID sid;
-  int eventKey;
-  int *reference_count;
-  UpnpDevice_Handle device_handle;
-} notify_thread_struct;
-
-
-/************************************************************************
-* Function : genaCallback									
-*																	
-* Parameters:														
-*	IN http_parser_t *parser: represents the parse state of the request
-*	IN http_message_t* request: HTTP message containing GENA request
-*	INOUT SOCKINFO *info: Structure containing information about the socket
-*
-* Description:														
-*	This is the callback function called by the miniserver to handle 
-*	incoming GENA requests. 
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-EXTERN_C void genaCallback (IN http_parser_t *parser, 
-							IN http_message_t* request, 
-							IN SOCKINFO *info);
-
-/************************************************************************
-* Function : genaSubscribe
-*																	
-* Parameters:														
-*	IN UpnpClient_Handle client_handle: 
-*	IN char * PublisherURL: NULL Terminated, of the form : 
-*						"http://134.134.156.80:4000/RedBulb/Event"
-*	INOUT int * TimeOut: requested Duration, if -1, then "infinite".
-*						in the OUT case: actual Duration granted 
-*						by Service, -1 for infinite
-*	OUT Upnp_SID out_sid:sid of subscription, memory passed in by caller
-*
-* Description:														
-*	This function subscribes to a PublisherURL ( also mentioned as EventURL
-*	some places). It sends SUBSCRIBE http request to service processes 
-*	request. Finally adds a Subscription to 
-*	the clients subscription list, if service responds with OK
-*
-* Returns: int
-*	return UPNP_E_SUCCESS if service response is OK else 
-*	returns appropriate error
-***************************************************************************/
-CLIENTONLY(
-	EXTERN_C int genaSubscribe(UpnpClient_Handle client_handle,
-				char * PublisherURL,
-				int * TimeOut, 
-				Upnp_SID  out_sid );)
-
-
-/************************************************************************
-* Function : genaUnSubscribe
-*																	
-* Parameters:														
-*	IN UpnpClient_Handle client_handle: UPnP client handle
-*	IN SID in_sid: The subscription ID
-*
-* Description:														
-*	This function unsubscribes a SID. It first validates the SID and 
-*	client_handle,copies the subscription, sends UNSUBSCRIBE http request 
-*	to service processes request and finally removes the subscription
-*
-* Returns: int
-*	return UPNP_E_SUCCESS if service response is OK else 
-*	returns appropriate error
-***************************************************************************/
-CLIENTONLY(EXTERN_C int genaUnSubscribe(UpnpClient_Handle client_handle,
-		   const Upnp_SID in_sid);)
-
-/************************************************************************
-* Function : genaUnregisterClient									
-*																	
-* Parameters:														
-*	IN UpnpClient_Handle client_handle: Handle containing all the control
-*			point related information
-*
-* Description:														
-*	This function unsubcribes all the outstanding subscriptions and cleans
-*	the subscription list. This function is called when control point 
-*	unregisters.
-*
-* Returns: int
-*	return UPNP_E_SUCCESS if successful else returns appropriate error
-***************************************************************************/
-CLIENTONLY(EXTERN_C int genaUnregisterClient(
-			UpnpClient_Handle client_handle);)
-
-//server
-/************************************************************************
-* Function : genaUnregisterDevice
-*																	
-* Parameters:														
-*	IN UpnpDevice_Handle device_handle: Handle of the root device
-*
-* Description:														
-*	This function cleans the service table of the device. 
-*
-* Returns: int
-*	returns UPNP_E_SUCCESS if successful else returns GENA_E_BAD_HANDLE
-****************************************************************************/
-DEVICEONLY(EXTERN_C int genaUnregisterDevice(
-				UpnpDevice_Handle device_handle);)
-
-
-/************************************************************************
-* Function : genaRenewSubscription
-*																	
-* Parameters:														
-*	IN UpnpClient_Handle client_handle: Client handle
-*	IN const Upnp_SID in_sid: subscription ID
-*	INOUT int * TimeOut: requested Duration, if -1, then "infinite".
-*						in the OUT case: actual Duration granted 
-*						by Service, -1 for infinite
-*
-* Description:														
-*	This function renews a SID. It first validates the SID and 
-*	client_handle and copies the subscription. It sends RENEW 
-*	(modified SUBSCRIBE) http request to service and processes
-*	the response.
-*
-* Returns: int
-*	return UPNP_E_SUCCESS if service response is OK else 
-*	returns appropriate error
-***************************************************************************/
-CLIENTONLY(EXTERN_C int genaRenewSubscription(
-							IN UpnpClient_Handle client_handle,
-							IN const Upnp_SID in_sid,
-							OUT int * TimeOut);)
-/****************************************************************************
-*	Function :	genaNotifyAll
-*
-*	Parameters :
-*		IN UpnpDevice_Handle device_handle : Device handle
-*		IN char *UDN :	Device udn
-*		IN char *servId :	Service ID
-*	    IN char **VarNames : array of varible names
-*	    IN char **VarValues :	array of variable values
-*		IN int var_count	 :	number of variables
-*
-*	Description : 	This function sends a notification to all the subscribed
-*	control points
-*
-*	Return :	int
-*
-*	Note : This function is similar to the genaNotifyAllExt. The only difference
-*			is it takes event variable array instead of xml document.
-****************************************************************************/
-DEVICEONLY(EXTERN_C int genaNotifyAll(UpnpDevice_Handle device_handle,
-			   char *UDN,
-			   char *servId,
-			   char **VarNames,
-			   char **VarValues,
-		    int var_count
-				      );)
-
-/****************************************************************************
-*	Function :	genaNotifyAllExt
-*
-*	Parameters :
-*			IN UpnpDevice_Handle device_handle : Device handle
-*			IN char *UDN :	Device udn
-*			IN char *servId :	Service ID
-*           IN IXML_Document *PropSet :	XML document Event varible property set
-*
-*	Description : 	This function sends a notification to all the subscribed
-*	control points
-*
-*	Return :	int
-*
-*	Note : This function is similar to the genaNotifyAll. the only difference
-*			is it takes the document instead of event variable array
-****************************************************************************/
-DEVICEONLY(EXTERN_C int genaNotifyAllExt(UpnpDevice_Handle device_handle, 
-		   char *UDN, char *servId,IN IXML_Document *PropSet);)
-
-/****************************************************************************
-*	Function :	genaInitNotify
-*
-*	Parameters :
-*		   IN UpnpDevice_Handle device_handle :	Device handle
-*		   IN char *UDN :	Device udn
-*		   IN char *servId :	Service ID
-*		   IN char **VarNames :	Array of variable names
-*		   IN char **VarValues :	Array of variable values
-*		   IN int var_count :	array size
-*		   IN Upnp_SID sid :	subscription ID
-*
-*	Description :	This function sends the intial state table dump to 
-*		newly subscribed control point. 
-*
-*	Return :	int
-*		returns GENA_E_SUCCESS if successful else returns appropriate error
-* 
-*	Note : No other event will be sent to this control point before the 
-*			intial state table dump.
-****************************************************************************/
-DEVICEONLY(EXTERN_C int genaInitNotify(IN UpnpDevice_Handle device_handle,
-			    IN char *UDN,
-			    IN char *servId,
-			    IN char **VarNames,
-			    IN char **VarValues,
-				IN int var_count,
-				IN Upnp_SID sid);)
-
-/****************************************************************************
-*	Function :	genaInitNotifyExt
-*
-*	Parameters :
-*		   IN UpnpDevice_Handle device_handle :	Device handle
-*		   IN char *UDN :	Device udn
-*		   IN char *servId :	Service ID
-*		   IN IXML_Document *PropSet :	Document of the state table
-*		   IN Upnp_SID sid :	subscription ID
-*
-*	Description :	This function is similar to the genaInitNofity. The only 
-*	difference is that it takes the xml document for the state table and 
-*	sends the intial state table dump to newly subscribed control point. 
-*
-*	Return :	int
-*		returns GENA_E_SUCCESS if successful else returns appropriate error
-* 
-*	Note : No other event will be sent to this control point before the 
-*			intial state table dump.
-****************************************************************************/
-DEVICEONLY(EXTERN_C  int genaInitNotifyExt(
-		   IN UpnpDevice_Handle device_handle, 
-		   IN char *UDN, 
-		   IN char *servId,
-		   IN IXML_Document *PropSet, 
-		   IN Upnp_SID sid);)
-
-
-/************************************************************************
-* Function : error_respond									
-*																	
-* Parameters:														
-*	IN SOCKINFO *info: Structure containing information about the socket
-*	IN int error_code: error code that will be in the GENA response
-*	IN http_message_t* hmsg: GENA request Packet 
-*
-* Description:														
-*	This function send an error message to the control point in the case
-*	incorrect GENA requests.
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-void error_respond( IN SOCKINFO *info, IN int error_code,
-				    IN http_message_t* hmsg );
-
-
-#endif // GENA
diff --git a/tombupnp/upnp/src/inc/gena_ctrlpt.h b/tombupnp/upnp/src/inc/gena_ctrlpt.h
deleted file mode 100644
index 5896be2..0000000
--- a/tombupnp/upnp/src/inc/gena_ctrlpt.h
+++ /dev/null
@@ -1,52 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include "sock.h"
-
-/************************************************************************
-* Function : gena_process_notification_event
-*																	
-* Parameters:														
-*	IN SOCKINFO *info: Socket structure containing the device socket 
-*					information
-*	IN http_message_t* event: The http message contains the GENA 
-*								notification
-*
-* Description:														
-*	This function processes NOTIFY events that are sent by devices. 
-*	called by genacallback()
-*
-* Returns: void
-*
-* Note : called by genacallback()
-****************************************************************************/
-void gena_process_notification_event( INOUT SOCKINFO *info,
-				      IN http_message_t* request );
diff --git a/tombupnp/upnp/src/inc/gena_device.h b/tombupnp/upnp/src/inc/gena_device.h
deleted file mode 100644
index 42077d0..0000000
--- a/tombupnp/upnp/src/inc/gena_device.h
+++ /dev/null
@@ -1,88 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include "sock.h"
-
-/****************************************************************************
-*	Function :	gena_process_subscription_request
-*
-*	Parameters :
-*			IN SOCKINFO *info :	socket info of the device 
-*			IN http_message_t* request : SUBSCRIPTION request from the control
-*										point
-*
-*	Description :	This function handles a subscription request from a 
-*		ctrl point. The socket is not closed on return.
-*
-*	Return :	void
-*
-*	Note :
-****************************************************************************/
-void gena_process_subscription_request( IN SOCKINFO *info,
-					IN http_message_t* request );
-
-
-/****************************************************************************
-*	Function :	gena_process_subscription_renewal_request
-*
-*	Parameters :
-*		IN SOCKINFO *info :	socket info of the device
-*		IN http_message_t* request : subscription renewal request from the 
-*									control point
-*
-*	Description :	This function handles a subscription renewal request 
-*		from a ctrl point. The connection is not destroyed on return.
-*
-*	Return :	void
-*
-*	Note :
-****************************************************************************/
-void gena_process_subscription_renewal_request( IN SOCKINFO *info,
-						IN http_message_t* request );
-
-
-/****************************************************************************
-*	Function :	gena_process_unsubscribe_request
-*
-*	Parameters :
-*			IN SOCKINFO *info :	socket info of the device
-*			IN http_message_t* request : UNSUBSCRIBE request from the control 
-*											point
-*
-*	Description : This function Handles a subscription cancellation request 
-*		from a ctrl point. The connection is not destroyed on return.
-*
-*	Return :	void
-*
-*	Note :
-****************************************************************************/
-void gena_process_unsubscribe_request(	IN SOCKINFO *info,
-					IN http_message_t* request );
diff --git a/tombupnp/upnp/src/inc/global.h b/tombupnp/upnp/src/inc/global.h
deleted file mode 100644
index 58d4b82..0000000
--- a/tombupnp/upnp/src/inc/global.h
+++ /dev/null
@@ -1,62 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-/* GLOBAL.H - RSAREF types and constants */
-/* PROTOTYPES should be set to one if and only if the compiler supports
-  function argument prototyping.
-
-  The following makes PROTOTYPES default to 0 if it has not already
-  been defined with C compiler flags.
-*/
-
-#ifndef PROTOTYPES
-#define PROTOTYPES 0
-#endif
-
-/* POINTER defines a generic pointer type */
-typedef unsigned char *POINTER;
-
-/* UINT2 defines a two byte word */
-typedef unsigned short int UINT2;
-
-/* UINT4 defines a four byte word */
-typedef unsigned long int UINT4;
-
-/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
-   If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
-   returns an empty list.
- */
-
-#if PROTOTYPES
-#define PROTO_LIST(list) list
-#else
-#define PROTO_LIST(list) ()
-#endif
diff --git a/tombupnp/upnp/src/inc/gmtdate.h b/tombupnp/upnp/src/inc/gmtdate.h
deleted file mode 100644
index 50152bf..0000000
--- a/tombupnp/upnp/src/inc/gmtdate.h
+++ /dev/null
@@ -1,97 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef GENLIB_UTIL_GMTDATE_H
-#define GENLIB_UTIL_GMTDATE_H
-
-#include <time.h>
-#include <genlib/util/util.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// input: monthStr:  3-letter or full month
-// returns month=0..11 or -1 on failure
-// output:
-//   charsRead - num chars that match the month
-//   fullNameMatch - full name match(1) or 3-letter match(0)
-//
-int ParseMonth( IN const char* monthStr,
-    OUT int* charsRead, OUT int* fullNameMatch );
-
-// input: dayOfWeek:  3-letter or full day of week ("mon" etc)
-// returns dayOfWeek=0..6 or -1 on failure
-// output:
-//   charsRead - num chars that match the month
-//   fullNameMatch - full name match(1) or 3-letter match(0)
-//
-int ParseDayOfWeek( IN const char* dayOfWeek,
-    OUT int* charsRead, OUT int* fullNameMatch );
-
-// converts date to string format: RFC 1123 format:
-// Sun, 06 Nov 1994 08:49:37 GMT
-// String returned must be freed using free() function
-// returns NULL if date is NULL
-//
-// throws OutOfMemoryException
-char* DateToString( const struct tm* date );
-
-// parses time in fmt hh:mm:ss, military fmt
-// returns 0 on success; -1 on error
-int ParseTime( const char* s, int* hour, int* minute, int* second );
-
-
-
-// tries to parse date according to RFCs 1123, 850, or asctime()
-//  format
-// params:
-//   str - contains date/time in string format
-//   dateTime - date and time obtained from 'str'
-// returns: 0 on success, -1 on error
-int ParseRFC850DateTime( IN const char* str,
-    OUT struct tm* dateTime, OUT int* numCharsParsed );
-
-int ParseRFC1123DateTime( IN const char* str,
-    OUT struct tm* dateTime, OUT int* numCharsParsed );
-
-int ParseAsctimeFmt( IN const char* str,
-    OUT struct tm* dateTime, OUT int* numCharsParsed );
-
-// parses any of these formats: 1123, 850 or asctime()  
-int ParseDateTime( IN const char* str,
-    OUT struct tm* dateTime, OUT int* numCharsParsed );
-
-#ifdef __cplusplus
-}   /* extern C */
-#endif
-
-#endif /* GENLIB_UTIL_GMTDATE_H */
diff --git a/tombupnp/upnp/src/inc/http_client.h b/tombupnp/upnp/src/inc/http_client.h
deleted file mode 100644
index 165cfca..0000000
--- a/tombupnp/upnp/src/inc/http_client.h
+++ /dev/null
@@ -1,249 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef _http_client_h_
-#define _http_client_h_
-#ifdef __cplusplus
-#define EXTERN_C extern "C"
-#else
-#define EXTERN_C
-#endif
-#include "genlib/closesocket/upnpclosesocket.h"
-#include <fcntl.h>
-#include <string.h>
-#include <sys/types.h>
-#include <time.h>
-#include <errno.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <sys/time.h>
-#include "tools/config.h"
-#include "upnp.h"
-//#include "upnp_debug.h"
-
-
-#define HTTP_DATE_LENGTH 37 // length for HTTP DATE: 
-                            //"DATE: Sun, 01 Jul 2000 08:15:23 GMT<cr><lf>"
-#define SEPARATORS "()<>@,;:\\\"/[]?={} \t"
-#define MARK "-_.!~*'()"
-#define RESERVED ";/?:@&=+$,"
-#define HTTP_SUCCESS 1
-#define HTTP_E_BAD_URL UPNP_E_INVALID_URL
-#define HTTP_E_READ_SOCKET  UPNP_E_SOCKET_READ
-#define HTTP_E_BIND_SOCKET  UPNP_E_SOCKET_BIND
-#define HTTP_E_WRITE_SOCKET  UPNP_E_SOCKET_WRITE
-#define HTTP_E_CONNECT_SOCKET  UPNP_E_SOCKET_CONNECT
-#define HTTP_E_SOCKET    UPNP_E_OUTOF_SOCKET
-#define HTTP_E_BAD_RESPONSE UPNP_E_BAD_RESPONSE
-#define HTTP_E_BAD_REQUEST UPNP_E_BAD_REQUEST
-#define HTTP_E_BAD_IP_ADDRESS UPNP_E_INVALID_URL
-#define FALSE 0
-#define TAB 9
-#define CR 13
-#define LF 10
-#define RESPONSE_TIMEOUT 30
-#define SOCKET_BUFFER_SIZE 5000
-
-enum hostType { HOSTNAME, IPv4address };
-enum pathType { ABS_PATH, REL_PATH, OPAQUE_PART };
-enum uriType  { ABSOLUTE, RELATIVE };
-
-//Buffer used to store data read from 
-//a socket during an http transfer
-//in function read_bytes.
-typedef struct SOCKET_BUFFER{
-  char buff[SOCKET_BUFFER_SIZE];
-  int size;
-  struct SOCKET_BUFFER *next;
-} socket_buffer;
-
-//Buffer used in parsing
-//http messages, urls, etc.
-//generally this simply
-//holds a pointer into a larger array
-typedef struct TOKEN {
-   char * buff;
-  int size;
-} token;
-
-
-//Represents a host port:
-//e.g. :"127.127.0.1:80"
-//text is a token pointing to 
-//the full string representation
-typedef struct HOSTPORT {
-  token text; //full host port
-  struct sockaddr_in IPv4address; //Network Byte Order  
-} hostport_type;
-
-//Represents a URI
-//used in parse_uri and elsewhere
-typedef struct URI{
-  enum uriType type;
-  token scheme;
-  enum pathType path_type;
-  token pathquery;
-  token fragment;
-  hostport_type hostport;
-} uri_type;
-
-//Represents a list of URLs as in 
-//the "callback" header of SUBSCRIBE
-//message in GENA
-//char * URLs holds dynamic memory
-typedef struct URL_LIST {
-  int size;
-  char * URLs; //all the urls, delimited by <>
-  uri_type *parsedURLs;
-} URL_list;
-
-typedef struct HTTP_HEADER {
-  token header;
-  token value;
-  struct HTTP_HEADER * next;
-} http_header;
-
-typedef struct HTTP_STATUS_LINE{
-  token http_version;
-  token status_code;
-  token reason_phrase;
-} http_status;
-
-typedef struct HTTP_REQUEST_LINE {
-  token http_version;
-  uri_type request_uri;
-  token method;
-} http_request;
-
-//Represents a parsed HTTP_MESSAGE
-//head_list is dynamically allocated
-typedef struct HTTP_MESSAGE {
-  http_status status;
-  http_request request;
-  http_header * header_list;
-  token content;
-} http_message;
-
-
-EXTERN_C int transferHTTP( char * request,  char * toSend, 
-			  int toSendSize, char **out,  char * Url);
-
-
-EXTERN_C int transferHTTPRaw( char * toSend, int toSendSize, 
-			     char **out,  char *URL);
-
-//helper function
-EXTERN_C int transferHTTPparsedURL( char * request, 
-				    char * toSend, int toSendSize, 
-				   char **out, uri_type *URL);
-
-//assumes that char * out has enough space ( 38 characters)
-//outputs the current time in the following null terminated string:
-// "DATE: Sun, Jul 06 2000 08:53:01 GMT\r\n"
-EXTERN_C void currentTmToHttpDate(char *out);
-
-//returns dynamic memory or NULL on error
-EXTERN_C char * resolve_rel_url( char * base_url,  char * rel_url);
-
-EXTERN_C int parse_uri(  char * in, int max, uri_type * out);
-
-EXTERN_C int token_cmp( token *in1,  token *in2);
-
-EXTERN_C int token_string_casecmp( token * in1,  char * in2);
-
-EXTERN_C int token_string_cmp( token * in1,  char * in2);
-
-EXTERN_C int parse_http_response(  char * in, http_message * out, 
-				  int max_len);
-
-EXTERN_C int parse_http_request( char * in, http_message *out, 
-				int max_len);
-
-EXTERN_C int search_for_header( http_message * in, 
-			        char * header, token *out_value);
-
-
-
-EXTERN_C int parse_hostport(  char* in, int max, hostport_type *out );
-
-EXTERN_C size_t write_bytes(int fd,   char * bytes, size_t n, 
-			    int timeout);
-EXTERN_C void free_http_message(http_message * message);
-EXTERN_C int copy_URL_list( URL_list *in, URL_list *out);
-EXTERN_C void free_URL_list(URL_list * list);
-EXTERN_C int parse_port(int max,   char * port, unsigned short int * out);
-
-EXTERN_C int parse_http_line(  char * in, int max_size);
-EXTERN_C int parse_not_LWS(  char *in, token *out, int max_size);
-EXTERN_C int parse_LWS( char * in, int max_size);
-EXTERN_C int parse_token( char * in, token * out, int max_size);
-EXTERN_C ssize_t readLine(int fd, char *out, int max, int *timeout);
-EXTERN_C int remove_dots(char * in, int size);
-
-
-DBGONLY(EXTERN_C void print_http_request(http_message
-					 *message,Dbg_Level DLevel,
-					 Dbg_Module Module,char *DbgFileName,
-					 int DbgLineNo););
-
-DBGONLY(EXTERN_C void print_http_response(http_message *message,
-					  Dbg_Level DLevel,
-					  Dbg_Module Module,char *DbgFileName,
-					  int DbgLineNo););
-
-DBGONLY(EXTERN_C void print_token(  token * in,
-				    Dbg_Level DLevel,
-				    Dbg_Module Module,
-				    char *DbgFileName,
-				    int DbgLineNo););
-
-DBGONLY(EXTERN_C void print_status_line(http_status *in,
-					Dbg_Level DLevel,
-					Dbg_Module Module,
-					char *DbgFileName,
-					int DbgLineNo););
-
-DBGONLY(EXTERN_C void print_request_line(http_request *in,
-					 Dbg_Level DLevel,
-					 Dbg_Module Module,
-					 char *DbgFileName,int DbgLineNo));
-
-DBGONLY(EXTERN_C void print_uri( uri_type *in,
-				 Dbg_Level DLevel,
-				 Dbg_Module Module,
-				 char *DbgFileName,
-				 int DbgLineNo););
-
-#endif
diff --git a/tombupnp/upnp/src/inc/httpparser.h b/tombupnp/upnp/src/inc/httpparser.h
deleted file mode 100644
index 045e18a..0000000
--- a/tombupnp/upnp/src/inc/httpparser.h
+++ /dev/null
@@ -1,517 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-#ifndef GENLIB_NET_HTTP_HTTPPARSER_H
-#define GENLIB_NET_HTTP_HTTPPARSER_H
-
-#include "util.h"
-#include "membuffer.h"
-#include "uri.h"
-
-#include "LinkedList.h"
-
-////// private types ////////////
-
-
-//////////////////////
-// scanner
-///////////////////////
-// Used to represent different types of tokens in input
-typedef enum // token_type_t
-{
-	TT_IDENTIFIER, 
-	TT_WHITESPACE, 
-	TT_CRLF, 
-	TT_CTRL,				// needed ??
-	TT_SEPARATOR,			// ??
-	TT_QUOTEDSTRING,		// ??
-} token_type_t;
-
-typedef struct // scanner_t
-{
-	membuffer* msg;				// raw http msg
-	size_t cursor;				// current position in buffer
-	xboolean entire_msg_loaded;	// set this to TRUE if the entire msg is loaded in
-								//   in 'msg'; else FALSE if only partial msg in 'msg'
-								//   (default is FALSE)
-} scanner_t;
-
-typedef enum // parser_pos_t
-{
-	POS_REQUEST_LINE,
-	POS_RESPONSE_LINE,
-	POS_HEADERS,
-	POS_ENTITY,
-	POS_COMPLETE,
-} parser_pos_t;
-
-
-#define ENTREAD_DETERMINE_READ_METHOD	1
-#define ENTREAD_USING_CLEN				2
-#define ENTREAD_USING_CHUNKED			3
-#define ENTREAD_UNTIL_CLOSE				4
-#define ENTREAD_CHUNKY_BODY				5
-#define ENTREAD_CHUNKY_HEADERS			6
-
-
-// end of private section
-//////////////////
-// ##################################################################################
-
-// method in a HTTP request
-typedef enum // http_method_t
-{
-	HTTPMETHOD_POST, 
-	HTTPMETHOD_MPOST, 
-	HTTPMETHOD_SUBSCRIBE, 
-	HTTPMETHOD_UNSUBSCRIBE, 
-	HTTPMETHOD_NOTIFY, 
-	HTTPMETHOD_GET,
-	HTTPMETHOD_HEAD, 
-	HTTPMETHOD_MSEARCH, 
-	HTTPMETHOD_UNKNOWN,
-    SOAPMETHOD_POST,	 //murari
-	HTTPMETHOD_SIMPLEGET
-} http_method_t;
-
-// different types of HTTP headers
-#define HDR_UNKNOWN				-1
-#define HDR_CACHE_CONTROL		1
-#define HDR_CALLBACK			2
-#define HDR_CONTENT_LENGTH		3
-#define HDR_CONTENT_TYPE		4
-#define HDR_DATE				5
-#define HDR_EXT					6
-#define HDR_HOST				7
-//#define HDR_IF_MODIFIED_SINCE	8
-//#define HDR_IF_UNMODIFIED_SINCE	9
-//#define HDR_LAST_MODIFIED		10
-#define HDR_LOCATION			11
-#define HDR_MAN					12
-#define HDR_MX					13
-#define HDR_NT					14
-#define HDR_NTS					15
-#define HDR_SERVER				16
-#define HDR_SEQ					17
-#define HDR_SID					18
-#define HDR_SOAPACTION			19
-#define HDR_ST					20
-#define HDR_TIMEOUT				21
-#define HDR_TRANSFER_ENCODING	22
-#define HDR_USN					23
-#define HDR_USER_AGENT			24
-
-//Adding new header difinition//Beg_Murari
-#define HDR_ACCEPT              25
-#define HDR_ACCEPT_ENCODING     26
-#define HDR_ACCEPT_CHARSET      27
-#define HDR_ACCEPT_LANGUAGE     28
-#define HDR_ACCEPT_RANGE        29
-#define HDR_CONTENT_ENCODING    30
-#define HDR_CONTENT_LANGUAGE    31
-#define HDR_CONTENT_LOCATION    32
-#define HDR_CONTENT_RANGE       33
-#define HDR_IF_RANGE            34
-#define HDR_RANGE               35
-#define HDR_TE                  36
-//End_Murari
-
-// status of parsing
-typedef enum // parse_status_t
-{
-	PARSE_SUCCESS = 0,	// msg was parsed successfully
-	PARSE_INCOMPLETE,	// need more data to continue
-	PARSE_INCOMPLETE_ENTITY,	// for responses that don't have length specified
-	PARSE_FAILURE,		// parse failed; check status code for details
-	PARSE_OK,			// done partial
-	PARSE_NO_MATCH,		// token not matched
-
-	// private
-	PARSE_CONTINUE_1
-} parse_status_t;
-
-typedef struct // http_header_t
-{
-	memptr name;		// header name as a string
-	int name_id;		// header name id (for a selective group of headers only)
-	membuffer value;	// raw-value; could be multi-lined; min-length = 0
-
-    // private
-    membuffer name_buf;
-} http_header_t;
-
-typedef struct // http_message_t
-{
-    int initialized;
-	// request only
-	http_method_t method;
-	uri_type uri;
-
-	// response only
-	http_method_t request_method;
-	int status_code;
-	membuffer status_msg;
-
-	// fields used in both request or response messages
-	xboolean is_request;	// if TRUE, msg is a request, else response
-
-	int major_version;		// http major.minor version
-	int minor_version;
-
-
-	LinkedList headers;
-//NNS:	dlist headers;			// dlist<http_header_t *>
-	memptr entity;			// message body(entity)
-
-	// private fields
-	membuffer msg;		// entire raw message
-	char *urlbuf;	// storage for url string
-} http_message_t;
-
-typedef struct // http_parser_t
-{
-	http_message_t msg;
-	int http_error_code;	// read-only; in case of parse error, this
-							//  contains the HTTP error code (4XX or 5XX)
-
-    // read-only; this is set to true if a NOTIFY request has no content-length.
-    //  used to read valid sspd notify msg.
-    xboolean valid_ssdp_notify_hack;
-
-	// private data -- don't touch
-	parser_pos_t position;
-	int ent_position;
-	off_t content_length;
-	int chunk_size;
-	size_t entity_start_position;
-	scanner_t scanner;
-} http_parser_t;
-
-
-//--------------------------------------------------
-//////////////// functions /////////////////////////
-//--------------------------------------------------
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-
-/************************************************************************
-*	Function :	httpmsg_init
-*
-*	Parameters :
-*		INOUT http_message_t* msg ;	HTTP Message Object
-*
-*	Description :	Initialize and allocate memory for http message
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void httpmsg_init( INOUT http_message_t* msg );
-
-/************************************************************************
-*	Function :	httpmsg_destroy
-*
-*	Parameters :
-*		INOUT http_message_t* msg ;	HTTP Message Object
-*
-*	Description :	Free memory allocated for the http message
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void httpmsg_destroy( INOUT http_message_t* msg );
-
-/************************************************************************
-*	Function :	httpmsg_find_hdr_str
-*
-*	Parameters :
-*		IN http_message_t* msg ;	HTTP Message Object
-*		IN const char* header_name ; Header name to be compared with	
-*
-*	Description :	Compares the header name with the header names stored 
-*		in	the linked list of messages
-*
-*	Return : http_header_t* - Pointer to a header on success;
-*			 NULL on failure														
-*
-*	Note :
-************************************************************************/
-http_header_t* httpmsg_find_hdr_str( IN http_message_t* msg,
-			IN const char* header_name );
-
-/************************************************************************
-*	Function :	httpmsg_find_hdr
-*
-*	Parameters :
-*		IN http_message_t* msg ; HTTP Message Object
-*		IN int header_name_id ;	 Header Name ID to be compared with
-*		OUT memptr* value ;		 Buffer to get the ouput to.
-*
-*	Description :	Finds header from a list, with the given 'name_id'.
-*
-*	Return : http_header_t*  - Pointer to a header on success;										*
-*			 NULL on failure														
-*
-*	Note :
-************************************************************************/
-http_header_t* httpmsg_find_hdr( IN http_message_t* msg, 
-			IN int header_name_id, OUT memptr* value );
-
-/************************************************************************
-* Function: parser_request_init											
-*																		
-* Parameters:															
-*	OUT http_parser_t* parser ; HTTP Parser object									
-*																
-* Description: Initializes parser object for a request					
-*																		
-* Returns:																
-*	 void																
-************************************************************************/
-void parser_request_init( OUT http_parser_t* parser );
-
-/************************************************************************
-* Function: parser_response_init										
-*																		
-* Parameters:															
-*	OUT http_parser_t* parser	;	  HTTP Parser object
-*	IN http_method_t request_method	; Request method 					
-*																		
-* Description: Initializes parser object for a response					
-*																		
-* Returns:																
-*	 void																
-************************************************************************/
-void parser_response_init( OUT http_parser_t* parser, 
-			   IN http_method_t request_method );
-
-/************************************************************************
-* Function: parser_parse												
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser ; HTTP Parser object					
-*																		
-* Description: The parser function. Depending on the position of the 	
-*	parser object the actual parsing function is invoked				
-*																		
-* Returns:																
-*	 void																
-************************************************************************/
-parse_status_t parser_parse(INOUT http_parser_t * parser);
-
-/************************************************************************
-* Function: parser_parse_responseline									
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser	; HTTP Parser object					
-*																		
-* Description: Get HTTP Method, URL location and version information.	
-*																		
-* Returns:																
-*	PARSE_OK															
-*	PARSE_SUCCESS														
-*	PARSE_FAILURE														
-************************************************************************/
-parse_status_t parser_parse_responseline(INOUT http_parser_t *parser);
-
-/************************************************************************
-* Function: parser_parse_headers									
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser	; HTTP Parser object										
-*													
-* Description: Get HTTP Method, URL location and version information.	
-*																		
-* Returns:																
-*	PARSE_OK															
-*	PARSE_SUCCESS														
-*	PARSE_FAILURE														
-************************************************************************/
-parse_status_t parser_parse_headers(INOUT http_parser_t *parser);
-
-/************************************************************************
-* Function: parser_parse_entity											
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser	; HTTP Parser object					
-*																		
-* Description: Determines method to read entity							
-*																		
-* Returns:																
-*	 PARSE_OK															
-* 	 PARSE_FAILURE														
-*	 PARSE_COMPLETE	-- no more reading to do							
-************************************************************************/
-parse_status_t parser_parse_entity(INOUT http_parser_t *parser);
-
-/************************************************************************
-* Function: parser_get_entity_read_method								
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser	; HTTP Parser object					
-*																		
-* Description: Determines method to read entity							
-*																		
-* Returns:																
-*	 PARSE_OK															
-* 	 PARSE_FAILURE														
-*	 PARSE_COMPLETE	-- no more reading to do							
-************************************************************************/
-parse_status_t parser_get_entity_read_method( INOUT http_parser_t* parser );
-
-/************************************************************************
-* Function: parser_append												
-*																		
-* Parameters:															
-*	INOUT http_parser_t* parser ;	HTTP Parser Object					
-*	IN const char* buf	;			buffer to be appended to the parser 
-*									buffer							
-*	IN size_t buf_length ;			Size of the buffer												
-*																		
-* Description: The parser function. Depending on the position of the 	
-*	parser object the actual parsing function is invoked				
-*																		
-* Returns:																
-*	 void																
-************************************************************************/
-parse_status_t parser_append( INOUT http_parser_t* parser, 
-				 IN const char* buf,
-				 IN size_t buf_length );
-
-/************************************************************************
-* Function: matchstr													
-*																		
-* Parameters:															
-*	IN char *str ;		 String to be matched														
-*	IN size_t slen ;     Length of the string														
-*	IN const char* fmt ; Pattern format												
-*	...																	
-*																		
-* Description: Matches a variable parameter list with a string			
-*	and takes actions based on the data type specified.					
-*																		
-* Returns:																
-*   PARSE_OK															
-*   PARSE_NO_MATCH -- failure to match pattern 'fmt'					
-*   PARSE_FAILURE	-- 'str' is bad input							
-************************************************************************/
-int matchstr( IN char *str, IN size_t slen, IN const char* fmt, ... );
-
-// ====================================================
-// misc functions
-
-
-/************************************************************************
-* Function: raw_to_int													
-*																		
-* Parameters:															
-*	IN memptr* raw_value ;	Buffer to be converted 					
-*	IN int base ;			Base  to use for conversion
-*																		
-* Description: Converts raw character data to long-integer value					
-*																		
-* Returns:																
-*	 off_t																
-************************************************************************/
-off_t raw_to_int( IN memptr* raw_value, int base );
-
-/************************************************************************
-* Function: raw_find_str												
-*																		
-* Parameters:															
-*	IN memptr* raw_value ; Buffer containg the string												
-*	IN const char* str ;	Substring to be found													
-*																		
-* Description: Find a substring from raw character string buffer					
-*																		
-* Returns:																
-*	 int - index at which the substring is found.						
-************************************************************************/
-int raw_find_str( IN memptr* raw_value, IN const char* str );
-
-/************************************************************************
-* Function: method_to_str												
-*																		
-* Parameters:															
-* IN http_method_t method ; HTTP method						
-*																		
-* Description: A wrapper function that maps a method id to a method		
-*	nameConverts a http_method id stored in the HTTP Method				
-*																		
-* Returns:																
-*	 const char* ptr - Ptr to the HTTP Method																							*
-************************************************************************/
-const char* method_to_str( IN http_method_t method );
-
-/************************************************************************
-* Function: print_http_headers											
-*																		
-* Parameters:															
-*	http_message_t* hmsg ; HTTP Message object									
-*																		
-* Description:															
-*																		
-* Returns:																
-*	 void																
-************************************************************************/
-void print_http_headers( IN http_message_t* hmsg );
-
-#ifdef __cplusplus
-}		// extern "C"
-#endif	// __cplusplus
-
-
-#endif // GENLIB_NET_HTTP_HTTPPARSER_H
diff --git a/tombupnp/upnp/src/inc/httpreadwrite.h b/tombupnp/upnp/src/inc/httpreadwrite.h
deleted file mode 100644
index d80e601..0000000
--- a/tombupnp/upnp/src/inc/httpreadwrite.h
+++ /dev/null
@@ -1,607 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-#ifndef GENLIB_NET_HTTP_HTTPREADWRITE_H
-#define GENLIB_NET_HTTP_HTTPREADWRITE_H
-
-#include "config.h"
-#include "util.h"
-#include "sock.h"
-#include "httpparser.h"
-
-// timeout in secs
-#define HTTP_DEFAULT_TIMEOUT	30
-
-
-
-#ifdef __cplusplus
-#extern "C" {
-#endif
-
-int
-http_CancelHttpGet( IN void *Handle );
-
-/************************************************************************
-* Function: http_FixUrl													
-*																		
-* Parameters:															
-*	IN uri_type* url ;			URL to be validated and fixed
-*	OUT uri_type* fixed_url ;	URL after being fixed.
-*																		
-* Description: Validates URL											
-*																		
-* Returns:																
-*	 UPNP_E_INVALID_URL													
-* 	 UPNP_E_SUCCESS														
-************************************************************************/
-int http_FixUrl( IN uri_type* url, OUT uri_type* fixed_url );
-
-/************************************************************************
-* Function: http_FixStrUrl												
-*																		
-* Parameters:															
-*	IN char* urlstr ; 			Character string as a URL				
-*	IN int urlstrlen ; 			Length of the character string								
-*	OUT uri_type* fixed_url	;	Fixed and corrected URL
-*																		
-* Description: Parses URL and then validates URL						
-*																		
-* Returns:																
-*	 UPNP_E_INVALID_URL													
-* 	 UPNP_E_SUCCESS														
-************************************************************************/
-int http_FixStrUrl( IN char* urlstr, IN int urlstrlen, OUT uri_type* fixed_url );
-
-
-/************************************************************************
-* Function: http_Connect												
-*																		
-* Parameters:															
-*	IN uri_type* destination_url ; URL containing destination information					
-*	OUT uri_type *url ;			   Fixed and corrected URL
-*																		
-* Description: Gets destination address from URL and then connects to the 
-*	remote end
-*																		
-* Returns:																
-*	socket descriptor on sucess											
-*	UPNP_E_OUTOF_SOCKET													
-*	UPNP_E_SOCKET_CONNECT on error										
-************************************************************************/
-int http_Connect( IN uri_type* destination_url, OUT uri_type *url );
-
-/************************************************************************
-* Function: http_RecvMessage											
-*																		
-* Parameters:															
-*	IN SOCKINFO *info ;					Socket information object
-*	OUT http_parser_t* parser,			HTTP parser object
-*	IN http_method_t request_method ;	HTTP request method					
-*	IN OUT int* timeout_secs ;			time out											
-*	OUT int* http_error_code ;			HTTP error code returned
-*																		
-* Description: Get the data on the socket and take actions based on the 
-*	read data to modify the parser objects buffer. If an error is reported 
-*	while parsing the data, the error code is passed in the http_errr_code 
-*	parameter
-*																		
-* Returns:																
-*	 UPNP_E_BAD_HTTPMSG													
-* 	 UPNP_E_SUCCESS														
-************************************************************************/
-int http_RecvMessage( IN SOCKINFO *info, OUT http_parser_t* parser,
-		IN http_method_t request_method, 
-		IN OUT int* timeout_secs,
-		OUT int* http_error_code );
-
-
-/************************************************************************
-* Function: http_SendMessage											
-*																		
-* Parameters:															
-*	IN SOCKINFO *info ;		Socket information object
-*	IN OUT int * TimeOut ; 	time out value											
-*	IN const char* fmt, ...	 Pattern format to take actions upon								
-*																		
-* Description: Sends a message to the destination based on the			
-*	IN const char* fmt parameter										
-*	fmt types:															
-*		'f':	arg = const char * file name							
-*		'm':	arg1 = const char * mem_buffer; arg2= size_t buf_length	
-*	E.g.:																
-*		char *buf = "POST /xyz.cgi http/1.1\r\n\r\n";					
-*		char *filename = "foo.dat";										
-*		int status = http_SendMessage( tcpsock, "mf",					
-*					buf, strlen(buf),	// args for memory buffer		
-*					filename );			// arg for file					
-*																		
-* Returns:																
-*	UPNP_E_OUTOF_MEMORY													
-* 	UPNP_E_FILE_READ_ERROR												
-*	UPNP_E_SUCCESS														
-************************************************************************/
-int http_SendMessage( IN SOCKINFO *info, IN OUT int* timeout_secs, 
-					  IN const char* fmt, ... );
-
-/************************************************************************
-* Function: http_RequestAndResponse										
-*																		
-* Parameters:															
-*	IN uri_type* destination ;		Destination URI object which contains 
-*									remote IP address among other elements
-*	IN const char* request ;		Request to be sent
-*	IN size_t request_length ;		Length of the request
-*	IN http_method_t req_method ;	HTTP Request method
-*	IN int timeout_secs ;			time out value
-*	OUT http_parser_t* response	;	Parser object to receive the repsonse
-*																		
-* Description: Initiates socket, connects to the destination, sends a	
-*	request and waits for the response from the remote end				
-*																		
-* Returns:																
-*	UPNP_E_SOCKET_ERROR													
-* 	UPNP_E_SOCKET_CONNECT												
-*	Error Codes returned by http_SendMessage							
-*	Error Codes returned by http_RecvMessage							
-************************************************************************/
-int http_RequestAndResponse( IN uri_type* destination,
-						   IN const char* request, IN size_t request_length,
-						   IN http_method_t req_method,
-						   IN int timeout_secs, 
-						   OUT http_parser_t* response );
-
-/************************************************************************
-*  return codes:
-*		0 -- success
-*		UPNP_E_OUTOF_MEMORY
-*		UPNP_E_TIMEDOUT
-*		UPNP_E_BAD_REQUEST
-*		UPNP_E_BAD_RESPONSE
-*		UPNP_E_INVALID_URL
-*		UPNP_E_SOCKET_READ
-*		UPNP_E_SOCKET_WRITE
-************************************************************************/
-
-/************************************************************************
-*	Function :	http_Download
-*
-*	Parameters :
-*		IN const char* url_str :	String as a URL
-*		IN int timeout_secs :		time out value
-*		OUT char** document :		buffer to store the document extracted
-*									from the donloaded message.
-*		OUT int* doc_length :		length of the extracted document
-*	    OUT char* content_type :	Type of content
-*
-*	Description :	Download the document message and extract the document 
-*		from the message.
-*
-*	Return : int;
-*		UPNP_E_SUCCESS;
-*		UPNP_E_INVALID_URL;
-*			
-*
-*	Note :
-************************************************************************/
-int http_Download( IN const char* url, 
-				   IN int timeout_secs,
-				   OUT char** document, OUT int* doc_length,
-				   OUT char* content_type );
-
-
-/************************************************************************
-*	Function :	http_WriteHttpPost
-*
-*	Parameters :
-*		IN void *Handle :		Handle to the http post object
-*		IN char *buf :			Buffer to send to peer, if format used
-*								is not UPNP_USING_CHUNKED, 
-*		IN off_t *size :	Size of the data to be sent.
-*		IN int timeout :		time out value
-*
-*	Description :	Formats data if format used is UPNP_USING_CHUNKED.
-*		Writes data on the socket connected to the peer.
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Success
-*		UPNP_E_INVALID_PARAM - Invalid Parameter
-*		-1 - On Socket Error.
-*
-*	Note :
-************************************************************************/
-int http_WriteHttpPost(IN void *Handle,
-		       IN char *buf,
-		       IN off_t *size,
-		       IN int timeout);
-
-/************************************************************************
-*	Function :	http_CloseHttpPost
-*
-*	Parameters :
-*		IN void *Handle :			Handle to the http post object
-*		IN OUT int *httpStatus :	HTTP status returned on receiving a
-*									response message
-*		IN int timeout :			time out value
-*
-*	Description :	Sends remaining data if using  UPNP_USING_CHUNKED 
-*		format. Receives any more messages. Destroys socket and any socket
-*		associated memory. Frees handle associated with the HTTP POST msg.
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Sucess ;
-*		UPNP_E_INVALID_PARAM  - Invalid Parameter;
-*
-*	Note :
-************************************************************************/
-int http_CloseHttpPost(IN void *Handle, 
-		       IN OUT int *httpStatus,
-		       IN int timeout);
-
-/************************************************************************
-*	Function :	http_OpenHttpPost
-*
-*	Parameters :
-*		IN const char *url_str :		String as a URL	
-*		IN OUT void **Handle :			Pointer to buffer to store HTTP
-*										post handle
-*		IN const char *contentType :	Type of content
-*		IN off_t contentLength :			length of content
-*		IN int timeout :				time out value
-*
-*	Description :	Makes the HTTP POST message, connects to the peer, 
-*		sends the HTTP POST request. Adds the post handle to buffer of 
-*		such handles
-*
-*	Return : int;
-*		UPNP_E_SUCCESS - On Sucess ;
-*		UPNP_E_INVALID_PARAM - Invalid Paramter ;
-*		UPNP_E_OUTOF_MEMORY ;
-*		UPNP_E_SOCKET_ERROR ;
-*		UPNP_E_SOCKET_CONNECT ;
-*
-*	Note :
-************************************************************************/
-int http_OpenHttpPost(IN const char *url_str,
-		      IN OUT void **Handle,
-		      IN const char *contentType,
-		      IN off_t contentLength,
-		      IN int timeout);
-
-/************************************************************************
-*	Function :	http_ReadHttpGet
-*
-*	Parameters :
-*		IN void *Handle :			Handle to the HTTP get object
-*		IN OUT char *buf :			Buffer to get the read and parsed data
-*		IN OUT off_t *size :	Size of tge buffer passed
-*		IN int timeout :			time out value
-*
-*	Description :	Parses already existing data, then gets new data.
-*		Parses and extracts information from the new data.
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Sucess ;
-*		UPNP_E_INVALID_PARAM  - Invalid Parameter;
-*		UPNP_E_BAD_RESPONSE ;
-*		UPNP_E_BAD_HTTPMSG ;
-*
-*	Note :
-************************************************************************/
-int http_ReadHttpGet(IN void *Handle,
-					IN OUT char *buf,
-					IN OUT off_t *size,
-					IN int timeout);
-
-/************************************************************************
-*   Function :  http_HttpGetProgress
-*
-*   Parameters :
-*       IN void *Handle :           Handle to the HTTP get object
-*       OUT off_t *length :  Buffer to get the read and parsed data
-*       OUT off_t *total :   Size of tge buffer passed
-*
-*   Description :   Extracts information from the Handle to the HTTP get
-*                   object.
-*
-*   Return : int ;
-*       UPNP_E_SUCCESS - On Sucess ;
-*       UPNP_E_INVALID_PARAM  - Invalid Parameter;
-*
-*   Note :
-************************************************************************/
-int http_HttpGetProgress(IN void *Handle,
-						OUT off_t *length,
-						OUT off_t *total );
-
-/************************************************************************
-*	Function :	http_CloseHttpGet
-*
-*	Parameters :
-*		IN void *Handle ;	Handle to HTTP get object
-*
-*	Description :	Clears the handle allocated for the HTTP GET operation
-*		Clears socket states and memory allocated for socket operations. 
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Success
-*		UPNP_E_INVALID_PARAM - Invalid Parameter
-*
-*	Note :
-************************************************************************/
-int http_CloseHttpGet(IN void *Handle);
-
-/************************************************************************
-*	Function :	http_OpenHttpGet
-*
-*	Parameters :
-*		IN const char *url_str :	String as a URL
-*		IN OUT void **Handle :		Pointer to buffer to store HTTP
-*									post handle
-*		IN OUT char **contentType :	Type of content
-*		OUT off_t *contentLength :	length of content
-*		OUT int *httpStatus :		HTTP status returned on receiving a
-*									response message
-*		IN int timeout :			time out value
-*
-*	Description :	Makes the HTTP GET message, connects to the peer, 
-*		sends the HTTP GET request, gets the response and parses the 
-*		response.
-*
-*	Return : int;
-*		UPNP_E_SUCCESS - On Success ;
-*		UPNP_E_INVALID_PARAM - Invalid Paramters ;
-*		UPNP_E_OUTOF_MEMORY ;
-*		UPNP_E_SOCKET_ERROR ;
-*		UPNP_E_BAD_RESPONSE ;
-*
-*	Note :
-*
-************************************************************************/
-int http_OpenHttpGet(IN const char *url_str,
-					IN OUT void **Handle,
-					IN OUT char **contentType,
-					OUT off_t *contentLength,
-					OUT int *httpStatus,
-					IN int timeout);
-
-/************************************************************************
-*	Function :	http_OpenHttpGetProxy
-*
-*	Parameters :
-*		IN const char *url_str :	String as a URL
-*		IN const char *proxy_str :	String as a URL to the proxy
-*		IN OUT void **Handle :		Pointer to buffer to store HTTP
-*									post handle
-*		IN OUT char **contentType :	Type of content
-*		OUT off_t *contentLength :	length of content
-*		OUT int *httpStatus :		HTTP status returned on receiving a
-*									response message
-*		IN int timeout :			time out value
-*
-*	Description :	Makes the HTTP GET message, connects to the peer, 
-*		sends the HTTP GET request, gets the response and parses the 
-*		response.
-*
-*	Return : int;
-*		UPNP_E_SUCCESS - On Success ;
-*		UPNP_E_INVALID_PARAM - Invalid Paramters ;
-*		UPNP_E_OUTOF_MEMORY ;
-*		UPNP_E_SOCKET_ERROR ;
-*		UPNP_E_BAD_RESPONSE ;
-*
-*	Note :
-*
-************************************************************************/
-int http_OpenHttpGetProxy(IN const char *url_str,
-					IN const char *proxy_str,
-					IN OUT void **Handle,
-					IN OUT char **contentType,
-					OUT off_t *contentLength,
-					OUT int *httpStatus,
-					IN int timeout);
-
-
-/************************************************************************
-*	Function :	http_SendStatusResponse
-*
-*	Parameters :
-*		IN SOCKINFO *info :				Socket information object
-*		IN int http_status_code :		error code returned while making 
-*										or sending the response message
-*		IN int request_major_version :	request major version
-*		IN int request_minor_version :	request minor version
-*
-*	Description :	Generate a response message for the status query and
-*		send the status response.
-*
-*	Return : int;
-*		0 -- success
-*		UPNP_E_OUTOF_MEMORY
-*		UPNP_E_SOCKET_WRITE
-*		UPNP_E_TIMEDOUT
-*
-*	Note :
-************************************************************************/
-int http_SendStatusResponse( IN SOCKINFO *info, IN int http_status_code,
-						  IN int request_major_version,
-						  IN int request_minor_version );
-
-
-/************************************************************************
-*	Function :	http_MakeMessage
-*
-*	Parameters :
-*		INOUT membuffer* buf :		buffer with the contents of the 
-*									message
-*		IN int http_major_version :	HTTP major version
-*		IN int http_minor_version :	HTTP minor version
-*		IN const char* fmt :		Pattern format 
-*		... :	
-*
-*	Description :	Generate an HTTP message based on the format that is 
-*		specified in the input parameters.
-*
-*		fmt types:
-*		's':	arg = const char* C_string
-*		'b':	arg1 = const char* buf; arg2 = size_t buf_length 
-*				memory ptr
-*		'c':	(no args) appends CRLF "\r\n"
-*		'd':	arg = int number		// appends decimal number
-*		'h':	arg = off_t number		// appends off_t number
-*		't':	arg = time_t * gmt_time	// appends time in RFC 1123 fmt
-*		'D':	(no args) appends HTTP DATE: header
-*		'S':	(no args) appends HTTP SERVER: header
-*		'U':	(no args) appends HTTP USER-AGENT: header
-*		'C':	(no args) appends a HTTP CONNECTION: close header 
-*				depending on major,minor version
-*		'N':	arg1 = off_t content_length	// content-length header
-*		'Q':	arg1 = http_method_t; arg2 = char* url; 
-*				arg3 = int url_length // start line of request
-*		'R':	arg = int status_code // adds a response start line
-*		'B':	arg = int status_code 
-*				appends content-length, content-type and HTML body for given code
-*		'T':	arg = char * content_type; format e.g: "text/html";	
-*				 content-type header
-*       'H':    arg = *userHTTPHeaderList
-*       'A':    arg = const char* C_string
-*               adds a custom HTTP header to a specific response (filled out
-*               by the user in the File_Info struct), may be NULL
-*
-*	Return : int;
-*		0 - On Success
-*		UPNP_E_OUTOF_MEMORY
-*		UPNP_E_INVALID_URL;
-*
-*	Note :
-************************************************************************/
-int http_MakeMessage( INOUT membuffer* buf, 
-			IN int http_major_version,
-			IN int http_minor_version,
-			IN const char* fmt, ... );
-
-/************************************************************************
-*	Function :	http_CalcResponseVersion
-*
-*	Parameters :
-*		IN int request_major_vers :		Request major version
-*		IN int request_minor_vers :		Request minor version
-*		OUT int* response_major_vers :	Response mojor version
-*		OUT int* response_minor_vers :	Response minor version
-*
-*	Description :	Calculate HTTP response versions based on the request
-*		versions.
-*
-*	Return :	void
-*
-*	Note :
-************************************************************************/
-void http_CalcResponseVersion( 
-		IN int request_major_vers, IN int request_minor_vers,
-		OUT int* response_major_vers, OUT int* response_minor_vers );
-
-/************************************************************************
-*	Function :	http_OpenHttpGetEx
-*
-*	Parameters :
-*		IN const char *url_str :	String as a URL
-*		IN OUT void **Handle :		Pointer to buffer to store HTTP
-*									post handle
-*		IN OUT char **contentType :	Type of content
-*		OUT off_t *contentLength :	length of content
-*		OUT int *httpStatus :		HTTP status returned on receiving a
-*									response message
-*		IN int timeout :			time out value
-*
-*	Description :	Makes the HTTP GET message, connects to the peer, 
-*		sends the HTTP GET request, gets the response and parses the 
-*		response.
-*
-*	Return : int;
-*		UPNP_E_SUCCESS - On Success ;
-*		UPNP_E_INVALID_PARAM - Invalid Paramters ;
-*		UPNP_E_OUTOF_MEMORY ;
-*		UPNP_E_SOCKET_ERROR ;
-*		UPNP_E_BAD_RESPONSE ;
-*
-*	Note :
-*
-************************************************************************/
-int http_OpenHttpGetEx(IN const char *url_str,
-		     IN OUT void **Handle,
-		     IN OUT char **contentType,
-		     OUT off_t *contentLength,
-		     OUT int *httpStatus,
-			 IN int lowRange,
-			 IN int highRange,
-		     IN int timeout);
-
-/************************************************************************
-*	Function :	get_sdk_info
-*
-*	Parameters :
-*		OUT char *info ;	
-*
-*	Description :	Returns the server information for the operating 
-*		system
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void get_sdk_info( OUT char *info );
-
-#ifdef __cplusplus
-}	// #extern "C"
-#endif
-
-
-#endif // GENLIB_NET_HTTP_HTTPREADWRITE_H
diff --git a/tombupnp/upnp/src/inc/inet_pton.h b/tombupnp/upnp/src/inc/inet_pton.h
deleted file mode 100644
index ba91c34..0000000
--- a/tombupnp/upnp/src/inc/inet_pton.h
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifdef WIN32
-#ifndef INET_PTON
-#define INET_PTON
-
-#include <winsock2.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-typedef int socklen_t;
-#define EAFNOSUPPORT 97
-
-/*
- * WARNING: Don't even consider trying to compile this on a system where
- * sizeof(int) < 4.  sizeof(int) 4 is fine; all the world's not a VAX.
- */
-
-/* const char *
- * inet_ntop4(src, dst, size)
- *	format an IPv4 address
- * return:
- *	`dst' (as a const)
- * notes:
- *	(1) uses no statics
- *	(2) takes a u_char* not an in_addr as input
- * author:
- *	Paul Vixie, 1996.
- */
-extern const char * inet_ntop4(const u_char src, char *dst, socklen_t size);
-
-/* const char *
- * inet_ntop6(src, dst, size)
- *	convert IPv6 binary address into presentation (printable) format
- * author:
- *	Paul Vixie, 1996.
- */
-
-#ifdef INET_IPV6
-
-extern const char * inet_ntop6(src, dst, size);
-
-#endif /* INET_IPV6 */
-
-/* int
- * inet_pton4(src, dst)
- *	like inet_aton() but without all the hexadecimal and shorthand.
- * return:
- *	1 if `src' is a valid dotted quad, else 0.
- * notice:
- *	does not touch `dst' unless it's returning 1.
- * author:
- *	Paul Vixie, 1996.
- */
-extern inet_pton4(const char *src,u_char *dst);
-
-/* int
- * inet_pton6(src, dst)
- *	convert presentation level address to network order binary form.
- * return:
- *	1 if `src' is a valid [RFC1884 2.2] address, else 0.
- * notice:
- *	(1) does not touch `dst' unless it's returning 1.
- *	(2) :: in a full address is silently ignored.
- * credit:
- *	inspired by Mark Andrews.
- * author:
- *	Paul Vixie, 1996.
- */
-
-#ifdef INET_IPV6
-
-extern int inet_pton6(src, dst);
-
-#endif /* INET_IPV6 */
-
-
-
-/* char *
- * inet_ntop(af, src, dst, size)
- *	convert a network format address to presentation format.
- * return:
- *	pointer to presentation format address (`dst'), or NULL (see errno).
- * author:
- *	Paul Vixie, 1996.
- */
-extern const char *inet_ntop(int af,const void *src,char *dst,socklen_t size);
-
-
-/* int
- * inet_pton(af, src, dst)
- *	convert from presentation format (which usually means ASCII printable)
- *	to network format (which is usually some kind of binary format).
- * return:
- *	1 if the address was valid for the specified address family
- *	0 if the address wasn't valid (`dst' is untouched in this case)
- *	-1 if some other error occurred (`dst' is untouched in this case, too)
- * author:
- *	Paul Vixie, 1996.
- */
-extern int inet_pton(int af,const char *src,void *dst);
-
-#endif
-#endif
diff --git a/tombupnp/upnp/src/inc/membuffer.h b/tombupnp/upnp/src/inc/membuffer.h
deleted file mode 100644
index c9a61c9..0000000
--- a/tombupnp/upnp/src/inc/membuffer.h
+++ /dev/null
@@ -1,345 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef GENLIB_UTIL_MEMBUFFER_H
-#define GENLIB_UTIL_MEMBUFFER_H
-
-
-#include <stdlib.h>
-#include "util.h"
-
-#define MINVAL( a, b ) ( (a) < (b) ? (a) : (b) )
-#define MAXVAL( a, b ) ( (a) > (b) ? (a) : (b) )
-
-// pointer to a chunk of memory
-typedef struct // memptr
-{
-	char	*buf;			// start of memory (read/write)
-	size_t	length;			// length of memory (read-only)
-} memptr;
-
-
-// maintains a block of dynamically allocated memory
-// note: Total length/capacity should not exceed MAX_INT
-typedef struct // membuffer
-{
-	char	*buf;			// mem buffer; must not write 
-							//   beyond buf[length-1] (read/write)
-	size_t	length;			// length of buffer (read-only)
-	size_t	capacity;		// total allocated memory (read-only)
-	size_t	size_inc;		// used to increase size; MUST be > 0; (read/write)
-
-	// default value of size_inc
-	#define MEMBUF_DEF_SIZE_INC		5
-} membuffer;
-
-//--------------------------------------------------
-//////////////// functions /////////////////////////
-//--------------------------------------------------
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-/************************************************************************
-*	Function :	str_alloc
-*
-*	Parameters :
-*		IN const char* str ;	input string object
-*		IN size_t str_len ;		input string length
-*
-*	Description :	Allocate memory and copy information from the input 
-*		string to the newly allocated memory.
-*
-*	Return : char* ;
-*		Pointer to the newly allocated memory.
-*		NULL if memory cannot be allocated.
-*
-*	Note :
-************************************************************************/
-char* str_alloc( IN const char* str, IN size_t str_len );
-
-/************************************************************************
-*	Function :	memptr_cmp
-*
-*	Parameters :
-*		IN memptr* m ;	input memory object
-*		IN const char* s ;	constatnt string for the memory object to be 
-*					compared with
-*
-*	Description : Compares characters of strings passed for number of 
-*		bytes. If equal for the number of bytes, the length of the bytes 
-*		determines which buffer is shorter.
-*
-*	Return : int ;
-*		< 0 string1 substring less than string2 substring 
-*		0 string1 substring identical to string2 substring 
-*		> 0 string1 substring greater than string2 substring 
-*
-*	Note :
-************************************************************************/
-int memptr_cmp( IN memptr* m, IN const char* s );
-
-/************************************************************************
-*	Function :	memptr_cmp_nocase
-*
-*	Parameters :
-*		IN memptr* m ;	input memory object
-*		IN const char* s ;	constatnt string for the memory object to be 
-*					compared with
-*
-*	Description : Compares characters of 2 strings irrespective of the 
-*		case for a specific count of bytes  If the character comparison 
-*		is the same the length of the 2 srings determines the shorter 
-*		of the 2 strings.
-*
-*	Return : int ;
-*		< 0 string1 substring less than string2 substring 
-*		0 string1 substring identical to string2 substring 
-*		> 0 string1 substring greater than string2 substring 
-*  
-*	Note :
-************************************************************************/
-int memptr_cmp_nocase( IN memptr* m, IN const char* s );
-
-
-/************************************************************************
-*	Function :	membuffer_set_size
-*
-*	Parameters :
-*		INOUT membuffer* m ;	buffer whose size is to be modified
-*		IN size_t new_length ;	new size to which the buffer will be 
-*					modified
-*
-*	Description : Increases or decreases buffer cap so that at least
-*	   'new_length' bytes can be stored
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Success
-*		UPNP_E_OUTOF_MEMORY - On failure to allocate memory.
-*
-*	Note :
-************************************************************************/
-int membuffer_set_size( INOUT membuffer* m, 
-			IN size_t new_length );
-
-/************************************************************************
-*	Function :	membuffer_init
-*
-*	Parameters :
-*		INOUT membuffer* m ; buffer	to be initialized
-*
-*	Description : Wrapper to membuffer_initialize().
-*		Set the size of the buffer to MEMBUF_DEF_SIZE_INC
-*		Initializes m->buf to NULL, length=0
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void membuffer_init( INOUT membuffer* m );
-
-/************************************************************************
-*	Function :	membuffer_destroy
-*
-*	Parameters :
-*		INOUT membuffer* m ;	buffer to be destroyed
-*
-*	Description : Free's memory allocated for membuffer* m.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void membuffer_destroy( INOUT membuffer* m );
-
-
-/************************************************************************
-*	Function :	membuffer_assign
-*
-*	Parameters :
-*		INOUT membuffer* m ; buffer whose memory is to be allocated and 
-*					assigned.
-*		IN const void* buf ; source buffer whose contents will be copied
-*		IN size_t buf_len ;	 length of the source buffer
-*
-*	Description : Allocate memory to membuffer* m and copy the contents 
-*		of the in parameter IN const void* buf.
-*
-*	Return : int ;
-*	 UPNP_E_SUCCESS
-*	 UPNP_E_OUTOF_MEMORY
-*
-*	Note :
-************************************************************************/
-int membuffer_assign( INOUT membuffer* m, IN const void* buf, 
-					 IN size_t buf_len );
-
-/************************************************************************
-*	Function :	membuffer_assign_str
-*
-*	Parameters :
-*		INOUT membuffer* m ;	buffer to be allocated and assigned
-*		IN const char* c_str ;	source buffer whose contents will be 
-*					copied
-*
-*	Description : Wrapper function for membuffer_assign()
-*
-*	Return : int ;
-*	 UPNP_E_SUCCESS
-*	 UPNP_E_OUTOF_MEMORY
-*
-*	Note :
-************************************************************************/
-int membuffer_assign_str( INOUT membuffer* m, IN const char* c_str );
-
-/************************************************************************
-*	Function :	membuffer_append
-*
-*	Parameters :
-*		INOUT membuffer* m ; buffer whose memory is to be appended.
-*		IN const void* buf ; source buffer whose contents will be 
-*					copied
-*		IN size_t buf_len ;	length of the source buffer
-*
-*	Description : Invokes function to appends data from a constant buffer 
-*		to the buffer 
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int membuffer_append( INOUT membuffer* m, IN const void* buf,
-					 IN size_t buf_len );
-
-/************************************************************************
-*	Function :	membuffer_append_str
-*
-*	Parameters :
-*		INOUT membuffer* m ;	buffer whose memory is to be appended.
-*		IN const char* c_str ;	source buffer whose contents will be 
-*					copied
-*
-*	Description : Invokes function to appends data from a constant string 
-*		to the buffer 	
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int membuffer_append_str( INOUT membuffer* m, IN const char* c_str );
-
-/************************************************************************
-*	Function :	membuffer_insert
-*
-*	Parameters :
-*		INOUT membuffer* m ; buffer whose memory size is to be increased  
-*					and appended.
-*		IN const void* buf ; source buffer whose contents will be 
-*					copied
-*		 IN size_t buf_len ; size of the source buffer
-*		int index ;	index to determine the bounds while movinf the data
-*
-*	Description : Allocates memory for the new data to be inserted. Does
-*		memory management by moving the data from the existing memory to 
-*		the newly allocated memory and then appending the new data.
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int membuffer_insert( INOUT membuffer* m, IN const void* buf, 
-					 IN size_t buf_len, int index );
-
-
-/************************************************************************
-*	Function :	membuffer_delete
-*
-*	Parameters :
-*		INOUT membuffer* m ; buffer whose memory size is to be decreased
-*					and copied to the odified location
-*		IN int index ;	index to determine bounds while moving data
-*		IN size_t num_bytes ;	number of bytes that the data needs to 
-*					shrink by
-*
-*	Description : Shrink the size of the buffer depending on the current 
-*		size of the bufer and te input parameters. Move contents from the 
-*		old buffer to the new sized buffer.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void membuffer_delete( INOUT membuffer* m, IN int index, 
-					 IN size_t num_bytes );
-
-
-/************************************************************************
-*	Function :	membuffer_detach
-*
-*	Parameters :
-*		INOUT membuffer* m ; buffer to be returned and updated.	
-*
-*	Description : Detaches current buffer and returns it. The caller
-*		must free the returned buffer using free().
-*		After this call, length becomes 0.
-*
-*	Return : char* ;
-*		a pointer to the current buffer
-*
-*	Note :
-************************************************************************/
-char* membuffer_detach( INOUT membuffer* m );
-
-/************************************************************************
-*	Function :	membuffer_attach
-*
-*	Parameters :
-*		INOUT membuffer* m ;	buffer to be updated
-*		IN char* new_buf ;	 source buffer which will be assigned to the 
-*					buffer to be updated
-*		IN size_t buf_len ;	length of the source buffer 
-*
-*	Description : Free existing memory in membuffer and assign the new 
-*		buffer in its place.
-*
-*	Return : void ;
-*
-*	Note : 'new_buf' must be allocted using malloc or realloc so
-*		that it can be freed using free()
-************************************************************************/
-void membuffer_attach( INOUT membuffer* m, IN char* new_buf,
-					   IN size_t buf_len );
-#ifdef __cplusplus
-}		// extern "C"
-#endif	// __cplusplus
-
-#endif // GENLIB_UTIL_H
diff --git a/tombupnp/upnp/src/inc/miniserver.h b/tombupnp/upnp/src/inc/miniserver.h
deleted file mode 100644
index e546da8..0000000
--- a/tombupnp/upnp/src/inc/miniserver.h
+++ /dev/null
@@ -1,150 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef MINISERVER_H
-#define MINISERVER_H
-
-#include "sock.h"
-#include "httpparser.h"
-
-extern SOCKET gMiniServerStopSock;
-
-typedef struct MServerSockArray {
-  int miniServerSock;     //socket for listening for miniserver
-                          //requests
-  int miniServerStopSock; //socket for stopping miniserver 
-  int ssdpSock; //socket for incoming advertisments and search requests
-
-  int stopPort;
-  int miniServerPort;
-
-  CLIENTONLY(int ssdpReqSock;) //socket for sending search 
-       //requests and receiving
-       // search replies
-      
-} MiniServerSockArray;
-
-//typedef void (*MiniServerCallback) ( const char* document, int sockfd );
-
-typedef void (*MiniServerCallback) ( IN http_parser_t *parser,
-									 IN http_message_t* request, 
-									 IN SOCKINFO *info );
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/************************************************************************
-*	Function :	SetHTTPGetCallback
-*
-*	Parameters :
-*		MiniServerCallback callback ; - HTTP Callback to be invoked 
-*
-*	Description :	Set HTTP Get Callback
-*
-*	Return :	void
-*
-*	Note :
-************************************************************************/
-void SetHTTPGetCallback( MiniServerCallback callback );
-
-/************************************************************************
-*	Function :	SetSoapCallback
-*
-*	Parameters :
-*		MiniServerCallback callback ; - SOAP Callback to be invoked 
-*
-*	Description :	Set SOAP Callback
-*
-*	Return :	void
-*
-*	Note :
-************************************************************************/
-void SetSoapCallback( MiniServerCallback callback );
-
-/************************************************************************
-*	Function :	SetGenaCallback
-*
-*	Parameters :
-*		MiniServerCallback callback ; - GENA Callback to be invoked
-*
-*	Description :	Set GENA Callback
-*
-*	Return :	void
-*
-*	Note :
-************************************************************************/
-void SetGenaCallback( MiniServerCallback callback );
-
-/************************************************************************
-*	Function :	StartMiniServer
-*
-*	Parameters :
-*		unsigned short listen_port ; Port on which the server listens for 
-*									incoming connections
-*
-*	Description :	Initialize the sockets functionality for the 
-*		Miniserver. Initialize a thread pool job to run the MiniServer
-*		and the job to the thread pool. If listen port is 0, port is 
-*		dynamically picked
-*
-*		Use timer mechanism to start the MiniServer, failure to meet the 
-*		allowed delay aborts the attempt to launch the MiniServer.
-*
-*	Return : int ;
-*		Actual port socket is bound to - On Success: 
-*		A negative number UPNP_E_XXX - On Error   			
-*	Note :
-************************************************************************/
-int StartMiniServer( unsigned short listen_port );
-
-/************************************************************************
-*	Function :	StopMiniServer
-*
-*	Parameters :
-*		void ;	
-*
-*	Description :	Stop and Shutdown the MiniServer and free socket 
-*		resources.
-*
-*	Return : int ;
-*		Always returns 0 
-*
-*	Note :
-************************************************************************/
-int StopMiniServer( void );
-
-
-#ifdef __cplusplus
-}   /* extern C */
-#endif
-
-#endif /* MINISERVER_H */
diff --git a/tombupnp/upnp/src/inc/netall.h b/tombupnp/upnp/src/inc/netall.h
deleted file mode 100644
index d1ea4f0..0000000
--- a/tombupnp/upnp/src/inc/netall.h
+++ /dev/null
@@ -1,33 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include <genlib/net/netexception.h>
-#include <genlib/net/netreader.h>
diff --git a/tombupnp/upnp/src/inc/parsetools.h b/tombupnp/upnp/src/inc/parsetools.h
deleted file mode 100644
index 2f37285..0000000
--- a/tombupnp/upnp/src/inc/parsetools.h
+++ /dev/null
@@ -1,63 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef GENLIB_NET_HTTP_PARSETOOLS_H
-#define GENLIB_NET_HTTP_PARSETOOLS_H
-
-#include "util.h"
-#include "httpparser.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/************************************************************************
-* Function: has_xml_content_type										
-*																		
-* Parameters:															
-*	IN http_message_t* hmsg	; HTTP Message object
-*																		
-* Description: Find the header from the HTTP message and match the		
-*	header for xml data.												
-*																		
-* Returns:																
-*	 BOOLEAN															
-************************************************************************/
-xboolean has_xml_content_type( IN http_message_t* hmsg );
-
-#ifdef __cplusplus
-} // extern C
-#endif
-
-
-#endif // GENLIB_NET_HTTP_PARSETOOLS_H
diff --git a/tombupnp/upnp/src/inc/server.h b/tombupnp/upnp/src/inc/server.h
deleted file mode 100644
index cb57eee..0000000
--- a/tombupnp/upnp/src/inc/server.h
+++ /dev/null
@@ -1,69 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef GENLIB_NET_HTTP_SERVER_H
-#define GENLIB_NET_HTTP_SERVER_H
-
-#ifdef __cplusplus
-
-#include <genlib/net/http/parseutil.h>
-
-int http_ServerCallback( IN HttpMessage& request, IN int sockfd );
-
-// adds 'entity' to the alias list; the entity is referred using
-//
-// aliasRelURL: relative url for given entity
-// entity: entity to be served
-// actualAlias: [possibly] modified version of aliasResURL to resolve conflicts
-// returns:
-//   0 : success
-//   HTTP_E_OUT_OF_MEMORY
-int http_AddAlias( IN const char* aliasRelURL, IN HttpEntity* entity,
-    OUT xstring& actualAlias );
-
-extern "C" {
-#endif /* __cplusplus */
-
-void http_OldServerCallback( IN const char* msg, int sockfd );
-
-void http_SetRootDir( const char* httpRootDir );
-
-// removes a previously added entity
-// returns:
-//  0: success -- alias removed
-// -1: alias not found
-int http_RemoveAlias( IN const char* alias );
-
-#ifdef __cplusplus
-}   /* extern C */
-#endif
-
-#endif /* GENLIB_NET_HTTP_SERVER_H */
diff --git a/tombupnp/upnp/src/inc/service_table.h b/tombupnp/upnp/src/inc/service_table.h
deleted file mode 100644
index 39344ac..0000000
--- a/tombupnp/upnp/src/inc/service_table.h
+++ /dev/null
@@ -1,459 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef _SERVICE_TABLE
-#define _SERVICE_TABLE
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "config.h"
-#include "uri.h"
-#include "ixml.h"
-
-#include "upnp.h"
-#include <stdio.h>
-#include <time.h>
-
-#define SID_SIZE  41
-
-DEVICEONLY(
-
-typedef struct SUBSCRIPTION {
-  Upnp_SID sid;
-  int eventKey;
-  int ToSendEventKey;
-  time_t expireTime;
-  int active;
-  URL_list DeliveryURLs;
-  struct SUBSCRIPTION *next;
-} subscription;
-
-
-typedef struct SERVICE_INFO {
-  DOMString serviceType;
-  DOMString serviceId;
-  char		*SCPDURL ;
-  char		*controlURL;
-  char		*eventURL;
-  DOMString UDN;
-  int		active;
-  int		TotalSubscriptions;
-  subscription			*subscriptionList;
-  struct SERVICE_INFO	 *next;
-} service_info;
-
-typedef struct SERVICE_TABLE {
-  DOMString URLBase;
-  service_info *serviceList;
-  service_info *endServiceList;
-} service_table;
-
-
-/*			Functions for Subscriptions				*/
-
-/************************************************************************
-*	Function :	copy_subscription
-*
-*	Parameters :
-*		subscription *in ;	Source subscription
-*		subscription *out ;	Destination subscription
-*
-*	Description :	Makes a copy of the subscription
-*
-*	Return : int ;
-*		HTTP_SUCCESS - On Sucess
-*
-*	Note :
-************************************************************************/
-int copy_subscription(subscription *in, subscription *out);
-
-/************************************************************************
-*	Function :	RemoveSubscriptionSID
-*
-*	Parameters :
-*		Upnp_SID sid ;	subscription ID
-*		service_info * service ;	service object providing the list of
-*						subscriptions
-*
-*	Description :	Remove the subscription represented by the
-*		const Upnp_SID sid parameter from the service table and update 
-*		the service table.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void RemoveSubscriptionSID(Upnp_SID sid, service_info * service);
-
-/************************************************************************
-*	Function :	GetSubscriptionSID
-*
-*	Parameters :
-*		Upnp_SID sid ;	subscription ID
-*		service_info * service ;	service object providing the list of
-*						subscriptions
-*
-*	Description :	Return the subscription from the service table 
-*		that matches const Upnp_SID sid value. 
-*
-*	Return : subscription * - Pointer to the matching subscription 
-*		node;
-*
-*	Note :
-************************************************************************/
-subscription * GetSubscriptionSID(Upnp_SID sid,service_info * service); 
-  
-//returns a pointer to the subscription with the SID, NULL if not found
-
-subscription * CheckSubscriptionSID(Upnp_SID sid,service_info * service);
-
-//returns a pointer to the first subscription
-subscription * GetFirstSubscription(service_info *service);
-
-/************************************************************************
-*	Function :	GetNextSubscription
-*
-*	Parameters :
-*		service_info * service ; service object providing the list of
-*						subscriptions
-*		subscription *current ;	current subscription object
-*
-*	Description :	Get current and valid subscription from the service 
-*		table.
-*
-*	Return : subscription * - Pointer to the next subscription node;
-*
-*	Note :
-************************************************************************/	
-subscription * GetNextSubscription(service_info * service, subscription *current);
-
-/************************************************************************
-*	Function :	freeSubscription
-*
-*	Parameters :
-*		subscription * sub ;	subscription to be freed
-*
-*	Description :	Free's the memory allocated for storing the URL of 
-*		the subscription.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void freeSubscription(subscription * sub);
-
-/************************************************************************
-*	Function :	freeSubscriptionList
-*
-*	Parameters :
-*		subscription * head ;	head of the subscription list
-*
-*	Description :	Free's memory allocated for all the subscriptions 
-*		in the service table. 
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void freeSubscriptionList(subscription * head);
-
-/************************************************************************
-*	Function :	FindServiceId
-*
-*	Parameters :
-*		service_table *table ;	service table
-*		const char * serviceId ;string representing the service id 
-*								to be found among those in the table	
-*		const char * UDN ;		string representing the UDN 
-*								to be found among those in the table	
-*
-*	Description :	Traverses through the service table and returns a 
-*		pointer to the service node that matches a known service  id 
-*		and a known UDN
-*
-*	Return : service_info * - pointer to the matching service_info node;
-*
-*	Note :
-************************************************************************/
-service_info *FindServiceId( service_table * table, 
-			     const char * serviceId, const char * UDN);
-
-/************************************************************************
-*	Function :	FindServiceEventURLPath
-*
-*	Parameters :
-*		service_table *table ;	service table
-*		char * eventURLPath ;	event URL path used to find a service 
-*								from the table  
-*
-*	Description :	Traverses the service table and finds the node whose
-*		event URL Path matches a know value 
-*
-*	Return : service_info * - pointer to the service list node from the 
-*		service table whose event URL matches a known event URL;
-*
-*	Note :
-************************************************************************/
-service_info * FindServiceEventURLPath( service_table *table,
-					  char * eventURLPath
-					 );
-
-/************************************************************************
-*	Function :	FindServiceControlURLPath
-*
-*	Parameters :
-*		service_table * table ;	service table
-*		char * controlURLPath ;	control URL path used to find a service 
-*								from the table  
-*
-*	Description :	Traverses the service table and finds the node whose
-*		control URL Path matches a know value 
-*
-*	Return : service_info * - pointer to the service list node from the 
-*		service table whose control URL Path matches a known value;
-*
-*	Note :
-************************************************************************/
-service_info * FindServiceControlURLPath( service_table *table,
-					  const char * controlURLPath);
-
-/************************************************************************
-*	Function :	printService
-*
-*	Parameters :
-*		service_info *service ;Service whose information is to be printed
-*		Dbg_Level level ; Debug level specified to the print function
-*		Dbg_Module module ;	Debug module specified to the print function
-*
-*	Description :	For debugging purposes prints information from the 
-*		service passed into the function.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-DBGONLY(void printService(service_info *service,Dbg_Level
-				   level,
-				   Dbg_Module module));
-
-/************************************************************************
-*	Function :	printServiceList
-*
-*	Parameters :
-*		service_info *service ;	Service whose information is to be printed
-*		Dbg_Level level ;	Debug level specified to the print function
-*		Dbg_Module module ;	Debug module specified to the print function
-*
-*	Description :	For debugging purposes prints information of each 
-*		service from the service table passed into the function.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-DBGONLY(void printServiceList(service_info *service,
-				       Dbg_Level level, Dbg_Module module));
-
-/************************************************************************
-*	Function :	printServiceTable
-*
-*	Parameters :
-*		service_table * table ;	Service table to be printed
-*		Dbg_Level level ;	Debug level specified to the print function
-*		Dbg_Module module ;	Debug module specified to the print function
-*
-*	Description :	For debugging purposes prints the URL base of the table
-*		and information of each service from the service table passed into 
-*		the function.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-DBGONLY(void printServiceTable(service_table *
-					table,Dbg_Level
-					level,Dbg_Module module));
-
-/************************************************************************
-*	Function :	freeService
-*
-*	Parameters :
-*		service_info *in ;	service information that is to be freed
-*
-*	Description :	Free's memory allocated for the various components 
-*		of the service entry in the service table.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void freeService(service_info * in);
-
-/************************************************************************
-*	Function :	freeServiceList
-*
-*	Parameters :
-*		service_info * head ;	Head of the service list to be freed
-*
-*	Description :	Free's memory allocated for the various components 
-*		of each service entry in the service table.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void freeServiceList(service_info * head);
-
-
-/************************************************************************
-*	Function :	freeServiceTable
-*
-*	Parameters :
-*		service_table * table ;	Service table whose memory needs to be 
-*								freed
-*
-*	Description : Free's dynamic memory in table.
-*		(does not free table, only memory within the structure)
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void freeServiceTable(service_table * table);
-
-/************************************************************************
-*	Function :	removeServiceTable
-*
-*	Parameters :
-*		IXML_Node *node ;	XML node information
-*		service_table *in ;	service table from which services will be 
-*							removed
-*
-*	Description :	This function assumes that services for a particular 
-*		root device are placed linearly in the service table, and in the 
-*		order in which they are found in the description document
-*		all services for this root device are removed from the list
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int removeServiceTable(IXML_Node *node,
-				service_table *in);
-
-
-/************************************************************************
-*	Function :	addServiceTable
-*
-*	Parameters :
-*		IXML_Node *node ;	XML node information 
-*		service_table *in ;	service table that will be initialized with 
-*							services
-*		const char *DefaultURLBase ; Default base URL on which the URL 
-*							will be returned to the service list.
-*
-*	Description :	Add Service to the table.
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int addServiceTable(IXML_Node *node, service_table *in, const char *DefaultURLBase);
-
-/************************************************************************
-*	Function :	getServiceTable
-*
-*	Parameters :
-*		IXML_Node *node ;	XML node information
-*		service_table *out ;	output parameter which will contain the 
-*							service list and URL 
-*		const char *DefaultURLBase ; Default base URL on which the URL 
-*							will be returned.
-*
-*	Description :	Retrieve service from the table
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int getServiceTable(IXML_Node *node, service_table * out, const char * DefaultURLBase);
-
-
-/*						Misc helper functions						   */
-
-
-/************************************************************************
-*	Function :	getElementValue
-*
-*	Parameters :
-*		IXML_Node *node ;	Input node which provides the list of child 
-*							nodes
-*
-*	Description :	Returns the clone of the element value
-*
-*	Return : DOMString ;
-*
-*	Note : value must be freed with DOMString_free
-************************************************************************/
-DOMString getElementValue(IXML_Node *node);
-
-/************************************************************************
-*	Function :	getSubElement
-*
-*	Parameters :
-*		const char *element_name ;	sub element name to be searched for
-*		IXML_Node *node ;	Input node which provides the list of child 
-*							nodes
-*		IXML_Node **out ;	Ouput node to which the matched child node is
-*							returned.
-*
-*	Description :	Traverses through a list of XML nodes to find the 
-*		node with the known element name.
-*
-*	Return : int ;
-*		1 - On Success
-*		0 - On Failure
-*
-*	Note :
-************************************************************************/
-int getSubElement(const char *element_name, IXML_Node *node, 
-		  IXML_Node **out);
-
-
-)	/* DEVICEONLY */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SERVICE_TABLE */
diff --git a/tombupnp/upnp/src/inc/soaplib.h b/tombupnp/upnp/src/inc/soaplib.h
deleted file mode 100644
index 71fc7cb..0000000
--- a/tombupnp/upnp/src/inc/soaplib.h
+++ /dev/null
@@ -1,133 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef SOAPLIB_H
-#define SOAPLIB_H 
-
-
-//SOAP module API to be called in Upnp-Dk API
-/****************************************************************************
-*	Function :	soap_device_callback
-*
-*	Parameters :
-*		  IN http_parser_t *parser : Parsed request received by the device
-*		  IN http_message_t* request :	HTTP request 
-*		  INOUT SOCKINFO *info :	socket info
-*
-*	Description :	This is a callback called by minisever after receiving 
-*		the request from the control point. This function will start 
-*		processing the request. It calls handle_invoke_action to handle the
-*		SOAP action
-*
-*	Return :	void
-*
-*	Note :
-****************************************************************************/
-void soap_device_callback( 
-						  IN http_parser_t *parser, 
-						  IN http_message_t* request, 
-						  INOUT SOCKINFO *info );
-
-
-/****************************************************************************
-*	Function :	SoapSendAction
-*
-*	Parameters :
-*		IN char* action_url :	device contrl URL 
-*		IN char *service_type :	device service type
-*		IN IXML_Document *action_node : SOAP action node	
-*		OUT IXML_Document **response_node :	SOAP response node
-*
-*	Description :	This function is called by UPnP API to send the SOAP 
-*		action request and waits till it gets the response from the device
-*		pass the response to the API layer
-*
-*	Return :	int
-*		returns UPNP_E_SUCCESS if successful else returns appropriate error
-*	Note :
-****************************************************************************/
-int SoapSendAction( 
-		IN char* action_url, 
-		IN char *service_type,
-		IN IXML_Document *action_node,
-		OUT IXML_Document **response_node );
-
-/****************************************************************************
-*	Function :	SoapSendActionEx
-*
-*	Parameters :
-*		IN char* action_url :	device contrl URL 
-*		IN char *service_type :	device service type
-		IN IXML_Document *Header: Soap header
-*		IN IXML_Document *action_node : SOAP action node ( SOAP body)	
-*		OUT IXML_Document **response_node :	SOAP response node
-*
-*	Description :	This function is called by UPnP API to send the SOAP 
-*		action request and waits till it gets the response from the device
-*		pass the response to the API layer. This action is similar to the 
-*		the SoapSendAction with only difference that it allows users to 
-*		pass the SOAP header along the SOAP body ( soap action request)
-*
-*	Return :	int
-*		returns UPNP_E_SUCCESS if successful else returns appropriate error
-*	Note :
-****************************************************************************/
-int SoapSendActionEx(
-		IN char * ActionURL, 
-		IN char *ServiceType, 
-		IN IXML_Document *Header,
-		IN IXML_Document *ActNode , 
-		OUT IXML_Document **RespNode) ;
-
-/****************************************************************************
-*	Function :	SoapGetServiceVarStatus
-*
-*	Parameters :
-*			IN  char * action_url :	Address to send this variable 
-*									query message.
-*			IN  char *var_name : Name of the variable.
-*			OUT char **var_value :	Output value.
-*
-*	Description :	This function creates a status variable query message 
-*		send it to the specified URL. It also collect the response.
-*
-*	Return :	int
-*
-*	Note :
-****************************************************************************/
-int SoapGetServiceVarStatus(
-				IN char * ActionURL, 
-				IN DOMString VarName, 
-				OUT DOMString *StVar) ;   
-
-extern const char* ContentTypeHeader;
-
-#endif //SOAPLIB_H
diff --git a/tombupnp/upnp/src/inc/sock.h b/tombupnp/upnp/src/inc/sock.h
deleted file mode 100644
index 9f469de..0000000
--- a/tombupnp/upnp/src/inc/sock.h
+++ /dev/null
@@ -1,176 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef GENLIB_NET_SOCK_H
-#define GENLIB_NET_SOCK_H
-
-#include "util.h"
-
-#ifndef WIN32
- #include <netinet/in.h>
-#endif
-
-//Following variable is not defined under winsock.h
-#ifndef SD_RECEIVE
-#define SD_RECEIVE      0x00
-#define SD_SEND         0x01
-#define SD_BOTH         0x02
-#endif
-
-
-typedef struct 
-{
-	int socket;		// handle/descriptor to a socket
-
-    // the following two fields are filled only in incoming requests;
-    struct in_addr foreign_ip_addr;
-    unsigned short foreign_ip_port;
-    
-} SOCKINFO;
-
-#ifdef __cplusplus
-#extern "C" {
-#endif
-
-/************************************************************************
-*	Function :	sock_init
-*
-*	Parameters :
-*		OUT SOCKINFO* info ;	Socket Information Object
-*		IN int sockfd ;			Socket Descriptor
-*
-*	Description :	Assign the passed in socket descriptor to socket 
-*		descriptor in the SOCKINFO structure.
-*
-*	Return : int;
-*		UPNP_E_SUCCESS	
-*		UPNP_E_OUTOF_MEMORY
-*		UPNP_E_SOCKET_ERROR
-*	Note :
-************************************************************************/
-int sock_init( OUT SOCKINFO* info, IN int sockfd );
-
-/************************************************************************
-*	Function :	sock_init_with_ip
-*
-*	Parameters :
-*		OUT SOCKINFO* info ;				Socket Information Object
-*		IN int sockfd ;						Socket Descriptor
-*		IN struct in_addr foreign_ip_addr ;	Remote IP Address
-*		IN unsigned short foreign_ip_port ;	Remote Port number
-*
-*	Description :	Calls the sock_init function and assigns the passed in
-*		IP address and port to the IP address and port in the SOCKINFO
-*		structure.
-*
-*	Return : int;
-*		UPNP_E_SUCCESS	
-*		UPNP_E_OUTOF_MEMORY
-*		UPNP_E_SOCKET_ERROR
-*
-*	Note :
-************************************************************************/
-int sock_init_with_ip( OUT SOCKINFO* info, IN int sockfd, 
-        IN struct in_addr foreign_ip_addr, IN unsigned short foreign_ip_port );
-
-/************************************************************************
-*	Function :	sock_read
-*
-*	Parameters :
-*		IN SOCKINFO *info ;	Socket Information Object
-*		OUT char* buffer ;	Buffer to get data to  
-*		IN size_t bufsize ;	Size of the buffer
-*	    IN int *timeoutSecs ;	timeout value
-*
-*	Description :	Reads data on socket in sockinfo
-*
-*	Return : int;
-*		numBytes - On Success, no of bytes received		
-*		UPNP_E_TIMEDOUT - Timeout
-*		UPNP_E_SOCKET_ERROR - Error on socket calls
-*
-*	Note :
-************************************************************************/
-int sock_read( IN SOCKINFO *info, OUT char* buffer, IN size_t bufsize,
-		    		 INOUT int *timeoutSecs );
-
-
-// check is socket is ok for writing
-int sock_check_w( IN SOCKINFO * info );
-
-/************************************************************************
-*	Function :	sock_write
-*
-*	Parameters :
-*		IN SOCKINFO *info ;	Socket Information Object
-*		IN char* buffer ;	Buffer to send data from 
-*		IN size_t bufsize ;	Size of the buffer
-*	    IN int *timeoutSecs ;	timeout value
-*
-*	Description :	Writes data on the socket in sockinfo
-*
-*	Return : int;
-*		numBytes - On Success, no of bytes sent		
-*		UPNP_E_TIMEDOUT - Timeout
-*		UPNP_E_SOCKET_ERROR - Error on socket calls
-*
-*	Note :
-************************************************************************/
-int sock_write( IN SOCKINFO *info, IN char* buffer, IN size_t bufsize,
-		    		 INOUT int *timeoutSecs );
-
-/************************************************************************
-*	Function :	sock_destroy
-*
-*	Parameters :
-*		INOUT SOCKINFO* info ;	Socket Information Object
-*		int ShutdownMethod ;	How to shutdown the socket. Used by  
-*								sockets's shutdown() 
-*
-*	Description :	Shutsdown the socket using the ShutdownMethod to 
-*		indicate whether sends and receives on the socket will be 
-*		dis-allowed. After shutting down the socket, closesocket is called
-*		to release system resources used by the socket calls.
-*
-*	Return : int;
-*		UPNP_E_SOCKET_ERROR on failure
-*		UPNP_E_SUCCESS on success
-*
-*	Note :
-************************************************************************/
-int sock_destroy( INOUT SOCKINFO* info,int );
-
-#ifdef __cplusplus
-}	// #extern "C"
-#endif
-
-
-#endif // GENLIB_NET_SOCK_H
diff --git a/tombupnp/upnp/src/inc/ssdplib.h b/tombupnp/upnp/src/inc/ssdplib.h
deleted file mode 100644
index f18d759..0000000
--- a/tombupnp/upnp/src/inc/ssdplib.h
+++ /dev/null
@@ -1,544 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef SSDPLIB_H
-#define SSDPLIB_H 
-
-#include <sys/types.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <fcntl.h>
-#include <errno.h>
-#include "httpparser.h"
-#include "httpreadwrite.h"
-#include "miniserver.h"
-#ifndef WIN32
- #include <syslog.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/in_systm.h>
- #include <netinet/ip.h>
- #include <netinet/ip_icmp.h>
- #include <sys/time.h>
- #include <arpa/inet.h>
-#else
-#include <winsock2.h>
-#endif
-
-//Enumeration to define all different types of ssdp searches
-typedef enum SsdpSearchType{
-	SSDP_SERROR=-1,
-	SSDP_ALL,SSDP_ROOTDEVICE,
-	SSDP_DEVICEUDN,
-	SSDP_DEVICETYPE,
-	SSDP_SERVICE
-} SType;
-
-
-//Enumeration to define all different type of ssdp messages
-typedef enum SsdpCmdType{SSDP_ERROR=-1,
-	SSDP_OK,
-	SSDP_ALIVE,
-	SSDP_BYEBYE,
-	SSDP_SEARCH,
-	SSDP_NOTIFY,
-	SSDP_TIMEOUT
-} Cmd;
-
-
-
-//Constant
-#define	 BUFSIZE   2500
-#define  SSDP_IP   "239.255.255.250"
-#define  SSDP_PORT 1900
-#define  NUM_TRY 3
-#define  NUM_COPY 1
-#define  THREAD_LIMIT 50
-#define  COMMAND_LEN  300
-
-//Error code
-#define NO_ERROR_FOUND    0
-#define E_REQUEST_INVALID  	-3
-#define E_RES_EXPIRED		-4
-#define E_MEM_ALLOC		-5
-#define E_HTTP_SYNTEX		-6
-#define E_SOCKET 		-7
-#define RQST_TIMEOUT    20
-
-
-
-//Structure to store the SSDP information
-typedef struct SsdpEventStruct
-{
-  enum SsdpCmdType Cmd;
-  enum SsdpSearchType RequestType;
-  int  ErrCode;
-  int  MaxAge;
-  int  Mx;
-  char UDN[LINE_SIZE];
-  char DeviceType[LINE_SIZE];
-  char ServiceType[LINE_SIZE];  //NT or ST
-  char Location[LINE_SIZE];
-  char HostAddr[LINE_SIZE];
-  char Os[LINE_SIZE];
-  char Ext[LINE_SIZE];
-  char Date[LINE_SIZE];
-  struct sockaddr_in * DestAddr;
-  void * Cookie;
-} Event;
-
-typedef void (* SsdpFunPtr)(Event *);
-
-typedef Event SsdpEvent ;
-
-//Structure to contain Discovery response
-typedef struct resultData
-{
-  struct Upnp_Discovery param;
-  void *cookie;
-  Upnp_FunPtr ctrlpt_callback;
-}ResultData;
-
-
-typedef struct TData
-{
-   int Mx;
-   void * Cookie;
-   char * Data;
-   struct sockaddr_in DestAddr;
-   
-}ThreadData;
-
-typedef struct ssdpsearchreply
-{
-  int MaxAge;
-  UpnpDevice_Handle handle;
-  struct sockaddr_in dest_addr;
-  SsdpEvent event;
-  
-}SsdpSearchReply;
-
-typedef struct ssdpsearcharg
-{
-  int timeoutEventId;
-  char * searchTarget;
-  void *cookie;
-  enum SsdpSearchType requestType;
-} SsdpSearchArg;
-
-
-typedef struct 
-{
-  http_parser_t parser;
-  struct sockaddr_in dest_addr;
-} ssdp_thread_data;
-
-
-/* globals */
-
-CLIENTONLY(extern SOCKET gSsdpReqSocket;);
-
-typedef int (*ParserFun)(char *, Event *);
-
-
-//void InitParser();
-
-//int AnalyzeCommand(char * szCommand, Event * Evt);
-
-/************************************************************************
-* Function : Make_Socket_NoBlocking									
-*																	
-* Parameters:														
-*	IN int sock: socket 
-*
-* Description:														
-*	This function to make ssdp socket non-blocking.
-*
-* Returns: int
-*	0 if successful else -1 
-***************************************************************************/
-int Make_Socket_NoBlocking (int sock);
-
-/************************************************************************
-* Function : ssdp_handle_device_request									
-*																	
-* Parameters:														
-*		IN void *data:
-*
-* Description:														
-*	This function handles the search request. It do the sanity checks of
-*	the request and then schedules a thread to send a random time reply (
-*	random within maximum time given by the control point to reply).
-*
-* Returns: void *
-*	1 if successful else appropriate error
-***************************************************************************/
-void ssdp_handle_device_request( IN http_message_t* hmsg, 
-							 IN struct sockaddr_in* dest_addr );
-
-/************************************************************************
-* Function : ssdp_handle_ctrlpt_msg											
-*																	
-* Parameters:														
-*	IN http_message_t* hmsg: SSDP message from the device
-*	IN struct sockaddr_in* dest_addr: Address of the device
-*	IN xboolean timeout: timeout kept by the control point while sending 
-*						search message
-*	IN void* cookie: Cookie stored by the control point application. 
-*					This cookie will be returned to the control point
-*					in the callback 
-*																	
-* Description:														
-*	This function handles the ssdp messages from the devices. These 
-*	messages includes the search replies, advertisement of device coming 
-*	alive and bye byes.
-*
-* Returns: void
-*
-***************************************************************************/
-void ssdp_handle_ctrlpt_msg( IN http_message_t* hmsg, 
-							 IN struct sockaddr_in* dest_addr,
-							 IN xboolean timeout,
-							 IN void* cookie );
-
-/************************************************************************
-* Function : unique_service_name								
-*																	
-* Parameters:														
-*	IN char *cmd: Service Name string 
-*	OUT SsdpEvent *Evt: The SSDP event structure partially filled 
-*						by all the function.
-*
-* Description:														
-*	This function fills the fields of the event structure like DeviceType,
-*	Device UDN and Service Type
-*
-* Returns: int
-*	0 if successful else -1 
-***************************************************************************/
-int unique_service_name(char * cmd, SsdpEvent * Evt);
-
-
-/************************************************************************
-* Function : get_ssdp_sockets								
-*																	
-* Parameters:														
-*	OUT MiniServerSockArray *out: Arrays of SSDP sockets
-*
-* Description:														
-*	This function creates the ssdp sockets. It set their option to listen 
-*	for multicast traffic.
-*
-* Returns: int
-*	return UPNP_E_SUCCESS if successful else returns appropriate error
-***************************************************************************/
-int get_ssdp_sockets(MiniServerSockArray *out);
-
-
-/************************************************************************
-* Function : readFromSSDPSocket								
-*																	
-* Parameters:														
-*	IN SOCKET socket: SSDP socket
-*
-* Description:														
-*	This function reads the data from the ssdp socket.
-*
-* Returns: void
-*	
-***************************************************************************/
-void readFromSSDPSocket(SOCKET socket);
-
-
-/************************************************************************
-* Function : ssdp_request_type1								
-*																	
-* Parameters:														
-*	IN char *cmd: command came in the ssdp request
-*
-* Description:														
-*	This function figures out the type of the SSDP search in the 
-*	in the request.
-*
-* Returns: enum SsdpSearchType
-*	return appropriate search type else returns SSDP_ERROR
-***************************************************************************/
-enum SsdpSearchType ssdp_request_type1(IN char *cmd);
-
-
-/************************************************************************
-* Function : ssdp_request_type								
-*																	
-* Parameters:														
-*	IN char *cmd: command came in the ssdp request
-*	OUT SsdpEvent *Evt: The event structure partially filled by
-*		 this function.
-*
-* Description:														
-*	This function starts filling the SSDP event structure based upon the 
-*	request received. 
-*
-* Returns: int
-*	0 on success; -1 on error
-***************************************************************************/
-int ssdp_request_type(IN char * cmd, OUT SsdpEvent * Evt);
-
-
-/************************************************************************
-* Function : SearchByTarget											
-*																	
-* Parameters:														
-*		IN int Mx:Number of seconds to wait, to collect all the 
-*					responses.
-*		char *St: Search target.
-*		void *Cookie: cookie provided by control point application. This
-*						cokie will be returned to application in the 
-*						callback.
-*
-* Description:														
-*	This function creates and send the search request for a specific URL.
-*
-* Returns: int
-*	1 if successful else appropriate error
-***************************************************************************/
-int SearchByTarget(IN int Mx, IN char *St, IN void *Cookie);
-
-/************************************************************************
-* Function : DeviceAdvertisement									
-*																	
-* Parameters:														
-*	IN char * DevType : type of the device
-*	IN int RootDev: flag to indicate if the device is root device
-*	IN char * nt : value of NT
-*	IN char * usn :
-*	IN char * location :Location URL.
-*	IN int  duration :Service duration in sec.
-*
-* Description:														
-*	This function creates the device advertisement request based on 
-*	the input parameter, and send it to the multicast channel.
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-int DeviceAdvertisement(IN char * DevType, int RootDev,char * Udn, 
-						IN char * Location, IN int  Duration);
-
-
-/************************************************************************
-* Function : DeviceShutdown									
-*																	
-* Parameters:	
-*	IN char *DevType: Device Type.
-*	IN int RootDev:1 means root device.
-*	IN char * Udn: Device UDN
-*	IN char *_Server:
-*	IN char * Location: Location URL
-*	IN int  Duration :Device duration in sec.
-*
-* Description:														
-*	This function creates a HTTP device shutdown request packet 
-*	and sent it to the multicast channel through RequestHandler.
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-int DeviceShutdown( IN char * DevType, 
-				    IN int RootDev,
-					IN char * Udn, 
-					IN char * _Server, 
-					IN char * Location, 
-					IN int  Duration );
-
-/************************************************************************
-* Function : DeviceReply									
-*																	
-* Parameters:	
-*	IN struct sockaddr_in * DestAddr:destination IP address.
-*	IN char *DevType: Device type
-*	IN int RootDev: 1 means root device 0 means embedded device.
-*	IN char * Udn: Device UDN
-*	IN char * Location: Location of Device description document.
-*	IN int  Duration :Life time of this device.
-
-* Description:														
-*	This function creates the reply packet based on the input parameter, 
-*	and send it to the client address given in its input parameter DestAddr.
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-int DeviceReply(IN struct sockaddr_in * DestAddr, 
-				IN char *DevType, 
-				IN int RootDev, 
-				IN char * Udn, 
-				IN char * Location, IN int  Duration);
-
-/************************************************************************
-* Function : SendReply									
-*																	
-* Parameters:	
-*	IN struct sockaddr_in * DestAddr:destination IP address.
-*	IN char *DevType: Device type
-*	IN int RootDev: 1 means root device 0 means embedded device.
-*	IN char * Udn: Device UDN
-*	IN char *_Server:
-*	IN char * Location: Location of Device description document.
-*	IN int  Duration :Life time of this device.
-*	IN int ByType:
-*
-* Description:														
-*	This function creates the reply packet based on the input parameter, 
-*	and send it to the client addesss given in its input parameter DestAddr.
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-int SendReply(IN struct sockaddr_in * DestAddr, 
-			  IN char *DevType, 
-			  IN int RootDev, 
-			  IN char * Udn, 
-			  IN char * Location, 
-			  IN int  Duration, 
-			  IN int ByType );
-
-/************************************************************************
-* Function : ServiceAdvertisement									
-*																	
-* Parameters:	
-*	IN char * Udn: Device UDN
-*	IN char *ServType: Service Type.
-*	IN char * Location: Location of Device description document.
-*	IN int  Duration :Life time of this device.
-
-* Description:														
-*	This function creates the advertisement packet based 
-*	on the input parameter, and send it to the multicast channel.
-
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-int ServiceAdvertisement( IN char * Udn, 
-						 IN char * ServType,
-						 IN char * Location,
-						 IN int  Duration);
-
-/************************************************************************
-* Function : ServiceReply									
-*																	
-* Parameters:	
-*	IN struct sockaddr_in *DestAddr:
-*	IN char * Udn: Device UDN
-*	IN char *ServType: Service Type.
-*	IN char *Server: Not used
-*	IN char * Location: Location of Device description document.
-*	IN int  Duration :Life time of this device.
-
-* Description:														
-*	This function creates the advertisement packet based 
-*	on the input parameter, and send it to the multicast channel.
-
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-int ServiceReply(IN struct sockaddr_in *DestAddr,  
-				 IN char * ServType, 
-				 IN char * Udn, 
-				 IN char * Location,
-				 IN int  Duration);
-
-/************************************************************************
-* Function : ServiceShutdown									
-*																	
-* Parameters:	
-*	IN char * Udn: Device UDN
-*	IN char *ServType: Service Type.
-*	IN char * Location: Location of Device description document.
-*	IN int  Duration :Service duration in sec.
-
-* Description:														
-*	This function creates a HTTP service shutdown request packet 
-*	and sent it to the multicast channel through RequestHandler.
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-int ServiceShutdown( IN char * Udn, IN char * ServType,
-					IN char * Location,
-					IN int  Duration);
-
-
-/************************************************************************
-* Function : advertiseAndReplyThread									
-*																	
-* Parameters:														
-*		IN void *data: Structure containing the search request
-*
-* Description:														
-*	This function is a wrapper function to reply the search request 
-*	coming from the control point.
-*
-* Returns: void *
-*	always return NULL
-***************************************************************************/
-void * advertiseAndReplyThread(IN void * data);
-
-/************************************************************************
-* Function : AdvertiseAndReply									
-*																	
-* Parameters:														
-*	IN int AdFlag: -1 = Send shutdown, 0 = send reply, 
-*					1 = Send Advertisement
-*	IN UpnpDevice_Handle Hnd: Device handle
-*	IN enum SsdpSearchType SearchType:Search type for sending replies
-*	IN struct sockaddr_in *DestAddr:Destination address
-*   IN char *DeviceType:Device type
-*	IN char *DeviceUDN:Device UDN
-*   IN char *ServiceType:Service type
-*	IN int Exp:Advertisement age
-*
-* Description:														
-*	This function to send SSDP advertisements, replies and shutdown messages.
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-int AdvertiseAndReply(IN int AdFlag, 
-					IN UpnpDevice_Handle Hnd, 
-					IN enum SsdpSearchType SearchType, 
-					IN struct sockaddr_in *DestAddr,
-                    IN char *DeviceType, 
-					IN char *DeviceUDN, 
-                    IN char *ServiceType, int Exp);
-
-#endif
diff --git a/tombupnp/upnp/src/inc/statcodes.h b/tombupnp/upnp/src/inc/statcodes.h
deleted file mode 100644
index 9ca7abb..0000000
--- a/tombupnp/upnp/src/inc/statcodes.h
+++ /dev/null
@@ -1,115 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef GENLIB_NET_HTTP_STATCODES_H
-#define GENLIB_NET_HTTP_STATCODES_H
-
-// HTTP response status codes
-
-#define HTTP_CONTINUE                       100
-#define HTTP_SWITCHING_PROCOTOLS            101
-
-#define HTTP_OK                             200
-#define HTTP_CREATED                        201
-#define HTTP_ACCEPTED                       202
-#define HTTP_NON_AUTHORATATIVE              203
-#define HTTP_NO_CONTENT                     204
-#define HTTP_RESET_CONTENT                  205
-#define HTTP_PARTIAL_CONTENT                206
-
-#define HTTP_MULTIPLE_CHOICES               300
-#define HTTP_MOVED_PERMANENTLY              301
-#define HTTP_FOUND                          302
-#define HTTP_SEE_OTHER                      303
-#define HTTP_NOT_MODIFIED                   304
-#define HTTP_USE_PROXY                      305
-#define HTTP_UNUSED_3XX                     306
-#define HTTP_TEMPORARY_REDIRECT             307
-
-#define HTTP_BAD_REQUEST                    400
-#define HTTP_UNAUTHORIZED                   401
-#define HTTP_PAYMENT_REQD                   402
-#define HTTP_FORBIDDEN                      403
-#define HTTP_NOT_FOUND                      404
-#define HTTP_METHOD_NOT_ALLOWED             405
-#define HTTP_NOT_ACCEPTABLE                 406
-#define HTTP_PROXY_AUTH_REQD                407
-#define HTTP_REQUEST_TIMEOUT                408
-#define HTTP_CONFLICT                       409
-#define HTTP_GONE                           410
-#define HTTP_LENGTH_REQUIRED                411
-#define HTTP_PRECONDITION_FAILED            412
-#define HTTP_REQ_ENTITY_TOO_LARGE           413
-#define HTTP_REQ_URI_TOO_LONG               414
-#define HTTP_UNSUPPORTED_MEDIA_TYPE         415
-#define HTTP_REQUEST_RANGE_NOT_SATISFIABLE  416
-#define HTTP_EXPECTATION_FAILED             417
-
-#define HTTP_INTERNAL_SERVER_ERROR          500
-#define HTTP_NOT_IMPLEMENTED                501
-#define HTTP_BAD_GATEWAY                    502
-#define HTTP_SERVICE_UNAVAILABLE            503
-#define HTTP_GATEWAY_TIMEOUT                504
-#define HTTP_HTTP_VERSION_NOT_SUPPORTED     505
-
-// *********** HTTP lib error codes **********
-
-#define HTTP_E_OUT_OF_MEMORY    -2
-#define HTTP_E_BAD_MSG_FORMAT   -3
-#define HTTP_E_TIMEDOUT         -4
-#define HTTP_E_FILE_READ        -5
-
-// *******************************************
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/************************************************************************
-* Function: http_get_code_text											
-*																		
-* Parameters:															
-*	int statusCode ; Status code based on which the status table and 
-*					status message is returned 							
-*																		
-* Description: Return the right status message based on the passed in	
-*	int statusCode input parameter										
-*																		
-* Returns:																
-*	 const char* ptr - pointer to the status message string				
-************************************************************************/
-const char* http_get_code_text( int statusCode );
-
-#ifdef __cplusplus
-} // extern C
-#endif
-
-#endif /* GENLIB_NET_HTTP_STATCODES_H */
diff --git a/tombupnp/upnp/src/inc/statuscodes.h b/tombupnp/upnp/src/inc/statuscodes.h
deleted file mode 100644
index 0793141..0000000
--- a/tombupnp/upnp/src/inc/statuscodes.h
+++ /dev/null
@@ -1,102 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef GENLIB_NET_HTTP_STATUSCODES_H
-#define GENLIB_NET_HTTP_STATUSCODES_H
-
-// HTTP response status codes
-
-#define HTTP_CONTINUE                       100
-#define HTTP_SWITCHING_PROCOTOLS            101
-
-#define HTTP_OK                             200
-#define HTTP_CREATED                        201
-#define HTTP_ACCEPTED                       202
-#define HTTP_NON_AUTHORATATIVE              203
-#define HTTP_NO_CONTENT                     204
-#define HTTP_RESET_CONTENT                  205
-#define HTTP_PARTIAL_CONTENT                206
-
-#define HTTP_MULTIPLE_CHOICES               300
-#define HTTP_MOVED_PERMANENTLY              301
-#define HTTP_FOUND                          302
-#define HTTP_SEE_OTHER                      303
-#define HTTP_NOT_MODIFIED                   304
-#define HTTP_USE_PROXY                      305
-#define HTTP_UNUSED_3XX                     306
-#define HTTP_TEMPORARY_REDIRECT             307
-
-#define HTTP_BAD_REQUEST                    400
-#define HTTP_UNAUTHORIZED                   401
-#define HTTP_PAYMENT_REQD                   402
-#define HTTP_FORBIDDEN                      403
-#define HTTP_NOT_FOUND                      404
-#define HTTP_METHOD_NOT_ALLOWED             405
-#define HTTP_NOT_ACCEPTABLE                 406
-#define HTTP_PROXY_AUTH_REQD                407
-#define HTTP_REQUEST_TIMEOUT                408
-#define HTTP_CONFLICT                       409
-#define HTTP_GONE                           410
-#define HTTP_LENGTH_REQUIRED                411
-#define HTTP_PRECONDITION_FAILED            412
-#define HTTP_REQ_ENTITY_TOO_LARGE           413
-#define HTTP_REQ_URI_TOO_LONG               414
-#define HTTP_UNSUPPORTED_MEDIA_TYPE         415
-#define HTTP_REQUEST_RANGE_NOT_SATISFIABLE  416
-#define HTTP_EXPECTATION_FAILED             417
-
-#define HTTP_INTERNAL_SERVER_ERROR          500
-#define HTTP_NOT_IMPLEMENTED                501
-#define HTTP_BAD_GATEWAY                    502
-#define HTTP_SERVICE_UNAVAILABLE            503
-#define HTTP_GATEWAY_TIMEOUT                504
-#define HTTP_HTTP_VERSION_NOT_SUPPORTED     505
-
-// *********** HTTP lib error codes **********
-
-#define HTTP_E_OUT_OF_MEMORY    -2
-#define HTTP_E_BAD_MSG_FORMAT   -3
-#define HTTP_E_TIMEDOUT         -4
-#define HTTP_E_FILE_READ        -5
-
-// *******************************************
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-const char* http_GetCodeText( int statusCode );
-
-#ifdef __cplusplus
-} // extern C
-#endif
-
-#endif /* GENLIB_NET_HTTP_STATUSCODES_H */
diff --git a/tombupnp/upnp/src/inc/strintmap.h b/tombupnp/upnp/src/inc/strintmap.h
deleted file mode 100644
index 6ddcb1c..0000000
--- a/tombupnp/upnp/src/inc/strintmap.h
+++ /dev/null
@@ -1,102 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef GENLIB_UTIL_STRINTMAP_H
-#define GENLIB_UTIL_STRINTMAP_H
-
-#include <stdlib.h>
-#include "util.h"
-
-// Util to map from a string to an integer and vice versa
-
-typedef struct // str_int_entry
-{
-	char *name;		// a value in string form
-	int  id;		// same value in integer form
-} str_int_entry;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/************************************************************************
-*	Function :	map_str_to_int
-*
-*	Parameters :
-*		IN const char* name ;	string containing the name to be matched
-*		IN size_t name_len ;	size of the string to be matched
-*		IN str_int_entry* table ;	table of entries that need to be 
-*					matched.
-*		IN int num_entries ; number of entries in the table that need 
-*					to be searched.
-*		IN xboolean case_sensitive ; whether the case should be case
-*					sensitive or not
-*
-*	Description : Match the given name with names from the entries in the 
-*		table. Returns the index of the table when the entry is found.
-*
-*	Return : int ;
-*		index - On Success
-*		-1 - On failure
-*
-*	Note :
-************************************************************************/
-int map_str_to_int( IN const char* name, IN size_t name_len,
-		IN str_int_entry* table, IN int num_entries, 
-		IN xboolean case_sensitive );
-
-
-/************************************************************************
-*	Function :	map_int_to_str
-*
-*	Parameters :
-*		IN int id ;	ID to be matched
-*		IN str_int_entry* table ;	table of entries that need to be 
-*					matched.
-*		IN int num_entries ; number of entries in the table that need 
-*					to be searched.
-*
-*	Description : Returns the index from the table where the id matches 
-*		the entry from the table.
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int map_int_to_str( IN int id, IN str_int_entry* table,
-		IN int num_entries );
-
-#ifdef __cplusplus
-} // extern C
-#endif
-
-
-#endif // GENLIB_UTIL_STRINTMAP_H
diff --git a/tombupnp/upnp/src/inc/strtoofft.h b/tombupnp/upnp/src/inc/strtoofft.h
deleted file mode 100644
index 6edb8ef..0000000
--- a/tombupnp/upnp/src/inc/strtoofft.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef __CURL_STRTOOFFT_H__
-#define __CURL_STRTOOFFT_H__
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id: strtoofft.h,v 1.14 2004/12/17 18:33:09 giva Exp $
- ***************************************************************************/
-
-/* This code has been adapted for libupnp 
- * by Sergey 'Jin' Bostandzhyan <jin at mediatomb.org> 
- */
-
-#include <stddef.h>
-#include "upnpconfig.h"
-
-#ifdef HAVE_STRTOLL
-    #define str_to_offt strtoll
-#else
-    long long upnp_strtoll(const char *nptr, char **endptr, int base);
-    #define str_to_offt upnp_strtoll
-    #define NEED_UPNP_STRTOLL
-#endif
-
-#ifndef LLONG_MIN
-    #define LLONG_MIN 0x8000000000000000LL
-#endif
-
-#ifndef LLONG_MAX
-    #define LLONG_MAX 0x7FFFFFFFFFFFFFFFLL
-#endif
-
-#if 0
-#if (SIZEOF_CURL_OFF_T > 4) && (SIZEOF_LONG < 8)
-#if HAVE_STRTOLL
-#define curlx_strtoofft strtoll
-#else /* HAVE_STRTOLL */
-
-/* For MSVC7 we can use _strtoi64() which seems to be a strtoll() clone */
-#if defined(_MSC_VER) && (_MSC_VER >= 1300)
-#define curlx_strtoofft _strtoi64
-#else /* MSVC7 or later */
-curl_off_t curlx_strtoll(const char *nptr, char **endptr, int base);
-#define curlx_strtoofft curlx_strtoll
-#define NEED_CURL_STRTOLL
-#endif /* MSVC7 or later */
-
-#endif /* HAVE_STRTOLL */
-#else /* (SIZEOF_CURL_OFF_T > 4) && (SIZEOF_LONG < 8) */
-/* simply use strtol() to get numbers, either 32 or 64 bit */
-#define curlx_strtoofft strtol
-#endif
-
-#if defined(_MSC_VER) || defined(__WATCOMC__)
-#define CURL_LLONG_MIN 0x8000000000000000i64
-#define CURL_LLONG_MAX 0x7FFFFFFFFFFFFFFFi64
-#elif defined(HAVE_LL)
-#define CURL_LLONG_MIN 0x8000000000000000LL
-#define CURL_LLONG_MAX 0x7FFFFFFFFFFFFFFFLL
-#else
-#define CURL_LLONG_MIN 0x8000000000000000L
-#define CURL_LLONG_MAX 0x7FFFFFFFFFFFFFFFL
-#endif
-
-#endif // #if 0
-#endif
diff --git a/tombupnp/upnp/src/inc/sysdep.h b/tombupnp/upnp/src/inc/sysdep.h
deleted file mode 100644
index 774b3ff..0000000
--- a/tombupnp/upnp/src/inc/sysdep.h
+++ /dev/null
@@ -1,64 +0,0 @@
-  /*
-  ** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
-  ** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &
-  ** Digital Equipment Corporation, Maynard, Mass.
-  ** Copyright (c) 1998 Microsoft.
-  ** To anyone who acknowledges that this file is provided "AS IS"
-  ** without any express or implied warranty: permission to use, copy,
-  ** modify, and distribute this file for any purpose is hereby
-  ** granted without fee, provided that the above copyright notices and
-  ** this notice appears in all source code copies, and that none of
-  ** the names of Open Software Foundation, Inc., Hewlett-Packard
-  ** Company, or Digital Equipment Corporation be used in advertising
-  ** or publicity pertaining to distribution of the software without
-  ** specific, written prior permission.  Neither Open Software
-  ** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital Equipment
-  ** Corporation makes any representations about the suitability of
-  ** this software for any purpose.
-  */
-
-#include <sys/types.h>
-#ifndef WIN32
- #include <sys/time.h>
-#endif
-//#include <sys/sysinfo.h>
-#include "ithread.h"
-
-/* change to point to where MD5 .h's live */
-/* get MD5 sample implementation from RFC 1321 */
-#include "global.h"
-#include "upnp_md5.h"
-
-/* set the following to the number of 100ns ticks of the actual
-   resolution of
-   your system's clock */
-#define UUIDS_PER_TICK 1024
-
-/* Set the following to a call to acquire a system wide global lock
- */
-extern ithread_mutex_t gUUIDMutex;
-
-#define UUIDLock()      ithread_mutex_lock(&gUUIDMutex)
-#define UUIDUnlock()    ithread_mutex_unlock(&gUUIDMutex)
-
-typedef unsigned long   unsigned32;
-typedef unsigned short  unsigned16;
-typedef unsigned char   unsigned8;
-typedef unsigned char   byte;
-
-/* Set this to what your compiler uses for 64 bit data type */
-#ifndef WIN32
- #define unsigned64_t unsigned long long
-#else
- #define unsigned64_t __int64
-#endif
-#define I64(C) C##LL
-
-typedef unsigned64_t uuid_time_t;
-typedef struct {
-    char nodeID[6];
-} uuid_node_t;
-
-void get_ieee_node_identifier(uuid_node_t *node);
-void get_system_time(uuid_time_t *uuid_time);
-void get_random_info(unsigned char seed[16]);
diff --git a/tombupnp/upnp/src/inc/unixutil.h b/tombupnp/upnp/src/inc/unixutil.h
deleted file mode 100644
index 0f9624f..0000000
--- a/tombupnp/upnp/src/inc/unixutil.h
+++ /dev/null
@@ -1,47 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-// Unix-specific network utilities
-
-#ifndef GENLIB_NET_UNIXUTIL_H
-#define	GENLIB_NET_UNIXUTIL_H
-
-#include <sys/types.h>
-#ifndef WIN32
- #include <sys/socket.h>
-#else
- #define XINLINE
-
- typedef int socklen_t;
- #define EAFNOSUPPORT 97
-#endif
-
-#endif // GENLIB_NET_UNIXUTIL_H
diff --git a/tombupnp/upnp/src/inc/upnp_md5.h b/tombupnp/upnp/src/inc/upnp_md5.h
deleted file mode 100644
index e65b196..0000000
--- a/tombupnp/upnp/src/inc/upnp_md5.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * This is the header file for the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest.  This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
- * will fill a supplied 16-byte array with the digest.
- *
- * Changed so as no longer to depend on Colin Plumb's `usual.h'
- * header definitions; now uses stuff from dpkg's config.h
- *  - Ian Jackson <ian at chiark.greenend.org.uk>.
- * Still in the public domain.
- */
-
-#ifndef MD5_H
-#define MD5_H
-
-#define md5byte unsigned char
-
-#if SIZEOF_UNSIGNED_LONG==4
-# define UWORD32 unsigned long
-#elif SIZEOF_UNSIGNED_INT==4
-# define UWORD32 unsigned int
-#else
-# error I do not know what to use for a UWORD32.
-#endif
-
-struct MD5Context {
-       UWORD32 buf[4];
-       UWORD32 bytes[2];
-       UWORD32 in[16];
-};
-
-void MD5Init(struct MD5Context *context);
-void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len);
-void MD5Final(unsigned char digest[16], struct MD5Context *context);
-void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]);
-
-#endif /* !MD5_H */
diff --git a/tombupnp/upnp/src/inc/upnp_timeout.h b/tombupnp/upnp/src/inc/upnp_timeout.h
deleted file mode 100644
index 65ab657..0000000
--- a/tombupnp/upnp/src/inc/upnp_timeout.h
+++ /dev/null
@@ -1,58 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef _UPNPTIMEOUTH_
-#define _UPNPTIMEOUTH_
-
-typedef struct UPNP_TIMEOUT {
-  int EventType;
-  int handle;
-  int eventId;
-  void *Event;
-} upnp_timeout;
-
-
-/************************************************************************
-*	Function :	free_upnp_timeout
-*
-*	Parameters :
-*		upnp_timeout *event ;	Event which needs to be freed
-*
-*	Description : Free memory associated with event and memory for any 
-*		sub-elements 
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void free_upnp_timeout(upnp_timeout *event);
-
-#endif
diff --git a/tombupnp/upnp/src/inc/upnp_uuid.h b/tombupnp/upnp/src/inc/upnp_uuid.h
deleted file mode 100644
index 54980f8..0000000
--- a/tombupnp/upnp/src/inc/upnp_uuid.h
+++ /dev/null
@@ -1,50 +0,0 @@
-  /*
-  ** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
-  ** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &
-  ** Digital Equipment Corporation, Maynard, Mass.
-  ** Copyright (c) 1998 Microsoft.
-  ** To anyone who acknowledges that this file is provided "AS IS"
-  ** without any express or implied warranty: permission to use, copy,
-  ** modify, and distribute this file for any purpose is hereby
-  ** granted without fee, provided that the above copyright notices and
-  ** this notice appears in all source code copies, and that none of
-  ** the names of Open Software Foundation, Inc., Hewlett-Packard
-  ** Company, or Digital Equipment Corporation be used in advertising
-  ** or publicity pertaining to distribution of the software without
-  ** specific, written prior permission.  Neither Open Software
-  ** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital Equipment
-  ** Corporation makes any representations about the suitability of
-  ** this software for any purpose.
-  */
-
-  typedef struct _uuid_upnp {
-      unsigned32          time_low;
-      unsigned16          time_mid;
-      unsigned16          time_hi_and_version;
-      unsigned8           clock_seq_hi_and_reserved;
-      unsigned8           clock_seq_low;
-      byte                node[6];
-  } uuid_upnp;
-
-  /* uuid_create -- generate a UUID */
-  int uuid_create(uuid_upnp * id);
-  void uuid_unpack(uuid_upnp *u, char *out);	// out will be xxxx-xx-xx-xx-xxxxxx format
-
-  /* uuid_create_from_name -- create a UUID using a "name"
-     from a "name space" */
-  void uuid_create_from_name(
-    uuid_upnp * uid,        /* resulting UUID */
-    uuid_upnp nsid,          /* UUID to serve as context, so identical
-                             names from different name spaces generate
-                             different UUIDs */
-    void * name,          /* the name from which to generate a UUID */
-    int namelen           /* the length of the name */
-  );
-
-  /* uuid_compare --  Compare two UUID's "lexically" and return
-          -1   u1 is lexically before u2
-           0   u1 is equal to u2
-           1   u1 is lexically after u2
-     Note:   lexical ordering is not temporal ordering!
-  */
-  int uuid_compare(uuid_upnp *u1, uuid_upnp *u2);
diff --git a/tombupnp/upnp/src/inc/upnpapi.h b/tombupnp/upnp/src/inc/upnpapi.h
deleted file mode 100644
index 7f9228a..0000000
--- a/tombupnp/upnp/src/inc/upnpapi.h
+++ /dev/null
@@ -1,210 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-// File : upnpapi.h
-
-#ifndef UPNPDK_H
-#define UPNPDK_H
-
-#include "upnp.h"
-#include "client_table.h"
-#include "membuffer.h"
-
-//#include "../ssdp/ssdplib.h"
-
-
-
-
-#define MAX_INTERFACES 256
-
-#define DEFAULT_INTERFACE 1
-
-#define DEV_LIMIT 200
-
-#define NUM_HANDLE 200
-
-#define DEFAULT_MX 5
-
-#define DEFAULT_MAXAGE 1800
-
-#define DEFAULT_SOAP_CONTENT_LENGTH 16000
-#define MAX_SOAP_CONTENT_LENGTH 32000
-
-// LARGE FILE IMPLEMENTATION DEFINES
-#if SIZEOF_OFF_T > 4
-    #define OFF_T_SPRINTF "%ll"
-#else
-    #define OFF_T_SPRINTF "%l"
-#endif
-
-extern off_t g_maxContentLength;
-
-// 30-second timeout
-#define UPNP_TIMEOUT	30
-
-typedef enum {HND_INVALID=-1,HND_CLIENT,HND_DEVICE} Upnp_Handle_Type;
-
-// Data to be stored in handle table for
-struct Handle_Info
-{
-    Upnp_Handle_Type HType;
-    Upnp_FunPtr  Callback; // Callback function pointer.
-    char * Cookie;
-
-    DEVICEONLY(char  DescURL[LINE_SIZE];)   // URL for the use of SSDP
-    DEVICEONLY(char  DescXML[LINE_SIZE];)   // XML file path for device 
-                                            //description
-
-    DEVICEONLY(int MaxAge;)                 // Advertisement timeout
-    DEVICEONLY(IXML_Document *DescDocument;)     // Description parsed in 
-                                            //terms of DOM document 
-    DEVICEONLY(IXML_NodeList *DeviceList;)       // List of devices in the 
-                                            //description document
-    DEVICEONLY(IXML_NodeList *ServiceList;)      // List of services in the 
-                                            // description document
-    DEVICEONLY(service_table ServiceTable;) //table holding subscriptions and 
-                                //URL information
-    DEVICEONLY(int MaxSubscriptions;)
-    DEVICEONLY(int MaxSubscriptionTimeOut;)
-     
-       //Client only
-    CLIENTONLY(client_subscription * ClientSubList;) //client subscription list
-    CLIENTONLY(LinkedList SsdpSearchList;) // active ssdp searches   
-    int   aliasInstalled;       // 0 = not installed; otherwise installed
-} ;
-
-extern ithread_mutex_t GlobalHndMutex;
-Upnp_Handle_Type GetHandleInfo(int Hnd, struct Handle_Info **HndInfo); 
-
-#define HandleLock()  DBGONLY(UpnpPrintf(UPNP_INFO,API,__FILE__,__LINE__,"Trying Lock")); ithread_mutex_lock(&GlobalHndMutex); DBGONLY(UpnpPrintf(UPNP_INFO,API,__FILE__,__LINE__,"LOCK"));
-#define HandleUnlock() DBGONLY(UpnpPrintf(UPNP_INFO,API,__FILE__,__LINE__,"Trying Unlock")); ithread_mutex_unlock(&GlobalHndMutex); DBGONLY(UpnpPrintf(UPNP_INFO,API,__FILE__,__LINE__,"Unlock"));
-Upnp_Handle_Type GetClientHandleInfo(int *client_handle_out, 
-                                     struct Handle_Info **HndInfo);
-Upnp_Handle_Type GetDeviceHandleInfo(int *device_handle_out, 
-                                     struct Handle_Info **HndInfo);
-
-
-extern char LOCAL_HOST[LINE_SIZE];
-
-extern unsigned short LOCAL_PORT;
-
-extern TimerThread gTimerThread;
-extern ThreadPool gRecvThreadPool;
-extern ThreadPool gSendThreadPool;
-
-
-typedef enum {
-    SUBSCRIBE,
-    UNSUBSCRIBE,
-    DK_NOTIFY,
-    QUERY,
-    ACTION,
-    STATUS,
-    DEVDESCRIPTION,
-    SERVDESCRIPTION,
-    MINI,
-    RENEW} UpnpFunName;
-
-struct  UpnpNonblockParam 
-{ 
-    UpnpFunName  FunName;
-    int   Handle;
-    int   TimeOut;
-    char  VarName[NAME_SIZE];
-    char  NewVal[NAME_SIZE];
-    char  DevType[NAME_SIZE];
-    char  DevId[NAME_SIZE];
-    char  ServiceType[NAME_SIZE];
-    char  ServiceVer[NAME_SIZE];
-    char  Url[NAME_SIZE];
-    Upnp_SID   SubsId;
-    char  *Cookie;
-    Upnp_FunPtr Fun;
-	IXML_Document *Header;
-    IXML_Document *Act;
-    struct DevDesc *Devdesc;
-};
-
-
-extern virtualDirList *pVirtualDirList;
-extern struct UpnpVirtualDirCallbacks virtualDirCallback;
-
-
-typedef enum { WEB_SERVER_DISABLED, WEB_SERVER_ENABLED } WebServerState;
-
-#define E_HTTP_SYNTAX -6
-
-void InitHandleList();
-int GetFreeHandle();
-int FreeHandle(int Handle);
-void UpnpThreadDistribution(struct UpnpNonblockParam * Param);
-
-
-void AutoAdvertise(void *input); 
-int getlocalhostname(char *out);
-
-virtualDirList *pVirtualDirList;
-userHTTPHeaderList *pUserHTTPHeaderList;
-// concatenated list of custom http headers
-membuffer gUserHTTPHeaders;
-
-
-extern WebServerState bWebServerState;
-
-int gUpnpSdkShutdown;
-
-int gMaxHTTPTimeoutRetries;
-#endif
-
-
-
-/************************ END OF upnpapi.h **********************/
diff --git a/tombupnp/upnp/src/inc/upnpclosesocket.h b/tombupnp/upnp/src/inc/upnpclosesocket.h
deleted file mode 100644
index fb1ec89..0000000
--- a/tombupnp/upnp/src/inc/upnpclosesocket.h
+++ /dev/null
@@ -1,37 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef UPNPCLOSESOCKET_H
-#define UPNPCLOSESOCKET_H
-
-#define UpnpCloseSocket close
-
-#endif
diff --git a/tombupnp/upnp/src/inc/uri.h b/tombupnp/upnp/src/inc/uri.h
deleted file mode 100644
index ba9c523..0000000
--- a/tombupnp/upnp/src/inc/uri.h
+++ /dev/null
@@ -1,517 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef GENLIB_NET_URI_H
-#define GENLIB_NET_URI_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <fcntl.h>
-#include <string.h>
-#include <sys/types.h>
-#include <time.h>
-#include <errno.h>
-#include <ctype.h>
-#include <stdlib.h>
-#ifndef WIN32
- #include <arpa/inet.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <unistd.h>
- #include <netdb.h>
- #include <sys/time.h>
-#else
- #include <time.h>
-
- #define strncasecmp strnicmp
-#endif
-
-#include "upnp.h"
-//#include <upnp_debug.h>
-
-
-#define HTTP_DATE_LENGTH 37 // length for HTTP DATE: 
-                            //"DATE: Sun, 01 Jul 2000 08:15:23 GMT<cr><lf>"
-#define SEPARATORS "()<>@,;:\\\"/[]?={} \t"
-#define MARK "-_.!~*'()"
-#define RESERVED ";/?:@&=+$,{}" //added {} for compatibility
-#define HTTP_SUCCESS 1
-
-#define FALSE 0
-#define TAB 9
-#define CR 13
-#define LF 10
-#define SOCKET_BUFFER_SIZE 5000
-
-enum hostType { HOSTNAME, IPv4address };
-enum pathType { ABS_PATH, REL_PATH, OPAQUE_PART };
-#ifndef WIN32
-// there is a conflict in windows with other symbols
-enum uriType  { ABSOLUTE, RELATIVE };
-#else
-enum uriType  { absolute, relative };
-#endif
-
-/*	Buffer used in parsinghttp messages, urls, etc. generally this simply
-*	holds a pointer into a larger array									*/
-typedef struct TOKEN {
-  const char *buff;
-  int size;
-} token;
-
-
-/*	Represents a host port:e.g. :"127.127.0.1:80"
-*	text is a token pointing to the full string representation */
-typedef struct HOSTPORT {
-  token text; //full host port
-  struct sockaddr_in IPv4address; //Network Byte Order  
-} hostport_type;
-
-/*	Represents a URI used in parse_uri and elsewhere */
-typedef struct URI{
-  enum uriType type;
-  token scheme;
-  enum pathType path_type;
-  token pathquery;
-  token fragment;
-  hostport_type hostport;
-} uri_type;
-
-/* Represents a list of URLs as in the "callback" header of SUBSCRIBE
-*	message in GENA 
-*	char * URLs holds dynamic memory								*/
-typedef struct URL_LIST {
-  int size;
-  char * URLs; //all the urls, delimited by <>
-  uri_type *parsedURLs;
-} URL_list;
-
-
-/************************************************************************
-*	Function :	replace_escaped
-*
-*	Parameters :
-*		char * in ;	string of characters
-*		int index ;	index at which to start checking the characters
-*		int *max ;	
-*
-*	Description : Replaces an escaped sequence with its unescaped version 
-*		as in http://www.ietf.org/rfc/rfc2396.txt  (RFC explaining URIs)
-*       Size of array is NOT checked (MUST be checked by caller)
-*
-*	Return : int ;
-*
-*	Note : This function modifies the string. If the sequence is an 
-*		escaped sequence it is replaced, the other characters in the 
-*		string are shifted over, and NULL characters are placed at the 
-*		end of the string.
-************************************************************************/
-int replace_escaped(char * in, int index, int *max);
-
-/************************************************************************
-*	Function :	copy_URL_list
-*
-*	Parameters :
-*		URL_list *in ;	Source URL list
-*		URL_list *out ;	Destination URL list
-*
-*	Description : Copies one URL_list into another. This includes 
-*		dynamically allocating the out->URLs field (the full string),
-*       and the structures used to hold the parsedURLs. This memory MUST 
-*		be freed by the caller through: free_URL_list(&out)
-*
-*	Return : int ;
-*		HTTP_SUCCESS - On Success
-*		UPNP_E_OUTOF_MEMORY - On Failure to allocate memory
-*
-*	Note :
-************************************************************************/
-int copy_URL_list( URL_list *in, URL_list *out);
-
-/************************************************************************
-*	Function :	free_URL_list
-*
-*	Parameters :
-*		URL_list * list ;	URL List object
-*
-*	Description : Frees the memory associated with a URL_list. Frees the 
-*		dynamically allocated members of of list. Does NOT free the 
-*		pointer to the list itself ( i.e. does NOT free(list))
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void free_URL_list(URL_list * list);
-
-/************************************************************************
-*	Function :	print_uri
-*
-*	Parameters :
-*		uri_type *in ;	URI object
-*
-*	Description : Function useful in debugging for printing a parsed uri.
-*		Compiled out with DBGONLY macro. 
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-DBGONLY(void print_uri( uri_type *in);)
-
-/************************************************************************
-*	Function :	print_token
-*
-*	Parameters :
-*		token * in ;	
-*
-*	Description : Function useful in debugging for printing a token.
-*		Compiled out with DBGONLY macro. 
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void print_token(  token * in);
-
-/************************************************************************
-*	Function :	token_string_casecmp
-*
-*	Parameters :
-*		token * in1 ;	Token object whose buffer is to be compared
-*		char * in2 ;	string of characters to compare with
-*
-*	Description :	Compares buffer in the token object with the buffer 
-*		in in2
-*
-*	Return : int ;
-*		< 0 string1 less than string2 
-*		0 string1 identical to string2 
-*		> 0 string1 greater than string2 
-*
-*	Note :
-************************************************************************/
-int token_string_casecmp( token * in1,  char * in2);
-
-/************************************************************************
-*	Function :	token_string_cmp
-*
-*	Parameters :
-*		token * in1 ;	Token object whose buffer is to be compared
-*		char * in2 ;	string of characters to compare with
-*
-*	Description : Compares a null terminated string to a token (exact)	
-*
-*	Return : int ;
-*		< 0 string1 less than string2 
-*		0 string1 identical to string2 
-*		> 0 string1 greater than string2 
-*
-*	Note :
-************************************************************************/
-int token_string_cmp( token * in1,  char * in2);
-
-/************************************************************************
-*	Function :	token_cmp
-*
-*	Parameters :
-*		token *in1 ;	First token object whose buffer is to be compared
-*		token *in2 ;	Second token object used for the comparison
-*
-*	Description : Compares two tokens	
-*
-*	Return : int ;
-*		< 0 string1 less than string2 
-*		0 string1 identical to string2 
-*		> 0 string1 greater than string2 
-*
-*	Note :
-************************************************************************/
-int token_cmp( token *in1,  token *in2);
-
-/************************************************************************
-*	Function :	parse_port
-*
-*	Parameters :
-*		int max ;	sets a maximum limit
-*		char * port ;	port to be parsed.
-*		unsigned short * out ;	 out parameter where the port is parsed 
-*							and converted into network format
-*
-*	Description : parses a port (i.e. '4000') and converts it into a 
-*		network ordered unsigned short int.
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int parse_port(int max, const char *port, unsigned short int *out);
-
-/************************************************************************
-*	Function :	parse_hostport
-*
-*	Parameters :
-*		char *in ;	string of characters representing host and port
-*		int max ;	sets a maximum limit
-*		hostport_type *out ;	out parameter where the host and port
-*					are represented as an internet address
-*
-*	Description : Parses a string representing a host and port
-*		(e.g. "127.127.0.1:80" or "localhost") and fills out a 
-*		hostport_type struct with internet address and a token 
-*		representing the full host and port.  uses gethostbyname.
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int parse_hostport(const char *in, int max, hostport_type *out );
-
-/************************************************************************
-*	Function :	remove_escaped_chars
-*
-*	Parameters :
-*		INOUT char *in ;	string of characters to be modified
-*		INOUT int *size ;	size limit for the number of characters
-*
-*	Description : removes http escaped characters such as: "%20" and 
-*		replaces them with their character representation. i.e. 
-*		"hello%20foo" -> "hello foo". The input IS MODIFIED in place. 
-*		(shortened). Extra characters are replaced with NULL.
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS
-*
-*	Note :
-************************************************************************/
-int remove_escaped_chars(char *in,int *size);
-
-/************************************************************************
-*	Function :	remove_dots
-*
-*	Parameters :
-*		char *in ;	string of characters from which "dots" have to be 
-*					removed
-*		int size ;	size limit for the number of characters
-*
-*	Description : Removes ".", and ".." from a path. If a ".." can not
-*		be resolved (i.e. the .. would go past the root of the path) an 
-*		error is returned. The input IS modified in place.)
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Success
-*		UPNP_E_OUTOF_MEMORY - On failure to allocate memory
-*		UPNP_E_INVALID_URL - Failure to resolve URL
-*
-*	Note :
-*		Examples
-*       char path[30]="/../hello";
-*       remove_dots(path, strlen(path)) -> UPNP_E_INVALID_URL
-*       char path[30]="/./hello";
-*       remove_dots(path, strlen(path)) -> UPNP_E_SUCCESS, 
-*       in = "/hello"
-*       char path[30]="/./hello/foo/../goodbye" -> 
-*       UPNP_E_SUCCESS, in = "/hello/goodbye"
-
-************************************************************************/
-int remove_dots(char * in, int size);
-
-/************************************************************************
-*	Function :	resolve_rel_url
-*
-*	Parameters :
-*		char * base_url ;	Base URL
-*		char * rel_url ;	Relative URL
-*
-*	Description : resolves a relative url with a base url returning a NEW 
-*		(dynamically allocated with malloc) full url. If the base_url is 
-*		NULL, then a copy of the  rel_url is passed back if the rel_url 
-*		is absolute then a copy of the rel_url is passed back if neither 
-*		the base nor the rel_url are Absolute then NULL is returned.
-*		otherwise it tries and resolves the relative url with the base 
-*		as described in: http://www.ietf.org/rfc/rfc2396.txt (RFCs 
-*		explaining URIs) 
-*       : resolution of '..' is NOT implemented, but '.' is resolved 
-*
-*	Return : char * ;
-*
-*	Note :
-************************************************************************/
-char * resolve_rel_url( char * base_url,  char * rel_url);
-
-/************************************************************************
-*	Function :	parse_uri
-*
-*	Parameters :
-*		char * in ;	character string containing uri information to be 
-*					parsed
-*		int max ;	maximum limit on the number of characters
-*		uri_type * out ; out parameter which will have the parsed uri
-*					information	
-*
-*	Description : parses a uri as defined in http://www.ietf.org/rfc/
-*		rfc2396.txt (RFC explaining URIs)
-*		Handles absolute, relative, and opaque uris. Parses into the 
-*		following pieces: scheme, hostport, pathquery, fragment (path and
-*		query are treated as one token)
-*       Caller should check for the pieces they require.
-*
-*	Return : int ;
-*
-*	Note :
-************************************************************************/
-int parse_uri(const char * in, int max, uri_type * out);
-
-/************************************************************************
-*	Function :	parse_uri_and_unescape
-*
-*	Parameters :
-*		char * in ;	
-*		int max ;	
-*		uri_type * out ;	
-*
-*	Description : Same as parse_uri, except that all strings are 
-*		unescaped (%XX replaced by chars)
-*
-*	Return : int ;
-*
-*	Note: This modifies 'pathquery' and 'fragment' parts of the input
-************************************************************************/
-int parse_uri_and_unescape(char * in, int max, uri_type * out);
-
-int parse_token( char * in, token * out, int max_size);
-
-/************************************************************************
-*				commented #defines, functions and typdefs				*
-************************************************************************/
-
-/************************************************************************
-*						Commented #defines								*
-************************************************************************/
-//#define HTTP_E_BAD_URL UPNP_E_INVALID_URL
-//#define HTTP_E_READ_SOCKET  UPNP_E_SOCKET_READ
-//#define HTTP_E_BIND_SOCKET  UPNP_E_SOCKET_BIND
-//#define HTTP_E_WRITE_SOCKET  UPNP_E_SOCKET_WRITE
-//#define HTTP_E_CONNECT_SOCKET  UPNP_E_SOCKET_CONNECT
-//#define HTTP_E_SOCKET    UPNP_E_OUTOF_SOCKET
-//#define HTTP_E_BAD_RESPONSE UPNP_E_BAD_RESPONSE
-//#define HTTP_E_BAD_REQUEST UPNP_E_BAD_REQUEST
-//#define HTTP_E_BAD_IP_ADDRESS UPNP_E_INVALID_URL
-
-//#define RESPONSE_TIMEOUT 30
-
-/************************************************************************
-*						Commented typedefs								*
-************************************************************************/
-//Buffer used to store data read from a socket during an http transfer
-//in function read_bytes.
-//typedef struct SOCKET_BUFFER{
-//  char buff[SOCKET_BUFFER_SIZE];
-//  int size;
-//  struct SOCKET_BUFFER *next;
-//} socket_buffer;
-
-//typedef struct HTTP_HEADER {
-//  token header;
-//  token value;
-//  struct HTTP_HEADER * next;
-//} http_header;
-
-//typedef struct HTTP_STATUS_LINE{
-//  token http_version;
-//  token status_code;
-//  token reason_phrase;
-//} http_status;
-
-//typedef struct HTTP_REQUEST_LINE {
-//  token http_version;
-//  uri_type request_uri;
-//  token method;
-//} http_request;
-
-//Represents a parsed HTTP_MESSAGE head_list is dynamically allocated
-//typedef struct HTTP_MESSAGE {
-//  http_status status;
-//  http_request request;
-//  http_header * header_list;
-//  token content;
-//} http_message;
-
-/************************************************************************
-*						Commented functions								*
-************************************************************************
-
-EXTERN_C int transferHTTP( char * request,  char * toSend, 
-			  int toSendSize, char **out,  char * Url);
-
-
-EXTERN_C int transferHTTPRaw( char * toSend, int toSendSize, 
-			     char **out,  char *URL);
-
-helper function
-EXTERN_C int transferHTTPparsedURL( char * request, 
-				    char * toSend, int toSendSize, 
-				   char **out, uri_type *URL);
-
-assumes that char * out has enough space ( 38 characters)
-outputs the current time in the following null terminated string:
- "DATE: Sun, Jul 06 2000 08:53:01 GMT\r\n"
-EXTERN_C void currentTmToHttpDate(char *out);
-
-EXTERN_C int parse_http_response(  char * in, http_message * out, 
-				  int max_len);
-
-EXTERN_C int parse_http_request( char * in, http_message *out, 
-				int max_len);
-
-EXTERN_C void print_http_message( http_message * message);
-EXTERN_C int search_for_header( http_message * in, 
-			        char * header, token *out_value);
-
-EXTERN_C void print_status_line(http_status *in);
-EXTERN_C void print_request_line(http_request *in);
-EXTERN_C int parse_http_line(  char * in, int max_size);
-EXTERN_C int parse_not_LWS(  char *in, token *out, int max_size);
-EXTERN_C int parse_LWS( char * in, int max_size);
-
-EXTERN_C size_t write_bytes(int fd,   char * bytes, size_t n, 
-						    int timeout);
-EXTERN_C void free_http_message(http_message * message);
-
-************************************************************************/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // GENLIB_NET_URI_H
diff --git a/tombupnp/upnp/src/inc/urlconfig.h b/tombupnp/upnp/src/inc/urlconfig.h
deleted file mode 100644
index 35f8078..0000000
--- a/tombupnp/upnp/src/inc/urlconfig.h
+++ /dev/null
@@ -1,83 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef URLCONFIG_H
-#define URLCONFIG_H
-#ifndef WIN32
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
-#else
- #include <winsock2.h>
-#endif
-
-// functions available only if the web server is included 
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/************************************************************************
-*	Function :	configure_urlbase
-*
-*	Parameters :
-*		INOUT IXML_Document *doc ;	IXML Description document
-*		IN const struct sockaddr_in* serverAddr ;	socket address object
-*					providing the IP address and port information
-*		IN const char* alias ;	string containing the alias
-*		IN time_t last_modified ;	time when the XML document was 
-*					downloaded
-*		OUT char docURL[LINE_SIZE] ;	buffer to hold the URL of the 
-*					document.
-*
-*	Description : Configure the full URL for the description document.
-*		Create the URL document and add alias, description information.
-*		The doc is added to the web server to be served using the given 
-*		alias.
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Success
-*		UPNP_E_OUTOF_MEMORY - Default Error
-*
-*	Note :
-****************************************************************************/
-int configure_urlbase( INOUT IXML_Document *doc,
-    IN const struct sockaddr_in* serverAddr,
-    IN const char* alias,
-	IN time_t last_modified,
-    OUT char docURL[LINE_SIZE] );
-
-
-#ifdef __cplusplus
-} // extern C
-#endif
-
-#endif /* URLCONFIG_H */
diff --git a/tombupnp/upnp/src/inc/util.h b/tombupnp/upnp/src/inc/util.h
deleted file mode 100644
index 77948e3..0000000
--- a/tombupnp/upnp/src/inc/util.h
+++ /dev/null
@@ -1,172 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#ifndef UTIL_H
-#define UTIL_H
-#include "upnp.h"
-
-// usually used to specify direction of parameters in functions
-#ifndef IN
-#define IN
-#endif
-
-#ifndef OUT
-#define OUT
-#endif
-
-#ifndef INOUT
-#define INOUT
-#endif
-
-
-#ifdef NO_DEBUG
-#define DBG(x)
-#else
-#define DBG(x) x
-#endif
-
-#define GEMD_OUT_OF_MEMORY -1
-#define EVENT_TIMEDOUT -2
-#define EVENT_TERMINATE	-3
-
-
-#ifndef WIN32
- #define max(a, b)   (((a)>(b))? (a):(b))
- #define min(a, b)   (((a)<(b))? (a):(b))
-#endif
-
-
-// boolean type in C
-typedef char xboolean;
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-///////////////////////////
-// funcs
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void log_error( IN const char *fmt, ... );
-
-/************************************************************************
-*	Function :	linecopy
-*
-*	Parameters :
-*		OUT char dest[LINE_SIZE] ;	output buffer
-*		IN const char* src ;	input buffer
-*
-*	Description : Copy no of bytes spcified by the LINE_SIZE constant, 
-*		from the source buffer. Null terminate the destination buffer
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void linecopy( OUT char dest[LINE_SIZE], IN const char* src );
-
-/************************************************************************
-*	Function :	namecopy
-*
-*	Parameters :
-*		OUT char dest[NAME_SIZE] ;	output buffer
-*		IN const char* src ;	input buffer
-*
-*	Description : Copy no of bytes spcified by the NAME_SIZE constant, 
-*		from the source buffer. Null terminate the destination buffer
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void namecopy( OUT char dest[NAME_SIZE], IN const char* src );
-
-/************************************************************************
-*	Function :	linecopylen
-*
-*	Parameters :
-*		OUT char dest[LINE_SIZE] ;	output buffer
-*		IN const char* src ;	input buffer
-*		IN size_t srclen ;	bytes to be copied.
-*
-*	Description : Determine if the srclen passed in paramter is less than 
-*		the permitted LINE_SIZE. If it is use the passed parameter, if not
-*		use the permitted LINE_SIZE as the length parameter
-*		Copy no of bytes spcified by the LINE_SIZE constant, 
-*		from the source buffer. Null terminate the destination buffer
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-void linecopylen( OUT char dest[LINE_SIZE], IN const char* src, IN size_t srclen );
-
-
-#ifdef __cplusplus
-} // extern C
-#endif
-
-//////////////////////////////////
-
-// C specific
-#ifndef __cplusplus
-
-#ifndef WIN32
- #define		XINLINE inline
-#else
-
- #ifndef S_ISREG
- #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
- #endif
- 
- #ifndef S_ISDIR
- #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
- #endif
-
- #define EADDRINUSE WSAEADDRINUSE
-
- #define strcasecmp stricmp
- #define strncasecmp strnicmp
-
- #define sleep Sleep
- #define usleep(a) Sleep((a)/1000)
-#endif
-
-#endif // __cplusplus
-
-#endif /* GENLIB_UTIL_UTIL_H */
diff --git a/tombupnp/upnp/src/inc/utilall.h b/tombupnp/upnp/src/inc/utilall.h
deleted file mode 100644
index bd3099b..0000000
--- a/tombupnp/upnp/src/inc/utilall.h
+++ /dev/null
@@ -1,33 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-#include <genlib/util/util.h>
-#include <genlib/util/xstring.h>
diff --git a/tombupnp/upnp/src/inc/webserver.h b/tombupnp/upnp/src/inc/webserver.h
deleted file mode 100644
index 53825dc..0000000
--- a/tombupnp/upnp/src/inc/webserver.h
+++ /dev/null
@@ -1,171 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-
-#ifndef GENLIB_NET_HTTP_WEBSERVER_H
-#define GENLIB_NET_HTTP_WEBSERVER_H
-
-#include <time.h>
-#include "sock.h"
-#include "httpparser.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-struct SendInstruction
-{
-   int  IsVirtualFile;
-   int  IsChunkActive;
-   int  IsRangeActive;
-   int  IsTrailers;
-   char RangeHeader[200];
-   off_t RangeOffset;
-   off_t ReadSendSize;  // Read from local source and send on the network.
-   off_t RecvWriteSize; // Recv from the network and write into local file.
-
-   //Later few more member could be added depending on the requirement.
-};
-
-/************************************************************************
-* Function: web_server_init												
-*																		
-* Parameters:															
-*	none																
-*																		
-* Description: Initilialize the different documents. Initialize the		
-*	memory for root directory for web server. Call to initialize global 
-*	XML document. Sets bWebServerState to WEB_SERVER_ENABLED			
-*																		
-* Returns:																
-*	0 - OK																
-*	UPNP_E_OUTOF_MEMORY: note: alias_content is not freed here			
-************************************************************************/
-int web_server_init( void );
-
-/************************************************************************
-* Function: web_server_destroy											
-*																		
-* Parameters:															
-*	none																
-*																		
-* Description: Release memory allocated for the global web server root	
-*	directory and the global XML document								
-*	Resets the flag bWebServerState to WEB_SERVER_DISABLED				
-*																		
-* Returns:																
-*	void																
-************************************************************************/
-void web_server_destroy( void );
-
-/************************************************************************
-* Function: web_server_set_alias										
-*																		
-* Parameters:															
-*	alias_name: webserver name of alias; created by caller and freed by 
-*				caller (doesn't even have to be malloc()d .)					
-*	alias_content:	the xml doc; this is allocated by the caller; and	
-*					freed by the web server											
-*	alias_content_length: length of alias body in bytes					
-*	last_modified:	time when the contents of alias were last			
-*					changed (local time)											
-*																		
-* Description: Replaces current alias with the given alias. To remove	
-*	the current alias, set alias_name to NULL.							
-*																		
-* Returns:																
-*	0 - OK																
-*	UPNP_E_OUTOF_MEMORY: note: alias_content is not freed here			
-************************************************************************/
-int web_server_set_alias( IN const char* alias_name,
-		IN const char* alias_content, IN size_t alias_content_length,
-		IN time_t last_modified );
-
-/************************************************************************
-* Function: web_server_set_root_dir										
-*																		
-* Parameters:															
-*	IN const char* root_dir ; String having the root directory for the 
-*								document		 						
-*																		
-* Description: Assign the path specfied by the IN const char* root_dir	
-*	parameter to the global Document root directory. Also check for		
-*	path names ending in '/'											
-*																		
-* Returns:																
-*	int																	
-************************************************************************/
-int web_server_set_root_dir( IN const char* root_dir );
-
-/************************************************************************
-* Function: web_server_callback											*
-*																		*
-* Parameters:															*
-*	IN http_parser_t *parser,											*
-*	INOUT http_message_t* req,											*
-*	IN SOCKINFO *info													*
-*																		*
-* Description: main entry point into web server;						*
-*	handles HTTP GET and HEAD requests									*
-*																		*
-* Returns:																*
-*	void																*
-************************************************************************/
-void web_server_callback( IN http_parser_t *parser, IN http_message_t* req, INOUT SOCKINFO *info );
-
-
-#ifdef __cplusplus
-} // extern C
-#endif
-
-
-#endif // GENLIB_NET_HTTP_WEBSERVER_H
diff --git a/tombupnp/upnp/src/inet_pton.c b/tombupnp/upnp/src/inet_pton.c
deleted file mode 100644
index 40735f0..0000000
--- a/tombupnp/upnp/src/inet_pton.c
+++ /dev/null
@@ -1,389 +0,0 @@
-#ifdef WIN32
-/*
- * Copyright (c) 1996-1999 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-/*#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>*/
-#include <winsock2.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-typedef int socklen_t;
-#define EAFNOSUPPORT 97
-/*
- * WARNING: Don't even consider trying to compile this on a system where
- * sizeof(int) < 4.  sizeof(int) 4 is fine; all the world's not a VAX.
- */
-
-
-/* const char *
- * inet_ntop4(src, dst, size)
- *	format an IPv4 address
- * return:
- *	`dst' (as a const)
- * notes:
- *	(1) uses no statics
- *	(2) takes a u_char* not an in_addr as input
- * author:
- *	Paul Vixie, 1996.
- */
-static const char *
-inet_ntop4(const u_char *src, char *dst, socklen_t size)
-{
-	char tmp[sizeof ("255.255.255.255") + 1] = "\0";
-	int octet;
-	int i;
-
-	i = 0;
-	for (octet = 0; octet <= 3; octet++) {
-
-		if (src[octet]>255) {
-			//__set_errno (ENOSPC);
-			return (NULL);
-		}
-		tmp[i++] = '0' + src[octet] / 100;
-		if (tmp[i - 1] == '0') {
-			tmp[i - 1] = '0' + (src[octet] / 10 % 10);
-			if (tmp[i - 1] == '0') i--;
-		} else {
-			tmp[i++] = '0' + (src[octet] / 10 % 10);
-		}
-		tmp[i++] = '0' + src[octet] % 10;
-		tmp[i++] = '.';
-	}
-	tmp[i - 1] = '\0';
-
-	if ((socklen_t)strlen(tmp)>size) {
-		//__set_errno (ENOSPC);
-		return (NULL);
-	}
-
-	return strcpy(dst, tmp);
-}
-
-
-/* const char *
- * inet_ntop6(src, dst, size)
- *	convert IPv6 binary address into presentation (printable) format
- * author:
- *	Paul Vixie, 1996.
- */
-
-#ifdef INET_IPV6
-
-static const char *
-inet_ntop6(src, dst, size)
-	const u_char *src;
-	char *dst;
-	socklen_t size;
-{
-	/*
-	 * Note that int32_t and int16_t need only be "at least" large enough
-	 * to contain a value of the specified size.  On some systems, like
-	 * Crays, there is no such thing as an integer variable with 16 bits.
-	 * Keep this in mind if you think this function should have been coded
-	 * to use pointer overlays.  All the world's not a VAX.
-	 */
-	char tmp[sizeof ("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")], *tp;
-	struct { int base, len; } best, cur;
-	u_int words[8];
-	int i;
-
-	/*
-	 * Preprocess:
-	 *	Copy the input (bytewise) array into a wordwise array.
-	 *	Find the longest run of 0x00's in src[] for :: shorthanding.
-	 */
-	memset(words, '\0', sizeof words);
-	for (i = 0; i < 16; i += 2)
-		words[i / 2] = (src[i] << 8) | src[i + 1];
-	best.base = -1;
-	cur.base = -1;
-	for (i = 0; i < 8; i++) {
-		if (words[i] == 0) {
-			if (cur.base == -1)
-				cur.base = i, cur.len = 1;
-			else
-				cur.len++;
-		} else {
-			if (cur.base != -1) {
-				if (best.base == -1 || cur.len best.len)
-					best = cur;
-				cur.base = -1;
-			}
-		}
-	}
-	if (cur.base != -1) {
-		if (best.base == -1 || cur.len best.len)
-			best = cur;
-	}
-	if (best.base != -1 && best.len < 2)
-		best.base = -1;
-
-	/*
-	 * Format the result.
-	 */
-	tp = tmp;
-	for (i = 0; i < 8; i++) {
-		/* Are we inside the best run of 0x00's? */
-		if (best.base != -1 && i >= best.base &&
-		    i < (best.base + best.len)) {
-			if (i == best.base)
-				*tp++ = ':';
-			continue;
-		}
-		/* Are we following an initial run of 0x00s or any real hex? */
-		if (i != 0)
-			*tp++ = ':';
-		/* Is this address an encapsulated IPv4? */
-		if (i == 6 && best.base == 0 &&
-		    (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
-			if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
-				return (NULL);
-			tp += strlen(tp);
-			break;
-		}
-		tp += SPRINTF((tp, "%x", words[i]));
-	}
-	/* Was it a trailing run of 0x00's? */
-	if (best.base != -1 && (best.base + best.len) == 8)
-		*tp++ = ':';
-	*tp++ = '\0';
-
-	/*
-	 * Check for overflow, copy, and we're done.
-	 */
-	if ((socklen_t)(tp - tmp) size) {
-		//__set_errno (ENOSPC);
-		return (NULL);
-	}
-	return strcpy(dst, tmp);
-}
-#endif /* INET_IPV6 */
-
-
-/* int
- * inet_pton4(src, dst)
- *	like inet_aton() but without all the hexadecimal and shorthand.
- * return:
- *	1 if `src' is a valid dotted quad, else 0.
- * notice:
- *	does not touch `dst' unless it's returning 1.
- * author:
- *	Paul Vixie, 1996.
- */
-static int
-inet_pton4(const char *src,u_char *dst)
-{
-	int saw_digit, octets, ch;
-	u_char tmp[4], *tp;
-
-	saw_digit = 0;
-	octets = 0;
-	*(tp = tmp) = 0;
-	while ((ch = *src++) != '\0') {
-
-		if (ch >= '0' && ch <= '9') {
-			u_int new = *tp * 10 + (ch - '0');
-
-			if (new>255)
-				return (0);
-			*tp = new;
-			if (! saw_digit) {
-				if (++octets>4)
-					return (0);
-				saw_digit = 1;
-			}
-		} else if (ch == '.' && saw_digit) {
-			if (octets == 4)
-				return (0);
-			*++tp = 0;
-			saw_digit = 0;
-		} else
-			return (0);
-	}
-	if (octets < 4)
-		return (0);
-	memcpy(dst, tmp, 4);
-	return (1);
-}
-
-/* int
- * inet_pton6(src, dst)
- *	convert presentation level address to network order binary form.
- * return:
- *	1 if `src' is a valid [RFC1884 2.2] address, else 0.
- * notice:
- *	(1) does not touch `dst' unless it's returning 1.
- *	(2) :: in a full address is silently ignored.
- * credit:
- *	inspired by Mark Andrews.
- * author:
- *	Paul Vixie, 1996.
- */
-
-#ifdef INET_IPV6
-
-static int
-inet_pton6(src, dst)
-	const char *src;
-	u_char *dst;
-{
-	static const char xdigits[] = "0123456789abcdef";
-	u_char tmp[16], *tp, *endp, *colonp;
-	const char *curtok;
-	int ch, saw_xdigit;
-	u_int val;
-
-	tp = memset(tmp, '\0', 16);
-	endp = tp + 16;
-	colonp = NULL;
-	/* Leading :: requires some special handling. */
-	if (*src == ':')
-		if (*++src != ':')
-			return (0);
-	curtok = src;
-	saw_xdigit = 0;
-	val = 0;
-	while ((ch = tolower (*src++)) != '\0') {
-		const char *pch;
-
-		pch = strchr(xdigits, ch);
-		if (pch != NULL) {
-			val <<= 4;
-			val |= (pch - xdigits);
-			if (val 0xffff)
-				return (0);
-			saw_xdigit = 1;
-			continue;
-		}
-		if (ch == ':') {
-			curtok = src;
-			if (!saw_xdigit) {
-				if (colonp)
-					return (0);
-				colonp = tp;
-				continue;
-			} else if (*src == '\0') {
-				return (0);
-			}
-			if (tp + 2 endp)
-				return (0);
-			*tp++ = (u_char) (val >8) & 0xff;
-			*tp++ = (u_char) val & 0xff;
-			saw_xdigit = 0;
-			val = 0;
-			continue;
-		}
-		if (ch == '.' && ((tp + 4) <= endp) &&
-		    inet_pton4(curtok, tp) 0) {
-			tp += 4;
-			saw_xdigit = 0;
-			break;	/* '\0' was seen by inet_pton4(). */
-		}
-		return (0);
-	}
-	if (saw_xdigit) {
-		if (tp + 2 endp)
-			return (0);
-		*tp++ = (u_char) (val >8) & 0xff;
-		*tp++ = (u_char) val & 0xff;
-	}
-	if (colonp != NULL) {
-		/*
-		 * Since some memmove()'s erroneously fail to handle
-		 * overlapping regions, we'll do the shift by hand.
-		 */
-		const int n = tp - colonp;
-		int i;
-
-		if (tp == endp)
-			return (0);
-		for (i = 1; i <= n; i++) {
-			endp[- i] = colonp[n - i];
-			colonp[n - i] = 0;
-		}
-		tp = endp;
-	}
-	if (tp != endp)
-		return (0);
-	memcpy(dst, tmp, 16);
-	return (1);
-}
-
-#endif /* INET_IPV6 */
-
-
-
-/* char *
- * inet_ntop(af, src, dst, size)
- *	convert a network format address to presentation format.
- * return:
- *	pointer to presentation format address (`dst'), or NULL (see errno).
- * author:
- *	Paul Vixie, 1996.
- */
-extern const char *inet_ntop(int af,const void *src,char *dst,socklen_t size)
-{
-	switch (af) {
-	case AF_INET:
-		return (inet_ntop4(src, dst, size));
-#ifdef INET_IPV6
-	case AF_INET6:
-		return (inet_ntop6(src, dst, size));
-#endif
-	default:
-		//__set_errno (EAFNOSUPPORT);
-		return (NULL);
-	}
-	/* NOTREACHED */
-}
-
-
-/* int
- * inet_pton(af, src, dst)
- *	convert from presentation format (which usually means ASCII printable)
- *	to network format (which is usually some kind of binary format).
- * return:
- *	1 if the address was valid for the specified address family
- *	0 if the address wasn't valid (`dst' is untouched in this case)
- *	-1 if some other error occurred (`dst' is untouched in this case, too)
- * author:
- *	Paul Vixie, 1996.
- */
-int inet_pton(int af,const char *src,void *dst)
-{
-	switch (af) {
-	case AF_INET:
-		return (inet_pton4(src, dst));
-#ifdef INET_IPV6
-	case AF_INET6:
-		return (inet_pton6(src, dst));
-#endif
-	default:
-		//__set_errno (EAFNOSUPPORT);
-		return (-1);
-	}
-	/* NOTREACHED */
-}
-#endif
diff --git a/tombupnp/upnp/src/soap/soap_common.c b/tombupnp/upnp/src/soap/soap_common.c
deleted file mode 100644
index 5a20a79..0000000
--- a/tombupnp/upnp/src/soap/soap_common.c
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#if EXCLUDE_SOAP == 0
-
-#include "httpparser.h"
-#include "sock.h"
-#include "soaplib.h"
-
-
-
-#endif // EXCLUDE_SOAP
diff --git a/tombupnp/upnp/src/soap/soap_ctrlpt.c b/tombupnp/upnp/src/soap/soap_ctrlpt.c
deleted file mode 100644
index 4c9145d..0000000
--- a/tombupnp/upnp/src/soap/soap_ctrlpt.c
+++ /dev/null
@@ -1,988 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#ifdef INCLUDE_CLIENT_APIS
-#if EXCLUDE_SOAP == 0
-
-#include <assert.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "miniserver.h"
-#include "membuffer.h"
-#include "httpparser.h"
-#include "httpreadwrite.h"
-#include "statcodes.h"
-#include "parsetools.h"
-#include "upnpapi.h"
-#include "soaplib.h"
-#include "uri.h"
-#include "upnp.h"
-
-#include "unixutil.h"
-
-#define SOAP_ACTION_RESP	1
-#define SOAP_VAR_RESP		2
-//#define SOAP_ERROR_RESP       3
-#define SOAP_ACTION_RESP_ERROR  3
-#define SOAP_VAR_RESP_ERROR   4
-
-/****************************************************************************
-*	Function :	dom_cmp_name
-*
-*	Parameters :
-*			IN char *name :	lookup name
-*			IN IXML_Node *node : xml node
-*
-*	Description : This function compares 'name' and node's name	
-*
-*	Return : int
-*		0 if both are equal; 1 if not equal, and UPNP_E_OUTOF_MEMORY
-*
-*	Note :
-****************************************************************************/
-static int
-dom_cmp_name( IN char *name,
-              IN IXML_Node * node )
-{
-    const DOMString node_name = NULL;
-    memptr nameptr,
-      dummy;
-    int ret_code;
-
-    assert( name );
-    assert( node );
-
-    node_name = ixmlNode_getNodeName( node );
-    if( node_name == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    if( strcmp( name, node_name ) == 0 ) {
-        ret_code = 0;
-    } else if( matchstr( ( char * )node_name, strlen( node_name ),
-                         "%s:%s%0", &dummy, &nameptr ) == PARSE_OK &&
-               strcmp( nameptr.buf, name ) == 0 ) {
-        ret_code = 0;
-    } else {
-        ret_code = 1;           // names are not the same
-    }
-
-    return ret_code;
-}
-
-/****************************************************************************
-*	Function :	dom_find_node
-*
-*	Parameters :
-*			IN char* node_name : name of the node	
-*			IN IXML_Node *start_node :	complete xml node
-*			OUT IXML_Node ** matching_node : matched node
-*
-*	Description :	This function goes thru each child of 'start_node' 
-*		looking for a node having the name 'node_name'. 
-*
-*	Return : int
-*		return UPNP_E_SUCCESS if successful else returns appropriate error
-*
-*	Note :
-****************************************************************************/
-static int
-dom_find_node( IN char *node_name,
-               IN IXML_Node * start_node,
-               OUT IXML_Node ** matching_node )
-{
-    IXML_Node *node;
-
-    // invalid args
-    if( node_name == NULL || start_node == NULL ) {
-        return UPNP_E_NOT_FOUND;
-    }
-
-    node = ixmlNode_getFirstChild( start_node );
-    while( node != NULL ) {
-        // match name
-        if( dom_cmp_name( node_name, node ) == 0 ) {
-            *matching_node = node;
-            return UPNP_E_SUCCESS;
-        }
-        // free and next node
-        node = ixmlNode_getNextSibling( node ); // next node
-    }
-
-    return UPNP_E_NOT_FOUND;
-}
-
-/****************************************************************************
-*	Function :	dom_find_deep_node
-*
-*	Parameters :
-*			IN char* names[] : array of names
-*			IN int num_names :	size of array
-*			IN IXML_Node *start_node : Node from where it should should be 
-*										searched	
-*			OUT IXML_Node ** matching_node : Node that matches the last name
-*											of the array
-*
-*	Description :	This function searches for the node specifed by the last 
-*		name in the 'name' array.
-*
-*	Return : int
-*		return UPNP_E_SUCCESS if successful else returns appropriate error
-*	Note :
-****************************************************************************/
-static int
-dom_find_deep_node( IN char *names[],
-                    IN int num_names,
-                    IN IXML_Node * start_node,
-                    OUT IXML_Node ** matching_node )
-{
-    int i;
-    IXML_Node *node;
-    IXML_Node *match_node;
-
-    assert( num_names > 0 );
-
-    node = start_node;
-    if( dom_cmp_name( names[0], start_node ) == 0 ) {
-        if( num_names == 1 ) {
-            *matching_node = start_node;
-            return UPNP_E_SUCCESS;
-        }
-    }
-
-    for( i = 1; i < num_names; i++ ) {
-        if( dom_find_node( names[i], node, &match_node ) !=
-            UPNP_E_SUCCESS ) {
-            return UPNP_E_NOT_FOUND;
-        }
-
-        if( i == num_names - 1 ) {
-            *matching_node = match_node;
-            return UPNP_E_SUCCESS;
-        }
-
-        node = match_node;      // try again
-    }
-
-    return UPNP_E_NOT_FOUND;    // this line not reached
-}
-
-/****************************************************************************
-*	Function :	get_node_value
-*
-*	Parameters :
-*			IN IXML_Node *node : input node	
-*
-*	Description :	This function returns the value of the text node
-*
-*	Return : DOMString
-*		string containing the node value
-*
-*	Note :The given node must have a text node as its first child
-****************************************************************************/
-static const DOMString
-get_node_value( IN IXML_Node * node )
-{
-    IXML_Node *text_node = NULL;
-    const DOMString text_value = NULL;
-
-    text_node = ixmlNode_getFirstChild( node );
-    if( text_node == NULL ) {
-        return NULL;
-    }
-
-    text_value = ixmlNode_getNodeValue( text_node );
-    return text_value;
-}
-
-/****************************************************************************
-*	Function :	get_host_and_path
-*
-*	Parameters :
-*			IN char *ctrl_url :	URL 
-*			OUT memptr *host :	host string
-*			OUT memptr *path :	path string
-*			OUT uri_type* url :	URL type
-*
-*	Description :	This function retrives the host and path from the 
-*		control URL
-*
-*	Return : int
-*		returns 0 on sucess; -1 on error
-*
-*	Note :
-****************************************************************************/
-static XINLINE int
-get_host_and_path( IN char *ctrl_url,
-                   OUT const memptr *host,
-                   OUT const memptr *path,
-                   OUT uri_type * url )
-{
-    if( parse_uri( ctrl_url, strlen( ctrl_url ), url ) != HTTP_SUCCESS ) {
-        return -1;
-    }
-    // This is done to ensure that the buffer is kept const
-    ((memptr *)host)->buf = (char *)url->hostport.text.buff;
-    ((memptr *)host)->length = url->hostport.text.size;
-
-    ((memptr *)path)->buf = (char *)url->pathquery.buff;
-    ((memptr *)path)->length = url->pathquery.size;
-
-    return 0;
-}
-
-/****************************************************************************
-*	Function :	get_action_name
-*
-*	Parameters :
-*			IN char* action :	string containing action name
-*			OUT memptr* name : name of the action	
-*
-*	Description :	This functions retirves the action name in the buffer
-*
-*	Return : int
-*		returns 0 on success; -1 on error
-*
-*	Note :
-****************************************************************************/
-static XINLINE int
-get_action_name( IN char *action,
-                 OUT memptr * name )
-{
-    memptr dummy;
-    int ret_code;
-
-    ret_code =
-        matchstr( action, strlen( action ), " <%s:%s", &dummy, name );
-
-    return ret_code == PARSE_OK ? 0 : -1;
-}
-
-/****************************************************************************
-*	Function :	add_man_header
-*
-*	Parameters :
-*			INOUT membuffer* headers :	HTTP header
-*
-*	Description :	This function adds "MAN" field in the HTTP header
-*
-*	Return : int
-*		returns 0 on success; UPNP_E_OUTOFMEMORY on error
-*
-*	Note :
-****************************************************************************/
-static XINLINE int
-add_man_header( INOUT membuffer * headers )
-{
-    char *soap_action_hdr;
-    char *man_hdr = "MAN: \"http://schemas.xmlsoap.org/soap/envelope/\"; "
-        "ns=01\r\n01-";
-
-    // change POST to M-POST
-    if( membuffer_insert( headers, "M-", 2, 0 ) != 0 ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    soap_action_hdr = strstr( headers->buf, "SOAPACTION:" );
-    assert( soap_action_hdr != NULL );  // can't fail
-
-    // insert MAN header
-    if( membuffer_insert( headers, man_hdr, strlen( man_hdr ),
-                          soap_action_hdr - headers->buf ) != 0 ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    return 0;
-}
-
-/****************************************************************************
-*	Function :	soap_request_and_response
-*
-*	Parameters :
-*		IN membuffer* request :	request that will be sent to the device
-*		IN uri_type* destination_url :	destination address string
-*		OUT http_parser_t *response :	response from the device
-*
-*	Description :	This function sends the control point's request to the 
-*		device and receives a response from it.
-*
-*	Return : int
-*
-*	Note :
-****************************************************************************/
-static int
-soap_request_and_response( IN membuffer * request,
-                           IN uri_type * destination_url,
-                           OUT http_parser_t * response )
-{
-    int ret_code;
-
-    ret_code = http_RequestAndResponse( destination_url, request->buf,
-                                        request->length,
-                                        SOAPMETHOD_POST,
-                                        UPNP_TIMEOUT, response );
-    if( ret_code != 0 ) {
-        httpmsg_destroy( &response->msg );
-        return ret_code;
-    }
-    // method-not-allowed error
-    if( response->msg.status_code == HTTP_METHOD_NOT_ALLOWED ) {
-        ret_code = add_man_header( request );   // change to M-POST msg
-        if( ret_code != 0 ) {
-            return ret_code;
-        }
-
-        httpmsg_destroy( &response->msg );  // about to reuse response
-
-        // try again
-        ret_code = http_RequestAndResponse( destination_url, request->buf,
-                                            HTTPMETHOD_MPOST,
-                                            request->length, UPNP_TIMEOUT,
-                                            response );
-        if( ret_code != 0 ) {
-            httpmsg_destroy( &response->msg );
-        }
-
-    }
-
-    return ret_code;
-}
-
-/****************************************************************************
-*	Function :	get_response_value
-*
-*	Parameters :
-*			IN http_message_t* hmsg :	HTTP response message
-*			IN int code :	return code in the HTTP response
-*			IN char*name :	name of the action
-*			OUT int *upnp_error_code :	UPnP error code
-*			OUT IXML_Node ** action_value :	SOAP response node 
-*			OUT DOMString * str_value : state varible value ( in the case of 
-*							querry state variable request)	
-*
-*	Description :	This function handles the response coming back from the 
-*		device. This function parses the response and gives back the SOAP 
-*		response node.
-*
-*	Return : int
-*		return the type of the SOAP message if successful else returns 
-*	appropriate error.
-*
-*	Note :
-****************************************************************************/
-static int
-get_response_value( IN http_message_t * hmsg,
-                    IN int code,
-                    IN char *name,
-                    OUT int *upnp_error_code,
-                    OUT IXML_Node ** action_value,
-                    OUT DOMString * str_value )
-{
-    IXML_Node *node = NULL;
-    IXML_Node *root_node = NULL;
-    IXML_Node *error_node = NULL;
-    IXML_Document *doc = NULL;
-    char *node_str = NULL;
-    const char *temp_str = NULL;
-    DOMString error_node_str = NULL;
-    int err_code;
-    xboolean done = FALSE;
-    char *names[5];
-    const DOMString nodeValue;
-
-    err_code = UPNP_E_BAD_RESPONSE; // default error
-
-    // only 200 and 500 status codes are relevant
-    if( ( hmsg->status_code != HTTP_OK &&
-          hmsg->status_code != HTTP_INTERNAL_SERVER_ERROR ) ||
-        !has_xml_content_type( hmsg ) ) {
-
-        goto error_handler;
-    }
-
-    if( ixmlParseBufferEx( hmsg->entity.buf, &doc ) != IXML_SUCCESS ) {
-
-        goto error_handler;
-    }
-
-    root_node = ixmlNode_getFirstChild( ( IXML_Node * ) doc );
-    if( root_node == NULL ) {
-
-        goto error_handler;
-    }
-
-    if( code == SOAP_ACTION_RESP ) {
-        //
-        // try reading soap action response
-        //
-        assert( action_value != NULL );
-
-        *action_value = NULL;
-
-        names[0] = "Envelope";
-        names[1] = "Body";
-        names[2] = name;
-        if( dom_find_deep_node( names, 3, root_node, &node ) ==
-            UPNP_E_SUCCESS ) {
-            node_str = ixmlPrintNode( node );
-            if( node_str == NULL ) {
-                err_code = UPNP_E_OUTOF_MEMORY;
-                goto error_handler;
-            }
-
-            if( ixmlParseBufferEx( node_str,
-                                   ( IXML_Document ** ) action_value ) !=
-                IXML_SUCCESS ) {
-                err_code = UPNP_E_BAD_RESPONSE;
-                goto error_handler;
-            }
-
-            err_code = SOAP_ACTION_RESP;
-            done = TRUE;
-        }
-    } else if( code == SOAP_VAR_RESP ) {
-        // try reading var response
-        assert( str_value != NULL );
-        *str_value = NULL;
-
-        names[0] = "Envelope";
-        names[1] = "Body";
-        names[2] = "QueryStateVariableResponse";
-        names[3] = "return";
-        if( dom_find_deep_node( names, 4, root_node, &node )
-            == UPNP_E_SUCCESS ) {
-            nodeValue = get_node_value( node );
-            if( nodeValue == NULL ) {
-                goto error_handler;
-            }
-
-            *str_value = ixmlCloneDOMString( nodeValue );
-            err_code = SOAP_VAR_RESP;
-            done = TRUE;
-        }
-    }
-
-    if( !done ) {
-        // not action or var resp; read error code and description
-        *str_value = NULL;
-
-        names[0] = "Envelope";
-        names[1] = "Body";
-        names[2] = "Fault";
-        names[3] = "detail";
-        names[4] = "UPnPError";
-        if( dom_find_deep_node( names, 5, root_node, &error_node )
-            != UPNP_E_SUCCESS ) {
-            goto error_handler;
-        }
-
-        if( dom_find_node( "errorCode", error_node, &node )
-            != UPNP_E_SUCCESS ) {
-            goto error_handler;
-        }
-
-        temp_str = get_node_value( node );
-        if( temp_str == NULL ) {
-            goto error_handler;
-        }
-
-        *upnp_error_code = atoi( temp_str );
-        if( *upnp_error_code > 400 ) {
-            err_code = *upnp_error_code;
-            goto error_handler; // bad SOAP error code
-        }
-
-        if( code == SOAP_VAR_RESP ) {
-            if( dom_find_node( "errorDescription", error_node, &node )
-                != UPNP_E_SUCCESS ) {
-                goto error_handler;
-            }
-
-            nodeValue = get_node_value( node );
-            if( nodeValue == NULL ) {
-                goto error_handler;
-            }
-            *str_value = ixmlCloneDOMString( nodeValue );
-            if( *str_value == NULL ) {
-                goto error_handler;
-            }
-            err_code = SOAP_VAR_RESP_ERROR;
-        }
-
-        else if( code == SOAP_ACTION_RESP ) {
-            error_node_str = ixmlPrintNode( error_node );
-            if( error_node_str == NULL ) {
-                err_code = UPNP_E_OUTOF_MEMORY;
-                goto error_handler;
-            }
-
-            if( ixmlParseBufferEx( error_node_str,
-                                   ( IXML_Document ** ) action_value ) !=
-                IXML_SUCCESS ) {
-                err_code = UPNP_E_BAD_RESPONSE;
-
-                goto error_handler;
-            }
-            err_code = SOAP_ACTION_RESP_ERROR;
-        }
-    }
-
-  error_handler:
-
-    ixmlDocument_free( doc );
-    ixmlFreeDOMString( node_str );
-    ixmlFreeDOMString( error_node_str );
-    return err_code;
-}
-
-/****************************************************************************
-*	Function :	SoapSendAction
-*
-*	Parameters :
-*		IN char* action_url :	device contrl URL 
-*		IN char *service_type :	device service type
-*		IN IXML_Document *action_node : SOAP action node	
-*		OUT IXML_Document **response_node :	SOAP response node
-*
-*	Description :	This function is called by UPnP API to send the SOAP 
-*		action request and waits till it gets the response from the device
-*		pass the response to the API layer
-*
-*	Return :	int
-*		returns UPNP_E_SUCCESS if successful else returns appropriate error
-*	Note :
-****************************************************************************/
-int
-SoapSendAction( IN char *action_url,
-                IN char *service_type,
-                IN IXML_Document * action_node,
-                OUT IXML_Document ** response_node )
-{
-    char *action_str = NULL;
-    memptr name;
-    membuffer request;
-    membuffer responsename;
-    int err_code;
-    int ret_code;
-    http_parser_t response;
-    uri_type url;
-    int upnp_error_code;
-    char *upnp_error_str;
-    xboolean got_response = FALSE;
-
-    char *xml_start =
-        "<s:Envelope "
-        "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
-        "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n"
-        "<s:Body>";
-    char *xml_end =
-        "</s:Body>\r\n"
-        "</s:Envelope>\r\n\r\n";
-    int xml_start_len;
-    int xml_end_len;
-    int action_str_len;
-
-    *response_node = NULL;      // init
-
-    err_code = UPNP_E_OUTOF_MEMORY; // default error
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
-                         "Inside SoapSendAction():" );
-         )
-        // init
-        membuffer_init( &request );
-    membuffer_init( &responsename );
-
-    // print action
-    action_str = ixmlPrintNode( ( IXML_Node * ) action_node );
-    if( action_str == NULL ) {
-        goto error_handler;
-    }
-    // get action name
-    if( get_action_name( action_str, &name ) != 0 ) {
-        err_code = UPNP_E_INVALID_ACTION;
-        goto error_handler;
-    }
-    // parse url
-    if( http_FixStrUrl( action_url, strlen( action_url ), &url ) != 0 ) {
-        err_code = UPNP_E_INVALID_URL;
-        goto error_handler;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
-                         "path=%.*s, hostport=%.*s\n",
-                         url.pathquery.size, url.pathquery.buff,
-                         url.hostport.text.size,
-                         url.hostport.text.buff ); )
-
-        xml_start_len = strlen( xml_start );
-    xml_end_len = strlen( xml_end );
-    action_str_len = strlen( action_str );
-
-    // make request msg
-    request.size_inc = 50;
-    if( http_MakeMessage( &request, 1, 1, "q" "N" "s" "sssbs" "UC" "c" "bbb", 
-                          SOAPMETHOD_POST, 
-                          &url, (off_t)(xml_start_len + action_str_len + xml_end_len),   // content-length
-                          ContentTypeHeader,
-                          "SOAPACTION: \"", service_type, "#", name.buf,
-                          (size_t)name.length, "\"", 
-                          xml_start, (size_t)xml_start_len,
-                          action_str, (size_t)action_str_len, xml_end,
-                          (size_t)xml_end_len ) != 0 ) {
-        goto error_handler;
-    }
-
-    ret_code = soap_request_and_response( &request, &url, &response );
-    got_response = TRUE;
-    if( ret_code != UPNP_E_SUCCESS ) {
-        err_code = ret_code;
-        goto error_handler;
-    }
-
-    if( membuffer_append( &responsename, name.buf, name.length ) != 0 ||
-        membuffer_append_str( &responsename, "Response" ) != 0 ) {
-        goto error_handler;
-    }
-    // get action node from the response
-    ret_code = get_response_value( &response.msg, SOAP_ACTION_RESP,
-                                   responsename.buf, &upnp_error_code,
-                                   ( IXML_Node ** ) response_node,
-                                   &upnp_error_str );
-
-    if( ret_code == SOAP_ACTION_RESP ) {
-        err_code = UPNP_E_SUCCESS;
-    } else if( ret_code == SOAP_ACTION_RESP_ERROR ) {
-        err_code = upnp_error_code;
-    } else {
-        err_code = ret_code;
-    }
-
-  error_handler:
-    ixmlFreeDOMString( action_str );
-    membuffer_destroy( &request );
-    membuffer_destroy( &responsename );
-    if( got_response ) {
-        httpmsg_destroy( &response.msg );
-    }
-
-    return err_code;
-}
-
-/****************************************************************************
-*	Function :	SoapSendActionEx
-*
-*	Parameters :
-*		IN char* action_url :	device contrl URL 
-*		IN char *service_type :	device service type
-		IN IXML_Document *Header: Soap header
-*		IN IXML_Document *action_node : SOAP action node ( SOAP body)	
-*		OUT IXML_Document **response_node :	SOAP response node
-*
-*	Description :	This function is called by UPnP API to send the SOAP 
-*		action request and waits till it gets the response from the device
-*		pass the response to the API layer. This action is similar to the 
-*		the SoapSendAction with only difference that it allows users to 
-*		pass the SOAP header along the SOAP body ( soap action request)
-*
-*	Return :	int
-*		returns UPNP_E_SUCCESS if successful else returns appropriate error
-*	Note :
-****************************************************************************/
-int
-SoapSendActionEx( IN char *action_url,
-                  IN char *service_type,
-                  IN IXML_Document * header,
-                  IN IXML_Document * action_node,
-                  OUT IXML_Document ** response_node )
-{
-    char *xml_header_str = NULL;
-    char *action_str = NULL;
-    memptr name;
-    membuffer request;
-    membuffer responsename;
-    int err_code;
-    int ret_code;
-    http_parser_t response;
-    uri_type url;
-    int upnp_error_code;
-    char *upnp_error_str;
-    xboolean got_response = FALSE;
-
-    char *xml_start =
-        "<s:Envelope "
-        "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
-        "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n";
-    char *xml_header_start =
-        "<s:Header>\r\n";
-    char *xml_header_end =
-        "</s:Header>\r\n";
-    char *xml_body_start =
-        "<s:Body>";
-    char *xml_end =
-        "</s:Body>\r\n"
-        "</s:Envelope>\r\n";
-    int xml_start_len;
-    int xml_header_start_len;
-    int xml_header_str_len;
-    int xml_header_end_len;
-    int xml_body_start_len;
-    int action_str_len;
-    int xml_end_len;
-
-    *response_node = NULL;      // init
-
-    err_code = UPNP_E_OUTOF_MEMORY; // default error
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
-                         "Inside SoapSendActionEx():" );
-         )
-        // init
-        membuffer_init( &request );
-    membuffer_init( &responsename );
-
-    // header string
-    xml_header_str = ixmlPrintNode( ( IXML_Node * ) header );
-    if( xml_header_str == NULL ) {
-        goto error_handler;
-    }
-    // print action
-    action_str = ixmlPrintNode( ( IXML_Node * ) action_node );
-    if( action_str == NULL ) {
-        goto error_handler;
-    }
-    // get action name
-    if( get_action_name( action_str, &name ) != 0 ) {
-        err_code = UPNP_E_INVALID_ACTION;
-        goto error_handler;
-    }
-    // parse url
-    if( http_FixStrUrl( action_url, strlen( action_url ), &url ) != 0 ) {
-        err_code = UPNP_E_INVALID_URL;
-        goto error_handler;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
-                         "path=%.*s, hostport=%.*s\n",
-                         url.pathquery.size, url.pathquery.buff,
-                         url.hostport.text.size,
-                         url.hostport.text.buff ); )
-
-        xml_start_len = strlen( xml_start );
-    xml_body_start_len = strlen( xml_body_start );
-    xml_end_len = strlen( xml_end );
-    action_str_len = strlen( action_str );
-
-    xml_header_start_len = strlen( xml_header_start );
-    xml_header_end_len = strlen( xml_header_end );
-    xml_header_str_len = strlen( xml_header_str );
-
-    // make request msg
-    request.size_inc = 50;
-    if( http_MakeMessage( &request, 1, 1, "q" "N" "s" "sssbs" "UC" "c" "bbbbbbb", 
-                          SOAPMETHOD_POST, 
-                          &url, (off_t)(xml_start_len + 
-                                        xml_header_start_len + 
-                                        xml_header_str_len + 
-                                        xml_header_end_len + 
-                                        xml_body_start_len + 
-                                        action_str_len + 
-                                        xml_end_len), // content-length
-                          ContentTypeHeader,
-                          "SOAPACTION: \"", service_type, "#", name.buf,
-                          (size_t)name.length, "\"",
-                          xml_start, (size_t)xml_start_len,
-                          xml_header_start, (size_t)xml_header_start_len,
-                          xml_header_str, (size_t)xml_header_str_len,
-                          xml_header_end, (size_t)xml_header_end_len,
-                          xml_body_start, (size_t)xml_body_start_len,
-                          action_str, (size_t)action_str_len,
-                          xml_end, (size_t)xml_end_len ) != 0 ) {
-        goto error_handler;
-    }
-
-    ret_code = soap_request_and_response( &request, &url, &response );
-    got_response = TRUE;
-    if( ret_code != UPNP_E_SUCCESS ) {
-        err_code = ret_code;
-        goto error_handler;
-    }
-
-    if( membuffer_append( &responsename, name.buf, name.length ) != 0 ||
-        membuffer_append_str( &responsename, "Response" ) != 0 ) {
-        goto error_handler;
-    }
-    // get action node from the response
-    ret_code = get_response_value( &response.msg, SOAP_ACTION_RESP,
-                                   responsename.buf, &upnp_error_code,
-                                   ( IXML_Node ** ) response_node,
-                                   &upnp_error_str );
-
-    if( ret_code == SOAP_ACTION_RESP ) {
-        err_code = UPNP_E_SUCCESS;
-    } else if( ret_code == SOAP_ACTION_RESP_ERROR ) {
-        err_code = upnp_error_code;
-    } else {
-        err_code = ret_code;
-    }
-
-  error_handler:
-
-    ixmlFreeDOMString( action_str );
-    ixmlFreeDOMString( xml_header_str );
-    membuffer_destroy( &request );
-    membuffer_destroy( &responsename );
-    if( got_response ) {
-        httpmsg_destroy( &response.msg );
-    }
-
-    return err_code;
-}
-
-/****************************************************************************
-*	Function :	SoapGetServiceVarStatus
-*
-*	Parameters :
-*			IN  char * action_url :	Address to send this variable 
-*									query message.
-*			IN  char *var_name : Name of the variable.
-*			OUT char **var_value :	Output value.
-*
-*	Description :	This function creates a status variable query message 
-*		send it to the specified URL. It also collect the response.
-*
-*	Return :	int
-*
-*	Note :
-****************************************************************************/
-int
-SoapGetServiceVarStatus( IN char *action_url,
-                         IN char *var_name,
-                         OUT char **var_value )
-{
-    const memptr host;                // value for HOST header
-    const memptr path;                // ctrl path in first line in msg
-    uri_type url;
-    membuffer request;
-    int ret_code;
-    http_parser_t response;
-    int upnp_error_code;
-
-    char *xml_start =
-        "<s:Envelope "
-        "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
-        "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n"
-        "<s:Body>\r\n"
-        "<u:QueryStateVariable xmlns:u=\"urn:schemas-upnp-org:control-1-0\">\r\n"
-        "<u:varName>";
-
-    char *xml_end =
-        "</u:varName>\r\n"
-        "</u:QueryStateVariable>\r\n"
-        "</s:Body>\r\n"
-        "</s:Envelope>\r\n";
-
-    *var_value = NULL;          // return NULL in case of an error
-
-    membuffer_init( &request );
-
-    // get host hdr and url path
-    if( get_host_and_path( action_url, &host, &path, &url ) == -1 ) {
-        return UPNP_E_INVALID_URL;
-    }
-    // make headers
-    request.size_inc = 50;
-    if( http_MakeMessage( &request, 1, 1, "Q" "sbc" "N" "s" "s" "UC" "c" "sss", 
-                          SOAPMETHOD_POST, 
-                          path.buf, 
-                          (size_t)path.length, 
-                          "HOST: ", 
-                          host.buf, 
-                          (size_t)host.length, 
-                          (off_t)(strlen( xml_start ) + strlen( var_name ) + strlen( xml_end )),   // content-length
-                          ContentTypeHeader,
-                          "SOAPACTION: \"urn:schemas"
-                          "-upnp-org:control-1-0#QueryStateVariable\"\r\n",
-                          xml_start, var_name, xml_end ) != 0 ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    // send msg and get reply
-    ret_code = soap_request_and_response( &request, &url, &response );
-    membuffer_destroy( &request );
-    if( ret_code != UPNP_E_SUCCESS ) {
-        return ret_code;
-    }
-    // get variable value from the response
-    ret_code = get_response_value( &response.msg, SOAP_VAR_RESP, NULL,
-                                   &upnp_error_code, NULL, var_value );
-
-    httpmsg_destroy( &response.msg );
-
-    if( ret_code == SOAP_VAR_RESP ) {
-        return UPNP_E_SUCCESS;
-    } else if( ret_code == SOAP_VAR_RESP_ERROR ) {
-        return upnp_error_code;
-    } else {
-        return ret_code;
-    }
-}
-
-#endif // EXCLUDE_SOAP
-#endif // INCLUDE_CLIENT_APIS
diff --git a/tombupnp/upnp/src/soap/soap_device.c b/tombupnp/upnp/src/soap/soap_device.c
deleted file mode 100644
index 19740e2..0000000
--- a/tombupnp/upnp/src/soap/soap_device.c
+++ /dev/null
@@ -1,1096 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#ifdef INCLUDE_DEVICE_APIS
-#if EXCLUDE_SOAP == 0
-
-#define SOAP_BODY "Body"
-#define SOAP_URN "http:/""/schemas.xmlsoap.org/soap/envelope/"
-
-#define QUERY_STATE_VAR_URN "urn:schemas-upnp-org:control-1-0"
-
-#include "upnpapi.h"
-#include "parsetools.h"
-#include "statcodes.h"
-#include "httpparser.h"
-#include "httpreadwrite.h"
-#include "unixutil.h"
-#include "soaplib.h"
-#include "ssdplib.h"
-
-#ifdef WIN32
- #define snprintf _snprintf
-#endif
-
-// timeout duration in secs for transmission/reception
-#define SOAP_TIMEOUT UPNP_TIMEOUT
-
-#define SREQ_HDR_NOT_FOUND	 -1
-#define SREQ_BAD_HDR_FORMAT	 -2
-
-#define SOAP_INVALID_ACTION 401
-#define SOAP_INVALID_ARGS	402
-#define SOAP_OUT_OF_SYNC	403
-#define SOAP_INVALID_VAR	404
-#define SOAP_ACTION_FAILED	501
-
-static const char *Soap_Invalid_Action = "Invalid Action";
-
-//static const char* Soap_Invalid_Args = "Invalid Args";
-static const char *Soap_Action_Failed = "Action Failed";
-static const char *Soap_Invalid_Var = "Invalid Var";
-
-const char *ContentTypeHeader =
-    "CONTENT-TYPE: text/xml; charset=UTF-8\r\n";
-
-/****************************************************************************
-*	Function :	get_request_type
-*
-*	Parameters :
-*			IN http_message_t* request :	HTTP request
-*			OUT memptr* action_name :	SOAP action name
-*
-*	Description :	This function retrives the name of the SOAP action
-*
-*	Return : int
-*		0 if successful else returns appropriate error.
-*	Note :
-****************************************************************************/
-static XINLINE int
-get_request_type( IN http_message_t * request,
-                  OUT memptr * action_name )
-{
-    memptr value;
-    memptr ns_value,
-      dummy_quote;
-    http_header_t *hdr;
-    char save_char;
-    char *s;
-    membuffer soap_action_name;
-
-    // find soapaction header
-    //
-    if( request->method == SOAPMETHOD_POST ) {
-        if( httpmsg_find_hdr( request, HDR_SOAPACTION, &value )
-            == NULL ) {
-            return SREQ_HDR_NOT_FOUND;
-        }
-    } else                      // M-POST
-    {
-        // get NS value from MAN header
-        hdr = httpmsg_find_hdr( request, HDR_MAN, &value );
-        if( hdr == NULL ) {
-            return SREQ_HDR_NOT_FOUND;
-        }
-
-        if( matchstr( value.buf, value.length, "%q%i ; ns = %s",
-                      &dummy_quote, &ns_value ) != 0 ) {
-            return SREQ_BAD_HDR_FORMAT;
-        }
-        // create soapaction name header
-        membuffer_init( &soap_action_name );
-        if( ( membuffer_assign( &soap_action_name,
-                                ns_value.buf, ns_value.length )
-              == UPNP_E_OUTOF_MEMORY ) ||
-            ( membuffer_append_str( &soap_action_name,
-                                    "-SOAPACTION" ) ==
-              UPNP_E_OUTOF_MEMORY )
-             ) {
-            membuffer_destroy( &soap_action_name );
-            return UPNP_E_OUTOF_MEMORY;
-        }
-
-        hdr = httpmsg_find_hdr_str( request, soap_action_name.buf );
-        membuffer_destroy( &soap_action_name );
-        if( hdr == NULL ) {
-            return SREQ_HDR_NOT_FOUND;
-        }
-
-        value.buf = hdr->value.buf;
-        value.length = hdr->value.length;
-    }
-
-    // determine type
-    //
-    save_char = value.buf[value.length];
-    value.buf[value.length] = '\0';
-
-    s = strchr( value.buf, '#' );
-    if( s == NULL ) {
-        value.buf[value.length] = save_char;
-        return SREQ_BAD_HDR_FORMAT;
-    }
-
-    s++;                        // move to value
-
-    if( matchstr( s, value.length - ( s - value.buf ), "%s",
-                  action_name ) != PARSE_OK ) {
-        value.buf[value.length] = save_char;
-        return SREQ_BAD_HDR_FORMAT;
-    }
-    // action name or variable ?
-    if( memptr_cmp( action_name, "QueryStateVariable" ) == 0 ) {
-        // query variable
-        action_name->buf = NULL;
-        action_name->length = 0;
-    }
-
-    value.buf[value.length] = save_char;    // restore
-    return 0;
-}
-
-/****************************************************************************
-*	Function :	send_error_response
-*
-*	Parameters :
-*			IN SOCKINFO *info :	socket info
-*			IN int error_code :	error code
-*			IN const char* err_msg :	error message
-*			IN http_message_t* hmsg :	HTTP request
-*
-*	Description :	This function sends SOAP error response
-*
-*	Return : void
-*
-*	Note :
-****************************************************************************/
-static void
-send_error_response( IN SOCKINFO * info,
-                     IN int error_code,
-                     IN const char *err_msg,
-                     IN http_message_t * hmsg )
-{
-    off_t content_length;
-    int timeout_secs = SOAP_TIMEOUT;
-    int major,
-      minor;
-    const char *start_body =
-//		"<?xml version=\"1.0\"?>\n" required??
-        "<s:Envelope "
-        "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
-        "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
-        "<s:Body>\n"
-        "<s:Fault>\n"
-        "<faultcode>s:Client</faultcode>\n"
-        "<faultstring>UPnPError</faultstring>\n"
-        "<detail>\n"
-        "<UPnPError xmlns=\"urn:schemas-upnp-org:control-1-0\">\n"
-        "<errorCode>";
-
-    const char *mid_body = "</errorCode>\n" "<errorDescription>";
-
-    const char *end_body =
-        "</errorDescription>\n"
-        "</UPnPError>\n"
-        "</detail>\n" "</s:Fault>\n" "</s:Body>\n" "</s:Envelope>\n";
-
-    char err_code_str[30];
-
-    membuffer headers;
-
-    sprintf( err_code_str, "%d", error_code );
-
-    // calc body len
-    content_length = strlen( start_body ) + strlen( err_code_str ) +
-        strlen( mid_body ) + strlen( err_msg ) + strlen( end_body );
-
-    http_CalcResponseVersion( hmsg->major_version, hmsg->minor_version,
-                              &major, &minor );
-
-    // make headers
-    membuffer_init( &headers );
-    if( http_MakeMessage( &headers, major, minor,
-                          "RNsDsSCAc" "sssss",
-                          500,
-                          content_length,
-                          ContentTypeHeader,
-                          "EXT:\r\n",
-                          gUserHTTPHeaders.buf,
-                          start_body, err_code_str, mid_body, err_msg,
-                          end_body ) != 0 ) {
-        membuffer_destroy( &headers );
-        return;                 // out of mem
-    }
-    // send err msg
-    http_SendMessage( info, &timeout_secs, "b",
-                      headers.buf, (size_t)headers.length );
-
-    membuffer_destroy( &headers );
-}
-
-/****************************************************************************
-*	Function :	send_var_query_response
-*
-*	Parameters :
-*			IN SOCKINFO *info :	socket info
-*			IN const char* var_value :	value of the state variable
-*			IN http_message_t* hmsg :	HTTP request
-*
-*	Description :	This function sends response of get var status
-*
-*	Return : void
-*
-*	Note :
-****************************************************************************/
-static XINLINE void
-send_var_query_response( IN SOCKINFO * info,
-                         IN const char *var_value,
-                         IN http_message_t * hmsg )
-{
-    off_t content_length;
-    int timeout_secs = SOAP_TIMEOUT;
-    int major;
-    int minor;
-    const char *start_body =
-        "<s:Envelope "
-        "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
-        "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
-        "<s:Body>\n"
-        "<u:QueryStateVariableResponse "
-        "xmlns:u=\"urn:schemas-upnp-org:control-1-0\">\n" "<return>";
-
-    const char *end_body =
-        "</return>\n"
-        "</u:QueryStateVariableResponse>\n"
-        "</s:Body>\n" "</s:Envelope>\n";
-
-    membuffer response;
-
-    http_CalcResponseVersion( hmsg->major_version, hmsg->minor_version,
-                              &major, &minor );
-
-    content_length = strlen( start_body ) + strlen( var_value ) +
-        strlen( end_body );
-
-    // make headers
-    membuffer_init( &response );
-    if( http_MakeMessage( &response, major, minor,
-                          "RNsDsSCAc" "sss",
-                          HTTP_OK,
-                          content_length,
-                          ContentTypeHeader,
-                          "EXT:\r\n",
-                          gUserHTTPHeaders.buf,
-                          start_body, var_value, end_body ) != 0 ) {
-        membuffer_destroy( &response );
-        return;                 // out of mem
-    }
-    // send msg
-    http_SendMessage( info, &timeout_secs, "b",
-                      response.buf, (size_t)response.length );
-
-    membuffer_destroy( &response );
-}
-
-/****************************************************************************
-*	Function :	get_action_node
-*
-*	Parameters :
-*		IN IXML_Document *TempDoc :	The root DOM node.
-*		IN char *NodeName :	IXML_Node name to be searched.
-*		OUT IXML_Document ** RespNode :	Response/Output node.
-*
-*	Description :	This function separates the action node from 
-*	the root DOM node.
-*
-*	Return :	static XINLINE int
-*		0 if successful, or -1 if fails.
-*
-*	Note :
-****************************************************************************/
-static XINLINE int
-get_action_node( IN IXML_Document * TempDoc,
-                 IN char *NodeName,
-                 OUT IXML_Document ** RespNode )
-{
-    IXML_Node *EnvpNode = NULL;
-    IXML_Node *BodyNode = NULL;
-    IXML_Node *ActNode = NULL;
-    DOMString ActNodeName = NULL;
-    const DOMString nodeName;
-    int ret_code = -1;          // error, by default
-    IXML_NodeList *nl = NULL;
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
-                         "get_action_node(): node name =%s\n ", NodeName );
-         )
-
-        * RespNode = NULL;
-
-    // Got the Envelope node here
-    EnvpNode = ixmlNode_getFirstChild( ( IXML_Node * ) TempDoc );
-    if( EnvpNode == NULL ) {
-        goto error_handler;
-    }
-
-    nl = ixmlElement_getElementsByTagNameNS( ( IXML_Element * ) EnvpNode,
-                                             "*", "Body" );
-
-    if( nl == NULL ) {
-        goto error_handler;
-    }
-
-    BodyNode = ixmlNodeList_item( nl, 0 );
-
-    if( BodyNode == NULL ) {
-        goto error_handler;
-    }
-    // Got action node here
-    ActNode = ixmlNode_getFirstChild( BodyNode );
-    if( ActNode == NULL ) {
-        goto error_handler;
-    }
-    //Test whether this is the action node
-    nodeName = ixmlNode_getNodeName( ActNode );
-    if( nodeName == NULL ) {
-        goto error_handler;
-    }
-
-    if( strstr( nodeName, NodeName ) == NULL ) {
-        goto error_handler;
-    } else {
-        ActNodeName = ixmlPrintNode( ActNode );
-        if( ActNodeName == NULL ) {
-            goto error_handler;
-        }
-
-        ret_code = ixmlParseBufferEx( ActNodeName, RespNode );
-        if( ret_code != IXML_SUCCESS ) {
-            ixmlFreeDOMString( ActNodeName );
-            ret_code = -1;
-            goto error_handler;
-        }
-    }
-
-    ret_code = 0;               // success
-
-  error_handler:
-
-    ixmlFreeDOMString( ActNodeName );
-
-    if( nl )
-        ixmlNodeList_free( nl );
-    return ret_code;
-}
-
-/****************************************************************************
-*	Function :	check_soap_body
-*
-*	Parameters :
-*		IN IXML_Document *doc :	soap body xml document
-*		    IN const char *urn : 
-*		    IN const char *actionName : Name of the requested action 	
-*
-*	Description :	This function checks the soap body xml came in the
-*		SOAP request.
-*
-*	Return : int
-*		UPNP_E_SUCCESS if successful else returns appropriate error
-*
-*	Note :
-****************************************************************************/
-static int
-check_soap_body( IN IXML_Document * doc,
-                 IN const char *urn,
-                 IN const char *actionName )
-{
-    IXML_NodeList *nl = NULL;
-    IXML_Node *bodyNode = NULL;
-    IXML_Node *actionNode = NULL;
-    const DOMString ns = NULL;
-    const DOMString name = NULL;
-
-    int ret_code = UPNP_E_INVALID_ACTION;
-
-    nl = ixmlDocument_getElementsByTagNameNS( doc, SOAP_URN, SOAP_BODY );
-
-    if( nl ) {
-        bodyNode = ixmlNodeList_item( nl, 0 );
-        if( bodyNode ) {
-            actionNode = ixmlNode_getFirstChild( bodyNode );
-            if( actionNode ) {
-                ns = ixmlNode_getNamespaceURI( actionNode );
-                name = ixmlNode_getLocalName( actionNode );
-
-                if( ( !strcmp( actionName, name ) )
-                    && ( !strcmp( urn, ns ) ) ) {
-                    ret_code = UPNP_E_SUCCESS;
-                }
-            }
-        }
-        ixmlNodeList_free( nl );
-    }
-    return ret_code;
-
-}
-
-/****************************************************************************
-*	Function :	check_soap_action_header
-*
-*	Parameters :
-*		IN http_message_t *request : HTTP request
-*		IN const char *urn :
-*		OUT char **actionName :	 name of the SOAP action
-*
-*	Description :	This function checks the HTTP header of the SOAP request
-*		coming from the control point
-*
-*	Return :	static int
-*		UPNP_E_SUCCESS if successful else returns appropriate error
-*
-*	Note :
-****************************************************************************/
-static int
-check_soap_action_header( IN http_message_t * request,
-                          IN const char *urn,
-                          OUT char **actionName )
-{
-    memptr header_name;
-    http_header_t *soap_action_header = NULL;
-    char *ns_compare = NULL;
-    int tempSize = 0;
-    int ret_code = UPNP_E_SUCCESS;
-    char *temp_header_value = NULL;
-    char *temp = NULL;
-    char *temp2 = NULL;
-
-    //check soap action header
-
-    soap_action_header = httpmsg_find_hdr( request, HDR_SOAPACTION,
-                                           &header_name );
-
-    if( !soap_action_header ) {
-        ret_code = UPNP_E_INVALID_ACTION;
-        return ret_code;
-    }
-
-    if( soap_action_header->value.length <= 0 ) {
-        ret_code = UPNP_E_INVALID_ACTION;
-        return ret_code;
-    }
-
-    temp_header_value =
-        ( char * )malloc( soap_action_header->value.length + 1 );
-
-    if( !temp_header_value ) {
-        ret_code = UPNP_E_OUTOF_MEMORY;
-        free( temp_header_value );
-        return ret_code;
-    }
-
-    strncpy( temp_header_value, soap_action_header->value.buf,
-             soap_action_header->value.length );
-    temp_header_value[soap_action_header->value.length] = 0;
-
-    temp = strchr( temp_header_value, '#' );
-    if( !temp ) {
-        free( temp_header_value );
-        ret_code = UPNP_E_INVALID_ACTION;
-        return ret_code;
-    }
-
-    ( *temp ) = 0;              //temp make string
-
-    //check to see if it is Query State Variable or
-    //Service Action
-
-    tempSize = strlen( urn ) + 2;
-
-    ns_compare = ( char * )malloc( tempSize );
-
-    if( !ns_compare ) {
-        ret_code = UPNP_E_OUTOF_MEMORY;
-        free( temp_header_value );
-        return ret_code;
-    }
-
-    snprintf( ns_compare, tempSize, "\"%s", urn );
-
-    if( strcmp( temp_header_value, ns_compare ) ) {
-        ret_code = UPNP_E_INVALID_ACTION;
-    } else {
-        ret_code = UPNP_E_SUCCESS;
-        temp++;
-        temp2 = strchr( temp, '\"' );
-
-        if( temp2 )             //remove ending " if present
-        {
-            ( *temp2 ) = 0;
-        }
-
-        if( *temp )
-            ( *actionName ) = strdup( temp );
-        if( !*actionName ) {
-            ret_code = UPNP_E_OUTOF_MEMORY;
-        }
-    }
-
-    free( temp_header_value );
-    free( ns_compare );
-    return ret_code;
-}
-
-/****************************************************************************
-*	Function :	get_device_info
-*
-*	Parameters :
-*		IN http_message_t* request :	HTTP request
-*		IN int isQuery :	flag for a querry
-*		IN IXML_Document *actionDoc :	action request document
-*		OUT char device_udn[LINE_SIZE] :	Device UDN string
-*		OUT char service_id[LINE_SIZE] :	Service ID string
-*		OUT Upnp_FunPtr *callback :	callback function of the device 
-*									application
-*		OUT void** cookie :	cookie stored by device application 
-*							
-*	Description :	This function retrives all the information needed to 
-*		process the incoming SOAP request. It finds the device and service info
-*		and also the callback function to hand-over the request to the device
-*		application.
-*
-*	Return : int
-*		UPNP_E_SUCCESS if successful else returns appropriate error
-*
-*	Note :
-****************************************************************************/
-static int
-get_device_info( IN http_message_t * request,
-                 IN int isQuery,
-                 IN IXML_Document * actionDoc,
-                 OUT char device_udn[LINE_SIZE],
-                 OUT char service_id[LINE_SIZE],
-                 OUT Upnp_FunPtr * callback,
-                 OUT void **cookie )
-{
-    struct Handle_Info *device_info;
-    int device_hnd;
-    service_info *serv_info;
-    char save_char;
-    int ret_code = -1;          // error by default
-    const char *control_url;
-    char *actionName = NULL;
-
-    // null-terminate pathquery of url
-    control_url = request->uri.pathquery.buff;
-    save_char = control_url[request->uri.pathquery.size];
-    ((char *)control_url)[request->uri.pathquery.size] = '\0';
-
-    HandleLock(  );
-
-    if( GetDeviceHandleInfo( &device_hnd, &device_info ) != HND_DEVICE ) {
-        goto error_handler;
-    }
-
-    if( ( serv_info =
-          FindServiceControlURLPath( &device_info->ServiceTable,
-                                     control_url ) ) == NULL ) {
-        goto error_handler;
-    }
-
-    if( isQuery ) {
-        ret_code = check_soap_action_header( request, QUERY_STATE_VAR_URN,
-                                             &actionName );
-        if( ( ret_code != UPNP_E_SUCCESS )
-            && ( ret_code != UPNP_E_OUTOF_MEMORY ) ) {
-            ret_code = UPNP_E_INVALID_ACTION;
-            goto error_handler;
-        }
-        //check soap body
-        ret_code =
-            check_soap_body( actionDoc, QUERY_STATE_VAR_URN, actionName );
-        free( actionName );
-        if( ret_code != UPNP_E_SUCCESS ) {
-            goto error_handler;
-        }
-    } else {
-        ret_code = check_soap_action_header( request,
-                                             serv_info->serviceType,
-                                             &actionName );
-        if( ( ret_code != UPNP_E_SUCCESS )
-            && ( ret_code != UPNP_E_OUTOF_MEMORY ) ) {
-            ret_code = UPNP_E_INVALID_SERVICE;
-            goto error_handler;
-        }
-        //check soap body
-        ret_code =
-            check_soap_body( actionDoc, serv_info->serviceType,
-                             actionName );
-        free( actionName );
-        if( ret_code != UPNP_E_SUCCESS ) {
-            ret_code = UPNP_E_INVALID_SERVICE;
-            goto error_handler;
-        }
-    }
-
-    namecopy( service_id, serv_info->serviceId );
-    namecopy( device_udn, serv_info->UDN );
-    *callback = device_info->Callback;
-    *cookie = device_info->Cookie;
-
-    ret_code = 0;
-
-  error_handler:
-    ((char *)control_url)[request->uri.pathquery.size] = save_char;   // restore
-    HandleUnlock(  );
-    return ret_code;
-}
-
-/****************************************************************************
-*	Function :	send_action_response
-*
-*	Parameters :
-*		IN SOCKINFO *info :	socket info
-*		IN IXML_Document *action_resp : The response document	
-*		IN http_message_t* request :	action request document
-*
-*	Description :	This function sends the SOAP response 
-*
-*	Return : void
-*
-*	Note :
-****************************************************************************/
-static XINLINE void
-send_action_response( IN SOCKINFO * info,
-                      IN IXML_Document * action_resp,
-                      IN http_message_t * request )
-{
-    char *xml_response = NULL;
-    membuffer headers;
-    int major,
-      minor;
-    int err_code;
-    off_t content_length;
-    int ret_code;
-    int timeout_secs = SOAP_TIMEOUT;
-    static char *start_body =
-//        "<?xml version=\"1.0\"?>" required??
-        "<s:Envelope xmlns:s=\"http://schemas.xmlsoap."
-        "org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap."
-        "org/soap/encoding/\"><s:Body>\n";
-    static char *end_body = "</s:Body> </s:Envelope>";
-
-    // init
-    http_CalcResponseVersion( request->major_version,
-                              request->minor_version, &major, &minor );
-    membuffer_init( &headers );
-    err_code = UPNP_E_OUTOF_MEMORY; // one error only
-
-    // get xml
-    xml_response = ixmlPrintNode( ( IXML_Node * ) action_resp );
-    if( xml_response == NULL ) {
-        goto error_handler;
-    }
-
-    content_length = strlen( start_body ) + strlen( xml_response ) +
-        strlen( end_body );
-
-    // make headers
-    if( http_MakeMessage( &headers, major, minor,
-        "RNsDsSCAc", 
-        HTTP_OK,   // status code
-        content_length,
-        ContentTypeHeader, 
-        "EXT:\r\n",// EXT header
-        gUserHTTPHeaders.buf
-         ) != 0 ) {
-        goto error_handler;
-    }
-    // send whole msg
-    ret_code = http_SendMessage( info, &timeout_secs, "bbbb",
-                                 headers.buf, (size_t)headers.length,
-                                 start_body, strlen( start_body ),
-                                 xml_response, strlen( xml_response ),
-                                 end_body, strlen( end_body ) );
-
-    if( ret_code != 0 ) {
-        DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
-                         "Failed to send response: err code = %d\n",
-                         ret_code );)
-    }
-
-        err_code = 0;
-
-  error_handler:
-    ixmlFreeDOMString( xml_response );
-    membuffer_destroy( &headers );
-    if( err_code != 0 ) {
-        // only one type of error to worry about - out of mem
-        send_error_response( info, SOAP_ACTION_FAILED, "Out of memory",
-                             request );
-    }
-}
-
-/****************************************************************************
-*	Function :	get_var_name
-*
-*	Parameters :
-*		IN IXML_Document *TempDoc :	Document containing variable request
-*		OUT char* VarName :	Name of the state varible
-*
-*	Description :	This function finds the name of the state variable 
-*				asked in the SOAP request.
-*
-*	Return :	int
-*		returns 0 if successful else returns -1.
-*	Note :
-****************************************************************************/
-static XINLINE int
-get_var_name( IN IXML_Document * TempDoc,
-              OUT char *VarName )
-{
-    IXML_Node *EnvpNode = NULL;
-    IXML_Node *BodyNode = NULL;
-    IXML_Node *StNode = NULL;
-    IXML_Node *VarNameNode = NULL;
-    IXML_Node *VarNode = NULL;
-    const DOMString StNodeName = NULL;
-    const DOMString Temp = NULL;
-    int ret_val = -1;
-
-    // Got the Envelop node here
-    EnvpNode = ixmlNode_getFirstChild( ( IXML_Node * ) TempDoc );
-    if( EnvpNode == NULL ) {
-        goto error_handler;
-    }
-    // Got Body here
-    BodyNode = ixmlNode_getFirstChild( EnvpNode );
-    if( BodyNode == NULL ) {
-        goto error_handler;
-    }
-    // Got action node here
-    StNode = ixmlNode_getFirstChild( BodyNode );
-    if( StNode == NULL ) {
-        goto error_handler;
-    }
-    //Test whether this is the action node
-    StNodeName = ixmlNode_getNodeName( StNode );
-    if( StNodeName == NULL || strstr( StNodeName,
-                                      "QueryStateVariable" ) == NULL ) {
-        goto error_handler;
-    }
-
-    VarNameNode = ixmlNode_getFirstChild( StNode );
-    if( VarNameNode == NULL ) {
-        goto error_handler;
-    }
-
-    VarNode = ixmlNode_getFirstChild( VarNameNode );
-    Temp = ixmlNode_getNodeValue( VarNode );
-    linecopy( VarName, Temp );
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
-                         "Received query for variable  name %s\n",
-                         VarName );
-         )
-
-        ret_val = 0;            // success
-
-  error_handler:
-    return ret_val;
-}
-
-/****************************************************************************
-*	Function :	handle_query_variable
-*
-*	Parameters :
-*		IN SOCKINFO *info :	Socket info
-*		IN http_message_t* request : HTTP request	
-*		IN IXML_Document *xml_doc :	Document containing the variable request 
-*									SOAP message
-*
-*	Description :	This action handles the SOAP requests to querry the 
-*				state variables. This functionality has been deprecated in 
-*				the UPnP V1.0 architecture
-*
-*	Return :	void
-*
-*	Note :
-****************************************************************************/
-static XINLINE void
-handle_query_variable( IN SOCKINFO * info,
-                       IN http_message_t * request,
-                       IN IXML_Document * xml_doc )
-{
-    Upnp_FunPtr soap_event_callback;
-    void *cookie;
-    char var_name[LINE_SIZE];
-    struct Upnp_State_Var_Request variable;
-    const char *err_str;
-    int err_code;
-
-    // get var name
-    if( get_var_name( xml_doc, var_name ) != 0 ) {
-        send_error_response( info, SOAP_INVALID_VAR,
-                             Soap_Invalid_Var, request );
-        return;
-    }
-    // get info for event
-    if( get_device_info( request, 1, xml_doc, variable.DevUDN,
-                         variable.ServiceID,
-                         &soap_event_callback, &cookie ) != 0 ) {
-        send_error_response( info, SOAP_INVALID_VAR,
-                             Soap_Invalid_Var, request );
-        return;
-    }
-
-    linecopy( variable.ErrStr, "" );
-    variable.ErrCode = UPNP_E_SUCCESS;
-    namecopy( variable.StateVarName, var_name );
-    variable.CurrentVal = NULL;
-    variable.CtrlPtIPAddr = info->foreign_ip_addr;
-
-    // send event
-    soap_event_callback( UPNP_CONTROL_GET_VAR_REQUEST, &variable, cookie );
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
-                         "Return from callback for var request\n" ) );
-
-    // validate, and handle result
-    if( variable.CurrentVal == NULL ) {
-        err_code = SOAP_ACTION_FAILED;
-        err_str = Soap_Action_Failed;
-        send_error_response( info, SOAP_INVALID_VAR,
-                             Soap_Invalid_Var, request );
-        return;
-    }
-    if( variable.ErrCode != UPNP_E_SUCCESS ) {
-        if( strlen( variable.ErrStr ) > 0 ) {
-            err_code = SOAP_INVALID_VAR;
-            err_str = Soap_Invalid_Var;
-        } else {
-            err_code = variable.ErrCode;
-            err_str = variable.ErrStr;
-        }
-        send_error_response( info, err_code, err_str, request );
-        return;
-    }
-    // send response
-    send_var_query_response( info, variable.CurrentVal, request );
-    ixmlFreeDOMString( variable.CurrentVal );
-
-}
-
-/****************************************************************************
-*	Function :	handle_invoke_action
-*
-*	Parameters :
-*		IN SOCKINFO *info :	Socket info
-*		IN http_message_t* request : HTTP Request	
-*		IN memptr action_name :	 Name of the SOAP Action
-*		IN IXML_Document *xml_doc :	document containing the SOAP action 
-*									request
-*
-*	Description :	This functions handle the SOAP action request. It checks 
-*		the integrity of the SOAP action request and gives the call back to 
-*		the device application.
-*
-*	Return : void
-*
-*	Note :
-****************************************************************************/
-static void
-handle_invoke_action( IN SOCKINFO * info,
-                      IN http_message_t * request,
-                      IN memptr action_name,
-                      IN IXML_Document * xml_doc )
-{
-    char save_char;
-    IXML_Document *resp_node = NULL;
-    struct Upnp_Action_Request action;
-    Upnp_FunPtr soap_event_callback;
-    void *cookie = NULL;
-    int err_code;
-    const char *err_str;
-
-    action.ActionResult = NULL;
-
-    // null-terminate
-    save_char = action_name.buf[action_name.length];
-    action_name.buf[action_name.length] = '\0';
-
-    // set default error
-    err_code = SOAP_INVALID_ACTION;
-    err_str = Soap_Invalid_Action;
-
-    // get action node
-    if( get_action_node( xml_doc, action_name.buf, &resp_node ) == -1 ) {
-        goto error_handler;
-    }
-    // get device info for action event
-    err_code = get_device_info( request, 0, xml_doc, action.DevUDN,
-                                action.ServiceID, &soap_event_callback,
-                                &cookie );
-
-    if( err_code != UPNP_E_SUCCESS ) {
-        goto error_handler;
-    }
-
-    namecopy( action.ActionName, action_name.buf );
-    linecopy( action.ErrStr, "" );
-    action.ActionRequest = resp_node;
-    action.ActionResult = NULL;
-    action.ErrCode = UPNP_E_SUCCESS;
-    action.CtrlPtIPAddr = info->foreign_ip_addr;
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
-                         "Calling Callback\n" ) );
-
-    soap_event_callback( UPNP_CONTROL_ACTION_REQUEST, &action, cookie );
-
-    if( action.ErrCode != UPNP_E_SUCCESS ) {
-        if( strlen( action.ErrStr ) <= 0 ) {
-            err_code = SOAP_ACTION_FAILED;
-            err_str = Soap_Action_Failed;
-        } else {
-            err_code = action.ErrCode;
-            err_str = action.ErrStr;
-        }
-        goto error_handler;
-    }
-    // validate, and handle action error
-    if( action.ActionResult == NULL ) {
-        err_code = SOAP_ACTION_FAILED;
-        err_str = Soap_Action_Failed;
-        goto error_handler;
-    }
-    // send response
-    send_action_response( info, action.ActionResult, request );
-
-    err_code = 0;
-
-    // error handling and cleanup
-  error_handler:
-    ixmlDocument_free( action.ActionResult );
-    ixmlDocument_free( resp_node );
-    action_name.buf[action_name.length] = save_char;    // restore
-    if( err_code != 0 ) {
-        send_error_response( info, err_code, err_str, request );
-    }
-}
-
-/****************************************************************************
-*	Function :	soap_device_callback
-*
-*	Parameters :
-*		  IN http_parser_t *parser : Parsed request received by the device
-*		  IN http_message_t* request :	HTTP request 
-*		  INOUT SOCKINFO *info :	socket info
-*
-*	Description :	This is a callback called by minisever after receiving 
-*		the request from the control point. This function will start 
-*		processing the request. It calls handle_invoke_action to handle the
-*		SOAP action
-*
-*	Return :	void
-*
-*	Note :
-****************************************************************************/
-void
-soap_device_callback( IN http_parser_t * parser,
-                      IN http_message_t * request,
-                      INOUT SOCKINFO * info )
-{
-    int err_code;
-    const char *err_str;
-    memptr action_name;
-    IXML_Document *xml_doc = NULL;
-
-    // set default error
-    err_code = SOAP_INVALID_ACTION;
-    err_str = Soap_Invalid_Action;
-
-    // validate: content-type == text/xml
-    if( !has_xml_content_type( request ) ) {
-        goto error_handler;
-    }
-    // type of request
-    if( get_request_type( request, &action_name ) != 0 ) {
-        goto error_handler;
-    }
-    // parse XML
-    err_code = ixmlParseBufferEx( request->entity.buf, &xml_doc );
-    if( err_code != IXML_SUCCESS ) {
-        if( err_code == IXML_INSUFFICIENT_MEMORY ) {
-            err_code = UPNP_E_OUTOF_MEMORY;
-        } else {
-            err_code = SOAP_ACTION_FAILED;
-        }
-
-        err_str = "XML error";
-        goto error_handler;
-    }
-
-    if( action_name.length == 0 ) {
-        // query var
-        handle_query_variable( info, request, xml_doc );
-    } else {
-        // invoke action
-        handle_invoke_action( info, request, action_name, xml_doc );
-    }
-
-    err_code = 0;               // no error
-
-  error_handler:
-    ixmlDocument_free( xml_doc );
-    if( err_code != 0 ) {
-        send_error_response( info, err_code, err_str, request );
-    }
-}
-
-#endif // EXCLUDE_SOAP
-
-#endif // INCLUDE_DEVICE_APIS
diff --git a/tombupnp/upnp/src/ssdp/ssdp_ctrlpt.c b/tombupnp/upnp/src/ssdp/ssdp_ctrlpt.c
deleted file mode 100644
index 0e0430e..0000000
--- a/tombupnp/upnp/src/ssdp/ssdp_ctrlpt.c
+++ /dev/null
@@ -1,637 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#include "util.h"
-#ifdef INCLUDE_CLIENT_APIS
-#if EXCLUDE_SSDP == 0
-
-#include "ssdplib.h"
-#include "upnpapi.h"
-#include <stdio.h>
-#include "ThreadPool.h"
-
-#include "httpparser.h"
-#include "httpreadwrite.h"
-#include "statcodes.h"
-
-#include "unixutil.h"
-
-#ifdef WIN32
- #include <ws2tcpip.h>
- #include <winsock2.h>
- #ifndef imillisleep
- #define imillisleep Sleep
- #endif
-#endif
-
-
-/************************************************************************
-* Function : send_search_result											
-*																	
-* Parameters:														
-*	IN void *data: Search reply from the device
-*																	
-* Description:														
-*	This function sends a callback to the control point application with 
-*	a SEARCH result
-*
-* Returns: void
-*
-***************************************************************************/
-void
-send_search_result( IN void *data )
-{
-    ResultData *temp = ( ResultData * ) data;
-
-    temp->ctrlpt_callback( UPNP_DISCOVERY_SEARCH_RESULT,
-                           &temp->param, temp->cookie );
-    free( temp );
-}
-
-/************************************************************************
-* Function : ssdp_handle_ctrlpt_msg
-*
-* Parameters:
-*	IN http_message_t* hmsg: SSDP message from the device
-*	IN struct sockaddr_in* dest_addr: Address of the device
-*	IN xboolean timeout: timeout kept by the control point while
-*		sending search message
-*	IN void* cookie: Cookie stored by the control point application. 
-*		This cookie will be returned to the control point
-*		in the callback 
-*
-* Description:
-*	This function handles the ssdp messages from the devices. These 
-*	messages includes the search replies, advertisement of device coming 
-*	alive and bye byes.
-*
-* Returns: void
-*
-***************************************************************************/
-void
-ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
-                        IN struct sockaddr_in *dest_addr,
-                        IN xboolean timeout,    // only in search reply
-
-                        IN void *cookie )   // only in search reply
-{
-    int handle;
-    struct Handle_Info *ctrlpt_info = NULL;
-    memptr hdr_value;
-    xboolean is_byebye;         // byebye or alive
-    struct Upnp_Discovery param;
-    SsdpEvent event;
-    xboolean nt_found,
-      usn_found,
-      st_found;
-    char save_char;
-    Upnp_EventType event_type;
-    Upnp_FunPtr ctrlpt_callback;
-    void *ctrlpt_cookie;
-    ListNode *node = NULL;
-    SsdpSearchArg *searchArg = NULL;
-    int matched = 0;
-    ResultData *threadData;
-    ThreadPoolJob job;
-
-    // we are assuming that there can be only one client supported at a time
-
-    HandleLock(  );
-
-    if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        return;
-    }
-    // copy
-    ctrlpt_callback = ctrlpt_info->Callback;
-    ctrlpt_cookie = ctrlpt_info->Cookie;
-    HandleUnlock(  );
-
-    // search timeout
-    if( timeout ) {
-        ctrlpt_callback( UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie );
-        return;
-    }
-
-    param.ErrCode = UPNP_E_SUCCESS;
-
-    // MAX-AGE
-    param.Expires = -1;         // assume error
-    if( httpmsg_find_hdr( hmsg, HDR_CACHE_CONTROL, &hdr_value ) != NULL ) {
-        if( matchstr( hdr_value.buf, hdr_value.length,
-                      "%imax-age = %d%0", &param.Expires ) != PARSE_OK )
-            return;
-    }
-
-    // DATE
-    param.Date[0] = '\0';
-    if( httpmsg_find_hdr( hmsg, HDR_DATE, &hdr_value ) != NULL ) {
-        linecopylen( param.Date, hdr_value.buf, hdr_value.length );
-    }
-
-    // dest addr
-    param.DestAddr = dest_addr;
-
-    // EXT
-    param.Ext[0] = '\0';
-    if( httpmsg_find_hdr( hmsg, HDR_EXT, &hdr_value ) != NULL ) {
-        linecopylen( param.Ext, hdr_value.buf, hdr_value.length );
-    }
-    // LOCATION
-    param.Location[0] = '\0';
-    if( httpmsg_find_hdr( hmsg, HDR_LOCATION, &hdr_value ) != NULL ) {
-        linecopylen( param.Location, hdr_value.buf, hdr_value.length );
-    }
-    // SERVER / USER-AGENT
-    param.Os[0] = '\0';
-    if( httpmsg_find_hdr( hmsg, HDR_SERVER, &hdr_value ) != NULL ||
-        httpmsg_find_hdr( hmsg, HDR_USER_AGENT, &hdr_value ) != NULL ) {
-        linecopylen( param.Os, hdr_value.buf, hdr_value.length );
-    }
-    // clear everything
-    param.DeviceId[0] = '\0';
-    param.DeviceType[0] = '\0';
-    param.ServiceType[0] = '\0';
-
-    param.ServiceVer[0] = '\0'; // not used; version is in ServiceType
-
-    event.UDN[0] = '\0';
-    event.DeviceType[0] = '\0';
-    event.ServiceType[0] = '\0';
-
-    nt_found = FALSE;
-
-    if( httpmsg_find_hdr( hmsg, HDR_NT, &hdr_value ) != NULL ) {
-        save_char = hdr_value.buf[hdr_value.length];
-        hdr_value.buf[hdr_value.length] = '\0';
-
-        nt_found = ( ssdp_request_type( hdr_value.buf, &event ) == 0 );
-
-        hdr_value.buf[hdr_value.length] = save_char;
-    }
-
-    usn_found = FALSE;
-    if( httpmsg_find_hdr( hmsg, HDR_USN, &hdr_value ) != NULL ) {
-        save_char = hdr_value.buf[hdr_value.length];
-        hdr_value.buf[hdr_value.length] = '\0';
-
-        usn_found = ( unique_service_name( hdr_value.buf, &event ) == 0 );
-
-        hdr_value.buf[hdr_value.length] = save_char;
-    }
-
-    if( nt_found || usn_found ) {
-        strcpy( param.DeviceId, event.UDN );
-        strcpy( param.DeviceType, event.DeviceType );
-        strcpy( param.ServiceType, event.ServiceType );
-    }
-
-    // ADVERT. OR BYEBYE
-    if( hmsg->is_request ) {
-        // use NTS hdr to determine advert., or byebye
-        //
-        if( httpmsg_find_hdr( hmsg, HDR_NTS, &hdr_value ) == NULL ) {
-            return;             // error; NTS header not found
-        }
-        if( memptr_cmp( &hdr_value, "ssdp:alive" ) == 0 ) {
-            is_byebye = FALSE;
-        } else if( memptr_cmp( &hdr_value, "ssdp:byebye" ) == 0 ) {
-            is_byebye = TRUE;
-        } else {
-            return;             // bad value
-        }
-
-        if( is_byebye ) {
-            // check device byebye
-            if( !nt_found || !usn_found ) {
-                return;         // bad byebye
-            }
-            event_type = UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE;
-        } else {
-            // check advertisement      
-            // .Expires is valid if positive. This is for testing
-            //  only. Expires should be greater than 1800 (30 mins)
-            if( !nt_found ||
-                !usn_found ||
-                strlen( param.Location ) == 0 || param.Expires <= 0 ) {
-                return;         // bad advertisement
-            }
-
-            event_type = UPNP_DISCOVERY_ADVERTISEMENT_ALIVE;
-        }
-
-        // call callback
-        ctrlpt_callback( event_type, &param, ctrlpt_cookie );
-
-    } else                      // reply (to a SEARCH)
-    {
-        // only checking to see if there is a valid ST header
-        st_found = FALSE;
-        if( httpmsg_find_hdr( hmsg, HDR_ST, &hdr_value ) != NULL ) {
-            save_char = hdr_value.buf[hdr_value.length];
-            hdr_value.buf[hdr_value.length] = '\0';
-            st_found = ssdp_request_type( hdr_value.buf, &event ) == 0;
-            hdr_value.buf[hdr_value.length] = save_char;
-        }
-        if( hmsg->status_code != HTTP_OK ||
-            param.Expires <= 0 ||
-            strlen( param.Location ) == 0 || !usn_found || !st_found ) {
-            return;             // bad reply
-        }
-        //check each current search
-        HandleLock(  );
-        if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
-            HandleUnlock(  );
-            return;
-        }
-        node = ListHead( &ctrlpt_info->SsdpSearchList );
-
-        //temporary add null termination
-        //save_char = hdr_value.buf[ hdr_value.length ];
-        //hdr_value.buf[ hdr_value.length ] = '\0';
-
-        while( node != NULL ) {
-            searchArg = node->item;
-            matched = 0;
-            //check for match of ST header and search target
-            switch ( searchArg->requestType ) {
-                case SSDP_ALL:
-                    {
-                        matched = 1;
-                        break;
-                    }
-                case SSDP_ROOTDEVICE:
-                    {
-                        matched = ( event.RequestType == SSDP_ROOTDEVICE );
-                        break;
-                    }
-                case SSDP_DEVICEUDN:
-                    {
-                        matched = !( strncmp( searchArg->searchTarget,
-                                              hdr_value.buf,
-                                              hdr_value.length ) );
-                        break;
-                    }
-                case SSDP_DEVICETYPE:
-                    {
-                        int m = min( hdr_value.length,
-                                     strlen( searchArg->searchTarget ) );
-
-                        matched = !( strncmp( searchArg->searchTarget,
-                                              hdr_value.buf, m ) );
-                        break;
-                    }
-                case SSDP_SERVICE:
-                    {
-                        int m = min( hdr_value.length,
-                                     strlen( searchArg->searchTarget ) );
-
-                        matched = !( strncmp( searchArg->searchTarget,
-                                              hdr_value.buf, m ) );
-                        break;
-                    }
-                default:
-                    {
-                        matched = 0;
-                        break;
-                    }
-            }
-
-            if( matched ) {
-                //schedule call back
-                threadData =
-                    ( ResultData * ) malloc( sizeof( ResultData ) );
-                if( threadData != NULL ) {
-                    threadData->param = param;
-                    threadData->cookie = searchArg->cookie;
-                    threadData->ctrlpt_callback = ctrlpt_callback;
-                    TPJobInit( &job, ( start_routine ) send_search_result,
-                               threadData );
-                    TPJobSetPriority( &job, MED_PRIORITY );
-                    TPJobSetFreeFunction( &job, ( free_routine ) free );
-                    if (ThreadPoolAdd( &gRecvThreadPool, &job, NULL ) != 0) {a
-                        SSDPResultData_delete(threadData);
-                    }
-                }
-            }
-            node = ListNext( &ctrlpt_info->SsdpSearchList, node );
-        }
-
-        HandleUnlock(  );
-        //ctrlpt_callback( UPNP_DISCOVERY_SEARCH_RESULT, &param, cookie );
-    }
-}
-
-/************************************************************************
-* Function : process_reply											
-*																	
-* Parameters:														
-*		IN char* request_buf: the response came from the device
-*		IN int buf_len: The length of the response buffer
-*	    IN struct sockaddr_in* dest_addr: The address of the device
-*		IN void *cookie : cookie passed by the control point application
-*							at the time of sending search message
-*
-* Description:														
-*	This function processes reply recevied from a search
-*
-* Returns: void
-*
-***************************************************************************/
-static XINLINE void
-process_reply( IN char *request_buf,
-               IN int buf_len,
-               IN struct sockaddr_in *dest_addr,
-               IN void *cookie )
-{
-    http_parser_t parser;
-
-    parser_response_init( &parser, HTTPMETHOD_MSEARCH );
-
-    // parse
-    if( parser_append( &parser, request_buf, buf_len ) != PARSE_SUCCESS ) {
-        httpmsg_destroy( &parser.msg );
-        return;
-    }
-    // handle reply
-    ssdp_handle_ctrlpt_msg( &parser.msg, dest_addr, FALSE, cookie );
-
-    // done
-    httpmsg_destroy( &parser.msg );
-}
-
-/************************************************************************
-* Function : CreateClientRequestPacket											
-*																	
-* Parameters:														
-*		IN char * RqstBuf:Output string in HTTP format.
-*		IN char *SearchTarget:Search Target
-*	    IN int Mx dest_addr: Number of seconds to wait to 
-*							collect all the responses
-*
-* Description:														
-*	This function creates a HTTP search request packet 
-* depending on the input parameter.
-*
-* Returns: void
-*
-***************************************************************************/
-static void
-CreateClientRequestPacket( IN char *RqstBuf,
-                           IN int Mx,
-                           IN char *SearchTarget )
-{
-    char TempBuf[COMMAND_LEN];
-
-    strcpy( RqstBuf, "M-SEARCH * HTTP/1.1\r\n" );
-
-    sprintf( TempBuf, "HOST: %s:%d\r\n", SSDP_IP, SSDP_PORT );
-    strcat( RqstBuf, TempBuf );
-    strcat( RqstBuf, "MAN: \"ssdp:discover\"\r\n" );
-
-    if( Mx > 0 ) {
-        sprintf( TempBuf, "MX: %d\r\n", Mx );
-        strcat( RqstBuf, TempBuf );
-    }
-
-    if( SearchTarget != NULL ) {
-        sprintf( TempBuf, "ST: %s\r\n", SearchTarget );
-        strcat( RqstBuf, TempBuf );
-    }
-    strcat( RqstBuf, "\r\n" );
-
-}
-
-/************************************************************************
-* Function : searchExpired											
-*																	
-* Parameters:														
-*		IN void * arg:
-*
-* Description:														
-*	This function 
-*
-* Returns: void
-*
-***************************************************************************/
-void
-searchExpired( void *arg )
-{
-
-    int *id = ( int * )arg;
-    int handle = -1;
-    struct Handle_Info *ctrlpt_info = NULL;
-
-    //remove search Target from list and call client back
-    ListNode *node = NULL;
-    SsdpSearchArg *item;
-    Upnp_FunPtr ctrlpt_callback;
-    void *cookie = NULL;
-    int found = 0;
-
-    HandleLock(  );
-
-    //remove search target from search list
-
-    if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
-        free( id );
-        HandleUnlock(  );
-        return;
-    }
-
-    ctrlpt_callback = ctrlpt_info->Callback;
-
-    node = ListHead( &ctrlpt_info->SsdpSearchList );
-
-    while( node != NULL ) {
-        item = ( SsdpSearchArg * ) node->item;
-        if( item->timeoutEventId == ( *id ) ) {
-            free( item->searchTarget );
-            cookie = item->cookie;
-            found = 1;
-            item->searchTarget = NULL;
-            free( item );
-            ListDelNode( &ctrlpt_info->SsdpSearchList, node, 0 );
-            break;
-        }
-        node = ListNext( &ctrlpt_info->SsdpSearchList, node );
-    }
-    HandleUnlock(  );
-
-    if( found ) {
-        ctrlpt_callback( UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie );
-    }
-
-    free( id );
-}
-
-/************************************************************************
-* Function : SearchByTarget
-*
-* Parameters:
-*	IN int Mx:Number of seconds to wait, to collect all the	responses.
-*	IN char *St: Search target.
-*	IN void *Cookie: cookie provided by control point application.
-*		This cokie will be returned to application in the callback.
-*
-* Description:
-*	This function creates and send the search request for a specific URL.
-*
-* Returns: int
-*	1 if successful else appropriate error
-***************************************************************************/
-int
-SearchByTarget( IN int Mx,
-                IN char *St,
-                IN void *Cookie )
-{
-    int socklen = sizeof( struct sockaddr_in );
-    int *id = NULL;
-    char *ReqBuf;
-    struct sockaddr_in destAddr;
-    fd_set wrSet;
-    SsdpSearchArg *newArg = NULL;
-    int timeTillRead = 0;
-    int handle;
-    struct Handle_Info *ctrlpt_info = NULL;
-    enum SsdpSearchType requestType;
-    unsigned long addr = inet_addr( LOCAL_HOST );
-
-    //ThreadData *ThData;
-    ThreadPoolJob job;
-
-    requestType = ssdp_request_type1( St );
-    if( requestType == SSDP_SERROR ) {
-        return UPNP_E_INVALID_PARAM;
-    }
-
-    ReqBuf = ( char * )malloc( BUFSIZE );
-    if( ReqBuf == NULL )
-        return UPNP_E_OUTOF_MEMORY;
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
-                         ">>> SSDP SEND >>>\n%s\n", ReqBuf );
-         )
-
-        timeTillRead = Mx;
-
-    if( timeTillRead < MIN_SEARCH_TIME ) {
-        timeTillRead = MIN_SEARCH_TIME;
-    } else if( timeTillRead > MAX_SEARCH_TIME ) {
-        timeTillRead = MAX_SEARCH_TIME;
-    }
-
-    CreateClientRequestPacket( ReqBuf, timeTillRead, St );
-    memset( ( char * )&destAddr, 0, sizeof( struct sockaddr_in ) );
-
-    destAddr.sin_family = AF_INET;
-    destAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
-    destAddr.sin_port = htons( SSDP_PORT );
-
-    FD_ZERO( &wrSet );
-    FD_SET( gSsdpReqSocket, &wrSet );
-
-    //add search criteria to list
-    HandleLock(  );
-    if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
-        HandleUnlock(  );
-        free( ReqBuf );
-        return UPNP_E_INTERNAL_ERROR;
-    }
-
-    newArg = ( SsdpSearchArg * ) malloc( sizeof( SsdpSearchArg ) );
-    newArg->searchTarget = strdup( St );
-    newArg->cookie = Cookie;
-    newArg->requestType = requestType;
-
-    id = ( int * )malloc( sizeof( int ) );
-    TPJobInit( &job, ( start_routine ) searchExpired, id );
-    TPJobSetPriority( &job, MED_PRIORITY );
-    TPJobSetFreeFunction( &job, ( free_routine ) free );
-
-    //Schdule a timeout event to remove search Arg
-    TimerThreadSchedule( &gTimerThread, timeTillRead,
-                         REL_SEC, &job, SHORT_TERM, id );
-    newArg->timeoutEventId = ( *id );
-
-    ListAddTail( &ctrlpt_info->SsdpSearchList, newArg );
-    HandleUnlock(  );
-
-    setsockopt( gSsdpReqSocket, IPPROTO_IP, IP_MULTICAST_IF,
-                ( char * )&addr, sizeof( addr ) );
-
-    if( select( gSsdpReqSocket + 1, NULL, &wrSet, NULL, NULL )
-        == UPNP_SOCKETERROR ) {
-        DBGONLY( if( errno == EBADF ) {
-                 UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
-                             "SSDP_LIB :RequestHandler:An invalid file descriptor"
-                             " was givenin one of the sets. \n" );}
-                 else
-                 if( errno == EINTR ) {
-                 UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
-                             "SSDP_LIB :RequestHandler:  A non blocked "
-                             "signal was caught.    \n" );}
-                 else
-                 if( errno == EINVAL ) {
-                 UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
-                             "SSDP_LIB :RequestHandler: n is negative.  \n" );}
-                 else
-                 if( errno == ENOMEM ) {
-                 UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
-                             "SSDP_LIB : RequestHandler:select was unable to "
-                             "allocate memory for internal tables.\n" );}
- )
-shutdown( gSsdpReqSocket, SD_BOTH );
-        UpnpCloseSocket( gSsdpReqSocket );
-        free( ReqBuf );
-        return UPNP_E_INTERNAL_ERROR;
-    } else if( FD_ISSET( gSsdpReqSocket, &wrSet ) ) {
-        int NumCopy = 0;
-
-        while( NumCopy < NUM_SSDP_COPY ) {
-            sendto( gSsdpReqSocket, ReqBuf, strlen( ReqBuf ), 0,
-                    ( struct sockaddr * )&destAddr, socklen );
-            NumCopy++;
-            imillisleep( SSDP_PAUSE );
-        }
-    }
-
-    free( ReqBuf );
-    return 1;
-}
-
-#endif // EXCLUDE_SSDP
-#endif // INCLUDE_CLIENT_APIS
diff --git a/tombupnp/upnp/src/ssdp/ssdp_device.c b/tombupnp/upnp/src/ssdp/ssdp_device.c
deleted file mode 100644
index 4c25d9d..0000000
--- a/tombupnp/upnp/src/ssdp/ssdp_device.c
+++ /dev/null
@@ -1,847 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-/*TU*
-    
-    TombUPnP - a library for developing UPnP applications.
-    
-    Copyright (C) 2006-2010 Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License version 2.1 as published by the Free Software Foundation.
-    
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-    
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
-*/
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#ifdef INCLUDE_DEVICE_APIS
-#if EXCLUDE_SSDP == 0
-#include <assert.h>
-#include <stdio.h>
-#include "ssdplib.h"
-#include "upnpapi.h"
-#include "ThreadPool.h"
-#include "httpparser.h"
-#include "httpreadwrite.h"
-#include "statcodes.h"
-#include "unixutil.h"
-
-#ifdef WIN32
- #include <ws2tcpip.h>
- #include <winsock2.h>
-#endif
-
-#define MSGTYPE_SHUTDOWN		0
-#define MSGTYPE_ADVERTISEMENT	1
-#define MSGTYPE_REPLY			2
-
-/************************************************************************
-* Function : advertiseAndReplyThread									
-*																	
-* Parameters:														
-*		IN void *data: Structure containing the search request
-*
-* Description:														
-*	This function is a wrapper function to reply the search request 
-*	coming from the control point.
-*
-* Returns: void *
-*	always return NULL
-***************************************************************************/
-void *
-advertiseAndReplyThread( IN void *data )
-{
-    SsdpSearchReply *arg = ( SsdpSearchReply * ) data;
-
-    AdvertiseAndReply( 0, arg->handle,
-                       arg->event.RequestType,
-                       &arg->dest_addr,
-                       arg->event.DeviceType,
-                       arg->event.UDN,
-                       arg->event.ServiceType, arg->MaxAge );
-    free( arg );
-
-    return NULL;
-}
-
-/************************************************************************
-* Function : ssdp_handle_device_request									
-*																	
-* Parameters:														
-*		IN http_message_t* hmsg: SSDP search request from the control point
-*		IN struct sockaddr_in* dest_addr: The address info of control point
-*
-* Description:														
-*	This function handles the search request. It do the sanity checks of
-*	the request and then schedules a thread to send a random time reply (
-*	random within maximum time given by the control point to reply).
-*
-* Returns: void *
-*	1 if successful else appropriate error
-***************************************************************************/
-void
-ssdp_handle_device_request( IN http_message_t * hmsg,
-                            IN struct sockaddr_in *dest_addr )
-{
-#define MX_FUDGE_FACTOR 10
-
-    int handle;
-    struct Handle_Info *dev_info = NULL;
-    memptr hdr_value;
-    int mx;
-    char save_char;
-    SsdpEvent event;
-    int ret_code;
-    SsdpSearchReply *threadArg = NULL;
-    ThreadPoolJob job;
-    int replyTime;
-    int maxAge;
-
-    // check man hdr
-    if( httpmsg_find_hdr( hmsg, HDR_MAN, &hdr_value ) == NULL ||
-        memptr_cmp( &hdr_value, "\"ssdp:discover\"" ) != 0 ) {
-        return;                 // bad or missing hdr
-    }
-    // MX header
-    if( httpmsg_find_hdr( hmsg, HDR_MX, &hdr_value ) == NULL ||
-        ( mx = raw_to_int( &hdr_value, 10 ) ) < 0 ) {
-        return;
-    }
-    // ST header
-    if( httpmsg_find_hdr( hmsg, HDR_ST, &hdr_value ) == NULL ) {
-        return;
-    }
-    save_char = hdr_value.buf[hdr_value.length];
-    hdr_value.buf[hdr_value.length] = '\0';
-    ret_code = ssdp_request_type( hdr_value.buf, &event );
-    hdr_value.buf[hdr_value.length] = save_char;    // restore
-    if( ret_code == -1 ) {
-        return;                 // bad ST header
-    }
-
-    HandleLock(  );
-    // device info
-    if( GetDeviceHandleInfo( &handle, &dev_info ) != HND_DEVICE ) {
-        HandleUnlock(  );
-        return;                 // no info found
-    }
-    maxAge = dev_info->MaxAge;
-    HandleUnlock(  );
-
-    DBGONLY( UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__,
-                         "ssdp_handle_device_request with Cmd %d SEARCH\n",
-                         event.Cmd );
-             UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__,
-                         "MAX-AGE     =  %d\n", maxAge );
-             UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__,
-                         "MX     =  %d\n", event.Mx );
-             UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__,
-                         "DeviceType   =  %s\n", event.DeviceType );
-             UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__,
-                         "DeviceUuid   =  %s\n", event.UDN );
-             UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__,
-                         "ServiceType =  %s\n", event.ServiceType ); )
-
-        threadArg =
-        ( SsdpSearchReply * ) malloc( sizeof( SsdpSearchReply ) );
-
-    if( threadArg == NULL ) {
-        return;
-    }
-    threadArg->handle = handle;
-    threadArg->dest_addr = ( *dest_addr );
-    threadArg->event = event;
-    threadArg->MaxAge = maxAge;
-
-    TPJobInit( &job, advertiseAndReplyThread, threadArg );
-    TPJobSetFreeFunction( &job, ( free_routine ) free );
-
-    //Subtract a percentage from the mx
-    //to allow for network and processing delays
-    // (i.e. if search is for 30 seconds, 
-    //       respond withing 0 - 27 seconds)
-
-    if( mx >= 2 ) {
-        mx -= MAXVAL( 1, mx / MX_FUDGE_FACTOR );
-    }
-
-    if( mx < 1 ) {
-        mx = 1;
-    }
-
-    replyTime = rand(  ) % mx;
-
-    TimerThreadSchedule( &gTimerThread, replyTime, REL_SEC, &job,
-                         SHORT_TERM, NULL );
-}
-
-/************************************************************************
-* Function : NewRequestHandler									
-*																	
-* Parameters:														
-*		IN struct sockaddr_in * DestAddr: Ip address, to send the reply.
-*		IN int NumPacket: Number of packet to be sent.
-*		IN char **RqPacket:Number of packet to be sent.
-*
-* Description:														
-*	This function works as a request handler which passes the HTTP 
-*	request string to multicast channel then
-*
-* Returns: void *
-*	1 if successful else appropriate error
-***************************************************************************/
-static int
-NewRequestHandler( IN struct sockaddr_in *DestAddr,
-                   IN int NumPacket,
-                   IN char **RqPacket )
-{
-    int ReplySock,
-      socklen = sizeof( struct sockaddr_in );
-    int NumCopy,
-      Index;
-    unsigned long replyAddr = inet_addr( LOCAL_HOST );
-    int ttl = 4;                //a/c to UPNP Spec
-
-    ReplySock = socket( AF_INET, SOCK_DGRAM, 0 );
-    if( ReplySock == UPNP_INVALID_SOCKET ) {
-        DBGONLY( UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
-                             "SSDP_LIB: New Request Handler:"
-                             "Error in socket operation !!!\n" ) );
-
-        return UPNP_E_OUTOF_SOCKET;
-    }
-
-    setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_IF,
-                ( char * )&replyAddr, sizeof( replyAddr ) );
-    setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_TTL,
-                ( char * )&ttl, sizeof( int ) );
-
-    for( Index = 0; Index < NumPacket; Index++ ) {
-        int rc;
-
-        // The reason to keep this loop is purely historical/documentation,
-        // according to section 9.2 of HTTPU spec:
-        // 
-        // "If a multicast resource would send a response(s) to any copy of the 
-        //  request, it SHOULD send its response(s) to each copy of the request 
-        //  it receives. It MUST NOT repeat its response(s) per copy of the 
-        //  reuqest."
-        //  
-        // http://www.upnp.org/download/draft-goland-http-udp-04.txt
-        //
-        // So, NUM_COPY has been changed from 2 to 1.
-        NumCopy = 0;
-        while( NumCopy < NUM_COPY ) {
-            DBGONLY( UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
-                                 ">>> SSDP SEND >>>\n%s\n",
-                                 *( RqPacket + Index ) );
-                 )
-                rc = sendto( ReplySock, *( RqPacket + Index ),
-                             strlen( *( RqPacket + Index ) ),
-                             0, ( struct sockaddr * )DestAddr, socklen );
-                if (rc == -1) {
-                    DBGONLY( UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
-                                "SSDP_LIB: sendto failed!\n") );
-                }
-            imillisleep( SSDP_PAUSE );
-            ++NumCopy;
-        }
-    }
-
-    shutdown( ReplySock, SD_BOTH );
-    UpnpCloseSocket( ReplySock );
-    return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-* Function : CreateServiceRequestPacket									
-*																	
-* Parameters:														
-*	IN int msg_type : type of the message ( Search Reply, Advertisement 
-*												or Shutdown )
-*	IN char * nt : ssdp type
-*	IN char * usn : unique service name ( go in the HTTP Header)
-*	IN char * location :Location URL.
-*	IN int  duration :Service duration in sec.
-*	OUT char** packet :Output buffer filled with HTTP statement.
-*
-* Description:														
-*	This function creates a HTTP request packet.  Depending 
-*	on the input parameter it either creates a service advertisement
-*   request or service shutdown request etc.
-*
-* Returns: void
-*	
-***************************************************************************/
-void
-CreateServicePacket( IN int msg_type,
-                     IN char *nt,
-                     IN char *usn,
-                     IN char *location,
-                     IN int duration,
-                     OUT char **packet )
-{
-    int ret_code;
-    char *nts;
-    membuffer buf;
-
-    //Notf=0 means service shutdown, 
-    //Notf=1 means service advertisement, Notf =2 means reply   
-
-    membuffer_init( &buf );
-    buf.size_inc = 30;
-
-    *packet = NULL;
-
-    if( msg_type == MSGTYPE_REPLY ) {
-        ret_code = http_MakeMessage( &buf, 1, 1,
-                                     "R" "sdc" "D" "s" "ssc" "S" "ssc"
-                                     "ssc" "A" "c", HTTP_OK,
-                                     "CACHE-CONTROL: max-age=", duration,
-                                     "EXT:\r\n", "LOCATION: ", location,
-                                     "ST: ", nt, "USN: ", usn, 
-                                     gUserHTTPHeaders.buf );
-        if( ret_code != 0 ) {
-            return;
-        }
-    } else if( msg_type == MSGTYPE_ADVERTISEMENT ||
-               msg_type == MSGTYPE_SHUTDOWN ) {
-        if( msg_type == MSGTYPE_ADVERTISEMENT ) {
-            nts = "ssdp:alive";
-        } else                  // shutdown
-        {
-            nts = "ssdp:byebye";
-        }
-
-        // NOTE: The CACHE-CONTROL and LOCATION headers are not present in
-        //  a shutdown msg, but are present here for MS WinMe interop.
-
-        ret_code = http_MakeMessage( &buf, 1, 1,
-                                     "Q" "sssdc" "sdc" "ssc" "ssc" "ssc"
-                                     "S" "ssc" "A" "c", HTTPMETHOD_NOTIFY, "*",
-                                     (size_t)1, "HOST: ", SSDP_IP, ":", SSDP_PORT,
-                                     "CACHE-CONTROL: max-age=", duration,
-                                     "LOCATION: ", location, "NT: ", nt,
-                                     "NTS: ", nts, 
-                                     "USN: ", usn, gUserHTTPHeaders.buf );
-        if( ret_code != 0 ) {
-            return;
-        }
-
-    } else {
-        assert( 0 );            // unknown msg
-    }
-
-    *packet = membuffer_detach( &buf ); // return msg
-
-    membuffer_destroy( &buf );
-
-    return;
-}
-
-/************************************************************************
-* Function : DeviceAdvertisement									
-*																	
-* Parameters:														
-*	IN char * DevType : type of the device
-*	IN int RootDev: flag to indicate if the device is root device
-*	IN char * nt : ssdp type
-*	IN char * usn : unique service name
-*	IN char * location :Location URL.
-*	IN int  duration :Service duration in sec.
-*
-* Description:														
-*	This function creates the device advertisement request based on 
-*	the input parameter, and send it to the multicast channel.
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-int
-DeviceAdvertisement( IN char *DevType,
-                     int RootDev,
-                     char *Udn,
-                     IN char *Location,
-                     IN int Duration )
-{
-    struct sockaddr_in DestAddr;
-
-    //char Mil_Nt[LINE_SIZE]
-    char Mil_Usn[LINE_SIZE];
-    char *msgs[3];
-    int ret_code;
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
-                         "In function SendDeviceAdvertisemenrt\n" );
-         )
-
-        DestAddr.sin_family = AF_INET;
-    DestAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
-    DestAddr.sin_port = htons( SSDP_PORT );
-
-    msgs[0] = NULL;
-    msgs[1] = NULL;
-    msgs[2] = NULL;
-
-    //If deviceis a root device , here we need to 
-    //send 3 advertisement or reply
-    if( RootDev ) {
-        sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
-        CreateServicePacket( MSGTYPE_ADVERTISEMENT, "upnp:rootdevice",
-                             Mil_Usn, Location, Duration, &msgs[0] );
-    }
-    // both root and sub-devices need to send these two messages
-    //
-
-    CreateServicePacket( MSGTYPE_ADVERTISEMENT, Udn, Udn,
-                         Location, Duration, &msgs[1] );
-
-    sprintf( Mil_Usn, "%s::%s", Udn, DevType );
-    CreateServicePacket( MSGTYPE_ADVERTISEMENT, DevType, Mil_Usn,
-                         Location, Duration, &msgs[2] );
-
-    // check error
-    if( ( RootDev && msgs[0] == NULL ) ||
-        msgs[1] == NULL || msgs[2] == NULL ) {
-        free( msgs[0] );
-        free( msgs[1] );
-        free( msgs[2] );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    // send packets
-    if( RootDev ) {
-        // send 3 msg types
-        ret_code = NewRequestHandler( &DestAddr, 3, &msgs[0] );
-    } else                      // sub-device
-    {
-        // send 2 msg types
-        ret_code = NewRequestHandler( &DestAddr, 2, &msgs[1] );
-    }
-
-    // free msgs
-    free( msgs[0] );
-    free( msgs[1] );
-    free( msgs[2] );
-
-    return ret_code;
-}
-
-/************************************************************************
-* Function : SendReply									
-*																	
-* Parameters:	
-*	IN struct sockaddr_in * DestAddr:destination IP address.
-*	IN char *DevType: Device type
-*	IN int RootDev: 1 means root device 0 means embedded device.
-*	IN char * Udn: Device UDN
-*	IN char * Location: Location of Device description document.
-*	IN int  Duration :Life time of this device.
-*	IN int ByType:
-*
-* Description:														
-*	This function creates the reply packet based on the input parameter, 
-*	and send it to the client addesss given in its input parameter DestAddr.
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-int
-SendReply( IN struct sockaddr_in *DestAddr,
-           IN char *DevType,
-           IN int RootDev,
-           IN char *Udn,
-           IN char *Location,
-           IN int Duration,
-           IN int ByType )
-{
-    int ret_code;
-    char *msgs[2];
-    int num_msgs;
-    char Mil_Usn[LINE_SIZE];
-    int i;
-
-    msgs[0] = NULL;
-    msgs[1] = NULL;
-
-    if( RootDev ) {
-        // one msg for root device
-        num_msgs = 1;
-
-        sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
-        CreateServicePacket( MSGTYPE_REPLY, "upnp:rootdevice",
-                             Mil_Usn, Location, Duration, &msgs[0] );
-    } else {
-        // two msgs for embedded devices
-        num_msgs = 1;
-
-        //NK: FIX for extra response when someone searches by udn
-        if( !ByType ) {
-            CreateServicePacket( MSGTYPE_REPLY, Udn, Udn, Location,
-                                 Duration, &msgs[0] );
-        } else {
-            sprintf( Mil_Usn, "%s::%s", Udn, DevType );
-            CreateServicePacket( MSGTYPE_REPLY, DevType, Mil_Usn,
-                                 Location, Duration, &msgs[0] );
-        }
-    }
-
-    // check error
-    for( i = 0; i < num_msgs; i++ ) {
-        if( msgs[i] == NULL ) {
-            free( msgs[0] );
-            return UPNP_E_OUTOF_MEMORY;
-        }
-    }
-
-    // send msgs
-    ret_code = NewRequestHandler( DestAddr, num_msgs, msgs );
-    for( i = 0; i < num_msgs; i++ ) {
-        if( msgs[i] != NULL )
-            free( msgs[i] );
-    }
-
-    return ret_code;
-}
-
-/************************************************************************
-* Function : DeviceReply									
-*																	
-* Parameters:	
-*	IN struct sockaddr_in * DestAddr:destination IP address.
-*	IN char *DevType: Device type
-*	IN int RootDev: 1 means root device 0 means embedded device.
-*	IN char * Udn: Device UDN
-*	IN char * Location: Location of Device description document.
-*	IN int  Duration :Life time of this device.
-
-* Description:														
-*	This function creates the reply packet based on the input parameter, 
-*	and send it to the client address given in its input parameter DestAddr.
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-int
-DeviceReply( IN struct sockaddr_in *DestAddr,
-             IN char *DevType,
-             IN int RootDev,
-             IN char *Udn,
-             IN char *Location,
-             IN int Duration )
-{
-    char *szReq[3],
-      Mil_Nt[LINE_SIZE],
-      Mil_Usn[LINE_SIZE];
-    int RetVal;
-
-    szReq[0] = NULL;
-    szReq[1] = NULL;
-    szReq[2] = NULL;
-
-    // create 2 or 3 msgs
-
-    if( RootDev ) {
-        // 3 replies for root device
-        strcpy( Mil_Nt, "upnp:rootdevice" );
-        sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
-        CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
-                             Location, Duration, &szReq[0] );
-    }
-
-    sprintf( Mil_Nt, "%s", Udn );
-    sprintf( Mil_Usn, "%s", Udn );
-    CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
-                         Location, Duration, &szReq[1] );
-
-    sprintf( Mil_Nt, "%s", DevType );
-    sprintf( Mil_Usn, "%s::%s", Udn, DevType );
-    CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
-                         Location, Duration, &szReq[2] );
-
-    // check error
-
-    if( ( RootDev && szReq[0] == NULL ) ||
-        szReq[1] == NULL || szReq[2] == NULL ) {
-        free( szReq[0] );
-        free( szReq[1] );
-        free( szReq[2] );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    // send replies
-    if( RootDev ) {
-        RetVal = NewRequestHandler( DestAddr, 3, szReq );
-    } else {
-        RetVal = NewRequestHandler( DestAddr, 2, &szReq[1] );
-    }
-
-    // free
-    free( szReq[0] );
-    free( szReq[1] );
-    free( szReq[2] );
-
-    return RetVal;
-}
-
-/************************************************************************
-* Function : ServiceAdvertisement									
-*																	
-* Parameters:	
-*	IN char * Udn: Device UDN
-*	IN char *ServType: Service Type.
-*	IN char * Location: Location of Device description document.
-*	IN int  Duration :Life time of this device.
-
-* Description:														
-*	This function creates the advertisement packet based 
-*	on the input parameter, and send it to the multicast channel.
-
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-int
-ServiceAdvertisement( IN char *Udn,
-                      IN char *ServType,
-                      IN char *Location,
-                      IN int Duration )
-{
-    char Mil_Usn[LINE_SIZE];
-    char *szReq[1];
-    struct sockaddr_in DestAddr;
-    int RetVal;
-
-    DestAddr.sin_family = AF_INET;
-    DestAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
-    DestAddr.sin_port = htons( SSDP_PORT );
-
-    sprintf( Mil_Usn, "%s::%s", Udn, ServType );
-
-    //CreateServiceRequestPacket(1,szReq[0],Mil_Nt,Mil_Usn,
-    //Server,Location,Duration);
-    CreateServicePacket( MSGTYPE_ADVERTISEMENT, ServType, Mil_Usn,
-                         Location, Duration, &szReq[0] );
-    if( szReq[0] == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    RetVal = NewRequestHandler( &DestAddr, 1, szReq );
-
-    free( szReq[0] );
-    return RetVal;
-}
-
-/************************************************************************
-* Function : ServiceReply									
-*																	
-* Parameters:	
-*	IN struct sockaddr_in *DestAddr:
-*	IN char * Udn: Device UDN
-*	IN char *ServType: Service Type.
-*	IN char * Location: Location of Device description document.
-*	IN int  Duration :Life time of this device.
-
-* Description:														
-*	This function creates the advertisement packet based 
-*	on the input parameter, and send it to the multicast channel.
-
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-int
-ServiceReply( IN struct sockaddr_in *DestAddr,
-              IN char *ServType,
-              IN char *Udn,
-              IN char *Location,
-              IN int Duration )
-{
-    char Mil_Usn[LINE_SIZE];
-    char *szReq[1];
-    int RetVal;
-
-    szReq[0] = NULL;
-
-    sprintf( Mil_Usn, "%s::%s", Udn, ServType );
-
-    CreateServicePacket( MSGTYPE_REPLY, ServType, Mil_Usn,
-                         Location, Duration, &szReq[0] );
-    if( szReq[0] == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    RetVal = NewRequestHandler( DestAddr, 1, szReq );
-
-    free( szReq[0] );
-    return RetVal;
-}
-
-/************************************************************************
-* Function : ServiceShutdown									
-*																	
-* Parameters:	
-*	IN char * Udn: Device UDN
-*	IN char *ServType: Service Type.
-*	IN char * Location: Location of Device description document.
-*	IN int  Duration :Service duration in sec.
-
-* Description:														
-*	This function creates a HTTP service shutdown request packet 
-*	and sent it to the multicast channel through RequestHandler.
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-int
-ServiceShutdown( IN char *Udn,
-                 IN char *ServType,
-                 IN char *Location,
-                 IN int Duration )
-{
-    char Mil_Usn[LINE_SIZE];
-    char *szReq[1];
-    struct sockaddr_in DestAddr;
-    int RetVal;
-
-    DestAddr.sin_family = AF_INET;
-    DestAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
-    DestAddr.sin_port = htons( SSDP_PORT );
-
-    //sprintf(Mil_Nt,"%s",ServType);
-    sprintf( Mil_Usn, "%s::%s", Udn, ServType );
-    //CreateServiceRequestPacket(0,szReq[0],Mil_Nt,Mil_Usn,
-    //Server,Location,Duration);
-    CreateServicePacket( MSGTYPE_SHUTDOWN, ServType, Mil_Usn,
-                         Location, Duration, &szReq[0] );
-    if( szReq[0] == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    RetVal = NewRequestHandler( &DestAddr, 1, szReq );
-
-    free( szReq[0] );
-    return RetVal;
-}
-
-/************************************************************************
-* Function : DeviceShutdown									
-*																	
-* Parameters:	
-*	IN char *DevType: Device Type.
-*	IN int RootDev:1 means root device.
-*	IN char * Udn: Device UDN
-*	IN char * Location: Location URL
-*	IN int  Duration :Device duration in sec.
-*
-* Description:														
-*	This function creates a HTTP device shutdown request packet 
-*	and sent it to the multicast channel through RequestHandler.
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-int
-DeviceShutdown( IN char *DevType,
-                IN int RootDev,
-                IN char *Udn,
-                IN char *_Server,
-                IN char *Location,
-                IN int Duration )
-{
-    struct sockaddr_in DestAddr;
-    char *msgs[3];
-    char Mil_Usn[LINE_SIZE];
-    int ret_code;
-
-    msgs[0] = NULL;
-    msgs[1] = NULL;
-    msgs[2] = NULL;
-
-    DestAddr.sin_family = AF_INET;
-    DestAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
-    DestAddr.sin_port = htons( SSDP_PORT );
-
-    // root device has one extra msg
-    if( RootDev ) {
-        sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
-        CreateServicePacket( MSGTYPE_SHUTDOWN, "upnp:rootdevice",
-                             Mil_Usn, Location, Duration, &msgs[0] );
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
-                         "In function DeviceShutdown\n" ); )
-        // both root and sub-devices need to send these two messages
-        CreateServicePacket( MSGTYPE_SHUTDOWN, Udn, Udn,
-                             Location, Duration, &msgs[1] );
-
-    sprintf( Mil_Usn, "%s::%s", Udn, DevType );
-    CreateServicePacket( MSGTYPE_SHUTDOWN, DevType, Mil_Usn,
-                         Location, Duration, &msgs[2] );
-
-    // check error
-    if( ( RootDev && msgs[0] == NULL ) ||
-        msgs[1] == NULL || msgs[2] == NULL ) {
-        free( msgs[0] );
-        free( msgs[1] );
-        free( msgs[2] );
-        return UPNP_E_OUTOF_MEMORY;
-    }
-    // send packets
-    if( RootDev ) {
-        // send 3 msg types
-        ret_code = NewRequestHandler( &DestAddr, 3, &msgs[0] );
-    } else                      // sub-device
-    {
-        // send 2 msg types
-        ret_code = NewRequestHandler( &DestAddr, 2, &msgs[1] );
-    }
-
-    // free msgs
-    free( msgs[0] );
-    free( msgs[1] );
-    free( msgs[2] );
-
-    return ret_code;
-}
-
-#endif // EXCLUDE_SSDP
-#endif // INCLUDE_DEVICE_APIS
diff --git a/tombupnp/upnp/src/ssdp/ssdp_server.c b/tombupnp/upnp/src/ssdp/ssdp_server.c
deleted file mode 100644
index 04d6174..0000000
--- a/tombupnp/upnp/src/ssdp/ssdp_server.c
+++ /dev/null
@@ -1,1053 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#if EXCLUDE_SSDP == 0
-
-#include "membuffer.h"
-#include "ssdplib.h"
-#include <stdio.h>
-#include "ThreadPool.h"
-#include "miniserver.h"
-
-#include "upnpapi.h"
-#include "httpparser.h"
-#include "httpreadwrite.h"
-
-#ifdef WIN32
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include "unixutil.h"
-#endif
-
-#define MAX_TIME_TOREAD  45
-
-CLIENTONLY( SOCKET gSsdpReqSocket = 0;
-     )
-
-     void RequestHandler(  );
-     Event ErrotEvt;
-
-     enum Listener { Idle, Stopping, Running };
-
-     unsigned short ssdpStopPort;
-
-     struct SSDPSockArray {
-         int ssdpSock;          //socket for incoming advertisments and search requests
-           CLIENTONLY( int ssdpReqSock;
-              )                 //socket for sending search 
-             //requests and receiving
-             // search replies
-     };
-
-#ifdef INCLUDE_DEVICE_APIS
-#if EXCLUDE_SSDP == 0
-
-/************************************************************************
-* Function : AdvertiseAndReply									
-*																	
-* Parameters:														
-*	IN int AdFlag: -1 = Send shutdown, 0 = send reply, 
-*					1 = Send Advertisement
-*	IN UpnpDevice_Handle Hnd: Device handle
-*	IN enum SsdpSearchType SearchType:Search type for sending replies
-*	IN struct sockaddr_in *DestAddr:Destination address
-*   IN char *DeviceType:Device type
-*	IN char *DeviceUDN:Device UDN
-*   IN char *ServiceType:Service type
-*	IN int Exp:Advertisement age
-*
-* Description:														
-*	This function sends SSDP advertisements, replies and shutdown messages.
-*
-* Returns: int
-*	UPNP_E_SUCCESS if successful else appropriate error
-***************************************************************************/
-     int AdvertiseAndReply( IN int AdFlag,
-                            IN UpnpDevice_Handle Hnd,
-                            IN enum SsdpSearchType SearchType,
-                            IN struct sockaddr_in *DestAddr,
-                            IN char *DeviceType,
-                            IN char *DeviceUDN,
-                            IN char *ServiceType,
-                            int Exp )
-{
-    int i,
-      j;
-    int defaultExp = DEFAULT_MAXAGE;
-    struct Handle_Info *SInfo = NULL;
-    char UDNstr[100],
-      devType[100],
-      servType[100];
-    IXML_NodeList *nodeList = NULL;
-    IXML_NodeList *tmpNodeList = NULL;
-    IXML_Node *tmpNode = NULL;
-    IXML_Node *tmpNode2 = NULL;
-    IXML_Node *textNode = NULL;
-    const DOMString tmpStr;
-    char SERVER[200];
-
-    DBGONLY( const DOMString dbgStr;
-             UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Inside AdvertiseAndReply with AdFlag = %d\n",
-                         AdFlag ); )
-
-        HandleLock(  );
-    if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
-        HandleUnlock(  );
-        return UPNP_E_INVALID_HANDLE;
-    }
-    defaultExp = SInfo->MaxAge;
-
-    //Modifed to prevent more than one thread from accessing the 
-    //UpnpDocument stored with the handle at the same time
-    // HandleUnlock();
-    nodeList = NULL;
-
-    //get server info
-
-    get_sdk_info( SERVER );
-
-    // parse the device list and send advertisements/replies 
-    for( i = 0;; i++ ) {
-
-        DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                             "Entering new device list with i = %d\n\n",
-                             i );
-             )
-
-            tmpNode = ixmlNodeList_item( SInfo->DeviceList, i );
-        if( tmpNode == NULL ) {
-            DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                                 "Exiting new device list with i = %d\n\n",
-                                 i );
-                 )
-                break;
-        }
-
-        DBGONLY( dbgStr = ixmlNode_getNodeName( tmpNode );
-                 UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "Extracting device type once for %s\n",
-                             dbgStr ); )
-            // extract device type 
-            ixmlNodeList_free( nodeList );
-        nodeList = NULL;
-        nodeList =
-            ixmlElement_getElementsByTagName( ( IXML_Element * ) tmpNode,
-                                              "deviceType" );
-        if( nodeList == NULL ) {
-            continue;
-        }
-
-        DBGONLY( dbgStr = ixmlNode_getNodeName( tmpNode );
-                 UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                             "Extracting UDN for %s\n", dbgStr ); )
-
-            DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                                 "Extracting device type\n" );
-             )
-
-            tmpNode2 = ixmlNodeList_item( nodeList, 0 );
-        if( tmpNode2 == NULL ) {
-            continue;
-        }
-        textNode = ixmlNode_getFirstChild( tmpNode2 );
-        if( textNode == NULL ) {
-            continue;
-        }
-
-        DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                             "Extracting device type \n" );
-             )
-
-            tmpStr = ixmlNode_getNodeValue( textNode );
-        if( tmpStr == NULL ) {
-            continue;
-        }
-
-        strcpy( devType, tmpStr );
-        if( devType == NULL ) {
-            continue;
-        }
-
-        DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                             "Extracting device type = %s\n", devType );
-                 if( tmpNode == NULL ) {
-                 UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                             "TempNode is NULL\n" );}
-                 dbgStr = ixmlNode_getNodeName( tmpNode );
-                 UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                             "Extracting UDN for %s\n", dbgStr ); )
-            // extract UDN 
-            ixmlNodeList_free( nodeList );
-        nodeList = NULL;
-        nodeList = ixmlElement_getElementsByTagName( ( IXML_Element * )
-                                                     tmpNode, "UDN" );
-        if( nodeList == NULL ) {
-
-            DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__,
-                                 __LINE__, "UDN not found!!!\n" );
-                 )
-                continue;
-        }
-        tmpNode2 = ixmlNodeList_item( nodeList, 0 );
-        if( tmpNode2 == NULL ) {
-
-            DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__,
-                                 __LINE__, "UDN not found!!!\n" );
-                 )
-                continue;
-        }
-        textNode = ixmlNode_getFirstChild( tmpNode2 );
-        if( textNode == NULL ) {
-
-            DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__,
-                                 __LINE__, "UDN not found!!!\n" );
-                 )
-                continue;
-        }
-        tmpStr = ixmlNode_getNodeValue( textNode );
-        if( tmpStr == NULL ) {
-            DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
-                                 "UDN not found!!!!\n" );
-                 )
-                continue;
-        }
-        strcpy( UDNstr, tmpStr );
-        if( UDNstr == NULL ) {
-            continue;
-        }
-
-        DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "Sending UDNStr = %s \n", UDNstr );
-             )
-            if( AdFlag ) {
-            // send the device advertisement 
-            if( AdFlag == 1 ) {
-                DeviceAdvertisement( devType, i == 0,
-                                     UDNstr, SInfo->DescURL, Exp );
-            } else              // AdFlag == -1
-            {
-                DeviceShutdown( devType, i == 0, UDNstr,
-                                SERVER, SInfo->DescURL, Exp );
-            }
-        } else {
-            switch ( SearchType ) {
-
-                case SSDP_ALL:
-                    DeviceReply( DestAddr,
-                                 devType, i == 0,
-                                 UDNstr, SInfo->DescURL, defaultExp );
-                    break;
-
-                case SSDP_ROOTDEVICE:
-                    if( i == 0 ) {
-                        SendReply( DestAddr, devType, 1,
-                                   UDNstr, SInfo->DescURL, defaultExp, 0 );
-                    }
-                    break;
-                case SSDP_DEVICEUDN:
-                    {
-                        if( DeviceUDN != NULL && strlen( DeviceUDN ) != 0 ) {
-                            if( strcasecmp( DeviceUDN, UDNstr ) ) {
-                                DBGONLY( UpnpPrintf
-                                         ( UPNP_INFO, API, __FILE__,
-                                           __LINE__,
-                                           "DeviceUDN=%s and search "
-                                           "UDN=%s did not match\n",
-                                           UDNstr, DeviceUDN );
-                                     )
-                                    break;
-                            } else {
-                                DBGONLY( UpnpPrintf
-                                         ( UPNP_INFO, API, __FILE__,
-                                           __LINE__,
-                                           "DeviceUDN=%s and search "
-                                           "UDN=%s MATCH\n", UDNstr,
-                                           DeviceUDN );
-                                     )
-                                    SendReply( DestAddr, devType, 0,
-                                               UDNstr, SInfo->DescURL,
-                                               defaultExp, 0 );
-                                break;
-                            }
-                        }
-                    }
-                case SSDP_DEVICETYPE:
-                    {
-                        if( !strncasecmp
-                            ( DeviceType, devType,
-                              strlen( DeviceType ) ) ) {
-                            DBGONLY( UpnpPrintf
-                                     ( UPNP_INFO, API, __FILE__, __LINE__,
-                                       "DeviceType=%s and search devType=%s MATCH\n",
-                                       devType, DeviceType );
-                                 )
-                                SendReply( DestAddr, devType, 0, UDNstr,
-                                           SInfo->DescURL, defaultExp, 1 );
-                        }
-
-                        DBGONLY(
-                                    else
-                                    UpnpPrintf( UPNP_INFO, API, __FILE__,
-                                                __LINE__,
-                                                "DeviceType=%s and search devType=%s"
-                                                " DID NOT MATCH\n",
-                                                devType, DeviceType );
-                             )
-
-                            break;
-                    }
-                default:
-                    break;
-            }
-        }
-        // send service advertisements for services corresponding 
-        // to the same device 
-        DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "Sending service Advertisement\n" );
-             )
-
-            tmpNode = ixmlNodeList_item( SInfo->ServiceList, i );
-        if( tmpNode == NULL ) {
-            continue;
-        }
-        ixmlNodeList_free( nodeList );
-        nodeList = NULL;
-        nodeList = ixmlElement_getElementsByTagName( ( IXML_Element * )
-                                                     tmpNode, "service" );
-        if( nodeList == NULL ) {
-            DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                                 "Service not found 3\n" );
-                 )
-                continue;
-        }
-        for( j = 0;; j++ ) {
-            tmpNode = ixmlNodeList_item( nodeList, j );
-            if( tmpNode == NULL )
-                break;
-
-            ixmlNodeList_free( tmpNodeList );
-            tmpNodeList = NULL;
-            tmpNodeList = ixmlElement_getElementsByTagName( ( IXML_Element
-                                                              * ) tmpNode,
-                                                            "serviceType" );
-
-            if( tmpNodeList == NULL ) {
-                DBGONLY( UpnpPrintf
-                         ( UPNP_CRITICAL, API, __FILE__, __LINE__,
-                           "ServiceType not found \n" );
-                     )
-                    continue;
-            }
-            tmpNode2 = ixmlNodeList_item( tmpNodeList, 0 );
-            if( tmpNode2 == NULL ) {
-                continue;
-            }
-            textNode = ixmlNode_getFirstChild( tmpNode2 );
-            if( textNode == NULL ) {
-                continue;
-            }
-            // servType is of format Servicetype:ServiceVersion
-            tmpStr = ixmlNode_getNodeValue( textNode );
-            if( tmpStr == NULL ) {
-                continue;
-            }
-            strcpy( servType, tmpStr );
-            if( servType == NULL ) {
-                continue;
-            }
-
-            DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                                 "ServiceType = %s\n", servType );
-                 )
-                if( AdFlag ) {
-                if( AdFlag == 1 ) {
-                    ServiceAdvertisement( UDNstr, servType,
-                                          SInfo->DescURL, Exp );
-                } else          // AdFlag == -1
-                {
-                    ServiceShutdown( UDNstr, servType,
-                                     SInfo->DescURL, Exp );
-                }
-
-            } else {
-                switch ( SearchType ) {
-                    case SSDP_ALL:
-                        {
-                            ServiceReply( DestAddr, servType,
-                                          UDNstr, SInfo->DescURL,
-                                          defaultExp );
-                            break;
-                        }
-                    case SSDP_SERVICE:
-                        {
-                            if( ServiceType != NULL ) {
-                                if( !strncasecmp( ServiceType,
-                                                  servType,
-                                                  strlen( ServiceType ) ) )
-                                {
-                                    ServiceReply( DestAddr, servType,
-                                                  UDNstr, SInfo->DescURL,
-                                                  defaultExp );
-                                }
-                            }
-                            break;
-                        }
-                    default:
-                        break;
-                }               // switch(SearchType)               
-
-            }
-        }
-        ixmlNodeList_free( tmpNodeList );
-        tmpNodeList = NULL;
-        ixmlNodeList_free( nodeList );
-        nodeList = NULL;
-    }
-    DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
-                         "Exiting AdvertiseAndReply : \n" );
-         )
-
-        HandleUnlock(  );
-
-    return UPNP_E_SUCCESS;
-
-}  /****************** End of AdvertiseAndReply *********************/
-
-#endif
-#endif
-
-/************************************************************************
-* Function : Make_Socket_NoBlocking									
-*																	
-* Parameters:														
-*	IN int sock: socket 
-*
-* Description:														
-*	This function makes socket non-blocking.
-*
-* Returns: int
-*	0 if successful else -1 
-***************************************************************************/
-int
-Make_Socket_NoBlocking( int sock )
-{
-#ifdef WIN32
-     u_long val=1;
-     return ioctlsocket(sock, FIONBIO, &val);
-#else
-    int val;
-
-    val = fcntl( sock, F_GETFL, 0 );
-    if( fcntl( sock, F_SETFL, val | O_NONBLOCK ) == -1 ) {
-        return -1;
-    }
-#endif
-    return 0;
-}
-
-/************************************************************************
-* Function : unique_service_name								
-*																	
-* Parameters:														
-*	IN char *cmd: Service Name string 
-*	OUT SsdpEvent *Evt: The SSDP event structure partially filled 
-*						by all the function.
-*
-* Description:														
-*	This function fills the fields of the event structure like DeviceType,
-*	Device UDN and Service Type
-*
-* Returns: int
-*	0 if successful else -1 
-***************************************************************************/
-int
-unique_service_name( IN char *cmd,
-                     IN SsdpEvent * Evt )
-{
-    char *TempPtr,
-      TempBuf[COMMAND_LEN],
-     *Ptr,
-     *ptr1,
-     *ptr2,
-     *ptr3;
-    int CommandFound = 0;
-
-    if( ( TempPtr = strstr( cmd, "uuid:schemas" ) ) != NULL ) {
-
-        ptr1 = strstr( cmd, ":device" );
-        if( ptr1 != NULL ) {
-            ptr2 = strstr( ptr1 + 1, ":" );
-        } else {
-            return -1;
-        }
-
-        if( ptr2 != NULL ) {
-            ptr3 = strstr( ptr2 + 1, ":" );
-        } else {
-            return -1;
-        }
-
-        if( ptr3 != NULL ) {
-            sprintf( Evt->UDN, "uuid:%s", ptr3 + 1 );
-        } else {
-            return -1;
-        }
-
-        ptr1 = strstr( cmd, ":" );
-        if( ptr1 != NULL ) {
-            strncpy( TempBuf, ptr1, ptr3 - ptr1 );
-            TempBuf[ptr3 - ptr1] = '\0';
-            sprintf( Evt->DeviceType, "urn%s", TempBuf );
-        } else {
-            return -1;
-        }
-        return 0;
-    }
-
-    if( ( TempPtr = strstr( cmd, "uuid" ) ) != NULL ) {
-        //printf("cmd = %s\n",cmd);
-        if( ( Ptr = strstr( cmd, "::" ) ) != NULL ) {
-            strncpy( Evt->UDN, TempPtr, Ptr - TempPtr );
-            Evt->UDN[Ptr - TempPtr] = '\0';
-        } else {
-            strcpy( Evt->UDN, TempPtr );
-        }
-        CommandFound = 1;
-    }
-
-    if( strstr( cmd, "urn:" ) != NULL
-        && strstr( cmd, ":service:" ) != NULL ) {
-
-        if( ( TempPtr = strstr( cmd, "urn" ) ) != NULL ) {
-            strcpy( Evt->ServiceType, TempPtr );
-            CommandFound = 1;
-        }
-    }
-
-    if( strstr( cmd, "urn:" ) != NULL
-        && strstr( cmd, ":device:" ) != NULL ) {
-        if( ( TempPtr = strstr( cmd, "urn" ) ) != NULL ) {
-            strcpy( Evt->DeviceType, TempPtr );
-            CommandFound = 1;
-        }
-    }
-
-    if( CommandFound == 0 ) {
-
-        return -1;
-    }
-
-    return 0;
-}
-
-/************************************************************************
-* Function : ssdp_request_type1								
-*																	
-* Parameters:														
-*	IN char *cmd: command came in the ssdp request
-*
-* Description:														
-*	This function figures out the type of the SSDP search in the 
-*	in the request.
-*
-* Returns: enum SsdpSearchType
-*	return appropriate search type else returns SSDP_ERROR
-***************************************************************************/
-enum SsdpSearchType
-ssdp_request_type1( IN char *cmd )
-{
-    if( strstr( cmd, ":all" ) != NULL ) {
-        return SSDP_ALL;
-    }
-    if( strstr( cmd, ":rootdevice" ) != NULL ) {
-        return SSDP_ROOTDEVICE;
-    }
-    if( strstr( cmd, "uuid:" ) != NULL ) {
-        return SSDP_DEVICEUDN;
-    }
-    if( ( strstr( cmd, "urn:" ) != NULL )
-        && ( strstr( cmd, ":device:" ) != NULL ) ) {
-        return SSDP_DEVICETYPE;
-    }
-    if( ( strstr( cmd, "urn:" ) != NULL )
-        && ( strstr( cmd, ":service:" ) != NULL ) ) {
-        return SSDP_SERVICE;
-    }
-    return SSDP_SERROR;
-}
-
-/************************************************************************
-* Function : ssdp_request_type								
-*																	
-* Parameters:														
-*	IN char *cmd: command came in the ssdp request
-*	OUT SsdpEvent *Evt: The event structure partially filled by
-*		 this function.
-*
-* Description:														
-*	This function starts filling the SSDP event structure based upon the 
-*	request received. 
-*
-* Returns: int
-*	0 on success; -1 on error
-***************************************************************************/
-int
-ssdp_request_type( IN char *cmd,
-                   OUT SsdpEvent * Evt )
-{
-    // clear event
-    memset( Evt, 0, sizeof( SsdpEvent ) );
-    unique_service_name( cmd, Evt );
-    Evt->ErrCode = NO_ERROR_FOUND;
-
-    if( ( Evt->RequestType = ssdp_request_type1( cmd ) ) == SSDP_SERROR ) {
-        Evt->ErrCode = E_HTTP_SYNTEX;
-        return -1;
-    }
-    return 0;
-}
-
-/************************************************************************
-* Function : free_ssdp_event_handler_data								
-*																	
-* Parameters:														
-*	IN void *the_data: ssdp_thread_data structure. This structure contains
-*			SSDP request message.
-*
-* Description:														
-*	This function frees the ssdp request
-*
-* Returns: VOID
-*	
-***************************************************************************/
-static void
-free_ssdp_event_handler_data( void *the_data )
-{
-    ssdp_thread_data *data = ( ssdp_thread_data * ) the_data;
-
-    if( data != NULL ) {
-        http_message_t *hmsg = &data->parser.msg;
-
-        // free data
-        httpmsg_destroy( hmsg );
-        free( data );
-    }
-}
-
-/************************************************************************
-* Function : valid_ssdp_msg								
-*																	
-* Parameters:														
-*	IN void *the_data: ssdp_thread_data structure. This structure contains
-*			SSDP request message.
-*
-* Description:														
-*	This function do some quick checking of the ssdp msg
-*
-* Returns: xboolean
-*	returns TRUE if msg is valid else FALSE
-***************************************************************************/
-static XINLINE xboolean
-valid_ssdp_msg( IN http_message_t * hmsg )
-{
-    memptr hdr_value;
-
-    // check for valid methods - NOTIFY or M-SEARCH
-    if( hmsg->method != HTTPMETHOD_NOTIFY &&
-        hmsg->method != HTTPMETHOD_MSEARCH
-        && hmsg->request_method != HTTPMETHOD_MSEARCH ) {
-        return FALSE;
-    }
-    if( hmsg->request_method != HTTPMETHOD_MSEARCH ) {
-        // check PATH == *
-        if( hmsg->uri.type != RELATIVE ||
-            strncmp( "*", hmsg->uri.pathquery.buff,
-                     hmsg->uri.pathquery.size ) != 0 ) {
-            return FALSE;
-        }
-        // check HOST header
-        if( ( httpmsg_find_hdr( hmsg, HDR_HOST, &hdr_value ) == NULL ) ||
-            ( memptr_cmp( &hdr_value, "239.255.255.250:1900" ) != 0 )
-             ) {
-            return FALSE;
-        }
-    }
-    return TRUE;                // passed quick check
-}
-
-/************************************************************************
-* Function : start_event_handler								
-*																	
-* Parameters:														
-*	IN void *the_data: ssdp_thread_data structure. This structure contains
-*			SSDP request message.
-*
-* Description:														
-*	This function parses the message and dispatches it to a handler 
-*	which handles the ssdp request msg
-*
-* Returns: int
-*	0 if successful -1 if error
-***************************************************************************/
-static XINLINE int
-start_event_handler( void *Data )
-{
-
-    http_parser_t *parser = NULL;
-    parse_status_t status;
-    ssdp_thread_data *data = ( ssdp_thread_data * ) Data;
-
-    parser = &data->parser;
-
-    status = parser_parse( parser );
-    if( status == PARSE_FAILURE ) {
-        if( parser->msg.method != HTTPMETHOD_NOTIFY ||
-            !parser->valid_ssdp_notify_hack ) {
-            DBGONLY( UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
-                                 "SSDP recvd bad msg code = %d\n",
-                                 status );
-                 )
-                // ignore bad msg, or not enuf mem
-                goto error_handler;
-        }
-        // valid notify msg
-    } else if( status != PARSE_SUCCESS ) {
-        DBGONLY( UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
-                             "SSDP recvd bad msg code = %d\n", status );
-             )
-
-            goto error_handler;
-    }
-    // check msg
-    if( !valid_ssdp_msg( &parser->msg ) ) {
-        goto error_handler;
-    }
-    return 0;                   //////// done; thread will free 'data'
-
-  error_handler:
-    free_ssdp_event_handler_data( data );
-    return -1;
-}
-
-/************************************************************************
-* Function : ssdp_event_handler_thread								
-*																	
-* Parameters:														
-*	IN void *the_data: ssdp_thread_data structure. This structure contains
-*			SSDP request message.
-*
-* Description:														
-*	This function is a thread that handles SSDP requests.
-*
-* Returns: void
-*	
-***************************************************************************/
-static void
-ssdp_event_handler_thread( void *the_data )
-{
-    ssdp_thread_data *data = ( ssdp_thread_data * ) the_data;
-    http_message_t *hmsg = &data->parser.msg;
-
-    if( start_event_handler( the_data ) != 0 ) {
-        return;
-    }
-    // send msg to device or ctrlpt
-    if( ( hmsg->method == HTTPMETHOD_NOTIFY ) ||
-        ( hmsg->request_method == HTTPMETHOD_MSEARCH ) ) {
-
-        CLIENTONLY( ssdp_handle_ctrlpt_msg( hmsg, &data->dest_addr,
-                                            FALSE, NULL );
-             );
-    } else {
-
-        DEVICEONLY( ssdp_handle_device_request( hmsg, &data->dest_addr );
-             );
-    }
-
-    // free data
-    free_ssdp_event_handler_data( data );
-}
-
-/************************************************************************
-* Function : readFromSSDPSocket								
-*																	
-* Parameters:														
-*	IN SOCKET socket: SSDP socket
-*
-* Description:														
-*	This function reads the data from the ssdp socket.
-*
-* Returns: void
-*	
-***************************************************************************/
-void
-readFromSSDPSocket( SOCKET socket )
-{
-    char *requestBuf = NULL;
-    char staticBuf[BUFSIZE];
-    struct sockaddr_in clientAddr;
-    ThreadPoolJob job;
-    ssdp_thread_data *data = NULL;
-    socklen_t socklen = 0;
-    int byteReceived = 0;
-
-    requestBuf = staticBuf;
-
-    //in case memory
-    //can't be allocated, still drain the 
-    //socket using a static buffer
-
-    socklen = sizeof( struct sockaddr_in );
-
-    data = ( ssdp_thread_data * )
-        malloc( sizeof( ssdp_thread_data ) );
-
-    if( data != NULL ) {
-        //initialize parser
-
-#ifdef INCLUDE_CLIENT_APIS
-        if( socket == gSsdpReqSocket ) {
-            parser_response_init( &data->parser, HTTPMETHOD_MSEARCH );
-        } else {
-            parser_request_init( &data->parser );
-        }
-#else
-        parser_request_init( &data->parser );
-#endif
-
-        //set size of parser buffer
-
-        if( membuffer_set_size( &data->parser.msg.msg, BUFSIZE ) == 0 ) {
-            //use this as the buffer for recv
-            requestBuf = data->parser.msg.msg.buf;
-
-        } else {
-            free( data );
-            data = NULL;
-        }
-    }
-    byteReceived = recvfrom( socket, requestBuf,
-                             BUFSIZE - 1, 0,
-                             ( struct sockaddr * )&clientAddr, &socklen );
-
-    if( byteReceived > 0 ) {
-
-        requestBuf[byteReceived] = '\0';
-        DBGONLY( UpnpPrintf( UPNP_INFO, SSDP,
-                             __FILE__, __LINE__,
-                             "Received response !!!  "
-                             "%s From host %s \n",
-                             requestBuf,
-                             inet_ntoa( clientAddr.sin_addr ) );
-             )
-
-            DBGONLY( UpnpPrintf( UPNP_PACKET, SSDP,
-                                 __FILE__, __LINE__,
-                                 "Received multicast packet:"
-                                 "\n %s\n", requestBuf );
-             )
-            //add thread pool job to handle request
-            if( data != NULL ) {
-            data->parser.msg.msg.length += byteReceived;
-            // null-terminate
-            data->parser.msg.msg.buf[byteReceived] = 0;
-            data->dest_addr = clientAddr;
-            TPJobInit( &job, ( start_routine )
-                       ssdp_event_handler_thread, data );
-            TPJobSetFreeFunction( &job, free_ssdp_event_handler_data );
-            TPJobSetPriority( &job, MED_PRIORITY );
-
-            if( ThreadPoolAdd( &gRecvThreadPool, &job, NULL ) != 0 ) {
-                free_ssdp_event_handler_data( data );
-            }
-        }
-
-    } else {
-        free_ssdp_event_handler_data( data );
-    }
-}
-
-/************************************************************************
-* Function : get_ssdp_sockets								
-*																	
-* Parameters:														
-*	OUT MiniServerSockArray *out: Arrays of SSDP sockets
-*
-* Description:														
-*	This function creates the ssdp sockets. It set their option to listen 
-*	for multicast traffic.
-*
-* Returns: int
-*	return UPNP_E_SUCCESS if successful else returns appropriate error
-***************************************************************************/
-int
-get_ssdp_sockets( MiniServerSockArray * out )
-{
-    SOCKET ssdpSock;
-
-    CLIENTONLY( SOCKET ssdpReqSock;
-         )
-    int onOff = 1;
-    u_char ttl = 4;
-    struct ip_mreq ssdpMcastAddr;
-    struct sockaddr_in ssdpAddr;
-    int option = 1;
-    struct in_addr addr;
-
-    CLIENTONLY( if( ( ssdpReqSock = socket( AF_INET, SOCK_DGRAM, 0 ) )
-                    == UPNP_INVALID_SOCKET ) {
-                DBGONLY( UpnpPrintf( UPNP_CRITICAL,
-                                     SSDP, __FILE__, __LINE__,
-                                     "Error in socket operation !!!\n" ); )
-                return UPNP_E_OUTOF_SOCKET;}
-                setsockopt( ssdpReqSock,
-                            IPPROTO_IP,
-                            IP_MULTICAST_TTL, &ttl, sizeof( ttl ) );
-                // just do it, regardless if fails or not.
-                Make_Socket_NoBlocking( ssdpReqSock ); gSsdpReqSocket = ssdpReqSock; )  //CLIENTONLY
-
-        if( ( ssdpSock = socket( AF_INET, SOCK_DGRAM, 0 ) )
-            == UPNP_INVALID_SOCKET ) {
-            DBGONLY( UpnpPrintf( UPNP_CRITICAL,
-                                 SSDP, __FILE__, __LINE__,
-                                 "Error in socket operation !!!\n" );
-                 )
-                CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );
-            CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );
-            return UPNP_E_OUTOF_SOCKET;
-        }
-
-    onOff = 1;
-    if( setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEADDR,
-                    ( char * )&onOff, sizeof( onOff ) ) != 0 ) {
-
-        DBGONLY( UpnpPrintf( UPNP_CRITICAL,
-                             SSDP, __FILE__, __LINE__,
-                             "Error in set reuse addr !!!\n" );
-             )
-            CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );
-        CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );
-        shutdown( ssdpSock, SD_BOTH );
-        UpnpCloseSocket( ssdpSock );
-        return UPNP_E_SOCKET_ERROR;
-    }
-    
-    #if defined(__FreeBSD__) || defined(__NetBSD__)
-    if( setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEPORT,
-                    ( char * )&onOff, sizeof( onOff ) ) != 0 ) {
-
-        DBGONLY( UpnpPrintf( UPNP_CRITICAL,
-                             SSDP, __FILE__, __LINE__,
-                             "Error in set reuse port !!!\n" );
-             )
-            CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );
-        CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );
-        shutdown( ssdpSock, SD_BOTH );
-        UpnpCloseSocket( ssdpSock );
-        return UPNP_E_SOCKET_ERROR;
-    }
-    #endif
-
-    memset( ( void * )&ssdpAddr, 0, sizeof( struct sockaddr_in ) );
-    ssdpAddr.sin_family = AF_INET;
-    //  ssdpAddr.sin_addr.s_addr = inet_addr(LOCAL_HOST);
-    ssdpAddr.sin_addr.s_addr = htonl( INADDR_ANY );
-    ssdpAddr.sin_port = htons( SSDP_PORT );
-    if( bind
-        ( ssdpSock, ( struct sockaddr * )&ssdpAddr,
-          sizeof( ssdpAddr ) ) != 0 ) {
-        DBGONLY( UpnpPrintf
-                 ( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
-                   "Error in binding !!!\n" );
-             )
-            shutdown( ssdpSock, SD_BOTH );
-        UpnpCloseSocket( ssdpSock );
-        CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );
-        CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );
-        return UPNP_E_SOCKET_BIND;
-    }
-
-    memset( ( void * )&ssdpMcastAddr, 0, sizeof( struct ip_mreq ) );
-    ssdpMcastAddr.imr_interface.s_addr = inet_addr( LOCAL_HOST );
-    ssdpMcastAddr.imr_multiaddr.s_addr = inet_addr( SSDP_IP );
-    if( setsockopt( ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
-                    ( char * )&ssdpMcastAddr,
-                    sizeof( struct ip_mreq ) ) != 0 ) {
-        DBGONLY( UpnpPrintf
-                 ( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
-                   "Error in joining" " multicast group !!!\n" );
-             )
-            shutdown( ssdpSock, SD_BOTH );
-        CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );
-        UpnpCloseSocket( ssdpSock );
-        CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );
-        return UPNP_E_SOCKET_ERROR;
-    }
-
-    /* Set multicast interface. */
-    memset( ( void * )&addr, 0, sizeof( struct in_addr ));
-    addr.s_addr = inet_addr(LOCAL_HOST);
-    if (setsockopt(ssdpSock, IPPROTO_IP, IP_MULTICAST_IF,
-                   (char *)&addr, sizeof addr) != 0) {
-        DBGONLY(UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
-                            "Couldn't set multicast interface.\n" ));
-        /* This is probably not a critical error, so let's continue. */
-    }
-
-    // result is not checked becuase it will fail in WinMe and Win9x.
-    setsockopt( ssdpSock, IPPROTO_IP,
-                IP_MULTICAST_TTL, &ttl, sizeof( ttl ) );
-    if( setsockopt( ssdpSock, SOL_SOCKET, SO_BROADCAST,
-                    ( char * )&option, sizeof( option ) ) != 0 ) {
-        DBGONLY( UpnpPrintf( UPNP_CRITICAL,
-                             SSDP, __FILE__, __LINE__,
-                             "Error in setting broadcast !!!\n" );
-             )
-            shutdown( ssdpSock, SD_BOTH );
-        CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );
-        UpnpCloseSocket( ssdpSock );
-        CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );
-        return UPNP_E_NETWORK_ERROR;
-    }
-
-    CLIENTONLY( out->ssdpReqSock = ssdpReqSock;
-         );
-    out->ssdpSock = ssdpSock;
-    return UPNP_E_SUCCESS;
-}
-
-#endif // EXCLUDE_SSDP
diff --git a/tombupnp/upnp/src/urlconfig/urlconfig.c b/tombupnp/upnp/src/urlconfig/urlconfig.c
deleted file mode 100644
index d2f6d6a..0000000
--- a/tombupnp/upnp/src/urlconfig/urlconfig.c
+++ /dev/null
@@ -1,437 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2000-2003 Intel Corporation 
-// All rights reserved. 
-//
-// Redistribution and use in source and binary forms, with or without 
-// modification, are permitted provided that the following conditions are met: 
-//
-// * Redistributions of source code must retain the above copyright notice, 
-// this list of conditions and the following disclaimer. 
-// * Redistributions in binary form must reproduce the above copyright notice, 
-// this list of conditions and the following disclaimer in the documentation 
-// and/or other materials provided with the distribution. 
-// * Neither name of Intel Corporation nor the names of its contributors 
-// may be used to endorse or promote products derived from this software 
-// without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
-// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#include <assert.h>
-#ifndef WIN32
- #ifndef __APPLE__
-    #ifdef __OpenBSD__
-        #include <sys/types.h>
-    #endif
-    #include <sys/socket.h>
-    #include <netinet/in.h>
-    #include <arpa/inet.h>
- #endif
-#else
- #include <winsock2.h>
-#endif
-#include "upnp.h"
-#include "util.h"
-#include "webserver.h"
-#include "uri.h"
-#include "membuffer.h"
-#include "urlconfig.h"
-#include "unixutil.h"
-
-/************************************************************************
-*	Function :	addrToString
-*
-*	Parameters :
-*		IN const struct sockaddr_in* addr ;	socket address object with 
-*					the IP Address and port information
-*		OUT char ipaddr_port[] ;	character array which will hold the 
-*					IP Address  in a string format.
-*
-*	Description : Converts an Internet address to a string and stores it 
-*		a buffer.
-*
-*	Return : void ;
-*
-*	Note :
-************************************************************************/
-static XINLINE void
-addrToString( IN const struct sockaddr_in *addr,
-              OUT char ipaddr_port[] )
-{
-    sprintf( ipaddr_port, "%s:%d", inet_ntoa( addr->sin_addr ),
-             ntohs( addr->sin_port ) );
-}
-
-/************************************************************************
-*	Function :	calc_alias
-*
-*	Parameters :
-*		IN const char* alias ;	String containing the alias
-*		IN const char* rootPath ;	String containing the root path
-*		OUT char** newAlias ;	String pointer to hold the modified new
-*					alias
-*
-*	Description : Determine alias based urlbase's root path.
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Success.
-*		UPNP_E_OUTOF_MEMORY - On Failure to allocate memory for new alias
-*
-*	Note : 'newAlias' should be freed using free()
-************************************************************************/
-static XINLINE int
-calc_alias( IN const char *alias,
-            IN const char *rootPath,
-            OUT char **newAlias )
-{
-    const char *aliasPtr;
-    size_t root_len;
-    char *temp_str;
-    size_t new_alias_len;
-    char *alias_temp;
-
-    assert( rootPath );
-    assert( alias );
-
-    // add / suffix, if missing
-    root_len = strlen( rootPath );
-    if( root_len == 0 || rootPath[root_len - 1] != '/' ) {
-        temp_str = "/";
-    } else {
-        temp_str = "";          // suffix already present
-    }
-
-    // discard / prefix, if present
-    if( alias[0] == '/' ) {
-        aliasPtr = alias + 1;
-    } else {
-        aliasPtr = alias;
-    }
-
-    new_alias_len = root_len + strlen( temp_str ) + strlen( aliasPtr );
-    alias_temp = ( char * )malloc( new_alias_len + 1 );
-    if( alias_temp == NULL ) {
-        return UPNP_E_OUTOF_MEMORY;
-    }
-
-    strcpy( alias_temp, rootPath );
-    strcat( alias_temp, temp_str );
-    strcat( alias_temp, aliasPtr );
-
-    *newAlias = alias_temp;
-    return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-*	Function :	calc_descURL
-*
-*	Parameters :
-*		IN const char* ipPortStr ;	String containing the port number
-*		IN const char* alias ;		String containing the alias
-*		OUT char descURL[LINE_SIZE] ;	buffer to hold the calculated 
-*					description URL
-*
-*	Description : Determines the description URL
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Success
-*		UPNP_E_URL_TOO_BIG - length of the URL is determined to be to
-*		exceeding the limit.
-*
-*	Note :
-************************************************************************/
-static XINLINE int
-calc_descURL( IN const char *ipPortStr,
-              IN const char *alias,
-              OUT char descURL[LINE_SIZE] )
-{
-    size_t len;
-    const char *http_scheme = "http://";
-
-    assert( ipPortStr != NULL && strlen( ipPortStr ) > 0 );
-    assert( alias != NULL && strlen( alias ) > 0 );
-
-    len = strlen( http_scheme ) + strlen( ipPortStr ) + strlen( alias );
-
-    if( len > ( LINE_SIZE - 1 ) ) {
-        return UPNP_E_URL_TOO_BIG;
-    }
-    strcpy( descURL, http_scheme );
-    strcat( descURL, ipPortStr );
-    strcat( descURL, alias );
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                         "desc url: %s\n", descURL );
-         )
-
-        return UPNP_E_SUCCESS;
-}
-
-/************************************************************************
-*	Function :	config_description_doc
-*
-*	Parameters :
-*		INOUT IXML_Document *doc ;IMXL description document to be 
-*					configured	
-*		IN const char* ip_str ;	string containing the IP port number
-*		OUT char** root_path_str ;	buffer to hold the root path
-*					of the configured description document
-*		INOUT IXML_Document *doc :	Description document
-*		IN const char* ip_str :	ipaddress string
-*		OUT char** root_path_str :	root path string
-*
-*	Description : Configure the description document. Add the standard 
-*		format and then add information from the root device and any
-*		child nodes.
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Success
-*		UPNP_E_OUTOF_MEMORY - Default Error
-*		UPNP_E_INVALID_DESC - Invalid child node		
-*		UPNP_E_INVALID_URL - Invalid node information
-*
-*	Note :
-************************************************************************/
-static int
-config_description_doc( INOUT IXML_Document * doc,
-                        IN const char *ip_str,
-                        OUT char **root_path_str )
-{
-    IXML_NodeList *baseList;
-    IXML_Element *element = NULL;
-    IXML_Element *newElement = NULL;
-    IXML_Node *textNode = NULL;
-    IXML_Node *rootNode = NULL;
-    IXML_Node *urlbase_node = NULL;
-    char *urlBaseStr = "URLBase";
-    const DOMString domStr = NULL;
-    uri_type uri;
-    int err_code;
-    int len;
-    membuffer url_str;
-    membuffer root_path;
-
-    membuffer_init( &url_str );
-    membuffer_init( &root_path );
-
-    err_code = UPNP_E_OUTOF_MEMORY; // default error
-
-    baseList = ixmlDocument_getElementsByTagName( doc, urlBaseStr );
-    if( baseList == NULL ) {
-        // urlbase not found -- create new one
-        element = ixmlDocument_createElement( doc, urlBaseStr );
-        if( element == NULL ) {
-            goto error_handler;
-        }
-
-        if( membuffer_append_str( &url_str, "http://" ) != 0 ||
-            membuffer_append_str( &url_str, ip_str ) != 0 ||
-            membuffer_append_str( &url_str, "/" ) != 0 ||
-            membuffer_append_str( &root_path, "/" ) != 0 ) {
-            goto error_handler;
-        }
-
-        rootNode = ixmlNode_getFirstChild( ( IXML_Node * ) doc );
-        if( rootNode == NULL ) {
-            err_code = UPNP_E_INVALID_DESC;
-            goto error_handler;
-        }
-
-        err_code =
-            ixmlNode_appendChild( rootNode, ( IXML_Node * ) element );
-        if( err_code != IXML_SUCCESS ) {
-            goto error_handler;
-        }
-
-        textNode =
-            ixmlDocument_createTextNode( doc, ( char * )url_str.buf );
-        if( textNode == NULL ) {
-            goto error_handler;
-        }
-
-        err_code =
-            ixmlNode_appendChild( ( IXML_Node * ) element, textNode );
-        if( err_code != IXML_SUCCESS ) {
-            goto error_handler;
-        }
-
-    } else {
-        // urlbase found
-        urlbase_node = ixmlNodeList_item( baseList, 0 );
-        assert( urlbase_node != NULL );
-
-        textNode = ixmlNode_getFirstChild( urlbase_node );
-        if( textNode == NULL ) {
-            err_code = UPNP_E_INVALID_DESC;
-            goto error_handler;
-        }
-
-        domStr = ixmlNode_getNodeValue( textNode );
-        if( domStr == NULL ) {
-            err_code = UPNP_E_INVALID_URL;
-            goto error_handler;
-        }
-
-        len = parse_uri( domStr, strlen( domStr ), &uri );
-        if( len < 0 || uri.type != ABSOLUTE ) {
-            err_code = UPNP_E_INVALID_URL;
-            goto error_handler;
-        }
-
-        if( membuffer_assign( &url_str, uri.scheme.buff,
-                              uri.scheme.size ) != 0 ||
-            membuffer_append_str( &url_str, "://" ) != 0 ||
-            membuffer_append_str( &url_str, ip_str ) != 0 ) {
-            goto error_handler;
-        }
-        // add leading '/' if missing from relative path
-        if( ( uri.pathquery.size > 0 && uri.pathquery.buff[0] != '/' ) ||
-            ( uri.pathquery.size == 0 )
-             ) {
-            if( membuffer_append_str( &url_str, "/" ) != 0 ||
-                membuffer_append_str( &root_path, "/" ) != 0 ) {
-                goto error_handler;
-            }
-        }
-
-        if( membuffer_append( &url_str, uri.pathquery.buff,
-                              uri.pathquery.size ) != 0 ||
-            membuffer_append( &root_path, uri.pathquery.buff,
-                              uri.pathquery.size ) != 0 ) {
-            goto error_handler;
-        }
-        // add trailing '/' if missing
-        if( url_str.buf[url_str.length - 1] != '/' ) {
-            if( membuffer_append( &url_str, "/", 1 ) != 0 ) {
-                goto error_handler;
-            }
-        }
-
-        err_code = ixmlNode_setNodeValue( textNode, url_str.buf );
-        if( err_code != IXML_SUCCESS ) {
-            goto error_handler;
-        }
-    }
-
-    *root_path_str = membuffer_detach( &root_path );    // return path
-    err_code = UPNP_E_SUCCESS;
-
-  error_handler:
-    if( err_code != UPNP_E_SUCCESS ) {
-        ixmlElement_free( newElement );
-    }
-
-    ixmlNodeList_free( baseList );
-
-    membuffer_destroy( &root_path );
-    membuffer_destroy( &url_str );
-
-    return err_code;
-}
-
-/************************************************************************
-*	Function :	configure_urlbase
-*
-*	Parameters :
-*		INOUT IXML_Document *doc ;	IXML Description document
-*		IN const struct sockaddr_in* serverAddr ;	socket address object
-*					providing the IP address and port information
-*		IN const char* alias ;	string containing the alias
-*		IN time_t last_modified ;	time when the XML document was 
-*					downloaded
-*		OUT char docURL[LINE_SIZE] ;	buffer to hold the URL of the 
-*					document.
-*		INOUT IXML_Document *doc:dom document whose urlbase is to be modified
-*		IN const struct sockaddr_in* serverAddr : ip address and port of 
-*													the miniserver
-*		IN const char* alias : a name to be used for the temp; e.g.:"foo.xml"
-*		IN time_t last_modified :	time
-*		OUT char docURL[LINE_SIZE] :	document URL
-*
-*	Description : Configure the full URL for the description document.
-*		Create the URL document and add alias, description information.
-*		The doc is added to the web server to be served using the given 
-*		alias.
-*
-*	Return : int ;
-*		UPNP_E_SUCCESS - On Success
-*		UPNP_E_OUTOF_MEMORY - Default Error
-*
-*	Note :
-************************************************************************/
-int
-configure_urlbase( INOUT IXML_Document * doc,
-                   IN const struct sockaddr_in *serverAddr,
-                   IN const char *alias,
-                   IN time_t last_modified,
-                   OUT char docURL[LINE_SIZE] )
-{
-    char *root_path = NULL;
-    char *new_alias = NULL;
-    char *xml_str = NULL;
-    int err_code;
-    char ipaddr_port[LINE_SIZE];
-
-    err_code = UPNP_E_OUTOF_MEMORY; // default error
-
-    // get IP address and port
-    addrToString( serverAddr, ipaddr_port );
-
-    // config url-base in 'doc'
-    err_code = config_description_doc( doc, ipaddr_port, &root_path );
-    if( err_code != UPNP_E_SUCCESS ) {
-        goto error_handler;
-    }
-    // calc alias
-    err_code = calc_alias( alias, root_path, &new_alias );
-    if( err_code != UPNP_E_SUCCESS ) {
-        goto error_handler;
-    }
-    // calc full url for desc doc
-    err_code = calc_descURL( ipaddr_port, new_alias, docURL );
-    if( err_code != UPNP_E_SUCCESS ) {
-        goto error_handler;
-    }
-    // xml doc to str
-    xml_str = ixmlPrintDocument( doc );
-    if( xml_str == NULL ) {
-        goto error_handler;
-    }
-
-    DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                         "desc url: %s\n", docURL );
-         )
-        DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
-                             "doc = %s\n", xml_str );
-         )
-        // store in web server
-        err_code =
-        web_server_set_alias( new_alias, xml_str, strlen( xml_str ),
-                              last_modified );
-
-  error_handler:
-    free( root_path );
-    free( new_alias );
-
-    if( err_code != UPNP_E_SUCCESS ) {
-        ixmlFreeDOMString( xml_str );
-    }
-    return err_code;
-}
diff --git a/tombupnp/upnp/src/uuid/sysdep.c b/tombupnp/upnp/src/uuid/sysdep.c
deleted file mode 100644
index 19e6105..0000000
--- a/tombupnp/upnp/src/uuid/sysdep.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- ** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
- ** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &
- ** Digital Equipment Corporation, Maynard, Mass.
- ** Copyright (c) 1998 Microsoft.
- ** To anyone who acknowledges that this file is provided "AS IS"
- ** without any express or implied warranty: permission to use, copy,
- ** modify, and distribute this file for any purpose is hereby
- ** granted without fee, provided that the above copyright notices and
- ** this notice appears in all source code copies, and that none of
- ** the names of Open Software Foundation, Inc., Hewlett-Packard
- ** Company, or Digital Equipment Corporation be used in advertising
- ** or publicity pertaining to distribution of the software without
- ** specific, written prior permission.  Neither Open Software
- ** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital Equipment
- ** Corporation makes any representations about the suitability of
- ** this software for any purpose.
- */
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#ifndef WIN32
- #include <unistd.h>
-#else
- #include <winsock2.h>
-#endif
-#include <string.h>
-#include <stdio.h>
-#include "sysdep.h"
-
-/*-----------------------------------------------------------------------------*/
-/*
-   system dependent call to get IEEE node ID.
-   This sample implementation generates a random node ID
- */
-void
-get_ieee_node_identifier( uuid_node_t * node )
-{
-    unsigned char seed[16];
-    static int inited = 0;
-    static uuid_node_t saved_node;
-
-    if( !inited ) {
-        get_random_info( seed );
-        seed[0] |= 0x80;
-        memcpy( &saved_node, seed, sizeof( uuid_node_t ) );
-
-        inited = 1;
-    };
-
-    *node = saved_node;
-};
-
-/*-----------------------------------------------------------------------------*/
-/*
-   system dependent call to get the current system time.
-   Returned as 100ns ticks since Oct 15, 1582, but resolution may be
-   less than 100ns.
- */
-
-#ifdef _WINDOWS_
-
-void
-get_system_time( uuid_time_t * uuid_time )
-{
-    ULARGE_INTEGER time;
-
-    GetSystemTimeAsFileTime( ( FILETIME * ) & time );
-
-    /*
-       NT keeps time in FILETIME format which is 100ns ticks since
-       Jan 1, 1601.  UUIDs use time in 100ns ticks since Oct 15, 1582.
-       The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec)
-       + 18 years and 5 leap days.
-     */
-
-    time.QuadPart += ( unsigned __int64 )( 1000 * 1000 * 10 )   // seconds
-        * ( unsigned __int64 )( 60 * 60 * 24 )  // days
-        * ( unsigned __int64 )( 17 + 30 + 31 + 365 * 18 + 5 );  // # of days
-
-    *uuid_time = time.QuadPart;
-
-};
-
-/*-----------------------------------------------------------------------------*/
-void
-get_random_info( unsigned char seed[16] )
-{
-    struct MD5Context c;
-    typedef struct {
-        MEMORYSTATUS m;
-        SYSTEM_INFO s;
-        FILETIME t;
-        LARGE_INTEGER pc;
-        DWORD tc;
-        DWORD l;
-        char hostname[MAX_COMPUTERNAME_LENGTH + 1];
-    } randomness;
-    randomness r;
-
-    MD5Init( &c );
-    /*
-       memory usage stats 
-     */
-    GlobalMemoryStatus( &r.m );
-    /*
-       random system stats 
-     */
-    GetSystemInfo( &r.s );
-    /*
-       100ns resolution (nominally) time of day 
-     */
-    GetSystemTimeAsFileTime( &r.t );
-    /*
-       high resolution performance counter 
-     */
-    QueryPerformanceCounter( &r.pc );
-    /*
-       milliseconds since last boot 
-     */
-    r.tc = GetTickCount(  );
-    r.l = MAX_COMPUTERNAME_LENGTH + 1;
-
-    GetComputerName( r.hostname, &r.l );
-    MD5Update( &c, &r, sizeof( randomness ) );
-    MD5Final( seed, &c );
-};
-#else
-
-/*-----------------------------------------------------------------------------*/
-void
-get_system_time( uuid_time_t * uuid_time )
-{
-    struct timeval tp;
-
-    gettimeofday( &tp, ( struct timezone * )0 );
-
-    /*
-       Offset between UUID formatted times and Unix formatted times.
-       UUID UTC base time is October 15, 1582.
-       Unix base time is January 1, 1970.
-     */
-    *uuid_time = ( tp.tv_sec * 10000000 ) + ( tp.tv_usec * 10 ) +
-        I64( 0x01B21DD213814000 );
-};
-
-/*-----------------------------------------------------------------------------*/
-void
-get_random_info( unsigned char seed[16] )
-{
-    struct MD5Context c;
-    typedef struct {
-//        struct sysinfo s;
-        struct timeval t;
-        char hostname[257];
-    } randomness;
-    randomness r;
-
-    MD5Init( &c );
-
-    gettimeofday( &r.t, ( struct timezone * )0 );
-    gethostname( r.hostname, 256 );
-    MD5Update( &c, (unsigned char *)&r, sizeof( randomness ) );
-    MD5Final( seed, &c );
-};
-
-#endif
diff --git a/tombupnp/upnp/src/uuid/upnp_md5.c b/tombupnp/upnp/src/uuid/upnp_md5.c
deleted file mode 100644
index 7b23429..0000000
--- a/tombupnp/upnp/src/uuid/upnp_md5.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest.  This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
- * will fill a supplied 16-byte array with the digest.
- *
- * Changed so as no longer to depend on Colin Plumb's `usual.h' header
- * definitions; now uses stuff from dpkg's config.h.
- *  - Ian Jackson <ian at chiark.greenend.org.uk>.
- * Still in the public domain.
- */
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-
-#include <string.h>            /* for memcpy() */
-#include <sys/types.h>         /* for stupid systems */
-#include <netinet/in.h>                /* for ntohl() */
-
-#include "upnp_md5.h"
-
-#ifdef WORDS_BIGENDIAN
-void
-byteSwap(UWORD32 *buf, unsigned words)
-{
-       md5byte *p = (md5byte *)buf;
-
-       do {
-               *buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 |
-                       ((unsigned)p[1] << 8 | p[0]);
-               p += 4;
-       } while (--words);
-}
-#else
-#define byteSwap(buf,words)
-#endif
-
-/*
- * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
- * initialization constants.
- */
-void
-MD5Init(struct MD5Context *ctx)
-{
-       ctx->buf[0] = 0x67452301;
-       ctx->buf[1] = 0xefcdab89;
-       ctx->buf[2] = 0x98badcfe;
-       ctx->buf[3] = 0x10325476;
-
-       ctx->bytes[0] = 0;
-       ctx->bytes[1] = 0;
-}
-
-/*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
-void
-MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len)
-{
-       UWORD32 t;
-
-       /* Update byte count */
-
-       t = ctx->bytes[0];
-       if ((ctx->bytes[0] = t + len) < t)
-               ctx->bytes[1]++;        /* Carry from low to high */
-
-       t = 64 - (t & 0x3f);    /* Space available in ctx->in (at least 1) */
-       if (t > len) {
-               memcpy((md5byte *)ctx->in + 64 - t, buf, len);
-               return;
-       }
-       /* First chunk is an odd size */
-       memcpy((md5byte *)ctx->in + 64 - t, buf, t);
-       byteSwap(ctx->in, 16);
-       MD5Transform(ctx->buf, ctx->in);
-       buf += t;
-       len -= t;
-
-       /* Process data in 64-byte chunks */
-       while (len >= 64) {
-               memcpy(ctx->in, buf, 64);
-               byteSwap(ctx->in, 16);
-               MD5Transform(ctx->buf, ctx->in);
-               buf += 64;
-               len -= 64;
-       }
-
-       /* Handle any remaining bytes of data. */
-       memcpy(ctx->in, buf, len);
-}
-
-/*
- * Final wrapup - pad to 64-byte boundary with the bit pattern
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
-void
-MD5Final(md5byte digest[16], struct MD5Context *ctx)
-{
-       int count = ctx->bytes[0] & 0x3f;       /* Number of bytes in ctx->in */
-       md5byte *p = (md5byte *)ctx->in + count;
-
-       /* Set the first char of padding to 0x80.  There is always room. */
-       *p++ = 0x80;
-
-       /* Bytes of padding needed to make 56 bytes (-8..55) */
-       count = 56 - 1 - count;
-
-       if (count < 0) {        /* Padding forces an extra block */
-               memset(p, 0, count + 8);
-               byteSwap(ctx->in, 16);
-               MD5Transform(ctx->buf, ctx->in);
-               p = (md5byte *)ctx->in;
-               count = 56;
-       }
-       memset(p, 0, count);
-       byteSwap(ctx->in, 14);
-
-       /* Append length in bits and transform */
-       ctx->in[14] = ctx->bytes[0] << 3;
-       ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
-       MD5Transform(ctx->buf, ctx->in);
-
-       byteSwap(ctx->buf, 4);
-       memcpy(digest, ctx->buf, 16);
-       memset(ctx, 0, sizeof(struct MD5Context));    /* In case it's sensitive */
-}
-
-#ifndef ASM_MD5
-
-/* The four core functions - F1 is optimized somewhat */
-
-/* #define F1(x, y, z) (x & y | ~x & z) */
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define MD5STEP(f,w,x,y,z,in,s) \
-        (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data.  MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-void
-MD5Transform(UWORD32 buf[4], UWORD32 const in[16])
-{
-       register UWORD32 a, b, c, d;
-
-       a = buf[0];
-       b = buf[1];
-       c = buf[2];
-       d = buf[3];
-
-       MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
-       MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
-       MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
-       MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
-       MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
-       MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
-       MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
-       MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
-       MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
-       MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
-       MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
-       MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
-       MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
-       MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
-       MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
-       MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
-       MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
-       MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
-       MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
-       MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
-       MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
-       MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
-       MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
-       MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
-       MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
-       MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
-       MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
-       MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
-       MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
-       MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
-       MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
-       MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
-       MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
-       MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
-       MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
-       MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
-       MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
-       MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
-       MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
-       MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
-       MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
-       MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
-       MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
-       MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
-       MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
-       MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
-       MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
-       MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-
-       MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
-       MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
-       MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
-       MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
-       MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
-       MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
-       MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
-       MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
-       MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
-       MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
-       MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
-       MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
-       MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
-       MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
-       MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
-       MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
-
-       buf[0] += a;
-       buf[1] += b;
-       buf[2] += c;
-       buf[3] += d;
-}
-
-#endif
diff --git a/tombupnp/upnp/src/uuid/upnp_uuid.c b/tombupnp/upnp/src/uuid/upnp_uuid.c
deleted file mode 100644
index 2368dc0..0000000
--- a/tombupnp/upnp/src/uuid/upnp_uuid.c
+++ /dev/null
@@ -1,387 +0,0 @@
-  /*
-   ** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
-   ** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &
-   ** Digital Equipment Corporation, Maynard, Mass.
-   ** Copyright (c) 1998 Microsoft.
-   ** To anyone who acknowledges that this file is provided "AS IS"
-   ** without any express or implied warranty: permission to use, copy,
-   ** modify, and distribute this file for any purpose is hereby
-   ** granted without fee, provided that the above copyright notices and
-   ** this notice appears in all source code copies, and that none of
-   ** the names of Open Software Foundation, Inc., Hewlett-Packard
-   ** Company, or Digital Equipment Corporation be used in advertising
-   ** or publicity pertaining to distribution of the software without
-   ** specific, written prior permission.  Neither Open Software
-   ** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital Equipment
-   ** Corporation makes any representations about the suitability of
-   ** this software for any purpose.
-   */
-#ifdef HAVE_CONFIG_H
-    #include "autoconfig.h"
-#endif
-
-
-#include "config.h"
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <netinet/in.h>
-#include "sysdep.h"
-#include "upnp_uuid.h"
-
-/*
-   various forward declarations 
- */
-static int read_state( unsigned16 * clockseq,
-                       uuid_time_t * timestamp,
-                       uuid_node_t * node );
-static void write_state( unsigned16 clockseq,
-                         uuid_time_t timestamp,
-                         uuid_node_t node );
-static void format_uuid_v1( uuid_upnp * uid,
-                            unsigned16 clockseq,
-                            uuid_time_t timestamp,
-                            uuid_node_t node );
-static void format_uuid_v3( uuid_upnp * uid,
-                            unsigned char hash[16] );
-static void get_current_time( uuid_time_t * timestamp );
-static unsigned16 true_random( void );
-
-/*-----------------------------------------------------------------------------*/
-/*
-   uuid_create -- generator a UUID 
- */
-int
-uuid_create( uuid_upnp * uid )
-{
-    uuid_time_t timestamp,
-      last_time;
-    unsigned16 clockseq;
-    uuid_node_t node;
-    uuid_node_t last_node;
-    int f;
-
-    /*
-       acquire system wide lock so we're alone 
-     */
-    UUIDLock(  );
-
-    /*
-       get current time 
-     */
-    get_current_time( &timestamp );
-
-    /*
-       get node ID 
-     */
-    get_ieee_node_identifier( &node );
-
-    /*
-       get saved state from NV storage 
-     */
-    f = read_state( &clockseq, &last_time, &last_node );
-
-    /*
-       if no NV state, or if clock went backwards, or node ID changed
-       (e.g., net card swap) change clockseq 
-     */
-    if( !f || memcmp( &node, &last_node, sizeof( uuid_node_t ) ) )
-        clockseq = true_random(  );
-    else if( timestamp < last_time )
-        clockseq++;
-
-    /*
-       stuff fields into the UUID 
-     */
-    format_uuid_v1( uid, clockseq, timestamp, node );
-
-    /*
-       save the state for next time 
-     */
-    write_state( clockseq, timestamp, node );
-
-    UUIDUnlock(  );
-    return ( 1 );
-};
-
-/*-----------------------------------------------------------------------------*/
-void
-uuid_unpack( uuid_upnp * u,
-             char *out )
-{
-
-    sprintf( out,
-             "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
-             ( unsigned int )u->time_low, u->time_mid,
-             u->time_hi_and_version, u->clock_seq_hi_and_reserved,
-             u->clock_seq_low, u->node[0], u->node[1], u->node[2],
-             u->node[3], u->node[4], u->node[5] );
-
-    *( out + 36 ) = '\0';
-
-};
-
-/*-----------------------------------------------------------------------------*/
-/*
-   format_uuid_v1 -- make a UUID from the timestamp, clockseq,
-   and node ID 
- */
-void
-format_uuid_v1( uuid_upnp * uid,
-                unsigned16 clock_seq,
-                uuid_time_t timestamp,
-                uuid_node_t node )
-{
-    /*
-       Construct a version 1 uuid with the information we've gathered
-       * plus a few constants. 
-     */
-    uid->time_low = ( unsigned long )( timestamp & 0xFFFFFFFF );
-    uid->time_mid = ( unsigned short )( ( timestamp >> 32 ) & 0xFFFF );
-    uid->time_hi_and_version = ( unsigned short )( ( timestamp >> 48 ) &
-                                                   0x0FFF );
-    uid->time_hi_and_version |= ( 1 << 12 );
-    uid->clock_seq_low = clock_seq & 0xFF;
-    uid->clock_seq_hi_and_reserved = ( clock_seq & 0x3F00 ) >> 8;
-    uid->clock_seq_hi_and_reserved |= 0x80;
-    memcpy( &uid->node, &node, sizeof uid->node );
-};
-
-/*-----------------------------------------------------------------------------*/
-/*
-   data type for UUID generator persistent state 
- */
-typedef struct {
-    uuid_time_t ts;             /* saved timestamp */
-    uuid_node_t node;           /* saved node ID */
-    unsigned16 cs;              /* saved clock sequence */
-} uuid_state;
-
-static uuid_state st;
-static int stateInited = 0;
-
-/*-----------------------------------------------------------------------------*/
-/*
-   read_state -- read UUID generator state from non-volatile store 
- */
-int
-read_state( unsigned16 * clockseq,
-            uuid_time_t * timestamp,
-            uuid_node_t * node )
-{
-
-    if( !stateInited ) {
-        return 0;
-    };
-
-    *clockseq = st.cs;
-    *timestamp = st.ts;
-    *node = st.node;
-    return 1;
-};
-
-/*-----------------------------------------------------------------------------*/
-/*
-   write_state -- save UUID generator state back to non-volatile
-   storage 
- */
-void
-write_state( unsigned16 clockseq,
-             uuid_time_t timestamp,
-             uuid_node_t node )
-{
-    static uuid_time_t next_save;
-
-    if( !stateInited ) {
-        next_save = timestamp;
-        stateInited = 1;
-    };
-
-    /*
-       always save state to volatile shared state 
-     */
-    st.cs = clockseq;
-    st.ts = timestamp;
-    st.node = node;
-    if( timestamp >= next_save ) {
-        /*
-           schedule next save for 10 seconds from now 
-         */
-        next_save = timestamp + ( 10 * 10 * 1000 * 1000 );
-    };
-};
-
-/*-----------------------------------------------------------------------------*/
-/*
-   get-current_time -- get time as 60 bit 100ns ticks since whenever.
-   Compensate for the fact that real clock resolution is
-   less than 100ns. 
- */
-void
-get_current_time( uuid_time_t * timestamp )
-{
-    uuid_time_t time_now;
-    static uuid_time_t time_last;
-    static unsigned16 uuids_this_tick;
-    static int inited = 0;
-
-    if( !inited ) {
-        get_system_time( &time_now );
-        uuids_this_tick = UUIDS_PER_TICK;
-        inited = 1;
-    };
-
-    while( 1 ) {
-        get_system_time( &time_now );
-
-        /*
-           if clock reading changed since last UUID generated... 
-         */
-        if( time_last != time_now ) {
-            /*
-               reset count of uuids gen'd with this clock reading 
-             */
-            uuids_this_tick = 0;
-            break;
-        };
-
-        if( uuids_this_tick < UUIDS_PER_TICK ) {
-            uuids_this_tick++;
-            break;
-        };
-        /*
-           going too fast for our clock; spin 
-         */
-    };
-
-    /*
-       add the count of uuids to low order bits of the clock reading 
-     */
-    *timestamp = time_now + uuids_this_tick;
-    time_last = *timestamp;
-};
-
-/*-----------------------------------------------------------------------------*/
-/*
-   true_random -- generate a crypto-quality random number.
-   This sample doesn't do that. 
- */
-static unsigned16
-true_random( void )
-{
-    static int inited = 0;
-    uuid_time_t time_now;
-
-    if( !inited ) {
-        get_system_time( &time_now );
-        time_now = time_now / UUIDS_PER_TICK;
-        srand( ( unsigned int )( ( ( time_now >> 32 ) ^ time_now ) &
-                                 0xffffffff ) );
-        inited = 1;
-    };
-
-    return ( rand(  ) );
-}
-
-/*-----------------------------------------------------------------------------*/
-/*
-   uuid_create_from_name -- create a UUID using a "name" from a "name space" 
- */
-void
-uuid_create_from_name( uuid_upnp * uid, /* resulting UUID */
-
-                       uuid_upnp nsid,  /* UUID to serve as context, so identical
-                                           names from different name spaces generate
-                                           different UUIDs */
-
-                       void *name,  /* the name from which to generate a UUID */
-
-                       int namelen  /* the length of the name */
-     )
-{
-    struct MD5Context c;
-    unsigned char hash[16];
-    uuid_upnp net_nsid;         /* context UUID in network byte order */
-
-    /*
-       put name space ID in network byte order so it hashes the same
-       no matter what endian machine we're on 
-     */
-    net_nsid = nsid;
-    net_nsid.time_low = htonl( net_nsid.time_low );
-    net_nsid.time_mid = htons( net_nsid.time_mid );
-    net_nsid.time_hi_and_version = htons( net_nsid.time_hi_and_version );
-
-    MD5Init( &c );
-    MD5Update( &c, (unsigned char *)&net_nsid, sizeof( uuid_upnp ) );
-    MD5Update( &c, name, namelen );
-    MD5Final( hash, &c );
-
-    /*
-       the hash is in network byte order at this point 
-     */
-    format_uuid_v3( uid, hash );
-};
-
-/*-----------------------------------------------------------------------------*/
-/*
-   format_uuid_v3 -- make a UUID from a (pseudo)random 128 bit number
- */
-void
-format_uuid_v3( uuid_upnp * uid,
-                unsigned char hash[16] )
-{
-    /*
-       Construct a version 3 uuid with the (pseudo-)random number
-       * plus a few constants. 
-     */
-
-    memcpy( uid, hash, sizeof( uuid_upnp ) );
-
-    /*
-       convert UUID to local byte order 
-     */
-    uid->time_low = ntohl( uid->time_low );
-    uid->time_mid = ntohs( uid->time_mid );
-    uid->time_hi_and_version = ntohs( uid->time_hi_and_version );
-
-    /*
-       put in the variant and version bits 
-     */
-    uid->time_hi_and_version &= 0x0FFF;
-    uid->time_hi_and_version |= ( 3 << 12 );
-    uid->clock_seq_hi_and_reserved &= 0x3F;
-    uid->clock_seq_hi_and_reserved |= 0x80;
-};
-
-/*-----------------------------------------------------------------------------*/
-/*
-   uuid_compare --  Compare two UUID's "lexically" and return
-   -1   u1 is lexically before u2
-   0   u1 is equal to u2
-   1   u1 is lexically after u2
-
-   Note:   lexical ordering is not temporal ordering!
- */
-int
-uuid_compare( uuid_upnp * u1,
-              uuid_upnp * u2 )
-{
-    int i;
-
-#define CHECK(f1, f2) if (f1 != f2) return f1 < f2 ? -1 : 1;
-    CHECK( u1->time_low, u2->time_low );
-    CHECK( u1->time_mid, u2->time_mid );
-    CHECK( u1->time_hi_and_version, u2->time_hi_and_version );
-    CHECK( u1->clock_seq_hi_and_reserved, u2->clock_seq_hi_and_reserved );
-    CHECK( u1->clock_seq_low, u2->clock_seq_low )
-        for( i = 0; i < 6; i++ ) {
-        if( u1->node[i] < u2->node[i] )
-            return -1;
-        if( u1->node[i] > u2->node[i] )
-            return 1;
-    }
-
-    return 0;
-};
diff --git a/tombupnp/upnp/src/win_dll.c b/tombupnp/upnp/src/win_dll.c
deleted file mode 100644
index 4adacaf..0000000
--- a/tombupnp/upnp/src/win_dll.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// upnpLib.cpp : Defines the entry point for the DLL application.
-//
-
-#ifdef WIN32
-
-#include <windows.h>
-BOOL APIENTRY DllMain( HANDLE hModule, 
-                       DWORD  ul_reason_for_call, 
-                       LPVOID lpReserved
-					 )
-{
-	if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
-	}
-    return TRUE;
-}
-
-#endif
diff --git a/web/Makefile.am b/web/Makefile.am
deleted file mode 100644
index bde1476..0000000
--- a/web/Makefile.am
+++ /dev/null
@@ -1,101 +0,0 @@
-_DIST_FILES_IMAGES = \
-./icons/nanotree/images/minus.png \
-./icons/nanotree/images/plus.png \
-./icons/nanotree/images/minus_last_no_root.png \
-./icons/nanotree/images/minus_last.png \
-./icons/nanotree/images/white.png \
-./icons/nanotree/images/plus_no_root.png \
-./icons/nanotree/images/line.png \
-./icons/nanotree/images/plus_last_no_root.png \
-./icons/nanotree/images/minus_no_root.png \
-./icons/nanotree/images/t_no_root.png \
-./icons/nanotree/images/t.png \
-./icons/nanotree/images/plus_last.png \
-./icons/nanotree/images/lastnode.png \
-./icons/nanotree/images/folder_closed.png \
-./icons/nanotree/images/folder_open.png \
-./icons/nanotree/images/autoscan_timed_folder_closed.png \
-./icons/nanotree/images/autoscan_timed_folder_open.png \
-./icons/nanotree/images/autoscan_timed_config_folder_open.png \
-./icons/nanotree/images/autoscan_timed_config_folder_closed.png \
-./icons/nanotree/images/autoscan_inotify_folder_closed.png \
-./icons/nanotree/images/autoscan_inotify_folder_open.png \
-./icons/nanotree/images/autoscan_inotify_config_folder_open.png \
-./icons/nanotree/images/autoscan_inotify_config_folder_closed.png
-
-_DIST_FILES_ICONS = \
-./icons/document-new.png \
-./icons/folder_new.png \
-./icons/go-first.png \
-./icons/go-last.png \
-./icons/go-next.png \
-./icons/go-previous.png \
-./icons/remove_all.png \
-./icons/remove_this.png \
-./icons/stock-add.png \
-./icons/add_as_autoscan.png \
-./icons/remove_autoscan.png \
-./icons/stock_edit.png \
-./icons/stock_exit.png \
-./icons/autoscan_timed_config_folder_open.png \
-./icons/autoscan_timed_folder_open.png \
-./icons/autoscan_inotify_config_folder_open.png \
-./icons/autoscan_inotify_folder_open.png \
-./icons/folder_open.png \
-./icons/status.png \
-./icons/status_loading.png \
-./icons/status_updates_pending.png \
-./icons/mediatomb.png \
-./icons/film.png \
-./icons/mt-icon120.jpg \
-./icons/mt-icon120.png \
-./icons/mt-icon120.bmp \
-./icons/mt-icon48.jpg \
-./icons/mt-icon48.png \
-./icons/mt-icon48.bmp \
-./icons/mt-icon32.jpg \
-./icons/mt-icon32.png \
-./icons/mt-icon32.bmp \
-./icons/blank.png \
-./icons/blank.gif
-
-_DIST_FILES_JS = \
-./js/autoscan.js \
-./js/md5.js \
-./js/prototype.js \
-./js/auth.js \
-./js/tasks.js \
-./js/tree.js \
-./js/tools.js \
-./js/items.js \
-./js/icons.js \
-./js/nanotree.js \
-./js/iepngfix.htc
-
-_DIST_FILES_WEB = \
-./disabled.html \
-./std_treelook.css \
-./index.html \
-./left.html \
-./right.html \
-./top.html \
-./topleft.html \
-./topright.html \
-./main.css \
-./cm.xml \
-./cds.xml \
-./favicon.ico \
-./mr_reg.xml
-
-imagesdir = $(pkgdatadir)/web/icons/nanotree/images
-dist_images_DATA = $(_DIST_FILES_IMAGES)
-
-iconsdir = $(pkgdatadir)/web/icons
-dist_icons_DATA = $(_DIST_FILES_ICONS)
-    
-jsdir = $(pkgdatadir)/web/js
-dist_js_DATA = $(_DIST_FILES_JS)
-
-webdir = $(pkgdatadir)/web
-dist_web_DATA = $(_DIST_FILES_WEB)
-
diff --git a/web/disabled.html b/web/disabled.html
index 9b3f01e..8baf83f 100644
--- a/web/disabled.html
+++ b/web/disabled.html
@@ -1,4 +1,6 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
+        "http://www.w3.org/TR/html4/frameset.dtd">
+<!-- This file is part of Gerbera, based on MediaTomb. GPLv2 Applies, see LICENCE.md -->
 <html>
     <head>
         <title>MediaTomb</title>
diff --git a/web/favicon.ico b/web/favicon.ico
index 565bd3b..6fbb97c 100644
Binary files a/web/favicon.ico and b/web/favicon.ico differ
diff --git a/web/icons/film.png b/web/icons/film.png
deleted file mode 100644
index 126ba38..0000000
Binary files a/web/icons/film.png and /dev/null differ
diff --git a/web/icons/mediatomb.png b/web/icons/mediatomb.png
index 7cefa30..81bc873 100644
Binary files a/web/icons/mediatomb.png and b/web/icons/mediatomb.png differ
diff --git a/web/icons/mt-icon120.bmp b/web/icons/mt-icon120.bmp
index 3d45f2c..d495bf4 100644
Binary files a/web/icons/mt-icon120.bmp and b/web/icons/mt-icon120.bmp differ
diff --git a/web/icons/mt-icon120.jpg b/web/icons/mt-icon120.jpg
index 940fa7b..b0103f1 100644
Binary files a/web/icons/mt-icon120.jpg and b/web/icons/mt-icon120.jpg differ
diff --git a/web/icons/mt-icon120.png b/web/icons/mt-icon120.png
index d8f7cd4..8007752 100644
Binary files a/web/icons/mt-icon120.png and b/web/icons/mt-icon120.png differ
diff --git a/web/icons/mt-icon32.bmp b/web/icons/mt-icon32.bmp
index 54b016c..1429da8 100644
Binary files a/web/icons/mt-icon32.bmp and b/web/icons/mt-icon32.bmp differ
diff --git a/web/icons/mt-icon32.jpg b/web/icons/mt-icon32.jpg
index 4326f26..1a5e107 100644
Binary files a/web/icons/mt-icon32.jpg and b/web/icons/mt-icon32.jpg differ
diff --git a/web/icons/mt-icon32.png b/web/icons/mt-icon32.png
index 56d9804..bacf8fb 100644
Binary files a/web/icons/mt-icon32.png and b/web/icons/mt-icon32.png differ
diff --git a/web/icons/mt-icon48.bmp b/web/icons/mt-icon48.bmp
index 8e0be95..a63f1f2 100644
Binary files a/web/icons/mt-icon48.bmp and b/web/icons/mt-icon48.bmp differ
diff --git a/web/icons/mt-icon48.jpg b/web/icons/mt-icon48.jpg
index 4990e15..e63380d 100644
Binary files a/web/icons/mt-icon48.jpg and b/web/icons/mt-icon48.jpg differ
diff --git a/web/icons/mt-icon48.png b/web/icons/mt-icon48.png
index 809a3a4..cde97be 100644
Binary files a/web/icons/mt-icon48.png and b/web/icons/mt-icon48.png differ
diff --git a/web/icons/status.png b/web/icons/status.png
index f549eb2..8b1ae71 100644
Binary files a/web/icons/status.png and b/web/icons/status.png differ
diff --git a/web/index.html b/web/index.html
index 974a411..ecb0b7f 100644
--- a/web/index.html
+++ b/web/index.html
@@ -1,37 +1,10 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
-     "http://www.w3.org/TR/html4/frameset.dtd">
-<!--*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    index.html - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
--->
+        "http://www.w3.org/TR/html4/frameset.dtd">
+<!-- This file is part of Gerbera, based on MediaTomb. GPLv2 Applies, see LICENCE.md -->
   <html>
     <head>
         <meta http-equiv="content-type" content="text/html; charset=UTF-8">
-        <title>MEDIATOMB</title>
+        <title>Gerbera</title>
         <link rel="shortcut icon" href="favicon.ico" type="image/ico">
         <script type="text/javascript" language="JavaScript" src="js/tools.js"></script>
         <script type="text/javascript" language="JavaScript" src="js/icons.js"></script>
@@ -58,7 +31,7 @@
                 if (msieWarn != "ok")
                 {
                     setCookie("MSIEwarn", "ok");
-                    alert('MediaTomb UI is very limited with Internet Explorer and some elements will be displayed incorrectly! Please see the section "Internet Explorer" in the README file.');
+                    alert('Gerbera UI is very limited with Internet Explorer and some elements will be displayed incorrectly! Please see the section "Internet Explorer" in the README file.');
                 }
             }
             function init() {
@@ -129,7 +102,7 @@
                     
                     onException: function()
                     {
-                        alert("MediaTomb cannot be reached! Please check if the server is still running.");
+                        alert("Gerbera cannot be reached! Please check if the server is still running.");
                         clearPollInterval();
                         if(Ajax.activeRequestCount < 0)
                             Ajax.activeRequestCount = 0;
@@ -183,14 +156,14 @@
         </script>
 
     </head>
-    <frameset frameborder="1" border="2" framespacing="2" bordercolor="#FFFFFF" rows="112px,*" onload="init();">
+    <frameset frameborder="1" border="2" framespacing="2" bordercolor="#000000" rows="112px,*" onload="init();">
         <frame src="top.html" name="topF" frameborder="0" noresize>
-        <frameset cols="30%,*" frameborder="1" border="2" framespacing="2" bordercolor="#FFFFFF">
-            <frameset rows="40px,*"  frameborder="1" border="2" framespacing="2" bordercolor="#FFFFFF">
+        <frameset cols="30%,*" frameborder="1" border="2" framespacing="2" bordercolor="#EEE">
+            <frameset rows="40px,*"  frameborder="1" border="2" framespacing="2" bordercolor="#EEE">
                 <frame src="topleft.html" name="topleftF" frameborder="0" noresize>
                 <frame src="left.html" name="leftF" frameborder="0" noresize>
             </frameset>
-            <frameset rows="40px,*" frameborder="1" border="2" framespacing="2" bordercolor="#FFFFFF">
+            <frameset rows="40px,*" frameborder="1" border="2" framespacing="2" bordercolor="#EEE">
                 <frame src="topright.html" name="toprightF" frameborder="0" noresize>
                 <frame src="right.html" name="rightF" frameborder="0" noresize>
             </frameset>
diff --git a/web/left.html b/web/left.html
index 38e5235..b895bf7 100644
--- a/web/left.html
+++ b/web/left.html
@@ -1,40 +1,13 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-     "http://www.w3.org/TR/html4/loose.dtd">
-<!--*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    left.html - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
--->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
+        "http://www.w3.org/TR/html4/frameset.dtd">
+<!-- This file is part of Gerbera, based on MediaTomb. GPLv2 Applies, see LICENCE.md -->
 <html>
-    <head>
-        <title>M E D I A T O M B</title>
-        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
-        <link rel="StyleSheet" href="main.css" type="text/css">
-        <link rel="StyleSheet" href="std_treelook.css" type="text/css">
-    </head>
+<head>
+    <title>M E D I A T O M B</title>
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+    <link rel="StyleSheet" href="main.css" type="text/css">
+    <link rel="StyleSheet" href="std_treelook.css" type="text/css">
+</head>
 <body id="body">
     <div id="treeDiv" style="display:none;"></div>
     <div id="leftLoginDiv" style="margin-top:55px; margin-right:10px; display:none;" align="right">
diff --git a/web/main.css b/web/main.css
index 9dc6fe1..2058102 100644
--- a/web/main.css
+++ b/web/main.css
@@ -1,36 +1,37 @@
 /*MT*
-    
+
     MediaTomb - http://www.mediatomb.cc/
-    
+
     main.css - this file is part of MediaTomb.
-    
+
     Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
                        Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
+
     Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
                             Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
                             Leonhard Wimmer <leo at mediatomb.cc>
-    
+
     MediaTomb is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2
     as published by the Free Software Foundation.
-    
+
     MediaTomb is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-    
+
     You should have received a copy of the GNU General Public License
     version 2 along with MediaTomb; if not, write to the Free Software
     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
+
     $Id$
 */
 body
 {
-    background-color:#dddddd;
+    background-color:#EFEFEF;
     font-family: "Helvetica", "Arial", "MS Sans Serif", sans-serif;
     font-size: 13px;
+    color: #444;
     margin:0;
     padding:0;
 }
@@ -54,7 +55,7 @@ input.button
 
 a
 {
-    color:#000000;
+    color:#444;
     text-decoration:none;
 }
 
@@ -72,8 +73,8 @@ div#db_fs_selector a
 div#db_fs_selector a.selected
 {
     /* text-decoration:underline; */
-    background-color: #222222;
-	color: #ffffff;
+    background-color: #ff8000;
+	color: #444;
     
 }
 
@@ -91,12 +92,12 @@ table.contTable
 
 tr.itemRowA
 {
-    background-color:#cccccc;
+    background-color:#EFEFEF;
 }
 
 tr.itemRowB
 {
-    background-color:#aaaaaa;
+    background-color:#fff;
 }
 
 td.itemEntry
@@ -114,14 +115,11 @@ td.itemButtons
     text-align:right;
 }
 
-tr.itemRowA:hover, tr.itemRowB:hover
-{
-    background-color:#888888;
-}
-
+tr.itemRowA:hover, tr.itemRowB:hover,
 tr.itemRowA div.itemLeft:hover
 {
-    background-color:#888888;
+    background-color:#ff8000;
+    color: #FFF;
 }
 
 tr.itemRowA div.itemLeft
diff --git a/web/right.html b/web/right.html
index c42b34e..75bb424 100644
--- a/web/right.html
+++ b/web/right.html
@@ -1,33 +1,6 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-     "http://www.w3.org/TR/html4/loose.dtd">
-<!--*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    right.html - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
--->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
+        "http://www.w3.org/TR/html4/frameset.dtd">
+<!-- This file is part of Gerbera, based on MediaTomb. GPLv2 Applies, see LICENCE.md -->
 <html>
     <head>
         <title>MEDIATOMB</title>
diff --git a/web/std_treelook.css b/web/std_treelook.css
index 4d0aead..67cf9f8 100644
--- a/web/std_treelook.css
+++ b/web/std_treelook.css
@@ -2,19 +2,19 @@
 .treetitle {
 	padding:2px;
 	cursor:default;
-	
-	font-family: Tahoma,Verdana,Arial, Helvetica, sans-serif;
-	font-size: 11px;
-	color: #000000;
+
+	font-family: "Helvetica", "Arial", "MS Sans Serif", sans-serif;
+	font-size: 13px;
+	color: #444444;
 }
 .editednode {
 	padding:2px;
 	cursor:default;
 	background-color: #FFFFFF;;
 	color: #000000;
-	
-	font-family: Tahoma,Verdana,Arial, Helvetica, sans-serif;
-	font-size: 11px;
+
+	font-family: "Helvetica", "Arial", "MS Sans Serif", sans-serif;
+	font-size: 13px;
 }
 .editednodeinput {
 	background-color: #FFFFFF;;
@@ -26,23 +26,23 @@
 	border-style: solid;
 	border-width: 1px;
 	border-color: #000000;
-	
-	font-family: Tahoma,Verdana,Arial, Helvetica, sans-serif;
-	font-size: 11px;
+
+	font-family: "Helvetica", "Arial", "MS Sans Serif", sans-serif;
+	font-size: 13px;
 }
 .treetitleselectedfocused {
 	padding:2px;
 	cursor:default;
-	background-color: #222222;
-	color: #ffffff;
-	font-family: Tahoma,Verdana,Arial, Helvetica, sans-serif;
-	font-size: 11px;
+	background-color: #ff8000;
+	color: #FFF;
+	font-family: "Helvetica", "Arial", "MS Sans Serif", sans-serif;
+	font-size: 13px;
 }
 .treetitleselectedblured {
 	padding:2px;
 	cursor:default;
-	background-color: #222222;
-	color: #ffffff;
-	font-family: Tahoma,Verdana,Arial, Helvetica, sans-serif;
-	font-size: 11px;
+	background-color: #ff8000;
+	color: #444;
+	font-family: "Helvetica", "Arial", "MS Sans Serif", sans-serif;
+	font-size: 13px;
 }
diff --git a/web/top.html b/web/top.html
index d84694d..047e910 100644
--- a/web/top.html
+++ b/web/top.html
@@ -1,33 +1,6 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-     "http://www.w3.org/TR/html4/loose.dtd">
-<!--*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    top.html - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
--->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
+        "http://www.w3.org/TR/html4/frameset.dtd">
+<!-- This file is part of Gerbera, based on MediaTomb. GPLv2 Applies, see LICENCE.md -->
 <html>
     <head>
         <title>MEDIATOMB</title>
@@ -35,7 +8,7 @@
         <link rel="StyleSheet" href="main.css" type="text/css">
     </head>
     <body>
-        <div id="topDiv" style="color:black; background-image:url(icons/film.png); background-repeat:repeat-x; background-position: 40px 15px;">
+        <div id="topDiv">
             <table width="100%" cellspacing="0" border="0">
                 <tr>
                     <td width="20%" valign="middle" align="left">
diff --git a/web/topleft.html b/web/topleft.html
index 5e59ea3..37aeb39 100644
--- a/web/topleft.html
+++ b/web/topleft.html
@@ -1,33 +1,6 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-     "http://www.w3.org/TR/html4/loose.dtd">
-<!--*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    topleft.html - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
--->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
+        "http://www.w3.org/TR/html4/frameset.dtd">
+<!-- This file is part of Gerbera, based on MediaTomb. GPLv2 Applies, see LICENCE.md -->
 <html>
     <head>
         <title>MEDIATOMB</title>
diff --git a/web/topright.html b/web/topright.html
index 24c4917..326e10e 100644
--- a/web/topright.html
+++ b/web/topright.html
@@ -1,33 +1,6 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-     "http://www.w3.org/TR/html4/loose.dtd">
-<!--*MT*
-    
-    MediaTomb - http://www.mediatomb.cc/
-    
-    topright.html - this file is part of MediaTomb.
-    
-    Copyright (C) 2005 Gena Batyan <bgeradz at mediatomb.cc>,
-                       Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>
-    
-    Copyright (C) 2006-2010 Gena Batyan <bgeradz at mediatomb.cc>,
-                            Sergey 'Jin' Bostandzhyan <jin at mediatomb.cc>,
-                            Leonhard Wimmer <leo at mediatomb.cc>
-    
-    MediaTomb is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation.
-    
-    MediaTomb is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-    
-    You should have received a copy of the GNU General Public License
-    version 2 along with MediaTomb; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-    
-    $Id$
--->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
+        "http://www.w3.org/TR/html4/frameset.dtd">
+<!-- This file is part of Gerbera, based on MediaTomb. GPLv2 Applies, see LICENCE.md -->
 <html>
     <head>
         <title>MEDIATOMB</title>

-- 
gerbera packaging



More information about the pkg-multimedia-commits mailing list