diff --git a/cpp/Barbershop/Doxyfile b/cpp/Barbershop/Doxyfile
new file mode 100644
index 0000000000000000000000000000000000000000..3ffb5e884143b7ae9a3fa1e3e337d83fcfe7c121
--- /dev/null
+++ b/cpp/Barbershop/Doxyfile
@@ -0,0 +1,2454 @@
+# Doxyfile 1.8.10
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = Barbershop
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         = 
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = doc
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES    = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = .
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd,
+# *.vhdl, *.ucf, *.qsf, *.as and *.js.
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.idl \
+                         *.ddl \
+                         *.odl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.cs \
+                         *.d \
+                         *.php \
+                         *.php4 \
+                         *.php5 \
+                         *.phtml \
+                         *.inc \
+                         *.m \
+                         *.markdown \
+                         *.md \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.f \
+                         *.for \
+                         *.tcl \
+                         *.vhd \
+                         *.vhdl \
+                         *.ucf \
+                         *.qsf \
+                         *.as \
+                         *.js
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS = 
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = YES
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# compiled with the --with-libclang option.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        = 
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  = 
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               = 
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           = 
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     = 
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     = 
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       = 
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     = 
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           = 
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET = 
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    = 
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR             = 
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            = 
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               = 
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = NO
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = YES
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = svg
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               = /usr/local/bin/dot
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           = 
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           = 
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH      = 
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH  = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
diff --git a/cpp/Barbershop/Makefile b/cpp/Barbershop/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..705f72461731871514ec597b5c4dd83b46078871
--- /dev/null
+++ b/cpp/Barbershop/Makefile
@@ -0,0 +1,27 @@
+ODEMX_HOME := ../ODEMx-lite
+
+CFLAGS := -std=c++14 -O3 -flto -I$(ODEMX_HOME)/include -I$(ODEMX_HOME)/external/CppLog/include
+LFLAGS := -L$(ODEMX_HOME)/lib
+
+CPPFILES := $(wildcard *.cpp)
+HPPFILES := $(wildcard *.h) $(wildcard *.hpp)
+
+LIBS := -lOdemx
+OBJS := $(CPPFILES:%.cpp=%.o)
+TARGET := Barbershop
+
+# compile
+%.o: %.cpp
+	$(CXX) $(CFLAGS) -c $< -o $@
+
+# link
+all: $(OBJS)
+	$(CXX) $(LFLAGS) $^ $(LIBS) -o $(TARGET)
+
+# run
+run: all
+	./$(TARGET)
+
+# clean
+clean:
+	$(RM) $(RMFILES) $(OBJS) $(TARGET)
diff --git a/cpp/Barbershop/main.cpp b/cpp/Barbershop/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..70eb7f452a7035ecea311747479344dd66d47721
--- /dev/null
+++ b/cpp/Barbershop/main.cpp
@@ -0,0 +1,159 @@
+
+#include <odemx/odemx.h>
+#include <vector>
+#include <memory>
+#include <iostream>
+
+using odemx::base::SimTime;
+using odemx::base::Process;
+using odemx::base::Simulation;
+using odemx::synchronization::Bin;
+using odemx::random::Uniform;
+using odemx::statistics::Tally;
+using odemx::data::output::OStreamReport;
+
+// helper constants
+const SimTime SIM_DURATION = 24.0*60.0*7.0*3.0;
+
+namespace Barbershop {
+	///@brief A barbershop-specific simulation class.
+	struct Sim: Simulation {
+		///@brief The barber that can only serve one customer concurrently.
+		Bin joe;
+		///@brief Statistics collection for the time customers spend waiting.
+		Tally wait_time;
+		///@brief Pointer to the main process.
+		std::unique_ptr<Process> main;
+		
+		///@brief Initializes the main process and the other attributes.
+		Sim(SimTime duration);
+		
+	protected:
+		///@brief Automatically called method activating the main process.
+		void initSimulation() override {
+			main->activate();
+		}
+	};
+	
+	///@brief Active customer trying to get a haircut from Joe.
+	class Customer: public Process {
+		///@brief The amount of time needed by Joe to serve this customer once
+		/// it is their turn.
+		SimTime delay;
+		
+	public:
+		///@brief Constructor.
+		Customer(Sim& sim, SimTime delay)
+		:	Process(sim, "Customer"),
+			delay(delay) {}
+		
+		///@brief Method containing the lifecycle of the customer.
+		int main() override {
+			Sim& sim = static_cast<Sim&>(getSimulation());
+			
+			// access the barber and record the time for the report
+			SimTime arrival_time = getTime();
+			sim.joe.take(1);
+			sim.wait_time.update(getTime() - arrival_time);
+			
+			// spend time
+			holdFor(delay);
+			// release the barber
+			sim.joe.give(1);
+			
+			return 0;
+		}
+	};
+	
+	///@brief The process responsible for generating customers.
+	class CustomerGenerator: public Process {
+		///@brief A list of all the customers generated by this process.
+		std::vector<std::unique_ptr<Customer>> customers;
+		
+	public:
+		///@brief The constructor.
+		CustomerGenerator(Sim& sim): Process(sim, "Customer Generator") {}
+		
+		///@brief Method containing the lifecycle of the customer generator.
+		int main() override {
+			Sim& sim = static_cast<Sim&>(getSimulation());
+			Uniform dist_a(sim, "Time between customers", 12.0, 24.0);
+			Uniform dist_s(sim, "Time for each customer", 12.0, 18.0);
+			
+			while (true) {
+				holdFor(dist_a.sample());
+				customers.push_back(std::make_unique<Customer>(
+					sim, dist_s.sample()
+				));
+				customers.back()->activate();
+			}
+			
+			return 0;
+		}
+	};
+	
+	///@brief The main process.
+	class Main: public Process {
+		///@brief Time between opening and closing the shop.
+		SimTime duration;
+		///@brief Internal customer generator process.
+		CustomerGenerator generator;
+		
+	public:
+		///@brief The constructor.
+		Main(Sim& sim, SimTime duration)
+		:	Process(sim, "Main Process"),
+			duration(duration),
+			generator(sim)
+		{}
+		
+		///@brief The method containing the lifecycle of the main process.
+		int main() override {
+			// activate a process to generate the customers
+			generator.activate();
+			
+			// wait until the store closes
+			holdFor(duration);
+			generator.cancel();
+			
+			// finish processing the queue (no more customers arrive)
+			return 0;
+		}
+	};
+	
+	// Simulation constructor moved down here to prevent backwards references.
+	Sim::Sim(SimTime duration)
+	:	Simulation("Barbershop"),
+		joe(*this, "Joe", 1),
+		wait_time(*this, "Wait Time"),
+		main(std::make_unique<Main>(*this, duration))
+	{}
+}
+
+#ifdef RUST_FFI
+///@brief Entry point for the function used to benchmark this scenario.
+extern "C" void barbershop(SimTime duration) {
+	// set up the simulation model
+	Barbershop::Sim sim(duration);
+	
+	// run to completion
+	sim.run();
+	
+	// no report
+}
+#else
+int main() {
+	// set up the simulation model
+	Barbershop::Sim sim(SIM_DURATION);
+	
+	// run to completion
+	sim.run();
+	
+	// generate the report
+	OStreamReport report(std::cout);
+	report.addReportProducer(sim.wait_time);
+	report.generateReport();
+	
+	return 0;
+}
+#endif
diff --git a/cpp/Ferry/Doxyfile b/cpp/Ferry/Doxyfile
new file mode 100644
index 0000000000000000000000000000000000000000..0b1be5b603d95cba3d0775435d70967f7b6a71e6
--- /dev/null
+++ b/cpp/Ferry/Doxyfile
@@ -0,0 +1,2454 @@
+# Doxyfile 1.8.10
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = Ferry
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         = 
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = doc
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES    = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = .
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd,
+# *.vhdl, *.ucf, *.qsf, *.as and *.js.
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.idl \
+                         *.ddl \
+                         *.odl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.cs \
+                         *.d \
+                         *.php \
+                         *.php4 \
+                         *.php5 \
+                         *.phtml \
+                         *.inc \
+                         *.m \
+                         *.markdown \
+                         *.md \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.f \
+                         *.for \
+                         *.tcl \
+                         *.vhd \
+                         *.vhdl \
+                         *.ucf \
+                         *.qsf \
+                         *.as \
+                         *.js
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS = 
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = YES
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# compiled with the --with-libclang option.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        = 
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  = 
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               = 
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           = 
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     = 
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     = 
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       = 
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     = 
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           = 
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET = 
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    = 
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR             = 
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            = 
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               = 
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = NO
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = YES
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = svg
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               = /usr/local/bin/dot
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           = 
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           = 
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH      = 
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH  = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
diff --git a/cpp/Ferry/Makefile b/cpp/Ferry/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..b4b865b1e31b917a8ae95266b512224c8297f472
--- /dev/null
+++ b/cpp/Ferry/Makefile
@@ -0,0 +1,27 @@
+ODEMX_HOME := ../ODEMx-lite
+
+CFLAGS := -std=c++14 -O3 -flto -I$(ODEMX_HOME)/include -I$(ODEMX_HOME)/external/CppLog/include
+LFLAGS := -L$(ODEMX_HOME)/lib
+
+CPPFILES := $(wildcard *.cpp)
+HPPFILES := $(wildcard *.h) $(wildcard *.hpp)
+
+LIBS := -lOdemx
+OBJS := $(CPPFILES:%.cpp=%.o)
+TARGET := Ferry
+
+# compile
+%.o: %.cpp
+	$(CXX) $(CFLAGS) -c $< -o $@
+
+# link
+all: $(OBJS)
+	$(CXX) $(LFLAGS) $^ $(LIBS) -o $(TARGET)
+
+# run
+run: all
+	./$(TARGET)
+
+# clean
+clean:
+	$(RM) $(RMFILES) $(OBJS) $(TARGET)
diff --git a/cpp/Ferry/main.cpp b/cpp/Ferry/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cd0b483ebaf00e589adc98dd5a22d5f63757f49a
--- /dev/null
+++ b/cpp/Ferry/main.cpp
@@ -0,0 +1,285 @@
+
+#include <odemx/odemx.h>
+#include <vector>
+#include <memory>
+#include <iostream>
+#include <utility>
+
+using odemx::base::SimTime;
+using odemx::base::Process;
+using odemx::base::Simulation;
+using odemx::synchronization::PortHeadT;
+using odemx::synchronization::PortTailT;
+using odemx::synchronization::Timer;
+using odemx::synchronization::IMemory;
+using odemx::random::NegativeExponential;
+using odemx::random::Normal;
+using odemx::statistics::Tally;
+
+const SimTime      SIM_DURATION    = 24.0*60.0*7.0;
+const SimTime      HARBOR_DISTANCE = 10.0;
+const SimTime      FERRY_TIMEOUT   =  5.0;
+const unsigned int FERRY_CAPACITY  =  5;
+const unsigned int FERRY_COUNT     =  2;
+const unsigned int HARBOR_COUNT    =  4;
+
+namespace Ferry {
+	// forward declarations
+	struct Car;
+	class Pier;
+	class Ferry;
+	
+	// These are just ODEMx-flavored sender/receiver-pairs for the same channel.
+	typedef odemx::synchronization::PortTailT<Car> PortTail;
+	typedef odemx::synchronization::PortHeadT<Car> PortHead;
+	
+	///@brief A car-ferry-specific simulation class.
+	class Sim: public Simulation {
+		///@brief A vector for all of the harbors.
+		std::vector<std::unique_ptr<Pier>> piers;
+		///@brief A vector for all of the ferries.
+		std::vector<std::unique_ptr<Ferry>> ferries;
+		
+	public:
+		///@brief Constructor setting up the number of harbors and ferries.
+		Sim(unsigned int ferries, unsigned int harbors);
+		
+		///@brief Cleans up the model by accounting for all of the remaining
+		/// cars of the harbors.
+		void finalize();
+		
+		///@brief Statistical aggregations.
+		Tally ferry_cargo_len;
+		Tally ferry_load_time;
+		Tally car_wait_time;
+		
+	protected:
+		///@brief Automatically called method activating all of the ferries and
+		/// harbors.
+		void initSimulation() override;
+	};
+	
+	///@brief A passive structure for cars.
+	struct Car {
+		SimTime arrival_time;
+		SimTime load_duration;
+	};
+	
+	///@brief The process modeling a harbor with arriving cars.
+	class Pier: public Process {
+		///@brief Writing end for the queue with arriving cars.
+		PortTail::Ptr landing_site;
+		
+		///@brief Returns an upcasted version of the basic simulation.
+		Sim& getSimulation() {
+			return static_cast<Sim&>(Process::getSimulation());
+		}
+		
+	public:
+		///@brief The constructor initializing the car queue.
+		Pier(Sim& sim)
+		:	Process(sim, "Harbor"),
+			landing_site(PortTail::create(sim, "Harbor Port"))
+		{}
+		
+		///@brief Cleans up the harbor by accounting for all of the cars that
+		/// are still waiting for a ferry.
+		void finalize() {
+			unsigned int count = landing_site->count();
+			PortHead::Ptr head = landing_site->getHead();
+			Sim& sim = getSimulation();
+		
+			// take cars into account that weren't picked up by a ferry
+			for (unsigned int i = 0; i < count; ++i) {
+				sim.car_wait_time.update(sim.getTime() - head->get()->arrival_time);
+			}
+		}
+		
+		///@brief Method providing access to the reading end of the car queue.
+		inline PortHead::Ptr getHead() {
+			return landing_site->getHead();
+		}
+		
+		///@brief Models the lifecycle of the harbor.
+		int main() override {
+			NegativeExponential arrival_delay(getSimulation(), "Arrival Delay", 0.1);
+			Normal loading_delay(getSimulation(), "Loading Delay", 0.5, 0.2);
+		
+			while (true) {
+				double load_duration;
+			
+				holdFor(arrival_delay.sample());
+			
+				do load_duration = loading_delay.sample();
+				while (load_duration < 0.0);
+			
+				landing_site->put(Car {
+					getTime(), load_duration
+				});
+			}
+		
+			return 0;
+		}
+	};
+	
+	///@brief The process modeling an individual ferry.
+	class Ferry: public Process {
+		///@brief Space for the cars.
+		std::vector<Car> cargo;
+		///@brief Maximum car capacity.
+		unsigned int capacity;
+		///@brief Time to wait for another car before leaving before filling all
+		/// of the available cargo space.
+		SimTime timeout;
+		///@brief Travel time between (any) two harbors.
+		SimTime travel_time;
+		///@brief Vector of reading ends for all of the harbors.
+		std::vector<PortHead::Ptr> piers;
+		
+		///@brief Returns an upcasted version of the basic simulation.
+		Sim& getSimulation() {
+			return static_cast<Sim&>(Process::getSimulation());
+		}
+		
+	public:
+		///@brief Constructor.
+		Ferry(Sim& sim, unsigned int capacity,
+		      SimTime timeout, SimTime travel_time,
+			  std::vector<PortHead::Ptr>&& piers)
+	  	:	Process(sim, "Ferry"),
+	  		capacity(capacity),
+	  		timeout(timeout),
+	  		travel_time(travel_time),
+	  		piers(piers)
+	  	{}
+		
+		///@brief Models the lifecycle of the ferry.
+		int main() override {
+			Timer timer(getSimulation(), "FerryTimer");
+			IMemory* notifier;
+			Car car;
+		
+			while (true) {
+				for (auto& pier: piers) {
+					// unload the cars
+					for (auto& car: cargo) {
+						holdFor(car.load_duration);
+					}
+					cargo.clear();
+				
+					SimTime begin_loading = getTime();
+				
+					// wait until new cars arrive or a timeout occurs
+					while (cargo.size() < capacity) {
+						timer.setIn(timeout);
+						notifier = wait(&timer, pier.get());
+					
+						if (notifier != &timer) {
+							// a car arrived in time
+							car = *pier->get();
+							timer.stop();
+							getSimulation()
+								.car_wait_time
+								.update(getTime() - car.arrival_time);
+							holdFor(car.load_duration);
+							cargo.push_back(car);
+						} else {
+							// the timeout has been triggered
+							break;
+						}
+					}
+				
+					getSimulation()
+						.ferry_load_time
+						.update(getTime() - begin_loading);
+					getSimulation()
+						.ferry_cargo_len
+						.update(cargo.size());
+				
+					// travel to the next harbor
+					holdFor(travel_time);
+				}
+			}
+		
+			return 0;
+		}
+	};
+	
+	// Implementation of the simulation class.
+	
+	Sim::Sim(unsigned int ferries, unsigned int harbors)
+	:	Simulation("Ferry"),
+		ferry_cargo_len(*this, "Ferry Cargo Len"),
+		ferry_load_time(*this, "Ferry Load Time"),
+		car_wait_time(*this, "Car Wait Time")
+	{
+		// create all of the harbors
+		for (unsigned int i = 0; i < harbors; ++i) {
+			piers.push_back(std::make_unique<Pier>(*this));
+		}
+		
+		// create all of the ferries
+		for (unsigned int i = 0; i < ferries; ++i) {
+			std::vector<PortHead::Ptr> ports;
+	
+			for (unsigned int j = i; j < harbors; ++j) {
+				ports.push_back(piers[j]->getHead());
+			}
+			
+			for (unsigned int j = 0; j < i; ++j) {
+				ports.push_back(piers[j]->getHead());
+			}
+			
+			this->ferries.push_back(std::make_unique<Ferry>(
+				*this, FERRY_CAPACITY, FERRY_TIMEOUT, HARBOR_DISTANCE,
+				std::move(ports)
+			));
+		}
+	}
+	
+	void Sim::finalize() {
+		for (auto& pier: piers) {
+			pier->finalize();
+		}
+	}
+	
+	void Sim::initSimulation() {
+		// activate the harbors
+		for (auto& pier: piers) {
+			pier->activate();
+		}
+
+		// activate the ferries
+		for (auto& ferry: ferries) {
+			ferry->activate();
+		}
+	}
+}
+
+#ifdef RUST_FFI
+///@brief Entry point for the function used to benchmark this scenario.
+extern "C" void ferry(SimTime duration, unsigned int ferries, unsigned int harbors) {
+	// set up the simulation model
+	Ferry::Sim sim(ferries, harbors);
+	sim.runUntil(duration);
+	sim.finalize();
+	
+	// no report
+}
+#else
+int main() {
+	// set up the simulation model
+	Ferry::Sim sim(FERRY_COUNT, HARBOR_COUNT);
+	sim.runUntil(SIM_DURATION);
+	sim.finalize();
+	
+	// generate the report
+	odemx::data::output::OStreamReport report(std::cout);
+	report.addReportProducer(sim.ferry_cargo_len);
+	report.addReportProducer(sim.ferry_load_time);
+	report.addReportProducer(sim.car_wait_time);
+	report.generateReport();
+	
+	return 0;
+}
+#endif
diff --git a/cpp/Philosophers/Doxyfile b/cpp/Philosophers/Doxyfile
new file mode 100644
index 0000000000000000000000000000000000000000..cf78a3ea099c13777782b8050caaa15c36df3e8a
--- /dev/null
+++ b/cpp/Philosophers/Doxyfile
@@ -0,0 +1,2454 @@
+# Doxyfile 1.8.10
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = Dining Philosophers
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         = 
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = doc
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES    = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = .
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd,
+# *.vhdl, *.ucf, *.qsf, *.as and *.js.
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.idl \
+                         *.ddl \
+                         *.odl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.cs \
+                         *.d \
+                         *.php \
+                         *.php4 \
+                         *.php5 \
+                         *.phtml \
+                         *.inc \
+                         *.m \
+                         *.markdown \
+                         *.md \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.f \
+                         *.for \
+                         *.tcl \
+                         *.vhd \
+                         *.vhdl \
+                         *.ucf \
+                         *.qsf \
+                         *.as \
+                         *.js
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS = 
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = YES
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# compiled with the --with-libclang option.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        = 
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  = 
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               = 
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           = 
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     = 
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     = 
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       = 
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     = 
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           = 
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET = 
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    = 
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR             = 
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            = 
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               = 
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = NO
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = YES
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = svg
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               = /usr/local/bin/dot
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           = 
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           = 
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH      = 
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH  = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
diff --git a/cpp/Philosophers/Makefile b/cpp/Philosophers/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..2f149051de7cab38af11404ef0bc8eb97cc537e2
--- /dev/null
+++ b/cpp/Philosophers/Makefile
@@ -0,0 +1,27 @@
+ODEMX_HOME := ../ODEMx-lite
+
+CFLAGS := -std=c++14 -O3 -flto -I$(ODEMX_HOME)/include -I$(ODEMX_HOME)/external/CppLog/include
+LFLAGS := -L$(ODEMX_HOME)/lib
+
+CPPFILES := $(wildcard *.cpp)
+HPPFILES := $(wildcard *.h) $(wildcard *.hpp)
+
+LIBS := -lOdemx
+OBJS := $(CPPFILES:%.cpp=%.o)
+TARGET := Philosophers
+
+# compile
+%.o: %.cpp
+	$(CXX) $(CFLAGS) -c $< -o $@
+
+# link
+all: $(OBJS)
+	$(CXX) $(LFLAGS) $^ $(LIBS) -o $(TARGET)
+
+# run
+run: all
+	./$(TARGET)
+
+# clean
+clean:
+	$(RM) $(RMFILES) $(OBJS) $(TARGET)
diff --git a/cpp/Philosophers/main.cpp b/cpp/Philosophers/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e137beb22216427b65eebae00a99764a1f064cae
--- /dev/null
+++ b/cpp/Philosophers/main.cpp
@@ -0,0 +1,169 @@
+#include <odemx/odemx.h>
+#include <iostream>
+#include <vector>
+#include <memory>
+
+const int PHILOSOPHER_COUNT =   5;
+const int EXPERIMENT_COUNT  = 500;
+
+using odemx::base::Simulation;
+using odemx::base::Process;
+using odemx::synchronization::Bin;
+using odemx::statistics::Tally;
+using odemx::data::output::OStreamReport;
+
+namespace Philosophers {
+	///@brief Passive class used to model the table that the philosophers are
+	/// seated around
+	class Table {
+		///@brief A vector for the forks.
+		std::vector<std::unique_ptr<Bin>> forks;
+		
+	public:
+		///@brief Constructor initializing the fork-vector.
+		Table(Simulation& sim, unsigned int forks) {
+			for (int i = 0; i < forks; ++i) {
+				this->forks.push_back(std::make_unique<Bin>(sim, "Fork", 1));
+			}
+		}
+		
+		///@brief Blocks until the requested fork is available and acquires it.
+		void acquire_fork(unsigned int i) {
+			i %= forks.size();
+			forks[i]->take(1);
+		}
+		
+		///@brief Returns the requested fork (presumably wiped clean) to the 
+		/// table.
+		void release_fork(unsigned int i) {
+			i %= forks.size();
+			forks[i]->give(1);
+		}
+	};
+	
+	///@brief An active philosopher, philosophising and eating at the table.
+	class Philosopher: public Process {
+		///@brief The table.
+		Table& table;
+		///@brief The seat number of this particular philosopher.
+		unsigned int seat;
+		
+	public:
+		///@brief Constructor initializing table and seat.
+		Philosopher(Simulation& sim, Table& table, unsigned int seat)
+		:	Process(sim, "Philosopher"),
+			table(table),
+			seat(seat)
+		{}
+		
+		///@brief Method containing the lifecycle of the philosopher.
+		int main() override {
+			using namespace odemx::random;
+			NegativeExponential thinking_duration(getSimulation(), "thinking", 1.0);
+			Uniform artificial_delay(getSimulation(), "delay", 0.1, 0.2);
+			Normal eating_duration(getSimulation(), "eating", 0.5, 0.2);
+			
+			while (true) {
+				double duration;
+				
+				// spend some time pondering the nature of things
+				holdFor(thinking_duration.sample());
+				
+				// acquire the first fork
+				table.acquire_fork(seat);
+				
+				// introduce an artificial delay to leave room for deadlocks
+				holdFor(artificial_delay.sample());
+				
+				// acquire the second fork
+				table.acquire_fork(seat + 1);
+				
+				// spend some time eating
+				do duration = eating_duration.sample();
+				while (duration < 0.0);
+				holdFor(duration);
+				
+				// release the forks
+				table.release_fork(seat + 1);
+				table.release_fork(seat);
+			}
+			
+			return 0;
+		}
+	};
+	
+	///@brief A dining-philosopher-specific simulation class.
+	class Sim: public Simulation {
+		///@brief The table.
+		Table table;
+		///@brief A vector storing all of the philosophers.
+		std::vector<std::unique_ptr<Philosopher>> philo;
+		
+	public:
+		///@brief Constructor populating the philosopher vector based on the
+		/// requested entry-count.
+		Sim(unsigned int count)
+		:	Simulation("Dining Philosophers"),
+			table(*this, count)
+		{
+			// create the philosopher-processes
+			for (int i = 0; i < count; ++i) {
+				philo.push_back(std::make_unique<Philosopher>(*this, table, i));
+			}
+		}
+		
+		///@brief Runs multiple simulations in quick succession and returns
+		/// statistical information about the model-times recorded before a
+		/// deadlock occurred.
+		static Tally main(unsigned int count, unsigned int reruns) {
+			Tally sim_duration(odemx::getDefaultSimulation(), "Sim Duration");
+			unsigned long seed = 907;
+			
+			// run the simulation a number of times
+			for (unsigned int i = 0; i < reruns; ++i) {
+				// create a new simulation context
+				Sim sim(count);
+				
+				// set the seed for the simulation's rng
+				sim.setSeed(seed);
+				
+				// run until no more processes can be scheduled;
+				// this would indicate a deadlock-situation
+				sim.run();
+				
+				// tabulate the latest simulation time
+				sim_duration.update(sim.getTime());
+				
+				// extract the seed for the next simulation
+				seed = sim.getNextSeed();
+			}
+			
+			return sim_duration;
+		}
+		
+	protected:
+		///@brief Automatically called method activating the philosophers.
+		void initSimulation() override {
+			// activate the philosopher-processes
+			for (auto& p: philo) { p->hold(); }
+		}
+	};
+}
+
+#ifdef RUST_FFI
+///@brief Entry point for the benchmarking function.
+extern "C" void philosophers(unsigned int count, unsigned int reruns) {
+	Philosophers::Sim::main(count, reruns);
+}
+#else
+int main() {
+	Tally sim_duration =
+		Philosophers::Sim::main(PHILOSOPHER_COUNT, EXPERIMENT_COUNT);
+	
+	// generate the report
+	OStreamReport report(std::cout);
+	report.addReportProducer(sim_duration);
+	report.generateReport();
+	return 0;
+}
+#endif
diff --git a/odemx-lite/COPYING b/odemx-lite/COPYING
new file mode 100644
index 0000000000000000000000000000000000000000..acb9717c93b70722674b2f1aa1988732e9a3c8fa
--- /dev/null
+++ b/odemx-lite/COPYING
@@ -0,0 +1,504 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 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 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., 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/odemx-lite/Doxygen/Doxyfile b/odemx-lite/Doxygen/Doxyfile
new file mode 100644
index 0000000000000000000000000000000000000000..820963fe3c63a54c3db3335a65fa887d4c3c239d
--- /dev/null
+++ b/odemx-lite/Doxygen/Doxyfile
@@ -0,0 +1,2421 @@
+# Doxyfile 1.8.10
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = ODEMx-control
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control_ system is used.
+
+PROJECT_NUMBER         = "Version 3.1 Humboldt-Universit&auml;t zu Berlin"
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = ../doc
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = YES
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES    = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       = "The $name class     " \
+                         "The $name widget     " \
+                         "The $name file     " \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = NO
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    = ../include
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = YES
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = YES
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = NO
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = NO
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control_ system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = ../src \
+                         ../include \
+                         .
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd,
+# *.vhdl, *.ucf, *.qsf, *.as and *.js.
+
+FILE_PATTERNS          = *.h \
+                         *.cpp \
+                         *.dox \
+                         *.hpp
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = */.svn/* \
+                         */omsi/*
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        = SuiteCppLogUnitTest \
+                         std
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           = ../examples
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS = 
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = YES
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# compiled with the --with-libclang option.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        = 
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  = 
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = YES
+
+# With HTML_INDEX_NUM_ENTRIES one can control_ the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               = ../doc/odemx.chm
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           = 
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     = 
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control_ over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     = 
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       = 
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     = 
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           = 
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET = 
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = YES
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = YES
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    = 
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR             = 
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = YES
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           = ../src
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             = ODEMX_USE_CONTINUOUS \
+                         ODEMX_USE_OBSERVATION
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = NO
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            = 
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               = 
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = NO
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control_ over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = YES
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = svg
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = YES
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               = /usr/local/bin/dot
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           = 
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           = 
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH      = 
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH  = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
diff --git a/odemx-lite/Doxygen/Doxyfile.bak b/odemx-lite/Doxygen/Doxyfile.bak
new file mode 100644
index 0000000000000000000000000000000000000000..c2f8ef626f9c9f676e10a3de8db7e13cb841c6ab
--- /dev/null
+++ b/odemx-lite/Doxygen/Doxyfile.bak
@@ -0,0 +1,1700 @@
+# Doxyfile 1.7.3
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = ODEMx
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = "Version 3.0 Humboldt-Universit&auml;t zu Berlin"
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is 
+# included in the documentation. The maximum height of the logo should not 
+# exceed 55 pixels and the maximum width should not exceed 200 pixels. 
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = ${CMAKE_CURRENT_BINARY_DIR}/doc
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = YES
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, 
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English 
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, 
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = "The $name class     " \
+                         "The $name widget     " \
+                         "The $name file     " \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = ../include
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful if your file system 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it 
+# parses. With this tag you can assign which parser to use for a given extension. 
+# Doxygen has a built-in mapping, but you can override or extend it using this 
+# tag. The format is ext=language, where ext is a file extension, and language 
+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, 
+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make 
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C 
+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions 
+# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also makes the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = YES
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to 
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
+# determine which symbols to keep in memory and which to flush to disk. 
+# When the cache is full, less often used symbols will be written to disk. 
+# For small to medium size projects (<1000 input files) the default value is 
+# probably good enough. For larger projects a too small cache size can cause 
+# doxygen to be busy swapping symbols to and from disk most of the time 
+# causing a significant performance penalty. 
+# If the system has enough physical memory increasing the cache will improve the 
+# performance by keeping more symbols in memory. Note that the value works on 
+# a logarithmic scale so increasing the size by one will roughly double the 
+# memory usage. The cache size is given by this formula: 
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen 
+# will list include files with double quotes in the documentation 
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen 
+# will sort the (brief and detailed) documentation of class members so that 
+# constructors and destructors are listed first. If set to NO (the default) 
+# the constructors will appear in the respective orders defined by 
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. 
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO 
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a 
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen 
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = NO
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or macro consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and macros in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index 
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed 
+# by doxygen. The layout file controls the global structure of the generated 
+# output files in an output format independent way. The create the layout file 
+# that represents doxygen's defaults, run doxygen with the -l option. 
+# You can optionally specify a file name after the option, if omitted 
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE            = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = ${CMAKE_CURRENT_SOURCE_DIR}/Doxygen \
+                         ${CMAKE_CURRENT_SOURCE_DIR}/src \
+                         ${CMAKE_CURRENT_SOURCE_DIR}/include \
+                         ${CMAKE_CURRENT_SOURCE_DIR}/external/CppLog \
+                         ${CMAKE_CURRENT_BINARY_DIR}/include
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh 
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py 
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS          = *.h \
+                         *.cpp \
+                         *.dox
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = ${CMAKE_CURRENT_SOURCE_DIR}/test
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix file system feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = */.svn/* \
+                         */omsi/*
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = SuiteCppLogUnitTest \
+                         std \
+                         std::tr1 \
+                         Poco
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = ${CMAKE_CURRENT_SOURCE_DIR}/examples \
+                         ${CMAKE_CURRENT_SOURCE_DIR}/external/CppLog/src/samples/src
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty or if 
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file 
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) 
+# and it is also possible to disable source filtering for a specific pattern 
+# using *.ext= (so without naming a filter). This option only has effect when 
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS = 
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = YES
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 
+# link to the source code.  Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. 
+# Doxygen will adjust the colors in the stylesheet and background images 
+# according to this color. Hue is specified as an angle on a colorwheel, 
+# see http://en.wikipedia.org/wiki/Hue for more information. 
+# For instance the value 0 represents red, 60 is yellow, 120 is green, 
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. 
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of 
+# the colors in the HTML output. For a value of 0 the output will use 
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to 
+# the luminance component of the colors in the HTML output. Values below 
+# 100 gradually make the output lighter, whereas values above 100 make 
+# the output darker. The value divided by 100 is the actual gamma applied, 
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, 
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML 
+# page will contain the date and time when the page was generated. Setting 
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup. 
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html 
+# for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify 
+# the documentation publisher. This should be a reverse domain-name style 
+# string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = ../doc/odemx.chm
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file 
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and 
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated 
+# that can be used as input for Qt's qhelpgenerator to generate a 
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to 
+# add. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the 
+# custom filter to add. For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> 
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this 
+# project's 
+# filter section matches. 
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> 
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files  
+# will be generated, which together with the HTML files, form an Eclipse help 
+# plugin. To install this plugin and make it available under the help contents 
+# menu in Eclipse, the contents of the directory containing the HTML and XML 
+# files needs to be copied into the plugins directory of eclipse. The name of 
+# the directory within the plugins directory should be the same as 
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before 
+# the help appears.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin 
+# the directory name containing the HTML and XML files should also have 
+# this name.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [0,1..20]) 
+# that doxygen will group on one line in the generated HTML documentation. 
+# Note that a value of 0 will completely suppress the enum values from
+# appearing in the overview section.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
+# structure should be generated to display hierarchical information. 
+# If the tag value is set to YES, a side panel will be generated 
+# containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). 
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = YES
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, 
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES       = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open 
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images 
+# generated for formulas are transparent PNGs. Transparent PNGs are 
+# not supported properly for IE 6.0, but are supported on all modern browsers. 
+# Note that when changing this option you need to delete any form_*.png files 
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax 
+# (see http://www.mathjax.org) which uses client side Javascript for the 
+# rendering instead of using prerendered bitmaps. Use this if you do not 
+# have LaTeX installed or if you want to formulas look prettier in the HTML 
+# output. When enabled you also need to install MathJax separately and 
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you need to specify the location relative to the 
+# HTML output directory using the MATHJAX_RELPATH option. The destination 
+# directory should contain the MathJax.js script. For instance, if the mathjax 
+# directory is located at the same level as the HTML output directory, then 
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the
+# mathjax.org site, so you can quickly see the result without installing 
+# MathJax, but it is strongly recommended to install a local copy of MathJax 
+# before deployment.
+
+MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box 
+# for the HTML output. The underlying search engine uses javascript 
+# and DHTML and should work on any modern browser. Note that when using 
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets 
+# (GENERATE_DOCSET) there is already a search function so this one should 
+# typically be disabled. For large projects the javascript based search engine 
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be 
+# implemented using a PHP enabled web server instead of at the web client 
+# using Javascript. Doxygen will generate the search PHP script and index 
+# file to put on the web server. The advantage of the server 
+# based approach is that it scales better to large projects and allows 
+# full text search. The disadvantages are that it is more difficult to setup 
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name. 
+# Note that when enabling USE_PDFLATEX this option is only used for 
+# generating bitmaps for formulas in the HTML output, but not in the 
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include 
+# source code with syntax highlighting in the LaTeX output. 
+# Note that which sources are shown also depends on other settings 
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = YES
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = YES
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = ${CMAKE_CURRENT_SOURCE_DIR}/src
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = ODEMX_USE_CONTINUOUS \
+                         ODEMX_USE_OBSERVATION
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all references to function-like macros 
+# that are alone on a line, have an all uppercase name, and do not end with a 
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links. 
+# Note that each tag file must have a unique name 
+# (where the name does NOT include the path) 
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = ${CMAKE_CURRENT_BINARY_DIR}/doc/odemx.tag
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = NO
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option also works with HAVE_DOT disabled, but it is recommended to 
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = NO
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = NO
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is 
+# allowed to run in parallel. When set to 0 (the default) doxygen will 
+# base this on the number of processors available in the system. You can set it 
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS        = 0
+
+# By default doxygen will write a font called Helvetica to the output 
+# directory and reference it in all dot files that doxygen generates. 
+# When you want a differently looking font you can specify the font name 
+# using DOT_FONTNAME. You need to make sure dot is able to find the font, 
+# which can be done by putting it in a standard location or by setting the 
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory 
+# containing the font.
+
+DOT_FONTNAME           = FreeSans.ttf
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the output directory to look for the 
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a 
+# different font using DOT_FONTNAME you can set the path where dot 
+# can find it using this tag.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include 
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, svg, gif or svg. 
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that 
+# contain msc files that are included in the documentation (see the 
+# \mscfile command).
+
+MSCFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, because dot on Windows does not 
+# seem to support this out of the box. Warning: Depending on the platform used, 
+# enabling this option may lead to badly anti-aliased labels on the edges of 
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
diff --git a/odemx-lite/Doxygen/groups.dox b/odemx-lite/Doxygen/groups.dox
new file mode 100644
index 0000000000000000000000000000000000000000..c7b884ab767d5e6f87ba73ebfac3c19e4a7c3f40
--- /dev/null
+++ b/odemx-lite/Doxygen/groups.dox
@@ -0,0 +1,54 @@
+/**
+
+\defgroup base Base
+The core group of ODEMx modeling classes. The module contains base classes
+for discrete and continuous processes, events, a scheduler and ts execution
+list, as well as the simulation context. See \ref module_base.
+
+\defgroup coroutine Coroutine
+This group contains a portable coroutine implementation that is used to model
+the sequentialized execution of logically parallel processes. The implementation
+on POSIX systems used to be based on the functions \c setjmp and \c longjmp 
+which always replaced the runtime stack with that of the current coroutine.
+On MS Windows platforms, the lightweight fibers were used. The same API has
+since been implemented for POSIX platforms on top of the @c ucontext. This is 
+safer because it provides a separate runtime stack for each coroutine.  
+See \ref module_coroutine.
+
+\defgroup data Data
+The data group contains all components tasked with producing, collecting,
+printing, or storing ODEMx simulation data. There are base classes for
+three data collection concepts: logging, observation, and report.
+See \ref module_data.
+
+\defgroup protocol Protocol
+This group provides model components for simulating communication
+protocols in arbitrary networks. Primarily, the components are used
+to assemble protocol stacks and to link nodes in a network. The behavior
+of active components in the stacks is user-defined.
+See \ref module_protocol.
+
+\defgroup random Random
+This module provides random number generators for continuous and discrete
+distributions. The classes offer support for a variety of distributions
+such as uniform, normal, or poisson distributions.  
+See \ref module_random.
+
+\defgroup statistics Statistics
+This module provides various classes for computing statistical analyses.
+The classes range from simple counters to more sophisticated accumulating 
+components for various statistical characteristics.
+See \ref module_statistics.
+
+\defgroup synch Synchronization
+This module consists of classes which can be used for synchronizing
+processes. Besides different queue variants, this also includes a waiting
+concept for processes, as well as timers and resource modeling components.  
+See \ref module_synchronization
+
+\defgroup util Utilities
+This module contains ODEMx utilities, such as various exceptions, a function
+for computing the library path, and string conversion functions.
+See \ref module_util
+
+*/
diff --git a/odemx-lite/Doxygen/mainPage.dox b/odemx-lite/Doxygen/mainPage.dox
new file mode 100644
index 0000000000000000000000000000000000000000..77fb57d25250d7366bb5e1ab1eccc4ec8640c91a
--- /dev/null
+++ b/odemx-lite/Doxygen/mainPage.dox
@@ -0,0 +1,97 @@
+/**
+	\mainpage
+
+	\section Introduction
+	Welcome to ODEMx. ODEMx is a library for discrete event simulation in C++.
+	\ref toc "(Table of Contents)"
+
+	ODEMx is a C++ library for process and event simulation, which
+	is a branch of computer simulation. As such it uses processes and
+	events to model real-world or fictional systems.
+	A process in this context is a continuous or discrete
+	sequence of actions which are somehow closely related to each
+	other, for instance they are all 'done' by one agent. The
+	sequence can be divided into branches, and broken off by idle
+	periods or synchronisation. An event on the other hand describes
+	only one atomic action in this context.
+
+	\section installation Installation
+	There is no installation procedure for ODEMx, at least not in
+	this version. To use ODEMx in your projects you need to
+	build the library, include its header files in your project, and 
+	finally link your object files against the compiled library. 
+
+	As ODEMx uses many modern C++ components, it must be compiled with a
+	GCC version higher than 4.0 because starting with that version,
+	GCC includes the C++ standard library extensions from the
+	Technical Report 1, which adds new containers such as hash maps, 
+	tuples and arrays, as well as smart pointers and function object 
+	generators. All of these components are currently in use in ODEMx.
+
+	Building ODEMx on Windows operating systems requires MinGW
+	and MSYS to be installed. The current version of ODEMx does not 
+	support Visual Studio because there are several known bugs in the
+	implementation of the TR1 components. Even though the library and 
+	its dependencies have been successfully built with VS 2008 and
+	VS 2010, the resulting code did not run reliably.  
+	
+	\subsection	mingw_setup Setting up MinGW and MSYS
+	The procedure is fairly simple, as it only requires downloading
+	the minimal MinGW component set, plus the g++ compiler
+	(see http://mingw.org/wiki/Getting_Started). All of the downloaded 
+	archives are simply unzipped to the same directory of the user's choice.
+	After that,	the MinGW/bin path needs to be added to the Windows PATH
+	variable, and then gcc should be available from the command line.
+	MSYS provides a collection of GNU utilities such as bash, make and rm.
+	ODEMx itself does not require this, but the POCO libraries'
+	build system for MinGW depends on the execution of various
+	build scripts, besides make. MSYS can be set up by getting the
+	installer for version 1.0.11 (http://downloads.sourceforge.net/mingw/MSYS-1.0.11.exe) 
+	
+	\section firststeps First Steps
+	At first you will have to build ODEMx - see \ref installation for details.
+	Afterwards try the examples included. That should give you a good start.
+	Apart from that you can use them to check whether ODEMx is working properly on your
+	computer. \n
+
+	ODEMx includes an online documentation as well. You will need Doxygen
+	(http://www.doxygen.org) to generate the documentation from the source files.
+	To do so, change to \c odemx/Doxygen directory and run \c doxygen.
+
+	\section contributions Contributions
+	ODEMx is based on ODEM (http://odem.sf.net). That's why all contributors of
+	ODEM could be listed here, too. Instead only those who put their
+	hands on this code directly will be mentioned. Anyway, we encourage
+	you to take a look at ODEM and its contributors list as well.
+
+	\li Ralf Gerstenberger <gerstenb@users.sourceforge.net>
+	\li Ronald Kluth (since Version 2.0)
+	\li Toralf Niebuhr <niebuhr@niebuhrt.de> (since Version 2.0)
+	\li Magnus Mueller <evnu@users.sf.net> (since Version 3.0)
+
+	\section toc Table of Contents
+	<ol>
+	<li>\ref overview
+		<ol>
+		<li>\ref module_base</li>
+		<li>\ref module_coroutine</li>
+		<li>\ref module_data</li>
+		<li>\ref module_protocol</li>
+		<li>\ref module_random</li>
+		<li>\ref module_statistics</li>
+		<li>\ref module_synchronization</li>
+		<li>\ref module_test</li>
+		<li>\ref module_util</li>
+		</ol>
+	</li>
+	<li>\ref otoo
+	</li>
+	</ol>
+
+	\section copyright Copyright and License
+	ODEMx is protected by the GNU LESSER GENERAL PUBLIC LICENSE as
+	described in the file COPYING, which has to be present in
+	the ODEMx package; if not, write to the Free Software Foundation,
+	Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+
+*/
diff --git a/odemx-lite/Doxygen/namespaceOdemx.dox b/odemx-lite/Doxygen/namespaceOdemx.dox
new file mode 100644
index 0000000000000000000000000000000000000000..b3dc8581ca14af8f1dd3eed8f46699cc3973b7d0
--- /dev/null
+++ b/odemx-lite/Doxygen/namespaceOdemx.dox
@@ -0,0 +1,13 @@
+/**	\namespace odemx
+
+	\brief Main namespace for this project.
+
+	<!-- [detailed description] -->
+	All classes and types are members of this namespace.
+
+	<!-- [\todo {todos for this file}]* -->
+	\todo spell checking of comments and documentation
+	\todo finish documentation
+
+	\since 1.0
+*/
diff --git a/odemx-lite/Doxygen/odemToOdemx.dox b/odemx-lite/Doxygen/odemToOdemx.dox
new file mode 100644
index 0000000000000000000000000000000000000000..471d6f24b17de0f14a14344cd2427c1e43c10b90
--- /dev/null
+++ b/odemx-lite/Doxygen/odemToOdemx.dox
@@ -0,0 +1,691 @@
+/**
+\page otoo From ODEM to ODEMx
+In this chapter we describe differences between 
+ODEMx and its predecessor ODEM and features they have in common. \n
+
+<ol>
+<li>\ref oview
+</li>
+<li>\ref nfeatures
+</li>
+<li>\ref lfeatures
+</li>
+<li>\ref changes
+</li>
+</ol>
+
+\section oview Overview
+The following table lists all classes from ODEM and ODEMx and
+their status in ODEMx. This Table is not supposed to be
+a documentation for ODEMx. \n
+
+<table>
+<tr>
+<td><b>Class</b></td><td><b>Status</b></td>
+<td><b>Description</b></td><td><b>Comment</b></td>
+</tr>
+
+<tr>
+<td>Accumulate</td> <td>changed</td> <td>Statistics</td> <td>\ref stati1</td> 
+</tr>
+
+<tr>
+<td>Bin</td> <td>changed</td> <td>Ressource-like synchronisation</td> <td>\ref synchi1</td> 
+</tr>
+
+<tr>
+<td>BinObserver</td> <td>new</td> <td>Observer</td> <td>\ref observat1</td> 
+</tr>
+
+<tr>
+<td>Buff_head</td> <td>lost</td> <td>Buffered communication</td> <td>not transferred to ODEMx</td> 
+</tr>
+
+<tr>
+<td>Buff_tab</td> <td>lost</td> <td>Buffered communication</td> <td>not transferred to ODEMx</td> 
+</tr>
+
+<tr>
+<td>Buff_tail</td> <td>lost</td> <td>Buffered communication</td> <td>not transferred to ODEMx</td> 
+</tr>
+
+<tr>
+<td>CondQ</td> <td>changed</td> <td>Condition queue</td> <td>\ref synchi1</td> 
+</tr>
+
+<tr>
+<td>CondQObserver</td> <td>new</td> <td>Observer</td> <td>\ref observat1</td> 
+</tr>
+
+<tr>
+<td>Continuous</td> <td>changed</td> <td>Time-continuous process</td> <td>\ref continu1</td> 
+</tr>
+
+<tr>
+<td>ContinuousObserver</td> <td>new</td> <td>Observer</td> <td>\ref observat1</td> 
+</tr>
+
+<tr>
+<td>ContuTrace</td> <td>new</td> <td>Trace for Continuous</td> <td>\ref continu1</td> 
+</tr>
+
+<tr>
+<td>Coroutine</td> <td>new</td> <td>Portable coroutine implementation</td> <td>\ref corout1</td> 
+</tr>
+
+<tr>
+<td>CoroutineContext</td> <td>new</td> <td>Portable coroutine implementation</td> <td>\ref corout1</td> 
+</tr>
+
+<tr>
+<td>CoroutineContextObserver</td> <td>new</td> <td>Observer</td> <td>\ref observat1</td> 
+</tr>
+
+<tr>
+<td>CoroutineObserver</td> <td>new</td> <td>Observer</td> <td>\ref observat1</td> 
+</tr>
+
+<tr>
+<td>Count</td> <td>changed</td> <td>Statistic</td> <td>\ref stati1</td> 
+</tr>
+
+<tr>
+<td>DebugTrace</td> <td>lost</td> <td>Text-logfile</td> <td>replaced by HtmlTrace</td> 
+</tr>
+
+<tr>
+<td>DefaultContext</td> <td>new</td> <td>Portable coroutine implementation</td> <td>\ref corout1</td> 
+</tr>
+
+<tr>
+<td>DefaultOrder</td> <td>new</td> <td>Process sorting scheme</td> <td>\ref proque1</td> 
+</tr>
+
+<tr>
+<td>DefaultSimulation</td> <td>new</td> <td>Default implementation of Simulation</td> <td>\ref encaps1</td> 
+</tr>
+
+<tr>
+<td>DefaultTimeIO</td> <td>lost</td> <td>Time to string to time</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>DefLabeledObject</td> <td>new</td> <td>Object labels</td> <td>\ref label1</td> 
+</tr>
+
+<tr>
+<td>Discrete</td> <td>lost</td> <td>Time-discrete process</td> <td>replaced by Process</td> 
+</tr>
+
+<tr>
+<td>Dist</td> <td>changed</td> <td>Random number generator</td> <td>\ref randi1</td> 
+</tr>
+
+<tr>
+<td>DistContext</td> <td>new</td> <td>Random number generator</td> <td>\ref randi1</td> 
+</tr>
+
+<tr>
+<td>Draw</td> <td>changed</td> <td>Random number generator</td> <td>\ref randi1</td> 
+</tr>
+
+<tr>
+<td>dynTableDefinition</td> <td>new</td> <td>Report</td> <td>\ref report1</td> 
+</tr>
+
+<tr>
+<td>Elem</td> <td>lost</td> <td>ODEM-internal</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Empirical</td> <td>lost</td> <td>Random number generator</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Entity</td> <td>lost</td> <td>ODEM-internal</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Entry</td> <td>lost</td> <td>ODEM-internal</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Erlang</td> <td>changed</td> <td>Random number generator</td> <td>\ref randi1</td> 
+</tr>
+
+<tr>
+<td>Event</td> <td>lost</td> <td>ODEM-internal</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>ExecutionList</td> <td>new</td> <td>Process scheduling</td> <td>\ref proce2</td> 
+</tr>
+
+<tr>
+<td>ExecutionListObserver</td> <td>new</td> <td>Observer</td> <td>\ref observat1</td> 
+</tr>
+
+<tr>
+<td>File_list</td> <td>lost</td> <td>ODEM-internal</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>FormatedTimeInput</td> <td>lost</td> <td>String to time</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>FormatedTimeOutput</td> <td>lost</td> <td>Time to string</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Graph</td> <td>lost</td> <td>ODEM trace for Continuous</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Head</td> <td>lost</td> <td>ODEM-internal</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Histo</td> <td>changed</td> <td>Statistic</td> <td>\ref stati1</td> 
+</tr>
+
+<tr>
+<td>HtmlReport</td> <td>new</td> <td>Report</td> <td>\ref report1</td> 
+</tr>
+
+<tr>
+<td>HtmlTrace</td> <td>new</td> <td>Trace</td> <td>\ref trace1</td> 
+</tr>
+
+<tr>
+<td>Iconst</td> <td>changed</td> <td>Random number generator</td> <td>\ref randi1</td> 
+</tr>
+
+<tr>
+<td>Idist</td> <td>changed</td> <td>Random number generator</td> <td>\ref randi1</td> 
+</tr>
+
+<tr>
+<td>LabeledObject</td> <td>new</td> <td>Object labels</td> <td>\ref label1</td> 
+</tr>
+
+<tr>
+<td>LabelScope</td> <td>new</td> <td>Unique object labels</td> <td>label1</td> 
+</tr>
+
+<tr>
+<td>Link</td> <td>lost</td> <td>ODEM-internal</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>MarkType</td> <td>new</td> <td>Trace</td> <td>\ref trace1</td> 
+</tr>
+
+<tr>
+<td>Memo</td> <td>lost</td> <td>ODEM object linking</td> <td>replaced by \ref observat1</td> 
+</tr>
+
+<tr>
+<td>Msg</td> <td>lost</td> <td>Buffered communication</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Negexp</td> <td>changed</td> <td>Random number generator</td> <td>\ref randi1</td> 
+</tr>
+
+<tr>
+<td>Normal</td> <td>changed</td> <td>Random number generator</td> <td>\ref randi1</td> 
+</tr>
+
+<tr>
+<td>NoQueue</td> <td>lost</td> <td>ODEM-internal</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>NoTally</td> <td>lost</td> <td>ODEM-internal</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Observable</td> <td>new</td> <td>Observation of individual objects</td> <td>\ref observat1</td> 
+</tr>
+
+<tr>
+<td>Object_names</td> <td>lost</td> <td>Object labels</td> <td>replaced by LabeledObject</td> 
+</tr>
+
+<tr>
+<td>Odem</td> <td>lost</td> <td>ODEM-internal</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Poisson</td> <td>changed</td> <td>Random number generator</td> <td>\ref randi1</td> 
+</tr>
+
+<tr>
+<td>Port</td> <td>lost</td> <td>Port synchronisation</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Port_head</td> <td>lost</td> <td>Port synchronisation</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Port_tail</td> <td>lost</td> <td>Port synchronisation</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>PriorityOrder</td> <td>new</td> <td>Process sorting scheme</td> <td>\ref proque1</td> 
+</tr>
+
+<tr>
+<td>Process</td> <td>changed</td> <td>Process</td> <td>\ref proce2</td> 
+</tr>
+
+<tr>
+<td>Process_clock</td> <td>lost</td> <td>Time event</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>ProcessObserver</td> <td>new</td> <td>Observer</td> <td>\ref observat1</td> 
+</tr>
+
+<tr>
+<td>ProcessOrder</td> <td>new</td> <td>Process sorting scheme</td> <td>\ref proque1</td> 
+</tr>
+
+<tr>
+<td>ProcessQueue</td> <td>new</td> <td>Process list</td> <td>\ref proque1</td> 
+</tr>
+
+<tr>
+<td>Queue</td> <td>changed</td> <td>Process synchronisation queue</td> <td>\ref synchi1</td> 
+</tr>
+
+<tr>
+<td>Randint</td> <td>changed</td> <td>Random number generator</td> <td>\ref randi1</td> 
+</tr>
+
+<tr>
+<td>Rconst</td> <td>changed</td> <td>Random number generator</td> <td>\ref randi1</td> 
+</tr>
+
+<tr>
+<td>Rdist</td> <td>changed</td> <td>Random number generator</td> <td>\ref randi1</td> 
+</tr>
+
+<tr>
+<td>Regression</td> <td>changed</td> <td>Statistics</td> <td>\ref stati1</td> 
+</tr>
+
+<tr>
+<td>Report</td> <td>new</td> <td>Report</td> <td>\ref report1</td> 
+</tr>
+
+<tr>
+<td>ReportProducer</td> <td>new</td> <td>Report</td> <td>\ref report1</td> 
+</tr>
+
+<tr>
+<td>Reportq</td> <td>changed</td> <td>Report</td> <td>replaced by Report</td> 
+</tr>
+
+<tr>
+<td>Res</td> <td>changed</td> <td>Ressource-like synchronisation</td> <td>\ref synchi1</td> 
+</tr>
+
+<tr>
+<td>ResObserver</td> <td>new</td> <td>Observer</td> <td>\ref observat1</td> 
+</tr>
+
+<tr>
+<td>Resource</td> <td>lost</td> <td>Ressource-like synchronisation</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Sched</td> <td>lost</td> <td>Scheduling</td> <td>replaced by ExecutionList</td> 
+</tr>
+
+<tr>
+<td>ShortGermanTF1</td> <td>lost</td> <td>Time to string</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Simulation</td> <td>new</td> <td>Simulation</td> <td>\ref encaps1</td> 
+</tr>
+
+<tr>
+<td>SimulationObserver</td> <td>new</td> <td>Observer</td> <td>\ref observat1</td> 
+</tr>
+
+<tr>
+<td>Stackdir</td> <td>lost</td> <td>ODEM-internal</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Starter</td> <td>lost</td> <td>ODEM-internal</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>StatisticManager</td> <td>new</td> <td>Statistic</td> <td>\ref stati1</td> 
+</tr>
+
+<tr>
+<td>StatisticObject</td> <td>new</td> <td>Statistic</td> <td>\ref stati1</td> 
+</tr>
+
+<tr>
+<td>Sum</td> <td>changed</td> <td>Statistic</td> <td>\ref stati1</td> 
+</tr>
+
+<tr>
+<td>Tab</td> <td>changed</td> <td>Statistic</td> <td>\ref stati1</td> 
+</tr>
+
+<tr>
+<td>Table</td> <td>new</td> <td>Report data table</td> <td>\ref report1</td> 
+</tr>
+
+<tr>
+<td>TableDefinition</td> <td>new</td> <td>Report table structure</td> <td>\ref report1</td> 
+</tr>
+
+<tr>
+<td>Tag</td> <td>new</td> <td>Trace</td> <td>\ref trace1</td> 
+</tr>
+
+<tr>
+<td>Tally</td> <td>changed</td> <td>Statistic</td> <td>\ref stati1</td> 
+</tr>
+
+<tr>
+<td>Timer</td> <td>lost</td> <td>Time events</td> <td>not transferred</td> 
+</tr>
+
+<tr>
+<td>Trace</td> <td>changed</td> <td>Trace</td> <td>\ref trace1</td> 
+</tr>
+
+<tr>
+<td>TraceClient</td> <td>lost</td> <td>Trace</td> <td>replaced by TraceConsumer</td> 
+</tr>
+
+<tr>
+<td>TraceConsumer</td> <td>new</td> <td>Trace</td> <td>\ref trace1</td> 
+</tr>
+
+<tr>
+<td>TraceFilter</td> <td>new</td> <td>Trace</td> <td>\ref trace1</td> 
+</tr>
+
+<tr>
+<td>TraceProducer</td> <td>new</td> <td>Trace</td> <td>\ref trace1</td> 
+</tr>
+
+<tr>
+<td>TraceServer</td> <td>lost</td> <td>Trace</td> <td>replaced by Trace</td> 
+</tr>
+
+<tr>
+<td>TypedObject</td> <td>new</td> <td>C++ RTTI</td> <td>Interface to standard C++ RTTI</td> 
+</tr>
+
+<tr>
+<td>Unifrom</td> <td>changed</td> <td>Random number generator</td> <td>\ref randi1</td> 
+</tr>
+
+<tr>
+<td>utTableDef</td> <td>new</td> <td>Report</td> <td>\ref report1</td> 
+</tr>
+
+<tr>
+<td>Version</td> <td>new</td> <td>ODEMx version information</td> <td>no comment</td> 
+</tr>
+
+<tr>
+<td>Wait</td> <td>new</td> <td>Synchronization with child-processes</td> <td>\ref synchi1</td> 
+</tr>
+
+<tr>
+<td>WaitQ</td> <td>changed</td> <td>Master-Slave synchronisation</td> <td>\ref synchi1</td> 
+</tr>
+
+<tr>
+<td>WaitQObserver</td> <td>new</td> <td>Observer</td> <td>\ref observat1</td> 
+</tr>
+</tr>
+
+</table>
+
+
+\section nfeatures New features
+\subsection observat1 Observation
+ODEMx introduces a system for observing individual objects. Observable
+objects provide an interface with call-back-functions for the events of that
+object. Observers implement this interface to handle selected events. An
+observable object inherits an observer management from the template class Observable. Observable objects also have an optional
+constructor parameter, which allows to register an initial observer.
+\par Documentation:
+\li \ref odemx::data::Observable
+\li \ref odemx::base::ProcessObserver
+
+\subsection encaps1 Encapsulation
+In contrast to ODEM, ODEMx does encapsulate simulations. While in ODEM the main
+program is always made a part of the simulation, ODEMx separates the simulation
+from its environment. Simulation specific data and services are put into
+the class Simulation instead of being placed in the global scope. For many objects
+of ODEMx this requires a link to the Simulation class, which is in general
+handed over during construction. \n
+The separation is often realised by the introduction of context-objects.
+Simulation for instance is the context-object for processes. Due to multiple
+inheritance Simulation also serves as a context-object for other types of
+objects, like random number generators, labelled objects and trace producers. \n
+The advantage of the encapsulation is that a simulation can be programmed
+as an independent component without side-effects on its environment. It is
+for instance possible to run a simulation in a simulation.
+\par Documentation:
+\li \ref odemx::base::Simulation
+\li \ref odemx::base::Process
+
+\subsection corout1 Coroutines
+ODEMx separates the implementation of coroutines from the implementation of
+processes for process-simulation. ODEM on the other hand implements the 
+coroutine functionality inside its process implementation. The coroutine
+implementation of ODEMx is apart from a few concepts in the Utilities module
+independent from the rest of ODEMx. It is designed to be portable and already
+ported to Windows higher than Windows 95 (x86 architecture) as well as Unix and
+Linux (Sparc, and x86 architecture). Though in some compiler-os-platform
+configurations there could be problems. \n
+The techniques used to realise coroutines are based on ODEM which in turn has
+used previous works from HANSEN and others. ODEMx however introduces the
+encapsulation of coroutines in separate contexts.
+
+\subsection proque1 Process queue
+While in ODEM processes are itself designed to be part of a linked list, ODEMx
+uses STL containers to manage object collections. ProcessQueue is introduced
+in ODEMx to manage such collections. ProcessQueue allows different sorting
+schemes like considering the priority or the execution time of a process.
+Derived from ProcessQueue is the class Queue designed for synchronisation
+objects like Res, Bin, and WaitQ.
+
+
+\section lfeatures Lost features
+\subsection memo1 Memo
+In ODEM many classes include the functionality to be part of a linked list.
+The Memo concept of ODEM uses this property to provide a synchronisation
+technique. A Process object can genericWait in a Memo object until the Memo object
+is alerted or becomes 'available'. From Memo derived classes can override
+a function to redefine the 'available' condition. Process from ODEM for
+instance is also a Memo object which redefines 'available'. A Process in
+ODEM is 'available' if it is terminated. \n
+ODEMx does not include the Memo
+feature. But it is possible to realise Memo-like synchronisation with the
+\ref observat1 feature. The ODEMx class Wait in the module Synchronisation is
+an example for this.
+
+\subsection port1 Port
+In the HU-Release of ODEMx there is no concept for a buffered process-communication.
+A user will have to develop its own classes for this purpose. ODEM had such
+a concept in its Port mechanism.
+
+\subsection timioq Time translation
+In the later versions of ODEM a simtime to string to simtime translation
+was introduced to allow human readable time strings other than simple
+floating point numbers. This feature was introduced for a special application
+of ODEM. ODEMx has not yet such a feature, but is likely to get it in
+a future version.
+
+\subsection gl1 OpenGL visualisation
+ODEM had an experimental 3D visualisation of simulation events. Experiences
+from this 3D-project had lead to changes in the trace-mechanism which finally
+concluded the current Trace concept of ODEMx. A visualisation might be
+available in ODEMx in a future version. But the old 3D-Trace of ODEM is not
+transferable without a redesign.
+
+\subsection graph1 Continuous Graph
+ODEM provides the class Graph which logs Continuous state changes in a text
+format used by external visualisation tools. A similar tool is already
+present in ODEMx (\ref odemx::base::ContuTrace). But at the moment there is no
+component in ODEMx that generates output in the exact text-format like Graph.
+
+\subsection buffer1 Buffer
+Like the missing \ref port1 mechanism the simplified Buffer system is not
+transferred to ODEMx.
+
+\subsection empiri1 Empirical
+Empirical from ODEM is not available in ODEMx. 
+
+
+\section changes Changes
+\subsection synchi1 Synchronisation
+ODEMx provides the following synchronisation components: \ref odemx::synchronization::Res,
+\ref odemx::synchronization::Bin, \ref odemx::synchronization::WaitQ, \ref
+odemx::synchronization::CondQ and 
+\ref odemx::synchronization::Wait.
+The first four components are transferred from ODEM but are changed.
+Res and Bin for instance are not derived from a common base class Resource.
+The constructors of both classes have additional parameters compared to
+Res and Bin from ODEM which reflect the \ref encaps1 and the \ref observat1
+feature. Both classes have more get* methods to receive information about
+the statistic. Both classes have a report function according to the \ref report1
+changes. The basic synchronisation functions however are not changed. \n
+Similar things can be said about WaitQ and CondQ. The general meaning has not
+changed while the classes have been adjusted to reflect the ODEMx features.
+In WaitQ and CondQ however, small changes have been applied to the classic
+synchronisation functions as well.
+\par Documentation:
+\li \ref odemx::synchronization::Res
+\li \ref odemx::synchronization::Bin
+\li \ref odemx::synchronization::WaitQ
+\li \ref odemx::synchronization::CondQ
+
+\subsection stati1 Statistics
+Many of the statistic components from ODEM have been transferred to ODEMx.
+The components in ODEMx share the update() function with their predecessors
+as well as the used algorithms. They 
+were also changed to match the \ref encaps1 and the \ref report1
+feature. Furthermore, several get* methods for
+the statistical data were added.
+\par Documentation:
+\li \ref odemx::statistics::Accumulate
+\li \ref odemx::statistics::Count
+\li \ref odemx::statistics::Histogram
+\li \ref odemx::statistics::Regression
+\li \ref odemx::statistics::Sum
+\li \ref odemx::statistics::Tally
+
+\subsection randi1 Random
+The random number generators in ODEMx were taken from ODEM and changed
+to match the features of ODEMx. They have additional get* methods for
+statistical information, and require a pointer to a DistContext
+object during construction. They also provide a report function for the
+report feature of ODEMx. \n
+The DistContext class was introduced to support the \ref encaps1 feature.
+All random number generators linked to one DistContext are
+independent from each other, while the RNGs in different DistContext
+produce the same sequence of numbers (unless the seed is changed).
+\par Documentation:
+\li \ref odemx::statistics::Accumulate
+\li \ref odemx::statistics::Count
+\li \ref odemx::statistics::Histogram
+\li \ref odemx::statistics::Regression
+\li \ref odemx::statistics::Sum
+\li \ref odemx::statistics::Tally
+
+\subsection proce2 Process
+The Process class of ODEMx replaces the Process class and the Discrete
+class of ODEM. Its interface is more like the interface of Discrete
+than of Process. The following table matches the different scheduling
+functions of Discrete to the functions of ODEMx Process: \n
+
+<table>
+<tr><td><b>Discrete</b></td>			<td><b>odemx::base::Process</b></td></tr>
+<tr><td>start(NOW)</td>					<td>hold()</td></tr>
+<tr><td>start(AT, t)</td>				<td>holdUntil(t)</td></tr>
+<tr><td>start(AT, t, PRIOR)</td>		<td>activateAt(t)</td></tr>
+<tr><td>start(DELAY, t)</td>			<td>holdFor(t)</td></tr>
+<tr><td>start(DELAY, t, PRIOR)</td>		<td>activateIn(t)</td></tr>
+<tr><td>activate(NOW)</td>				<td>hold() or activate() (FIFO or LIFO)</td></tr>
+<tr><td>activate(AT, t)</td>			<td>holdUntil(t)</td></tr>
+<tr><td>activate(AT, t, PRIOR)</td>		<td>activateAt(t)</td></tr>
+<tr><td>activate(DELAY, t)</td>			<td>holdFor(t)</td></tr>
+<tr><td>activate(DELAY, t, PRIOR)</td>	<td>activateIn(t)</td></tr>
+<tr><td>activate(BEFORE, q)</td>		<td>activateBefore(q)</td></tr>
+<tr><td>activate(AFTER, q)</td>			<td>activateAfter(q)</td></tr>
+<tr><td>hold(t)</td>					<td>holdFor(t)</td></tr>
+<tr><td>passivate()</td>				<td>sleep()</td></tr>
+<tr><td>e_interrupt()</td>				<td>interrupt() (!see documentation!)</td></tr>
+<tr><td>cancel()</td>					<td>cancel()</td></tr>
+</table> \n
+ODEMx Process has only one priority attribute which is used in scheduling
+as well as in synchronisation queues. The \c interrupt function in ODEMx has
+a different effect than the \c e_interrupt of Discrete. In ODEMx an interrupt
+causes an immediate activation (activate). The interrupted process is
+responsible to handle the interrupt.
+\par Documentation:
+\li \ref odemx::base::Process
+
+\subsection continu1 Continuous
+The Continuous class of ODEMx is derived from Process. The algorithm used
+to compute the state changes is taken from ODEM. Some of the Continuous
+functions in ODEM are also transferred to ODEMx. Other than the ODEM version
+of Continuous, the ODEMx version does not log the state changes on its own.
+If a user wants this service he/she has to use the ODEMx class ContuTrace.
+\par Documentation:
+\li \ref odemx::base::Continuous
+\li \ref odemx::base::ContuTrace
+
+\subsection label1 Object labels
+The support of object labels has changed in ODEMx. It is now provided
+by the classes \ref odemx::LabeledObject, \ref odemx::LabelScope and
+\ref odemx::DefLabeledObject. In contrast to ODEM labels are no longer
+unique to the program but to a certain LabelScope. Each simulation has
+of course its own scope.
+\par Documentation:
+\li \ref odemx::LabeledObject
+\li \ref odemx::LabelScope
+\li \ref odemx::DefLabeledObject
+
+\subsection trace1 Trace
+\warning 
+The current implementation (as of Mi 16. Mär 15:54:28 CET 2011) differs from
+    the following description. An example on the default trace functionality is given in Example_Shop.cpp
+        
+
+\p
+ODEMx introduces the class HtmlTrace. Objects of this class generate Html
+output from simulation events. HtmlTrace also provides a simple filter
+for events to reduce the generated output. The trace control_ is implemented
+in the ODEMx Trace class which is a base class of Simulation.
+\par Documentation:
+\li \ref odemx::HtmlTrace
+
+\subsection report1 Report
+ODEMx supports several reports in one simulation. A report is generated by
+an object of the HtmlReport class. In contrast to ODEM a user has to register
+model components to the report. The final report is triggered manually by the function call
+'generateReport()'. 
+\par Documentation:
+\li \ref odemx::HtmlReport
+
+
+*/
diff --git a/odemx-lite/Doxygen/odemxOverview.dox b/odemx-lite/Doxygen/odemxOverview.dox
new file mode 100644
index 0000000000000000000000000000000000000000..e5c47c9fd7dc5b716fb0ccce53c084fa7bbe0d12
--- /dev/null
+++ b/odemx-lite/Doxygen/odemxOverview.dox
@@ -0,0 +1,262 @@
+/**
+
+\page overview ODEMx - An Overview of the Library.
+
+This page describes the following topics:
+<ul>
+	<li>\ref structure</li>
+	<li>\ref module_base</li>
+	<li>\ref module_coroutine</li>
+	<li>\ref module_data</li>
+	<li>\ref module_protocol</li>
+	<li>\ref module_random</li>
+	<li>\ref module_statistics</li>
+	<li>\ref module_synchronization</li>
+	<li>\ref module_test</li>
+	<li>\ref module_util</li>
+</ul>
+
+\section structure Library Structure
+On this page we give an overview of the structure of ODEMx and its primary
+simulation components.
+ODEMx is divided into the modules \ref base, \ref coroutine, \ref data,
+\ref protocol, \ref random, \ref statistics, \ref synch, \b Test,
+and \ref util. All modules depend on the modules Data and Utilities.
+The following sections describe the concepts implemented by each module.
+
+\section module_base Base Components
+The \ref base module contains the core of the simulation building blocks, such
+as the simulation context (including a default implementation), base classes
+for events and processes, as well as the scheduler with its execution list.
+Besides time-discrete processes, ODEMx also provides support for time-continuous
+processes on the basis of ordinary differential equations. 
+
+Every simulation with ODEMx requires an implementation of the abstract base
+class odemx::base::Simulation. This class provides a context for all the
+other model components like processes, events, synchronization classes,
+and random number generators. In user-defined simulation classes the method
+@c initSimulation must be implemented in order to create and initialize model
+components.
+
+For convenience ODEMx also provides the class \c DefaultSimulation with an empty
+implementation of @c initSimulation. If the user does not want to define a 
+specific simulation class, this default implementation can be used. A reference
+to a static object of this class is returned by the free function 
+odemx::getDefaultSimulation. However, this requires that all simulation 
+components are initialized globally, or from within the @c main function of the
+simulation program. ODEMx allows at most one DefaultSimulation-object per program.
+If users define their own simulation classes, several simulation contexts can
+be used within the same program. This includes simulations inside 
+of simulations as well as the parallel (interleaved) execution of simulations.
+
+The base class for all simple simulations events is odemx::base::Event. 
+Events typically describe exactly one action that happens during the
+simulation run. Each different event type must be implemented as a 
+specialization of this class, which usually only requires the definition
+of the method \c eventAction. Events may reschedule themselves in order to
+model recurring atomic actions in a system.
+
+The class odemx::base::Process serves as base class for all user-defined classes modeling 
+discrete processes. Each different type of process in a system model requires 
+the specification of a new process class. This class has to define the behavior
+(the sequence of actions, synchronizations and idle periods) of its objects as
+an implementation of the method @c main.
+While process classes are not necessarily associated with specific simulation
+classes, every process object must be linked to only one simulation context.
+Thus, the constructor of class Process requires a reference to a simulation
+object.
+
+The class odemx::base::Continuous is the base class
+for continuous processes. Continuous itself is derived from Process, but
+provides additional functions to define time-continuous behavior. This kind
+of behavior can only be approximated by ODEMx by using a stepwise computation
+of state changes, which of course introduces an inherent error rate. 
+ODEMx is observing these error values to stay within defined boundaries.
+In addition to its implementation of @c main, user-defined time-continuous processes 
+must also provide an implementation of the method @c derivatives. In this
+method the continuous state changes are coded by setting the change rates
+for each state variable. A continuous computation phase is started in @c main
+by calling the method @c integrate (which internally uses @c derivatives).
+The output of continuous processes can be recorded by an object of type 
+odemx::base::ContuTrace, which observes valid state changes and logs the 
+computed values of each valid step to a text file. An object of type ContuTrace
+is always linked to exactly one object of type Continuous.
+
+\section module_coroutine Coroutine Implementation
+The module \ref coroutine provides a platform-independent implementation of
+coroutines, which are essentially functions whose execution can be stopped and
+resumed at predefined points. This mechanism allows the modeling of 
+pseudo-parallel function execution through coroutine switches, thereby
+changing the execution context between several different coroutines in a 
+sequentialized and deterministic manner. This concept is used for modeling 
+ODEMx processes, whose logically parallel execution must be sequentialized, by 
+implementing their lifetime and behavior on the basis of coroutines. The 
+difference to threads is that coroutines are generally lighter constructs than
+threads, and that their execution order is always deterministic and reproducible.   
+
+The class odemx::coroutine::Coroutine is based on the Windows Fiber API. On POSIX
+platforms, the functionality of fibers is emulated and implemented on top of the
+user context and its related functions, which also allows context switching in
+a deterministic manner. This implementation assigns each coroutine its own 
+runtime stack, which may consume a lot of memory when simulations contain many 
+processes. Therefore, ODEMx also
+retains support for the legacy implementation of coroutines, which is based
+on copying and replacing only the relevant part of the program's runtime stack
+using the functions
+@c setjmp and @c longjmp. While this method offers the advantage of a smaller
+memory footprint, it has the drawback that processes cannot exchange addresses
+of stack-allocated objects because these are simply not available at the 
+expected address after a context switch.
+
+\section module_data Data Collection, Storage, and Display 
+Module \ref data combines all classes that deal with the computation, collection,
+storage, and display of simulation data. Three different concepts
+are employed for the collection of simulation data:
+@li Logging
+@li Report
+@li Observation.
+
+@b Logging is provided by the external library CppLog. This concept is employed 
+to collect detailed data about state changes in the system model. Logging 
+components play one of three roles: source, channel, and sink. 
+Channels represent different logging
+categories such as trace, debug, or statistics. ODEMx data sources are represented
+by the class odemx::data::Producer, which is used as base class for nearly all
+ODEMx model elements. Logging sinks are classes that implement a record-consumer
+interface. ODEMx provides sinks that write simple text or XML, and it can also
+store records in a database. Supported database management systems (DBMS) are 
+SQLite, which is embedded in ODEMx, and external DBMSs, which support access 
+via ODBC.  
+
+@b Report is a concept that allows the display of accumulated data in tables. 
+Report-producing classes implement the interface odemx::data::ReportProducer
+to be accessed upon report
+generation (either simple text or XML format). Currently, the report concept
+is used by statistics-computing classes only. These components collect their
+data internally and compute statistical characteristics. All relevant information
+such as component name, parameters, reset time, and the computed values is fed
+to predefined tables, which are then arranged for display by an implementation
+of the base class odemx::data::Report.  
+
+@b Observation is a concept that focuses on the observation of the state 
+changes of specific objects.
+There are two roles: observer and observable. One observable object may have
+multiple observers. Observable classes must be derived from the class template
+odemx::data::Observable and additionally provide an @c Observer interface,
+which must be implemented by specific observer classes in order to be able
+to receive notifications. When certain state changes occur, all registered 
+observers of an observable object are notified via calls to the interface.
+
+\section module_protocol Communication Protocol Simulation
+The module \ref protocol contains higher level modeling classes for simulating
+communication networks. Conceptually, networks are modeled as collections of
+interconnected nodes, each of which owns one or more network interfaces for
+communicating with connected peers. There is no base class for nodes, as these
+can be of arbitrary structure. ODEMx merely requires that one or several 
+transmission media manage a network topology of registered network interfaces.
+Links between these interfaces are set via the method @c Medium::addLink. It
+is also possible to dynamically remove links during a simulation run.
+For convenience, simple communication services can also be realized without
+specifying a network topology. In this case, each network node only needs 
+to use its own Service object (derived from class odemx::protocol::Service),
+which implements the network topology as direct connections between all 
+registered nodes.
+
+More advanced communication models usually employ a protocol stack (as
+provided by the class odemx::protocol::Stack), which is typically comprised 
+of several protocol layers, each offering one or several different protocol
+services. Access to services is provided through asynchronous interfaces, 
+so-called service access points (SAP, modeled by class odemx::protocol::Sap).
+The service functionality is always implemented by subclasses of 
+odemx::protocol::ServiceProvider. This base class is the foundation for more
+specific implementations such as Service, Entity, and Device. Service
+providers are the active components in protocol simulations and are therefore
+derived from class Process. Their behavior is implemented as waiting period for
+input on one of their SAPs. Users must define what is to be done when one
+of these input queues contains data.
+
+When using a stack as communication interface of network nodes, it is 
+possible to create simulation models that include the physical layer. This 
+requires the definition of network interfaces by subclassing 
+odemx::protocol::Device, and the use of one or several transmission media
+representing cables or radio waves. However, it is also possible to abstract
+from the network topology by simply using a Service implementation in the
+lowest layer of the stack. Transmission errors can be modeled by implementing
+the interface odemx::protocol::ErrorModel. Instances of such classes can then
+be registered globally with Service implementations or a Medium object. In the
+latter case, it is also possible to assign each link between two nodes its own
+error model.
+
+\section module_random Random Number Generation 
+The \ref random module is a collection of random number generators (RNGs),
+which can be used for statistical simulations. Various discrete and continuous
+distributions can be generated by these classes. Examples are Poisson, uniform,
+or negative exponential distribution. All RNGs provide a method @c sample, 
+which returns the next random number. The parameters for each generator are set
+in the constructor.
+
+\section module_statistics Statistics Computation
+Module \ref statistics contains classes for statistical analyses. The provided
+components are able to compute various statistical characteristics such as
+min, max, mean and the standard deviation. There are also classes for creating
+histograms and linear correlation analyses.    
+
+\section module_synchronization Process Synchronization
+An important part of process simulations is the synchronization of different
+processes with certain situations during a simulation. The module 
+\ref synchronization is a collection of classes which implement
+model components for various synchronization tasks. 
+
+There are two resource-type classes: odemx::sync::Bin and odemx::sync::Res.
+Both classes are used to model resource-like synchronization. A process is
+blocked if the resource is exhausted. Otherwise it continous its actions by
+acquiring resources. Bin and Res use token counters to simulate real resources.
+There are also template-implementations of these classes, which use actual
+token objects of the type provided as template argument.
+
+Furthermore, the classes odemx::sync::WaitQ and odemx::sync::CondQ provide
+queue-like synchronisation components. The WaitQ provides a 
+master-slave-synchronisation (MSS). MSS is a synchronisation between two
+processes. One of them (the master) takes control_ of the other (the slave)
+after a successful synchronization. The slave is delivered to the master
+according to different schemes. It can simply be the first process in the 
+waiting queue, but it can also be chosen according to the criteria of a 
+selection function, or a weight function provided by the queued master.
+An odemx::sync::CondQ is used to wait for an arbitrary condition. A process
+provides a function which implements the condition check. The condition is 
+checked every time any process object signals a CondQ object. The user is
+responsible to call @c signal on a CondQ when the relevant situation changes 
+occur in the system model.
+
+Additionally, the synchronization module contains classes for the implementation of
+a wait-alert concept. The concept's core component is the interface @c IMemory,
+which is intended to store pointers to waiting processes in order to alert them 
+at a later point in simulation time. To use the concept, processes call the 
+method @c genericWait with a number of IMemory objects. As soon as one of them becomes
+available and calls @c alert, the process is rescheduled for immediate 
+execution. As soon as it continues its execution, the process can check its
+alerter and determine the appropriate action. There are several IMemory 
+implementations available. The default implementation is the class Memory,
+which provides the storage of Process pointers and the means to alert waiting
+processes. Other classes are odemx::sync::Timer, which uses a Memory member
+to implement its functionality, and the class templates PortHeadT and PortTailT,
+which subclass Memory to use its functionality. The latter port construct models
+a limited buffer with separate input(tail) and output(head) interfaces.
+
+Finally, the class Wait is an observer example implementation that synchronizes
+a process with a set of partner processes. The process that creates the Wait
+object is blocked until one or all of its partner processes are terminated.
+
+\section module_test Unit Tests
+The test module contains unit tests for all ODEMx components. To allow for
+quick and easy test suite creation and execution of all tests, the external
+library UnitTest++ is used. It has been integrated in ODEMx and provides
+an easy-to-use interface for the creation of new test cases and test suites.
+The test module contains its own documentation in odemx/test/Doc.
+
+\section module_util Utilities
+This module contains utility classes and functions to simplify the implementation
+of other ODEMx components. This involves memory mangement, string conversions,
+and sorting. These components are usually not used directly.
+
+*/
diff --git a/odemx-lite/Makefile b/odemx-lite/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1b167d3d991fde2cd4a6ba53671c8baa6f141b0b
--- /dev/null
+++ b/odemx-lite/Makefile
@@ -0,0 +1,104 @@
+OBJS = \
+./src/base/Comparators.o \
+./src/base/Continuous.o \
+./src/base/DefaultSimulation.o \
+./src/base/Event.o \
+./src/base/ExecutionList.o \
+./src/base/Process.o \
+./src/base/Sched.o \
+./src/base/Scheduler.o \
+./src/base/Simulation.o \
+./src/base/continuous/Continuous.o \
+./src/base/continuous/DfDt.o \
+./src/base/continuous/JacobiMatrix.o \
+./src/base/continuous/Monitor.o \
+./src/base/continuous/ODEObject.o \
+./src/base/continuous/ODESolver.o \
+./src/base/continuous/Rate.o \
+./src/base/continuous/State.o \
+./src/base/continuous/StateEvent.o \
+./src/base/continuous/VariableContainer.o \
+./src/base/control/ControlBase.o \
+./src/coroutine/Coroutine.o \
+./src/coroutine/CoroutineContext.o \
+./src/coroutine/ucFiber.o \
+./src/data/buffer/SimRecordBuffer.o \
+./src/data/buffer/StatisticsBuffer.o \
+./src/data/LoggingManager.o \
+./src/data/ManagedChannels.o \
+./src/data/output/ErrorWriter.o \
+./src/data/output/GermanTime.o \
+./src/data/output/Iso8601Time.o \
+./src/data/output/OStreamReport.o \
+./src/data/output/OStreamWriter.o \
+./src/data/output/TimeFormat.o \
+./src/data/Producer.o \
+./src/data/Report.o \
+./src/data/ReportProducer.o \
+./src/data/ReportTable.o \
+./src/data/SimRecord.o \
+./src/data/SimRecordFilter.o \
+./src/protocol/Device.o \
+./src/protocol/Entity.o \
+./src/protocol/ErrorModelDraw.o \
+./src/protocol/Layer.o \
+./src/protocol/Medium.o \
+./src/protocol/Sap.o \
+./src/protocol/Service.o \
+./src/protocol/ServiceProvider.o \
+./src/protocol/Stack.o \
+./src/random/ContinuousConst.o \
+./src/random/ContinuousDist.o \
+./src/random/DiscreteConst.o \
+./src/random/DiscreteDist.o \
+./src/random/Dist.o \
+./src/random/DistContext.o \
+./src/random/Draw.o \
+./src/random/Erlang.o \
+./src/random/NegativeExponential.o \
+./src/random/Normal.o \
+./src/random/Poisson.o \
+./src/random/RandomInt.o \
+./src/random/Uniform.o \
+./src/statistics/Accumulate.o \
+./src/statistics/Count.o \
+./src/statistics/Histogram.o \
+./src/statistics/Regression.o \
+./src/statistics/Sum.o \
+./src/statistics/Tab.o \
+./src/statistics/Tally.o \
+./src/synchronization/Bin.o \
+./src/synchronization/CondQ.o \
+./src/synchronization/IMemory.o \
+./src/synchronization/Memory.o \
+./src/synchronization/ProcessQueue.o \
+./src/synchronization/Queue.o \
+./src/synchronization/Res.o \
+./src/synchronization/Timer.o \
+./src/synchronization/Wait.o \
+./src/synchronization/WaitQ.o
+
+ifeq ($(OS),Windows_NT)
+	EXT = .exe
+else
+	EXT = .out
+endif
+
+CXXFLAGS = -g -std=c++11 -Iinclude -Iexternal/CppLog/include
+ODEMXLIB = lib/libOdemxD.a
+INCLUDES = ./include ./external/CppLog/include
+EXAMPLES = $(wildcard ./examples/*.cpp)
+BINARIES = $(EXAMPLES:%.cpp=%$(EXT))
+
+$(ODEMXLIB): $(OBJS)
+	ar cr $@ $^
+
+%$(EXT): %.o
+	$(CXX) $< $(ODEMXLIB) -o $@
+
+all: $(ODEMXLIB)
+
+samples: $(BINARIES)
+
+clean:
+	rm -f $(OBJS) $(ODEMXLIB) $(BINARIES)
diff --git a/odemx-lite/README b/odemx-lite/README
new file mode 100644
index 0000000000000000000000000000000000000000..d8fb7940e2fb0fcdefe93af6186b56ed38b25ec9
--- /dev/null
+++ b/odemx-lite/README
@@ -0,0 +1,92 @@
+################################################################
+#                                                              #
+#                                                              #
+#      OO  DDDD    EEEE   M M                                  #
+#    O   O D   D   E     M M M   X X                           #
+#   O    O D    D EEEE  M  M  M   X                            #
+#   O  @ O D @  D E     M     M  X X                           #
+#    OOOO   DDDD  EEEEE M     M X   X                          #
+#                                                              #
+#    ODEMx  version 3.0                                        # 
+#   --------------------                                       #
+#                                                              #
+#    Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009    #
+#                       Humboldt-Universität zu Berlin and     #
+#                       Ralf Gerstenberger and                 #
+#                       Ronald Kluth                           #
+#                                                              #
+################################################################
+
+  Welcome
+ ---------
+ Welcome to ODEMx. ODEMx is a C++ library for discrete event simulation.
+
+
+  About ODEMx
+ -------------
+ODEMx is a library for discrete event simulation, which is a 
+branch of computer simulation. It supports process-based and event-
+based simulation models. As such it uses processes and/or events to
+model real-world or fictional systems. A process in this context
+is a continuous or discrete sequence of actions which are somehow
+closely related to each	other, for instance they are all 'done' by
+one agent. The sequence can be divided into branches, and broken
+off by idle periods or synchronisation. Events in this context simply
+describe one action in a system that can take place at any time during
+a simulation. 
+
+
+  Copyright and License
+ -----------------------
+ODEMx is protected by the GNU LESSER GENERAL PUBLIC LICENSE as
+described in the file Copying.txt, which should be present in 
+the ODEMx package; if not, write to the Free Software Foundation,
+Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+
+The examples in examples/omsi are released under the GNU GENERAL 
+PUBLIC LICENSE, Version 2.
+
+  Installation
+ --------------
+For a precise description on how to build ODEMx for your plattform,
+please read the file BUILDING.
+
+There is no installation procedure for ODEMx, at least not in
+this version. To use ODEMx in your projects choose the respective
+folder that fits your needs best (Gcc on Unix and Linux systems, Msvc 
+or Msvc7.1 on windows), build the library and finally set-up your 
+project to use the library.
+
+Note:
+If you are using GCC we recommend to use a version higher than 3.x.x.
+
+Always take care to activate RTTI in your projects, because ODEMx
+depends on this feature. (MSVC and MSCVC7.1 disable RTTI by default)
+ 
+
+  First Steps
+ -------------
+At first you will have to build ODEMx - see Installation for details.
+Afterwards try the examples included. That should give you a good start.
+Apart from that you can use them to check whether ODEMx is working properly
+on your computer.
+
+ODEMx includes an online documentation as well. You will need Doxygen
+(http://www.doxygen.org) to generate the documentation from the source files.
+To do so, go to your build directory and run "make doxygen". This will
+build the doxygen documentation and put it into $BUILDIR/doc/html .
+
+
+  Contributions
+ ---------------
+ODEMx is based on ODEM (http://odem.sf.net). That's why all contributors of 
+ODEM could be listed here, too. Instead only those who put their
+hands on this code directly will be mentioned. Anyway, we encourage
+you to take a look at ODEM and its contributors list as well.
+ 
+Ralf Gerstenberger (gerstenb@users.sourceforge.net)
+Ronald Kluth
+Toralf Niebuhr
+Magnus Müller
+
+EOF
diff --git a/odemx-lite/examples/Example_BinT.cpp b/odemx-lite/examples/Example_BinT.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..407deb6798c62234940bc3f4dfd06a6431b78071
--- /dev/null
+++ b/odemx-lite/examples/Example_BinT.cpp
@@ -0,0 +1,228 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_BinT.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/04/24
+ * @brief Example displaying the basic usage of an unlimited resource with a
+ * user-defined token type (odemx::synchronization::BinT)
+ * @since 3.0
+ */
+
+/**
+ * @example Example_BinT.cpp
+ * The basic usage of an unlimited resource is introduced.
+ *
+ * There are two processes involved in this simulation. One takes the role of
+ * a producer of a certain type of items, while the other takes the role of a
+ * consumer of such items. These two are linked by a temporary storage space,
+ * i.e. an unlimited resource, where the producer puts new items, which will
+ * eventually be used by the consumer.
+ */
+
+#include <odemx/odemx.h>
+using odemx::base::Process;
+using odemx::base::Simulation;
+using odemx::data::output::OStreamWriter;
+using odemx::toString;
+
+#include <iostream>
+#include <string>
+#include <vector>
+#ifdef _MSC_VER
+#include <memory>
+#else
+#include <memory>
+#endif
+
+
+// forward declaration
+odemx::base::SimTime getRandomTime( odemx::random::ContinuousDist& dist );
+
+//-----------------------------------------------------------------------globals
+//
+// We use two random number generators to model the time it takes to produce
+// or consume items.
+//
+odemx::random::Normal productionPeriod( odemx::getDefaultSimulation(),
+		"Production Period", 10, 2 );
+odemx::random::Normal consumptionPeriod( odemx::getDefaultSimulation(),
+		"Consumption Period", 3, 2 );
+
+//--------------------------------------------------------------------------Item
+//
+// The struct Item is just a simple type holding the name of some item. It is
+// used as token type for the BinT class template.
+//
+struct Item
+{
+	Item( const std::string& name ): name( name ) {}
+	std::string name;
+};
+
+//-------------------------------------------------------------------ItemStorage
+//
+// The storage space is simply an instantiation of BinT with Item as its token
+// type. We will use it to have the consumer wait for new items to be produced.
+// BinT handles this transparently by keeping the consumer in a queue while
+// there are not enough items in storage. All the consumer has to do is request
+// a number of items. It will be awakened as soon as these become available.
+//
+typedef odemx::synchronization::BinT< Item > ItemStorage;
+
+//------------------------------------------------------------------ItemProducer
+//
+// The producer process creates new named items and puts them into the storage.
+//
+class ItemProducer: public Process
+{
+public:
+	ItemProducer( ItemStorage& storage )
+	:	Process( odemx::getDefaultSimulation(), "The Producer" )
+	,	storage_( &storage )
+	{}
+
+protected:
+	virtual int main()
+	{
+		static std::size_t itemCount = 0;
+		while( true )
+		{
+			//
+			// Wait for as long as production requires.
+			//
+			holdFor( getRandomTime( productionPeriod ) );
+			//
+			// Fill a vector with newly created items.
+			//
+			std::vector< Item > newItems;
+			for( int i = 5; i > 0; --i )
+			{
+				newItems.push_back(
+						Item( std::string("Item ") + toString( ++itemCount ) ) );
+			}
+			//
+			// Add items to the storage bin.
+			//
+			storage_->give( newItems );
+			//
+			// Log production of new items
+			//
+			info << log( "produced 5 new items" );
+		}
+		return 0;
+	}
+
+private:
+	ItemStorage* storage_;
+};
+
+//------------------------------------------------------------------ItemConsumer
+//
+// The consumer process simply waits for items to arrive at the temporary item
+// storage. When the requested number of items are available, they are taken
+// from the storage and the consumer logs their names upon use.
+//
+class ItemConsumer: public Process
+{
+public:
+	ItemConsumer( ItemStorage& storage )
+	:	Process( odemx::getDefaultSimulation(), "The Consumer" )
+	,	storage_( &storage )
+	{}
+
+protected:
+	virtual int main()
+	{
+		while( true )
+		{
+			//
+			// By calling take on the BinT object, the consumer enters a queue
+			// and waits until the requested amount of tokens becomes available.
+			// It receives them in a vector.
+			//
+			std::unique_ptr< std::vector< Item > > newItems = storage_->take( 2 );
+			//
+			// Consumption of the two items is logged to the info channel.
+			//
+			info << log( "consumed 2 items" )
+					.detail( "first", newItems->front().name )
+					.detail( "second", newItems->back().name );
+			//
+			// Wait for as long as it takes to consume items.
+			//
+			holdFor( getRandomTime( consumptionPeriod ) );
+		}
+		return 0;
+	}
+
+private:
+	ItemStorage* storage_;
+};
+
+//--------------------------------------------------------------------------main
+
+int main( int argc, char* argv[] )
+{
+	using namespace odemx;
+	//
+	// Since we are using subclasses of Process without providing a simulation
+	// context, we also have to use the implicitly assumed DefaultSimulation
+	// here.
+	//
+	Simulation& sim = getDefaultSimulation();
+	//
+	// Since we are logging data to the info channel, we must set a data
+	// consumer. Here, we use a simple writer to std::cout.
+	//
+	sim.addConsumer( data::channel_id::info, OStreamWriter::create( std::cout ) );
+	//
+	// Initialize item storage as well as producer and consumer processes.
+	//
+	ItemStorage tempStorage( sim, "Temporary Storage" );
+	ItemProducer producer( tempStorage );
+	ItemConsumer consumer( tempStorage );
+	//
+	// Schedule the processes for immediate execution at SimTime 0.
+	//
+	producer.activate();
+	consumer.activate();
+	//
+	// Run the simulation with a time limit. Otherwise, both processes would
+	// run forever and the simulation would never stop.
+	//
+	sim.runUntil( 45 );
+	return 0;
+}
+//
+// Since random number generators sometimes also generate negative values,
+// we cannot simply use samples as time values. This helper function ensures
+// that only values greater than or equal to zero are returned.
+//
+odemx::base::SimTime getRandomTime( odemx::random::ContinuousDist& dist )
+{
+	odemx::base::SimTime retVal;
+	do
+	{
+		retVal = (odemx::base::SimTime) dist.sample();
+	}
+	while( retVal <= 0 );
+
+	return retVal;
+}
diff --git a/odemx-lite/examples/Example_Connection.cpp b/odemx-lite/examples/Example_Connection.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fb625334ae065b966a6be5541eb1e84aaef55c42
--- /dev/null
+++ b/odemx-lite/examples/Example_Connection.cpp
@@ -0,0 +1,142 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_Connection.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/03/16
+ * @brief Example displaying the basic usage of a user-defined coroutine class
+ * @since 3.0
+ */
+
+/**
+ * @example Example_Connection.cpp
+ * The basic usage of a coroutine implementation is demonstrated
+ *
+ * This example demonstrates how protocol connections can be modeled
+ * in ODEMx as separate coroutines. For this example, we use a very simple
+ * message class that can only report its type.
+ *
+ * Next, a user-defined coroutine class is defined. Its @c run method keeps
+ * it active for as long as the connection has not been closed. Each time
+ * the coroutine resumes, it checks whether there is a new message and
+ * simply prints the type. After that, it yields to return control to its
+ * caller.
+ *
+ * The main program uses this behavior to resume the coroutine several times,
+ * setting new messages whenever the coroutine yields control.
+ */
+
+#include <iostream>
+#include <odemx/odemx.h>
+
+using namespace odemx;
+//
+// Simple message class that only has a type and no data
+//
+class Message
+{
+public:
+	enum Type { T1, T2 };
+
+	Message( Type t ): type_( t ) {}
+	Type getType() const { return type_; }
+private:
+	Type type_;
+};
+//
+// User-defined coroutine subclass that implements a simple protocol
+// connection which can maintain an internal state and yield control
+// to a caller.
+//
+class Connection: public coroutine::Coroutine
+{
+public:
+	Connection( base::Simulation& sim )
+	:	Coroutine( &sim )
+	,	msg_( 0 )
+	,	closed_( false )
+	{}
+
+	virtual void run()
+	{
+		//
+		// Run until connection gets closed
+		//
+		while( ! closed_ )
+		{
+			if( msg_ )
+			{
+				//
+				// If a message was set for this connection, display the type
+				//
+				switch( msg_->getType() )
+				{
+					case Message::T1:
+						std::cout << "T1" << std::endl;
+						break;
+					case Message::T2:
+						std::cout << "T2" << std::endl;
+						break;
+				}
+			}
+			//
+			// Return control to the caller of the coroutine
+			//
+			yield();
+		}
+		//
+		// The connection was closed
+		//
+		std::cout << "Connection closed" << std::endl;
+	}
+	void setMessage( Message* msg )
+	{
+		msg_ = msg;
+	}
+	void close()
+	{
+		closed_ = true;
+	}
+private:
+	Message* msg_;
+	bool closed_;
+};
+
+int main()
+{
+	//
+	// Create two message objects to pass to the connection object
+	//
+	Message m1( Message::T1 );
+	Message m2( Message::T2 );
+	base::Simulation& sim = getDefaultSimulation();
+	//
+	// Create one coroutine-based connection object and resume it
+	// several times.
+	//
+	Connection c( sim );
+	c();
+	c.setMessage( &m1 );
+	c();
+	c.setMessage( &m2 );
+	c();
+	c.close();
+	c();
+	return 0;
+}
diff --git a/odemx-lite/examples/Example_Continuous.cpp b/odemx-lite/examples/Example_Continuous.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..509dae5c452769e03f15d9f46560532f45faf319
--- /dev/null
+++ b/odemx-lite/examples/Example_Continuous.cpp
@@ -0,0 +1,346 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Example_Continuous.cpp
+
+	\author Ralf Gerstenberger
+
+	\date created at 2003/07/02
+
+	\brief Example for continuous simulations
+
+	This example demonstrates the use of Continuous and	ContuTrace.
+
+	\since 1.0
+*/
+/** \example Example_Continuous.cpp
+
+	The basic continuous simulation techniques of ODEMx are introduced.
+
+	Apart from discrete processes a simulation can also contain so called
+	continuous processes. A discrete process does change the system state
+	only at discrete moments in simulation time. It uses the
+	actions defined in its 'main()' function. The progress of time for a
+	process is realised with functions like 'holdFor', 'activateAt' and so on.
+	See the basic simulation example for details.
+	A continuous process instead changes the state of a system continuously.
+	Such a process could be for example the melting of a block of metal
+	inside an oven.
+	At every time, during the melting process, the temperature of the
+	metal is changed. That means \b every time you measure the temperature you
+	will get a new value.
+	Of course real continuity is quite impossible in the discrete world of
+	our computers. So ODEMx has to approximate continuous state changes with
+	a step by step computation.
+*/
+
+#include <odemx/base/Continuous.h>
+#include <odemx/base/Simulation.h>
+#include <odemx/base/DefaultSimulation.h>
+using namespace odemx::base;
+
+#ifdef ODEMX_USE_CONTINUOUS
+
+//
+// The first Continuous process is very simple. It only defines
+// a sinus/co-sinus oscillator.
+//
+class Oscillator : public Continuous {
+public:
+	//
+	// The construction of a Continuous object is a little different to
+	// that of a Process object. You also have to provide the number
+	// of state-variables used by your process. In case of Oscillator
+	// we need two variables.
+	//
+	Oscillator() : Continuous( odemx::getDefaultSimulation(), "Oscillator", 2 ) {};
+
+protected:
+	//
+	// The main-function of a continuous process is quite similar to that of
+	// a discrete process. You can do everything that is possible in Process.
+	// That's why a continuous can behave just like a discrete process. But
+	// it can also go through phases of continuous state changes.
+	//
+	virtual int main() {
+		//
+		// Before you can start the solver, which is computing the continuous
+		// state changes, you will have to initialise the state variables.
+		//
+		state[0]=1;
+		state[1]=0;
+
+		//
+		// Than you should set some parameters for the internal solver. These
+		// parameters include error sensitivity and the step length.
+		//
+		// The step length is set with 'setStepLength()'. The first parameter
+		// sets the minimal step length, while the second defines the maximal
+		// step length. The internal solver will compute new states in steps.
+		// Between every step the process holds. The actual length of the step
+		// taken will depend on numerical errors, peer processes, state events,
+		// and the parameters provided with 'setStepLength()'. The actual step
+		// length will not exceed your provided maximum. If the step length has
+		// to be reduced because of numerical errors or state events it will not
+		// be reduced below your provided minimum.
+		//
+		setStepLength(0.01, 0.1);
+
+		//
+		// The error sensitivity is set with 'setErrorlimit()'. The first parameter
+		// defines whether the errors should be considered relative to the value of
+		// the state variables (0) or absolute (1). The second parameter
+		// sets the maximum error acceptable (relative or absolute). If the actual
+		// error exceeds this value the solver will try to reduce the step length.
+		// If this fails, because the step length is already to small, you will get
+		// a simulation error.
+		//
+		setErrorlimit(0, 0.1);
+
+        	//
+		// Finally, the continuous phase is started with 'integrate()'. It is stopped
+		// either by a time event, a state event or an interrupt from another process.
+		//
+		// The time event is set by the first parameter. If it is 0 the solver will
+		// run for ever. Otherwise it will run to the given absolute time. If the
+		// provided time has already passed it will return at once. The return value of
+		// integrate will be 0 if the time event was hit. If the process is interrupted
+		// 'integrate()' returns 2.
+		//
+		integrate(20.0, 0);
+
+		return 0;
+	}
+
+	//
+	// Every Continuous process has to provide its specific 'derivatives()' function.
+	// In this function you define how the state changes during the time. You do this
+	// by setting the rate in which a state variable is changed. Although you don't have
+	// to, you can include the time provided by t in your computation. But never use
+	// 'getCurrentTime()' to get the time.
+	//
+    virtual void derivatives (double t) {
+		rate[0]=-state[1];
+		rate[1]=state[0];
+	}
+};
+
+//
+// The FreeFall continuous process needs only one state variable. It demonstrates
+// the use of parameter t in 'derivatives()'. The result is an idealistic free fall.
+//
+class FreeFall : public Continuous {
+public:
+	FreeFall() : Continuous( odemx::getDefaultSimulation(), "FreeFall", 1) {};
+
+protected:
+	virtual int main() {
+		state[0]=0.0;
+
+		setStepLength(.1,1);
+		integrate(20.0, 0);
+
+		return 0;
+	}
+
+	//
+	// Again, never use getCurrentTime() to include the current time in your
+	// computation. The reason for this is, that 'derivatives()' is called multiple
+	// times for each step and these calls are not synchronised to the
+	// 'official' time in the simulation.
+	//
+    virtual void derivatives (double t) {
+		double g=9.81;
+
+		rate[0]=t*g;
+	}
+};
+
+//
+// RealFall simulates a 'real fall' which is slowed down by friction.
+//
+class RealFall : public Continuous {
+public:
+	RealFall() : Continuous( odemx::getDefaultSimulation(), "RealFall", 2 ) {};
+
+protected:
+	//
+	// As in FreeFall we don't set the error limits. We can do so because
+	// ODEMx uses default settings for error limits and step length. The
+	// default for the error limits is a relative (0) error limit of 0.1 .
+	//
+	virtual int main() {
+		state[0]=2.0;
+		state[1]=0.0;
+
+		setStepLength(.1, 1);
+		integrate(20.0, 0);
+
+		return 0;
+	}
+
+    virtual void derivatives (double t) {
+		double k=0.5;
+		double g=-9.81;
+
+		rate[0]=state[1];
+		rate[1]=g - k*state[1];
+	}
+};
+
+//
+// RealBounce finally demonstrates the use of state events.
+//
+class RealBounce : public Continuous {
+public:
+	RealBounce() : Continuous( odemx::getDefaultSimulation(), "RealBounce", 3 ) {};
+
+	//
+	// 'hitGround()' is used to check a state event. The signature
+	// of functions that can be used as state-event-functions is:
+	//     bool(Process::*)()
+	// ODEMx uses pointer to member functions if it needs a call-back.
+	// The advantage is, you can use member functions with full access
+	// to internal data of your classes to check state events. The
+	// costs of this design decision is that you will always have to
+	// cast the address of your state-event-function to the type 'Condition'.
+	//
+	// A state function has to return true if a state event has occurred.
+	// Remember, the computation of state changes is done in steps. Because
+	// of that it is unlikely to hit a state event exactly. This has to
+	// be considered when programming a state-event-function. If a state
+	// event has occurred (or passed) the internal solver starts a binary
+	// search to get closer to the exact event time. Finally, if it gets close
+	// enough (minimum step length) the computation is stopped and 'integrate()'
+	// returns 1.
+	//
+	bool hitGround() {
+		return state[0]<=0.0;
+	}
+
+protected:
+	virtual int main() {
+		double g=-9.81;
+
+		state[0]=2.0;
+		state[1]=0.0;
+		state[2]=g;
+
+		setStepLength(0.01, 0.1);
+		//
+		// RealBounce uses the return value of 'integrate()' to control
+		// the computation. Remember 'integrate()' returns 0 if a
+		// time event occurred, 2 if the process was interrupted and 1
+		// if a state event was detected.
+		// 'integrate()' is called with the time event 20.0 and the
+		// state-event-function 'hitGround()'. If the state event
+		// is hit we reflect the movement 'state[1]=-(0.8*state[1])'
+		// and continue until the simulation time exceeds 20.0.
+		//
+		// EDIT: instead of passing in the above defined "hitground" function,
+		// it is now also possible to directly pass a lambda function as
+		// a state event. For compatibility reasons, the Process* argument
+		// must still be provided, although every nessecery information may
+		// be captured using a capture default "[&]"
+		while (integrate(20.0, [&](Process*){
+			return state[0]<=0.0;
+		}))
+		{
+			//
+			// The ball hit the ground and is reflected.
+			//
+			if (fabs(state[1])<0.01 && state[0]<0.01) {
+				//
+				// We must stop the ball if it has lost to much energy.
+				// Otherwise we would produce an annoying loop. The
+				// state event would be hit in every step.
+				//
+				state[1]=0.0;
+				state[2]=0.0;
+			}
+			state[1]=-(0.8*state[1]);
+		}
+
+		return 0;
+	}
+
+    virtual void derivatives (double t) {
+		double k=0.5;
+
+		rate[0]=state[1];
+		rate[1]=state[2] - k*fabs(state[1]);
+		rate[2]=0.0;
+	}
+};
+
+int main(int argc, char* argv[]) {
+
+	Oscillator* osci = new Oscillator();
+	FreeFall* free = new FreeFall();
+	RealFall* real = new RealFall();
+	RealBounce* bounce = new RealBounce();
+
+	//
+	// To follow the state changes we use the class ContuTrace.
+	// ContuTrace observes a provided continuous process and logs all
+	// state changes into a text file. The file is managed by ContuTrace.
+	// The name is either set in the constructor or build from the
+	// name of the observed continuous process. If you run the simulation
+	// you will find the 4 text files:
+	//     Oscillator_trace.txt
+	//     FreeFall_trace.txt
+	//     RealFall_trace.txt
+	//     RealBounce_trace.txt
+	//
+
+	ContuTrace osciTrace(osci), freeTrace(free), realTrace(real), bounceTrace(bounce);
+
+	//
+	// Continuous processes are activated just like discrete processes.
+	//
+	osci->activate();
+	free->activate();
+	real->activate();
+	bounce->activate();
+
+	//
+	// We can run the simulation without a time limit because all
+	// our continuous processes end at 20.0 .
+	//
+	odemx::getDefaultSimulation().run();
+
+	delete bounce;
+	delete real;
+	delete free;
+	delete osci;
+
+	return 0;
+}
+
+#else // ODEMX_USE_CONTINUOUS not defined
+
+#include <iostream>
+
+int main( int argc, char* argv[] )
+{
+	std::cerr << "ODEMx compiled without support for continuous processes."
+			  << std::endl;
+	return 0;
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
diff --git a/odemx-lite/examples/Example_Control.cpp b/odemx-lite/examples/Example_Control.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9267493e557a7fbf53f558102c3af50fc8cd6f1f
--- /dev/null
+++ b/odemx-lite/examples/Example_Control.cpp
@@ -0,0 +1,100 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2003, 2004, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_Control.cpp
+ * @author Jonathan Schlue
+ * @date created at 2016/10/06
+ * @brief Example for using Control variables to wait until an arbitrary condition turns true.
+ * @since 3.1
+ */
+
+/**
+ * @example Example_Control.cpp
+ * The basic usage of Control variables to wait until an arbitrary condition turns true.
+ *
+ * There are two processes: a Ping process, and a Pong process.
+ * ping says "ping" from time to time, by switching pong's controlled bool variable "pinged_".
+ * pong is waiting for changes to exactly this variable, and whenever it is set to true, pong prints an update about the current
+ * recognized ping to the console.
+ */
+
+#include <iostream>
+
+#include <odemx/odemx.h>
+
+struct Pong: Process
+{
+	Control<bool> pinged_;
+
+	Pong() :Process(odemx::getDefaultSimulation(), "Pong"), pinged_{false}
+	{}
+
+protected:
+	virtual int main() override
+	{
+
+		int times_pinged = 0;
+
+		for(;;)
+		{
+			waitUntil([&](Process*) { // <-- NOTE the capture default by reference "[&]", to actually always get the current value of "pinged_".
+				return pinged_;
+			}, "waiting for a ping", {pinged_});
+
+			++times_pinged;
+
+			std::cout << "#" << times_pinged << ": \tgot pinged at time " << getTime() << std::endl;
+			pinged_ = false;
+		}
+		return 0;
+	}
+};
+
+struct Ping: Process
+{
+	Pong* pong_;
+
+	Ping(Pong* pong) :Process(odemx::getDefaultSimulation(), "Ping"), pong_{pong}
+	{}
+
+protected:
+	virtual int main() override
+	{
+
+		for(int interval = 1;; ++interval)
+		{
+			// ping once in a while
+			holdFor(interval);
+			pong_->pinged_ = true;
+		}
+		return 0;
+	}
+};
+
+
+
+int main()
+{
+	Pong pong;
+	Ping ping{&pong};
+	ping.hold();
+	pong.hold();
+	odemx::getDefaultSimulation().runUntil(101);
+	return 0;
+}
diff --git a/odemx-lite/examples/Example_Custom_Channel.cpp b/odemx-lite/examples/Example_Custom_Channel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f171527bb01da7cb62933808d882b1f468d87daf
--- /dev/null
+++ b/odemx-lite/examples/Example_Custom_Channel.cpp
@@ -0,0 +1,78 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_Custom_Channel.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/16
+ * @brief Example demonstrating how to create and use a new log channel
+ * @since 3.0
+ */
+
+/**
+ * @example Example_Custom_Channel.cpp
+ * The usage of ODEMx channels is demonstrated.
+ *
+ * ODEMx provides 7 separate log channels in order to represent relevant
+ * logging categories: trace, debug, info, warning, error, fatal, and
+ * statistics. However, ODEMx users are not limited to these logging
+ * categories but can instead create their own. This is demonstrated
+ * by first creating a new channel id and then a consumer class that makes
+ * use of the channel.
+ */
+
+#include <odemx/odemx.h>
+//
+// First we use a macro to create a new channel ID. This value will be
+// created in namespace odemx::data::channel_id.
+//
+ODEMX_DECLARE_DATA_CHANNEL_WITH_ID( clock, 99 );
+//
+// Next, we define a simple producer class that has a shared_ptr member
+// for the ODEMx log channel type. During construction, this pointer
+// gets initialized be requesting a new channel pointer from the simulation
+// context. The method @c useChannel then demonstrates how this channel
+// can be put to use.
+//
+class CustomProducer: public odemx::data::Producer {
+public:
+	CustomProducer( odemx::base::Simulation& sim, const odemx::data::Label& label )
+	:	Producer( sim, label )
+	{
+		clock = sim.getChannel( odemx::data::channel_id::clock );
+	}
+	void useChannel() {
+		clock << log( "using my own channel" );
+	}
+private:
+	std::shared_ptr< Log::Channel< odemx::data::SimRecord > > clock;
+};
+
+int main()
+{
+	odemx::base::Simulation& sim = odemx::getDefaultSimulation();
+	//
+	// After creating a new producer object, we enable the default logging
+	// functionality of ODEMx an choose to log output to the console.
+	// Then, the method @c useChannel is called to produce some
+	// text output on the console.
+	//
+	CustomProducer p( sim, "Custom Producer" );
+	sim.enableDefaultLogging( odemx::data::output::STDOUT );
+	p.useChannel();
+}
diff --git a/odemx-lite/examples/Example_DiningPhilosophers.cpp b/odemx-lite/examples/Example_DiningPhilosophers.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..81744e2239ef26193cb4544d041179c6d020449a
--- /dev/null
+++ b/odemx-lite/examples/Example_DiningPhilosophers.cpp
@@ -0,0 +1,86 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_DiningPhilosophers.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/24
+ * @brief Example showing a variation of the dining philosophers problem
+ * @since 3.0
+ */
+
+/**
+ * @example Example_DiningPhilosophers.cpp
+ *
+ * There are 800 seats and as many philosophers and forks on one table.
+ * Philosophers either spend time thinking or eating. But the latter is only
+ * possible if two forks are available. As this Simulation is fairly time
+ * consuming, it was used to measure ODEMx performance.
+ */
+
+#include <odemx/odemx.h>
+#include <deque>
+
+class Philosopher: public odemx::base::Process {
+public:
+	Philosopher( bool& fork1, bool& fork2, odemx::base::SimTime timePeriod )
+	:	Process( odemx::getDefaultSimulation(), "Philosopher" )
+	,	fork1( fork1 ), fork2( fork2 ), timePeriod( timePeriod )
+	{}
+private:
+	virtual int main() {
+		while( true ) {
+			do { // thinking
+				spendTime();
+			} while( ! takeForks() );
+			// forks acquired, start eating
+			spendTime();
+			returnForks();
+		}
+		return 0;
+	}
+private:
+	bool& fork1;
+	bool& fork2;
+	int timePeriod;
+private:
+	bool takeForks() {
+		if( fork1 && fork2 ) {
+			fork1 = fork2 = false;
+			return true;
+		}
+		return false;
+	}
+	void returnForks() { fork1 = fork2 = true; }
+	void spendTime(){ holdFor( timePeriod ); }
+};
+
+int main() {
+	std::deque< Philosopher* > phils;
+	std::deque< bool > forks;
+	int seats = 800;
+	for( int i = 0; i < seats; ++i ) { forks.push_back( true ); }
+	for( int i = 0; i < seats - 1; ++i ) {
+		phils.push_back( new Philosopher( forks[ i ],  forks[ i + 1 ], 10 ) );
+	}
+	phils.push_back( new Philosopher( forks[ forks.size() - 1 ],  forks[ 0 ], 10 ) );
+
+	for( int i = 0; i < phils.size(); ++i ) { phils[ i ]->activate(); }
+	odemx::getDefaultSimulation().runUntil( 10000 );
+	std::for_each( phils.begin(), phils.end(), odemx::DeletePtr< Philosopher >() );
+}
diff --git a/odemx-lite/examples/Example_Event.cpp b/odemx-lite/examples/Example_Event.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7a7cf7ec7826b8970f9f1c1925d467e48da2929b
--- /dev/null
+++ b/odemx-lite/examples/Example_Event.cpp
@@ -0,0 +1,160 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_Event.cpp
+ * @author Ronald Kluth
+ * @date created at 2008/12/08
+ * @brief Example displaying the basic techniques for realizing an event-based
+ * simulation with ODEMx.
+ * @since 2.1
+*/
+
+/**
+ * @example Example_Event.cpp
+ * Further basic simulation techniques of ODEMx are introduced.
+ *
+ * An event-based simulation contains a number of event objects that describe
+ * certain event occurrences in a model. An event represents one atomic
+ * action. These actions are timeless. In this example, several scheduling
+ * operations are presented together with an example event class.
+ */
+
+#include <odemx/base/Event.h>
+#include <odemx/base/Simulation.h>
+#include <odemx/base/DefaultSimulation.h>
+using odemx::base::Event;
+using odemx::base::Simulation;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+
+//--------------------------------------------------------------------------Tick
+//
+// This example Event represents simple SimTime ticks. It outputs a '*' every
+// full tick in SimTime.
+//
+class Tick: public Event
+{
+public:
+	//
+	// Every event object needs a reference to the simulation context it belongs
+	// to. However, ODEMx provides a default simulation context, to enable use
+	// of processes and events without having to define a customized simulation
+	// class. Events, like all simulation elements, require a label for
+	// identification. ODEMx ensures that labels are unique within the same
+	// simulation context by appending numbers to duplicate labels.
+	//
+	Tick(): Event( odemx::getDefaultSimulation(), "Tick" ) {}
+	//
+	// This method overrides the pure virtual method of the base class Event.
+	// It describes the corresponding action in a model if this event occurs.
+	// Here, we simply output a '*' and reschedule the event to model the
+	// recurring ticks of a clock.
+	//
+	virtual void eventAction()
+	{
+		scheduleIn( 1 );
+		cout << " * ";
+	}
+};
+
+//--------------------------------------------------------------------------main
+
+int main( int argc, char* argv[] )
+{
+	//
+	// For this example, the default simulation context is used. In more complex
+	// applications it is recommended to provide a customized simulation class.
+	//
+	Simulation& sim = odemx::getDefaultSimulation();
+	//
+	// Using the default constructor, our Tick event will use the default
+	// simulation context that is also referenced by 'sim'.
+	//
+	Tick ticker;
+	//
+	// The event object is just created at this point. It will not be executed
+	// because it is not scheduled. An event can be scheduled by any of these
+	// methods:
+	//
+	// 'schedule()'
+	// 'scheduleIn()'
+	// 'scheduleAt()'
+	// 'scheduleAppend()'
+	// 'scheduleAppendIn()'
+	// 'scheduleAppendAt()'
+	//
+	// 'schedule()' and 'scheduleAppend()' are equal to
+	// 'scheduleIn( 0 )' and scheduleAppendIn( 0 ), respectively.
+	// 'scheduleAt( t )' and 'scheduleAppendAt( t )' are equal to
+	// 'scheduleIn( t - now )' and 'scheduleAppendIn( t - now )'.
+	//
+	ticker.scheduleAt( 1 );
+	//
+	// There are three ways to compute a simulation. Firstly, you can 'run()'
+	// the simulation until it is finished. A simulation is finished if there
+	// is no active process or event scheduled, or if it is stopped with
+	// 'exitSimulation()'. Secondly, you can compute a simulation 'step()' by
+	// step. Thirdly, you can run a simulation until a given SimTime is
+	// reached with 'runUntil()'.
+	//
+	// Because Tick events will reschedule themselves forever, we should not use
+	// 'run()'. Instead we try both 'step()' and 'runUntil()'.
+	//
+	cout << "Basic Event Simulation Example\n";
+	cout << "==============================\n";
+
+	for( int i = 1; i < 5; ++i )
+	{
+		sim.step();
+		cout << "\n" << "Step " << i << ": time = " << sim.getTime() << "\n";
+	}
+
+	cout << "\n" << "continue until SimTime 6 is reached:";
+	sim.runUntil( 6 );
+	cout << "\n" << "time = " << sim.getTime() << "\n";
+
+	cout << "==============================" << endl;
+	return 0;
+}
+
+//----------------------------------------------------------------program output
+//
+// Basic Event Simulation Example
+// ==============================
+//  *
+// Step 1: time = 1
+//  *
+// Step 2: time = 2
+//  *
+// Step 3: time = 3
+//  *
+// Step 4: time = 4
+//
+// continue until SimTime 6 is reached: *  *
+// time = 6
+// ===============================
+//
+// In contrast to the basicProcess example there is a '*' at step 1 because
+// event actions are atomic. Keep in mind that always all of the statements
+// in eventAction() are executed, even if there are scheduling calls. In this
+// case, the same Event object is rescheduled, but it still outputs the '*'.
+// Once an Event's action is started, it cannot be stopped or postponed.
+//
diff --git a/odemx-lite/examples/Example_Filter.cpp b/odemx-lite/examples/Example_Filter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..17d9e3bbd2a21bf31a6d5c7a5f072b4dccb417e2
--- /dev/null
+++ b/odemx-lite/examples/Example_Filter.cpp
@@ -0,0 +1,79 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file examples/Example_Filter.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/24
+ * @brief Example demonstrating how to use a SimRecordFilter
+ * @since 3.0
+ */
+
+/**
+ * @example Example_Filter.cpp
+ * The usage of the ODEMx log record filter class is shown.
+ *
+ * All four methods of filtering simulation records are shown in the
+ * main function. Filtering can be done by record text, record scope,
+ * producer label, or producer type.
+ */
+
+#include "Example_Producer_DebugStopWatch.h"
+#include <iostream>
+using namespace odemx;
+
+int main() {
+	typedef std::shared_ptr< data::SimRecordFilter > FilterPtr;
+	FilterPtr filter = data::SimRecordFilter::create();
+
+	base::Simulation& sim = getDefaultSimulation();
+	sim.enableDefaultLogging( data::output::STDOUT );
+	sim.setFilter( filter );
+
+	//
+	// The construction of the DebugStopWatch is filtered here.
+	//
+	filter->addRecordText() << "construction";
+	DebugStopWatch watch( sim, "Stop Watch" );
+
+	//
+	// The scope filters all output from a class in hierarchy, in this case
+	// the records sent by class DebugStopWatch. Therefore, only the base class
+	// records from StopWatch may pass here.
+	//
+	filter->addRecordScope() << typeid( DebugStopWatch );
+	watch.start();
+	watch.stop();
+
+	//
+	// Filtering by label means blocking everything that is sent by this object.
+	// So, no output happens when calling @c start.
+	//
+	filter->addProducerLabel() << "Stop Watch";
+	watch.start();
+
+	//
+	// Resetting the filter removes all previously added values. However,
+	// adding the producer type is different than using a scope because
+	// this will now also filter all records, but not only from one object
+	// but all objects of class DebugStopWatch.
+	//
+	filter->resetFilter();
+	filter->addProducerType() << typeid( DebugStopWatch );
+	watch.stop();
+}
diff --git a/odemx-lite/examples/Example_Matryoshka_Simulation.cpp b/odemx-lite/examples/Example_Matryoshka_Simulation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3f0bf0e9bcd8e2b9a33ee03eadbd19d7eb07cf77
--- /dev/null
+++ b/odemx-lite/examples/Example_Matryoshka_Simulation.cpp
@@ -0,0 +1,184 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Example_Matryoshka_Simulation.cpp
+
+	\author Ralf Gerstenberger
+
+	\date created at 2002/12/14
+
+	\brief Example for recursive simulations
+
+	This example shows the techniques for
+	realising a recursive simulation with ODEMx.
+
+	\since 1.0
+*/
+/** \example Example_Matryoshka_Simulation.cpp
+	Recursive simulations are
+	introduced.
+
+	One of the unique features of ODEMx is the possibility to run a simulation inside
+	another simulation without unwanted side-effects. This could come in handy if you
+	want to simulate an agent network for instance. Agents have an internal model of
+	their environment, which they use to make their decisions. With ODEMx such an
+	agent could be modelled with an internal (simplified) simulation. Another example
+	could be a very complex simulation task. With ODEMx you could split the model into
+	several blocks, develop	each one as a simulation on its own, and plug them together
+	at the end.
+*/
+
+#include <odemx/base/Process.h>
+#include <odemx/base/Simulation.h>
+using odemx::base::Process;
+using odemx::base::Simulation;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+
+//
+// In this example we demonstrate the possibility to cascade simulations in a recursive
+// simulation called Matryoshka. Like the Russian puppet inside a puppet inside a puppet
+// inside ...
+//
+// A user defined simulation is a class derived from Simulation. Every process or model
+// component requires a pointer to its simulation. The user defined simulation can provide
+// its processes with additional data. Furthermore, a user defined simulation must implement
+// the 'initSimulation()' function to start its processes and to do specific initialisations.
+//
+class Matryoshka
+:	public Simulation
+{
+	//
+	// The simulation contains only the process Proc.
+	// This process expects a Matryoshka-simulation as
+	// environment. Defining the process as an inside
+	// class of Matryoshka is of course not required.
+	//
+	class Proc
+	:	public Process
+	{
+	public:
+		Proc( Matryoshka& sim )
+		:	Process( sim, "Proc" )
+		{}
+
+	protected:
+		//
+		// In its 'main()' function the process gets a pointer to
+		// its simulation. After a cast (the dynanmic_cast could
+		// be spared) the process can access the data provided by
+		// its simulation.
+		//
+		virtual int main()
+		{
+			int i;
+			Matryoshka& sim = dynamic_cast< Matryoshka& >( this->getSimulation() );
+			int level = sim.getLevel();
+
+			for( i = level; i > 0; --i )
+			{
+				cout << ' ';
+			}
+
+			if( level % 2 > 0 )
+			{
+				cout << "Di " << level << endl;
+			}
+			else
+			{
+				cout << "Da " << level << endl;
+			}
+
+			//
+			// After some outputs the process starts the recursion.
+			//
+			if( level > 0 )
+			{
+				Matryoshka m( level - 1 );
+				m.run();
+			}
+
+			for( i = level; i > 0; --i )
+			{
+				cout << ' ';
+			}
+
+			if( level % 2 > 0 )
+			{
+				cout << "Di " << level << endl;
+			}
+			else
+			{
+				cout << "Da " << level << endl;
+			}
+			return 0;
+		}
+	};
+
+	Proc p;
+	unsigned int mLevel;
+
+public:
+	//
+	// Because of the recursion Matryoshka needs the additional
+	// parameter 'level'.
+	//
+	Matryoshka( unsigned int level )
+	:	Simulation( "Matryoshka" )
+	,	p( *this )
+	,	mLevel( level )
+	{}
+
+	~Matryoshka()
+	{
+		//delete p;
+	}
+
+	//
+	// 'level' is the recursion parameter of the Matryoshka simulation.
+	//
+	unsigned int getLevel() { return mLevel; }
+
+protected:
+	//
+	// If you are defining your own simulation class you have to provide 'initSimulation'
+	// to initialise the simulation. This function is called when the simulation is started
+	// for the first time.
+	//
+	virtual void initSimulation()
+	{
+		p.activate();
+	}
+};
+
+//
+// The 'main' function looks a bit deserted in this example. Almost everything
+// is done in the simulation. The advantage is, you can 'reuse' the simulation
+// as it is.
+//
+int main(int argc, char* argv[])
+{
+	// Start the first simulation to kick off the recursion
+	Matryoshka m( 10 );
+	m.run();
+
+	return 0;
+}
+
diff --git a/odemx-lite/examples/Example_Parallel_Simulation.cpp b/odemx-lite/examples/Example_Parallel_Simulation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a63f99ee98535fc89a43d712c5bc19e37496c908
--- /dev/null
+++ b/odemx-lite/examples/Example_Parallel_Simulation.cpp
@@ -0,0 +1,224 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Example_Parallel_Simulation.cpp
+
+	\author Ralf Gerstenberger
+
+	\date created at 2002/12/14
+
+	\brief Example for multiple (parallel) simulations
+
+	This example shows the techniques for realising
+	multiple (parallel) simulations in one program.
+
+	\since 1.0
+*/
+/** \example Example_Parallel_Simulation.cpp
+	Multiple (parallel) simulations in one program are
+	introduced.
+
+	As shown in the example for simulations inside simulations, it is
+	possible to have multiple simulations in one program. These simulations
+	can be computed one after another or 'parallel'. In this example both
+	situations are presented.
+*/
+
+#include <iostream>
+using namespace std;
+
+#include <odemx/base/Process.h>
+#include <odemx/base/Simulation.h>
+#include <odemx/synchronization/WaitQ.h>
+using namespace odemx::base;
+using namespace odemx::synchronization;
+
+//
+// In this example we demonstrate multiple parallel simulations. We have
+// two simulations (SimA and SimB) which are at first computed one after
+// another and then parallel.
+//
+// SimA contains two processes (Master and Slave) which cooperate through
+// an instance of WaitQ. Master uses the function 'coopt()' which returns a
+// waiting slave. Slave calls the function 'wait()' to show its readiness.
+// Both functions block the execution of the active process if an immediate
+// interaction between a slave and a master is not possible.
+//
+class SimA : public Simulation {
+	// process types of SimA
+	class Master : public Process {
+	public:
+		Master(SimA& sim)
+			: Process(sim, "Master") {}
+
+	protected:
+		virtual int main() {
+			SimA& sim = dynamic_cast<SimA&>( this->getSimulation());
+			Slave* s=0;
+
+			cout << getLabel() << " coopt" << endl;
+			s = dynamic_cast<Slave*>(sim.getQueue()->coopt());
+
+			//
+			// The function 'activateAfter()' causes the activation
+			// of a process after another.
+			//
+			s->activateAfter(this);
+
+			cout << getLabel() << " coopt finished" << endl;
+
+			return 0;
+		}
+	};
+
+	class Slave : public Process {
+	public:
+		Slave(SimA& sim)
+			: Process(sim, "Slave") {}
+
+	protected:
+		virtual int main() {
+			SimA& sim = dynamic_cast<SimA&>(getSimulation());
+
+			cout << getLabel() << " wait" << endl;
+			sim.getQueue()->wait();
+			cout << getLabel() << " wait finished" << endl;
+
+			return 0;
+		}
+	};
+
+	Master* m;
+	Slave* s;
+	WaitQ* q;
+
+public:
+	SimA(SimulationObserver* o = 0)
+		: Simulation("SimA", o), m(0), s(0), q(0) {}
+
+	~SimA() {
+		delete m;
+		delete s;
+		delete q;
+	}
+
+	WaitQ* getQueue() {return q;}
+
+protected:
+	virtual void initSimulation() {
+		m = new Master(*this);
+		s = new Slave(*this);
+		q = new WaitQ(*this, "queue");
+
+		m->activate();
+		s->activate();
+	}
+};
+
+//
+// SimB contains a process called Loop which 10 times writes
+// its label and holds for 1 time unit.
+//
+class SimB : public Simulation {
+	// process types of SimA
+	class Loop : public Process {
+	public:
+		Loop(SimB& sim, ProcessObserver* o = 0)
+			: Process(sim, "Loop", o) {}
+
+	protected:
+		virtual int main() {
+			for (int i= 0; i<10; ++i) {
+				cout << getLabel() << i << endl;
+				holdFor(1);
+			}
+
+			return 0;
+		}
+	};
+
+public:
+	SimB(SimulationObserver* o = 0)
+		: Simulation("SimB", o), l(0) {}
+
+	~SimB() {
+		delete l;
+	}
+
+	Loop* l;
+
+protected:
+	virtual void initSimulation() {
+		l=new Loop(*this);
+
+		l->activate();
+	}
+};
+
+//
+// The main function runs at first a simulation of type SimA,
+// than a simulation of type SimB and finally a simulation of
+// type SimA parallel to a simulation of type SimB (step by step).
+//
+int main(int argc, char* argv[]) {
+
+	//
+	// Run simulation of type SimA
+	//
+	cout << "Part 1" << endl;
+	for (int i=0; i<5; ++i) {
+		SimA s;
+		s.run();
+	}
+	cout << "Simulation A has run 5 times.";
+
+	//
+	// Run simulation of type SimB
+	//
+	cout << endl << "Part 2" << endl;
+	{
+		SimB s;
+		s.run();
+	}
+	cout << "Simulation B has run once.";
+
+	//
+	// Run simulations of type SimA and type SimB
+	//
+	cout << endl << "Part 3 -- Running two interleaved simulations" << endl;
+	{
+		SimA s1;
+		SimB s2;
+
+		s1.step();
+		s2.step();
+
+		while ( !(s1.isFinished() && s2.isFinished()) ) {
+
+			if (!s1.isFinished())
+				s1.step();
+
+			if (!s2.isFinished())
+				s2.step();
+		}
+	}
+
+	cout << endl << "Finished" << endl;
+	return 0;
+}
+
diff --git a/odemx-lite/examples/Example_Port2.cpp b/odemx-lite/examples/Example_Port2.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fd275fb9d6eaa167293b8be91b5eb67cab7c1e3a
--- /dev/null
+++ b/odemx-lite/examples/Example_Port2.cpp
@@ -0,0 +1,376 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Example_Port2.cpp
+
+	\author Ralf Gerstenberger
+
+	\date created at 2003/07/28
+
+	\brief Port2 example from ODEM
+
+	Port2 example from ODEM transferred to ODEMx.
+*/
+
+/** \example Example_Port2.cpp
+	This example demonstrates a migration from ODEM to ODEMx.
+	The original Port2 simulation was taken from ODEM and adjusted
+	to run with ODEMx. Port2 simulates a port with tides. The
+	original source-code is preserved in this file to show the
+	differences.
+*/
+
+/*
+#include "odem.h"
+
+	ODEMx requires different include files than ODEM. The
+	most simple solution is to include odemx.h. This file
+	in turn includes other header from ODEMx. All classes
+	of ODEMx are placed in the namespace ODEMx. In this simple
+	example it is safe to use the whole namespace.
+*/
+#include <odemx/odemx.h>
+using namespace odemx::base;
+using namespace odemx::random;
+using namespace odemx::synchronization;
+
+#include <vector>
+using namespace std;
+
+
+/*
+#ifdef _USE_GL
+#include "grtrace.h"
+#endif
+
+	ODEMx does not support the GrTrace from ODEM.
+
+	In ODEMx all model components require a pointer to the
+	simulation. In general a user would provide a class for
+	its special simulation which would inherit the ODEMx
+	Simulation class. But for convenience ODEMx also contains
+	a default simulation class. The function getDefaultSimulation()
+	returns a pointer to an object of this class.
+*/
+
+Simulation* sim = &odemx::getDefaultSimulation();
+
+/*
+	The names of the following classes have not been changed between
+	ODEM and ODEMx.
+*/
+Res*   tugs;				// Schlepper
+Res*   jetties;				// Anlegeplaetze
+CondQ* dockq;
+ContinuousDist* next;
+ContinuousDist* discharge;
+
+/*
+class Boat : public Discrete {
+public:
+	int main ();
+	Boat() : Discrete("boat"){}
+};
+
+	The ODEM base class Discrete for active model components
+	has been replaced by the class Process in ODEMx. As in ODEM
+	a user has to provide an implementation of the function
+	virtual int main(). The constructor of Process requires,
+	in addition to a name, a pointer to the simulation class.
+	Another difference between ODEM and ODEMx is, that call-backs
+	used for coding conditions or selections are member-functions
+	(bool cond1()).
+*/
+class Boat : public Process {
+public:
+	int main ();
+	Boat() : Process( *sim, "boat"){}
+
+	bool cond1();
+};
+
+/*
+bool cond1();
+*/
+
+int Boat::main() {
+// im Dock
+	jetties->acquire(1);
+	
+	/*
+	dockq->waituntil(cond1);
+	
+	The interface of CondQ has changed. In this example
+	we have to use wait(...) instead of waituntil(...).
+	The cast is required because of the decision to use
+	member functions for call-backs. We think the advantages
+	outweigh the disadvantages of this cast.
+	*/
+	dockq->wait([&](Process* self) {
+		return static_cast<Boat*>(self)->cond1();
+	});
+	
+	tugs->acquire(2);
+	
+	/*
+	hold(2.0);
+	
+	Most scheduling functions have been changed between ODEM and ODEMx.
+	hold() for instance is now replaced by a holdFor().
+	*/
+	holdFor(2);
+	
+	tugs->release(2);
+	dockq->signal();
+	
+// Loeschen der Ladung
+	/*
+	hold(discharge->sample());
+	*/
+	holdFor(static_cast< SimTime >( discharge->sample() ));
+
+// ablegen
+	tugs->acquire(1);
+
+	/*
+	hold (2.0);
+	*/
+	holdFor(2);
+
+	tugs->release(1);
+	jetties->release(1);
+	dockq->signal();
+
+	return 0;
+}
+
+/*
+class Tide : public Discrete {
+public:
+	static bool low;
+	Tide(): Discrete("tide") {}
+	int main ();
+
+	(see the comments for Boat)
+};
+*/
+class Tide : public Process {
+public:
+	static bool low;
+	Tide(): Process( *sim, "tide") {}
+	int main ();
+};
+
+bool Tide::low = false;
+
+/*
+bool cond1() {
+
+	(see the comments for Boat)
+*/
+bool Boat::cond1() {
+	/*
+	return (tugs->avail() >=2) && !Tide::low;
+
+	The function avail() is replaced by getTokenNumber()
+	in ODEMx.
+	*/
+	return (tugs->getTokenNumber() >=2) && !Tide::low;
+}
+
+int Tide::main() {
+	for (;;) {
+		// low
+		low = true;
+
+		/*
+		hold(4.0);
+		*/
+		holdFor(4);
+
+		low = false;
+		dockq->signal();
+
+		// high
+		/*
+		hold(9.0);
+		*/
+		holdFor(9);
+	}
+	return 0;
+}
+
+/*
+class Arrival : public Discrete {
+public:
+	Boat *b;
+	Arrival(): Discrete("arrival") {}
+	int main ();
+};
+
+	(see the comments for Boat)
+*/
+class Arrival : public Process {
+	vector<Boat*> generatedBoats;
+public:
+	Boat *b;
+	Arrival(): Process( *sim, "arrival") {}
+	~Arrival() {
+		vector<Boat*>::iterator i;
+		for ( i = generatedBoats.begin(); i != generatedBoats.end(); ++i )
+			delete *i;
+	}
+	int main ();
+};
+
+
+int Arrival::main() {
+	for (;;) {
+		b = new Boat;
+		generatedBoats.push_back(b);
+		/*
+		b->start(NOW);
+		hold(next->sample());
+
+		The function start() is not available in
+		ODEMx. In ODEMx any hold* or activate* function
+		can be used to start a new process.
+		*/
+		b->hold();
+		holdFor(static_cast< SimTime >( ::next->sample() ));
+	}
+	return 0;
+}
+
+int main(int argc, const char* argv[]) {
+/*
+	InitializeOdemLib(argc, argv);
+
+#ifdef _USE_GL
+	trace().addClient(new GrTrace);
+#endif
+	trace().start();
+
+	It is not necessary to initialise ODEMx.
+
+	The trace system has changed between ODEM and ODEMx.
+	The trace management is done by the simulation class.
+	A new trace is added with the function addConsumer(...).
+	The trace is controlled with startTrace(), stopTrace(),
+	pauseTrace() and continueTrace(). HtmlTrace logs the
+	simulation events in a html file. It also provides a simple
+	filter to reduce the output. Without a filter the ODEMx trace
+	logs much more events than its predecessor in ODEM. In
+	this example the filter is set to produce an ODEM-like output.
+
+	In ODEMx several reports are available in one simulation to the
+	cost of explicitly creating report objects (the class
+	HtmlReport is provided by ODEMx) and registering
+	model components to the different reports.
+
+	The results of this simulation can be found in the files
+	'Port2_Trace.html' and 'Port2_Report.html'. Trace and report
+	of the original ODEM version have been added to the ODEMx package
+	for you to compare output and results. They can be found
+	along with the Port2.cpp file ('Port2_Trace.txt' and
+	'Port2_Report.txt').
+*/
+//	HtmlTrace trace(sim, "Port2_Trace.html");
+//	HtmlReport report(sim, "Port2_Report.html");
+
+//	trace.setFilter("all; mtn:changeState, changeExTime, create, time,"
+//					"execute process, init, execute, changeTokenNumber,"
+//					"current process, run until, sleep");
+//	sim->addConsumer(&trace);
+//	sim->startTrace();
+
+	Arrival *a = new Arrival;
+	Tide *t = new Tide;
+
+/*
+	next = new NegativeExponential("next boat", 0.1);
+	discharge = new Normal("discharge", 14.0, 3.0);
+	tugs = new Res("tugs", 3);
+	jetties = new Res("jetties", 2);
+	dockq = new CondQ("dockq");
+
+	As already mentioned, in ODEMx most model components require
+	a pointer to an object of the simulation class. Res in
+	addition does need a maximum token number which can be larger
+	than the initial number of available token.
+*/
+	::next = new NegativeExponential(*sim, "next boat", 0.1);
+	discharge = new Normal(*sim, "discharge", 14.0, 3.0);
+	tugs = new Res(*sim, "tugs", 3, 3);
+	jetties = new Res(*sim, "jetties", 2, 2);
+	dockq = new CondQ(*sim, "dockq");
+
+//	report.addProducer(next);
+//	report.addProducer(discharge);
+//	report.addProducer(tugs);
+//	report.addProducer(jetties);
+//	report.addProducer(dockq);
+
+	/*
+	a->start(NOW);
+	t->start(DELAY,1);
+	main_Discrete()->hold(50.0);
+
+	(see Arrival::main comments as well)
+
+	In ODEMx the global main function is not integrated as a
+	process. The simulation control is instead realised by the
+	functions run(), runUntil(...) and step().
+	*/
+	a->activate();
+	t->activateIn(1);
+	sim->runUntil(50);
+
+	/*
+	trace().pause();
+	*/
+//	sim->pauseTrace();
+
+	/*
+	main_Discrete()->hold(28.0*24.0-50.0);
+	*/
+	sim->runUntil(28*24);
+
+	/*
+	report();
+
+	The function generateReport() has to be called for every report.
+	Registered model components mustn't be deleted because
+	generateReport() gathers data from them.
+	*/
+//	report.generateReport();
+
+//	sim->stopTrace();
+	sim->exitSimulation();
+
+	delete a;
+	delete t;
+	delete ::next;
+	delete discharge;
+	delete tugs;
+	delete jetties;
+	delete dockq;
+
+	return 0;
+}
+
diff --git a/odemx-lite/examples/Example_Process.cpp b/odemx-lite/examples/Example_Process.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..eb18c3ea847d6543c84e1f2a0888f18d223b9d3b
--- /dev/null
+++ b/odemx-lite/examples/Example_Process.cpp
@@ -0,0 +1,184 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_Process.cpp
+ * @author Ralf Gerstenberger
+ * @date created at 2002/08/26
+ * @brief Example demonstrating basic ODEMx process simulation techniques
+ * @since 1.0
+*/
+
+/**
+ * @example Example_Process.cpp
+ *
+ * The basic simulation techniques required for ODEMx process simulations
+ * are introduced.
+ *
+ * A process simulation contains a number of processes that describe
+ * active elements in a model. A process contains a description of its behavior,
+ * a sequence of actions. These actions are timeless. Time consumption is
+ * realized with special time operations. In this example several of these
+ * time operations are presented together with an example process.
+ */
+
+#include <odemx/base/Process.h>
+#include <odemx/base/Simulation.h>
+#include <odemx/base/DefaultSimulation.h>
+using odemx::base::Process;
+using odemx::base::Simulation;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+
+//-------------------------------------------------------------------------Clock
+//
+// This example Process is a simple SimTime clock. It outputs a '*' every full
+// tick in SimTime.
+//
+class Clock: public Process
+{
+public:
+	//
+	// We label all instances of this class 'Clock'. ODEMx ensures uniqueness
+	// of labels on its own to prevent confusion. It will add a number to the
+	// label if more than one Clock object is created in the same simulation
+	// context.
+	//
+	// When we create any kind of Process object, we have to provide a reference
+	// to the simulation context we want it to participate in. If the
+	// constructor of Process is called without a simulation context, it will
+	// use the default simulation context.
+	//
+	// Here, we choose to provide a simulation context.
+	//
+	Clock( Simulation& sim ): Process( sim, "Clock" ) {}
+	//
+	// The behavior of a user process must be defined by an implementation of
+	// the pure virtual function 'int main()'. The return value of this
+	// function is stored in the Process object and can be accessed via the
+	// method 'getReturnValue()'. As long as 'main()' has not finished, the
+	// return value is not valid. You can use the Process method 'hasReturned()'
+	// to check this condition.
+	//
+	virtual int main()
+	{
+		//
+		// Because our process has a recurring behavior pattern, we implement
+		// its life cycle by using a loop.
+		//
+		while( true )
+		{
+			//
+			// Since we are implementing a simple clock, we need a means to let
+			// the SimTime pass. Here, we use the member function 'holdFor()',
+			// which requires a time period as parameter. We could also use
+			// 'activateIn()' instead. The difference between these two is seen
+			// if there is more than one process scheduled at the same time.
+			// 'holdFor()' would than schedule the current process in the last
+			// position while 'activateIn()' would schedule the current process
+			// as the first one at that particular time. Therefore, hold... and
+			// activate... functions can be used to choose between fifo or lifo
+			// scheduling.
+			//
+			holdFor( 1 );
+
+			cout << " * ";
+		}
+		return 0;
+	}
+};
+
+//--------------------------------------------------------------------------main
+
+int main( int argc, char* argv[] )
+{
+	//
+	// For this example we can use the DefaultSimulation. In more complex
+	// applications it is recommended to provide a customized simulation class.
+	//
+	Simulation& sim = odemx::getDefaultSimulation();
+	Clock clock( sim );
+	//
+	// The new process is just created at this point. It will not be executed
+	// because it has not been activated yet. A process can be activated by any
+	// of these methods:
+	//
+	// 'hold()'
+	// 'holdFor()'
+	// 'holdUntil()'
+	// 'activate()'
+	// 'activateIn()'
+	// 'acitvateAt()'
+	//
+	// 'hold()' and 'activate()' are equal to 'holdFor( 0 )' and
+	// 'activateIn( 0 )'. 'holdUntil( t )' and 'activateAt( t )'
+	// are equal to 'holdFor( t - now )' and 'activateIn( t - now )'.
+	//
+	clock.activate();
+	//
+	// There are three ways to compute a simulation. Firstly, you can 'run()'
+	// the simulation until it is finished. A simulation is finished if there
+	// is no active process or event scheduled, or if it is stopped with
+	// 'exitSimulation()'. Secondly, you can compute a simulation 'step()' by
+	// step. Thirdly, you can run a simulation until a given SimTime is
+	// reached with 'runUntil()'.
+	//
+	// Because Clock processes are running forever, we should not use
+	// 'run()'. Instead we try both 'step()' and 'runUntil()'.
+	//
+	cout << "Basic Process Simulation Example\n";
+	cout << "================================\n";
+
+	for( int i = 1; i < 5; ++i )
+	{
+		sim.step();
+		cout << "\n" << "Step " << i << ": time = " << sim.getTime() << "\n";
+	}
+
+	cout << "\n" << "continue until SimTime 6 is reached:";
+	sim.runUntil( 6 );
+	cout << "\n" << "time = " << sim.getTime() << "\n";
+
+	cout << "================================" << endl;
+
+	return 0;
+}
+
+//----------------------------------------------------------------program output
+//
+// Basic Process Simulation Example
+// ================================
+//
+// Step 1: time = 0
+//  *
+// Step 2: time = 1
+//  *
+// Step 3: time = 2
+//  *
+// Step 4: time = 3
+//
+// continue until SimTime 6 is reached: *  *  *
+// time = 6
+// ================================
+//
+// Keep in mind that at step 1 our clock will not output a '*' because that is
+// the first step until the 'holdFor( 1 )' statement is reached. Only after
+// that, the clock starts ticking, so to speak.
+//
diff --git a/odemx-lite/examples/Example_Process_Deletion.cpp b/odemx-lite/examples/Example_Process_Deletion.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c3b8abf35bcd9977a9c0426b0858e9723fef25b4
--- /dev/null
+++ b/odemx-lite/examples/Example_Process_Deletion.cpp
@@ -0,0 +1,96 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_Process_Deletion.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/24
+ * @brief Example demonstrating how to delete terminated processes
+ * @since 3.0
+ */
+
+/**
+ * @example Example_Process_Deletion.cpp
+ * The usage of ODEMx process memory management is demonstrated.
+ *
+ * For this purpose, Processes are created, activated and immediately
+ * terminated after running once. These Process objects are then automatically
+ * destroyed.
+ */
+
+#include <odemx/odemx.h>
+using namespace odemx;
+using namespace odemx::base;
+
+#include <iostream>
+
+//
+// Process class that shows when a process is active and thus becomes terminated
+// after finishing its main function. Logging in the destructor shows when
+// the objects get destroyed.
+//
+class TestProcess: public Process {
+public:
+	TestProcess(): Process( odemx::getDefaultSimulation(), "TestProcess" ) {}
+	~TestProcess() { info << log( "process destroyed" ); }
+	virtual int main()
+	{
+		info << log( "active" );
+		return 0;
+	}
+};
+
+//
+// A generator event class that creates and schedules processes.
+//
+class Generator: public Event {
+public:
+	Generator( int count ): Event( odemx::getDefaultSimulation(), "Generator" )
+	, 	count_( count ) {}
+	virtual void eventAction()
+	{
+		for( int i = 0; i < count_; ++i )
+		{
+			info << log( "new process" );
+			Process* p = new TestProcess();
+			p->activateIn( 10 );
+		}
+	}
+private:
+	int count_;
+};
+
+int main()
+{
+	Simulation& sim = getDefaultSimulation();
+	//
+	// In order to have ODEMx delete terminated processes during a simulation
+	// run, the method @c autoDeleteProcesses must be called.
+	//
+	sim.autoDeleteProcesses();
+	sim.addConsumer( data::channel_id::info,
+			data::output::OStreamWriter::create( std::cout ) );
+	//
+	// All processes are created and scheduled at once, but each is
+	// deleted right after its execution when control goes back to the
+	// simulation context.
+	//
+	Generator gen( 5 );
+	gen.schedule();
+	sim.runUntil( 15 );
+}
diff --git a/odemx-lite/examples/Example_Producer_DebugStopWatch.h b/odemx-lite/examples/Example_Producer_DebugStopWatch.h
new file mode 100644
index 0000000000000000000000000000000000000000..50ec335af09007d7ecc4147347c9af29420d79da
--- /dev/null
+++ b/odemx-lite/examples/Example_Producer_DebugStopWatch.h
@@ -0,0 +1,60 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_Producer_DebugStopWatch.h
+ * @author Ronald Kluth
+ * @date created at 2010/04/13
+ * @brief Example demonstrating the use of ODEMx's debug channel within a producer class
+ * @since 3.0
+ */
+
+/**
+ * @example Example_Producer_DebugStopWatch.h
+ * The usage of ODEMx log channel @c debug is shown.
+ *
+ * For this purpose, a new log data producer is derived from the class
+ * @c StopWatch. It extends this class by hiding its methods @c start and @c stop
+ * in order to add debug statements to the calls.
+ */
+
+#ifndef EXAMPLE_PRODUCER_DEBUGSTOPWATCH_INCLUDED
+#define EXAMPLE_PRODUCER_DEBUGSTOPWATCH_INCLUDED
+
+#include "Example_Producer_StopWatch.h"
+
+class DebugStopWatch: public StopWatch {
+public:
+	DebugStopWatch( odemx::base::Simulation& sim, const odemx::data::Label& label )
+	:	StopWatch( sim, label ) {
+		debug << log( "construction" ).scope( typeid( DebugStopWatch ) );
+	}
+	~DebugStopWatch() {
+		debug << log( "destruction" ).scope( typeid( DebugStopWatch ) );
+	}
+	void start() {
+		debug << log( "started" ).scope( typeid( DebugStopWatch ) );
+		StopWatch::start();
+	}
+	void stop(){
+		debug << log( "stopped" ).scope( typeid( DebugStopWatch ) );
+		StopWatch::stop();
+	}
+};
+
+#endif /* EXAMPLE_PRODUCER_DEBUGSTOPWATCH_INCLUDED */
diff --git a/odemx-lite/examples/Example_Producer_LoggingManager.cpp b/odemx-lite/examples/Example_Producer_LoggingManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..14d20d7314b7c2a610eb18c71935540e87c32171
--- /dev/null
+++ b/odemx-lite/examples/Example_Producer_LoggingManager.cpp
@@ -0,0 +1,54 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_Producer_LoggingManager.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/12/28
+ * @brief Example showing the use of a producer class with ODEMx's default logging
+ * @since 3.0
+ */
+
+/**
+ * @example Example_Producer_LoggingManager.cpp
+ * The usage of ODEMx default logging is shown.
+ *
+ * The LoggingManager is responsible for managing default logging components.
+ * A simple call to @c enableDefaultLogging suffices to activate it. The
+ * parameters can be STDOUT, XML, or DATABASE. The latter two would then
+ * require another string to specify the location.
+ */
+
+#include "Example_Producer_StopWatch.h"
+
+int main() {
+	odemx::base::Simulation& sim = odemx::getDefaultSimulation();
+	sim.enableDefaultLogging( odemx::data::output::STDOUT );
+
+	StopWatch watch( sim, "Stop Watch" );
+	watch.start();
+	sim.setCurrentTime( 10 );
+	watch.stop();
+	//
+	// Even though, logging is disbled for the watch object, it will still
+	// produce warning messages because the failure-related channels cannot
+	// be deactivated.
+	//
+	watch.disableLogging();
+	watch.stop();
+}
diff --git a/odemx-lite/examples/Example_Producer_StopWatch.h b/odemx-lite/examples/Example_Producer_StopWatch.h
new file mode 100644
index 0000000000000000000000000000000000000000..1e64c90b29eba379ba3f90ceb75d19f36780f5ec
--- /dev/null
+++ b/odemx-lite/examples/Example_Producer_StopWatch.h
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_Producer_StopWatch.h
+ * @author Ronald Kluth
+ * @date created at 2010/04/13
+ * @brief Example showing the use of ODEMx log channels within a producer class
+ * @since 3.0
+*/
+
+/**
+ * @example Example_Producer_StopWatch.h
+ * The typical usage of ODEMx logging is shown.
+ *
+ * Since most ODEMx components are derived from odemx::data::Producer,
+ * it is actually quite easy to use the log channels provided by that
+ * base class. This example shows the definition of a log producing
+ * class that makes use of the channels @c info and @c error.
+ */
+
+#ifndef EXAMPLE_PRODUCER_STOPWATCH_H_
+#define EXAMPLE_PRODUCER_STOPWATCH_H_
+
+#include <odemx/odemx.h>
+
+class StopWatch: public odemx::data::Producer {
+public:
+	StopWatch( odemx::base::Simulation& sim, const odemx::data::Label& label )
+	:	Producer( sim, label ), running( false )
+	{}
+	void start() {
+		running = true;
+		startTime = getSimulation().getTime();
+		info << log( "started" );
+	}
+	void stop() {
+		if( running ) {
+			running = false;
+			info << log( "stopped" ).detail( "duration", getDuration() );
+		} else {
+			error << log( "StopWatch::stop(): stop watch is not running" );
+		}
+	}
+	odemx::base::SimTime getDuration() { return getSimulation().getTime()-startTime; }
+private:
+	bool running;
+	odemx::base::SimTime startTime;
+};
+
+#endif /* EXAMPLE_PRODUCER_STOPWATCH_H_ */
diff --git a/odemx-lite/examples/Example_ProtocolDevice.cpp b/odemx-lite/examples/Example_ProtocolDevice.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b994189d02afe9e8c4bfe780c5ff79d660c03467
--- /dev/null
+++ b/odemx-lite/examples/Example_ProtocolDevice.cpp
@@ -0,0 +1,239 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_ProtocolDevice.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/02
+ * @brief Example showing usage of the protocol simulation module
+ * @since 3.0
+*/
+
+/**
+ * @example Example_ProtocolDevice.cpp
+ * This example shows the simple communication protocol XCS with highest detail.
+ *
+ * Class Node uses a protocol stack to communicate with another node. The stack
+ * is composed of an entity class in the upper layer and a device in the
+ * lower layer. The communication runs over a medium which connects the
+ * devices of network nodes.
+ */
+
+#include <odemx/odemx.h>
+#include <iostream>
+
+using namespace odemx;
+using namespace odemx::protocol;
+using std::static_pointer_cast;
+
+typedef Service::AddressType Addr;
+typedef std::string SapName;
+//
+// PDU type used in the upper layer
+//
+struct StringData: Pdu
+{
+	typedef std::shared_ptr< StringData > Ptr;
+	Addr src, dest;
+	SapName destSap;
+	std::string data;
+
+	StringData( const Addr& src, const Addr& dest, const SapName& dSap,
+			const std::string& data )
+	:	src( src ), dest( dest ), destSap( dSap ), data( data )
+	{}
+	virtual PduPtr clone() const
+	{
+		return PduPtr( new StringData( src, dest, destSap , data ) );
+	}
+	virtual std::size_t getSize() const
+	{
+		return src.size() + dest.size() + destSap.size() + data.size() ;
+	}
+};
+//
+// PDU type used in the lower layer
+//
+struct TransmissionData: Pdu
+{
+	Addr& src;
+	Addr& dest;
+	StringData::Ptr payload;
+
+	TransmissionData( StringData::Ptr data )
+	:	src( data->src ), dest( data->dest ), payload( data )
+	{}
+	virtual PduPtr clone() const
+	{
+		return PduPtr( new TransmissionData( payload ) );
+	}
+	virtual std::size_t getSize() const
+	{
+		return payload->getSize();
+	}
+};
+//
+// The entity of the upper layer, which transforms StringData into
+// TransmissionData.
+//
+class XcsEntity: public Entity
+{
+public:
+	XcsEntity( base::Simulation& sim, const data::Label& label )
+	:	Entity( sim, label )
+	{
+		addSap( "XCSin" );
+		addSap( "CSout" );
+	}
+	virtual void handleInput( const std::string& sapName, PduPtr p )
+	{
+		if( sapName == "XCSin" )
+		{
+			StringData::Ptr pdu = static_pointer_cast< StringData >( p );
+			info << log( "send" );
+			send( "CSin", PduPtr( new TransmissionData( pdu ) ) );
+		}
+		else if( sapName == "CSout" )
+		{
+			StringData::Ptr pdu = static_pointer_cast< TransmissionData >( p )->payload;
+			info << log( "pass" );
+			pass( pdu->destSap, pdu );
+		}
+	}
+};
+//
+// Device class that sends data via the medium
+//
+class XcsDevice: public Device
+{
+public:
+	typedef TransmissionData PduType;
+
+	XcsDevice( base::Simulation& sim, const data::Label& label )
+	:	Device( sim, label )
+	{
+		addSap( "CSin" );
+	}
+	virtual void handleSend( const std::string& sap, PduPtr p )
+	{
+		info << log( "send" );
+		send( p );
+	}
+	virtual void handleReceive( PduPtr p )
+	{
+		info << log( "pass" );
+		pass( "CSout", p );
+	}
+	virtual base::SimTime computeTransmissionDuration( std::size_t pduSize )
+	{
+		return static_cast< base::SimTime >( pduSize );
+	}
+};
+//
+// Global medium
+//
+Medium medium( getDefaultSimulation(), "TransmissionMedium" );
+//
+// A stack factory function that creates the stack's layers and registers
+// service providers with them. The layers are then added to the stack
+// in top-down order.
+//
+std::auto_ptr< Stack > makeStack( base::Simulation& sim, const data::Label& label,
+		const Addr& address )
+{
+	Layer* entityLayer = new Layer( sim, label + " entity layer" );
+	entityLayer->addServiceProvider( new XcsEntity( sim, label + " entity" ) );
+	Layer* deviceLayer = new Layer( sim, label + " device layer" );
+	Device* device = new XcsDevice( sim, label + " device" );
+	deviceLayer->addServiceProvider( device );
+	medium.registerDevice( address, *device );
+
+	std::auto_ptr< Stack > stack( new Stack( sim, label ) );
+	stack->addLayer( entityLayer );
+	stack->addLayer( deviceLayer );
+	return stack;
+}
+//
+// Node is a very simple process that can either be a sender or a receiver,
+// depending on whether a reciever address is set. A stack is used to
+// facilitate the communication between nodes.
+//
+class Node: public base::Process
+{
+public:
+	Node( const data::Label& label, const Addr& addr, const Addr& recAddr = "" )
+	:	Process( getDefaultSimulation(), label )
+	,	stack_( makeStack( getSimulation(), getLabel(), addr ) )
+	,	address_( addr )
+	,	receiver_( recAddr )
+	,	isSender_( ! recAddr.empty() )
+	{
+		stack_->addReceiveSap( "XCSout" );
+	}
+	virtual int main()
+	{
+		if( isSender_ )
+		{
+			Sap* sap = stack_->getSap( "XCSin" );
+			StringData::Ptr pdu( new StringData( address_, receiver_, "XCSout", "message" ) );
+			info << log( "sending PDU via XCSin" )
+					.detail( "to", pdu->dest )
+					.detail( "data", pdu->data );
+			sap->write( pdu );
+		}
+		else
+		{
+			Sap* sap = stack_->getReceiveSap( "XCSout" );
+			while( true )
+			{
+				StringData::Ptr pdu = std::static_pointer_cast< StringData >( sap->read() );
+				info << log( "received PDU via XCSout" )
+						.detail( "from", pdu->src )
+						.detail( "data", pdu->data );
+			}
+		}
+		return 0;
+	}
+private:
+	std::auto_ptr< Stack > stack_;
+	Addr address_;
+	Addr receiver_;
+	bool isSender_;
+};
+
+//--------------------------------------------------------------------------main
+
+int main()
+{
+	base::Simulation& sim = getDefaultSimulation();
+	sim.addConsumer( data::channel_id::info,
+			data::output::OStreamWriter::create( std::cout ) );
+
+	Node sender( "Sender", "Addr0", "Addr1" );
+	Node receiver( "Receiver", "Addr1" );
+	sender.activate();
+	receiver.activate();
+	//
+	// Connect the devices of the two nodes by their addresses.
+	//
+	medium.addLink( "Addr0", "Addr1", 0 );
+	//
+	// Let the sender and receiver do their work.
+	//
+	sim.run();
+}
diff --git a/odemx-lite/examples/Example_ProtocolEntity.cpp b/odemx-lite/examples/Example_ProtocolEntity.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b9c705ce66b74f415ed88774e77d2bdfa2cd3899
--- /dev/null
+++ b/odemx-lite/examples/Example_ProtocolEntity.cpp
@@ -0,0 +1,230 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_ProtocolEntity.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/02
+ * @brief Example showing usage of the protocol simulation module
+ * @since 3.0
+*/
+
+/**
+ * @example Example_ProtocolEntity.cpp
+ * This example shows the simple communication protocol XCS with medium detail.
+ *
+ * Class Node uses a protocol stack to communicate with another node. The stack
+ * is composed of an entity class in the upper layer and a device in the
+ * lower layer. The communication runs directly between the connected service
+ * objects.
+ */
+
+#include <odemx/odemx.h>
+#include <iostream>
+
+using namespace odemx;
+using namespace odemx::protocol;
+using std::static_pointer_cast;
+
+typedef Service::AddressType Addr;
+typedef std::string SapName;
+//
+// PDU type used in the upper layer
+//
+struct StringData: Pdu
+{
+	typedef std::shared_ptr< StringData > Ptr;
+	Addr src, dest;
+	SapName destSap;
+	std::string data;
+
+	StringData( const Addr& src, const Addr& dest, const SapName& dSap,
+			const std::string& data )
+	:	src( src ), dest( dest ), destSap( dSap ), data( data )
+	{}
+	virtual PduPtr clone() const
+	{
+		return PduPtr( new StringData( src, dest, destSap , data ) );
+	}
+	virtual std::size_t getSize() const
+	{
+		return src.size() + dest.size() + destSap.size() + data.size() ;
+	}
+};
+//
+// PDU type used in the lower layer
+//
+struct TransmissionData: Pdu
+{
+	Addr& src;
+	Addr& dest;
+	StringData::Ptr payload;
+
+	TransmissionData( StringData::Ptr data )
+	:	src( data->src ), dest( data->dest ), payload( data )
+	{}
+	virtual PduPtr clone() const
+	{
+		return PduPtr( new TransmissionData( payload ) );
+	}
+	virtual std::size_t getSize() const
+	{
+		return payload->getSize();
+	}
+};
+//
+// The entity of the upper layer, which transforms StringData into
+// TransmissionData.
+//
+class XcsEntity: public Entity
+{
+public:
+	XcsEntity( base::Simulation& sim, const data::Label& label )
+	:	Entity( sim, label )
+	{
+		addSap( "XCSin" );
+		addSap( "CSout" );
+	}
+	virtual void handleInput( const std::string& sapName, PduPtr p )
+	{
+		if( sapName == "XCSin" )
+		{
+			info << log( "send" );
+			StringData::Ptr pdu = static_pointer_cast< StringData >( p );
+			send( "CSin", PduPtr( new TransmissionData( pdu ) ) );
+		}
+		else if( sapName == "CSout" )
+		{
+			info << log( "pass" );
+			StringData::Ptr pdu = static_pointer_cast< TransmissionData >( p )->payload;
+			pass( pdu->destSap, pdu );
+		}
+	}
+};
+//
+// Service implementation that transmits data directly to its peers.
+//
+class XcsService: public Service
+{
+public:
+	typedef TransmissionData PduType;
+
+	XcsService( base::Simulation& sim, const data::Label& label )
+	:	Service( sim, label )
+	{
+		addSap( "CSin" );
+	}
+	virtual void handleSend( const std::string& sap, PduPtr p )
+	{
+		info << log( "send" );
+		holdFor( p->getSize() );
+		send( std::static_pointer_cast< PduType >( p )->dest, p );
+	}
+	virtual void handleReceive( PduPtr p )
+	{
+		info << log( "pass" );
+		pass( "CSout", p );
+	}
+};
+//
+// A stack factory function that creates the stack's layers and registers
+// service providers with them. The layers are then added to the stack
+// in top-down order.
+//
+std::auto_ptr< Stack > makeStack( base::Simulation& sim, const data::Label& label,
+		const Addr& address )
+{
+	Layer* entityLayer = new Layer( sim, label + " entity layer" );
+	entityLayer->addServiceProvider( new XcsEntity( sim, label + " entity" ) );
+	Layer* serviceLayer = new Layer( sim, label + " service layer" );
+	Service* service = new XcsService( sim, label + " service" );
+	serviceLayer->addServiceProvider( service );
+	XcsService::registerService( address, *service );
+
+	std::auto_ptr< Stack > stack( new Stack( sim, label ) );
+	stack->addLayer( entityLayer );
+	stack->addLayer( serviceLayer );
+	return stack;
+}
+//
+// Node is a very simple process that can either be a sender or a receiver,
+// depending on whether a reciever address is set. A stack is used to
+// facilitate the communication between nodes.
+//
+class Node: public base::Process
+{
+public:
+	Node( const data::Label& label, const Addr& addr, const Addr& recAddr = "" )
+	:	Process( getDefaultSimulation(), label )
+	,	stack_( makeStack( getSimulation(), getLabel(), addr ) )
+	,	address_( addr )
+	,	receiver_( recAddr )
+	,	isSender_( ! recAddr.empty() )
+	{
+		stack_->addReceiveSap( "XCSout" );
+	}
+	virtual int main()
+	{
+		if( isSender_ )
+		{
+			Sap* sap = stack_->getSap( "XCSin" );
+			StringData::Ptr pdu( new StringData( address_, receiver_, "XCSout", "message" ) );
+			info << log( "sending PDU via XCSin" )
+					.detail( "to", pdu->dest )
+					.detail( "data", pdu->data );
+			sap->write( pdu );
+		}
+		else
+		{
+			Sap* sap = stack_->getReceiveSap( "XCSout" );
+			while( true )
+			{
+				StringData::Ptr pdu = std::static_pointer_cast< StringData >( sap->read() );
+				info << log( "received PDU via XCSout" )
+						.detail( "from", pdu->src )
+						.detail( "data", pdu->data );
+			}
+		}
+		return 0;
+	}
+private:
+	std::auto_ptr< Stack > stack_;
+	Addr address_;
+	Addr receiver_;
+	bool isSender_;
+};
+
+//--------------------------------------------------------------------------main
+
+int main()
+{
+	base::Simulation& sim = getDefaultSimulation();
+	sim.addConsumer( data::channel_id::info,
+			data::output::OStreamWriter::create( std::cout ) );
+
+	Node sender( "Sender", "Addr0", "Addr1" );
+	Node receiver( "Receiver", "Addr1" );
+	//
+	// Since the service objects of both nodes' stacks are connected
+	// upon construction, the sending of data will work automatically.
+	// No links need be set.
+	//
+	sender.activate();
+	receiver.activate();
+	sim.run();
+}
diff --git a/odemx-lite/examples/Example_ProtocolService.cpp b/odemx-lite/examples/Example_ProtocolService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9d990e5139b56d606c77af8ef6f6085cd26eb48c
--- /dev/null
+++ b/odemx-lite/examples/Example_ProtocolService.cpp
@@ -0,0 +1,161 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_ProtocolService.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/01
+ * @brief Example showing usage of the protocol simulation module
+ * @since 3.0
+*/
+
+/**
+ * @example Example_ProtocolService.cpp
+ * This example shows the simple communication protocol XCS with lowest detail.
+ *
+ * Class Node uses a simple service implementation to communicate with
+ * another node. We abstract from the stack as well as the network topology.
+ * The communication runs directly between the connected service
+ * objects.
+ */
+
+#include <odemx/odemx.h>
+#include <iostream>
+
+using namespace odemx;
+using namespace odemx::protocol;
+using std::static_pointer_cast;
+
+typedef Service::AddressType Addr;
+typedef std::string SapName;
+//
+// PDU type used for data transfer between nodes
+//
+struct StringData: Pdu
+{
+	typedef std::shared_ptr< StringData > Ptr;
+	Addr src, dest;
+	SapName destSap;
+	std::string data;
+
+	StringData( const Addr& src, const Addr& dest, const SapName& dSap,
+			const std::string& data )
+	:	src( src ), dest( dest ), destSap( dSap ), data( data )
+	{}
+	virtual PduPtr clone() const
+	{
+		return PduPtr( new StringData( src, dest, destSap , data ) );
+	}
+	virtual std::size_t getSize() const
+	{
+		return src.size() + dest.size() + destSap.size() + data.size() ;
+	}
+};
+//
+// Simple service implementation that waits before sending the data in
+// order to model a transmission duration.
+//
+class XcsService: public Service
+{
+public:
+	typedef StringData PduType;
+
+	XcsService( base::Simulation& sim, const data::Label& label )
+	:	Service( sim, label )
+	{
+		addSap( "XCSin" );
+	}
+	virtual void handleSend( const std::string& sap, PduPtr p )
+	{
+		info << log( "send" );
+		holdFor( p->getSize() );
+		send( static_pointer_cast< PduType >( p )->dest, p );
+	}
+	virtual void handleReceive( PduPtr p )
+	{
+		info << log( "pass" );
+		pass( static_pointer_cast< PduType >( p )->destSap, p );
+	}
+};
+//
+// Node is a very simple process that can either be a sender or a receiver,
+// depending on whether a receiver address is set. In the simplest form, a
+// service object is used to facilitate the communication between nodes.
+//
+class Node: public base::Process
+{
+public:
+	Node( const data::Label& label, const Addr& addr, const Addr& recAddr = "" )
+	:	Process( getDefaultSimulation(), label )
+	,	service_( getSimulation(), label + " service" )
+	,	address_( addr )
+	,	receiver_( recAddr )
+	,	isSender_( ! recAddr.empty() )
+	{
+		service_.addReceiveSap( "XCSout" );
+		XcsService::registerService( addr, service_ );
+	}
+	virtual int main()
+	{
+		if( isSender_ )
+		{
+			Sap* sap = service_.getSap( "XCSin" );
+			StringData::Ptr pdu( new StringData( address_, receiver_, "XCSout", "message" ) );
+			info << log( "sending PDU via XCSin" )
+					.detail( "to", pdu->dest )
+					.detail( "data", pdu->data );
+			sap->write( pdu );
+		}
+		else
+		{
+			Sap* sap = service_.getReceiveSap( "XCSout" );
+			while( true )
+			{
+				StringData::Ptr pdu = static_pointer_cast< StringData >( sap->read() );
+				info << log( "received PDU via XCSout" )
+						.detail( "from", pdu->src )
+						.detail( "data", pdu->data );
+			}
+		}
+		return 0;
+	}
+private:
+	XcsService service_;
+	Addr address_;
+	Addr receiver_;
+	bool isSender_;
+};
+
+//--------------------------------------------------------------------------main
+
+int main()
+{
+	base::Simulation& sim = getDefaultSimulation();
+	sim.addConsumer( data::channel_id::info,
+			data::output::OStreamWriter::create( std::cout ) );
+
+	Node sender( "Sender", "Addr0", "Addr1" );
+	Node receiver( "Receiver", "Addr1" );
+	//
+	// Since registered service objects are connected automaticallly,
+	// the sending of data will work automatically. No links need be set.
+	//
+	sender.activate();
+	receiver.activate();
+	sim.run();
+}
diff --git a/odemx-lite/examples/Example_Res.cpp b/odemx-lite/examples/Example_Res.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1c02fd7959bef8973edcb1133f896492896d14a0
--- /dev/null
+++ b/odemx-lite/examples/Example_Res.cpp
@@ -0,0 +1,291 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_Res.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/02/11
+ * @brief Example for basic simulation techniques using a limited resource
+ * @since 3.0
+ */
+
+/**
+ * @example Example_Res.cpp
+ *
+ * This example shows the basic techniques for simulating a limited resource
+ * with ODEMx. The class with the limited resource is a gas station with only
+ * two gas pumps.
+ *
+ * Cars are generated by a self-scheduling event until its counter reaches 0.
+ * When the car processes are activated, they enter the gas station and thereby
+ * try to acquire a resource - one of the pumps. If both pumps are in use, they
+ * will automatically wait their turn in a queue provided by an odemx::synchronization::Res
+ * object.
+ */
+
+#include <odemx/odemx.h>
+
+#include <iostream>
+#include <vector>
+//#include <cstdlib>
+#ifdef _MSC_VER
+#include <memory>
+#else
+#include <memory>
+#endif
+
+
+// short namespace alias
+namespace Rand = odemx::random;
+
+// forward declarations
+class Car;
+odemx::base::SimTime getRandomTime( Rand::ContinuousDist& dist );
+
+//--------------------------------------------------------------------GasStation
+//
+// This passive class models a very simple gas station that only has two pumps
+// and no other attributes. The pumps are represented by a Res object with two
+// initial tokens and a maximum token limit of two.
+//
+class GasStation
+{
+public:
+	typedef std::shared_ptr< GasStation > Ptr;
+
+	GasStation(): gasPumps_( odemx::getDefaultSimulation(), "Gas Pumps", 2, 2 ) {}
+	void enter();
+	void leave();
+private:
+	odemx::synchronization::Res gasPumps_;
+};
+
+//---------------------------------------------------------------------------Car
+//
+// Cars are modeled as very simple processes that do nothing else but enter
+// the station and leave it once they have been refueled. The only attributes
+// of this class are a reference to the gas station it uses and another
+// reference to a random number generator for randomized refuel periods.
+//
+class Car: public odemx::base::Process
+{
+public:
+	typedef std::shared_ptr< Car > Ptr;
+
+	Car( GasStation& station, Rand::ContinuousDist& refuelTime )
+	:	Process( odemx::getDefaultSimulation(), "Car" )
+	,	station_( station )
+	,	refuelTime_( refuelTime )
+	{}
+	virtual int main();
+	void refuel();
+private:
+	GasStation& station_;
+	Rand::ContinuousDist& refuelTime_;
+};
+
+//-----------------------------------------------------------------------Arrival
+//
+// This event class describes the arrival of a new car. It is a generator for
+// new cars, which are activated (scheduled) right after the event action is
+// finished. The number of cars to be generated is set in the constructor.
+// This class also provides memory management by using a vector to keep track
+// of all cars it creates.
+//
+class Arrival: public odemx::base::Event
+{
+public:
+	typedef std::shared_ptr< Arrival > Ptr;
+
+	Arrival( GasStation& station, unsigned int count,
+			Rand::ContinuousDist& arrivalTime,
+			Rand::ContinuousDist& refuelTime )
+	:	Event( odemx::getDefaultSimulation(), "Car Arrival Event" )
+	,	station_( station )
+	,	count_( count )
+	,	arrivalTime_( arrivalTime )
+	,	refuelTime_( refuelTime )
+	{}
+	virtual void eventAction();
+	void scheduleAtRandomTime();
+private:
+	GasStation& station_;
+	unsigned int count_;
+	Rand::ContinuousDist& arrivalTime_;
+	Rand::ContinuousDist& refuelTime_;
+	// automatic memory management
+	std::vector< Car::Ptr > generatedCars_;
+};
+
+//------------------------------------------------------------method definitions
+//
+// Entering the gas station is modeled by acquiring a resource (a gas pump).
+// If none is available, the caller's execution will automatically be blocked
+// and it will be inserted into a queue to wait its turn.
+//
+void GasStation::enter()
+{
+	gasPumps_.acquire( 1 );
+}
+//
+// Leaving the gas station is modeled by the release of an acquired resource.
+//
+void GasStation::leave()
+{
+	gasPumps_.release( 1 );
+}
+//
+// The car's described behavior only covers the entering and leaving of the
+// gas station. If it cannot be serviced right away, the call to enter() will
+// block the execution of main(). Once it was allowed to enter, the car can be
+// refueled. After waiting for a random amount of refueling time, the car leaves
+// the gas station.
+//
+int Car::main()
+{
+	info << log( "is entering the station" );
+	station_.enter();
+	info << log( "is refueling" );
+	holdFor( getRandomTime( refuelTime_ ) );
+	station_.leave();
+	info << log( "has left the station" );
+	return 0;
+}
+//
+// The action associated with an arrival event is the creation and activation
+// of a new car. After that, the event object reschedules itself after a random
+// period of time.
+//
+void Arrival::eventAction()
+{
+	Car::Ptr car( new Car( station_, refuelTime_ ) );
+	car->activate();
+	info << log( "activated car" ).detail( "name", car->getLabel() );
+	generatedCars_.push_back( car );
+
+	if( count_ > 0 )
+	{
+		--count_;
+		this->scheduleIn( getRandomTime( arrivalTime_ ) );
+	}
+}
+
+//--------------------------------------------------------------------------main
+
+int main( int argc, char* argv[] )
+{
+	using namespace odemx;
+	using namespace odemx::data::output;
+	using odemx::base::Simulation;
+	//
+	// Check command line arguments: we require a number for gas stations.
+	//
+	if( argc != 2 )
+	{
+		std::cerr << "Usage: " << argv[0] << " <station count>" << std::endl;
+		return -1;
+	}
+	//
+	// Get the station count and check for error.
+	//
+	int stationCount = std::atoi( argv[1] );
+	if( stationCount < 1 )
+	{
+		std::cerr << "Error: station count < 1" << std::endl;
+	}
+	//
+	// In our class definitions, we have only used Process and Event
+	// constructors without a Simulation parameter, thereby using the
+	// default simulation context. Here, we get a reference to it.
+	//
+	Simulation& sim = getDefaultSimulation();
+	//
+	// Every simulation run should be characterized by a description of the
+	// goals to be achieved.
+	//
+	sim.setDescription( "Simulation of a basic limited resource." );
+	//
+	// The simulation context can handle logging automatically and will use
+	// sensible defaults. All log records will be logged to a rotating
+	// XML file writer, while warnings and errors are also sent to stderr.
+	// Furthermore, all statistical records will be computed and buffered
+	// internally. A call to reportStatistics() will create an XML report.
+	//
+	sim.enableDefaultLogging( STDOUT );
+	//
+	// Only after setting log data consumers to the channels will log records
+	// be visible. We initialize all other simulation elements after calling
+	// enableDefaultLogging() to make sure we capture all log data.
+	//
+	// We use two random number generators for random time periods. One
+	// influences the arrival frequency of new cars, and the other is used for
+	// random refueling periods.
+	//
+	Rand::Normal randomArrival( sim, "Arrival Time", 5, 2 );
+	Rand::Normal randomRefueling( sim, "Refueling Time", 10, 5 );
+	//
+	// Create the needed objects: a number of gas stations, and the
+	// corresponding car generators. (We use vectors with shared pointers to
+	// objects for automatic memory management.)
+	//
+	std::vector< Arrival::Ptr > arrivalEvents;
+	std::vector< GasStation::Ptr > stations;
+	do
+	{
+		GasStation::Ptr newStation( new GasStation() );
+
+		Arrival::Ptr newCarGenerator(
+				new Arrival( *newStation, 10, randomArrival, randomRefueling ) );
+		//
+		// Schedule the car generator for its initial execution.
+		//
+		newCarGenerator->scheduleIn( getRandomTime( randomArrival ) );
+
+		stations.push_back( newStation );
+		arrivalEvents.push_back( newCarGenerator );
+	}
+	while( --stationCount );
+	//
+	// Start the simulation and let it run until the schedule is empty.
+	//
+	sim.run();
+	//
+	// Output a statistics report computed from the default log. In this case,
+	// it will contain usage data about the random number generators, the
+	// resource objects (gas pumps) and their internal queues.
+	//
+	sim.reportDefaultStatistics( STDOUT );
+	sim.reportDefaultStatistics( XML, "basicResourceStatistics.xml" );
+	return 0;
+}
+//
+// Since random number generators sometimes also generate negative values,
+// we cannot simply use samples as time values. This helper function ensures
+// that only values greater than or equal to zero are returned.
+//
+odemx::base::SimTime getRandomTime( Rand::ContinuousDist& dist )
+{
+	odemx::base::SimTime retVal;
+	do
+	{
+		retVal = (odemx::base::SimTime) dist.sample();
+	}
+	while( retVal <= 0 );
+
+	return retVal;
+}
diff --git a/odemx-lite/examples/Example_Shop.cpp b/odemx-lite/examples/Example_Shop.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..482542504bd118c7e68a2b51081f6c0c6ceb15ca
--- /dev/null
+++ b/odemx-lite/examples/Example_Shop.cpp
@@ -0,0 +1,872 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Example_Shop.cpp
+
+	\author Ralf Gerstenberger
+
+	\date created at 2003/07/15
+
+	\brief Shop example with ODEMx
+
+	This example shows more advanced techniques to
+	realize a process simulation with ODEMx.
+
+\since 1.0
+*/
+/** \example Example_Shop.cpp
+	In this example, a shop which is selling different
+	goods to customers is simulated. Shop-assistants handle
+	the final payment after a customer has gathered their
+	goods from the shelves in the shop. Each shelf is
+	holding a limited amount of one commodity. If a shelf
+	runs out of its commodity, a shop-assistant has to
+	restock the shelf. There is also a shopkeeper, who
+	employs the shop-assistants and orders goods, if the
+	store room of the shop is running out of any. Finally,
+	there is a process generating new customers after a
+	random delay.
+*/
+
+//
+// Includes
+//
+// We include the main ODEMx header file odemx.h which in
+// turn includes the other header files of ODEMx. All
+// header files of ODEMx define a macro when included,
+// to prevent repetitive inclusion. That means it doesn't
+// hurt to include a header file more than once, because
+// subsequent inclusions are ignored.
+//
+#include <odemx/odemx.h>
+//
+// Apart from ODEMx we use some C++ standard features in
+// this simulation.
+//
+#include <iostream>
+#include <fstream>
+#include <list>
+#include <string>
+#include <vector>
+
+//
+// Namespaces
+//
+// All ODEMx classes reside in a sub-namespace of namespace odemx
+// to prevent naming conflicts. In this simulation it is safe to
+// import several odemx namespaces into the global namespace.
+//
+using namespace odemx::base;
+using namespace odemx::data;
+using namespace odemx::data::output;
+using namespace odemx::random;
+using namespace odemx::synchronization;
+using namespace std;
+
+//
+// Global parameters
+//
+// To simplify matters we use global parameters in this example.
+// That is, however, not recommended in general. A better place
+// for simulation parameters is the specific simulation class.
+//
+// GOODS contains the different commodities sold in the shop.
+//
+static const string GOODS[] = {"Apple", "Bananas", "Bread", "Butter", "Candies",
+							  "Cheese", "Chips", "Chocolate", "Mixed-pickles", "Fish",
+							  "Jam", "Juice", "Lemon", "Lemonade", "Marmalade",
+							  "Milk", "Orange", "Pepper", "Pineapples", "Pork",
+							  "Salami", "Salt", "Sugar", "Tomatoes", "Water"};
+
+//
+// NUMBER_OF_GOODS is used in many for-loops as the end-condition.
+//
+static const int NUMBER_OF_GOODS = 25;
+
+//
+// INIT_STOCK is the initial amount of each good held in the
+// store room.
+//
+static const int INIT_STOCK = 50;
+
+//
+// INIT_TILLS is the initial number of tills available.
+//
+static const int INIT_TILLS = 5;
+
+//
+// INIT_PERSONNEL is the initial number of shop-assistants
+// employed by the shopkeeper.
+//
+static const int INIT_PERSONNEL = 8;
+
+//
+// SHELF_CAPACITY defines the capacity of a shelf. The capacity
+// is measured in items, not in size. That means every shelf
+// holds up to SHELF_CAPACITY items of its commodity.
+//
+static const int SHELF_CAPACITY = 15;
+
+//
+// ACCEPTED_QUEUE_LENGTH defines the queue length after
+// which a shop-assistant will help out at the tills.
+//
+static const int ACCEPTED_QUEUE_LENGTH = 5;
+
+//
+// ACCEPTED_SHELF_STOCK defines the number of items in
+// a shelf after which the shelf has to be refilled.
+//
+static const int ACCEPTED_SHELF_STOCK = 5;
+
+//
+// The following parameters define delays for payment,
+// for refilling shelves, for taking goods from a shelf, for moving
+// between shelves, and they define the time after which the shopkeeper
+// is checking the store room of the shop again.
+//
+static const SimTime PAYMENT_DELAY = 5;
+static const SimTime RESTOCK_DELAY = 15;
+static const SimTime TAKE_DELAY = 1;
+static const SimTime MOVE_DELAY = 1;
+static const SimTime STOCKKEEPER_DELAY = 60;
+
+//
+// Pre-declarations
+//
+class Shelf;
+class Tills;
+class Shopkeeper;
+class Assistant;
+class Customer;
+class CustomerGen;
+
+//
+// Classes
+//
+
+//
+// The class ShopSim is derived from Simulation and provides
+// access to some important objects of this simulation. All
+// classes which have a pointer to ShopSim can use the get*
+// methods to get these objects. In addition we could move
+// the global parameters to this class. ShopSim also
+// does some initializations in its constructor and the
+// initSimulation() function.
+//
+class ShopSim : public Simulation
+{
+	// Shelves in the shop, one for each commodity
+	vector<Shelf*>		shelves;
+	// Back-store for refilling shelves
+	vector<int>			stock;
+	// Customers pay at one of the tills
+	Tills*				tills;
+
+	Shopkeeper*			boss;
+	CustomerGen*		generator;
+
+	// Random number generators
+	RandomInt				*rng5, *rng10, *rng;
+	NegativeExponential*				delay;
+
+	// Assistant-management
+	CondQ*				work;
+
+public:
+	// Construction and initialisation
+	ShopSim();
+	virtual void initSimulation();
+
+	// get*() methods
+	vector<Shelf*>& getShelves() {return shelves;}
+	vector<int>& getStock() {return stock;}
+	Tills* getTills() {return tills;}
+
+	Shopkeeper* getBoss() {return boss;}
+	CustomerGen* getCustomerGen() {return generator;}
+
+	DiscreteDist* getRNG() {return rng;}
+	DiscreteDist* getRNG5() {return rng5;}
+	DiscreteDist* getRNG10() {return rng10;}
+	ContinuousDist* getDelay() {return delay;}
+
+	CondQ* getWork() {return work;}
+};
+
+//
+// Shelf represents a shelf in our shop. Every shelf
+// contains one commodity and provides methods for
+// customers to take goods. The shop-assistants refill
+// a shelf if its running out of stock.
+// The management of commodity items held in a shelf
+// is realised with the ODEMx standard component Res.
+//
+class Shelf
+{
+	// Pointer to ShopSim
+	ShopSim* sim;
+
+	// The type of commodity presented in this shelf
+	int type;
+
+	// The amount of goods left in this shelf
+	Res commodity;
+
+public:
+	// Construction
+	Shelf(ShopSim* s, int t);
+
+	// Type of commodity presented in this shelf
+	int getType() const {return type;}
+
+	// Customers use this method to take goods.
+	int takeCommodity(int n);
+
+	// Assistants use this method to restock the shelf.
+	int fillShelf(int n);
+
+	// Assistants use this method to check the stock.
+	int checkStock() const {return commodity.getTokenNumber();}
+};
+
+//
+// After taking their goods, customers go to the tills
+// to pay. There are several tills available but a till
+// also needs to be handled by a shop-assistant to be active.
+// The payment is managed with the ODEMx standard component
+// WaitQ which realizes the synchronization between customers
+// giving the money and shop-assistants taking it. The Tills
+// also collect statistic data about the number of assistants
+// by using the ODEMx class Accum.
+//
+class Tills
+{
+	// Pointer to ShopSim
+	ShopSim* sim;
+
+	// Customers wait in a WaitQ for service.
+	WaitQ	queue;
+
+	// Tills keep statistics about the assistants.
+	odemx::statistics::Accumulate* statistic;
+
+	// The number of assistants handling the tills.
+	int cashier;
+
+	// The number of tills available.
+	int tills;
+
+public:
+	// Construction
+	Tills(ShopSim* s);
+
+	// Customers use the method pay() to enter the queue (enqueue) at the
+	// tills and to pay.
+	void pay();
+
+	// Assistants use take to get the next customer.
+	Customer* take();
+
+	// The number of shop-assistants who take the payment changes,
+	// updated with updateCashier().
+	void updateCashier(int n);
+
+	// get* methods
+	int getQueueLength() const {return queue.getWaitingSlaves().size();}
+	int getCashier() const {return cashier;}
+	int getTills() const {return tills;}
+};
+
+//
+// The shopkeeper is responsible for the employment of shop-assistants
+// and the ordering of goods. The class Shopkeeper is derived from
+// Process and defines the behaviour of the shopkeeper by implementing
+// the function main().
+//
+class Shopkeeper : public Process
+{
+public:
+	// Construction
+	Shopkeeper(ShopSim& sim);
+
+	// Behaviour
+	virtual int main();
+};
+
+//
+// Shop-assistants represent the work-force driving the shop. They
+// refill the shelves or handle a till. The class Assistant defines
+// the behavior of the shop assistants by implementing main().
+// Shop assistants decide on their own which task they fulfil
+// next (handle a till or refill shelves). If neither is required
+// they wait for work in a conditional queue provided by ODEMx and
+// kept in the ShopSim class (ShopSim::work).
+//
+class Assistant : public Process
+{
+public:
+	// Construction
+	Assistant(ShopSim& sim);
+
+	// Behaviour
+	virtual int main();
+
+	// chooseWork and work are used to find the next task for an
+	// assistant or to wait for work.
+	int chooseWork();
+	bool work();
+};
+
+//
+// This class represents the customers in this simulation.
+// Customers have (random) demand which they try to fulfil
+// by taking goods from the shelves. Finally, a customer pays
+// for the taken goods at the tills.
+//
+class Customer : public Process
+{
+	// The customer's demand.
+	vector<int>	 demand;
+
+	// The goods in the customer's basket.
+	vector<int>	 basket;
+
+public:
+	// Construction
+	Customer(ShopSim& sim);
+
+	// Behaviour
+	virtual int main();
+};
+
+//
+// The Customers are randomly created by CustomerGen. By this means
+// we achieve an approximation of the customer-flow in our shop.
+//
+class CustomerGen : public Process
+{
+public:
+	// Construction
+	CustomerGen(ShopSim& sim);
+
+	// Behaviour
+	virtual int main();
+};
+
+//
+// Implementations of member functions
+//
+
+//
+// Construction of a ShopSim object itself and some other major
+// objects.
+//
+ShopSim::ShopSim() :
+	Simulation("ShopSim"),
+	shelves(NUMBER_OF_GOODS),
+	stock(NUMBER_OF_GOODS)
+{
+	// Create and initialise shelves, one shelf for each commodity.
+	for (int i=0; i<NUMBER_OF_GOODS; ++i)
+	{
+		shelves[i] = new Shelf(this, i);
+		stock[i] = INIT_STOCK;
+	}
+
+	// Create the tills, the boss, and the customer generator.
+	tills = new Tills(this);
+	boss = new Shopkeeper(*this);
+	generator = new CustomerGen(*this);
+
+	// Create the random number generators.
+	// RandomInt and NegativeExponential are provided by ODEMx.
+	rng = new RandomInt(*this, "RNG", 0, NUMBER_OF_GOODS -1);
+	rng5 = new RandomInt(*this, "RNG", 0, 5);
+	rng10 = new RandomInt(*this, "RNG", 0, 10);
+	delay = new NegativeExponential(*this, "Delay", 0.125);
+
+	// Finally, the CondQ work is created and added to the report.
+	work = new CondQ(*this, "Work");
+}
+
+//
+// initSimulation is called before the simulation starts. We
+// use this function to activate the boss and the customer
+// generator. They in turn create the other processes.
+// The initSimulation function is sort of an entry-point
+// of a simulation. It is called before the simulation
+// starts and is the best place to activate the first processes
+// of a simulation.
+//
+void ShopSim::initSimulation()
+{
+	boss->activate();
+	generator->activate();
+}
+
+//
+// Construction of a Shelf object.
+//
+Shelf::Shelf(ShopSim* s, int t) :
+	sim(s),
+	type(t),
+	commodity(*s, ("Shelf_" + GOODS[t]), 0, SHELF_CAPACITY)
+{
+	// Shelf is using a Res object to manage the amount of goods
+	// available. Res is providing some report about its usage.
+}
+
+//
+// fillShelf is used by the shop-assistants to restock the shelf.
+// In this version the function is only a wrapper to the release
+// method of the Res object which is actually managing the available
+// goods.
+//
+int Shelf::fillShelf(int n)
+{
+	commodity.release(n);
+	return commodity.getTokenNumber();
+}
+
+//
+// takeCommodity is used by the customers to get the goods. We
+// could just relay the call to commodity.acquire(). But then a
+// customer would wait until there are enough items available.
+// Instead we signal the shop-assistants the need to refill a
+// shelf and give the customer only the items available.
+//
+int Shelf::takeCommodity(int n)
+{
+	int avail = commodity.getTokenNumber();
+
+	if (avail > n)
+	{
+		commodity.acquire(n);
+		return n;
+	}
+	else
+	{
+		commodity.acquire(avail);
+		sim->getWork()->signal();
+		return avail;
+	}
+}
+
+//
+// Construction of the Tills object.
+//
+Tills::Tills(ShopSim* s) :
+	sim(s),
+	queue(*s, "Tills queue"),
+	cashier(0),
+	tills(INIT_TILLS)
+{
+	// Tills is providing some additional statistics about
+	// the number of assistants handling the tills.
+	statistic = new odemx::statistics::Accumulate( *sim, "Tills statistics");
+}
+
+//
+// Payment is done by the functions pay and take. There are
+// two objects working together to handle payment. A customer
+// giving the money and a shop-assistant taking it. Both have to
+// be synchronised. Tills uses the standard ODEMx synchronisation
+// object WaitQ to do this.
+//
+void Tills::pay()
+{
+	// Every time a customer wants to pay, waiting assistants
+	// are signaled.
+	sim->getWork()->signal();
+
+	// The synchronisation between a customer (who wants
+	// to pay) and an assistant is realised with WaitQ. WaitQ
+	// manages not only the synchronisation but also provides
+	// statistics. The wait() function used here adds the
+	// current process (the one that has just called pay()) to the
+	// queue.
+	queue.wait();
+}
+
+//
+// Assistants use take to get the next customer.
+//
+Customer* Tills::take()
+{
+	Process* p = 0;
+
+	// The coopt() function of WaitQ returns the next Customer
+	// in the queue(sorted according to priority and time of arrival).
+	// If there is no customer left the current process
+	// (the one that has just called take()) waits.
+	p = queue.coopt();
+
+	return (Customer*) p;
+}
+
+//
+// The number of assistants working at the tills is updated
+// with this function. In this function the statistic about
+// assistants handling tills is also updated.
+//
+void Tills::updateCashier(int n)
+{
+	cashier += n;
+	statistic->update(sim->getTime(), cashier);
+}
+
+//
+// Construction of Assistant objects.
+//
+Assistant::Assistant(ShopSim& sim) :
+	Process(sim, "Assistant")
+{}
+
+//
+// Assistant is derived from Process. That means it has to
+// provide its own main() function, where it defines the actions
+// done by an Assistant.
+//
+int Assistant::main()
+{
+	//
+	// At first we cache pointers to our simulation
+	// and to the tills.
+	//
+	ShopSim& sim = dynamic_cast< ShopSim& >( getSimulation() );
+	Tills* tills = sim.getTills();
+
+	while (true)
+	{
+		//
+		// Wait for something to do:
+		// Assistants have to do two different tasks.
+		// If required they handle a till to collect
+		// payment from the customers. Otherwise they go
+		// through the shop and refill empty shelves.
+		// If neither is required they wait for work.
+		// ShopSim uses the ODEMx synchronisation object
+		// CondQ to keep track of waiting Assistants.
+		// CondQ allows processes to wait for certain
+		// conditions defined by a condition call-back
+		// function. Assistant's member function work()
+		// was designed to define the condition when an
+		// Assistant has to act.
+		// The first real action of an assistant is to
+		// wait for a task.
+		//
+		sim.getWork()->wait([&](Process* self) {
+			return static_cast<Assistant*>(self)->work();
+		});
+
+		//
+		// Choose your work:
+		// The function chooseWork() determines what has
+		// to be done. It returns 1 if an assistant is
+		// needed at the tills and 2 if a shelf has to be
+		// refilled.
+		if (chooseWork()==1)
+		{
+			//
+			// Cashier task
+			//
+
+			// update number of assistants at the tills
+			tills->updateCashier(1);
+
+			// serve customers as long as there are any
+			while (tills->getQueueLength()>0)
+			{
+				// get the next customer in queue
+				Customer* c = tills->take();
+
+				// payment does take some time
+				holdFor(PAYMENT_DELAY);
+
+				// finally, activate the customer
+				// to let them leave the store
+				c->activate();
+			}
+
+			// update number of assistants at the tills
+			tills->updateCashier(-1);
+		}
+		else
+		{
+			//
+			// Restock task
+			//
+
+			// The assistant goes through all shelves and
+			// refills if necessary and possible.
+			vector<Shelf*>::iterator i;
+			for (i=sim.getShelves().begin(); i!=sim.getShelves().end(); ++i)
+			{
+				// We cache some pointer.
+				Shelf* shelf = *i;
+				vector<int>& stock = sim.getStock();
+				int type = shelf->getType();
+
+				if (shelf->checkStock() < ACCEPTED_SHELF_STOCK &&
+					stock[type] > 0)
+				{
+					// A shelf is filled up to its capacity
+					// if possible.
+					int n = SHELF_CAPACITY - shelf->checkStock();
+					if (stock[type] < n)
+						n = stock[type];
+
+					shelf->fillShelf(n);
+					stock[type] -= n;
+
+					// refilling takes time
+					holdFor(RESTOCK_DELAY);
+				}
+			}
+		}
+	}
+
+	// This one will never be reached.
+	return 0;
+}
+
+//
+// chooseWork() decides which task should be done.
+//
+int Assistant::chooseWork()
+{
+	ShopSim& sim = dynamic_cast< ShopSim& >( getSimulation() );
+	vector<Shelf*>::iterator i;
+
+	// If the queue at the tills has exceeded an acceptable
+	// length and we have a free till without an assistant,
+	// the assistant should work at it.
+	if (sim.getTills()->getQueueLength() >= ACCEPTED_QUEUE_LENGTH &&
+		sim.getTills()->getCashier() < sim.getTills()->getTills())
+		return 1;
+
+	// Otherwise, if there is a shelf out of stock while we have
+	// still goods left, the assistant should go on the refill-route.
+	for (i=sim.getShelves().begin(); i!=sim.getShelves().end(); ++i)
+	{
+		if ((*i)->checkStock()<ACCEPTED_SHELF_STOCK &&
+			(sim.getStock())[(*i)->getType()] > 0)
+			return 2;
+	}
+
+	// If neither is required the assistant should wait.
+	return 0;
+}
+
+//
+// The condition call-back work() uses the function chooseWork()
+// to find something to do.
+//
+bool Assistant::work()
+{
+	return chooseWork()!=0;
+}
+
+//
+// Construction of the Shopkeeper object.
+//
+Shopkeeper::Shopkeeper(ShopSim& sim) :
+	Process(sim, "Shopkeeper")
+{}
+
+//
+// Like Assistant Shopkeeper is a Process and has to
+// define its behaviour in the main() function.
+//
+int Shopkeeper::main()
+{
+	ShopSim& sim = dynamic_cast< ShopSim& >( getSimulation() );
+
+	//
+	// The first task of the shopkeeper is to employ
+	// some shop-assistants.
+	//
+	int i;
+	for (i=0; i<INIT_PERSONNEL; ++i)
+	{
+		Assistant* person = new Assistant(sim);
+		person->activate();
+	}
+
+	//
+	// Afterwards the only thing the shopkeeper has to do
+	// is to look after the stock of goods in his shop.
+	//
+	while (true)
+	{
+		//
+		// Order goods:
+		// We check all goods; if something runs out
+		// we fill it up again.
+		//
+		vector<int>& stock = sim.getStock();
+		for (i=0; i<NUMBER_OF_GOODS; ++i)
+		{
+			if (stock[i]==0) stock[i]=INIT_STOCK;
+		}
+
+		//
+		// Wait some time
+		//
+		holdFor(STOCKKEEPER_DELAY);
+	}
+
+	return 0;
+}
+
+//
+// Construction of the Customer objects.
+//
+Customer::Customer(ShopSim& sim) :
+	Process(sim , "Customer"),
+	demand(NUMBER_OF_GOODS),
+	basket(NUMBER_OF_GOODS)
+{}
+
+//
+// The Customer wants a random amount of a random number of
+// commodities. The customer tries to take the desired items
+// from the shelves, pays at the tills, and finally, leaves the
+// simulation.
+//
+int Customer::main()
+{
+	// We cache some pointer.
+	ShopSim& sim = dynamic_cast< ShopSim& >( getSimulation() );
+	vector<Shelf*>& shelves = sim.getShelves();
+	Tills* tills = sim.getTills();
+	DiscreteDist* rng = sim.getRNG();
+	DiscreteDist* rng5 = sim.getRNG5();
+	DiscreteDist* rng10 = sim.getRNG10();
+
+	//
+	// Init wish-list
+	//
+	int i;
+
+	// A customer wants up to 10 different types of goods.
+	int numberOfItems = rng10->sample();
+	for (i=0; i<numberOfItems; ++i)
+	{
+		int type = rng->sample();
+		int amount = rng5->sample();
+
+		demand[type] = amount;
+	}
+
+	//
+	// Get goods from shelves
+	//
+	for (i=0; i<NUMBER_OF_GOODS; ++i)
+	{
+		if (demand[i]==0)
+		{
+			holdFor(MOVE_DELAY);
+			continue;
+		}
+
+		Shelf* shelf = shelves[i];
+		basket[i] = shelf->takeCommodity(demand[i]);
+
+		holdFor(TAKE_DELAY + MOVE_DELAY);
+	}
+
+	//
+	// Pay at a till
+	//
+	tills->pay();
+
+	return 0;
+}
+
+//
+// Construction of the CustomerGen object.
+//
+CustomerGen::CustomerGen(ShopSim& sim) :
+	Process(sim, "CustomerGen")
+{}
+
+//
+// CustomerGen creates Customers.
+//
+int CustomerGen::main()
+{
+	// Cash the ShopSim pointers.
+	ShopSim& sim = dynamic_cast< ShopSim& >( getSimulation() );
+	Customer* c = 0;
+	SimTime delay;
+
+	while (true)
+	{
+		// Create and activate a new Customer.
+		c = new Customer(sim);
+		c->activate();
+
+		// Wait a random time and update statistic.
+		delay = static_cast< SimTime >( sim.getDelay()->sample() );
+		holdFor(delay);
+	}
+
+	return 0;
+}
+
+//
+// Main:
+// In the global main() function we finally create an object
+// of the type ShopSim, start the trace, run the simulation for
+// two simulated days, stop trace and generate the report.
+//
+int main(int argc, char* argv[])
+{
+	//
+	// Using a local variable to hold the ShopSim object is
+	// safe because the stack of the global main() function
+	// won't be touched during a simulation. The stacks of
+	// the Process main() functions however are not available
+	// to each other or to the global main(). You can of course
+	// use dynamic allocation as seen in CustomerGen::main().
+	//
+	ShopSim* sim = new ShopSim();
+
+	sim->enableDefaultLogging( XML, "Example_Shop_Log" );
+	//
+	// The Simulation class provides different functions to
+	// compute the simulation. runUntil() starts computation
+	// until the given simulation time is reached. We have to
+	// use this method because our simulation does not terminate
+	// on its own. Which would be the case, if a Process calls
+	// exitSimulation() at ShopSim or if there would be no
+	// process scheduled for execution.
+	//
+	sim->runUntil(60 * 24 * 2);
+
+	//
+	// The report is generated at this moment. All registered
+	// objects must be alive and ready to add their parts to
+	// the report.
+	//
+	sim->reportDefaultStatistics( XML, "Example_Shop.xml" );
+	return 0;
+}
+
diff --git a/odemx-lite/examples/Example_Statistics.cpp b/odemx-lite/examples/Example_Statistics.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bcb9a1c27a3ef98daf765c69e9a1711b756f8316
--- /dev/null
+++ b/odemx-lite/examples/Example_Statistics.cpp
@@ -0,0 +1,99 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Example_Statistics.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/13
+ * @brief Example showing how to use the StatisticsBuffer
+ * @since 3.0
+*/
+
+/**
+ * @example Example_Statistics.cpp
+ * The typical usage of ODEMx logging is shown.
+ *
+ * This example shows the use of the statistics channel on the producer's
+ * side and the use of a StatisticsBuffer on the log consumer side.
+ * For this purpose, the class StopWatch is again specialized in order
+ * to log statistical data.
+ */
+
+#include <iostream>
+#include "Example_Producer_StopWatch.h"
+
+using namespace odemx;
+
+class StatisticsStopWatch: public StopWatch {
+public:
+	StatisticsStopWatch( base::Simulation& sim, const data::Label& label )
+	:	StopWatch( sim, label )
+	{}
+	void start() {
+		StopWatch::start();
+		//
+		// We count the number of uses of this object
+		//
+		statistics << count( "uses" );
+	}
+	void stop() {
+		StopWatch::stop();
+		//
+		// We compute accumulated statistics about the duration measured with
+		// the StopWatch.
+		//
+		statistics << update( "duration", StopWatch::getDuration() );
+	}
+};
+
+int main() {
+	using data::buffer::StatisticsBuffer;
+	typedef std::shared_ptr< StatisticsBuffer > BufferPtr;
+	base::Simulation& sim = getDefaultSimulation();
+	//
+	// Initializing the buffer with true mean we want to store update pairs.
+	//
+	BufferPtr buf = StatisticsBuffer::create( sim, "Statistics Buffer", true );
+	sim.addConsumer( data::channel_id::statistics, buf );
+	//
+	// In order to produce a good value distribution, we use the watch
+	// 10000 times.
+	//
+	odemx::random::Normal normal( sim, "Normal Distribution", 42, 5 );
+	StatisticsStopWatch watch( sim, "Statistics Stop Watch" );
+	int i = 10000;
+	while( i-- ) {
+		watch.start();
+		sim.setCurrentTime( sim.getTime() + normal.sample() );
+		watch.stop();
+	}
+	//
+	// Now we can use the stored update pairs to produce a histogram
+	// for displaying the normal distribution.
+	//
+	const StatisticsBuffer::UpdateDeque& updates = buf->getUpdates( watch.getLabel(), "duration" );
+	statistics::Histogram histogram( sim, "StopWatch Duration", 20, 70, 25 );
+	for( StatisticsBuffer::UpdateDeque::size_type i = 0; i < updates.size(); ++i ) {
+		histogram.update( updates[ i ].second );
+	}
+	
+	data::output::OStreamReport report( std::cout );
+	report.addReportProducer( *buf );
+	report.addReportProducer( histogram );
+	report.generateReport();
+}
diff --git a/odemx-lite/examples/Example_Wait_Timer_Port.cpp b/odemx-lite/examples/Example_Wait_Timer_Port.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..278459ac64e0355b08c256335454a3f65b1a8bb1
--- /dev/null
+++ b/odemx-lite/examples/Example_Wait_Timer_Port.cpp
@@ -0,0 +1,211 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2007, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Example_Wait_Timer_Port.cpp
+
+	\author Ronald Kluth
+
+	\date created at 2007/10/01
+
+	\brief A short usage example of Ports and Timers
+
+	\since 2.0
+*/
+
+/**
+ * @example Example_Wait_Timer_Port.cpp
+ * The typical usage of the ODEMx process wait concept is demonstrated.
+ *
+ * A receiver process has both, a timer and a port. When a timeout occurs,
+ * the receiver process finishes its run. A event is used to put three messages
+ * into the receiver's input port, and while there is data, the receiver
+ * reads it from the port. Eventually, it runs out of data and a timeout
+ */
+
+#include <iostream>
+#include <string>
+using namespace std;
+
+#include <odemx/odemx.h>
+using namespace odemx::base;
+using namespace odemx::synchronization;
+
+//---------------------------------------------------------------------------Msg
+//
+// Since we want to use the default ports provided by odemx, we need the
+// port elements to be derived from PortData. Here, we define a simple
+// message type that transports a string.
+//
+struct Msg:	public PortData
+{
+	Msg( const string& str ): content( str ) {}
+	virtual Msg* clone() { return 0; }
+	string content;
+};
+
+//----------------------------------------------------------------------Receiver
+//
+// The receiver of messages is a process that allows us to demonstrate the use
+// of the concept wait-for-alert.
+//
+class Receiver: public Process
+{
+public:
+	Receiver()
+	:	Process( odemx::getDefaultSimulation(), "The Receiver" )
+	,	timer_( new Timer( odemx::getDefaultSimulation(), "Receiver Message Timer" ) )
+	,	port_( PortHead::create( odemx::getDefaultSimulation(), "Receiver Input Port" ) )
+	{}
+	//
+	// The life cycle of this process uses wait() to stop its run until a
+	// Memory object becomes available, i.e. the process gets alerted by it.
+	// After checking who the alerter is, appropriate action is taken by either
+	// logging the message and calling wait again, or by finishing its run if
+	// a timeout occurs.
+	//
+	virtual int main()
+	{
+		//
+		// Protect the receiver from deadlock by setting a timer.
+		//
+		SimTime timeLimit = 10;
+		timer_->setIn( timeLimit );
+		bool timeOut = false;
+
+		while( ! timeOut )
+		{
+			info << log( "waiting for next message with timeout at" )
+					.detail( "time", timer_->getExecutionTime() );
+			//
+			// Wait for message arrival at the port, or a timeout.
+			//
+			IMemory* who = wait( timer_.get(), port_.get() );
+			//
+			// When arriving at this point, the process was either alerted
+			// by a Memory object or interrupted by some other object.
+			//
+			if( who == timer_.get() )
+			{
+				//
+				// Timeout, stop message reception loop.
+				//
+				info << log( "alerted by timer" ).detail( "timeout at", getTime() );
+				timeOut = true;
+			}
+			else if( who == port_.get() )
+			{
+				info << log( "alerted by port" );
+				//
+				// Restart the timer for the next waiting period.
+				//
+				timer_->reset( timeLimit );
+				//
+				// PortHead::get() return an auto_ptr wrapping the actual
+				// pointer to the message. The returned data can be 0, if an
+				// error occurred.
+				//
+				std::unique_ptr< PortData* > data = port_->get();
+				if( data.get() != 0 )
+				{
+					//
+					// We need to manage memory allocated by MessageArrival event
+					//
+					std::unique_ptr< Msg > msg( static_cast< Msg* >( *data ) );
+					info << log( "received message" ).detail( "content", msg->content );
+				}
+				else
+				{
+					error << log( "PortHead::get() returned 0" );
+				}
+			}
+		}
+		info << log( "terminated at" ).detail( "time", getTime() );
+		return 0;
+	}
+
+	PortHead::TailPtr getInputPort() { return port_->getTail(); }
+
+private:
+	std::unique_ptr< Timer > timer_;
+	PortHead::Ptr port_;
+};
+
+//----------------------------------------------------------------MessageArrival
+//
+// The arrival of messages is modeled by a simple event class that puts
+// messages into a receiver's input port.
+//
+class MessageArrival: public Event
+{
+public:
+	MessageArrival( Receiver& receiver )
+	:	Event( odemx::getDefaultSimulation(), "Message Arrival" )
+	,	receiver_( &receiver )
+	{}
+	//
+	// The event action simply models the arrival of three messages at a port
+	//
+	virtual void eventAction()
+	{
+		info << log( "triggered for" ).detail( "receiver", receiver_->getLabel() );
+		receiver_->getInputPort()->put( new Msg( "message 1" ) );
+		receiver_->getInputPort()->put( new Msg( "message 2" ) );
+		receiver_->getInputPort()->put( new Msg( "message 3" ) );
+	}
+
+private:
+	Receiver* receiver_;
+};
+
+//--------------------------------------------------------------------------main
+
+int main( int argc, char* argv[] )
+{
+	using namespace odemx::data::output;
+
+	SimTime arrivalTime = 8;
+	Simulation& sim = odemx::getDefaultSimulation();
+
+	Receiver receiver;
+	MessageArrival arrival( receiver );
+	arrival.scheduleAt( arrivalTime );
+	receiver.activate();
+
+	sim.addConsumer( odemx::data::channel_id::info, OStreamWriter::create( std::cout ) );
+	sim.run();
+	return 0;
+}
+
+//----------------------------------------------------------------program output
+/*
+ODEMx Log
+=========
+0 info: The Receiver(Receiver) waiting for next message with timeout at [Details: # time=10]
+8 info: Message Arrival(MessageArrival) triggered for [Details: # receiver=The Receiver]
+8 info: The Receiver(Receiver) alerted by port
+8 info: The Receiver(Receiver) received message [Details: # content=message 1]
+8 info: The Receiver(Receiver) waiting for next message with timeout at [Details: # time=18]
+8 info: The Receiver(Receiver) alerted by port
+8 info: The Receiver(Receiver) received message [Details: # content=message 2]
+8 info: The Receiver(Receiver) waiting for next message with timeout at [Details: # time=18]
+8 info: The Receiver(Receiver) alerted by port
+8 info: The Receiver(Receiver) received message [Details: # content=message 3]
+8 info: The Receiver(Receiver) waiting for next message with timeout at [Details: # time=18]
+18 info: The Receiver(Receiver) alerted by timer [Details: # timeout at=18]
+18 info: The Receiver(Receiver) terminated at [Details: # time=18]
+*/
diff --git a/odemx-lite/external/CppLog/COPYING b/odemx-lite/external/CppLog/COPYING
new file mode 100644
index 0000000000000000000000000000000000000000..d93b3566ca8f266088efadf48019e0c9163fb7aa
--- /dev/null
+++ b/odemx-lite/external/CppLog/COPYING
@@ -0,0 +1,4 @@
+Copyright (c) 2009-2010 Ronald Kluth
+
+Distributed under the Boost Software License, Version 1.0. (See accompanying
+file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
diff --git a/odemx-lite/external/CppLog/CppLog.kdev4 b/odemx-lite/external/CppLog/CppLog.kdev4
new file mode 100644
index 0000000000000000000000000000000000000000..2c317a6a60741d065c153e1b1fda372947069a82
--- /dev/null
+++ b/odemx-lite/external/CppLog/CppLog.kdev4
@@ -0,0 +1,3 @@
+[Project]
+Manager=KDevGenericManager
+Name=CppLog
diff --git a/odemx-lite/external/CppLog/INSTALL b/odemx-lite/external/CppLog/INSTALL
new file mode 100644
index 0000000000000000000000000000000000000000..87c92adadeb3383cef6ef86b51648313e521cf01
--- /dev/null
+++ b/odemx-lite/external/CppLog/INSTALL
@@ -0,0 +1,3 @@
+See Doxygen documentation for information on:
+  - Using CppLog
+  - How to build the tests and examples
diff --git a/odemx-lite/external/CppLog/LICENSE_1_0.txt b/odemx-lite/external/CppLog/LICENSE_1_0.txt
new file mode 100644
index 0000000000000000000000000000000000000000..36b7cd93cdfbac762f5be4c6ce276df2ea6305c2
--- /dev/null
+++ b/odemx-lite/external/CppLog/LICENSE_1_0.txt
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/odemx-lite/external/CppLog/README b/odemx-lite/external/CppLog/README
new file mode 100644
index 0000000000000000000000000000000000000000..9e9318a97e3532106d95281c63337efd6c45d3e2
--- /dev/null
+++ b/odemx-lite/external/CppLog/README
@@ -0,0 +1,4 @@
+CppLog version 0.1
+Released Wednesday, 05 May 2010.
+
+See Doxygen documentation for API documentation and examples.
diff --git a/odemx-lite/external/CppLog/doc/Doxyfile b/odemx-lite/external/CppLog/doc/Doxyfile
new file mode 100644
index 0000000000000000000000000000000000000000..df862b8e5697b1709b76bd2b1017ba7f7f6958b7
--- /dev/null
+++ b/odemx-lite/external/CppLog/doc/Doxyfile
@@ -0,0 +1,1501 @@
+# Doxyfile 1.5.8
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME = CppLog
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER = 0.1
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = ./
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, 
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), 
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, 
+# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, 
+# Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF = "The $name class" "The $name widget" "The $name file" is provides specifies contains represents a an the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH = /Users/dimitri/doxygen/mail/1.5.7/doxywizard/
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses. 
+# With this tag you can assign which parser to use for a given extension. 
+# Doxygen has a built-in mapping, but you can override or extend it using this tag. 
+# The format is ext=language, where ext is a file extension, and language is one of 
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, 
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat 
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), 
+# use: inc=Fortran f=C
+
+EXTENSION_MAPPING = 
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = YES
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to 
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen to replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
+# determine which symbols to keep in memory and which to flush to disk. 
+# When the cache is full, less often used symbols will be written to disk. 
+# For small to medium size projects (<1000 input files) the default value is 
+# probably good enough. For larger projects a too small cache size can cause 
+# doxygen to be busy swapping symbols to and from disk most of the time 
+# causing a significant performance penality. 
+# If the system has enough physical memory increasing the cache will improve the 
+# performance by keeping more symbols in memory. Note that the value works on 
+# a logarithmic scale so increasing the size by one will rougly double the 
+# memory usage. The cache size is given by this formula: 
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS = YES
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST = YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index 
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by 
+# doxygen. The layout file controls the global structure of the generated output files 
+# in an output format independent way. The create the layout file that represents 
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a 
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name 
+# of the layout file.
+
+LAYOUT_FILE = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT = ../
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS = *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py *.f90 *.f *.vhd *.vhdl
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE = ../src/test ../include/CppLog/detail/string_literal.hpp ../include/CppLog/detail/Bindings.h ../include/CppLog/detail/EnableIf.h 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH = ../src/samples/src/ 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 
+# link to the source code.  Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup. 
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file 
+# content.
+
+CHM_INDEX_ENCODING = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER 
+# are set, an additional index file will be generated that can be used as input for 
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated 
+# HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = 
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. 
+# For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's 
+# filter section matches. 
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file.
+
+QHG_LOCATION = 
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
+# structure should be generated to display hierarchical information. 
+# If the tag value is set to FRAME, a side panel will be generated 
+# containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature. Other possible values 
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories, 
+# and Class Hierarchy pages using a tree view instead of an ordered list; 
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which 
+# disables this behavior completely. For backwards compatibility with previous 
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE 
+# respectively.
+
+GENERATE_TREEVIEW = ALL
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX = YES
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED = DOXYGEN_SKIP
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links. 
+# Note that each tag file must have a unique name 
+# (where the name does NOT include the path) 
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# By default doxygen will write a font called FreeSans.ttf to the output 
+# directory and reference it in all dot files that doxygen generates. This 
+# font does not include all possible unicode characters however, so when you need 
+# these (or just want a differently looking font) you can specify the font name 
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font, 
+# which can be done by putting it in a standard location or by setting the 
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory 
+# containing the font.
+
+DOT_FONTNAME = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the output directory to look for the 
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a 
+# different font using DOT_FONTNAME you can set the path where dot 
+# can find it using this tag.
+
+DOT_FONTPATH = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include 
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif 
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, because dot on Windows does not 
+# seem to support this out of the box. Warning: Depending on the platform used, 
+# enabling this option may lead to badly anti-aliased labels on the edges of 
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Options related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/odemx-lite/external/CppLog/doc/MainPage.dox b/odemx-lite/external/CppLog/doc/MainPage.dox
new file mode 100644
index 0000000000000000000000000000000000000000..e50f6c876aa26c10986b6658c9453a83ba08dd4d
--- /dev/null
+++ b/odemx-lite/external/CppLog/doc/MainPage.dox
@@ -0,0 +1,50 @@
+/**
+	@mainpage
+
+	@section Introduction
+	Welcome to CppLog, a slim, template-based C++ logging library.
+
+	\n
+	With regard to Software, logging refers to the collection and
+	visualization of runtime state information of a program. The most
+	simple variant of logging is writing console output, which is
+	usually problematic because it cannot easily be disabled (aside
+	from removing the statements in the code). In addition, console
+	output quickly becomes hard to read and follow when the logged data
+	reaches a sizeable amount. The next logical step is to use specialized
+	components that allow formatting and archiving of log records in
+	files or databases. That is the area CppLog is aimed at.
+	The library comes in header-only form and provides simple yet powerful
+	core components to facilitate application logging in C++ projects.
+	
+	The philosophy of the library is to make as few assumptions as
+	possible about what kinds of data are to be logged and how that is
+	to be achieved. Therefore, the library does not limit users to
+	one specific record type but rather provides templates that allow 
+	the specification of any user-defined type. Naturally, as with most
+	template code, this puts some limitations on what the library can offer
+	in terms of ease-of-use.
+
+	In order to address that fact, a default record type has been included
+	so that several default output components could be defined as well.
+	These provide stream-writing support for plain text and XML, and
+	additionally an XML file writer. Database support is also included
+	but introduces a dependency on the Poco C++ libraries
+	(http://pocoproject.org).
+
+	\section installation Installation
+	There is no installation procedure required for using the core 
+	components of CppLog. Simply copy the files into a directory that
+	is present in the compiler's include path. 
+	
+	However, for database connectivity, CppLog is currently dependent 
+	on the use of the Poco C++ libraries. These provide an interface for
+	communicating with SQLite and ODBC databases. Besides that, simple
+	Makefiles are included for compiling the examples and the test suite.
+
+	\section copyright Copyright and License
+	Copyright (c) 2009-2010 Ronald Kluth.
+	The library is istributed under the Boost Software License, Version 1.0.
+	(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+*/
diff --git a/odemx-lite/external/CppLog/include/CppLog.h b/odemx-lite/external/CppLog/include/CppLog.h
new file mode 100644
index 0000000000000000000000000000000000000000..833aac8358b2f244ca5ca7204c27f5cdd2f51c53
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog.h
@@ -0,0 +1,46 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file CppLog.h
+ * @author Ronald Kluth
+ * @date 2009/05/17
+ * @brief Forwarding header for all CppLog classes and macros
+ * @since 0.1
+ */
+
+#ifndef CPPLOG_INCLUDED
+#define CPPLOG_INCLUDED
+
+// include library setup, enables/disables database connectivity
+#include "setup.h"
+
+// include core components
+#include "CppLog/Channel.h"
+#include "CppLog/ChannelId.h"
+#include "CppLog/ChannelManager.h"
+#include "CppLog/Consumer.h"
+#include "CppLog/DeclareChannel.h"
+#include "CppLog/DeclareInfoType.h"
+#include "CppLog/DeclareInfoTypeList.h"
+#include "CppLog/DeclareSqlColumnTypes.h"
+#include "CppLog/Enable.h"
+#include "CppLog/Filter.h"
+#include "CppLog/NamedElement.h"
+#include "CppLog/NameScope.h"
+#include "CppLog/Producer.h"
+#include "CppLog/Record.h"
+#include "CppLog/StringLiteral.h"
+
+// include output components
+#include "CppLog/output/OStreamWriter.h"
+#include "CppLog/output/XmlFileWriter.h"
+#include "CppLog/output/XmlStreamWriter.h"
+#include "CppLog/output/XmlWriter.h"
+#include "CppLog/output/DatabaseAccessor.h"
+
+#endif /* CPPLOG_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/Channel.h b/odemx-lite/external/CppLog/include/CppLog/Channel.h
new file mode 100644
index 0000000000000000000000000000000000000000..5a296141cbdd9ffb3f3868a0a8e199fe6c537060
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/Channel.h
@@ -0,0 +1,286 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file Channel.h
+ * @author Ronald Kluth
+ * @date 2009/02/08
+ * @brief Declaration and implementation of class template Channel and operator<<
+ * @since 0.1
+ */
+
+#ifndef LOG_CHANNEL_INCLUDED
+#define LOG_CHANNEL_INCLUDED
+
+#include "ChannelId.h"
+#include "Consumer.h"
+#include "Filter.h"
+
+#include <cassert>
+#include <set>
+#ifdef _MSC_VER
+#include <memory>
+#else
+#include <memory>
+#endif
+
+
+namespace Log {
+
+/**
+ * @brief Class template for log channels that forward records to registered consumers
+ * @tparam RecordT Type of the log records to be used, the default is @c Record
+ *
+ * A channel provides the means to transport log records from any source to
+ * any number of consumers. Channels are used in a stream-like manner via an
+ * overloaded @c operator<<. Besides the registration of consumers, channels
+ * also allow for a filter to be set.
+ *
+ * Multiple channel objects of the same type can be created and controlled
+ * by a manager object to ensure they have the same lifetime, or to access
+ * several channels simultaneously when adding or removing consumers and
+ * record filters.
+ *
+ * Usage:
+ * @code
+ * Channel< std::string > channel;
+ * channel.addConsumer( con1 );
+ * channel.addConsumer( con2 );
+ * channel << std::string( "example message" );
+ * @endcode
+ *
+ * In the above usage example, the message is forwarded to both registered
+ * consumers @c con1 and @c con2.
+ * 
+ * @note This class is not intended to be inherited.
+ * @see ChannelId, Consumer, Filter, ChannelManager, Log::operator<<
+ */
+template < typename RecordT = Record >
+class Channel
+{
+public:
+	/// Type of the records to be logged
+	typedef RecordT RecordType;
+	/// Pointer type to manage registered log record consumers
+	typedef std::shared_ptr< Consumer< RecordType > > ConsumerPtr;
+	/// Set type to store pointers to record consumers
+	typedef std::set< ConsumerPtr > ConsumerSet;
+	/// Pointer type to manage RecordFilter objects
+	typedef std::shared_ptr< Filter< RecordType > > FilterPtr;
+
+	/**
+	 * @brief Construction with ID, or default construction with -1
+	 *
+	 * Channels may specify an ID in order to allow consumers to identity
+	 * which channel forwarded a record.
+	 */
+	explicit Channel( ChannelId const channelId = -1 )
+	:	id_( channelId )
+	,	filter_()
+	,	consumers_()
+	{
+	}
+
+	// Compiler-generated dtor o.k.
+
+	/**
+	 * @brief Get the channel's ID value set during contruction
+	 *
+	 * Channel IDs can be used by consumers to identify the channel that
+	 * forwarded log records. The default setting is -1, meaning the channel
+	 * was not given an ID.
+	 *
+	 * @return ID of the channel object, or -1 if not set
+	 */
+	ChannelId const getId() const
+	{
+		return id_;
+	}
+
+	/**
+	 * @brief Get access to the set of registered log record consumers
+	 *
+	 * This method is used by @c operator<< to iterate over all registered
+	 * consumers in order to forward the log record via the @c Consumer
+	 * interface.
+	 *
+	 * @return Reference to the set of consumers
+	 * @see Consumer
+	 */
+	ConsumerSet const& getConsumers() const
+	{
+		return consumers_;
+	}
+
+	/**
+	 * @brief Check whether the filter is set
+	 * @return @c true if the @c shared_ptr holding the filter is not empty
+	 */
+	bool hasFilter() const
+	{
+		return !!filter_;
+	}
+
+	/**
+	 * @brief Get a pointer to the channel's record filter
+	 * @return A copy of the @c shared_ptr holding the filter
+	 */
+	FilterPtr getFilter() const
+	{
+		return filter_;
+	}
+
+	/**
+	 * @brief Set a (new) record filter for the channel
+	 * @param filter @c shared_ptr to a filter, must not be empty
+	 *
+	 * This method resets the filter pointer to the given parameter.
+	 * A channel may only hold one filter. Thus, calling this method replaces
+	 * the previous filter, if one was set.
+	 */
+	void setFilter( FilterPtr filter )
+	{
+		assert( filter );
+		filter_ = filter;
+	}
+
+	/**
+	 * @brief Reset the record filter
+	 *
+	 * This method resets the @c shared_ptr managing the filter. If the channel
+	 * holds the last reference to the filter, it will be automatically deleted.
+	 */
+	void resetFilter()
+	{
+		filter_.reset();
+	}
+
+	/**
+	 * @brief Add another consumer to the channel
+	 * @param consumer @c shared_ptr to a consumer, must not be empty
+	 *
+	 * This method adds a new consumer to the channel's set. Consumer objects
+	 * are managed by @c shared_ptr so their existence is ensured until the last
+	 * channel holding a reference to them is destroyed.
+	 *
+	 * @retval true if the consumer was inserted successfully
+	 * @retval false if the consumer was already registered
+	 */
+	bool addConsumer( ConsumerPtr consumer )
+	{
+		assert( consumer );
+		return ( consumers_.insert( consumer ).second );
+	}
+
+	/**
+	 * @brief Remove a consumer from the channel's set
+	 * @param consumer @c shared_ptr to a consumer, must not be empty
+	 *
+	 * This method removes the given consumer from the channel's set,
+	 * thereby decreasing its @c shared_ptr reference count by one. If the
+	 * channel held the last reference to the consumer, the object is
+	 * automatically deleted.
+	 *
+	 * @retval true if the consumer was found and erased
+	 * @retval false if the consumer was not found in the set
+	 */
+	bool removeConsumer( ConsumerPtr consumer )
+	{
+		assert( consumer );
+		return ( consumers_.erase( consumer ) > 0 );
+	}
+
+	/**
+	 * @brief Remove all consumers from the channel
+	 *
+	 * This method clears the set of registered consumers, which effectively
+	 * disables a channel because no records can be forwarded via @c operator<<
+	 * anymore.
+	 */
+	void removeConsumers()
+	{
+		consumers_.clear();
+	}
+
+private:
+	/// Constant member to identify this channel object
+	ChannelId const id_;
+	/// Pointer to a record filter object associated with this channel
+	FilterPtr filter_;
+	/// Container of registered consumers which receive all records forwarded by this channel
+	ConsumerSet consumers_;
+
+	/// Non-copyable
+	Channel( Channel const& );
+	/// Non-assignable
+	Channel& operator=( Channel const& );
+};
+
+/**
+ * @brief Inserter overload for stream-like use of log channels
+ * @tparam RecordT Type of the records to be forwarded by the channel
+ *
+ * This overload of the insert operator provides the means to forward
+ * any kind of log records via any matching channel. The channel is checked
+ * for a filter, and if one is set, the given record must pass it in order to
+ * be forwarded to all the channel's consumers.
+ *
+ * @see Channel, Consumer
+ */
+template < typename RecordT >
+inline
+Channel< RecordT > const&
+operator<<( Channel< RecordT > const& channel, RecordT const& record )
+{
+	// check if the channel is filtered and if the record may pass
+	if( ! channel.hasFilter() || channel.getFilter()->pass( record ) )
+	{
+		// pass the record on to the channel's consumers
+		// by calling consume on each one with channel ID and record
+		for( typename Channel< RecordT >::ConsumerSet::const_iterator
+			iter = channel.getConsumers().begin();
+			iter != channel.getConsumers().end();
+			++iter )
+		{
+			( *iter )->consume( channel.getId(), record );
+		}
+	}
+	return channel;
+}
+
+/**
+ * @brief Inserter overload for @c shared_ptr to channel objects
+ * @tparam RecordT Type of the records to be forwarded by the channel
+ *
+ * This overload of the insert operator logs data only if the @c shared_ptr
+ * is set. This makes it possible for record producers to enable/disable
+ * logging dynamically by simply setting or resetting a @c shared_ptr to
+ * the channel. Using a @c shared_ptr to manage channel access can also be
+ * useful if log records are expensive to create. The pointer can be checked
+ * by a condition so that the insertion statement is only executed when the
+ * pointer is actually set.
+ *
+ * @note This operator uses the other overload for references to channels.
+ * @see Channel, Consumer, Log::operator<<
+ */
+template < typename RecordT >
+inline
+std::shared_ptr< Channel< RecordT > > const
+operator<<( std::shared_ptr< Channel< RecordT > > const channel, RecordT const& record )
+{
+	// log only if the channel is set, allows disabling logging per producer
+	// because it can just reset its shared_ptr if logging is not needed
+	if( channel )
+	{
+		*channel << record;
+	}
+	return channel;
+}
+
+} // namespace Log
+
+#endif /* LOG_CHANNEL_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/ChannelId.h b/odemx-lite/external/CppLog/include/CppLog/ChannelId.h
new file mode 100644
index 0000000000000000000000000000000000000000..2343404a4b870338dd7e8ead1992fb86d5a8fbcd
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/ChannelId.h
@@ -0,0 +1,36 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file ChannelId.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/11
+ * @brief Declaration of type ChannelId
+ * @since 0.1
+ */
+
+#ifndef LOG_CHANNELID_INCLUDED
+#define LOG_CHANNELID_INCLUDED
+
+namespace Log {
+
+/**
+ * @typedef ChannelId
+ * @brief An alias to make the use of channel IDs more obvious in the code.
+ *
+ * Every @c Channel object can be constructed with an ID. The default is -1,
+ * meaning that it is not set. Channel IDs can be used by consumers to identify
+ * the channel that forwarded a log record via call to @c consume. The consumer
+ * interface ensures that the @c ChannelId of the caller is given.
+ *
+ * @see Channel, Consumer
+ */
+typedef int ChannelId;
+
+} // namespace Log
+
+#endif /* LOG_CHANNELID_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/ChannelManager.h b/odemx-lite/external/CppLog/include/CppLog/ChannelManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..65ef0f57fb00360bd56ca4c9d6018470a384b2be
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/ChannelManager.h
@@ -0,0 +1,325 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file ChannelManager.h
+ * @author Ronald Kluth
+ * @date created at 2009/06/05
+ * @brief Declaration and implementation of class template ChannelManager
+ * @since 0.1
+ */
+
+#ifndef LOG_CHANNELMANAGER_INCLUDED
+#define LOG_CHANNELMANAGER_INCLUDED
+
+#include "ChannelId.h"
+#include "NameScope.h"
+
+#include <cassert>
+#include <map>
+
+#ifdef _MSC_VER
+#include <memory>
+#include <functional> // bind
+#else
+#include <memory>
+#include <functional> // bind
+#endif
+
+
+namespace Log {
+
+// forward declarations
+template < typename > class Channel;
+template < typename > class Consumer;
+template < typename > class Filter;
+class Record;
+
+/**
+ * @brief Manager template type that creates and manages log channels for producers
+ * @tparam RecordT Type of the log records the channels can use
+ *
+ * A channel manager serves two purposes. Firstly, it can be used to
+ * create multiple channels of the same type (i.e. channels using the
+ * same record type) and simplify their consumer and filter management. 
+ * Secondly, it may serve as name scope and channel provider for producer
+ * classes.
+ * 
+ * Usage:
+ * @code
+ * ChannelManager< std::string > mgr;
+ * shared_ptr< Channel< std::string > chan1 = mgr.getChannel( 1 );
+ * shared_ptr< Channel< std::string > chan2 = mgr.getChannel( 2 );
+ * mgr.addConsumer( con );
+ * chan1 << std::string( "Channel 1 message" );
+ * chan2 << std::string( "Channel 2 message" );
+ * mgr.removeConsumer( 2, con );
+ * @endcode
+ * 
+ * The above snippet shows the creation of a manager and the retrieval of two
+ * pointers to log channels via @c getChannel. Since the manager does not yet
+ * own channels with IDs 1 and 2, it creates them at the first request. Now 
+ * that the channels exist, we can register a consumer with the manager, which
+ * will pass them along to all of its currently owned channels. Hence, both
+ * subsequently sent log records will be passed on to the consumer @c con.
+ * The manager also allows to add or remove consumers for specific channels, 
+ * as is shown in the last line.
+ * 
+ * @note Pairing incompatible producer and channel manager types
+ * will most likely result in compile errors.
+ * @see Producer, Channel, ChannelId, Consumer, Filter
+ */
+template < typename RecordT = Record >
+class ChannelManager
+:	public NameScope
+{
+public:
+	/// The record type used by the log channels
+	typedef RecordT RecordType;
+	/// The channel type of the managed channels
+	typedef Channel< RecordType > ChannelType;
+	/// Pointer type to manage channels
+	typedef std::shared_ptr< ChannelType > ChannelPtr;
+	/// Pointer type to manage log consumers
+	typedef std::shared_ptr< Consumer< RecordType > > ConsumerPtr;
+	/// Pointer type to manage record filters
+	typedef std::shared_ptr< Filter< RecordType > > FilterPtr;
+	/// Map type to associate channel IDs with channel pointers
+	typedef std::map< ChannelId, ChannelPtr > ChannelMap;
+
+	/**
+	 * @brief Default construction
+	 *
+	 * This constructor uses the default name and default space character 
+	 * provided by class @c NameScope.
+	 */
+	ChannelManager()
+	:	NameScope()
+	,	channels_()
+	{
+	}
+
+	/** 
+	 * @brief Construction with user-defined default name and space
+	 * 
+	 * This constructor initializes the @c NameScope base class with a
+	 * different default name and space character to use with named elements
+	 * like producers.
+	 */
+	ChannelManager( std::string const& defLabel, char const defSpace )
+	:	NameScope( defLabel, defSpace )
+	,	channels_()
+	{
+	}
+
+	/// Destruction
+	virtual ~ChannelManager()
+	{
+	}
+
+	/**
+	 * @brief Get a pointer to a managed log channel by providing its ID
+	 * @param id The ID of the requested channel
+	 * 
+	 * The manager first tries to find the requested channel in its map.
+	 * If the channel does not exist yet, a new @c Channel object with the
+	 * requested ID will be created and stored in the manager's map so that
+	 * subsequent calls always return the same channel pointer.
+	 */
+	ChannelPtr getChannel( ChannelId const id )
+	{
+		// get the entry or create a new one
+		typename ChannelMap::iterator found = channels_.find( id );
+
+		// if the channel is set return it
+		if( found != channels_.end() )
+		{
+			return found->second;
+		}
+
+		// create new channel object and make sure it's in the map
+		std::pair< typename ChannelMap::iterator, bool > result =
+				channels_.insert( typename ChannelMap::value_type(
+						id, ChannelPtr( new ChannelType( id ) ) ) );
+		assert( result.second );
+
+		// return the new pointer
+		return result.first->second;
+	}
+
+	/**
+	 * @brief Add a log consumer to a managed log channel
+	 * @param id ID of the channel where the consumer shall be registered
+	 * @param consumer Pointer to the new consumer, must be valid
+	 * 
+	 * The manager will try to find the channel and register the new
+	 * consumer.
+	 * 
+	 * @return @c true if the channel was found and the consumer registered
+	 */
+	bool addConsumer( ChannelId const id, ConsumerPtr consumer )
+	{
+		typename ChannelMap::iterator found = channels_.find( id );
+		if( found != channels_.end() )
+		{
+			return found->second->addConsumer( consumer );
+		}
+		return false;
+	}
+
+	/**
+	 * @brief Add a log consumer to all managed channels
+	 * @param consumer Pointer to the new consumer, must be valid
+	 * 
+	 * The manager will iterate over all channels currently stored in its map
+	 * and register the consumer with them.
+	 */
+	void addConsumer( ConsumerPtr consumer )
+	{
+		using namespace std::placeholders;
+		iterateChannels(
+				std::bind( &ChannelType::addConsumer, _1, consumer ) );
+	}
+
+	/**
+	 * @brief Remove a log consumer from a managed channel
+	 * @param id ID of the channel from which to remove the consumer
+	 * @param consumer Pointer to the consumer
+	 *
+	 * The manager will try to find the channel and remove the existing
+	 * consumer.
+	 * 
+	 * @return @c true if the channel was found and the consumer removed
+	 */
+	bool removeConsumer( ChannelId const id, ConsumerPtr consumer )
+	{
+		typename ChannelMap::iterator found = channels_.find( id );
+		if( found != channels_.end() )
+		{
+			return found->second->removeConsumer( consumer );
+		}
+		return false;
+	}
+
+	/**
+	 * @brief Remove a log consumer from all managed channels
+	 * @param consumer Pointer to the consumer
+	 *
+	 * The manager will iterate over all channels currently stored in its map
+	 * and remove the given consumer.
+	 */
+	void removeConsumer( ConsumerPtr consumer )
+	{
+		using namespace std::placeholders;
+		iterateChannels(
+				std::bind( &ChannelType::removeConsumer, _1, consumer ) );
+	}
+
+	/**
+	 * @brief Set a record filter for a managed channel
+	 * @param id ID of the channel on which to set the filter
+	 * @param filter Pointer to the new filter
+	 *
+	 * The manager will try to find the channel and set the filter.
+	 *
+	 * @note This will replace the current filter of the channel.
+	 * @return @c true if the channel was found and the filter set
+	 */
+	bool setFilter( ChannelId const id, FilterPtr filter )
+	{
+		typename ChannelMap::iterator found = channels_.find( id );
+		if( found != channels_.end() )
+		{
+			found->second->setFilter( filter );
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * @brief Set a record filter for all managed channels
+	 * @param filter Pointer to the new filter
+	 *
+	 * The manager will iterate over all channels currently stored in its map
+	 * and set the given filter.
+	 *
+	 * @note This will replace any filters set on the channels
+	 */
+	void setFilter( FilterPtr filter )
+	{
+		assert( filter );
+		using namespace std::placeholders;
+		iterateChannels(
+				std::bind( &ChannelType::setFilter, _1, filter ) );
+	}
+
+	/**
+	 * @brief Reset the record filter of a managed channel
+	 * @param id ID of the channel on which to reset the filter
+	 *
+	 * The manager will try to find the channel and reset the filter.
+	 *
+	 * @return @c true if the channel was found and the filter reset
+	 */
+	bool resetFilter( ChannelId const id )
+	{
+		typename ChannelMap::iterator found = channels_.find( id );
+		if( found != channels_.end() )
+		{
+			found->second->resetFilter();
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * @brief Reset the record filter for all managed channels
+	 *
+	 * The manager will iterate over all channels currently stored in its map
+	 * and reset their filters.
+	 */
+	void resetFilter()
+	{
+		using namespace std::placeholders;
+		iterateChannels(
+				std::bind( &ChannelType::resetFilter, _1 ) );
+	}
+
+private:
+	/// Storage for channel pointers, indexed by the channel IDs
+	ChannelMap channels_;
+
+private:
+	/// Non-copyable
+	ChannelManager( ChannelManager const& );
+	/// Non-assignable
+	ChannelManager& operator=( ChannelManager const& );
+
+	/**
+	 * @brief Execute a callable entity on all managed channels
+	 * @param func The callable entity to execute for all channels
+	 * 
+	 * This method template takes any callable entity as parameter, iterates 
+	 * over the map of channels and calls @c func for each channel. Typically,
+	 * @c func is a functor created by @c bind that calls a member function of 
+	 * the channel.
+	 */
+	template < typename FuncT >
+	void iterateChannels( FuncT const& func )
+	{
+		typename ChannelMap::iterator iter;
+		for( iter = channels_.begin(); iter != channels_.end(); ++iter )
+		{
+			assert( iter->second );
+			func( iter->second );
+		}
+	}
+};
+
+} // namespace Log
+
+#endif /* LOG_CHANNELMANAGER_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/Consumer.h b/odemx-lite/external/CppLog/include/CppLog/Consumer.h
new file mode 100644
index 0000000000000000000000000000000000000000..b1f841d6916d0c701a4075443c94b2761056a6f8
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/Consumer.h
@@ -0,0 +1,89 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file Consumer.h
+ * @author Ronald Kluth
+ * @date created at 2009/02/08
+ * @brief Declaration and Implementation of interface Consumer
+ * @since 0.1
+ */
+
+#ifndef LOG_CONSUMER_INCLUDED
+#define LOG_CONSUMER_INCLUDED
+
+#include "ChannelId.h"
+
+namespace Log {
+
+// forward declaration
+class Record;
+
+/**
+ * @interface Consumer
+ * @brief Interface for classes that can consume records from log channels.
+ * @tparam RecordT Type of the records received from channels, the default
+ * is @c Record
+ *
+ * All log consumer classes must be derived from this class in order to be
+ * compatible with log channels (which store pointers to registered consumers).
+ * In addition, the channel and consumers must be templated on the same record
+ * type. The derived classes must override the method @c consume that defines 
+ * how to handle records.
+ *
+ * Usage:
+ * @code
+ * class ConsoleWriter: public Log::Consumer< std::string > {
+ * public:
+ *     virtual void consume( Log::ChannelId const channelId, std::string const& record ) {
+ *         std::cout << record << std::flush;
+ *     }
+ * };
+ * Log::Channel< std::string > channel;
+ * channel.addConsumer( std::shared_ptr< ConsoleWriter >( new ConsoleWriter() ) );
+ * @endcode
+ *
+ * @see Channel, Log::operator<<
+ * @ref Example_Channel_Consumer.cpp
+ */
+template < typename RecordT = Record >
+class Consumer
+{
+public:
+	/// Type of the log records to consume
+	typedef RecordT RecordType;
+
+	// Compiler-generated ctor, assignment o.k.
+
+protected:
+	/// Destruction
+	virtual ~Consumer() {}
+
+public:
+	/**
+	 * @brief Pure virtual method for consuming records
+	 * @param id A numerical value to identify which channel forwarded the record
+	 * @param record The currently forwarded record
+	 *
+	 * Whenever a record is sent through a channel, the channel forwards
+	 * it to all registered consumers by calling this method on them.
+	 * Usually, consumers then transform this record into readable information
+	 * and/or store it for later access.
+	 *
+	 * @note The record that is passed as reference to const most likely is a
+	 * a temporary object. In order to store its data for later use, the
+	 * consumer must copy it, for example by storing it in an STL container.
+	 *
+	 * @note Special care must be taken to ensure that stored records do not
+	 * reference deleted objects, and end up accessing dangling pointers.
+	 */
+	virtual void consume( ChannelId const id, RecordType const& record ) = 0;
+};
+
+} // namespace Log
+
+#endif /* LOG_CONSUMER_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/DeclareChannel.h b/odemx-lite/external/CppLog/include/CppLog/DeclareChannel.h
new file mode 100644
index 0000000000000000000000000000000000000000..94e948897928263e3079252ab762fb258cfbeade
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/DeclareChannel.h
@@ -0,0 +1,101 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file DeclareChannel.h
+ * @author Ronald Kluth
+ * @date created at 2009/06/05
+ * @brief Declaration and implementation of macro CPPLOG_DECLARE_CHANNEL
+ * @since 0.1
+ */
+
+#ifndef LOG_DECLARECHANNEL_INCLUDED
+#define LOG_DECLARECHANNEL_INCLUDED
+
+#include "Channel.h"
+#include "ChannelManager.h"
+#include "detail/ChannelField.h"
+
+/**
+ * @def CPPLOG_DECLARE_CHANNEL_WITH_ID( PP_NameSpace, PP_IdName, PP_RecordType, PP_Id )
+ * @brief Declaration of a log channel, corresponding ID, name, and producer member
+ * @param PP_NameSpace The namespace the ID should reside in
+ * @param PP_IdName The name of the channel ID to be created, also the member name
+ * @param PP_RecordType The type of records the channel transports
+ * @param PP_Id The value of the ID, must be unique for each macro use
+ *
+ * This macro has the same effect as @c CPPLOG_DECLARE_CHANNEL, but it allows
+ * the manual specification of the channel ID value. It is mainly provided for
+ * legacy compilers that do not support the use of the @c __COUNTER__ macro and
+ * thus cannot create ID values automatically.
+ *
+ * @note Since this macro creates template specializations, all uses must
+ * have unique ID values in order to create different log channels.
+ * @see CPPLOG_DECLARE_CHANNEL, Producer, ChannelManager
+ */
+#define CPPLOG_DECLARE_CHANNEL_WITH_ID( PP_NameSpace, PP_IdName, PP_RecordType, PP_Id ) \
+	namespace PP_NameSpace { enum { PP_IdName = PP_Id }; }								\
+	namespace Log {																		\
+	namespace Detail {																	\
+		template <>																		\
+		struct ChannelField< ::PP_NameSpace::PP_IdName >								\
+		{																				\
+			ChannelField() {}															\
+			ChannelField( ChannelManager< PP_RecordType >& manager )					\
+			{																			\
+				this->PP_IdName = manager.getChannel( ::PP_NameSpace::PP_IdName );		\
+			}																			\
+			protected:																	\
+				std::shared_ptr< Log::Channel< PP_RecordType > > PP_IdName;		\
+		};																				\
+	} } // namespace Log::Detail
+
+/**
+ * @def CPPLOG_DECLARE_CHANNEL( PP_NameSpace, PP_IdName, PP_RecordType )
+ * @brief Declares a log channel with corresponding ID and record type
+ * @param PP_NameSpace The namespace the ID should reside in
+ * @param PP_IdName The name of the channel ID to be created, also the member name
+ * @param PP_RecordType The type of records the channel transports
+ *
+ * This macro is used to declare log channels which are intended for
+ * use with producers and channel managers. In this pattern, the manager will
+ * create and manage channel objects with the given IDs, and the producer can
+ * automatically use these channels as @c shared_ptr members of the same name.
+ *
+ * Usage:
+ * @code
+ * CPPLOG_DECLARE_CHANNEL( channel_id, info, std::string )
+ * @endcode
+ *
+ * The above declaration creates an anonymous enum in namespace
+ * @c channel_id that contains @c info. Thus, the ID can be referred to as
+ * @c channel_id::info. This identifier can then be used in conjunction
+ * with the class templates @c Producer and @c Enable to activate log
+ * channel access for a producer class by instantiating the template.
+ * Log data producers can then be derived from that type and use the
+ * log channel @c info (which is automatically initialized by calling
+ * @c getChannel on the manager) as follows:
+ *
+ * @code
+ * typedef Log::Producer< Log::Enable< channel_id::info > > InfoProducer;
+ *
+ * class DataProducer
+ * {
+ * public:
+ *     DataProducer( Log::ChannnelManager< std::string >& mgr, const std::string& name )
+ *     : InfoProducer( mgr, name )
+ *     {
+ *         info << std::string( "example message" );
+ *     }
+ * };
+ * @endcode
+ * @see Producer, ChannelManager
+ */
+#define CPPLOG_DECLARE_CHANNEL( PP_NameSpace, PP_IdName, PP_RecordType ) \
+	CPPLOG_DECLARE_CHANNEL_WITH_ID( PP_NameSpace, PP_IdName, PP_RecordType, __COUNTER__ );
+
+#endif /* LOG_DECLAREMANAGEDCHANNEL_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/DeclareInfoType.h b/odemx-lite/external/CppLog/include/CppLog/DeclareInfoType.h
new file mode 100644
index 0000000000000000000000000000000000000000..e3b76f3a304b87ccc40b4784fc95e5a320406e41
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/DeclareInfoType.h
@@ -0,0 +1,66 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file DeclareInfoType.h
+ * @author Ronald Kluth
+ * @date created at 2009/06/05
+ * @brief Declaration and implementation of macro CPPLOG_DECLARE_INFO_TYPE
+ * @since 0.1
+ */
+
+#ifndef LOG_DECLAREINFOTYPE_INCLUDED
+#define LOG_DECLAREINFOTYPE_INCLUDED
+
+#include "StringLiteral.h"
+#include "detail/InfoType.h"
+
+/**
+ * @def CPPLOG_DECLARE_INFO_TYPE( PP_InfoTypeName, PP_StringName, PP_ValueType )
+ * @brief Macro to ease the creation of arbitrary record info types
+ * @param InfoTypeName The actual type name to be used
+ * @param StringName String representation for this type
+ * @param ValueType Type of the values the info type objects hold
+ *
+ * This macro is used to create record info types. In order for records to
+ * carry arbitrary values, these must be wrapped by @c InfoType classes.
+ * When expanded by the C++ preprocessor, this macro creates a new @c struct
+ * that is used as a tag to distinguish specializations of the class template
+ * InfoType holding the same value type.
+ * Additionally, it provides a static method @c getName that returns the given
+ * string representation (the second macro parameter). This string can be used
+ * during the automatic extraction of log record info data, e.g. to associate
+ * a piece of data with a table column in a database. The third macro parameter
+ * defines the type of the values this info type can hold. The value to be
+ * carried must be passed with the constructor and cannot be changed afterwards.
+ * Info types can transport copies as well as pointers or references to data.
+ *
+ * Example:
+ * @code
+ * CPPLOG_DECLARE_INFO_TYPE( FuncInfo, "Function", std::string );
+ * Channel< Record > channel;
+ * void foo()
+ * {
+ *   channel << Record( "function called" ) + FuncInfo( "foo()" );
+ * }
+ * @endcode
+ */
+#define CPPLOG_DECLARE_INFO_TYPE( PP_InfoTypeName, PP_StringName, PP_ValueType )		\
+																						\
+	struct PP_InfoTypeName##NameHolder													\
+	{																					\
+		static const Log::StringLiteral& getName() 										\
+		{ 																				\
+			static Log::StringLiteral name( PP_StringName ); 							\
+			return name; 																\
+		} 																				\
+	}; 																					\
+																						\
+	typedef Log::Detail::InfoType< PP_InfoTypeName##NameHolder, PP_ValueType > PP_InfoTypeName;
+
+
+#endif /* LOG_DECLAREINFOTYPE_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/DeclareInfoTypeList.h b/odemx-lite/external/CppLog/include/CppLog/DeclareInfoTypeList.h
new file mode 100644
index 0000000000000000000000000000000000000000..3f91bcaa877bb0af1c9ed0677e0703042cf77c4f
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/DeclareInfoTypeList.h
@@ -0,0 +1,44 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file DeclareInfoTypeList.h
+ * @author Ronald Kluth
+ * @date created at 2009/06/09
+ * @brief Declaration and implementation of macro CPPLOG_DECLARE_INFO_TYPE_LIST
+ * @since 0.1
+ */
+
+#ifndef LOG_DECLAREINFOTYPELIST_INCLUDED
+#define LOG_DECLAREINFOTYPELIST_INCLUDED
+
+#ifdef _MSC_VER
+#include <tuple>
+#else
+#include <tuple>
+#endif
+
+/**
+ * @def CPPLOG_DECLARE_INFO_TYPE_LIST( PP_InfoListName, ... )
+ * @brief This macro allows the creation of info type lists
+ * @param PP_InfoListName Type name of the list of info types
+ *
+ * Lists of info types are used in the automatic extraction of the data
+ * transported by Record objects. The first macro parameter specifies the
+ * type name of the list type, followed by a variable number of parameters,
+ * all of which must be info types declared with @c CPPLOG_DECLARE_INFO_TYPE.
+ * The implementation of these type lists is provided by the standard library
+ * class template @c tuple (added in TR1). The two helper templates
+ * @c tuple_size and @c tuple_element are used to iterate over the list at
+ * compile time.
+ *
+ * @see CPPLOG_DECLARE_INFO_TYPE
+ */
+#define CPPLOG_DECLARE_INFO_TYPE_LIST( PP_InfoListName, ... ) \
+	typedef std::tuple < __VA_ARGS__ > PP_InfoListName;
+
+#endif /* LOG_DECLAREINFOTYPELIST_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/DeclareSqlColumnTypes.h b/odemx-lite/external/CppLog/include/CppLog/DeclareSqlColumnTypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..0714985d4c18c2ffe3c25f432fd05e6a154ae458
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/DeclareSqlColumnTypes.h
@@ -0,0 +1,47 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file DeclareSqlColumnTypes.h
+ * @author Ronald Kluth
+ * @date created at 2009/06/19
+ * @brief Declaration and implementation of macro CPPLOG_DECLARE_SQL_COLUMN_TYPES
+ * @since 0.1
+ */
+
+#ifndef LOG_DECLARESQLCOLUMNTYPES_INCLUDED
+#define LOG_DECLARESQLCOLUMNTYPES_INCLUDED
+
+#ifdef _MSC_VER
+#include <tuple>
+#include <array>
+#else
+#include <tuple>
+#include <array>
+#endif
+
+
+/**
+ * @def CPPLOG_DECLARE_SQL_COLUMN_TYPES
+ * @brief This macro creates an array of SQL types matching an info type list
+ * @param PP_InfoListName Type name of the info type list
+ * @param PP_ArrayName Name of the array of SQL data types to be created
+ *
+ * The automatic extraction of info data from @c Record objects is based on
+ * iterating over info type lists. Writing into a database requires, however,
+ * that table columns have suitable SQL types that can stores the data
+ * transported by an info type. This macro is provided for the comfortable
+ * creation of SQL table definitions simply by iterating over the info type
+ * list and an array of matching column types, which is created by this macro.
+ *
+ * @see CPPLOG_DECLARE_INFO_TYPE_LIST
+ */
+#define CPPLOG_DECLARE_SQL_COLUMN_TYPES( PP_InfoListName, PP_ArrayName, ... ) \
+	std::array< std::string, std::tuple_size< PP_InfoListName >::value > \
+	PP_ArrayName = {{ __VA_ARGS__ }};
+
+#endif /* LOG_DECLARESQLCOLUMNTYPES_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/Enable.h b/odemx-lite/external/CppLog/include/CppLog/Enable.h
new file mode 100644
index 0000000000000000000000000000000000000000..5074930b23c26b010200d7fd698b8531ea24dcbd
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/Enable.h
@@ -0,0 +1,65 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file Enable.h
+ * @author Ronald Kluth
+ * @date 2010/04/24
+ * @brief Declaration and implementation of class template Enable
+ * @since 0.1
+ */
+
+#ifndef LOG_ENABLE_INCLUDED
+#define LOG_ENABLE_INCLUDED
+
+#include "detail/ChannelField.h"
+#include "detail/InheritFields.h"
+
+namespace Log {
+
+namespace Detail { enum { UNUSED = -100 }; }
+
+/**
+ * @brief Allows enabling of Producer channel members by providing declared channel IDs
+ * @note The unused IDs will match the general template of ChannelField, which
+ * becomes an empty class. Only IDs declared with CPPLOG_DECLARE_CHANNEL
+ * provide a specialization of ChannelField to be derived from.
+ * @note Declared IDs should not be negative numbers. The numbers for unused
+ * channels must be different so we do not derive from the same class twice.
+ */
+template <
+	int ID0,
+	int ID1 = Detail::UNUSED-1,
+	int ID2 = Detail::UNUSED-2,
+	int ID3 = Detail::UNUSED-3,
+	int ID4 = Detail::UNUSED-4,
+	int ID5 = Detail::UNUSED-5,
+	int ID6 = Detail::UNUSED-6,
+	int ID7 = Detail::UNUSED-7,
+	int ID8 = Detail::UNUSED-8,
+	int ID9 = Detail::UNUSED-9
+	>
+struct Enable
+{
+	typedef Detail::InheritFields<
+		Detail::ChannelField< ID0 >,
+		Detail::ChannelField< ID1 >,
+		Detail::ChannelField< ID2 >,
+		Detail::ChannelField< ID3 >,
+		Detail::ChannelField< ID4 >,
+		Detail::ChannelField< ID5 >,
+		Detail::ChannelField< ID6 >,
+		Detail::ChannelField< ID7 >,
+		Detail::ChannelField< ID8 >,
+		Detail::ChannelField< ID9 >
+		>
+	Type;
+};
+
+} // namespace Log
+
+#endif /* LOG_ENABLE_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/Filter.h b/odemx-lite/external/CppLog/include/CppLog/Filter.h
new file mode 100644
index 0000000000000000000000000000000000000000..bfa3ea69eda84096815954fbdfa9f7035d772993
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/Filter.h
@@ -0,0 +1,199 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file Filter.h
+ * @author Ronald Kluth
+ * @date created at 2009/06/07
+ * @brief Declaration and implementation of class Filter
+ * @since 0.1
+ */
+
+#ifndef LOG_FILTER_INCLUDED
+#define LOG_FILTER_INCLUDED
+
+#include "StringLiteral.h"
+#include "detail/InfoTypeFilter.h"
+#include "detail/SetInserter.h"
+#include "detail/TypeInfo.h"
+
+#include <map>
+
+#ifdef _MSC_VER
+#include <memory>
+#else
+#include <memory>
+#endif
+
+namespace Log {
+
+// forward declaration
+class Record;
+
+/**
+ * @brief Basic class template for log filters
+ * @note If this template is instantiated and @c pass is called, an assertion
+ * will fail because for each record type a specialization is required.
+ */
+template < typename RecordT = Record >
+class Filter
+{
+public:
+	bool pass( const RecordT& record ) const
+	{
+		assert( false && "Missing template specialization for record type" );
+		return false;
+	}
+};
+
+/**
+ * @brief A simple filter for log records, based on their text and info type values
+ *
+ * This class provides a simple filter for log records. It allows for record
+ * filtering by comparing each record's info type values to those stored in
+ * filter sets. All log channels have a member that may hold a record filter,
+ * but filter objects may be owned and used by log consumers as well to filter
+ * the records they receive.
+ *
+ * @b Usage:
+ * @code
+ * std::shared_ptr< Log::Filter< Record > > filter( new Log::Filter< Record >() );
+ * filter->passNone();
+ * filter->add< Log::ScopeInfo >() << "foo()" << "main()";
+ * @endcode
+ *
+ * The above code creates a filter object that allows no records to pass except
+ * those with scope "foo()" or scope "main()".
+ */
+template <>
+class Filter< Record >
+{
+public:
+	/// Creation via static method
+	static std::shared_ptr< Filter< Record > > create()
+	{
+		return std::shared_ptr< Filter< Record > >( new Filter() );
+	}
+
+	/// Reset filter to default values, which effectively disables it
+	void resetFilter()
+	{
+		isSet_ = false;
+		passAll_ = true;
+		recordTexts_.clear();
+		infoTypeFilters_.clear();
+	}
+
+	/// Only filter out the log records matched by the filter
+	void passAll()
+	{
+		isSet_ = true;
+		passAll_ = true;
+	}
+
+	/// Filter out all log records except those matched by the filter
+	void passNone()
+	{
+		isSet_ = true;
+		passAll_ = false;
+	}
+
+	/// Add record text values to the filter
+	Detail::SetInserter< StringLiteral > addRecordText()
+	{
+		// remember that the filter has been initialized
+		isSet_ = true;
+		return Detail::SetInserter< StringLiteral >( recordTexts_ );
+	}
+
+	/// Add values of type @c InfoT to the corresponding filter set
+	template < typename InfoT >
+	Detail::SetInserter< typename InfoT::ValueType > add()
+	{
+		using namespace std;
+		typedef Detail::InfoTypeFilterImpl< InfoT > FilterType;
+
+		// remember that the filter has been initialized
+		isSet_ = true;
+
+		// get the shared pointer to a filter or create a new one with op[]
+		InfoTypeFilterPtr& filter = infoTypeFilters_[ typeid( InfoT ) ];
+
+		// if the shared pointer is not initialized, do it now
+		if( ! filter )
+		{
+			filter.reset( new FilterType() );
+		}
+
+		// return a set inserter object that can be used with op<<
+		// TODO: using ValueType might not work for pointer types
+		return Detail::SetInserter< typename InfoT::ValueType >(
+				static_pointer_cast< FilterType >( filter )->filterSet_ );
+	}
+
+	/// Determine whether the @c record may pass the filter by checking info type sets and evaluating @c passAll_
+	bool pass( const Record& record ) const
+	{
+		// let all records pass if the filter is not set
+		if( ! isSet_ )
+		{
+			return true;
+		}
+
+		// check the record text first
+		if( recordTexts_.find( record.getText() ) != recordTexts_.end() )
+		{
+			// match found, the record may only pass if passAll_ is false
+			return ! passAll_;
+		}
+
+		// check all info type filters for matches in this record
+		bool found = false;
+		InfoTypeFilterMap::const_iterator iter;
+		for( iter = infoTypeFilters_.begin();
+			iter != infoTypeFilters_.end(); ++iter )
+		{
+			found = iter->second->matches( record );
+			if( found )
+			{
+				// match found, the record may only pass if passAll_ is false
+				return ! passAll_;
+			}
+		}
+		// no match found, the record may pass if passAll_ is true
+		return passAll_;
+	}
+
+protected:
+	/// Pointer type to manage info type filter objects
+	typedef std::shared_ptr< Detail::InfoTypeFilter > InfoTypeFilterPtr;
+	/// Map type that holds smart pointers to info type filters, indexed by type info
+	typedef std::map< Detail::TypeInfo, InfoTypeFilterPtr > InfoTypeFilterMap;
+
+	/// Stores whether the filter has been initialized with filter values
+	bool isSet_;
+	/// Stores whether the filter should by default pass all records or none
+	bool passAll_;
+	/// Stores text values to be matched when filtering records
+	std::set< StringLiteral > recordTexts_;
+	/// Stores the actual filter objects for different record info types
+	InfoTypeFilterMap infoTypeFilters_;
+
+protected:
+	/// Construction protected, use create instead
+	Filter()
+	:	isSet_( false )
+	,	passAll_( true )
+	,	recordTexts_()
+	,	infoTypeFilters_()
+	{
+	}
+};
+
+} // namespace Log
+
+#endif /* LOG_FILTER_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/NameScope.h b/odemx-lite/external/CppLog/include/CppLog/NameScope.h
new file mode 100644
index 0000000000000000000000000000000000000000..0885b54d5b5671ddc5e6779575253bafc7f51ee9
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/NameScope.h
@@ -0,0 +1,105 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file NameScope.h
+ * @author Ronald Kluth
+ * @date created at 2009/02/08
+ * @brief Declaration and implementation of class NameScope
+ * @since 0.1
+ */
+
+#ifndef LOG_NAMESCOPE_INCLUDED
+#define LOG_NAMESCOPE_INCLUDED
+
+#include <cstddef> // size_t
+#include <map>
+#include <sstream>
+#include <string>
+
+namespace Log {
+
+/**
+ * @class NameScope
+ * @brief This class provides a scope for object names.
+ *
+ * All named objects receive their name from a name scope. This guarantees
+ * that every name created by it is unique within the scope.
+ */
+class NameScope
+{
+public:
+	/**
+	 * @brief Construction
+	 * @param defaultName The default name, given to objects which don't request
+	 * a specific name
+	 * @param defaultSpace The default fill character separating the added number
+	 * from the name string
+	 */
+	NameScope( const std::string& defaultName = "Unnamed", const char defaultSpace = '_' );
+
+	/// Destruction
+	virtual ~NameScope();
+
+	/**
+	 * @brief Create a unique name for the caller
+	 * @param name The basic part of the name, if left blank the default
+	 * name is used
+	 * @return A unique name string
+	 *
+	 * This method builds a unique name. If there is already a name in this
+	 * scope equal to the requested @c name, the new name gets a number.
+	*/
+	std::string createUniqueName( std::string name );
+
+protected:
+	/// Holds the default name
+	const std::string defaultName_;
+	/// Holds the default fill character
+	const char defaultSpace_;
+	/// Holds requested names and their number of occurrences within the scope
+	std::map< std::string, std::size_t > nameLookup_;
+};
+
+//------------------------------------------------------construction/destruction
+
+inline NameScope::NameScope( const std::string& defaultName, const char defaultSpace )
+:	defaultName_( defaultName )
+,	defaultSpace_( defaultSpace )
+{
+}
+
+inline NameScope::~NameScope()
+{
+}
+
+//---------------------------------------------------------unique label creation
+
+inline std::string NameScope::createUniqueName( std::string name )
+{
+	if( name.empty() )
+	{
+		name = defaultName_;
+	}
+
+	// get count for this name and increment
+	unsigned int number = nameLookup_[ name ]++;
+
+	// append count if the name is not unique
+	if( number > 0 )
+	{
+		std::ostringstream stream;
+		stream << name << defaultSpace_ << number;
+		return stream.str();
+	}
+
+	return name;
+}
+
+} // namespace Log
+
+#endif /* LOG_NAMESCOPE_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/NamedElement.h b/odemx-lite/external/CppLog/include/CppLog/NamedElement.h
new file mode 100644
index 0000000000000000000000000000000000000000..559d419eeec36c6aec07916a9d09d9ad0a699df7
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/NamedElement.h
@@ -0,0 +1,73 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file NamedElement.h
+ * @author Ronald Kluth
+ * @date created at 2009/02/08
+ * @brief Declaration and implementation of class NamedElement
+ * @since 0.1
+ */
+
+#ifndef LOG_NAMEDELEMENT_INCLUDED
+#define LOG_NAMEDELEMENT_INCLUDED
+
+#include "NameScope.h"
+#include <string>
+
+namespace Log {
+
+/**
+ * @class NamedElement
+ * @brief The base class for all classes whose instances require unique names
+ * within a name scope
+ */
+class NamedElement
+{
+public:
+	/**
+	 * @brief Construction with scope and name initialization
+	 *
+	 * The constructor requests the use of @c name from the scope object. The
+	 * value of @c name provides the base for the actual name of the object
+	 * because the scope object may need to append a suffix to ensure the
+	 * uniqueness of names.
+	 */
+	NamedElement( NameScope& scope, const std::string& name );
+
+	/// Destruction
+	virtual ~NamedElement();
+
+	/// Get the object's name
+	const std::string& getName() const;
+
+private:
+	/// The name of an object
+	std::string name_;
+};
+
+//------------------------------------------------------construction/destruction
+
+inline NamedElement::NamedElement( NameScope& scope, const std::string& name )
+{
+	name_ = scope.createUniqueName( name );
+}
+
+inline NamedElement::~NamedElement()
+{
+}
+
+//-----------------------------------------------------------------------getters
+
+inline const std::string& NamedElement::getName() const
+{
+	return name_;
+}
+
+} // namespace Log
+
+#endif /* LOG_NAMEDELEMENT_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/Producer.h b/odemx-lite/external/CppLog/include/CppLog/Producer.h
new file mode 100644
index 0000000000000000000000000000000000000000..13d1e785472ee1073bfc5a14964397628085faee
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/Producer.h
@@ -0,0 +1,73 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file CppLog/Producer.h
+ * @author Ronald Kluth
+ * @date created at 2009/06/06
+ * @brief Declaration and implementation of class template Producer
+ * @since 0.1
+ */
+
+#ifndef LOG_PRODUCER_INCLUDED
+#define LOG_PRODUCER_INCLUDED
+
+#include "ChannelManager.h"
+#include "Enable.h"
+#include "NamedElement.h"
+
+namespace Log {
+
+/**
+ * @brief Producer template type, ensures that all producers have unique names
+ * @tparam EnableT The type of channels to be enabled for the producer
+ *
+ * The producer will automatically contain pointers to enabled channels, but
+ * these are not initialized. This is the responsibility of the subclass.
+ */
+template < typename EnableT >
+class Producer
+:	public NamedElement
+,	public EnableT::Type
+{
+public:
+	/**
+	 * @brief Construction
+	 * @param scope Reference to the name scope which ensures unique names
+	 * @param name Name of the log producer object, unique within the given scope
+	 */
+	Producer( NameScope& scope, std::string const& name )
+	:	NamedElement( scope, name )
+	{}
+
+	/**
+	 * @brief Construction with channel manager
+	 * @param manager Reference to a channel manager
+	 * @param name Name of the log producer object, unique within manager's scope
+	 * @note This constructor can only be used if all of the producer's channels
+	 * use the same record type, because the enabled channels are automatically
+	 * initialized during construction
+	 */
+	template < typename RecordT >
+	Producer( ChannelManager< RecordT >& manager, std::string const& name )
+	:	NamedElement( manager, name )
+	,	EnableT::Type( manager )
+	{}
+
+	/// Destruction
+	virtual ~Producer() {}
+
+private:
+	/// Non-copyable
+	Producer( Producer const& );
+	/// Non-assignable
+	Producer& operator=( Producer const& );
+};
+
+} // namespace Log
+
+#endif /* LOG_PRODUCER_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/Record.h b/odemx-lite/external/CppLog/include/CppLog/Record.h
new file mode 100644
index 0000000000000000000000000000000000000000..60390bd59c1b1e00254b3271e5a717766668e0d9
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/Record.h
@@ -0,0 +1,149 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file Record.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/01
+ * @brief Declaration and implementation of class Record
+ * @since 0.1
+ */
+
+#ifndef LOG_RECORD_INCLUDED
+#define LOG_RECORD_INCLUDED
+
+#include "DeclareInfoType.h"
+#include "StringLiteral.h"
+#include "detail/InfoHolder.h"
+#include "detail/InfoTypeLoop.h"
+
+namespace Log {
+
+/**
+ * @struct FileInfo
+ * @brief Record info type that holds filenames as @c std::string
+ */
+#ifndef DOXYGEN_SKIP
+CPPLOG_DECLARE_INFO_TYPE( FileInfo, "file", StringLiteral );
+#endif
+
+/**
+ * @struct LineInfo
+ * @brief Record info type that holds line numbers as <tt>unsigned int</tt>
+ */
+#ifndef DOXYGEN_SKIP
+CPPLOG_DECLARE_INFO_TYPE( LineInfo, "line", unsigned int );
+#endif
+
+/**
+ * @struct ScopeInfo
+ * @brief Record info type that holds scope information as @c std::string
+ */
+#ifndef DOXYGEN_SKIP
+CPPLOG_DECLARE_INFO_TYPE( ScopeInfo, "scope", StringLiteral );
+#endif
+
+/**
+ * @brief The default record type provided by the library
+ * 
+ * Objects of this class transport information passed through log channels
+ *
+ * By deriving from InfoHolder, record objects gain the ability to transport
+ * information of arbitrary type. All that is needed to use the feature are
+ * simple macro calls which declare the used information types.
+ *
+ * @code
+ * CPPLOG_DECLARE_INFO_TYPE( SenderInfo, "Sender", std::string );
+ * @endcode
+ *
+ * After this, the declared type can already be used to add more information
+ * to log records. Usage of this feature is implemented through an overloaded
+ * @c operator+.  The stored information can be retrieved by calling the method
+ * template @c get, which is defined in the base class InfoHolder. The template
+ * parameter is the information type.
+ *
+ * @code
+ * Record rec( "log message" );
+ * rec + SenderInfo( "class XYZ" );
+ *
+ * if( SenderInfo::ValueType* sender = rec.get< SenderInfo >() )
+ * {
+ *     std::cout << *sender;
+ * }
+ * @endcode
+ *
+ * The library by default provides three info types for log records:
+ * @c FileInfo, @c LineInfo, and @c ScopeInfo. Class Record provides chainable
+ * convenience methods to easily add these types. They can be used like this:
+ *
+ * @code
+ * Log::Record rec( "message text" );
+ * rec.file( __FILE__ ).line( __LINE__ ).scope( "foo()" );
+ * @endcode
+ */
+class Record
+:	public Detail::InfoHolder< Record >
+{
+public:
+	/// Default construction
+	Record() {}
+
+	/// Construction with text message
+	Record( const StringLiteral& text )
+	:	text_( text )
+	{}
+
+	/// Destruction
+	virtual ~Record() {}
+
+	/// Add file information to the record, supports method chaining
+	Record& file( const StringLiteral& file )
+	{
+		*this + FileInfo( file );
+		return *this;
+	}
+
+	/// Add line information to the record, supports method chaining
+	Record& line( const unsigned int lineNumber )
+	{
+		*this + LineInfo( lineNumber );
+		return *this;
+	}
+
+	/// Add scope information to the record, supports method chaining
+	Record& scope( const StringLiteral& scope )
+	{
+		*this + ScopeInfo( scope );
+		return *this;
+	}
+	/// Get the text message sent with the log record
+	const StringLiteral& getText() const
+	{
+		return text_;
+	}
+
+	/// Call @c func on the record object for all listed info types and return @c func
+	template < typename InfoListT, typename FuncT >
+	FuncT& iterateInfo( FuncT& func ) const
+	{
+		Detail::InfoTypeLoop<
+			FuncT,
+			Record,
+			InfoListT,
+			Detail::SizeOf< InfoListT >::value - 1
+		>::call( func, *this );
+		return func;
+	}
+
+private:
+	/// Stores the message text transported by a record
+	StringLiteral text_;
+};
+
+} // namespace Log
+
+#endif /* LOG_RECORD_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/StringLiteral.h b/odemx-lite/external/CppLog/include/CppLog/StringLiteral.h
new file mode 100644
index 0000000000000000000000000000000000000000..1949e32c3d05d15216b6b4bf0dd9f2a18445f8ba
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/StringLiteral.h
@@ -0,0 +1,38 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file StringLiteral.h
+ * @author Ronald Kluth
+ * @date created at 2009/11/19
+ * @brief Declaration of type StringLiteral
+ * @since 0.1
+ */
+
+#ifndef LOG_STRINGLITERAL_INCLUDED
+#define LOG_STRINGLITERAL_INCLUDED
+
+#include "detail/string_literal.hpp"
+
+namespace Log {
+
+/**
+ * @typedef StringLiteral
+ * @brief Thin wrapper around string literals, borrowed from boost::log
+ *
+ * This class provides a thin wrapper around string literals (i.e. "strings like this")
+ * with the const method interface of @c std::string. All member data are
+ * allocated on the stack, making it significantly faster than @c std::string.
+ * It can be contructed with or without a string literal, and the class offers
+ * assignment, clearing, and comparison operators. Explicit conversion to std::string
+ * and C-strings ist provided as well. Use in containers is possible.
+ */
+typedef boost::log::string_literal StringLiteral;
+
+} // namespace Log
+
+#endif /* LOG_STRINGLITERAL_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/Bindings.h b/odemx-lite/external/CppLog/include/CppLog/detail/Bindings.h
new file mode 100644
index 0000000000000000000000000000000000000000..546eeb9898a92666c2c9c0dd482e052af012fe54
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/Bindings.h
@@ -0,0 +1,144 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file Bindings.h
+ * @author Ronald Kluth
+ * @date 2009/11/28
+ * @brief Implementation of template specialization Poco::Data::Binding<boost::log::string_literal>
+ * @since 0.1
+ */
+
+#ifndef LOG_DETAIL_BINDINGS_INCLUDED
+#define LOG_DETAIL_BINDINGS_INCLUDED
+
+#include "string_literal.hpp"
+
+#include <Poco/Data/Binding.h>
+
+namespace Poco {
+namespace Data {
+
+/**
+ * @brief Template specialization for database insertion of boost::log::string_literal
+ */
+template <>
+class Binding< boost::log::string_literal >: public AbstractBinding
+	/// Binding const char* specialization wraps char pointer into string.
+{
+public:
+	explicit Binding( const boost::log::string_literal& pVal,
+		const std::string& name = "",
+		Direction direction = PD_IN):
+		AbstractBinding(name, direction),
+		_val( pVal.c_str() ),
+		_bound(false)
+		/// Creates the Binding by copying the passed string.
+	{
+	}
+
+	~Binding()
+		/// Destroys the Binding.
+	{
+	}
+
+	std::size_t numOfColumnsHandled() const
+	{
+		return 1u;
+	}
+
+	std::size_t numOfRowsHandled() const
+	{
+		return 1u;
+	}
+
+	bool canBind() const
+	{
+		return !_bound;
+	}
+
+	void bind(std::size_t pos)
+	{
+		poco_assert_dbg(getBinder() != 0);
+		TypeHandler<std::string>::bind(pos, _val, getBinder(), getDirection());
+		_bound = true;
+	}
+
+	void reset ()
+	{
+		_bound = false;
+		AbstractBinder* pBinder = getBinder();
+		poco_check_ptr (pBinder);
+		pBinder->reset();
+	}
+
+private:
+	std::string _val;
+	bool        _bound;
+};
+
+/**
+ * @brief Template specialization for database insertion of boost::log::string_literal
+ */
+template <>
+class CopyBinding< boost::log::string_literal >: public AbstractBinding
+	/// Binding const char* specialization wraps char pointer into string.
+{
+public:
+	explicit CopyBinding( const boost::log::string_literal& pVal,
+		const std::string& name = "",
+		Direction direction = PD_IN):
+		AbstractBinding(name, direction),
+		_val( pVal.c_str() ),
+		_bound(false)
+		/// Creates the Binding by copying the passed string.
+	{
+	}
+
+	~CopyBinding()
+		/// Destroys the Binding.
+	{
+	}
+
+	std::size_t numOfColumnsHandled() const
+	{
+		return 1u;
+	}
+
+	std::size_t numOfRowsHandled() const
+	{
+		return 1u;
+	}
+
+	bool canBind() const
+	{
+		return !_bound;
+	}
+
+	void bind(std::size_t pos)
+	{
+		poco_assert_dbg(getBinder() != 0);
+		TypeHandler<std::string>::bind(pos, _val, getBinder(), getDirection());
+		_bound = true;
+	}
+
+	void reset ()
+	{
+		_bound = false;
+		AbstractBinder* pBinder = getBinder();
+		poco_check_ptr (pBinder);
+		pBinder->reset();
+	}
+
+private:
+	std::string _val;
+	bool        _bound;
+};
+
+} } // namespace Poco::Data
+
+#endif /* LOG_DETAIL_BINDINGS_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/ChannelField.h b/odemx-lite/external/CppLog/include/CppLog/detail/ChannelField.h
new file mode 100644
index 0000000000000000000000000000000000000000..221bbaf30bffdd26a951b419d853e18dca38fb76
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/ChannelField.h
@@ -0,0 +1,41 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file ChannelField.h
+ * @author Ronald Kluth
+ * @date created at 2009/11/05
+ * @brief Declaration of class template ChannelField
+ * @since 0.1
+ */
+
+#ifndef LOG_CHANNELFIELD_INCLUDED
+#define LOG_CHANNELFIELD_INCLUDED
+
+#include "../ChannelManager.h"
+
+namespace Log {
+namespace Detail {
+
+/**
+ * @brief Class template for adding producer channel members, default is empty
+ *
+ * This template is used by the macro @c CPPLOG_DECLARE_CHANNEL, which defines
+ * specializations containing a named channel pointer member. These
+ * specializations are then inherited to add channel members to producers.
+ */
+template < int ID >
+struct ChannelField
+{
+	ChannelField(){}
+	template< typename ManagerT >
+	ChannelField( ManagerT& ignored ){}
+};
+
+} } // namespace Log::Detail
+
+#endif /* LOG_CHANNELFIELD_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/DebugOut.h b/odemx-lite/external/CppLog/include/CppLog/detail/DebugOut.h
new file mode 100644
index 0000000000000000000000000000000000000000..4a77daee8827058b844d49aedd9732b7749c289e
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/DebugOut.h
@@ -0,0 +1,63 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file DebugOut.h
+ * @author Ronald Kluth
+ * @date created at 2009/11/25
+ * @brief Declaration and implementation of class DebugOut and stream inserter
+ * @since 0.1
+ */
+
+#ifndef LOG_DETAIL_DEBUGOUT_INCLUDED
+#define LOG_DETAIL_DEBUGOUT_INCLUDED
+
+#include <iostream>
+#include <string>
+
+namespace Log {
+namespace Detail {
+
+/**
+ * @brief Helper struct to quickly add scoped stdout debugging
+ *
+ * When an object of this type is declared with its scope given as string,
+ * it will print 'entering scope' upon construction and 'leaving scope' upon
+ * destruction. During its lifetime, the object can then be used like an
+ * @c std::ostream to print arbitrary data to stdout.
+ */
+struct DebugOut
+{
+	DebugOut( const std::string& scope ): scope_( scope )
+	{
+		std::cout << "entering " << scope_ << std::endl;
+	}
+	~DebugOut()
+	{
+		std::cout << "leaving " << scope_ << std::endl;
+	}
+	std::string scope_;
+};
+
+/**
+ * @brief Overload of the stream inserter op<< for DebugOut and arbitrary values
+ * @tparam T Type of the value to be printed to @c stdout
+ * @param out Reference to the DebugOut object
+ * @param t Value to be printed to @c stdout
+ * @return @c out to enable chaining
+ */
+template < typename T >
+const DebugOut& operator<<( const DebugOut& out, const Strip<T>::Ref t )
+{
+	// shortcut to cout
+	std::cout << t << std::flush;
+	return out;
+}
+
+} } // namespace Log::Detail
+
+#endif /* LOG_DETAIL_DEBUGOUT_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/EnableIf.h b/odemx-lite/external/CppLog/include/CppLog/detail/EnableIf.h
new file mode 100644
index 0000000000000000000000000000000000000000..a727d07965ca1f3216a4b329c602030a58217d4b
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/EnableIf.h
@@ -0,0 +1,54 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file EnableIf.h
+ * @author Ronald Kluth
+ * @date created at 2009/11/25
+ * @brief Declaration and implementation of class template EnableIf
+ * @since 0.1
+ */
+
+#ifndef LOG_DETAIL_ENABLEIF_INCLUDED
+#define LOG_DETAIL_ENABLEIF_INCLUDED
+
+namespace Log {
+namespace Detail {
+
+/**
+ * @brief EnableIf implementation, matches @c true, has @c Type definition
+ */
+template < bool B, typename T = void >
+struct EnableIfImpl
+{
+	typedef T Type;
+};
+
+/**
+ * @brief EnableIf implementation, @c false specialization, has no @c Type definition
+ */
+template < typename T >
+struct EnableIfImpl< false, T >
+{
+};
+
+/**
+ * @brief Enables templates by checking a condition (e.g. using type traits)
+ * @note This technique is based on boost::enable_if
+ * @see InfoType
+ *
+ * This template is used to select template specializations, for example by
+ * checking type traits such as @c is_pointer or @c is_reference.
+ */
+template < typename Cond, typename T = void >
+struct EnableIf: public EnableIfImpl< Cond::value, T >
+{
+};
+
+} } // namespace Log::Detail
+
+#endif /* LOG_DETAIL_ENABLEIF_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/InfoHolder.h b/odemx-lite/external/CppLog/include/CppLog/detail/InfoHolder.h
new file mode 100644
index 0000000000000000000000000000000000000000..d96efeb3bc6a8e3cd4a29f3a53e18361dd4e3c0d
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/InfoHolder.h
@@ -0,0 +1,137 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file InfoHolder.h
+ * @author Ronald Kluth
+ * @date created at 2009/05/28
+ * @brief Declaration and implementation of class template InfoHolder
+ * @since 0.1
+ */
+
+#ifndef LOG_DETAIL_INFOHOLDER_INCLUDED
+#define LOG_DETAIL_INFOHOLDER_INCLUDED
+
+#include "TypeInfo.h"
+
+#include <cassert>
+#include <map>
+
+#ifdef _MSC_VER
+#include <memory>
+#include <unordered_map>
+#else
+#include <memory>
+#include <unordered_map>
+#endif
+
+namespace Log {
+namespace Detail {
+
+// forward declarations
+class InfoTypeBase;
+template < typename, typename , typename > class InfoType;
+
+/**
+ * @class InfoHolder
+ * @brief Base class that allows storage of any number of InfoType objects
+ *
+ * This class allows the storage of arbitrary data objects, they are
+ * instances of InfoType classes or one if their subclasses. It works by
+ * keeping a map of TypeInfo and InfoTypeBase objects. The actual InfoType
+ * value is accessed by a templated method that must provide the real type
+ * in order to retrieve it from the map by looking up the @c typeid.
+ *
+ * @note InfoType and InfoHolder are based on a technique demonstrated
+ * by boost::error_info.
+ */
+template < typename DerivedT >
+class InfoHolder
+{
+public:
+	// NOTE: using InfoTypeBase const* as map value would require InfoHolder
+	// to be non-copyable to avoid multiple deletion in the destructor,
+	// another (inefficient) option would be deep copying of the map
+
+	typedef DerivedT DerivedType;
+
+	/// Map type to hold pointers to InfoType objects, indexed by their TypeInfo
+//	typedef std::map< TypeInfo, std::shared_ptr< InfoTypeBase const > > InfoMap;
+	typedef std::unordered_map< TypeInfo, std::shared_ptr< InfoTypeBase const > > InfoMap;
+
+	// Compiler-generated ctor, copy, and assignment is o.k.
+
+	/// Destruction
+	virtual ~InfoHolder() {}
+
+	/// Overloaded @c operator+ provides the means to add InfoType objects to InfoHolder
+	template < typename InfoT >
+	friend
+	DerivedType const&
+	operator+( DerivedType const& holder, InfoT const& value )
+	{
+		// copy-construct a dynamically allocated Info object from value
+		// and store it in a base class pointer
+		std::shared_ptr< InfoTypeBase const > data( new InfoT( value ) );
+		holder.add( data, typeid( InfoT ) );
+		return holder;
+	}
+
+	/// Retrieval of InfoType objects via template method, @c InfoT must be specified
+	template < typename InfoT >
+	typename InfoT::Type const*
+	get() const
+	{
+		typedef InfoT Info;
+
+ 		std::shared_ptr< InfoTypeBase const > const&
+ 				basePtr = getInfoByType( typeid( Info ) );
+
+		// the returned basePtr object may be empty if type not found
+		if( ! basePtr )
+		{
+			return 0;
+		}
+
+		// retrieve the actual info type and return its value
+		Info const* data = static_cast< Info const* >( basePtr.get() );
+		return data->value();
+	}
+
+private:
+	// HACK: declared mutable to allow use of const temporaries with op+ above
+	/// Internal InfoType object storage, indexed by TypeInfo
+	mutable InfoMap infos_;
+
+private:
+	/// Internal method to add an InfoType object to the InfoHolder
+ 	void add( std::shared_ptr< InfoTypeBase const > const& data,
+ 			TypeInfo const& typeInfo ) const
+	{
+		//assert( data );
+		// existing entries will be replaced and automatically deleted
+		infos_[ typeInfo ] = data;
+	}
+
+	/// Internal method for retrieval of a stored InfoType object
+	std::shared_ptr< InfoTypeBase const > const&
+	getInfoByType( TypeInfo const& typeInfo ) const
+	{
+		InfoMap::const_iterator found = infos_.find( typeInfo );
+		if( found != infos_.end() )
+		{
+			return found->second;
+		}
+		// this allows us to always return a reference
+		static std::shared_ptr< InfoTypeBase const > const emptyPtr;
+		return emptyPtr;
+	}
+};
+
+} } // namespace Log::Detail
+
+#endif /* LOG_DETAIL_INFOHOLDER_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/InfoType.h b/odemx-lite/external/CppLog/include/CppLog/detail/InfoType.h
new file mode 100644
index 0000000000000000000000000000000000000000..bfe1570f61139b819e17b6283c489c8ee80ef302
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/InfoType.h
@@ -0,0 +1,194 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file InfoType.h
+ * @author Ronald Kluth
+ * @date created at 2009/05/28
+ * @brief Declaration and implementation of class template InfoType
+ * @since 0.1
+ */
+
+#ifndef LOG_DETAIL_INFOTYPE_INCLUDED
+#define LOG_DETAIL_INFOTYPE_INCLUDED
+
+#include "EnableIf.h"
+#include "Strip.h"
+#include "string_literal.hpp"
+
+#ifdef _MSC_VER
+#include <type_traits>
+#else
+#include <type_traits>
+#endif
+
+#include <string>
+
+namespace Log {
+namespace Detail {
+
+typedef boost::log::string_literal StringLiteral;
+
+/**
+ * @class InfoTypeBase
+ * @brief Empty base class used to emulate heterogeneous containers
+ *
+ * This class is used to allow storage of pointers to different @c InfoType<T>
+ * objects in containers. The real value is retrieved by using template methods
+ * parameterized with the correct info type.
+ *
+ * @see InfoType, InfoHolder
+ */
+class InfoTypeBase
+{
+public:
+	virtual ~InfoTypeBase() {}
+};
+
+/**
+ * @class InfoType
+ * @brief Wrapper for arbitrary value types to store additional record information
+ * @tparam NameHolderT Unique type to distinguish info types and get a string name
+ * @tparam ValueT Type of the wrappper's stored value, must be copyable
+ * @tparam EnableT Specialization selector, e.g. @c EnableIf<>
+ * @note The default template implementation copies the value.
+ *
+ * Info type classes can hold arbitrary data of type @c ValueT. The tag type
+ * @c TagT is required to distinguish info type objects with the same value
+ * type by using their @c typeid. Obviously, the tag types must be unique for
+ * this to work properly.
+ *
+ * @note InfoType and InfoHolder are based on a technique demonstrated
+ * by boost::error_info.
+ * @note This class template is not intended to be used directly, use the macro
+ * @c CPPLOG_DECLARE_INFO_TYPE instead.
+ */
+template < typename NameHolderT, typename ValueT, typename EnableT = void >
+class InfoType
+:	public InfoTypeBase
+{
+public:
+	/// Type of the struct providing the info type's string name
+	typedef NameHolderT NameHolderType;
+	/// Value type definition for template use and value access
+	typedef ValueT ValueType;
+	/// Actual type of the data, when pointer or reference is stripped
+	typedef typename Strip< ValueType >::Type Type;
+
+	/// Construction
+	InfoType( Type const& value )
+	:	value_( value )
+	{
+	}
+
+	/// Value retrieval
+	Type const* value() const
+	{
+		return &value_;
+	}
+
+	/// Get a string name for this info type
+	static StringLiteral const& getName()
+	{
+		return NameHolderType::getName();
+	}
+
+private:
+	/// Const value storage, no re-assignment
+	Type const value_;
+};
+
+#ifndef DOXYGEN_SKIP
+/**
+ * @brief Specialization of InfoType to hold pointer types
+ * @note This specialization only copies the pointer, not the value.
+ * @note The fact that the method @c value always returns a pointer to const
+ * allows @c InfoHolder::get to always return a pointer, instead of pointer-to-pointer.
+ */
+#endif
+template < typename NameHolderT, typename ValueT >
+class InfoType< NameHolderT, ValueT, typename EnableIf< typename std::is_pointer< ValueT > >::Type >
+:	public InfoTypeBase
+{
+public:
+	/// Type of the struct providing the info type's string name
+	typedef NameHolderT NameHolderType;
+	/// Value type definition for template use and value access
+	typedef ValueT ValueType;
+	/// Actual type of the data, when pointer or reference is stripped
+	typedef typename Strip< ValueType >::Type Type;
+
+	/// Construction
+	InfoType( Type const* value )
+	:	value_( value )
+	{
+	}
+
+	/// Value retrieval
+	Type const* value() const
+	{
+		return value_;
+	}
+
+	/// Get a string name for this info type
+	static StringLiteral const& getName()
+	{
+		return NameHolderType::getName();
+	}
+
+private:
+	/// Const value storage, no re-assignment
+	Type const* value_;
+};
+
+#ifndef DOXYGEN_SKIP
+/**
+ * @brief Specialization of InfoType to hold reference types
+ * @note The specialization only copies the reference, not the value
+ * @note The fact that the method @c value always returns a pointer to const
+ * allows @c InfoHolder::get to always return a pointer, instead of
+ * pointer-to-reference (which is not allowed).
+ */
+#endif
+template < typename NameHolderT, typename ValueT >
+class InfoType< NameHolderT, ValueT, typename EnableIf< typename std::is_reference< ValueT > >::Type >
+:	public InfoTypeBase
+{
+public:
+	/// Type of the struct providing the info type's string name
+	typedef NameHolderT NameHolderType;
+	/// Value type definition for template use and value access
+	typedef ValueT ValueType;
+	/// Actual type of the data, when pointer or reference is stripped
+	typedef typename Strip< ValueType >::Type Type;
+
+	/// Construction
+	InfoType( Type const& value )
+	:	value_( value )
+	{
+	}
+
+	/// Value retrieval
+	Type const* value() const
+	{
+		return &value_;
+	}
+
+	/// Get a string name for this info type
+	static StringLiteral const& getName()
+	{
+		return NameHolderType::getName();
+	}
+
+private:
+	/// Const value storage, no re-assignment
+	Type const& value_;
+};
+
+} } // namespace Log::Detail
+
+#endif /* LOG_DETAIL_INFOTYPE_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/InfoTypeFilter.h b/odemx-lite/external/CppLog/include/CppLog/detail/InfoTypeFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..a914692a1a54eebd4f2281005be5331b9dd6c761
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/InfoTypeFilter.h
@@ -0,0 +1,85 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file InfoTypeFilter.h
+ * @author Ronald Kluth
+ * @date created at 2009/06/07
+ * @brief Declaration and implementation of class InfoTypeFilter and template InfoTypeFilterImpl
+ * @since 0.1
+ */
+
+#ifndef LOG_DETAIL_INFOTYPEFILTER_INCLUDED
+#define LOG_DETAIL_INFOTYPEFILTER_INCLUDED
+
+#include "../Record.h"
+
+#include <set>
+
+namespace Log {
+namespace Detail {
+
+/**
+ * @class InfoTypeFilter
+ * @brief Interface class to emulate hetrogeneous containers
+ *
+ * A record filter holds a map of info type filters. In order to check records
+ * for filtering, the record filter iterates over all InfoTypeFilter objects
+ * and checks whether one of the stored values matches that stored in the record.
+ */
+class InfoTypeFilter
+{
+public:
+	/// Destruction
+	virtual ~InfoTypeFilter() {}
+	/// Called on derived objects that store sets of InfoType values
+	virtual bool matches( const Record& record ) = 0;
+};
+
+/**
+ * @class InfoTypeFilterImpl
+ * @brief Implementation of record filtering functionality based on info types
+ * @tparam InfoT Type of record info to be filtered
+ *
+ * The implementation of InfoTypeFilter holds a set of @c InfoT values to be
+ * matched against those transported by records. This class defines the method
+ * @c matches, which determines whether a given record contains an info
+ * type value that is stored in the filter set.
+ */
+template < typename InfoT >
+class InfoTypeFilterImpl
+:	public InfoTypeFilter
+{
+public:
+	/// The record info type that can be filtered by this class
+	typedef InfoT InfoType;
+	/// Set type to hold filter values
+	typedef std::set< typename InfoType::ValueType > FilterSet;
+
+	/// Destruction
+	virtual ~InfoTypeFilterImpl() {}
+
+	/// Check if the @c InfoT value of @c record is found in the filter set
+	virtual bool matches( const Record& record )
+	{
+		// try to retrieve the InfoType value from the record, may be 0
+		typename InfoType::ValueType const* value = record.get< InfoType >();
+		if( ! value )
+		{
+			return false;
+		}
+		// a record matches if the value is found in the filter set
+		return filterSet_.find( *value ) != filterSet_.end();
+	}
+
+	/// Stores @c InfoT values to determine which records get filtered out
+	FilterSet filterSet_;
+};
+
+} } // namespace Log::Detail
+
+#endif /* LOG_DETAIL_INFOTYPEFILTER_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/InfoTypeLoop.h b/odemx-lite/external/CppLog/include/CppLog/detail/InfoTypeLoop.h
new file mode 100644
index 0000000000000000000000000000000000000000..247529ad9bcc17db4add0d45650be38498d35332
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/InfoTypeLoop.h
@@ -0,0 +1,178 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file InfoTypeLoop.h
+ * @author Ronald Kluth
+ * @date created at 2009/06/09
+ * @brief Declaration and implementation of class template InfoTypeLoop,
+ * SizeOf and TypeOf for tuples
+ * @since 0.1
+ */
+
+#ifndef LOG_DETAIL_INFOTYPELOOP_INCLUDED
+#define LOG_DETAIL_INFOTYPELOOP_INCLUDED
+
+#ifdef _MSC_VER
+#include <tuple>
+#else
+#include <tuple>
+#endif
+
+
+namespace Log {
+namespace Detail {
+
+/**
+ * @brief Class type to represent empty type lists
+ *
+ * This empty class is used as default template parameter for default
+ * output components. It is needed in case the logged records do not contain
+ * any info types to extract. Extraction of a NullList stops the InfoTypeLoop
+ * and therefore does nothing.
+ */
+struct NullList {};
+
+/**
+ * @class SizeOf
+ * @brief Determine the number types of an info type list
+ * @tparam InfoListT A list of info types (must be an @c std::tuple)
+ *
+ * This class provides a wrapper over @c std::tuple_size to determine
+ * the number of types in @c InfoListT at compile time.
+ */
+template < typename InfoListT >
+struct SizeOf
+{
+	enum { value = std::tuple_size< InfoListT >::value };
+};
+
+#ifndef DOXYGEN_SKIP
+/// Template specialization for @c NullList
+#endif
+template<>
+struct SizeOf< NullList >
+{
+	enum { value = 0 };
+};
+
+/**
+ * @class TypeOf
+ * @brief Determine the type of an element in a list of info types
+ * @tparam InfoListT A list of info types
+ * @tparam Index The index of the element whose type is to be determined
+ *
+ * This class provides a wrapper over @c std::tuple_element to determine
+ * the type of the @c InfoListT type at position @c Index
+ */
+template < typename InfoListT, int Index >
+struct TypeOf
+{
+	typedef typename std::tuple_element< Index, InfoListT >::type type;
+};
+
+#ifndef DOXYGEN_SKIP
+/// Template specialization for @c NullList
+#endif
+template < int Index >
+struct TypeOf< NullList, Index >
+{
+};
+
+/**
+ * @class InfoTypeLoop
+ * @brief Loop type used to iterate over an info type list
+ * @tparam FuncT A functor type to be called for each info type
+ * @tparam InfoHolderT A type that allows transporting arbitrary info type data
+ * @tparam InfoListT A list of info types
+ * @tparam Index The index of the current recursion in the list
+ *
+ * @note The template parameter FuncT must support the follwing signature:
+ * @code
+ * template < class InfoT > func( const std::string&, const InfoT& );
+ * @endcode
+ * with @c InfoT being the same as @c InfoHolderT::ValueType.
+ *
+ * @see Log::Record::iterateInfo
+ */
+template <
+	typename FuncT,
+	typename InfoHolderT,
+	typename InfoListT,
+	int Index
+>
+struct InfoTypeLoop
+{
+	static void call( FuncT& func, const InfoHolderT& holder )
+	{
+		// recurse first
+		InfoTypeLoop< FuncT, InfoHolderT, InfoListT, Index - 1 >::call( func, holder );
+
+		typedef typename TypeOf< InfoListT, Index >::type CurrentInfo;
+		typename CurrentInfo::Type const* valuePtr = holder.template get< CurrentInfo >();
+
+		// call func upon return to keep the correct order
+		if( valuePtr )
+		{
+			func( CurrentInfo::getName(), *valuePtr, true );
+		}
+		else
+		{
+			func( CurrentInfo::getName(), 0, false );
+		}
+	}
+};
+
+#ifndef DOXYGEN_SKIP
+/**
+ * @brief Template specialization for index 0, terminates the recursion
+ */
+#endif
+template <
+	typename FuncT,
+	typename InfoHolderT,
+	typename InfoListT
+>
+struct InfoTypeLoop< FuncT, InfoHolderT, InfoListT, 0 >
+{
+	static void call( FuncT& func, const InfoHolderT& holder )
+	{
+		typedef typename TypeOf< InfoListT, 0 >::type CurrentInfo;
+		typename CurrentInfo::Type const* valuePtr = holder.template get< CurrentInfo >();
+
+		// stop recursion, call func( name, value );
+		if( valuePtr )
+		{
+			func( CurrentInfo::getName(), *valuePtr, true );
+		}
+		else
+		{
+			func( CurrentInfo::getName(), 0, false );
+		}
+	}
+};
+
+#ifndef DOXYGEN_SKIP
+/**
+ * @brief Template specialization for empty info type list
+ */
+#endif
+template <
+	typename FuncT,
+	typename InfoHolderT,
+	int Index
+>
+struct InfoTypeLoop< FuncT, InfoHolderT, NullList, Index >
+{
+	static void call( FuncT& func, const InfoHolderT& holder )
+	{
+	}
+};
+
+} } // namespace Log::Detail
+
+#endif /* LOG_DETAIL_INFOTYPELOOP_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/InheritFields.h b/odemx-lite/external/CppLog/include/CppLog/detail/InheritFields.h
new file mode 100644
index 0000000000000000000000000000000000000000..285325baf30444effb8454be41784bcd90696c89
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/InheritFields.h
@@ -0,0 +1,67 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file InheritFields.h
+ * @author Ronald Kluth
+ * @date created at 2009/12/17
+ * @brief Declaration and implementation of class template InheritFields
+ * @since 0.1
+ */
+
+#ifndef LOG_DETAIL_INHERITFIELDS
+#define LOG_DETAIL_INHERITFIELDS
+
+namespace Log {
+namespace Detail {
+
+/**
+ * @brief Helper class template to inherit from a maximum of 10 ChannelField specializations
+ */
+template <
+	typename T0,
+	typename T1,
+	typename T2,
+	typename T3,
+	typename T4,
+	typename T5,
+	typename T6,
+	typename T7,
+	typename T8,
+	typename T9
+	>
+struct InheritFields
+:	public T0
+,	public T1
+,	public T2
+,	public T3
+,	public T4
+,	public T5
+,	public T6
+,	public T7
+,	public T8
+,	public T9
+{
+	InheritFields(){}
+	template< typename ManagerT >
+	InheritFields( ManagerT& manager )
+	:	T0( manager )
+	,	T1( manager )
+	,	T2( manager )
+	,	T3( manager )
+	,	T4( manager )
+	,	T5( manager )
+	,	T6( manager )
+	,	T7( manager )
+	,	T8( manager )
+	,	T9( manager )
+	{}
+};
+
+} } // namespace Log::Detail
+
+#endif /* LOG_DETAIL_INHERITFIELDS */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/SetInserter.h b/odemx-lite/external/CppLog/include/CppLog/detail/SetInserter.h
new file mode 100644
index 0000000000000000000000000000000000000000..e4a3f9ca7c9895ace7180b2f9230395675182228
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/SetInserter.h
@@ -0,0 +1,71 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file SetInserter.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/29
+ * @brief Declaration and implementation of class template SetInserter
+ * @since 0.1
+ */
+
+#ifndef LOG_DETAIL_SETINSERTER_INCLUDED
+#define LOG_DETAIL_SETINSERTER_INCLUDED
+
+#include <set>
+
+namespace Log {
+namespace Detail {
+
+// forward declaration
+template < typename SetInserterT >
+const SetInserterT&
+operator<<( const SetInserterT& ins, const typename SetInserterT::ValueType& value );
+
+/**
+ * @brief Helper class to enable @c std::set value insertion with @c operator<<
+ */
+template< typename ValueT >
+struct SetInserter
+{
+	/// Type of the values the inserter can add to a set
+	typedef ValueT ValueType;
+	/// Set type to be modified by the inserter object
+	typedef std::set< ValueType > SetType;
+
+	/// Reference to the set which is to be modified
+	SetType& set_;
+
+	/// Construction with non-const reference to a set
+	SetInserter( SetType& set ): set_( set ) {}
+
+	/// Add a value to the referenced @c set_
+	const SetInserter& add( const ValueType& value ) const
+	{
+		set_.insert( value );
+		return *this;
+	}
+
+	template < typename SetInserterT >
+	friend
+	const SetInserterT&
+	operator<<( const SetInserterT& ins, const typename SetInserterT::ValueType& value );
+};
+
+/// Insertion operator to add values to a set in a stream-like manner
+template < typename SetInserterT >
+inline
+const SetInserterT&
+operator<<( const SetInserterT& ins, const typename SetInserterT::ValueType& value )
+{
+	ins.add( value );
+	return ins;
+}
+
+} } // namespace Log::Detail
+
+#endif /* LOG_DETAIL_SETINSERTER_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/SqlInserter.h b/odemx-lite/external/CppLog/include/CppLog/detail/SqlInserter.h
new file mode 100644
index 0000000000000000000000000000000000000000..11366605c3a4c7628adc5733c415e42e6a8bd4b3
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/SqlInserter.h
@@ -0,0 +1,403 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file SqlInserter.h
+ * @author Ronald Kluth
+ * @date created at 2009/07/30
+ * @brief Declaration and implementation of class SqlInserter
+ * @since 0.1
+ */
+
+#ifndef LOG_DETAIL_SQLINSERTER_INCLUDED
+#define LOG_DETAIL_SQLINSERTER_INCLUDED
+
+#include "string_literal.hpp"
+#include "Bindings.h"
+
+#include <Poco/Data/Statement.h>
+#include <Poco/Data/StatementImpl.h>
+#include <Poco/Data/AbstractBinding.h>
+
+namespace Log {
+namespace Detail {
+
+/**
+ * @brief Helper class to build SQL INSERT INTO TABLE statements
+ */
+class SqlInserter
+{
+private:
+	/// String literal type to wrap C character arrays
+	typedef boost::log::string_literal StringLiteral;
+
+/// FIXME Hacking around Poco fixupBinding and bindings being protected.
+        class LogStatementImpl : public Poco::Data::StatementImpl {
+                public:
+                void fixupBinding () {
+                        Poco::Data::StatementImpl::fixupBinding ();
+                }
+
+		Poco::Data::AbstractBindingVec& bindings() {
+			return Poco::Data::StatementImpl::bindings();
+		}
+        };
+
+	class LogStatement: public Poco::Data::Statement {
+		public:
+			LogStatement(Poco::Data::Session& session) : Poco::Data::Statement(session) 
+			{}
+
+			void fixupBinding () {
+				LogStatementImpl& lsi = (LogStatementImpl&) *impl();
+				lsi.fixupBinding();
+			}
+
+			Poco::Data::AbstractBindingVec& bindings () {
+				LogStatementImpl& lsi = (LogStatementImpl&) *impl();
+				return  lsi.bindings();
+			}
+	};
+	
+public:
+	/// Construction without table name, to be used with DatabaseAccessor::createInserter
+	SqlInserter( Poco::Data::Session& session, bool autoExec = false )
+	:	session_( &session )
+	,	stmt_( session )
+	,	executed_( false )
+	,	autoExec_( autoExec )
+	{}
+
+	/// Construction with table name, used for temporary inserter objects
+	SqlInserter( std::string const& tableName, Poco::Data::Session& session, bool autoExec = false )
+	:	session_( &session )
+	,	stmt_( session )
+	,	tableName_( tableName )
+	,	executed_( false )
+	,	autoExec_( autoExec )
+	{}
+
+	/// Destruction, executes the statement if necessary
+	~SqlInserter()
+	{
+		if( ! executed_ && autoExec_ )
+		{
+			execute();
+		}
+	}
+
+	/// Set the table of an inserter object
+	SqlInserter& table( std::string const& tableName )
+	{
+		executed_ = false;
+		tableName_ = tableName;
+		return *this;
+	}
+
+	/// Add a column and a placeholder to the SQL statement
+	SqlInserter& column( std::string const& columnName )
+	{
+		executed_ = false;
+		// add a comma if not the first value
+		if( ! columnNames_.empty() )
+		{
+			columnNames_.append( 1, ',' );
+			placeholders_.append( 1, ',' );
+		}
+		// store the column name and a placeholder
+		columnNames_.append( columnName );
+		placeholders_.append( 1, '?' );
+		return *this;
+	}
+
+	/// Add multiple columns and placeholders, according to the info type list
+	template < typename InfoListT >
+	SqlInserter& columns()
+	{
+		executed_ = false;
+		if( SizeOf< InfoListT >::value > 0 )
+		{
+			ColumnLoop<
+				InfoListT,
+				SizeOf< InfoListT >::value - 1
+			>::call( columnNames_, placeholders_ );
+		}
+		return *this;
+	}
+
+	/// Bind a value that corresponds to a placeholder in the SQL statement
+	template < typename ValueT >
+	SqlInserter& value( ValueT const& val )
+	{
+		executed_ = false;
+		columnBindings_.push_back( Poco::Data::Keywords::useRef( val ) );
+		return *this;
+	}
+
+	/// Bind multiple values from a Record object that correspond to placeholders
+	template < typename InfoListT, typename RecordT >
+	SqlInserter& values( RecordT const& record )
+	{
+		executed_ = false;
+		ValueAdder addBindings( columnBindings_ );
+		record.template iterateInfo< InfoListT >( addBindings );
+		return *this;
+	}
+
+	/// Add a column and a placeholder and bind the given value to it
+	template < typename ValueT >
+	SqlInserter& columnValue( std::string const& columnName, ValueT const& val )
+	{
+		executed_ = false;
+		// add a comma if not the first value
+		if( ! columnNames_.empty() )
+		{
+			columnNames_.append( 1, ',' );
+			placeholders_.append( 1, ',' );
+		}
+		// store the column name and a placeholder
+		columnNames_.append( columnName );
+		placeholders_.append( 1, '?' );
+		// store the data
+		columnBindings_.push_back( Poco::Data::Keywords::useRef( val ) );
+		return *this;
+	}
+
+	/// Add multiple columns and placeholders and bind the Record's stored values to them
+	template < typename InfoListT, typename RecordT >
+	SqlInserter& columnValues( RecordT const& record )
+	{
+		executed_ = false;
+		NameValueAdder addColumns( columnNames_, placeholders_, columnBindings_ );
+		record.template iterateInfo< InfoListT >( addColumns );
+		return *this;
+	}
+
+	/// Execute the constructed SQL statement
+	void execute()
+	{
+		// create the SQL command if it has not been constructed yet
+		if( sql_.empty() )
+		{
+			makeSql();
+			stmt_ << sql_;
+			stmt_.addBinding( columnBindings_, false );
+		}
+		else
+		{
+			stmt_.addBinding( columnBindings_, false );
+			stmt_.fixupBinding();
+		}
+		// execute the statement and reset bindings
+		stmt_.execute();
+		if( ! stmt_.done() )
+		{
+			throw std::runtime_error( "SqlInserter::execute(): "
+					"statement not done after calling execute" );
+		}
+		executed_ = true;
+		resetBindings();
+	}
+
+	std::string getSql()
+	{
+		if( sql_.empty() )
+		{
+			makeSql();
+		}
+		std::string sqlcopy = sql_;
+		sql_.clear();
+		return sqlcopy;
+	}
+
+	std::size_t getBindingCount() const
+	{
+		return columnBindings_.size();
+	}
+
+	bool isExecuted() const
+	{
+		return executed_;
+	}
+
+private:
+	/// Vector type to hold info value bindings
+	typedef Poco::Data::AbstractBindingVec BindingVec;
+
+	/// Reference to the database session
+	Poco::Data::Session* session_;
+	/// Reusable statement object, reset after every execution
+	LogStatement stmt_;
+	/// Stores the SQL insert command for fast inserter reuse
+	std::string sql_;
+	/// Stores the table name where data is inserted
+	std::string tableName_;
+	/// Stores the column names for which data is provided
+	std::string columnNames_;
+	/// Stores the same amount of place holders as column names
+	std::string placeholders_;
+	/// Stores value bindings to column data to be inserted
+	BindingVec columnBindings_;
+	/// Stores whether the statement has been executed with the current bindings
+	bool executed_;
+	/// Stores whether the statement shall be executed automatically during destruction
+	bool autoExec_;
+
+private:
+
+	/// Create an SQL string from the accumulated column data (names, placeholders)
+	void makeSql()
+	{
+		sql_.append( "INSERT INTO " );
+		sql_.append( tableName_ );
+		sql_.append( "(" );
+		sql_.append( columnNames_ );
+		sql_.append( ") VALUES(" );
+		sql_.append( placeholders_ );
+		sql_.append( ")" );
+	}
+
+	/// Clear the binding vector (after executing the SQL insert)
+	void resetBindings()
+	{
+		columnBindings_.clear();
+		stmt_.bindings().clear();
+	}
+
+private:
+	/// Loop type to iterate over an info list, adding column definitions to a string
+	template < typename InfoListT, int Index >
+	struct ColumnLoop
+	{
+		static void call( std::string& columnNames, std::string& placeholders )
+		{
+			// recurse first
+			ColumnLoop< InfoListT, Index - 1 >::call( columnNames, placeholders );
+
+			// add column data
+			typedef typename TypeOf< InfoListT, Index >::type CurrentType;
+			columnNames.append( 1, ',' );
+			columnNames.append( CurrentType::getName().c_str() );
+			placeholders.append( ",?" );
+		}
+	};
+
+#ifndef DOXYGEN_SKIP
+	/// Partial specialization of ColumnLoop, stops the info list recursion
+#endif
+	template < typename InfoListT >
+	struct ColumnLoop< InfoListT, 0 >
+	{
+		static void call( std::string& columnNames, std::string& placeholders )
+		{
+			// end recursion, add first column data
+			typedef typename TypeOf< InfoListT, 0 >::type CurrentType;
+			if( ! columnNames.empty() )
+			{
+				columnNames.append( 1, ',' );
+				placeholders.append( 1, ',' );
+			}
+			columnNames.append( CurrentType::getName().c_str() );
+			placeholders.append( 1, '?' );
+		}
+	};
+
+	/// Functor for adding record info value bindings
+	struct ValueAdder
+	{
+		BindingVec& bindings_;
+
+		ValueAdder( BindingVec& bindings )
+		:	bindings_( bindings )
+		{}
+
+		// overload for StringLiteral value
+		void operator()( StringLiteral const& name, StringLiteral const& val, bool found )
+		{
+			if( found )
+			{
+				// must use string wrapper here because ODBC bind is not implemented for const char*
+				bindings_.push_back( Poco::Data::Keywords::bind( std::string( val.c_str() ) ) );
+			}
+			else
+			{
+				bindings_.push_back( Poco::Data::Keywords::useRef( Poco::Data::Keywords::null ) );
+			}
+		}
+
+		template < typename InfoValueT >
+		void operator()( StringLiteral const& name, InfoValueT const& val, bool found )
+		{
+			if( found )
+			{
+				bindings_.push_back( Poco::Data::Keywords::useRef( val ) );
+			}
+			else
+			{
+				bindings_.push_back( Poco::Data::Keywords::useRef( Poco::Data::Keywords::null ) );
+			}
+		}
+	};
+
+	/// Functor for adding record info names, placeholders, and values
+	struct NameValueAdder
+	{
+		std::string& names_;
+		std::string& placeholders_;
+		BindingVec& bindings_;
+
+		NameValueAdder( std::string& names, std::string& placeholders, BindingVec& bindings )
+		:	names_( names )
+		,	placeholders_( placeholders )
+		,	bindings_( bindings )
+		{}
+
+		// overload for StringLiteral value
+		void operator()( StringLiteral const& name, StringLiteral const& val, bool found )
+		{
+			if( ! names_.empty() )
+			{
+				names_.append( 1, ',' );
+				placeholders_.append( 1, ',' );
+			}
+			names_.append( name.c_str() );
+			placeholders_.append( 1, '?' );
+			if( found )
+			{
+				bindings_.push_back( Poco::Data::Keywords::bind( std::string( val.c_str() ) ) );
+			}
+			else
+			{
+				bindings_.push_back( Poco::Data::Keywords::useRef( Poco::Data::Keywords::null ) );
+			}
+		}
+
+		template < typename InfoValueT >
+		void operator()( StringLiteral const& name, InfoValueT const& val, bool found )
+		{
+			if( ! names_.empty() )
+			{
+				names_.append( 1, ',' );
+				placeholders_.append( 1, ',' );
+			}
+			names_.append( name.c_str() );
+			placeholders_.append( 1, '?' );
+			if( found )
+			{
+				bindings_.push_back( Poco::Data::Keywords::useRef( val ) );
+			}
+			else
+			{
+				bindings_.push_back( Poco::Data::Keywords::useRef( Poco::Data::Keywords::null ) );
+			}
+		}
+	};
+};
+
+} } // namespace Log::Detail
+
+#endif /* LOG_DETAIL_SQLINSERTER_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/SqlTableCreator.h b/odemx-lite/external/CppLog/include/CppLog/detail/SqlTableCreator.h
new file mode 100644
index 0000000000000000000000000000000000000000..817890913e7c01021c2a5257cb1d70207a497ce8
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/SqlTableCreator.h
@@ -0,0 +1,208 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file SqlTableCreator.h
+ * @author Ronald Kluth
+ * @date created at 2009/07/30
+ * @brief Declaration and implementation of class SqlTableCreator
+ * @since 0.1
+ */
+
+#ifndef LOG_DETAIL_SQLTABLECREATOR_INCLUDED
+#define LOG_DETAIL_SQLTABLECREATOR_INCLUDED
+
+#include <Poco/Data/Session.h>
+#include <Poco/Data/Statement.h>
+
+#include <string>
+#ifdef _MSC_VER
+#include <array>
+#else
+#include <array>
+#endif
+
+#include <vector>
+
+namespace Log {
+namespace Detail {
+
+/**
+ * @brief Helper class to build SQL CREATE TABLE statements
+ */
+class SqlTableCreator
+{
+public:
+	/// Construction
+	SqlTableCreator( std::string const& tableName, Poco::Data::Session& session )
+	:	session_( session )
+	,	tableName_( tableName )
+	,	executed_( false )
+	{}
+
+	/// Destruction, executes the statement if necessary
+	~SqlTableCreator()
+	{
+		if( ! executed_ )
+		{
+			execute();
+		}
+	}
+
+	/// Add a table column to the statement with its corresponding SQL data type
+	SqlTableCreator& column( std::string const& columnName, std::string const& sqlDataType )
+	{
+		if( ! isValidColumnName( columnName ) )
+		{
+			// prevent automatic execution in destructor and throw error
+			executed_ = true;
+			throw std::runtime_error( std::string( "SqlTableCreator::column():"
+					"invalid column name: " ) + columnName );
+		}
+
+		if( ! columnDefs_.empty() )
+		{
+			columnDefs_.append( 1, ',' );
+		}
+		columnDefs_.append( columnName + " " + sqlDataType );
+		return *this;
+	}
+
+	/// Add table columns according to the given info type list and corresponding SQL types
+	template < typename InfoListT >
+	SqlTableCreator& columns(
+			std::array< std::string, SizeOf< InfoListT >::value > const& sqlDataTypes )
+	{
+		if( SizeOf< InfoListT >::value > 0 )
+		{
+			try
+			{
+				ColumnLoop<
+					InfoListT,
+					SizeOf< InfoListT >::value - 1
+				>::call( columnDefs_, sqlDataTypes );
+			}
+			catch( std::runtime_error const& )
+			{
+				executed_ = true;
+				throw;
+			}
+		}
+		return *this;
+	}
+
+	/// Add a table contraint specifying the primary key
+	SqlTableCreator& primaryKey( std::string const& columnName )
+	{
+		tableConstraints_.append( ",PRIMARY KEY(" );
+		tableConstraints_.append( columnName );
+		tableConstraints_.append( ")" );
+		return *this;
+	}
+
+	/// Execute the consructed statement, which creates the table in the database
+	void execute()
+	{
+		if( ! executed_ )
+		{
+			// create the statement and add text
+			session_.begin();
+
+			Poco::Data::Statement stmt( session_ );
+			stmt << "CREATE TABLE " << tableName_ << " ("
+				<< columnDefs_
+				<< tableConstraints_
+				<< ")";
+
+			stmt.execute();
+
+			session_.commit();
+			executed_ = true;
+		}
+	}
+
+private:
+	/// Reference to the database session
+	Poco::Data::Session& session_;
+	/// Stores the table name where data is inserted
+	std::string tableName_;
+	/// Stores the column names and sql data types
+	std::string columnDefs_;
+	/// Stores the table constraints
+	std::string tableConstraints_;
+	/// Stores whether the statement has been executed yet
+	bool executed_;
+
+private:
+
+	/// Check if a column name contains spaces, which would create invalid SQL
+	static bool isValidColumnName( std::string const& columnName )
+	{
+		std::size_t found = columnName.find_first_of( " " );
+		return found == std::string::npos;
+	}
+
+	/// Loop type to iterate over an info list, adding column definitions to a string
+	template < typename InfoListT, int Index >
+	struct ColumnLoop
+	{
+		static void call( std::string& columnDefs,
+				std::array< std::string, SizeOf< InfoListT >::value > const& sqlDataTypes )
+		{
+			// recurse first
+			ColumnLoop< InfoListT, Index - 1 >::call( columnDefs, sqlDataTypes );
+
+			// check and add column data
+			typedef typename TypeOf< InfoListT, Index >::type CurrentType;
+			std::string columnName = CurrentType::getName().c_str();
+			if( ! isValidColumnName( columnName ) )
+			{
+				// prevent automatic execution in destructor and throw error
+				throw std::runtime_error( std::string( "SqlTableCreator::ColumnLoop::call():"
+						"invalid column name: " ) + columnName );
+			}
+			columnDefs.append( "," );
+			columnDefs.append( columnName );
+			columnDefs.append( " " );
+			columnDefs.append( sqlDataTypes[ Index ] );
+		}
+	};
+
+#ifndef DOXYGEN_SKIP
+	/// Partial specialization of ColumnLoop, stops the info list recursion
+#endif
+	template < typename InfoListT >
+	struct ColumnLoop< InfoListT, 0 >
+	{
+		static void call( std::string& columnDefs,
+				std::array< std::string, SizeOf< InfoListT >::value > const& sqlDataTypes )
+		{
+			// end recursion, add first column data
+			// check and add column data
+			typedef typename TypeOf< InfoListT, 0 >::type CurrentType;
+			std::string columnName = CurrentType::getName().c_str();
+			if( ! isValidColumnName( columnName ) )
+			{
+				// prevent automatic execution in destructor and throw error
+				throw std::runtime_error( std::string( "SqlTableCreator::ColumnLoop::call():"
+						"invalid column name: " ) + columnName );
+			}
+
+			if( ! columnDefs.empty() )
+			{
+				columnDefs.append( "," );
+			}
+			columnDefs.append( columnName );
+			columnDefs.append( " " );
+			columnDefs.append( sqlDataTypes[ 0 ] );
+		}
+	};
+};
+
+} } // namespace Log::Detail
+
+#endif /* LOG_DETAIL_SQLTABLECREATOR_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/Strip.h b/odemx-lite/external/CppLog/include/CppLog/detail/Strip.h
new file mode 100644
index 0000000000000000000000000000000000000000..58bcd90cfddc514d01f29e5e581aaa3605d99426
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/Strip.h
@@ -0,0 +1,63 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file Strip.h
+ * @author Ronald Kluth
+ * @date created at 2009/09/06
+ * @brief Declaration and implementation of class template Strip
+ * @since 0.1
+ */
+
+#ifndef LOG_DETAIL_STRIP_INCLUDED
+#define LOG_DETAIL_STRIP_INCLUDED
+
+namespace Log {
+namespace Detail {
+
+/**
+ * @brief Strips pointer or reference types to enable use of the real type
+ *
+ * This is a helper class for templates that need to acquire the basic type
+ * of a parameter type, even if a pointer or reference was given. Used to
+ * implement a specialization of InfoType so it can hold pointer types.
+ *
+ * @see InfoType
+ */
+template < typename T >
+struct Strip
+{
+	typedef T Type;
+	typedef T* Ptr;
+	typedef T& Ref;
+};
+
+#ifndef DOXYGEN_SKIP
+/// Specialization for pointer types
+#endif
+template < typename T >
+struct Strip< T* >
+{
+	typedef T Type;
+	typedef T* Ptr;
+	typedef T& Ref;
+};
+
+#ifndef DOXYGEN_SKIP
+/// Specialization for reference types
+#endif
+template < typename T >
+struct Strip< T& >
+{
+	typedef T Type;
+	typedef T* Ptr;
+	typedef T& Ref;
+};
+
+} } // namespace Log::Detail
+
+#endif /* LOG_DETAIL_STRIP_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/TypeInfo.h b/odemx-lite/external/CppLog/include/CppLog/detail/TypeInfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..6be631ed1dafef959b0b11d207f78424836d2744
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/TypeInfo.h
@@ -0,0 +1,173 @@
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2001 by Andrei Alexandrescu
+// This code accompanies the book:
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+//     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
+// Permission to use, copy, modify, distribute and sell this software for any
+//     purpose is hereby granted without fee, provided that the above copyright
+//     notice appear in all copies and that both that copyright notice and this
+//     permission notice appear in supporting documentation.
+// The author or Addison-Wesley Longman make no representations about the
+//     suitability of this software for any purpose. It is provided "as is"
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @file detail/TypeInfo.h
+ * @brief Adapted Loki::TypeInfo from Andrei Alexandrescu's Modern C++ Design
+ * @since 0.1
+ */
+
+#ifndef LOG_DETAIL_TYPEINFO_INCLUDED
+#define LOG_DETAIL_TYPEINFO_INCLUDED
+
+#include "TypeToString.h"
+
+#include <cassert>
+#include <string>
+#include <typeinfo>
+#ifdef _MSC_VER
+#include <functional>
+#else
+#include <functional>
+#endif
+
+namespace Log {
+namespace Detail {
+
+/**
+ * @brief This class offers a first-class, comparable wrapper over std::type_info
+ *
+ * Sometimes it is useful to be able to store type infomation objects in standard
+ * containers, which is not possible with @c std::type_info. The logging library
+ * uses it as key type in an std::map to look up info type values transported in
+ * record objects.
+ *
+ * @note This is a modified version of Andrei Alexandrescu's Loki::TypeInfo.
+ */
+class TypeInfo
+{
+public:
+	/// Required for default construction and initialization check
+	class Null {};
+
+	/// Default-Construction (needed for containers)
+	TypeInfo();
+	/// Construction (also conversion operator)
+	TypeInfo( const std::type_info& );
+
+	/// Access for the wrapped std::type_info
+	const std::type_info& get() const;
+	/// Check if the type info is not TypeInfo::Null
+	bool isSet() const;
+	/// Get a (demangled) string representation of the type name
+	const std::string toString() const;
+
+	/// Compatibility function
+	bool before( const TypeInfo& rhs ) const;
+	/// Compatibility function
+	const char* name() const;
+
+private:
+	/// Pointer to the actual std::type_info object
+	const std::type_info* pInfo_;
+};
+
+//------------------------------------------------------construction/destruction
+
+inline TypeInfo::TypeInfo()
+{
+	pInfo_ = &typeid( TypeInfo::Null );
+	assert( pInfo_ );
+}
+
+inline TypeInfo::TypeInfo( const std::type_info& type )
+:	pInfo_( &type )
+{
+	assert( pInfo_ );
+}
+
+//----------------------------------------------------------comparison operators
+
+inline bool operator==( const TypeInfo& lhs, const TypeInfo& rhs )
+{
+	return ( lhs.get() == rhs.get() ) != 0;
+}
+
+inline bool operator<( const TypeInfo& lhs, const TypeInfo& rhs )
+{
+	return lhs.before( rhs );
+}
+
+inline bool operator!=( const TypeInfo& lhs, const TypeInfo& rhs )
+{
+	return ! ( lhs == rhs );
+}
+
+inline bool operator>( const TypeInfo& lhs, const TypeInfo& rhs )
+{
+	return rhs < lhs;
+}
+
+inline bool operator<=( const TypeInfo& lhs, const TypeInfo& rhs )
+{
+	return ! ( lhs > rhs );
+}
+
+inline bool operator>=( const TypeInfo& lhs, const TypeInfo& rhs )
+{
+	return ! ( lhs < rhs );
+}
+
+//----------------------------------------------------------------access methods
+
+inline bool TypeInfo::isSet() const
+{
+	return ( *this != typeid(TypeInfo::Null) );
+}
+
+inline const std::type_info& TypeInfo::get() const
+{
+	assert( pInfo_ );
+	return *pInfo_;
+}
+
+inline const std::string TypeInfo::toString() const
+{
+	assert( pInfo_ );
+	return typeToString( *pInfo_ );
+}
+
+//---------------------------------------------------------compatibility methods
+
+inline bool TypeInfo::before( const TypeInfo& rhs ) const
+{
+	assert( pInfo_ );
+	// type_info::before return type is int in some VC libraries
+	return pInfo_->before( *rhs.pInfo_ ) != 0;
+}
+
+inline const char* TypeInfo::name() const
+{
+	assert( pInfo_ );
+	return pInfo_->name();
+}
+
+} } // namespace Log::Detail
+
+namespace std {
+
+template <>
+struct hash< Log::Detail::TypeInfo >
+{
+	std::size_t operator ()( const Log::Detail::TypeInfo& val ) const
+    { // return hash value for val
+		hash< const std::type_info* > make_hash;
+		return make_hash( &val.get() );
+    }
+};
+
+} // namespace std
+
+#endif /* LOG_DETAIL_TYPEINFO_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/TypeToString.h b/odemx-lite/external/CppLog/include/CppLog/detail/TypeToString.h
new file mode 100644
index 0000000000000000000000000000000000000000..8640e770007394d4bc3213bace1acb152e7683f0
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/TypeToString.h
@@ -0,0 +1,91 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file detail/TypeToString.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/29
+ * @brief Declaration and implementation of the free function typeToString()
+ * @since 0.1
+ */
+
+#ifndef LOG_DETAIL_TYPETOSTRING_INCLUDED
+#define LOG_DETAIL_TYPETOSTRING_INCLUDED
+
+// typeid().name() returns a mangled type name on GCC,
+// needs to be treated differently than other compilers,
+// the following includes the demangling library header
+
+#if defined(__GNUC__) /* GNU Compiler */
+
+	#include <cxxabi.h>
+
+#endif
+
+#include <cstdlib>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+#include <typeinfo>
+
+namespace Log {
+namespace Detail {
+
+/**
+ * @brief Get a string representation of the type name
+ * @param type reference to a type_info object returned by typeid()
+ * @return the type name as string
+ *
+ * The method @c std::type_info::name returns a mangled type name on GCC
+ * and thus needs to be treated differently than on other compilers.
+ * This function applies demangling to retrieve a human-readable
+ * string representation of type names.
+ */
+inline std::string typeToString( const std::type_info& type )
+{
+#if defined(__GNUC__) /* GNU Compiler */
+
+	int demangleStatus = -1;
+
+	char* cString = abi::__cxa_demangle( type.name(), 0, 0, &demangleStatus );
+
+//	demangleStatus is set to one of the following values:
+//	 0: The demangling operation succeeded.
+//	-1: A memory allocation failure occurred.
+//	-2: mangled_name is not a valid name under the C++ ABI mangling rules.
+//	-3: One of the arguments is invalid.
+
+	if( demangleStatus != 0 )
+	{
+		std::ostringstream stream;
+		stream << "typeToString() failed,"
+				<< " error code: " << demangleStatus
+				<< " while trying to convert '" << type.name() << "'"
+				<< std::endl;
+
+		throw std::runtime_error( stream.str() );
+	}
+
+	std::string typeString;
+	if( cString != NULL )
+	{
+		typeString = cString;
+		std::free( cString );
+	}
+
+#else // other compilers should give a demangled name
+
+	std::string typeString( type.name() );
+
+#endif
+
+	return typeString;
+}
+
+} } // namespace Log::Detail
+
+#endif /* LOG_DETAIL_TYPETOSTRING_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/detail/string_literal.hpp b/odemx-lite/external/CppLog/include/CppLog/detail/string_literal.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7c9ab3e74b5379dcb785b77375fd5c0e167f870a
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/detail/string_literal.hpp
@@ -0,0 +1,523 @@
+/*
+ * (C) 2007 Andrey Semashev
+ *
+ * Use, modification and distribution is subject to the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/libs/log/doc/log.html.
+ */
+/*!
+ * \file   string_literal.hpp
+ * \author Andrey Semashev
+ * \date   24.06.2007
+ *
+ * The header contains implementation of a constant string literal wrapper.
+ */
+
+#if defined(_MSC_VER) && _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#ifndef BOOST_LOG_UTILITY_STRING_LITERAL_HPP_INCLUDED_
+#define BOOST_LOG_UTILITY_STRING_LITERAL_HPP_INCLUDED_
+
+#include <stdexcept>
+#include <iosfwd>
+#include <string>
+#include <iterator>
+#include <algorithm>
+#include <functional>
+#include <ios>
+//#include <boost/operators.hpp>
+//#include <boost/throw_exception.hpp>
+//#include <boost/compatibility/cpp_c_headers/cstddef>
+//#include <boost/type_traits/is_same.hpp>
+//#include <boost/utility/enable_if.hpp>
+//#include <boost/log/detail/prologue.hpp>
+
+namespace boost {
+
+namespace log {
+
+/*!
+ * \brief String literal wrapper
+ *
+ * The \c basic_string_literal is a thin wrapper around a constant string literal.
+ * It provides interface similar to STL strings, but because of read-only nature
+ * of string literals, lacks ability to modify string contents. However,
+ * \c basic_string_literal objects can be assigned to and cleared.
+ *
+ * The main advantage of this class comparing to other string classes is that
+ * it doesn't dynamically allocate memory and therefore is fast, thin and exception safe.
+ */
+template< typename CharT, typename TraitsT = std::char_traits< CharT > >
+class basic_string_literal
+{
+    //! Self type
+    typedef basic_string_literal< CharT, TraitsT > this_type;
+
+public:
+    typedef CharT value_type;
+    typedef TraitsT traits_type;
+
+    typedef std::size_t size_type;
+    typedef std::ptrdiff_t difference_type;
+    typedef const value_type* const_pointer;
+    typedef value_type const& const_reference;
+    typedef const value_type* const_iterator;
+    typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
+
+    //! Corresponding STL string type
+    typedef std::basic_string< value_type, traits_type > string_type;
+
+private:
+    //! Pointer to the beginning of the literal
+    const_pointer m_pStart;
+    //! Length
+    size_type m_Len;
+
+    //! Empty string literal to support clear
+    static const value_type g_EmptyString[1];
+
+public:
+    /*!
+     * Constructor
+     *
+     * \post <tt>empty() == true</tt>
+     */
+    basic_string_literal() { clear(); }
+
+    /*!
+     * Constructor from a string literal
+     *
+     * \post <tt>*this == p</tt>
+     * \param p A zero-terminated constant sequence of characters
+     */
+    template< typename T, size_type LenV >
+    basic_string_literal( T(&p)[LenV] )
+        : m_pStart(p), m_Len(LenV - 1)
+    {
+    }
+
+    /*!
+     * Copy constructor
+     *
+     * \post <tt>*this == that</tt>
+     * \param that Source literal to copy string from
+     */
+    basic_string_literal(basic_string_literal const& that)
+    : m_pStart(that.m_pStart), m_Len(that.m_Len)
+    {
+    }
+
+    /*!
+     * Assignment operator
+     *
+     * \post <tt>*this == that</tt>
+     * \param that Source literal to copy string from
+     */
+    this_type& operator= (this_type const& that)
+    {
+        return assign(that);
+    }
+    /*!
+     * Assignment from a string literal
+     *
+     * \post <tt>*this == p</tt>
+     * \param p A zero-terminated constant sequence of characters
+     */
+    template< typename T, size_type LenV >
+    this_type&
+    operator= ( T(&p)[LenV] )
+    {
+        return assign(p);
+    }
+
+    /*!
+     * Lexicographical comparison (equality)
+     *
+     * \param that Comparand
+     * \return \c true if the comparand string equals to this string, \c false otherwise
+     */
+    bool operator== (this_type const& that) const
+    {
+        return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) == 0);
+    }
+    /*!
+     * Lexicographical comparison (equality)
+     *
+     * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
+     * \return \c true if the comparand string equals to this string, \c false otherwise
+     */
+    bool operator== (const_pointer str) const
+    {
+        return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) == 0);
+    }
+    /*!
+     * Lexicographical comparison (equality)
+     *
+     * \param that Comparand
+     * \return \c true if the comparand string equals to this string, \c false otherwise
+     */
+    bool operator== (string_type const& that) const
+    {
+        return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) == 0);
+    }
+
+    /*!
+     * Lexicographical comparison (less ordering)
+     *
+     * \param that Comparand
+     * \return \c true if this string is less than the comparand, \c false otherwise
+     */
+    bool operator< (this_type const& that) const
+    {
+        return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) < 0);
+    }
+    /*!
+     * Lexicographical comparison (less ordering)
+     *
+     * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
+     * \return \c true if this string is less than the comparand, \c false otherwise
+     */
+    bool operator< (const_pointer str) const
+    {
+        return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) < 0);
+    }
+    /*!
+     * Lexicographical comparison (less ordering)
+     *
+     * \param that Comparand
+     * \return \c true if this string is less than the comparand, \c false otherwise
+     */
+    bool operator< (string_type const& that) const
+    {
+        return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) < 0);
+    }
+
+    /*!
+     * Lexicographical comparison (greater ordering)
+     *
+     * \param that Comparand
+     * \return \c true if this string is greater than the comparand, \c false otherwise
+     */
+    bool operator> (this_type const& that) const
+    {
+        return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) > 0);
+    }
+    /*!
+     * Lexicographical comparison (greater ordering)
+     *
+     * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
+     * \return \c true if this string is greater than the comparand, \c false otherwise
+     */
+    bool operator> (const_pointer str) const
+    {
+        return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) > 0);
+    }
+    /*!
+     * Lexicographical comparison (greater ordering)
+     *
+     * \param that Comparand
+     * \return \c true if this string is greater than the comparand, \c false otherwise
+     */
+    bool operator> (string_type const& that) const
+    {
+        return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) > 0);
+    }
+
+    /*!
+     * Subscript operator
+     *
+     * \pre <tt>i < size()</tt>
+     * \param i Requested character index
+     * \return Constant reference to the requested character
+     */
+    const_reference operator[] (size_type i) const
+    {
+        return m_pStart[i];
+    }
+    /*!
+     * Checked subscript
+     *
+     * \param i Requested character index
+     * \return Constant reference to the requested character
+     * \throw An <tt>std::exception</tt>-based exception if index \a i is out of string boundaries
+     */
+    const_reference at(size_type i) const
+    {
+        if (i < m_Len)
+            return m_pStart[i];
+        else
+            throw std::out_of_range("basic_string_literal::at: the index value is out of range");
+    }
+
+    /*!
+     * \return Pointer to the beginning of the literal
+     */
+    const_pointer c_str() const { return m_pStart; }
+    /*!
+     * \return Pointer to the beginning of the literal
+     */
+    const_pointer data() const { return m_pStart; }
+    /*!
+     * \return Length of the literal
+     */
+    size_type size() const { return m_Len; }
+    /*!
+     * \return Length of the literal
+     */
+    size_type length() const { return m_Len; }
+
+    /*!
+     * \return \c true if the literal is an empty string, \c false otherwise
+     */
+    bool empty() const
+    {
+        return (m_Len == 0);
+    }
+
+    /*!
+     * \return Iterator that points to the first character of the literal
+     */
+    const_iterator begin() const { return m_pStart; }
+    /*!
+     * \return Iterator that points after the last character of the literal
+     */
+    const_iterator end() const { return m_pStart + m_Len; }
+    /*!
+     * \return Reverse iterator that points to the last character of the literal
+     */
+    const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
+    /*!
+     * \return Reverse iterator that points before the first character of the literal
+     */
+    const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
+
+    /*!
+     * \return STL string constructed from the literal
+     */
+    string_type str() const
+    {
+        return string_type(m_pStart, m_Len);
+    }
+
+    /*!
+     * The method clears the literal
+     *
+     * \post <tt>empty() == true</tt>
+     */
+    void clear()
+    {
+        m_pStart = g_EmptyString;
+        m_Len = 0;
+    }
+    /*!
+     * The method swaps two literals
+     */
+    void swap(this_type& that)
+    {
+        std::swap(m_pStart, that.m_pStart);
+        std::swap(m_Len, that.m_Len);
+    }
+
+    /*!
+     * Assignment from another literal
+     *
+     * \post <tt>*this == that</tt>
+     * \param that Source literal to copy string from
+     */
+    this_type& assign(this_type const& that)
+    {
+        m_pStart = that.m_pStart;
+        m_Len = that.m_Len;
+        return *this;
+    }
+    /*!
+     * Assignment from another literal
+     *
+     * \post <tt>*this == p</tt>
+     * \param p A zero-terminated constant sequence of characters
+     */
+    template< typename T, size_type LenV >
+    this_type&
+    assign( T(&p)[LenV] )
+    {
+        m_pStart = p;
+        m_Len = LenV - 1;
+        return *this;
+    }
+
+    /*!
+     * The method copies the literal or its portion to an external buffer
+     *
+     * \pre <tt>pos < size()</tt>
+     * \param str Pointer to the external buffer beginning. Must not be NULL.
+     *            The buffer must have enough capacity to accommodate the requested number of characters.
+     * \param n Maximum number of characters to copy
+     * \param pos Starting position to start copying from
+     * \return Number of characters copied
+     * \throw An <tt>std::exception</tt>-based exception if \a pos is out of range.
+     */
+    size_type copy(value_type* str, size_type n, size_type pos = 0) const
+    {
+        if (pos <= size())
+        {
+            const size_type len = (std::min)(n, size() - pos);
+            traits_type::copy(str, m_pStart + pos, len);
+            return len;
+        }
+        else
+            throw std::out_of_range("basic_string_literal::copy: the position is out of range");
+    }
+
+    /*!
+     * Lexicographically compares the argument string to a part of this string
+     *
+     * \pre <tt>pos < size()</tt>
+     * \param pos Starting position within this string to perform comparison to
+     * \param n Length of the substring of this string to perform comparison to
+     * \param str Comparand. Must point to a sequence of characters, must not be NULL.
+     * \param len Number of characters in the sequence \a str.
+     * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
+     *         a positive value if this string is greater than the comparand.
+     * \throw An <tt>std::exception</tt>-based exception if \a pos is out of range.
+     */
+    int compare(size_type pos, size_type n, const_pointer str, size_type len) const
+    {
+        if (pos <= size())
+        {
+            const size_type compare_size = (std::min)((std::min)(n, len), size() - pos);
+            return compare_internal(m_pStart + pos, compare_size, str, compare_size);
+        }
+        else
+            throw std::out_of_range("basic_string_literal::compare: the position is out of range");
+    }
+    /*!
+     * Lexicographically compares the argument string to a part of this string
+     *
+     * \pre <tt>pos < size()</tt>
+     * \param pos Starting position within this string to perform comparison to
+     * \param n Length of the substring of this string to perform comparison to
+     * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
+     * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
+     *         a positive value if this string is greater than the comparand.
+     * \throw An <tt>std::exception</tt>-based exception if \a pos is out of range.
+     */
+    int compare(size_type pos, size_type n, const_pointer str) const
+    {
+        return compare(pos, n, str, traits_type::length(str));
+    }
+    /*!
+     * Lexicographically compares the argument string literal to a part of this string
+     *
+     * \pre <tt>pos < size()</tt>
+     * \param pos Starting position within this string to perform comparison to
+     * \param n Length of the substring of this string to perform comparison to
+     * \param that Comparand
+     * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
+     *         a positive value if this string is greater than the comparand.
+     * \throw An <tt>std::exception</tt>-based exception if \a pos is out of range.
+     */
+    int compare(size_type pos, size_type n, this_type const& that) const
+    {
+        return compare(pos, n, that.c_str(), that.size());
+    }
+    /*!
+     * Lexicographically compares the argument string to this string
+     *
+     * \param str Comparand. Must point to a sequence of characters, must not be NULL.
+     * \param len Number of characters in the sequence \a str.
+     * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
+     *         a positive value if this string is greater than the comparand.
+     */
+    int compare(const_pointer str, size_type len) const
+    {
+        return compare(0, m_Len, str, len);
+    }
+    /*!
+     * Lexicographically compares the argument string to this string
+     *
+     * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
+     * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
+     *         a positive value if this string is greater than the comparand.
+     */
+    int compare(const_pointer str) const
+    {
+        return compare(0, m_Len, str, traits_type::length(str));
+    }
+    /*!
+     * Lexicographically compares the argument string to this string
+     *
+     * \param that Comparand
+     * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
+     *         a positive value if this string is greater than the comparand.
+     */
+    int compare(this_type const& that) const
+    {
+        return compare(0, m_Len, that.c_str(), that.size());
+    }
+
+private:
+
+    //! Internal comparison implementation
+    static int compare_internal(const_pointer pLeft, size_type LeftLen, const_pointer pRight, size_type RightLen)
+    {
+        if (pLeft != pRight)
+        {
+            const int result = traits_type::compare(pLeft, pRight, (std::min)(LeftLen, RightLen));
+            if (result != 0)
+                return result;
+        }
+        return (LeftLen - RightLen);
+    }
+};
+
+template< typename CharT, typename TraitsT >
+typename basic_string_literal< CharT, TraitsT >::value_type const
+basic_string_literal< CharT, TraitsT >::g_EmptyString[1] =
+{
+    typename basic_string_literal< CharT, TraitsT >::value_type()
+};
+
+//! Output operator
+template< typename CharT, typename StrmTraitsT, typename LitTraitsT >
+inline std::basic_ostream< CharT, StrmTraitsT >& operator<< (
+    std::basic_ostream< CharT, StrmTraitsT >& strm, basic_string_literal< CharT, LitTraitsT > const& lit)
+{
+    strm.write(lit.c_str(), static_cast< std::streamsize >(lit.size()));
+    return strm;
+}
+
+//! External swap
+template< typename CharT, typename TraitsT >
+inline void swap(
+    basic_string_literal< CharT, TraitsT >& left,
+    basic_string_literal< CharT, TraitsT >& right)
+{
+    left.swap(right);
+}
+
+typedef basic_string_literal< char > string_literal;        //!< String literal type for narrow characters
+typedef basic_string_literal< wchar_t > wstring_literal;    //!< String literal type for wide characters
+
+//! Creates a string literal wrapper from a constant string literal
+template< typename T, std::size_t LenV >
+inline string_literal make_string_literal( T(&p)[LenV] )
+{
+    return string_literal(p);
+}
+
+//! Creates a string literal wrapper from a constant string literal
+template< typename T, std::size_t LenV >
+inline wstring_literal make_wstring_literal( T(&p)[LenV] )
+{
+    return wstring_literal(p);
+}
+
+} // namespace log
+
+} // namespace boost
+
+#endif // BOOST_LOG_UTILITY_STRING_LITERAL_HPP_INCLUDED_
diff --git a/odemx-lite/external/CppLog/include/CppLog/output/DatabaseAccessor.h b/odemx-lite/external/CppLog/include/CppLog/output/DatabaseAccessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e2c38e268777318fb3a651f23736f3aa6e3d4ed
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/output/DatabaseAccessor.h
@@ -0,0 +1,267 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file DatabaseAccessor.h
+ * @author Ronald Kluth
+ * @date 2009/06/17
+ * @brief Declaration and implementation of class DatabaseAccessor
+ * @since 0.1
+ */
+
+#ifndef LOG_OUTPUT_DATABASEACCESSOR_INCLUDED
+#define LOG_OUTPUT_DATABASEACCESSOR_INCLUDED
+
+#ifdef CPPLOG_USE_DATABASE
+
+#include "../../setup.h"
+#include "../Consumer.h"
+#include "../StringLiteral.h"
+#include "../detail/SqlTableCreator.h"
+#include "../detail/SqlInserter.h"
+
+#include <Poco/Data/Session.h>
+#include <Poco/Runnable.h>
+#include <Poco/Thread.h>
+#include <Poco/ThreadLocal.h>
+#include <Poco/Types.h>
+
+#if defined CPPLOG_USE_ODBC && defined CPPLOG_USE_SQLITE
+#error "CPPLOG_USE_ODBC and CPPLOG_USE_SQLITE are defined: ambiguous setup"
+#endif
+
+#if defined CPPLOG_USE_ODBC
+	#include <Poco/Data/ODBC/Connector.h>
+	#include <Poco/Data/ODBC/SessionImpl.h>
+#elif defined CPPLOG_USE_SQLITE
+	#include <Poco/Data/SQLite/Connector.h>
+#else
+#error "Neither CPPLOG_USE_ODBC nor CPPLOG_USE_SQLITE are defined: cannot register connector"
+#endif
+
+#include <algorithm> // for_each
+#include <cstddef> // size_t
+#include <memory> // auto_ptr
+#include <vector>
+
+namespace Log {
+
+/**
+ * @brief Base class that gives log consumers database access
+ *
+ * Even basic database interaction requires different SQL syntax on different
+ * database management systems. This class provides an abstraction layer for
+ * common database operations so that log consumers can use a single interface
+ * regardless of the underlying database, as long as it is supported by this
+ * class.
+ *
+ * @note This class requires the Data module of the Poco C++ libraries.
+ */
+class DatabaseAccessor
+{
+public:
+	/// Pull SqlTableCreator into this scope
+	typedef Detail::SqlTableCreator SqlTableCreator;
+	/// Pulls SqlInserter into this scope, improves usability
+	typedef Detail::SqlInserter SqlInserter;
+
+	/// Construction
+	DatabaseAccessor( const std::string& connectionString )
+	:	session_( 0 )
+	{
+#if defined CPPLOG_USE_ODBC
+		Poco::Data::ODBC::Connector::registerConnector();
+		session_.reset( new Poco::Data::Session( "ODBC", connectionString ) );
+		Poco::Data::ODBC::SessionImpl* impl = static_cast< Poco::Data::ODBC::SessionImpl* >( session_->impl() );
+		if( impl->isAutoCommit() )
+		{
+			impl->autoCommit( "", false );
+		}
+#elif defined CPPLOG_USE_SQLITE
+		Poco::Data::SQLite::Connector::registerConnector();
+		session_.reset( new Poco::Data::Session( "SQLite", connectionString ) );
+#endif
+	}
+
+	/// Destruction
+	~DatabaseAccessor()
+	{
+	}
+
+	/// Create a table by appending columns to a table builder object
+	SqlTableCreator createTable( const std::string& tableName )
+	{
+		return SqlTableCreator( tableName, *session_ );
+	}
+
+	/// Create an SQL inserter for reuse of a prepared statement
+	std::auto_ptr< SqlInserter > createInserter()
+	{
+		return std::auto_ptr< SqlInserter >( new SqlInserter( *session_, false ) );
+	}
+
+	/// Insert data into a table by appending values to an insert builder object
+	SqlInserter insertIntoTable( const std::string& tableName )
+	{
+		return SqlInserter( tableName, *session_, true );
+	}
+
+	/// Check if a table with the given name already exists
+	bool tableExists( const std::string& tableName )
+	{
+		using namespace Poco::Data;
+		using namespace Poco::Data::Keywords;
+		int count = 0;
+		Statement stmt( *session_ );
+		try
+		{
+#if defined CPPLOG_USE_ODBC
+			stmt <<	"SELECT count(table_name) FROM information_schema.tables "
+					"WHERE table_name = ?;", bind( tableName ), into( count );
+#elif defined CPPLOG_USE_SQLITE
+			stmt <<	"Select count(*) from sqlite_master where name=?;"
+					,useRef( tableName ), into( count );
+#else
+#error "DatabaseAccessor::tableExists() requires ODBC or SQLITE to be enabled"
+#endif
+			stmt.execute();
+		}
+		catch( const DataException& )
+		{
+			throw;
+		}
+		return count > 0;
+	}
+
+	/// Get maximum value of @c column in @c table and store it in @c valueHolder
+	template < typename T >
+	void getMaxColumnValue( std::string const& table, std::string const& column,
+			T& valueHolder )
+	{
+		using namespace Poco::Data;
+		using namespace Poco::Data::Keywords;
+		try
+		{
+			*session_ << "SELECT MAX(" << column << ") FROM " << table
+						,into( valueHolder ), now;
+		}
+		catch( const DataException& )
+		{
+			throw;
+		}
+	}
+
+	/// Count the number of rows in the given table
+	Poco::UInt64 getRowCount( std::string const& table )
+	{
+		using namespace Poco::Data;
+		using namespace Poco::Data::Keywords;
+		try
+		{
+			Poco::UInt64 rowCount = 0;
+			*session_ << "SELECT COUNT(*) FROM " << table
+						,into( rowCount ), now;
+			return rowCount;
+		}
+		catch( const DataException& )
+		{
+			throw;
+		}
+	}
+
+	/// Get the current time from the database
+	std::string getCurrentDatabaseTime()
+	{
+		using namespace Poco::Data;
+		using namespace Poco::Data::Keywords;
+		std::string currentTime;
+		Statement stmt( *session_ );
+		try
+		{
+#if defined CPPLOG_USE_ODBC
+			stmt << "SELECT CURRENT_TIMESTAMP;", into( currentTime );
+#elif defined CPPLOG_USE_SQLITE
+			stmt << "SELECT DATETIME('now');", into( currentTime );
+#else
+#error "DatabaseAccessor::getCurrentDatabaseTime() requires ODBC or SQLITE to be enabled"
+#endif
+			stmt.execute();
+		}
+		catch( const DataException& )
+		{
+			throw;
+		}
+		return currentTime;
+	}
+
+	/**
+	 * @brief Writes buffered records to the database
+	 * @tparam RecordBufferT Buffer type, must support forward iteration
+	 * @tparam InsertFuncT Function type to call with RecordBufferT::value_type
+	 *
+	 * @param buffer Record buffer to write the database, is cleared afterwards
+	 * @param insertFunc Function called for each record to write to the database
+	 *
+	 * This method is implmented in terms of std::for_each, meaning the buffer
+	 * must provide the methods @c begin and @c end, which return iterators to
+	 * the start and jsut past the end of the given buffer. The insert function
+	 * or functor must also provide the correct signature, which only takes
+	 * one buffered record as parameter.
+	 */
+	template < typename RecordBufferT, typename InsertFuncT >
+	void storeData( RecordBufferT& buffer, const InsertFuncT& insertFunc )
+	{
+		using namespace Poco::Data;
+		using namespace Poco::Data::Keywords;
+
+		// BEGIN TRANSACTION
+		session_->begin();
+
+		std::for_each( buffer.begin(), buffer.end(), insertFunc );
+
+		// COMMIT
+		session_->commit();
+	}
+
+#if defined CPPLOG_USE_SQLITE || defined CPPLOG_USE_POSTGRESQL
+
+	/// Get the last automatically generated serial/identity value
+	Poco::UInt64 getLastInsertId( const std::string& seqName = "" )
+	{
+		using namespace Poco::Data;
+		using namespace Poco::Data::Keywords;
+		try
+		{
+			Poco::UInt64 lastId;
+
+#if defined CPPLOG_USE_POSTGRESQL
+			*session_ << "SELECT currval('" << seqName << "')", into( lastId ), now;
+#elif defined CPPLOG_USE_SQLITE
+			*session_ << "SELECT last_insert_rowid();", into( lastId ), now;
+#else
+#error "DatabaseAccessor::getLastInsertId() requires SQLITE or POSTGRESQL to be enabled"
+#endif
+
+			return lastId;
+		}
+		catch( const DataException& )
+		{
+			throw;
+		}
+	}
+#endif
+
+private:
+	/// Pointer to the database session the log information is written to
+	std::auto_ptr< Poco::Data::Session > session_;
+};
+
+} // namespace Log
+
+#endif /* CPPLOG_USE_DATABASE */
+
+#endif /* LOG_OUTPUT_DATABASEACCESSOR_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/output/OStreamWriter.h b/odemx-lite/external/CppLog/include/CppLog/output/OStreamWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..99233787ba2954252256f55a7c25e4bdd8f6884a
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/output/OStreamWriter.h
@@ -0,0 +1,99 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file CppLog/output/OStreamWriter.h
+ * @author Ronald Kluth
+ * @date 2009/06/17
+ * @brief Declaration and implementation of class template OStreamWriter
+ * @since 0.1
+ */
+
+#ifndef LOG_OUTPUT_OSTREAMWRITER_INCLUDED
+#define LOG_OUTPUT_OSTREAMWRITER_INCLUDED
+
+#include "../Consumer.h"
+#include "../Record.h"
+
+#include <ostream>
+#include <sstream>
+#ifdef _MSC_VER
+#include <memory>
+#else
+#include <memory>
+#endif
+
+namespace Log {
+
+/**
+ * @brief Simple log consumer implementation that writes records to a stream
+ * @tparam InfoListT List of info types to retrieve from log records
+ *
+ * This class is a very simple test output component. The @c consume method
+ * simply transforms each record into a plain text line. Info type elements
+ * are added automatically, according to the type list provided as template
+ * parameter.
+ */
+template < typename InfoListT = Detail::NullList >
+class OStreamWriter : public Consumer< Record >
+{
+public:
+	/// List of info types to retrieve from log records
+	typedef InfoListT InfoListType;
+	/// Pointer type to manage instances
+	typedef std::shared_ptr< OStreamWriter< InfoListType > > Ptr;
+
+	/// Creation of OStreamWriter objects wrapped in a @c shared_ptr
+	static Ptr create( std::ostream& os )
+	{
+		return Ptr( new OStreamWriter( os ) );
+	}
+
+	/// Redefinition of the log consumer interface method
+	virtual void consume( const Log::ChannelId channelId, const Record& record )
+	{
+		if( ! record.getText().empty() )
+		{
+			os_ << record.getText();
+		}
+		MakeInfoString makeString;
+		record.iterateInfo< InfoListType >( makeString );
+
+		if( ! makeString.stream.str().empty() )
+		{
+			os_ << " [Info:" << makeString.stream.str() << "]";
+		}
+		os_ << std::endl;
+	}
+private:
+	/// Construction, private, use @c create instead
+	OStreamWriter( std::ostream& os ): os_( os ) {}
+
+private:
+	/// Reference to the stream the log information is written to
+	std::ostream& os_;
+
+private:
+	/// Functor to transform record info into strings
+	struct MakeInfoString
+	{
+		std::ostringstream stream;
+
+		template < typename InfoValueT >
+		void operator()( const Log::StringLiteral& name, const InfoValueT& value, bool found )
+		{
+			if( found )
+			{
+				stream << " " << name << "=" << value;
+			}
+		}
+	};
+};
+
+} // namespace Log
+
+#endif /* LOG_OUTPUT_OSTREAMWRITER_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/output/XmlFileWriter.h b/odemx-lite/external/CppLog/include/CppLog/output/XmlFileWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..295e4e9b521af37d140758c557c49660caf66fd7
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/output/XmlFileWriter.h
@@ -0,0 +1,165 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file XmlFileWriter.h
+ * @author Ronald Kluth
+ * @date 2010/03/26
+ * @brief Declaration and implementation of class template XmlFileWriter
+ * @since 0.1
+ */
+
+#ifndef LOG_OUTPUT_XMLFILEWRITER_INCLUDED
+#define LOG_OUTPUT_XMLFILEWRITER_INCLUDED
+
+#include "../Record.h"
+#include "XmlWriter.h"
+
+#include <cstddef> // size_t
+#include <fstream>
+#include <stdexcept> // runtime_error
+#ifdef _MSC_VER
+#include <memory>
+#else
+#include <memory>
+#endif
+
+namespace Log {
+
+/**
+ * @brief Simple log consumer implementation that writes records to an xml stream
+ * @tparam InfoListT List of info types to retrieve from log records
+ *
+ * This class is a simple XML-writing component. The @c consume method
+ * transforms each record into XML format by calling methods
+ * of the base class @c XmlWriter. Info type elements are added automatically,
+ * according to the type list provided as template parameter.
+ *
+ * As soon as the given file limit is reached, the current file is closed
+ * and a new one opened. For this purpose, the file name prefix is appended
+ * with a number.
+ *
+ * @note Be aware that string names of info types should not contain white space
+ * because these names are used  as XML tag names.
+ */
+template < typename InfoListT = Detail::NullList >
+class XmlFileWriter : public XmlWriter
+{
+public:
+	/// List of info types to retrieve from log records
+	typedef InfoListT InfoListType;
+	/// Pointer type to manage XmlFileWriter objects
+	typedef std::shared_ptr< XmlFileWriter< InfoListType > > Ptr;
+
+	/// Creation of XmlFileWriter objects wrapped in a @c shared_ptr
+	static Ptr create( const std::string& fileNamePrefix, std::size_t fileRecordLimit,
+			const std::string& root = "cpplog", unsigned int indent = 2 )
+	{
+		return Ptr( new XmlFileWriter( fileNamePrefix, fileRecordLimit, root, indent ) );
+	}
+
+	/**
+	 * @brief Destruction
+	 * 
+	 * If the last XML file is still open, the root element is closed,
+	 * as well as the file stream.
+	 */
+	virtual ~XmlFileWriter()
+	{
+		// finish the last file
+		if( fileStream_.is_open() )
+		{
+			XmlWriter::closeElement( fileStream_, 0, rootElement_ );
+			fileStream_.close();
+		}
+	}
+
+	/// Override of the log consumer interface method
+	virtual void consume( const Log::ChannelId channelId, const Record& record )
+	{
+		if( fileRecordCount_ >= fileRecordLimit_ )
+		{
+			startNewFile();
+		}
+
+		if( fileStream_.good() )
+		{
+			XmlWriter::startElement( fileStream_, indent_, "record" );
+			fileStream_ << std::endl;
+			if( ! record.getText().empty() )
+			{
+				XmlWriter::writeElement( fileStream_, indent_ + indent_, "text", record.getText() );
+			}
+			XmlWriter::StreamInfoElements addInfo( fileStream_, indent_ + indent_ );
+			record.iterateInfo< InfoListType >( addInfo );
+			XmlWriter::closeElement( fileStream_, indent_ , "record" );
+
+			++fileRecordCount_;
+		}
+	}
+private:
+	std::string fileNamePrefix_;
+	std::size_t fileRecordLimit_;
+	std::size_t fileRecordCount_;
+	std::size_t fileCount_;
+	std::ofstream fileStream_;
+	std::string rootElement_;
+	unsigned int indent_;
+
+private:
+
+	/// Construction only via create()
+	XmlFileWriter( const std::string& fileNamePrefix, unsigned int fileRecordLimit,
+			const std::string& root = "cpplog", unsigned int indent = 2 )
+	:	fileNamePrefix_( fileNamePrefix )
+	,	fileRecordLimit_( fileRecordLimit )
+	,	fileRecordCount_( 0 )
+	,	fileCount_( 0 )
+	,	fileStream_()
+	,	rootElement_( root )
+	,	indent_( indent )
+	{
+		startNewFile();
+	}
+
+	void startNewFile()
+	{
+		// close root element and previous file stream
+		if( fileStream_.is_open() )
+		{
+			XmlWriter::closeElement( fileStream_, 0, rootElement_ );
+			fileStream_.close();
+		}
+
+		// create new file name
+		std::ostringstream fileName;
+		fileName << fileNamePrefix_ << "_" << fileCount_ << ".xml";
+
+		// reset the record counter and increase the file count
+		fileRecordCount_ = 0;
+		++fileCount_;
+
+		// reset stream flags and open new file
+		fileStream_.clear();
+		fileStream_.open( fileName.str().c_str() );
+		if( ! fileStream_.good() )
+		{
+			throw std::runtime_error( std::string(
+					"XmlFileWriter::startNewFile(): failed to open file: " )
+					+ fileName.str() );
+		}
+
+		// start file with default XML header and open root element
+		XmlWriter::writeHeader( fileStream_ );
+		XmlWriter::startElement( fileStream_, 0, rootElement_ );
+		fileStream_ << std::endl;
+	}
+};
+
+} // namespace Log
+
+#endif /* LOG_OUTPUT_XMLFILEWRITER_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/output/XmlStreamWriter.h b/odemx-lite/external/CppLog/include/CppLog/output/XmlStreamWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..7c61df36d329e18a471c8ca518ffe938e900bb43
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/output/XmlStreamWriter.h
@@ -0,0 +1,94 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file XmlStreamWriter.h
+ * @author Ronald Kluth
+ * @date 2010/03/26
+ * @brief Declaration and implementation of class template XmlStreamWriter
+ * @since 0.1
+ */
+
+#ifndef LOG_OUTPUT_XMLSTREAMWRITER_INCLUDED
+#define LOG_OUTPUT_XMLSTREAMWRITER_INCLUDED
+
+#include "../Record.h"
+#include "XmlWriter.h"
+
+#ifdef _MSC_VER
+#include <memory>
+#else
+#include <memory>
+#endif
+
+namespace Log {
+
+/**
+ * @brief Simple log consumer implementation that writes records to an XML stream
+ * @tparam InfoListT List of info types to retrieve from log records
+ *
+ * This class is a very simple XML output component. The @c consume method
+ * simply transforms each record into XML format by calling methods
+ * of the base class @c XmlWriter. Info type elements are added automatically,
+ * according to the type list provided as template parameter.
+ *
+ * @note Be aware that string names of info types should not contain white space
+ * because these names are used  as XML tag names.
+ */
+template < typename InfoListT = Detail::NullList >
+class XmlStreamWriter : public XmlWriter
+{
+public:
+	/// List of info types to retrieve from log records
+	typedef InfoListT InfoListType;
+	/// Pointer type to manage instances
+	typedef std::shared_ptr< XmlStreamWriter< InfoListType > > Ptr;
+
+	/// Creation of XmlStreamWriter objects wrapped in a @c shared_ptr
+	static Ptr create( std::ostream& os, unsigned int indent = 0 )
+	{
+		return Ptr( new XmlStreamWriter( os, indent ) );
+	}
+
+	/// Destruction
+	virtual ~XmlStreamWriter()
+	{
+	}
+
+	/// Implementation of the log consumer interface, transforms records to XML
+	virtual void consume( const Log::ChannelId channelId, const Record& record )
+	{
+		if( os_.good() )
+		{
+			XmlWriter::startElement( os_, indent_, "record" );
+			os_ << std::endl;
+			if( ! record.getText().empty() )
+			{
+				XmlWriter::writeElement( os_, indent_ + indent_, "text", record.getText() );
+			}
+			XmlWriter::StreamInfoElements addInfo( os_, indent_ + indent_ );
+			record.iterateInfo< InfoListType >( addInfo );
+			XmlWriter::closeElement( os_, indent_, "record" );
+		}
+	}
+private:
+	/// Reference to the stream the log information is written to
+	std::ostream& os_;
+	/// Stores the number of spaces to be prepended before each line
+	unsigned int indent_;
+	
+private:
+	/// Construction private, use create() instead
+	XmlStreamWriter( std::ostream& os, unsigned int indent = 0 )
+	:	os_( os )
+	,	indent_( indent )
+	{}
+};
+
+} // namespace Log
+
+#endif /* LOG_OUTPUT_XMLSTREAMWRITER_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/CppLog/output/XmlWriter.h b/odemx-lite/external/CppLog/include/CppLog/output/XmlWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..59d576cf5104c4bd2945aff0c9a6d13ded36e8b9
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/CppLog/output/XmlWriter.h
@@ -0,0 +1,121 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file CppLog/output/XmlWriter.h
+ * @author Ronald Kluth
+ * @date 2010/03/25
+ * @brief Declaration and implementation of abstract class XmlWriter
+ * @since 0.1
+ */
+
+#ifndef LOG_OUTPUT_XMLWRITER_INCLUDED
+#define LOG_OUTPUT_XMLWRITER_INCLUDED
+
+#include "../detail/InfoTypeLoop.h"
+#include "../Consumer.h"
+#include "../StringLiteral.h"
+
+#include <ostream>
+#include <string>
+
+namespace Log {
+
+/**
+ * @brief Abstract base class for consumers that write records to output streams in XML
+ *
+ * This base class provides XML output components with some basic
+ * static methods for creating correct XML markup strings.
+ *
+ * @note Be aware that string names of info types should not contain white space
+ * because these names are used  as XML tag names.
+ */
+class XmlWriter : public Consumer< Record >
+{
+public:
+	/// Construction
+	XmlWriter()
+	{
+	}
+	
+	/// Destruction
+	virtual ~XmlWriter()
+	{
+	}
+
+	/// Prints start tag to the stream: <element>
+	static void startElement( std::ostream& os, unsigned int indent,
+			std::string const& tag )
+	{
+		os << std::string( indent, ' ' ) << "<" << tag << ">";
+	}
+
+	/// Prints close tag to the stream: </element>
+	static void closeElement( std::ostream& os, unsigned int indent,
+			std::string const& tag )
+	{
+		os << std::string( indent, ' ' ) << "</" << tag << ">" << std::endl;
+	}
+
+	/// Prints an empty element to the stream: <element/>
+	static void emptyElement( std::ostream& os, unsigned int indent,
+			std::string const& tag )
+	{
+		os << std::string( indent, ' ' ) << "<" << tag << "/>" << std::endl;
+	}
+
+	/// Prints a complete element to the stream: <element>value</element>
+	template< typename ValueT >
+	static void writeElement( std::ostream& os, unsigned int indent,
+			std::string const& tag, ValueT const& value )
+	{
+		startElement( os, indent, tag );
+		os << value;
+		closeElement( os, 0, tag ); 
+	}
+
+	/// Prints an XML header to the stream to start a document
+	static void writeHeader( std::ostream& os )
+	{
+		os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
+	}
+private:
+	/// Non-copyable
+	XmlWriter( XmlWriter const& );
+	/// Non-assignable
+	XmlWriter& operator=( XmlWriter const& );
+
+protected:
+	/// Functor that transforms record info into XML elements and writes them to a stream
+	struct StreamInfoElements
+	{
+		std::ostream& stream_;
+		unsigned int indent_;
+
+		StreamInfoElements( std::ostream& stream, unsigned int indent )
+		:	stream_( stream )
+		,	indent_( indent )
+		{}
+		
+		template < typename InfoValueT >
+		void operator()( Log::StringLiteral const& name, InfoValueT const& value, bool found )
+		{
+			if( found )
+			{
+				writeElement( stream_, indent_, name.c_str(), value );
+			}
+			else
+			{
+				emptyElement( stream_, indent_, name.c_str() );
+			}
+		}
+	};
+};
+
+} // namespace Log
+
+#endif /* LOG_OUTPUT_XMLWRITER_INCLUDED */
diff --git a/odemx-lite/external/CppLog/include/setup.h b/odemx-lite/external/CppLog/include/setup.h
new file mode 100644
index 0000000000000000000000000000000000000000..e7f7951febc12d7cc61fec6197ff25d50c4b6a51
--- /dev/null
+++ b/odemx-lite/external/CppLog/include/setup.h
@@ -0,0 +1,75 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file include/setup.h
+ * @author Ronald Kluth
+ * @date 2010/04/24
+ * @brief Preprocessor macros for compiling CppLog with different settings
+ * @since 0.1
+ */
+
+#ifndef CPPLOG_SETUP_INCLUDED
+#define CPPLOG_SETUP_INCLUDED
+
+/**
+ * @def CPPLOG_USE_DATABASE
+ * @brief Enables the component DatabaseAccessor
+ *
+ * The database component requires the library POCO Data. Hence, this
+ * define should only be activated when POCO is present in the compiler's
+ * include path.
+ */
+//#define CPPLOG_USE_DATABASE
+
+/**
+ * @def CPPLOG_USE_SQLITE
+ * @brief Enables the SQLite database connectivity
+ *
+ * The default database management system is the embedded library SQLite
+ * that comes with POCO Data. It is enabled by using this define.
+ */
+//#define CPPLOG_USE_SQLITE
+
+/**
+ * @def CPPLOG_USE_ODBC
+ * @brief Enables the ODBC database connectivity
+ *
+ * POCO's ODBC-Connector can be used by enabling this define. Some Methods
+ * of class DatabaseAccessor will need other defines to be enabled, which
+ * specify the external database.
+ *
+ * @see CPPLOG_USE_SQLITE, CPPLOG_USE_POSTGRESQL
+ */
+//#define CPPLOG_USE_ODBC
+
+/**
+ * @def CPPLOG_USE_POSTGRESQL
+ * @brief Enables ODBC and some PostgreSQL-specific SQL syntax
+ *
+ * Since all DBMS use different SQL dialects it became necessary to make the
+ * distinction between specific databases in order to enable some concurrency
+ * functionality.
+ *
+ * @see CPPLOG_USE_SQLITE, CPPLOG_USE_ODBC
+ */
+//#define CPPLOG_USE_POSTGRESQL
+
+//------------------------------------------------------------------dependencies
+
+// if any of the database defines is enabled, compile DatabaseAccessor
+#ifdef CPPLOG_USE_SQLITE
+	#define CPPLOG_USE_DATABASE
+#endif
+
+// if PostgreSQL is enabled, enable DatabaseAccessor and ODBC
+#ifdef CPPLOG_USE_POSTGRESQL
+	#define CPPLOG_USE_DATABASE
+	#define CPPLOG_USE_ODBC
+#endif
+
+#endif /* CPPLOG_SETUP_INCLUDED */
diff --git a/odemx-lite/external/CppLog/src/samples/CppLogSamples.kdev4 b/odemx-lite/external/CppLog/src/samples/CppLogSamples.kdev4
new file mode 100644
index 0000000000000000000000000000000000000000..4686551f50257c3a90bda6c56e010702c44ff114
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/samples/CppLogSamples.kdev4
@@ -0,0 +1,3 @@
+[Project]
+Manager=KDevCustomMakeManager
+Name=CppLogSamples
diff --git a/odemx-lite/external/CppLog/src/samples/Makefile b/odemx-lite/external/CppLog/src/samples/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..32ba97feccfd560d0bb1ef58f20ebd6791e47c04
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/samples/Makefile
@@ -0,0 +1,81 @@
+#
+# Copyright (c) 2009-2010 Ronald Kluth
+#
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#
+
+all: samples
+
+#---------------------------------------------------------customizable variables
+
+BUILD_DIR = build
+
+SOURCE_DIR = src
+
+# POCO_BASE_DIR = /home/ron/Develop/KDev4Projects/poco.rev.1217
+POCO_BASE_DIR = ../../../poco.rev.1094
+
+CXX_DEBUG_FLAGS = -Wall -O0 -g3 -pg -Wno-sign-compare
+CXX_RELEASE_FLAGS = -Wall -O3 -Wno-sign-compare
+
+INC_PATHS = \
+-I ../../include \
+-I $(POCO_BASE_DIR)/Foundation/include \
+-I $(POCO_BASE_DIR)/Data/include \
+-I $(POCO_BASE_DIR)/Data/SQLite/include \
+-I $(POCO_BASE_DIR)/Data/ODBC/include
+
+DEBUG_LIBS = \
+-l PocoXMLd \
+-l PocoSQLited \
+-l PocoODBCd \
+-l PocoDatad \
+-l PocoFoundationd \
+-l odbc \
+-l pthread \
+-l dl
+
+RELEASE_LIBS = \
+-l PocoXML \
+-l PocoSQLite \
+-l PocoODBC \
+-l PocoData \
+-l PocoFoundation \
+-l odbc \
+-l pthread \
+-l dl
+
+
+LIB_PATH = \
+-L $(POCO_BASE_DIR)/lib
+#-L $(POCO_BASE_DIR)/lib/Linux/x86_64
+
+CXX_FLAGS = $(CXX_RELEASE_FLAGS) 
+LIBS = $(RELEASE_LIBS)
+
+#-----------------------------------------------------------------automatic part
+
+# get all sources
+VPATH := $(SOURCE_DIR)
+
+# compute targets
+TARGETS := $(patsubst $(SOURCE_DIR)/%.cpp, $(BUILD_DIR)/%, $(wildcard $(SOURCE_DIR)/*.cpp))
+
+# create build directory
+build_dir:
+	@echo "Creating build directory: $(BUILD_DIR)"
+	@mkdir -p $(BUILD_DIR)
+
+# a rule to make all samples at once
+samples: build_dir $(TARGETS)
+
+# build targets from sources
+$(BUILD_DIR)/%: %.cpp
+	@echo "Compiling $< to target: $@"
+	@$(CXX) $(CXX_FLAGS) $(INC_PATHS) $(LIB_PATH) -o $@ $< $(LIBS)
+
+# clean build by removing
+clean:
+	@echo "Removing build directory: $(BUILD_DIR)"
+	@rm -rf $(BUILD_DIR)
diff --git a/odemx-lite/external/CppLog/src/samples/src/Example_Channel_Consumer.cpp b/odemx-lite/external/CppLog/src/samples/src/Example_Channel_Consumer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ef2a1ea3b107cafba56c81540a9ca7db87e1a83c
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/samples/src/Example_Channel_Consumer.cpp
@@ -0,0 +1,66 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file Example_Channel_Consumer.cpp
+ * @author Ronald Kluth
+ * @date 2009/11/22
+ * @brief Example introducing basic channel and consumer usage
+ * @since 0.1
+ */
+
+/**
+ * @example Example_Channel_Consumer.cpp
+ * 
+ * This example introduces basic channel usage with a custom consumer class.
+ * The consumer class @c %ConsoleWriter simply disregards the channel ID and
+ * prints the record string to the console.
+ * 
+ * The main function shows the use of a channel object and a @c shared_ptr 
+ * -managed channel using @c std::string as record type. First, a consumer
+ * is created, which is registered to a channel object. The following log
+ * record is then printed to the console.
+ * 
+ * Wrapping the channel in a
+ * @c shared_ptr provides a few more options. When the pointer is set, the
+ * record is forwarded to the console as expected. However, resetting the
+ * pointer disables logging through that channel because the pointer is checked
+ * in @c operator<<. However, the call to the operator still requires the
+ * record object to be created. This overhead can also be avoided by checking
+ * the pointer before even making the logging call, as is shown in the last 
+ * statement.
+ */
+
+#include <CppLog.h>
+#include <iostream>
+
+typedef std::string Rec;
+
+class ConsoleWriter: public Log::Consumer< Rec > {
+public:
+	virtual void consume( const Log::ChannelId channelId, const Rec& record ) {
+		std::cout << record << std::flush;
+	}
+};
+
+int main() {
+	typedef std::shared_ptr< Log::Channel< Rec > > ChannelPtr;
+	typedef std::shared_ptr< Log::Consumer< Rec > > ConsumerPtr;
+	ConsumerPtr consoleWriter = ConsumerPtr( new ConsoleWriter() );
+
+	Log::Channel< Rec > channel;
+	channel.addConsumer( consoleWriter );
+	channel << Rec( "Logging via Channel object\n" );
+
+	ChannelPtr p_channel( new Log::Channel< Rec >() );
+	p_channel->addConsumer( consoleWriter );
+	p_channel << Rec( "Logging via set Channel pointer produces output\n" );
+	p_channel.reset();
+	p_channel << Rec( "Logging via empty pointer prints nothing\n" );
+	if( p_channel )
+		p_channel << Rec( "Checking empty pointer avoids record creation\n" );
+}
diff --git a/odemx-lite/external/CppLog/src/samples/src/Example_Consumer_Sqlite.cpp b/odemx-lite/external/CppLog/src/samples/src/Example_Consumer_Sqlite.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c6084cbedc382f67e9137bd367494ba58f9db221
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/samples/src/Example_Consumer_Sqlite.cpp
@@ -0,0 +1,141 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file src/Example_Consumer_Sqlite.cpp
+ * @author Ronald Kluth
+ * @date 2009/11/28
+ * @brief Example showing the usage of DatabaseAccessor as consumer member
+ * @since 0.1
+ */
+
+/**
+ * @example src/Example_Consumer_Sqlite.cpp
+ *
+ * This example demonstrates how to write a custom consumer class that
+ * logs records to an SQLite database. It makes use of the library's
+ * default @c Record type to transport arbitrary information in log records.
+ * These so-called info types @c I1, @c I2, and @c I3 will be stored in table 
+ * columns named like the string parameter provided in their declaration with 
+ * the macro @c CPPLOG_DECLARE_INFO_TYPE. The subsequently declared list of 
+ * info types @c Infos is used to iterate over the info types during database
+ * table creation and the insertion of records.
+ *
+ * The consumer class @c SqliteWriter is initialized with a database file name 
+ * and a buffer limit. For connecting and communicating with the database, 
+ * a @c DatabaseAccessor object is used. To further speed up the insertion of 
+ * records, an @c SqlInserter object is used, which holds a prepared statement,
+ * thus avoiding SQL parsing overhead. For convenience, the accessor provides
+ * method templates that iterate the info list and extract the necessary 
+ * information automatically. The macro @c CPPLOG_DECLARE_SQL_COLUMN_TYPES is
+ * used to provide the SQL data types to be used in columns that store info
+ * types.
+ * 
+ * During initialization, the database table is created if
+ * it does not exist, and the inserter is initialized. When the buffer limit is 
+ * reached in @c consume, the buffered log records are efficiently written to 
+ * the database in one transaction by calling @c flush. The insertion is 
+ * implemented by providing the buffer and an insert functor as parameters to
+ * the accessor's @c storeData method.
+ *
+ * In the main function, a channel object is created and an @c SqliteWriter is
+ * registered as consumer. Afterwards, a large number of records is created and
+ * sent via the channel. One final call to @c flush is made to store any 
+ * remaining data from the buffer. Since the database functionality is 
+ * implemented on top of the Poco.Data library, we added a @c try-catch block 
+ * to handle possible exceptions.
+ */
+
+#define CPPLOG_USE_SQLITE
+
+#include <CppLog.h>
+#include <iostream>
+using namespace Log;
+
+CPPLOG_DECLARE_INFO_TYPE( I1, "info_1", std::string );
+CPPLOG_DECLARE_INFO_TYPE( I2, "info_2", int );
+CPPLOG_DECLARE_INFO_TYPE( I3, "info_3", float );
+CPPLOG_DECLARE_INFO_TYPE_LIST( Infos, I1, I2, I3 );
+
+class SqliteWriter: public Consumer<> {
+public:
+	SqliteWriter( const std::string& dbFileName, std::size_t bufferLimit )
+	:	db_( dbFileName ), bufferLimit_( bufferLimit ),
+		recordCount_( 0 ), initialized_( false )
+	{}
+	void flush();
+private:
+	virtual void consume( const ChannelId channelId, const Record& record );
+	void initialize();
+	void insert( const Record& record );
+private:
+	DatabaseAccessor db_;
+	std::auto_ptr< DatabaseAccessor::SqlInserter > inserter_;
+	std::vector< Record > buffer_;
+	std::size_t bufferLimit_, recordCount_;
+	bool initialized_;
+};
+
+void SqliteWriter::consume( const ChannelId channelId, const Record& record ) {
+	if( ! initialized_ ) initialize();
+
+	if( recordCount_ < bufferLimit_ ) {
+		++recordCount_;
+	} else {
+		flush();
+		recordCount_ = 0;
+	}
+	buffer_.push_back( record );
+}
+
+CPPLOG_DECLARE_SQL_COLUMN_TYPES( Infos, sqlTypes, "VARCHAR", "INTEGER", "REAL" );
+
+void SqliteWriter::initialize() {
+	if( ! db_.tableExists( "log_record" ) ) {
+		db_.createTable( "log_record" )
+			.column( "id", "INTEGER" )
+			.column( "text", "VARCHAR" )
+			.columns< Infos >( sqlTypes )
+			.primaryKey( "id" );
+	}
+	inserter_ = db_.createInserter();
+	inserter_->table( "log_record" )
+				.column( "text" )
+				.columns< Infos >();
+	initialized_ = true;
+}
+
+void SqliteWriter::flush() {
+	using namespace std;
+	db_.storeData( buffer_, bind( &SqliteWriter::insert, this, placeholders::_1 ) );
+	buffer_.clear();
+}
+
+void SqliteWriter::insert( const Record& record ) {
+	inserter_->value( record.getText().c_str() )
+				.values< Infos >( record )
+				.execute();
+}
+
+int main() {
+	try {
+		typedef std::shared_ptr< SqliteWriter > SqlitePtr;
+		SqlitePtr sqlite( new SqliteWriter( "Example_Consumer_Sqlite.db", 100000 ) );
+
+		Channel<> channel;
+		channel.addConsumer( sqlite );
+
+		int i = 100000;
+		while( i-- )
+		{
+			channel << Record( "Logging example: SQLite database access" )
+						+ I1( "string detail" ) + I2( 2 ) + I3( 3.0f );
+		}
+		sqlite->flush();
+	}
+	catch( const Poco::Exception& ex ) { std::cout << ex.displayText(); }
+}
diff --git a/odemx-lite/external/CppLog/src/samples/src/Example_DatabaseAccessor.cpp b/odemx-lite/external/CppLog/src/samples/src/Example_DatabaseAccessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4b1be38bed6f90bc4651fb4f71e81f8f9ed71271
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/samples/src/Example_DatabaseAccessor.cpp
@@ -0,0 +1,73 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file Example_DatabaseAccessor.cpp
+ * @author Ronald Kluth
+ * @date 2009/11/29
+ * @brief Example showing the usage of DatabaseAccessor with SQLite
+ * @since 0.1
+ */
+
+/**
+ * @example Example_DatabaseAccessor.cpp
+ *
+ * This example demonstrates how to use class @c DatabaseAccessor for writing
+ * data to an SQLite database. The record type is a pair of ID and string.
+ * The function @c insertRow defines how to write a single record to the
+ * database by using the accessor's method @c insertIntoTable.
+ *
+ * In the main program we first use the method @c tableExists to check if 
+ * the table is already contained in the database. If not, it is created 
+ * via the method @c createTable. We then retrieve the current maximum ID 
+ * value in order to create valid primary keys for new records. After that,
+ * two records are added to a buffer and finally, the buffer is written to 
+ * the database by calling @c storeData and providing the buffer and the
+ * function @c insertRow, which is called for every buffered record.
+ */
+
+#define CPPLOG_USE_SQLITE
+
+#include <CppLog.h>
+#include <string>
+#include <utility>
+#include <vector>
+using namespace std;
+
+Log::DatabaseAccessor db( "example.db" );
+
+void createTable()
+{
+	if( ! db.tableExists( "example_table" ) )
+	{
+		db.createTable( "example_table" )
+			.column( "id", "INTEGER" )
+			.column( "text", "VARCHAR" )
+			.primaryKey( "id" );
+	}
+}
+
+void insertRow( const pair< int, string >& record )
+{
+	db.insertIntoTable( "example_table" )
+		.columnValue( "id", record.first )
+		.columnValue( "text", record.second );
+}
+
+int main()
+{
+	createTable();
+
+	int maxId;
+	db.getMaxColumnValue( "example_table", "id", maxId );
+
+	vector< pair< int, string > > buffer;
+	buffer.push_back( make_pair( maxId + 1, "first_example_string" ) );
+	buffer.push_back( make_pair( maxId + 2, "second_example_string" ) );
+
+	db.storeData( buffer, &insertRow );
+}
diff --git a/odemx-lite/external/CppLog/src/samples/src/Example_Filter.cpp b/odemx-lite/external/CppLog/src/samples/src/Example_Filter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..78d2f275ac1af44de9d1b0db9238725e8aba7019
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/samples/src/Example_Filter.cpp
@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file src/Example_Filter.cpp
+ * @author Ronald Kluth
+ * @date 2009/11/29
+ * @brief Example introducing basic filter usage
+ * @since 0.1
+ */
+
+/**
+ * @example src/Example_Filter.cpp
+ *
+ * This example illustrates the basic usage of record filters. Since @c Filter
+ * is only an interface, we use the filter specialization for the library's
+ * default record type. Filtering of @c Record objects is based on filter sets
+ * for the record text and each info type.
+ * 
+ * Filter entries are added in a stream-like manner
+ * with @c operator<< to filter sets retrieved by the method template @c add.
+ * Filtering happens when a log record passes the channel inserter 
+ * (@c operator<<), which checks the channel for a filter and, if one is set, 
+ * whether the record may pass. In this example we filter records
+ * by the @c ScopeInfo value "foo()", which means that all records originating
+ * from the function @c foo are blocked.
+ */
+
+#include <CppLog.h>
+#include <iostream>
+using namespace Log;
+
+CPPLOG_DECLARE_INFO_TYPE_LIST( Infos, ScopeInfo );
+Channel<> channel;
+
+void foo() {
+	channel << Record( "Logging filter example (foo)" ) + ScopeInfo( "foo()" );
+}
+
+int main() {
+	std::shared_ptr< Filter<> > filter = Filter<>::create();
+	filter->add< ScopeInfo >() << "foo()";
+	channel.setFilter( filter );
+	channel.addConsumer( OStreamWriter< Infos >::create( std::cout ) );
+
+	channel << Record( "Logging filter example (main)" ) + ScopeInfo( "main()" );
+	foo();
+}
diff --git a/odemx-lite/external/CppLog/src/samples/src/Example_Logging_StringLiteral.cpp b/odemx-lite/external/CppLog/src/samples/src/Example_Logging_StringLiteral.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..60738bedf2278c212d7944f92d2040cb5d2958fc
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/samples/src/Example_Logging_StringLiteral.cpp
@@ -0,0 +1,96 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file Example_Logging_StringLiteral.cpp
+ * @author Ronald Kluth
+ * @date 2009/04/11
+ * @brief Example displaying use of CppLog with normal C-strings
+ * @since 0.1
+ */
+
+/**
+ * @example Example_Logging_StringLiteral.cpp
+ *
+ * This example illustrates how to log data with the simplest and fastest
+ * kind of strings - constant string literals. In order to do this we
+ * define Log::StringLiteral as the record type. To be able to use simple
+ * C-strings without constructor calls to Log::StringLiteral, another
+ * overload of @c operator<< must be provided that transforms const char[]
+ * to a Log::StringLiteral and writes it to the channel.
+ *
+ */
+#include <CppLog.h>
+#include <iostream>
+//
+//------------------------------------------------------------------------global
+//
+// To log strings, the simplest log records are sufficient.
+//
+typedef Log::StringLiteral Rec;
+//
+// In order to create log records from string literals, we must overload the
+// insertion operator for fixed-length character arrays.
+//
+template < std::size_t LenV >
+const Log::Channel< Rec >&
+operator<<( const Log::Channel< Rec >& channel, const char (&recordText)[LenV] )
+{
+	//
+	// The record text is used to create a simple StringLiteral record for
+	// each logged string, which is then sent through the channel via
+	// Log::operator<<.
+	//
+	channel << Rec( recordText );
+	return channel;
+}
+//
+// For simplicity, we use a global log channel object.
+//
+Log::Channel< Rec > logChannel;
+//
+//-----------------------------------------------------------------------classes
+//
+// To receive and handle log records, we subclass the DataConsumer interface
+// with the appropriate record type and implement the method 'consume()'
+// In this example, we print formatted records to the console.
+//
+class ConsoleWriter
+:	public Log::Consumer< Rec >
+{
+public:
+	//
+	// Override the pure virtual method 'consume()'. The second parameter
+	// uses a typedef from the base class DataConsumer to free us from
+	// using possibly complicated record type names.
+	//
+	virtual void consume( const Log::ChannelId channelId, const Rec& record )
+	{
+		std::cout << record << std::flush;
+	}
+};
+//
+//--------------------------------------------------------------------------main
+//
+int main( int argc, char* argv[] )
+{
+	//
+	// We register an instance of ConsoleWriter with the channel.
+	//
+	logChannel.addConsumer( std::shared_ptr< ConsoleWriter >( new ConsoleWriter() ) );
+	//
+	// Now, we can start logging right away by sending strings to the channel,
+	// which basically forwards them to stdout.
+	//
+	logChannel << "a string literal followed by some value: " << "2" << "\n";
+	return 0;
+}
+//
+//----------------------------------------------------------------program output
+//
+//a string record displaying some value: 2
+//
diff --git a/odemx-lite/external/CppLog/src/samples/src/Example_Producer_ChannelManager.cpp b/odemx-lite/external/CppLog/src/samples/src/Example_Producer_ChannelManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..813837e1b65f3a3baaa0fd533092a8c5550c52c1
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/samples/src/Example_Producer_ChannelManager.cpp
@@ -0,0 +1,80 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file Example_Producer_ChannelManager.cpp
+ * @author Ronald Kluth
+ * @date 2009/11/22
+ * @brief Example introducing basic producer and channel manager usage
+ * @since 0.1
+ */
+
+/**
+ * @example Example_Producer_ChannelManager.cpp
+ *
+ * This example illustrates the basic usage of the class templates @c Producer
+ * and @c ChannelManager. First, the record type is defined as a pair of two
+ * strings, followed by the declaration of two channels: @c info and @c debug.
+ * The IDs of the channels are used to enable channel members within the
+ * @c Producer template by providing an instance of @c Enable as template
+ * parameter. By deriving from the resulting type, class @c ExampleProducer
+ * can access the two channel members @c info and @c debug directly.
+ *
+ * Since a user-defined record type is employed, we must provide a suitable 
+ * consumer type: the class @c ConsoleWriter. It uses the channel IDs to
+ * print information about the forwarding channel.
+ *
+ * In the main function, a @c ChannelManager is created, which is used in the
+ * initialization of two producer objects. By adding a consumer to the manager,
+ * it is automatically registered with all currently managed channels, and
+ * the records sent by both producers are printed on the console.
+ */
+
+#include <CppLog.h>
+#include <iostream>
+
+typedef std::pair< std::string, std::string > Rec;
+
+CPPLOG_DECLARE_CHANNEL_WITH_ID( channel, info, Rec, 1 );
+CPPLOG_DECLARE_CHANNEL_WITH_ID( channel, debug, Rec, 2 );
+
+typedef Log::Producer< Log::Enable< channel::info, channel::debug > > ProducerType;
+
+class DataProducer: public ProducerType {
+public:
+	DataProducer( Log::ChannelManager< Rec >& mgr, const std::string& name )
+	:	ProducerType( mgr , name ) {}
+	void useInfo() {
+		info << log( "Info logging with Producer and ChannelManager" );
+	}
+	void useDebug() {
+		debug << log( "Debug logging with Producer and ChannelManager" );
+	}
+private:
+	Rec log( const std::string& text ) const { return Rec( getName(), text ); }
+};
+
+class ConsoleWriter: public Log::Consumer< Rec > {
+public:
+	virtual void consume( const Log::ChannelId channelId, const Rec& record ) {
+		switch( channelId ) {
+			case channel::info: std::cout << "INFO "; break;
+			case channel::debug: std::cout << "DEBUG "; break;
+			default: break;
+		}
+		std::cout << "(" << record.first << ") " << record.second << std::endl;
+	}
+};
+
+int main() {
+	typedef std::shared_ptr< Log::Consumer< Rec > > ConsumerPtr;
+	Log::ChannelManager< Rec > manager;
+	DataProducer p1( manager, "P1" ), p2( manager, "P2" );
+	manager.addConsumer( ConsumerPtr( new ConsoleWriter() ) );
+	p1.useInfo();
+	p2.useDebug();
+}
diff --git a/odemx-lite/external/CppLog/src/samples/src/Example_Record.cpp b/odemx-lite/external/CppLog/src/samples/src/Example_Record.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..845eb29e0508120746f73fe71c6ff06fd06d703a
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/samples/src/Example_Record.cpp
@@ -0,0 +1,72 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file Example_Record.cpp
+ * @author Ronald Kluth
+ * @date 2009/11/23
+ * @brief Example introducing basic default record usage
+ * @since 0.1
+ */
+
+/**
+ * @example Example_Record.cpp
+ *
+ * This example illustrates the basic usage of the library's default record
+ * type. Class @c Record always holds a text message, but it can also be used
+ * to transport arbitrary data. All that is necessary is a declaration of a
+ * so-called info type with the macro CPPLOG_DECLARE_INFO_TYPE. The library
+ * already provides three common info types: @c FileInfo, @c LineInfo, and
+ * @c ScopeInfo, all of which are used in this example. Additionally, a list
+ * of info types can be declared to provide automatic iteration over the
+ * contained information. This is done via the macro CPPLOG_DECLARE_INFO_TYPE_LIST.
+ *
+ * After declaring the list @c Infos of info types, we add the functor
+ * @c InfoWriter for printing info type values on the console. In the main
+ * function, we first create a record object with a text message and then
+ * add the info types with the class's methods @c file, @c line, and @c scope
+ * which all support chaining.
+ *
+ * The next part shows two different ways to extract information from @c Record
+ * objects. The text can be retrieved via @c getText, but the info types need a
+ * little more work as they are stored in a map with their type info as key.
+ * Hence they must be requested via the method template @c get, which returns
+ * a pointer to the data, or zero if the given info type was not found in the
+ * record. The other method is automatic iteration over info types via the
+ * method template @c iterateInfo, which requires an info type list and a
+ * functor to call for each value.
+ */
+#include <CppLog.h>
+#include <iostream>
+using namespace Log;
+
+CPPLOG_DECLARE_INFO_TYPE_LIST( Infos, FileInfo, LineInfo, ScopeInfo );
+
+struct InfoWriter {
+	template < typename ValT >
+	void operator()( const StringLiteral& name, const ValT& value, bool found ) {
+		if( found ) { std::cout << ", " << name << ": " << value; }
+	}
+} writer;
+
+int main() {
+	Record rec( "Logging class Record example" );
+	rec.file( __FILE__ ).line( __LINE__ ).scope( "main()" );
+
+	std::cout << rec.getText();
+	if( FileInfo::Type const* fi = rec.get< FileInfo >() )
+		std::cout << ", " << FileInfo::getName() << ": " << *fi;
+	if( LineInfo::Type const* li = rec.get< LineInfo >() )
+		std::cout << ", " << LineInfo::getName() << ": " << *li;
+	if( ScopeInfo::Type const* si = rec.get< ScopeInfo >() )
+		std::cout << ", " << ScopeInfo::getName() << ": " << *si;
+	std::cout << std::endl;
+
+	std::cout << rec.getText();
+	rec.iterateInfo< Infos >( writer );
+	std::cout << std::endl;
+}
diff --git a/odemx-lite/external/CppLog/src/samples/src/Example_Record_TextWriters.cpp b/odemx-lite/external/CppLog/src/samples/src/Example_Record_TextWriters.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d4211f2f3366de8ced14d4c8754431f04216dd18
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/samples/src/Example_Record_TextWriters.cpp
@@ -0,0 +1,57 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file Example_Record_TextWriters.cpp
+ * @author Ronald Kluth
+ * @date 2009/11/23
+ * @brief Example introducing default text writers
+ * @since 0.1
+ */
+
+/**
+ * @example Example_Record_TextWriters.cpp
+ *
+ * This example demonstrates the use of the library's default text writing
+ * components. To illustrate how they can be used with any class that provides
+ * a stream inserter overload (@c operator<<), we first define a structure
+ * @c Point3d and two info types @c PointInfo and @c DoubleInfo. These are then
+ * added to the list @c Infos, which we plan to extract automatically from the
+ * log records.
+ * 
+ * In the main function we create a channel object an register two consumers:
+ * an @c OStreamWriter which is connected to the console, and an @c XmlFileWriter
+ * which will store all records in XML files. The second parameter sets a record
+ * limit per file. When the limit is reached, a new XML file is created 
+ * automatically. The output of the log record in the last statement will appear
+ * on the console and in a file called @c Example_0.xml. The added @c Point3d
+ * is converted into a string by means of @c operator<<.
+ */
+
+#include <CppLog.h>
+#include <iostream>
+
+struct Point3d { float x, y, z; };
+
+std::ostream& operator<<( std::ostream& os, Point3d const& p ) {
+	os << "(" << p.x << " " << p.y << " " << p.z << ")";
+	return os;
+}
+
+CPPLOG_DECLARE_INFO_TYPE( PointInfo, "point", Point3d );
+CPPLOG_DECLARE_INFO_TYPE( DoubleInfo, "value", double& );
+CPPLOG_DECLARE_INFO_TYPE_LIST( Infos, PointInfo, DoubleInfo );
+
+int main() {
+	Log::Channel<> channel;
+	channel.addConsumer( Log::OStreamWriter< Infos >::create( std::cout ) );
+	channel.addConsumer( Log::XmlStreamWriter< Infos >::create( std::cout ) );
+	channel.addConsumer( Log::XmlFileWriter< Infos >::create( "Example", 1000 ) );
+
+	Point3d p = { 1, 2, 3 };
+	channel << Log::Record() + PointInfo( p ) + DoubleInfo( 123.45 );
+}
diff --git a/odemx-lite/external/CppLog/src/test/CppLogTest.kdev4 b/odemx-lite/external/CppLog/src/test/CppLogTest.kdev4
new file mode 100644
index 0000000000000000000000000000000000000000..9caa8cdee471d2eac18aee384b5b849e0bfc0be4
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/CppLogTest.kdev4
@@ -0,0 +1,3 @@
+[Project]
+Manager=KDevCustomMakeManager
+Name=CppLogTest
diff --git a/odemx-lite/external/CppLog/src/test/Makefile b/odemx-lite/external/CppLog/src/test/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..0d11d8bc83192430bcf5c835c51e347537d529ad
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/Makefile
@@ -0,0 +1,70 @@
+all: testing
+
+#---------------------------------------------------------customizable variables
+
+TARGET = TestCppLog
+
+BUILD_DIR = build
+
+SOURCE_DIR = src
+
+CXX_FLAGS = -g3 -Wall -Wno-sign-compare
+
+UNITTEST_PP_DIR = ../../../UnitTest++
+POCO_BASE_DIR = ../../../poco.rev.1094
+
+INC_PATHS = \
+-I ../../include \
+-I $(UNITTEST_PP_DIR)/src \
+-I $(POCO_BASE_DIR)/Foundation/include \
+-I $(POCO_BASE_DIR)/Data/include \
+-I $(POCO_BASE_DIR)/Data/SQLite/include
+
+LIB_PATHS = \
+-L $(UNITTEST_PP_DIR) \
+-L $(POCO_BASE_DIR)/lib
+
+LIBS = \
+-l UnitTest++ \
+-l PocoSQLited \
+-l PocoDatad \
+-l PocoFoundationd \
+-l pthread \
+-l dl
+
+#-----------------------------------------------------------------automatic part
+
+# get all sources
+VPATH := $(SOURCE_DIR)
+
+# compute objects
+OBJECTS := $(patsubst $(SOURCE_DIR)/%.cpp, $(BUILD_DIR)/%.o, $(wildcard $(SOURCE_DIR)/*.cpp))
+
+# create build directory
+build_dir:
+	@echo "Creating build directory: $(BUILD_DIR)"
+	@mkdir -p $(BUILD_DIR)
+
+# build objects from sources
+$(BUILD_DIR)/%.o: %.cpp
+	@echo "Compiling $< to target: $@"
+	@$(CXX) $(CXX_FLAGS) -c $< $(INC_PATHS) -o $@
+
+# link objects to executable
+test_runner: build_dir $(OBJECTS)
+	@echo "Creating executable: $(BUILD_DIR)/$(TARGET)"
+	@$(CXX) -o $(BUILD_DIR)/$(TARGET) $(OBJECTS) $(LIB_PATHS) $(LIBS)
+
+# preparations for testing
+prep:
+	@rm -f $(BUILD_DIR)/*.db
+
+# run all tests automatically
+testing: prep test_runner
+	@echo "Running tests..."
+	@cd $(BUILD_DIR); ./$(TARGET);
+
+# clean build by removing
+clean:
+	@echo "Removing build directory: $(BUILD_DIR)"
+	@rm -rf $(BUILD_DIR)
diff --git a/odemx-lite/external/CppLog/src/test/src/TestChannel.cpp b/odemx-lite/external/CppLog/src/test/src/TestChannel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..85fe8f215cc4617838a4fb8501f827f954b7f626
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestChannel.cpp
@@ -0,0 +1,111 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestChannel.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/05/16
+ * @brief Unit tests for class template Channel
+ * @since 0.1
+ */
+
+#include "global.h"
+#include <string>
+
+SUITE( CppLogUnitTest )
+{
+	template< typename RecordT >
+	struct DummyConsumer: public Log::Consumer< RecordT >
+	{
+		virtual void consume( const Log::ChannelId channelId, const RecordT& record )
+		{
+			lastChannelId = channelId;
+			lastRecord = record;
+		}
+		Log::ChannelId lastChannelId;
+		RecordT lastRecord;
+	};
+
+	struct TestChannelFixture
+	{
+		typedef Log::Channel< std::string > Channel;
+		typedef std::shared_ptr< Channel > ChannelPtr;
+		typedef Log::Filter< std::string > Filter;
+		typedef std::shared_ptr< Filter > FilterPtr;
+		typedef DummyConsumer< std::string > Consumer;
+		typedef std::shared_ptr< Consumer > ConsumerPtr;
+
+		TestChannelFixture()
+		:	channelId( 99 )
+		,	channel( channelId )
+		{}
+
+		Log::ChannelId channelId;
+		Channel channel;
+	};
+
+	TEST_FIXTURE( TestChannelFixture, Id )
+	{
+		CHECK_EQUAL( channel.getId(), channelId );
+	}
+
+	TEST_FIXTURE( TestChannelFixture, Filter )
+	{
+		FilterPtr filter( new Filter() );
+		channel.setFilter( filter );
+		CHECK( channel.hasFilter() );
+		CHECK_EQUAL( filter, channel.getFilter() );
+
+		channel.resetFilter();
+		CHECK( ! channel.hasFilter() );
+	}
+
+	TEST_FIXTURE( TestChannelFixture, Consumers )
+	{
+		ConsumerPtr con1( new Consumer() );
+		ConsumerPtr con2( new Consumer() );
+		ConsumerPtr con3( new Consumer() );
+		channel.addConsumer( con1 );
+		channel.addConsumer( con2 );
+		channel.addConsumer( con3 );
+
+		const Channel::ConsumerSet& cons = channel.getConsumers();
+		CHECK( cons.find( con1 ) != cons.end() );
+		CHECK( cons.find( con2 ) != cons.end() );
+		CHECK( cons.find( con3 ) != cons.end() );
+
+		channel.removeConsumer( con2 );
+		CHECK( cons.find( con1 ) != cons.end() );
+		CHECK( cons.find( con2 ) == cons.end() );
+		CHECK( cons.find( con3 ) != cons.end() );
+
+		channel.removeConsumers();
+		CHECK( cons.empty() );
+	}
+
+	TEST_FIXTURE( TestChannelFixture, Inserters )
+	{
+		ConsumerPtr con( new Consumer() );
+		channel.addConsumer( con );
+		std::string record( "Channel Object Inserter Test" );
+		channel << record;
+		CHECK_EQUAL( record, con->lastRecord );
+		CHECK_EQUAL( channel.getId(), con->lastChannelId );
+
+		ChannelPtr p_channel( new Channel( channelId + 1 ) );
+		p_channel->addConsumer( con );
+		record = "Channel Pointer Inserter Test";
+		p_channel << record;
+		CHECK_EQUAL( record, con->lastRecord );
+		CHECK_EQUAL( p_channel->getId(), con->lastChannelId );
+
+		p_channel.reset();
+		record.clear();
+		p_channel << record;
+		CHECK( ! con->lastRecord.empty() );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestChannelManager.cpp b/odemx-lite/external/CppLog/src/test/src/TestChannelManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1d7406058a12ba737b95eabc16c8e602a36325f8
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestChannelManager.cpp
@@ -0,0 +1,124 @@
+//
+// Copyright (c) 2009-2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestChannelManager.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/17
+ * @brief Unit tests for class template Channel
+ * @since 0.1
+ */
+
+#include "global.h"
+#include <string>
+
+SUITE( CppLogUnitTest )
+{
+	struct DummyConsumer: public Log::Consumer<>
+	{
+		virtual void consume( const Log::ChannelId channelId, const Log::Record& record ) {}
+	};
+
+	struct ChannelManagerFixture
+	{
+		typedef Log::Channel<> Channel;
+		typedef std::shared_ptr< Channel > ChannelPtr;
+		typedef DummyConsumer Consumer;
+		typedef std::shared_ptr< Consumer > ConsumerPtr;
+		typedef Log::Filter<> Filter;
+		typedef std::shared_ptr< Filter > FilterPtr;
+
+		ChannelManagerFixture()
+		:	manager(  )
+		,	id1( 123 )
+		,	id2( 456 )
+		{}
+
+		Log::ChannelManager<> manager;
+		Log::ChannelId id1;
+		Log::ChannelId id2;
+	};
+
+	TEST( ChannelManagerNameScopeDefaults )
+	{
+		std::string defaultName = "No label given";
+		char defaultSpacer = ' ';
+		Log::ChannelManager<> manager( defaultName, defaultSpacer );
+		std::string emptyName = manager.createUniqueName( "" );
+		std::string emptyName1 = manager.createUniqueName( "" );
+
+		CHECK_EQUAL( defaultName, emptyName );
+		CHECK_EQUAL( defaultSpacer, emptyName1[ defaultName.size() ] );
+	}
+
+	TEST_FIXTURE( ChannelManagerFixture, GetChannel )
+	{
+		ChannelPtr c1 = manager.getChannel( id1 );
+		CHECK( (bool)c1 );
+		ChannelPtr c2 = manager.getChannel( id1 );
+		CHECK_EQUAL( c1, c2 );
+	}
+
+	TEST_FIXTURE( ChannelManagerFixture, AddConsumer )
+	{
+		ConsumerPtr con( new Consumer() );
+		ChannelPtr c1 = manager.getChannel( id1 );
+		manager.addConsumer( id1, con );
+		CHECK_EQUAL( 1, c1->getConsumers().size() );
+		CHECK( c1->getConsumers().find( con ) != c1->getConsumers().end() );
+
+		ConsumerPtr con2( new Consumer() );
+		ChannelPtr c2 = manager.getChannel( id2 );
+		manager.addConsumer( con2 );
+		CHECK_EQUAL( 2, c1->getConsumers().size() );
+		CHECK_EQUAL( 1, c2->getConsumers().size() );
+		CHECK( c1->getConsumers().find( con2 ) != c1->getConsumers().end() );
+		CHECK( c2->getConsumers().find( con2 ) != c2->getConsumers().end() );
+	}
+
+	TEST_FIXTURE( ChannelManagerFixture, RemoveConsumer )
+	{
+		ConsumerPtr con( new Consumer() );
+		ConsumerPtr con2( new Consumer() );
+		ChannelPtr c1 = manager.getChannel( id1 );
+		ChannelPtr c2 = manager.getChannel( id2 );
+		manager.addConsumer( con );
+		manager.addConsumer( con2 );
+		manager.removeConsumer( id1, con );
+
+		CHECK_EQUAL( 1, c1->getConsumers().size() );
+		CHECK( c1->getConsumers().find( con ) == c1->getConsumers().end() );
+
+		manager.removeConsumer( con2 );
+		CHECK_EQUAL( 0, c1->getConsumers().size() );
+		CHECK_EQUAL( 1, c2->getConsumers().size() );
+		CHECK( c1->getConsumers().find( con2 ) == c1->getConsumers().end() );
+		CHECK( c2->getConsumers().find( con2 ) == c2->getConsumers().end() );
+		CHECK( c2->getConsumers().find( con ) != c1->getConsumers().end() );
+	}
+
+	TEST_FIXTURE( ChannelManagerFixture, SetResetFilter )
+	{
+		FilterPtr filter = Filter::create();
+		ChannelPtr c1 = manager.getChannel( id1 );
+		ChannelPtr c2 = manager.getChannel( id2 );
+
+		manager.setFilter( id1, filter );
+		CHECK_EQUAL( filter, c1->getFilter() );
+
+		manager.setFilter( filter );
+		CHECK_EQUAL( filter, c1->getFilter() );
+		CHECK_EQUAL( filter, c2->getFilter() );
+
+		manager.resetFilter( id1 );
+		CHECK( ! c1->hasFilter() );
+
+		manager.resetFilter();
+		CHECK( ! c1->hasFilter() );
+		CHECK( ! c2->hasFilter() );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestConsumer.cpp b/odemx-lite/external/CppLog/src/test/src/TestConsumer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5b6d67e340b4bec705a8e0336a4424bb9db5c52e
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestConsumer.cpp
@@ -0,0 +1,44 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestConsumer.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/27
+ * @brief Unit tests for class template Consumer
+ * @since 0.1
+ */
+
+#include "global.h"
+#include <string>
+
+SUITE( CppLogUnitTest )
+{
+	struct TestConsumer: public Log::Consumer< std::string >
+	{
+		TestConsumer(): lastId( 0 ), lastRecord( "" ) {}
+		virtual void consume( Log::ChannelId const channelId, std::string const& record )
+		{
+			lastId = channelId;
+			lastRecord = record;
+		}
+		Log::ChannelId lastId;
+		std::string lastRecord;
+	};
+
+	TEST( TestConsumerInterfaceCall )
+	{
+		std::string testRecord( "test record" );
+		Log::ChannelId id = 666;
+		Log::Channel< std::string > channel( id );
+		std::shared_ptr< TestConsumer > testConsumer( new TestConsumer() );
+		channel.addConsumer( testConsumer );
+		channel << testRecord;
+		CHECK_EQUAL( channel.getId(), testConsumer->lastId );
+		CHECK_EQUAL( testRecord, testConsumer->lastRecord );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestDeclareChannel.cpp b/odemx-lite/external/CppLog/src/test/src/TestDeclareChannel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8b798038b4e8979a77c7c60512c5946977e31c78
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestDeclareChannel.cpp
@@ -0,0 +1,57 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestDeclareChannel.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/27
+ * @brief Unit tests for macro CPPLOG_DECLARE_CHANNEL
+ * @since 0.1
+ */
+
+#include "global.h"
+#include <string>
+
+static const int testChannelId = 666;
+typedef unsigned long TestRecordType;
+
+CPPLOG_DECLARE_CHANNEL_WITH_ID( Channel, testChannel , TestRecordType, testChannelId );
+
+SUITE( CppLogUnitTest )
+{
+	TEST( TestDeclareChannelId )
+	{
+		CHECK_EQUAL( testChannelId, (int)Channel::testChannel );
+	}
+
+	struct TestDeclareChannelProducer: Log::Detail::ChannelField< Channel::testChannel >
+	{
+		using Log::Detail::ChannelField< Channel::testChannel >::testChannel;
+	};
+	struct TestDeclareChannelConsumer: Log::Consumer< TestRecordType >
+	{
+		virtual void consume( Log::ChannelId const channelId, TestRecordType const& record )
+		{
+			lastRecord = record;
+		}
+		TestRecordType lastRecord;
+	};
+
+	TEST( TestDeclareChannelMember )
+	{
+		TestRecordType testRecord( 42 );
+		TestDeclareChannelProducer p;
+		std::shared_ptr< TestDeclareChannelConsumer > testConsumer(
+				new TestDeclareChannelConsumer() );
+
+		p.testChannel.reset( new Log::Channel< TestRecordType >( Channel::testChannel ) );
+		p.testChannel->addConsumer( testConsumer );
+		p.testChannel << testRecord;
+
+		CHECK_EQUAL( testRecord, testConsumer->lastRecord );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestDeclareInfoType.cpp b/odemx-lite/external/CppLog/src/test/src/TestDeclareInfoType.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7e17b58d3dd1ac99e3edf5eb4a048a5c0885f0ad
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestDeclareInfoType.cpp
@@ -0,0 +1,47 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestDeclareInfoType.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/27
+ * @brief Unit tests for macro CPPLOG_DECLARE_INFO_TYPE
+ * @since 0.1
+ */
+
+#include "global.h"
+#include <string>
+
+CPPLOG_DECLARE_INFO_TYPE( PointerInfo, "pointer info", std::string* );
+CPPLOG_DECLARE_INFO_TYPE( CopyInfo, "copy info", std::string );
+CPPLOG_DECLARE_INFO_TYPE( ReferenceInfo, "reference info", std::string& );
+
+SUITE( CppLogUnitTest )
+{
+	TEST( TestDeclareInfoTypeStringName )
+	{
+		CHECK_EQUAL( "pointer info", PointerInfo::getName().c_str() );
+	}
+
+	TEST( TestDeclareInfoTypePointer )
+	{
+		std::string testString( "test string" );
+		CHECK_EQUAL( &testString, PointerInfo( &testString ).value() );
+	}
+
+	TEST( TestDeclareInfoTypeCopy )
+	{
+		std::string testString( "test string" );
+		CHECK_EQUAL( "test string", CopyInfo( testString ).value()->c_str() );
+	}
+
+	TEST( TestDeclareInfoTypeReference )
+	{
+		std::string testString( "test string" );
+		CHECK_EQUAL( &testString, ReferenceInfo( testString ).value() );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestDeclareInfoTypeList.cpp b/odemx-lite/external/CppLog/src/test/src/TestDeclareInfoTypeList.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..38551dd3ecbea9eb9aca933750a16cfc96066ac0
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestDeclareInfoTypeList.cpp
@@ -0,0 +1,45 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestDeclareInfoTypeList.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/27
+ * @brief Unit tests for macro CPPLOG_DECLARE_INFO_TYPE_LIST
+ * @since 0.1
+ */
+
+#include "global.h"
+#include <string>
+#include <vector>
+#include <type_traits>
+
+CPPLOG_DECLARE_INFO_TYPE_LIST( TestInfoTypeList, std::string, int, std::vector< bool > );
+
+SUITE( CppLogUnitTest )
+{
+	TEST( TestDeclareInfoTypeListTypes )
+	{
+		bool isSame = std::is_same<
+						std::string,
+						Log::Detail::TypeOf< TestInfoTypeList, 0 >::type
+						>::value;
+		CHECK( isSame );
+
+		isSame = std::is_same<
+						int,
+						Log::Detail::TypeOf< TestInfoTypeList, 1 >::type
+						>::value;
+		CHECK( isSame );
+
+		isSame = std::is_same<
+						std::vector< bool >,
+						Log::Detail::TypeOf< TestInfoTypeList, 2 >::type
+						>::value;
+		CHECK( isSame );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestDeclareSqlColumnTypes.cpp b/odemx-lite/external/CppLog/src/test/src/TestDeclareSqlColumnTypes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..313ed3d9d9f9a9d1c9530e97863a58db891d6884
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestDeclareSqlColumnTypes.cpp
@@ -0,0 +1,32 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestDeclareSqlColumnTypes.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/27
+ * @brief Unit tests for macro CPPLOG_DECLARE_SQL_COLUMN_TYPES
+ * @since 0.1
+ */
+
+#include "global.h"
+#include <string>
+#include <vector>
+#include <type_traits>
+
+CPPLOG_DECLARE_INFO_TYPE_LIST( TestInfoTypeList, std::string, int, std::vector< bool > );
+CPPLOG_DECLARE_SQL_COLUMN_TYPES( TestInfoTypeList, testSqlTypes, "VARCHAR", "INTEGER", "BLOB" );
+
+SUITE( CppLogUnitTest )
+{
+	TEST( TestDeclareSqlColumnTypesValues )
+	{
+		CHECK_EQUAL( "VARCHAR", testSqlTypes[ 0 ] );
+		CHECK_EQUAL( "INTEGER", testSqlTypes[ 1 ] );
+		CHECK_EQUAL( "BLOB", testSqlTypes[ 2 ] );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestEnable.cpp b/odemx-lite/external/CppLog/src/test/src/TestEnable.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..759bd9a410d118190f7cac76bb756524d9231483
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestEnable.cpp
@@ -0,0 +1,43 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestEnable.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/27
+ * @brief Unit tests for class template Enable
+ * @since 0.1
+ */
+
+#include "global.h"
+#include <string>
+#include <vector>
+#include <type_traits>
+
+SUITE( CppLogUnitTest )
+{
+	enum
+	{
+		id1,
+		id2
+	};
+
+	TEST( TestEnableChannelFields )
+	{
+		typedef Log::Producer< Log::Enable< id1, id2 > > TestEnableProducer;
+		bool inheritedField1 = std::is_base_of<
+							Log::Detail::ChannelField< id1 >,
+							TestEnableProducer
+							>::value;
+		bool inheritedField2 = std::is_base_of<
+							Log::Detail::ChannelField< id2 >,
+							TestEnableProducer
+							>::value;
+		CHECK( inheritedField1 );
+		CHECK( inheritedField2 );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestFilter.cpp b/odemx-lite/external/CppLog/src/test/src/TestFilter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6d8eea7385ef591eb347abb6b37de6ad3b16a775
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestFilter.cpp
@@ -0,0 +1,62 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestFilter.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/27
+ * @brief Unit tests for class template specialization Filter< Record >
+ * @since 0.1
+ */
+
+#include "global.h"
+#include <iostream>
+
+CPPLOG_DECLARE_INFO_TYPE( TestFilterInfo, "test filter info", std::string )
+
+SUITE( CppLogUnitTest )
+{
+	TEST( TestFilterRecordText )
+	{
+		std::shared_ptr< Log::Filter<> > filter = Log::Filter<>::create();
+		Log::Record rec( "text filter test" );
+		filter->addRecordText() << "text filter test";
+		CHECK( ! filter->pass( rec ) );
+	}
+
+	TEST( TestFilterRecordInfo )
+	{
+		std::shared_ptr< Log::Filter<> > filter = Log::Filter<>::create();
+		Log::Record rec;
+		rec + TestFilterInfo( "info filter test" );
+		filter->add< TestFilterInfo >() << "info filter test";
+		CHECK( ! filter->pass( rec ) );
+	}
+
+	TEST( TestFilterRecordMode )
+	{
+		std::shared_ptr< Log::Filter<> > filter = Log::Filter<>::create();
+		Log::Record rec( "mode filter test" );
+		rec + TestFilterInfo( "mode filter test" );
+		filter->addRecordText() << "mode filter test";
+		filter->add< TestFilterInfo >() << "mode filter test";
+		filter->passNone();
+		CHECK( filter->pass( rec ) );
+		filter->passAll();
+		CHECK( ! filter->pass( rec ) );
+	}
+
+	TEST( TestFilterRecordReset )
+	{
+		std::shared_ptr< Log::Filter<> > filter = Log::Filter<>::create();
+		Log::Record rec;
+		rec + TestFilterInfo( "reset filter test" );
+		filter->add< TestFilterInfo >() << "reset filter test";
+		filter->resetFilter();
+		CHECK( filter->pass( rec ) );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestNameScope.cpp b/odemx-lite/external/CppLog/src/test/src/TestNameScope.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e55525498b3697512f253e71139e060280ba3e1d
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestNameScope.cpp
@@ -0,0 +1,56 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestNameScope.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/05/17
+ * @brief Unit tests for class NameScope
+ * @since 0.1
+ */
+
+#include "global.h"
+#include <string>
+
+SUITE( CppLogUnitTest )
+{
+	TEST( NameScopeDefaults )
+	{
+		std::string defaultName = "No label given";
+		char defaultSpacer = ' ';
+		Log::NameScope scope( defaultName, defaultSpacer );
+		std::string emptyName = scope.createUniqueName( "" );
+		std::string emptyName1 = scope.createUniqueName( "" );
+
+		CHECK_EQUAL( defaultName, emptyName );
+		CHECK_EQUAL( defaultSpacer, emptyName1[ defaultName.size() ] );
+	}
+
+	TEST( NameScopeUniqueness )
+	{
+		Log::NameScope scope;
+		std::set< std::string > names;
+		int i, iterations;
+		i = iterations = 10000;
+		while( i-- )
+		{
+			names.insert( scope.createUniqueName( "UniqueName" ) );
+		}
+
+		CHECK_EQUAL( iterations, names.size() );
+	}
+
+	TEST( NameScopeNameCreation )
+	{
+		Log::NameScope scope;
+		std::string testName = "Name Scope Test Name";
+
+		CHECK( scope.createUniqueName( testName ).find( testName ) != std::string::npos );
+		CHECK( scope.createUniqueName( testName ).find( testName ) != std::string::npos );
+		CHECK( scope.createUniqueName( testName ).find( testName ) != std::string::npos );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestNamedElement.cpp b/odemx-lite/external/CppLog/src/test/src/TestNamedElement.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b1db6024581a2021b293e021e1a9144dac9c4e9e
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestNamedElement.cpp
@@ -0,0 +1,29 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestNamedElement.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/05/18
+ * @brief Unit tests for class NamedElement
+ * @since 0.1
+ */
+
+#include "global.h"
+#include <string>
+
+SUITE( CppLogUnitTest )
+{
+	TEST( NamedElementLabel )
+	{
+		std::string label = "Label Test";
+		Log::NameScope scope;
+		Log::NamedElement obj( scope, label );
+
+		CHECK_EQUAL( label , obj.getName() );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestOutputDatabaseAccessor.cpp b/odemx-lite/external/CppLog/src/test/src/TestOutputDatabaseAccessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..63da0d4f8bf5f2dd173d8c104204a6180be6dd6e
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestOutputDatabaseAccessor.cpp
@@ -0,0 +1,176 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestOutputDatabaseAccessor.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/28
+ * @brief Unit tests for class DatabaseAccessor
+ * @since 0.1
+ */
+
+#define CPPLOG_USE_DATABASE
+
+#include "../../../setup.h"
+
+#ifndef CPPLOG_USE_ODBC
+#define CPPLOG_USE_SQLITE
+
+#include "global.h"
+#include <iostream>
+
+CPPLOG_DECLARE_INFO_TYPE( TestDbInfo1, "test_db_info1", std::string )
+CPPLOG_DECLARE_INFO_TYPE( TestDbInfo2, "test_db_info2", std::size_t )
+CPPLOG_DECLARE_INFO_TYPE_LIST( TestDbInfos, TestDbInfo1, TestDbInfo2 );
+CPPLOG_DECLARE_SQL_COLUMN_TYPES( TestDbInfos, testDbSqlTypes, "VARCHAR", "INTEGER" );
+
+CPPLOG_DECLARE_INFO_TYPE( TestDbInfoKey, "id", std::size_t )
+CPPLOG_DECLARE_INFO_TYPE_LIST( TestStoreDataInfos, TestDbInfoKey, TestDbInfo1, TestDbInfo2 );
+
+SUITE( CppLogUnitTest )
+{
+	struct TestOutputDatabaseAccessorFixture
+	{
+		Log::DatabaseAccessor db;
+		std::string tableName;
+		TestOutputDatabaseAccessorFixture()
+		:	db( "TestOutputDatabaseAccessor.db" )
+		,	tableName( "TestOutputDatabaseAccessor" )
+		{}
+
+		void insertRecord( Log::Record const& rec )
+		{
+			db.insertIntoTable( tableName )
+					.columnValues< TestStoreDataInfos >( rec );
+		}
+	};
+
+	TEST_FIXTURE( TestOutputDatabaseAccessorFixture, CreateTable )
+	{
+		CHECK_THROW( db.createTable( "InvalidTableColumn" )
+				.column( "column with spaces", "VARCHAR" ), std::runtime_error );
+
+		db.createTable( tableName )
+				.column( "id", "INTEGER NOT NULL" )
+				.columns< TestDbInfos >( testDbSqlTypes )
+				.primaryKey( "id" );
+
+		CHECK( db.tableExists( tableName ) );
+	}
+
+	TEST_FIXTURE( TestOutputDatabaseAccessorFixture, InsertIntoTable )
+	{
+		bool tableExists = db.tableExists( tableName );
+		CHECK( tableExists );
+
+		if( tableExists )
+		{
+			Log::Record rec;
+			rec + TestDbInfo1( "Info1" ) + TestDbInfo2( 42 );
+
+			std::size_t key;
+			db.getMaxColumnValue( tableName, "id", key );
+			db.insertIntoTable( tableName )
+					.columnValue( "id", ++key )
+					.columnValues< TestDbInfos >( rec );
+
+			CHECK_EQUAL( 1, db.getRowCount( tableName ) );
+
+			std::size_t keyCheck = 0;
+			db.getMaxColumnValue( tableName, "id", keyCheck );
+			CHECK_EQUAL( key, keyCheck );
+
+			std::string info1Check;
+			db.getMaxColumnValue( tableName, TestDbInfo1NameHolder::getName().c_str(), info1Check );
+			CHECK_EQUAL( "Info1", info1Check );
+
+			std::size_t info2Check = 0;
+			db.getMaxColumnValue( tableName, TestDbInfo2NameHolder::getName().c_str(), info2Check );
+			CHECK_EQUAL( 42, info2Check );
+		}
+	}
+
+	TEST_FIXTURE( TestOutputDatabaseAccessorFixture, CreateInserter )
+	{
+		Log::Record rec;
+		rec + TestDbInfo1( "Info2" ) + TestDbInfo2( 43 );
+		std::size_t key = 0;
+
+		std::auto_ptr< Log::DatabaseAccessor::SqlInserter > inserter =
+				db.createInserter();
+
+		CHECK( inserter.get() != 0 );
+
+		inserter->table( tableName ).column( "id" ).columns< TestDbInfos >();
+
+		std::ostringstream os;
+		os
+		<< "INSERT INTO "
+		<< tableName
+		<< "(id,"
+		<< TestDbInfo1::getName().c_str() << ","
+		<< TestDbInfo2::getName().c_str()
+		<< ") VALUES(?,?,?)";
+
+		CHECK_EQUAL( os.str(), inserter->getSql() );
+
+		db.getMaxColumnValue( tableName, "id", key );
+		inserter->value( ++key ).values< TestDbInfos >( rec );
+
+		CHECK_EQUAL( 3, inserter->getBindingCount() );
+
+		inserter->execute();
+		CHECK( inserter->isExecuted() );
+	}
+
+	TEST_FIXTURE( TestOutputDatabaseAccessorFixture, CurrentDbTime )
+	{
+		std::string currentTime = db.getCurrentDatabaseTime();
+		CHECK( ! currentTime.empty() );
+	}
+
+	TEST_FIXTURE( TestOutputDatabaseAccessorFixture, StoreData )
+	{
+		std::size_t key;
+		db.getMaxColumnValue( tableName, "id", key );
+
+		std::vector< Log::Record > buffer;
+		buffer.push_back( Log::Record() + TestDbInfoKey( ++key )
+				+ TestDbInfo1( "test store data 1" ) + TestDbInfo2( 99 ) );
+		buffer.push_back( Log::Record()	+ TestDbInfoKey( ++key )
+				+ TestDbInfo1( "test store data 2" ) + TestDbInfo2( 100 ) );
+
+		std::size_t rowCount = db.getRowCount( tableName );
+		db.storeData( buffer,
+				std::bind( &TestOutputDatabaseAccessorFixture::insertRecord,
+						this, std::placeholders::_1 ) );
+
+		CHECK_EQUAL( rowCount + 2, db.getRowCount( tableName ) );
+	}
+
+	TEST_FIXTURE( TestOutputDatabaseAccessorFixture, LastInsertId )
+	{
+		db.createTable( "test_auto_inc_last_insert" )
+				.column( "id", "INTEGER NOT NULL" )
+				.column( "text", "VARCHAR" )
+				.primaryKey( "id" );
+
+		db.insertIntoTable( "test_auto_inc_last_insert" )
+				.columnValue( "text", "some test string" );
+
+		std::size_t generatedKey1 = db.getLastInsertId();
+
+		db.insertIntoTable( "test_auto_inc_last_insert" )
+				.columnValue( "text", "some test string" );
+
+		std::size_t generatedKey2 = db.getLastInsertId();
+
+		CHECK( generatedKey1 < generatedKey2 );
+	}
+}
+
+#endif /* ! defined CPPLOG_USE_ODBC */
diff --git a/odemx-lite/external/CppLog/src/test/src/TestOutputOStreamWriter.cpp b/odemx-lite/external/CppLog/src/test/src/TestOutputOStreamWriter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f9aeb08a30f09b67d0b330e0a03f33dd1bbc3a26
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestOutputOStreamWriter.cpp
@@ -0,0 +1,38 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestOutputOStreamWriter.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/28
+ * @brief Unit tests for class template OStreamWriter
+ * @since 0.1
+ */
+
+#include "global.h"
+
+SUITE( CppLogUnitTest )
+{
+	typedef Log::OStreamWriter< Infos > OStreamWriterType;
+	typedef std::shared_ptr< OStreamWriterType > OStreamWriterPtr;
+
+	TEST( TestOStreamWriterConsume )
+	{
+		std::ostringstream os;
+		OStreamWriterPtr osWriter = OStreamWriterType::create( os );
+
+		Point3d p3d = { 7, 8, 9 };
+		osWriter->consume( 0,
+				Log::Record( "test_ostream_writer_consume" )
+				+ StringInfo( "test_string_info" )
+				+ PointInfo( p3d ) );
+
+		CHECK( find( os.str(), "test_ostream_writer_consume" ) );
+		CHECK( find( os.str(), "test_string_info=test_string_info" ) );
+		CHECK( find( os.str(), "test_point_info=(7 8 9)" ) );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestOutputXmlFileWriter.cpp b/odemx-lite/external/CppLog/src/test/src/TestOutputXmlFileWriter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b0df8bdeb86c5e0a5c166bb64a0432e86cdedaf4
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestOutputXmlFileWriter.cpp
@@ -0,0 +1,100 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestOutputXmlFileWriter.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/28
+ * @brief Unit tests for class template XmlFileWriter
+ * @since 0.1
+ */
+
+#include "global.h"
+#include <Poco/File.h>
+
+SUITE( CppLogUnitTest )
+{
+	struct TestXmlFileWriterFixture
+	{
+		typedef Log::XmlFileWriter< Infos > XmlFileWriterType;
+		typedef std::shared_ptr< XmlFileWriterType > XmlFileWriterPtr;
+		std::string fileNameBase;
+		XmlFileWriterPtr xmlWriter;
+		TestXmlFileWriterFixture()
+		:	fileNameBase( "TestXmlFileWriter" )
+		,	xmlWriter()
+		{}
+	};
+
+	TEST_FIXTURE( TestXmlFileWriterFixture, NewFileAfterConstruction )
+	{
+		// a new file should have been opened during construction
+		xmlWriter = XmlFileWriterType::create( fileNameBase, 3 );
+		Poco::File file( fileNameBase + "_0.xml" );
+		CHECK( file.exists() );
+	}
+
+	TEST_FIXTURE( TestXmlFileWriterFixture, Consume )
+	{
+		xmlWriter = XmlFileWriterType::create(
+				fileNameBase, 3, "test_xml_file_writer", 4 );
+
+		Point3d p3d = { 1, 2, 3 };
+		xmlWriter->consume( 0,
+				Log::Record( "test_xml_file_writer_consume" )
+				+ StringInfo( "test_string_info" ) + PointInfo( p3d ) );
+		xmlWriter.reset(); // should destroy the writer and close the file
+
+		Poco::File file( fileNameBase + "_0.xml" );
+		CHECK( file.exists() );
+
+		std::ifstream is( (fileNameBase + "_0.xml").c_str(), std::ifstream::in );
+		std::string line;
+		std::getline( is, line );
+		CHECK( find( line, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" ) );
+
+		std::getline( is, line );
+		CHECK( find( line, "<test_xml_file_writer>" ) );
+
+		std::getline( is, line );
+		CHECK( find( line, "    <record>" ) );
+
+		std::getline( is, line );
+		CHECK( find( line, "        <text>test_xml_file_writer_consume</text>" ) );
+
+		std::getline( is, line );
+		CHECK( find( line, "        <test_string_info>test_string_info</test_string_info>" ) );
+
+		std::getline( is, line );
+		CHECK( find( line, "        <test_point_info>(1 2 3)</test_point_info>" ) );
+
+		std::getline( is, line );
+		CHECK( find( line, "    </record>" ) );
+
+		std::getline( is, line );
+		CHECK( find( line, "</test_xml_file_writer>" ) );
+	}
+
+	TEST_FIXTURE( TestXmlFileWriterFixture, LimitReachedStartNewFile )
+	{
+		xmlWriter = XmlFileWriterType::create(
+				fileNameBase, 3, "test_xml_file_writer", 4 );
+
+		int i = 4;
+		while( i-- )
+		{
+			Point3d p3d = { 1, 2, 3 };
+			xmlWriter->consume( 0,
+					Log::Record( "test_xml_file_writer_consume" )
+					+ StringInfo( "test_string_info" ) + PointInfo( p3d ) );
+		}
+		xmlWriter.reset(); // should destroy the writer and close the file
+
+		Poco::File file( fileNameBase + "_1.xml" );
+		CHECK( file.exists() );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestOutputXmlStreamWriter.cpp b/odemx-lite/external/CppLog/src/test/src/TestOutputXmlStreamWriter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..27c72920c4c1a4969c367726e1aac480c2ce8f5d
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestOutputXmlStreamWriter.cpp
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestOutputXmlStreamWriter.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/28
+ * @brief Unit tests for class template XmlStreamWriter
+ * @since 0.1
+ */
+
+#include "global.h"
+
+SUITE( CppLogUnitTest )
+{
+	typedef Log::XmlStreamWriter< Infos > XmlStreamWriterType;
+	typedef std::shared_ptr< XmlStreamWriterType > XmlStreamWriterPtr;
+
+	TEST( TestXmlStreamWriterConsume )
+	{
+		std::ostringstream os;
+		XmlStreamWriterPtr xmlWriter = XmlStreamWriterType::create( os, 2 );
+
+		Point3d p3d = { 4, 5, 6 };
+		xmlWriter->consume( 0,
+				Log::Record( "test_xml_stream_writer_consume" )
+				+ StringInfo( "test_string_info" )
+				+ PointInfo( p3d ) );
+
+		CHECK( find( os.str(), "  <record>" ) );
+		CHECK( find( os.str(), "    <text>test_xml_stream_writer_consume</text>" ) );
+		CHECK( find( os.str(), "    <test_string_info>test_string_info</test_string_info>" ) );
+		CHECK( find( os.str(), "    <test_point_info>(4 5 6)</test_point_info>" ) );
+		CHECK( find( os.str(), "  </record>" ) );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestOutputXmlWriter.cpp b/odemx-lite/external/CppLog/src/test/src/TestOutputXmlWriter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4d63b5d81b98b990bfeb5012bb268f561d357fb6
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestOutputXmlWriter.cpp
@@ -0,0 +1,70 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestOutputXmlWriter.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/28
+ * @brief Unit tests for class XmlWriter
+ * @since 0.1
+ */
+
+#include "global.h"
+#include <string>
+
+SUITE( CppLogUnitTest )
+{
+	TEST( TestXmlWriterStartElement )
+	{
+		std::ostringstream os;
+		Log::XmlWriter::startElement( os, 4, "test_start_element" );
+		CHECK_EQUAL( "    <test_start_element>", os.str() );
+	}
+
+	TEST( TestXmlWriterCloseElement )
+	{
+		std::ostringstream os;
+		Log::XmlWriter::closeElement( os, 4, "test_close_element" );
+		CHECK_EQUAL( "    </test_close_element>\n", os.str() );
+	}
+
+	TEST( TestXmlWriterEmptyElement )
+	{
+		std::ostringstream os;
+		Log::XmlWriter::emptyElement( os, 4, "test_empty_element" );
+		CHECK_EQUAL( "    <test_empty_element/>\n", os.str() );
+	}
+
+	TEST( TestXmlWriterWriteElement )
+	{
+		std::ostringstream os;
+		Log::XmlWriter::writeElement( os, 4, "test_write_element", 999 );
+		CHECK_EQUAL( "    <test_write_element>999</test_write_element>\n", os.str() );
+	}
+
+	TEST( TestXmlWriterWriteHeader )
+	{
+		std::ostringstream os;
+		Log::XmlWriter::writeHeader( os );
+		CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", os.str() );
+	}
+
+	struct DummyXmlWriter: Log::XmlWriter
+	{
+		using Log::XmlWriter::StreamInfoElements;
+	};
+
+	TEST( TestXmlWriterStreamInfoElements )
+	{
+		std::ostringstream os;
+		DummyXmlWriter::StreamInfoElements writer( os, 2 );
+		writer( "test_stream_info_elements_value", 111, true );
+		writer( "test_stream_info_elements_empty", 111, false );
+		CHECK_EQUAL( "  <test_stream_info_elements_value>111</test_stream_info_elements_value>\n"
+				"  <test_stream_info_elements_empty/>\n", os.str() );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestProducer.cpp b/odemx-lite/external/CppLog/src/test/src/TestProducer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f4b7775de0b277c46294aaaefada413a1a0608d7
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestProducer.cpp
@@ -0,0 +1,64 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestProducer.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/05/17
+ * @brief Unit tests for class template DataProducer
+ * @since 0.1
+ */
+
+#include "global.h"
+#include <string>
+
+CPPLOG_DECLARE_CHANNEL_WITH_ID( test, channel_one, int, 0 );
+CPPLOG_DECLARE_CHANNEL_WITH_ID( test, channel_two, int, 1 );
+
+typedef Log::Producer< Log::Enable< test::channel_one, test::channel_two > > ProducerType;
+
+SUITE( CppLogUnitTest )
+{
+	struct Producer: ProducerType
+	{
+		typedef std::shared_ptr< Log::Channel< int > > ChannelPtr;
+		
+		Producer( Log::NameScope& scope, std::string const& name )
+		:	ProducerType( scope, name )
+		{}
+		Producer( Log::ChannelManager< int >& scope, std::string const& name )
+		:	ProducerType( scope, name )
+		{}
+		ChannelPtr getChannelOne()
+		{
+			return channel_one;
+		}
+		ChannelPtr getChannelTwo()
+		{
+			return channel_two;
+		}
+	};
+	
+	TEST( ProducerName )
+	{
+		Log::NameScope scope;
+		Log::ChannelManager< int > manager;
+		std::string name( "Test Producer" );
+		Producer producer1( scope, name );
+		Producer producer2( manager, name );
+		CHECK_EQUAL( name, producer1.getName() );
+		CHECK_EQUAL( name, producer2.getName() );
+	}
+
+	TEST( ProducerChannelMemberInit )
+	{
+		Log::ChannelManager< int > manager;
+		Producer producer( manager, "Test Producer" );
+		CHECK( producer.getChannelOne() );
+		CHECK( producer.getChannelTwo() );
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/TestRecord.cpp b/odemx-lite/external/CppLog/src/test/src/TestRecord.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f5ef56bb434ebc402726dc0f80f7cd4824d561dc
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/TestRecord.cpp
@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file TestRecord.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/05/29
+ * @brief Unit tests for class Record
+ * @since 0.1
+ */
+
+#include "global.h"
+#include <string>
+#include <iostream>
+
+CPPLOG_DECLARE_INFO_TYPE( TestInfo, "test info", char );
+
+SUITE( CppLogUnitTest )
+{
+	TEST( RecordText )
+	{
+		Log::StringLiteral message = "Log record test message";
+		Log::Record rec( message );
+		CHECK_EQUAL( message, rec.getText() );
+	}
+
+	TEST( RecordInfo )
+	{
+		Log::Record rec;
+		Log::StringLiteral f = __FILE__;
+		int l = __LINE__;
+		Log::StringLiteral s = "TestRecordInfo";
+		
+		rec.file( f ).line( l ).scope( s );
+		CHECK( rec.get< Log::FileInfo >() );
+		CHECK( rec.get< Log::LineInfo >() );
+		CHECK( rec.get< Log::ScopeInfo >() );
+		CHECK_EQUAL( f, *rec.get< Log::FileInfo >() );
+		CHECK_EQUAL( l, *rec.get< Log::LineInfo >() );
+		CHECK_EQUAL( s, *rec.get< Log::ScopeInfo >() );
+		CHECK_EQUAL( (void*)0, rec.get< TestInfo >() );
+/*		
+		char c = 'X';
+		rec + TestInfo( c );
+		CHECK( rec.get< TestInfo >() );
+		CHECK_EQUAL( c, *rec.get< TestInfo >() );*/
+	}
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/global.cpp b/odemx-lite/external/CppLog/src/test/src/global.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..089d1702733d0ef3e6bf6b827a75a305bc299dff
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/global.cpp
@@ -0,0 +1,31 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file global.cpp
+ * @date created at 2010/04/28
+ * @author Ronald Kluth
+ * @brief Implementation of global components used for testing
+ */
+
+#include "global.h"
+
+namespace SuiteCppLogUnitTest {
+
+std::ostream& operator<<( std::ostream& os, Point3d const& p )
+{
+	os << "(" << p.x << " " << p.y << " " << p.z << ")";
+	return os;
+}
+
+bool find( std::string const& str, std::string const& seq )
+{
+	std::size_t found = str.find( seq );
+	return found != std::string::npos;
+}
+
+}
diff --git a/odemx-lite/external/CppLog/src/test/src/global.h b/odemx-lite/external/CppLog/src/test/src/global.h
new file mode 100644
index 0000000000000000000000000000000000000000..90d78d50eeddf576b38bf154b674e6701071d4d3
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/global.h
@@ -0,0 +1,38 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file global.h
+ * @date created at 2010/04/28
+ * @author Ronald Kluth
+ * @brief Declaration of global components used for testing
+ */
+
+#ifndef CPPLOGTEST_GLOBAL_INCLUDED
+#define CPPLOGTEST_GLOBAL_INCLUDED
+
+#include <UnitTest++.h>
+#include <CppLog.h>
+
+namespace SuiteCppLogUnitTest {
+
+struct Point3d
+{
+	float x, y, z;
+};
+
+extern std::ostream& operator<<( std::ostream& os, Point3d const& p );
+
+CPPLOG_DECLARE_INFO_TYPE( StringInfo, "test_string_info", std::string );
+CPPLOG_DECLARE_INFO_TYPE( PointInfo, "test_point_info", Point3d );
+CPPLOG_DECLARE_INFO_TYPE_LIST( Infos, StringInfo, PointInfo );
+
+extern bool find( std::string const& str, std::string const& seq );
+
+} // namespace CppLogUnitTest
+
+#endif /* CPPLOGTEST_GLOBAL_INCLUDED */
diff --git a/odemx-lite/external/CppLog/src/test/src/main.cpp b/odemx-lite/external/CppLog/src/test/src/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..904e2f68e933d990f75ab441a6e937254a342620
--- /dev/null
+++ b/odemx-lite/external/CppLog/src/test/src/main.cpp
@@ -0,0 +1,27 @@
+//
+// Copyright (c) 2010 Ronald Kluth
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * @file global.cpp
+ * @date created at 2010/04/28
+ * @author Ronald Kluth
+ * @brief Implementation of global components used for testing
+ */
+
+#include <UnitTest++.h>
+
+/**
+ * @brief This is the main function for the test runner application
+ *
+ * The function automatically runs all registered test suites.
+ * and returns the value of UnitTest::RunAllTests(), which states
+ * how many tests have failed during execution.
+ */
+int main()
+{
+	return UnitTest::RunAllTests();
+}
diff --git a/odemx-lite/include/odemx/base/Comparators.h b/odemx-lite/include/odemx/base/Comparators.h
new file mode 100644
index 0000000000000000000000000000000000000000..b1d7842881de89c891c96a1a2a72aac42d6edda2
--- /dev/null
+++ b/odemx-lite/include/odemx/base/Comparators.h
@@ -0,0 +1,81 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Comparators.h
+ * @author Ronald Kluth
+ * @date created at 2009/02/23
+ * @brief Declaration of odemx::base::DefaultCmp and odemx::base::QPriorityCmp
+ * @sa Comparators.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_BASE_COMPARATORS_INCLUDED
+#define ODEMX_BASE_COMPARATORS_INCLUDED
+
+namespace odemx {
+namespace base {
+
+// forward declarations
+class Sched;
+class Process;
+
+/** \struct DefaultCmp
+
+	\author Ronald Kluth
+
+	\brief DefaultCmp is used for ordering objects in std::list<>
+
+	\sa ListInSort, QPriorityCmp
+*/
+struct DefaultCmp
+{
+	bool operator()( const Sched* s1, const Sched* s2 ) const;
+};
+
+/** 
+	\var defCmp
+	\author Ronald Kluth
+	\brief defCmp is a callable object of type DefaultCmp.
+ */
+extern DefaultCmp defCmp;
+
+/** \struct QPriorityCmp
+
+	\author Ronald Kluth
+
+	\brief QPriorityCmp is used for ordering objects in std::list<>
+
+	\sa ListInSort, DefaultCmp
+*/
+struct QPriorityCmp
+{
+	bool operator()( const Process* p1, const Process* p2 ) const;
+};
+
+
+/** 
+	\var qPrioCmp
+	\author Ronald Kluth
+	\brief qPrioCmp is a callable object of type QPriorityCmp.
+ */
+extern QPriorityCmp qPrioCmp;
+
+} } // namespace odemx::base
+
+#endif /* ODEMX_BASE_COMPARATORS_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/Continuous.h b/odemx-lite/include/odemx/base/Continuous.h
new file mode 100644
index 0000000000000000000000000000000000000000..512f9afbaff519279f5444420b4601d01348e069
--- /dev/null
+++ b/odemx-lite/include/odemx/base/Continuous.h
@@ -0,0 +1,459 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2003, 2004, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file base/Continuous.h
+ * @author Ralf Gerstenberger
+ * @date created at 2003/06/15
+ * @brief Declaration of odemx::base::Continuous, its observer, and odemx::base::ContuTrace
+ * @sa Continuous.cpp
+ * @since 1.0
+ */
+
+#ifndef ODEMX_BASE_CONTINUOUS_INCLUDED
+#define ODEMX_BASE_CONTINUOUS_INCLUDED
+
+#include <odemx/setup.h>
+
+// usage of this class requires SimTime type double,
+// which can be switched at compile time by defining
+// ODEMX_USE_CONTINUOUS in file odemx/setup.h
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <odemx/base/Process.h>
+#include <odemx/base/TypeDefs.h>
+
+#include <string>
+#include <vector>
+#include <list>
+
+namespace odemx {
+namespace base {
+
+// forward declaration
+class ContinuousObserver;
+
+/** \class Continuous
+
+	\ingroup base
+
+	\author Ralf Gerstenberger
+
+	\brief Time continuous process
+
+	\note %Continuous supports Observation.
+	\note %Continuous supports Trace.
+
+	\sa Process
+
+	%Continuous is a base class for all user defined time continuous
+	processes. It provides functionality of Process and introduces
+	the possibility to define time continuous processes. A user has
+	to implement the derivatives() function to define the time
+	continuous state changes. The function integrate() computes
+	the time continuous state changes.
+
+	\par Example:
+	\include continuousProcesses.cpp
+
+	\since 1.0
+*/
+class Continuous
+:	public Process // is DataProducer, etc.
+,	public data::Observable< ContinuousObserver >
+{
+public:
+
+	/**
+		\brief Construction for user-defined Simulation
+		\param s
+			pointer to the Simulation object
+		\param l
+			label of this object
+		\param d
+			number of state variables used in derivatives()
+		\param o
+			initial observer
+	*/
+	Continuous( Simulation& sim, const data::Label& label, int dimension,
+			ContinuousObserver* o = 0 );
+
+	/// Destruction
+	virtual ~Continuous();
+
+	/**
+		\brief Interrupt
+
+		If a %Continuous process is interrupted inside integrate()
+		the computation is not synchronised to the time of the
+		interrupt. There might be an error depending on the step length.
+		This can be prevented if the process that caused the
+		interrupt is registered as a peer to the continuous process.
+
+		\sa Process::interrupt
+	*/
+	virtual void interrupt();
+
+	/**
+		\brief Get number of state variables
+
+		%getDimension() returns the number of state variables specified
+		in the constructor. No more than the specified state variables
+		may me used in derivatives(). The state variables are stored in
+		the STL vector state.
+	*/
+	unsigned int getDimension() const;
+
+	/**
+		\brief Set minimum and maximum step length
+
+		\param min
+			minimum step length
+		\param max
+			maximum step length
+
+		The integrate() function computes state changes step by step.
+		The step length used is variable depending on numerical	errors,
+		state events and registered peer processes. With %setStepLength()
+		the user can choose boundaries for the step length according to
+		the needed accuracy.
+
+		\sa integrate(), addPeer()
+
+	*/
+	void setStepLength( double min, double max );
+
+	/**
+		\brief Get current step length
+
+		The integrate() function computes state changes step by step.
+		The step length used is variable depending on numerical	errors,
+		state events and registered peer processes. %getStepLength()
+		returns the current step length.
+
+		 \sa integrate()
+	*/
+	double getStepLength() const;
+
+	/**
+		\brief Set errorlimit
+
+		\param type
+			error type: 1 for relative error; 0 for absolute error
+		\param limit
+			error limit
+
+		The integrate() function computes state changes step by step.
+		The step length used does depend on the numerical error during
+		computation. With %setErrorlimit() the user can set the highest
+		acceptable error. If the actual error is higher the step length
+		is reduced. \n
+		The limit can be set absolute or relative. In the second case the
+		limit is interpreted relative to the actual state values.
+
+		\sa integrate()
+
+	*/
+	void setErrorlimit( int type, double limit );
+
+	/**
+		\brief Add a partner process
+
+		\param p
+			pointer to Process object
+
+		The integrate() function computes state changes step by step. The
+		next state value is computed in advance to the time consumption.
+		If another process is accessing the state variables during the
+		time consumption it receives wrong values. The step length however
+		is variable and can be changed to synchronise computation with
+		partner Processes. The function  %addPeer() is used to register
+		partner Processes for synchronisation.
+
+		\note
+		A peer must have a higher priority than its	continuous partner
+		to interact properly. To support this a continuous process
+		reduces its priority by one inside integrate(). A peer has to
+		ensure that its priority is at least as high as the priority of
+		the continuous process.
+
+		\sa integrate(), delPeer()
+	*/
+	void addPeer( Process* newPeer );
+
+	/**
+		\brief Remove a peer
+
+		\param p
+			pointer to Process object
+
+		Removes a registered partner process.
+
+		\sa addPeer()
+	*/
+	void delPeer( Process* newPeer );
+
+	/**
+		\brief State variables
+
+		The \c state variables used during time continuous state changes
+		are stored in this STL vector. A process which is accessing
+		this variables directly should be registered with addPeer().
+
+		\sa integrate(), derivatives(), addPeer()
+	*/
+	std::vector< double > state;
+
+	/**
+		\brief Rate variables
+
+		The STL vector \c rate is used for the computation	of time continuous
+		state changes. The state variables are not changed directly. In
+		derivatives() the user sets the rate by witch each state variable
+		is changed.
+
+		\sa integrate(), derivatives()
+	*/
+	std::vector< double > rate;
+
+	/**
+		\brief Error vector
+
+		The step by step computation of time continuous state changes
+		introduces an inherent error. This error is computed for every state
+		variable independently. \c error_vector is used to store the error
+		values. The virtual function errorNorm() is called to compute a
+		single error value from this vector which is stored in \c error_value.
+
+		\sa integrate(), errorNorm(), error_value
+	*/
+	std::vector< double > error_vector;
+
+	/**
+		\brief Error
+
+		The step by step computation of time continuous state changes
+		introduces an inherent error. This error is computed for every state
+		variable independently. The function errorNorm() is used to compute
+		a single error value from the vector of error values which is stored
+		in \c error_value.
+
+		\sa integrate(), errorNorm()
+	*/
+	double error_value;
+
+protected:
+	/**
+		\brief User defined process behaviour
+
+		This function is implemented by the user to	define the process
+		behaviour.
+
+		\sa Process::main()
+	*/
+	virtual int main() = 0;
+
+	/**
+		\brief User defined continuous behaviour
+
+		\param t
+			time
+
+		The user has to implement the function %derivatives() to define
+		the time continuous state changes. This is done indirectly by
+		setting the rate by witch each state variable changes. The function
+		is called by integrate() several times for each step.
+
+		\dontinclude continuousExample.cpp
+		\par Example Oscillator
+		The %derivatives() function describes a simple sin/cos oscillator.
+		The two rate variables depend only on the two state variables:
+		\skipline virtual void derivatives (double t) {
+		\until }
+
+		\par Example FreeFall
+		This %derivatives() function uses the provided parameter \p t
+		to include the current time in the computation:
+		\skipline virtual void derivatives (double t) {
+		\until }
+
+		\note
+		If the time is required for the computation of the rates the
+		prameter \p t has to be used instead of getCurrentTime().
+
+		\sa integrate(), rate, state
+	*/
+    virtual void derivatives( double t ) = 0;
+
+	/**
+		\brief Computation of time continuous state changes
+
+		\param timeEvent
+			time limit for integration (0->infinite)
+		\param stateEvent
+			state event that stops integration by returning true (member call-back-function)
+		\return 0 if timeEvent hit; 1 if stateEvent hit;
+				2 if interrupted
+
+		The function %integrate() computes time continuous state changes
+		using the Runge-Kutta algorithm. The computation is stopped when
+		the time \p timeEvent is reached, the state event occurred or
+		the interrupt() function was called. \n
+		The computation is done step by step with a varying step length. The
+		actual step length depends on computation errors, registered peers
+		and the stop time (\p timeEvent). The user can set boundaries to
+		the step length with the function setStepLength(). The default
+		values used by integrate are 0.01 and 0.1 for minimum and maximum.
+		\n
+		The step by step computation of time continuous processes introduces
+		an inherent error. integrate() observes the computational errors for
+		each state variable. The function errorNorm() is called to compute
+		a single value from all error values. The user can use the function
+		setErrorlimit() to specify the largest acceptable error. If the single
+		value computed by errorNorm() exceeds the acceptable error %integrate()
+		tries to reduce the step length. This fails if the resulting step
+		length would be smaller than the minimum step length set with setStepLength().
+		The default error limit is an absolute error of 0.1.
+		\n
+		If during the computation a state event occurred, integrate() starts
+		a binary search to find the exact time of the event. The minimum
+		step length set by setStepLength() defines the accuracy of this
+		search.
+		\n
+		%integrate() synchronises computation with partner processes. A process
+		is registered as a partner with the function addPeer().
+
+		\sa derivatives(), setStepLength(), setErrorlimit(), errorNorm(), addPeer() and
+			state
+	*/
+	int integrate( SimTime timeEvent, Condition stateEvent = 0 );
+
+protected:
+	// Dimension
+	int dimension; // highest index
+
+	// integrations steps
+	double stepLength;
+	double maxStepLength, minStepLength;
+
+	// integration time
+	double time;
+
+	// solver error handling
+	int relative;
+	double errorLimit;
+
+	/**
+		\brief Compute error
+
+		\return single error value
+
+		This function is called to compute a single error value
+		from the error_vector. The default implementation returns
+		the largest error(). A user can overwrite this function to
+		use another error norm.
+
+		\sa error, error_value and integrate()
+	*/
+	virtual double errorNorm();
+
+	// solver
+	int stopped;
+
+	std::vector<double> initial_state;
+	std::vector<double> slope_1;
+	std::vector<double> slope_2;
+	std::vector<double> slope_3;
+
+	int reduce();
+	void binSearch();
+	virtual void takeAStep(double h);
+
+	// stop condition
+	bool stopIntegrate();
+	SimTime stopTime;
+	Condition stopCond;
+
+	// peers
+	ProcessList peers;
+};
+
+/** \interface ContinuousObserver
+
+	\author Ralf Gerstenberger
+
+	\brief Observer for Continuous specific events
+
+	\sa Continuous
+
+	\since 1.0
+*/
+class ContinuousObserver:
+	public ProcessObserver
+{
+public:
+//	virtual void onCreate( Continuous* sender ) {} ///< Construction
+
+	virtual void onAddPeer( Continuous* sender, Process* peer ) {} ///< Add peer
+	virtual void onRemovePeer( Continuous* sender, Process* peer ) {} ///< Remove peer
+
+	virtual void onBeginIntegrate( Continuous* sender ) {} ///< Begin integrate
+	virtual void onEndIntegrate( Continuous* sender, int result ) {} ///< End integrate
+
+	virtual void onNewValidState( Continuous* sender ) {} ///< New valid state
+};
+
+/** \class ContuTrace
+
+	\author Ralf Gerstenberger
+
+	\brief Trace for Continuous state changes
+
+	\sa Continuous ContinuousObserver
+
+	ContuTrace logs the state changes of a Continuous object
+	into a text file. The text file is automatically opened
+	and closed.
+
+	\since 1.0
+*/
+class ContuTrace
+:	public ContinuousObserver
+{
+public:
+	/// Construction
+	ContuTrace( Continuous* contu = 0, const std::string& fileName = "" );
+	/// Destruction
+	virtual ~ContuTrace();
+
+	/// Follow state changes
+	virtual void onNewValidState( Continuous* sender );
+
+private:
+	// Implementation
+	std::ostream* out;
+	bool firstTime;
+
+	void openFile( const std::string& fileName );
+};
+
+} } // namespace odemx::base
+
+#endif /* ODEMX_USE_CONTINUOUS */
+
+#endif /* ODEMX_BASE_CONTINUOUS_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/DefaultSimulation.h b/odemx-lite/include/odemx/base/DefaultSimulation.h
new file mode 100644
index 0000000000000000000000000000000000000000..02fad318a8817224881c760cd8b30da632aae4da
--- /dev/null
+++ b/odemx-lite/include/odemx/base/DefaultSimulation.h
@@ -0,0 +1,93 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file DefaultSimulation.h
+ * @author Ronald Kluth
+ * @date created at 2009/02/07
+ * @brief Declaration of class DefaultSimulation and getDefaultSimulation
+ * @sa DefaultSimulation.cpp, Simulation.h, Simulation.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DEFAULTSIMULATION_INCLUDED
+#define ODEMX_DEFAULTSIMULATION_INCLUDED
+
+#include <odemx/base/Simulation.h>
+
+namespace odemx {
+
+/**
+	@brief Get the DefaultSimulation
+	@return	Reference to the DefaultSimulation object
+
+	The first time getDefaultSimulation() is called, an
+	object of type DefaultSimulation is created and returned.
+	All following calls to getDefaultSimulation() also return
+	this object.
+
+	@note The reference returned by this function refers to a static object.
+	DefaultSimulation access is basically implemented like a Meyers singleton.
+
+	@see DefaultSimulation
+*/
+extern base::Simulation& getDefaultSimulation();
+
+namespace base {
+
+/** \class DefaultSimulation
+
+	\author Ralf Gerstenberger
+
+	\brief A default implementation of Simulation provided for convenience.
+
+	The %DefaultSimulation is provided for convenience. You can
+	use this simulation if you don't want to define your own. Use
+	getDefaultSimulation() to get a pointer to a %DefaultSimulation
+	object. Instead of \p init(), the \p main function of your simulation
+	program will be required to initialize all necessary objects for
+	the start of the simulation.
+
+	\since 1.0
+*/
+class DefaultSimulation
+:	public Simulation
+{
+private:
+
+	friend Simulation& odemx::getDefaultSimulation();
+
+	/**
+		\brief Construction
+
+		Use odemx::getDefaultSimulation() to get an object of %DefaultSimulation.
+
+		\sa odemx::getDefaultSimulation()
+	*/
+	DefaultSimulation();
+
+	/// private Destructor to prevent delete calls
+	~DefaultSimulation();
+
+protected:
+	virtual void initSimulation();
+};
+
+} } // namespace odemx::base
+
+#endif /*ODEMX_DEFAULTSIMULATION_INCLUDED*/
diff --git a/odemx-lite/include/odemx/base/Event.h b/odemx-lite/include/odemx/base/Event.h
new file mode 100644
index 0000000000000000000000000000000000000000..c47eb81ac9268e2a0a7bacd509f0b52a95786b3c
--- /dev/null
+++ b/odemx-lite/include/odemx/base/Event.h
@@ -0,0 +1,343 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2007, 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Event.h
+ * @author Ronald Kluth
+ * @date created at 2007/04/04
+ * @brief Declaration of odemx::base::Event and observer
+ * @sa Event.cpp
+ * @since 2.0
+ */
+
+#ifndef ODEMX_BASE_EVENT_INCLUDED
+#define ODEMX_BASE_EVENT_INCLUDED
+
+#include <odemx/base/Sched.h>
+#include <odemx/data/Observable.h>
+#include <odemx/util/attributes.h>
+
+namespace odemx {
+namespace base {
+
+// forward declaration
+class Simulation;
+class EventObserver;
+
+/** \class Event
+
+	\ingroup base
+
+	\author Ronald Kluth
+
+	\brief %Event is the base class for all user-defined events in a model.
+
+	\note %Event supports Observation.
+	\note %Event supports Trace.
+
+	\sa Process, Simulation
+
+	%Event is the base class for all user defined events in a model. Events,
+	unlike processes do not have a life cycle consisting of a chain of actions.
+	An event is a single action that changes the state of the system model.
+	It can, however be executed more than once.	A user
+	creates a derived class for every different type of event of their model.
+	In their own classes users have to provide the event action by implementing
+	the eventAction() method. The event action is executed according to an
+	execution schedule (ExecutionList) at a certain point in simulation time.
+	If multiple scheduled objects share the same execution time, the order of
+	execution is defined by	the way	the processes and/or events have been
+	scheduled. These objects can be scheduled with respect to their priority
+	First-In-First-Out or Last-In-First-Out at a point in time.
+
+	\since 2.0
+*/
+class Event
+:	public Sched // is DataProducer, etc.
+,	public data::Observable< EventObserver >
+{
+public:
+
+	/**
+		\brief Construction for user-defined Simulation
+		\param sim
+			Reference to the simulation object
+		\param label
+			Label of this object
+		\param obs
+			Initial observer
+	*/
+	Event( Simulation& sim, const data::Label& label, EventObserver* obs = 0 );
+
+	/// Destruction
+	virtual ~Event();
+
+
+	/**
+		\name Event Scheduling
+
+		These functions are used to schedule a simulation event
+		in simulation time. Events and processes are kept in one
+		schedule and follow the same scheduling rules.
+
+		@{
+	*/
+	/**
+		\brief Trigger the event at current simulation time
+
+		This function schedules the event at the current time before
+		all other processes and events with the same priority (LIFO). Unlike
+		high-priority processes, scheduling high-priority events at
+		SimTime now will not suspend the execution of the current process
+		- the process can either finish or reschedule itself, after which
+		the event will then be triggered.
+	*/
+	void schedule();
+
+	/**
+		\brief Trigger the event in (relative) time \p t
+		\param t
+			delay for activation
+
+		This function schedules the event at the simtime \c now + \p t
+		before all other processes with the same priority (LIFO). If
+		\p t is 0 this function is equal to schedule().
+
+		\sa schedule()
+	*/
+	void scheduleIn( SimTime t );
+
+	/**
+		\brief Trigger the event at (absolute) time \p t
+		\param t
+			time for activation
+
+		This function schedules the event at the simtime \p t
+		before all other processes with the same priority (LIFO). If
+		\p t is \c now this function is equal to schedule().
+
+		\sa schedule()
+	*/
+	void scheduleAt( SimTime t ); // schedule at absolute simulation time t
+
+	/**
+		\brief Trigger the event at current simulation time (FIFO)
+
+		This function schedules the event at the current time
+		after all other scheduled objects with the same priority.
+	*/
+	void scheduleAppend();
+
+	/**
+		\brief Trigger the event in (relative) time \p t (FIFO)
+
+		This function schedules the event at the time \c now + \p t
+		after all other scheduled objects with the same priority. If \p t
+		is 0 this function is equal to scheduleAppend().
+
+		\sa scheduleAppend()
+	*/
+	void scheduleAppendIn( SimTime t );
+
+	/**
+		\brief Trigger the event at (absolute) time \p t (FIFO)
+
+		This function schedules the event at simtime \p t
+		after all other scheduled objects with the same priority. If \p t
+		is \c now this function is equal to scheduleAppend().
+
+		\sa scheduleAppend()
+	*/
+	void scheduleAppendAt( SimTime t );
+
+	/**
+		\brief Remove the event from the execution list
+
+		This function finds this event in the execution list
+		and deletes the entry.
+	*/
+	void removeFromSchedule();
+	//@}
+
+	/**
+		\name Priority
+
+		These functions can be used to adjust the priority of the event.
+		A priority change causes an update of the execution list as scheduled
+		objects may switch positions. By default, events have the same
+		priority as processes.
+
+		@{
+	*/
+	/**
+		\brief Get priority
+		\return
+			event priority
+
+		This function returns the current event priority.
+	*/
+	virtual Priority getPriority() const;
+
+	/**
+		\brief Set new priority
+		\return
+			previous event priority
+
+		This function changes the event priority. The position
+		in the execution schedule and in queues is affected by
+		priority changes.
+	*/
+	virtual Priority setPriority( Priority newPriority );
+	//@}
+
+	/**
+		\name Execution Time
+
+		@{
+	*/
+	/**
+		\brief Get execution time
+		\return
+			execution time; 0 if the event is not scheduled
+
+		This function returns the execution time of the event.
+		An event is scheduled to be triggered at its execution time.
+	*/
+	SimTime getExecutionTime() const;
+	//@}
+
+	/**
+		\name Current System State
+
+		@{
+	*/
+	/**
+		\brief Get current simulation time
+		\deprecated substituted by Sched::getTime ()
+		\return
+			current simulation time
+
+		This function returns the current simulation time.
+	*/
+	DEPRECATED(SimTime getCurrentTime());
+	//@}
+
+	/** \cond PLEASE_DELETE_THIS_AND_CLOSE_#41
+		\brief Get pointer to Trace
+		\return
+			pointer to Trace object
+	*/
+	//virtual data::Trace* getTrace() const;
+	// \endcond
+
+protected:
+	/**
+		\brief User defined event action
+
+		This function must be implemented by the user to define the
+		action the event triggers. It is executed by ODEMx when the event
+		becomes the first, i.e. current, element in the schedule.
+		If a scheduling	function is called (directly or indirectly,
+		on itself or another process/event) the eventAction() function will still
+		finish, unlike processes, which would then be suspended.
+		The sequence in which different	processes and events are executed
+		is determined by the execution schedule.
+
+		\sa Process Scheduling
+	*/
+	virtual void eventAction() = 0;
+
+private:
+
+	friend class ExecutionList;
+
+	/**
+		\brief Set execution time
+		\return
+			previous execution time
+
+	 	This function is used by the library. Don't
+		call it directly! Use the scheduling functions
+		instead.
+	*/
+	SimTime setExecutionTime( SimTime time );
+
+	friend class Simulation;
+
+	/**
+		\brief Execution of this event
+
+		This function is used by the library. Don't
+		call it directly! The execution is managed
+		by the scheduling mechanism.
+	*/
+	void execute();
+
+private:
+
+	SimTime executionTime_;		///< simulation time of next event execution
+	Priority priority_;		///< priority for scheduling
+
+	/**
+		\brief Get currently running Sched object or simulation
+		\return
+			pointer to simulation or current Sched object
+	*/
+	const data::Label& getPartner();
+};
+
+/** \interface EventObserver
+
+	\author Ronald Kluth
+
+	\brief Observer for Event-specific calls.
+
+	\sa Event
+
+	\since 2.0
+*/
+class EventObserver
+{
+public:
+	virtual ~EventObserver() {}
+
+	virtual void onCreate( Event* sender ) {} ///< Construction
+
+	/// Activation (LIFO)
+	virtual void onSchedule( Event* sender ) {} ///< Immediate triggering
+	virtual void onScheduleAt( Event* sender, SimTime t ) {} ///< Trigger at
+	virtual void onScheduleIn( Event* sender, SimTime t ) {} ///< Trigger in
+
+	/// Activation (FIFO)
+	virtual void onScheduleAppend( Event* sender ) {} ///< Hold Triggering
+	virtual void onScheduleAppendAt( Event* sender, SimTime t ) {} ///< Hold triggering at
+	virtual void onScheduleAppendIn( Event* sender, SimTime t ) {} ///< Hold triggering in
+
+	/// Removal / Execution
+	virtual void onRemoveFromSchedule( Event* sender ) {} ///< Event de-scheduled
+	virtual void onExecuteEvent( Event* sender ) {} ///< Event executed
+
+	/// Event priority change
+	virtual void onChangePriority( Event* sender, Priority oldPriority, Priority newPriority ) {}
+	/// Event execution time change
+	virtual void onChangeExecutionTime( Event* sender, SimTime oldExecutionTime, SimTime newExecutionTime ) {}
+};
+
+} } // namespace odemx::base
+
+#endif /* ODEMX_BASE_EVENT_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/ExecutionList.h b/odemx-lite/include/odemx/base/ExecutionList.h
new file mode 100644
index 0000000000000000000000000000000000000000..7863210346b61659fa49ac0786fc0e74ded3d913
--- /dev/null
+++ b/odemx-lite/include/odemx/base/ExecutionList.h
@@ -0,0 +1,216 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ExecutionList.h
+ * @author Ralf Gerstenberger
+ * @date created at 2002/01/23
+ * @brief Declaration of odemx::base::ExecutionList
+ * @sa ExecutionList.cpp
+ * @since 1.0
+ */
+
+#ifndef ODEMX_EXECUTIONLIST_INCLUDED
+#define ODEMX_EXECUTIONLIST_INCLUDED
+
+#include <odemx/base/SimTime.h>
+#include <odemx/base/TypeDefs.h>
+#include <odemx/data/Label.h>
+#include <odemx/data/Producer.h>
+#include <odemx/data/Observable.h>
+#include <CppLog/Channel.h>
+
+namespace odemx {
+
+namespace data { class SimRecord; }
+
+namespace base {
+
+// forward declarations
+class Scheduler;
+class Simulation;
+
+typedef std::shared_ptr< Log::Channel< data::SimRecord > > ChannelPtr;
+
+/** \class ExecutionList
+
+	\ingroup base
+
+	\author Ralf Gerstenberger
+
+	\brief ExecutionList implements an execution schedule for Sched objects.
+
+	\note ExecutionList supports Observation.
+
+	ExecutionList is used to manage the Sched execution order. A Sched object
+	is scheduled at a given time considering its priority and a FIFO- or LIFO-
+	strategy, or in relation to an already scheduled object.
+
+	\since 1.0
+*/
+class ExecutionList
+:	public data::Producer
+{
+public:
+	/// Construction with Simulation
+	ExecutionList( Simulation& sim, const data::Label& label );
+
+	/// Destruction
+	virtual ~ExecutionList();
+
+	/**
+		\brief Print the schedule
+
+		This function prints a simple representation of the
+		execution list to stdout.
+	*/
+	void logToChannel( const ChannelPtr channel ) const;
+
+	/**
+		\name Sched Management
+
+		@{
+	*/
+	/**
+		\brief append Sched
+
+		\param p
+			pointer to Sched
+
+		Appends Sched \p p at its execution time.
+		If there are already Sched objects scheduled at
+		the execution time of \p p, addSched will consider
+		the priorities and use the FIFO strategy.
+
+		\sa insertSched
+	*/
+	void addSched( Sched* s );
+
+	/**
+		\brief insert Sched
+
+		\param p
+			pointer to Sched
+
+		Inserts Sched \p p at its execution time.
+		If there are already Sched objects scheduled at
+		the execution time of \p p, insertSched will consider
+		the priorities and use the LIFO strategy.
+
+		\sa addSched
+	*/
+	void insertSched( Sched* s );
+
+	/**
+		\brief insert Sched \p p after \p previous
+
+		\param p
+			pointer to new Sched object
+
+		\param previous
+			pointer to Sched object after which the new Sched
+			should be inserted
+
+		Inserts Sched \p p after the \p previous Sched object
+		in ExecutionList.
+
+		\note insertSchedAfter will change the priority of
+		Sched \p p if necessary.
+
+		\sa insertSchedBefore
+	*/
+	void insertSchedAfter( Sched* s, Sched* partner );
+
+	/**
+		\brief insert Sched \p p before \p next
+
+		\param p
+			pointer to new Sched
+
+		\param next
+			pointer to Sched before which the new Sched
+			should be inserted
+
+		Inserts Sched \p p before the \p next Sched
+		in ExecutionList.
+
+		\note insertSchedBefore will change the priority of
+		Sched \p p if necessary.
+
+		\sa insertSchedAfter
+	*/
+	void insertSchedBefore( Sched* s, Sched* partner );
+
+	/**
+		\brief remove Sched
+
+		Removes Sched \p p from ExecutionList.
+	*/
+	void removeSched( Sched* s );
+	//@}
+
+	/**
+		\brief top most Sched in ExecutionList
+
+		\return
+			pointer to top most Sched in ExecutionList
+	*/
+	Sched* getNextSched() const;
+
+	/**
+	 * @brief Get the execution time of the first schedule entry
+	 * @return 0 if schedule is empty
+	 */
+	SimTime getNextExecutionTime() const;
+
+	/**
+		\brief check if ExecutionList is empty
+	*/
+	bool isEmpty() const;
+
+	/**
+		\brief get simulation time
+
+		\return
+			current simulation time
+	*/
+	SimTime getTime();
+
+	// Implementation
+private:
+	/// Map type to associate simulation times with lists of scheduled objects
+	typedef std::map< SimTime, SchedList > Schedule;
+	/// Actual schedule holding pointers to Sched objects sorted by time and priority
+	Schedule schedule_;
+
+	friend class Scheduler;
+	/**
+		\brief inSort Sched \p e in Sched list
+
+		\param e
+			pointer to Sched
+
+		\param fifo
+			use FIFO or LIFO strategy for inSort
+	*/
+	void inSort( Sched* s, bool fifo = true );
+};
+
+} } // namespace odemx::base
+
+#endif
diff --git a/odemx-lite/include/odemx/base/Process.h b/odemx-lite/include/odemx/base/Process.h
new file mode 100644
index 0000000000000000000000000000000000000000..68cd6f37f757914766fd2f9692cf47f7a010f27d
--- /dev/null
+++ b/odemx-lite/include/odemx/base/Process.h
@@ -0,0 +1,783 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007, 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Process.h
+ * @author Ralf Gerstenberger
+ * @date created at 2002/01/30
+ * @brief Declaration of odemx::base::Process and observer
+ * @sa Process.cpp
+ * @since 1.0
+ */
+
+#ifndef ODEMX_BASE_PROCESS_INCLUDED
+#define ODEMX_BASE_PROCESS_INCLUDED
+
+#include <odemx/base/Sched.h>
+#include <odemx/base/TypeDefs.h>
+#include <odemx/coroutine/Coroutine.h>
+#include <odemx/data/Observable.h>
+#include <odemx/synchronization/IMemory.h>
+#include <odemx/util/attributes.h>
+#include <odemx/synchronization/Memory.h>
+#include <odemx/base/control/ControlBase.h>
+
+//#include <odemx/base/Control.h>
+
+namespace odemx {
+
+// forward declarations
+namespace synchronization {
+class ProcessQueue;
+}
+
+namespace base {
+
+class ControlBase; // include follows in Process.cpp
+class Simulation;
+class ProcessObserver;
+
+/** \class Process
+
+	\ingroup base
+
+	\author Ralf Gerstenberger
+
+	\brief %Process is the base class for all user processes in a model.
+
+	\note %Process supports Observation.
+	\note %Process supports Trace.
+
+	\sa Event, Condition, Selection and Simulation
+
+	%Process is the base class for all user defined processes in a model. A user
+	creates a derived class for every different type of process of its model. In
+	its classes the user has to provide the behaviour by implementing the main()
+	method. The behaviour is executed according to an execution schedule
+	(ExecutionList) at a certain point in simulation time. If multiple processes
+	share the same execution time, the order of execution is defined by the way
+	the processes have been scheduled. A process can be scheduled with respect
+	to its priority FirstInFirstOut or LastInFirstOut at a point in time, or
+	in relation to an already scheduled partner process (immediately after or before
+	that process).
+
+	\par Example:
+	\include basicProcess.cpp
+
+	\since 1.0
+*/
+class Process
+:	public Sched // is DataProducer, etc.
+,	public coroutine::Coroutine
+,	public data::Observable< ProcessObserver >
+{
+public:
+	/**
+		\brief Process states
+
+		A process passes different process states during its life time
+		(between new and delete). After construction a process is CREATED.
+		In this state a process isn't scheduled for execution and hasn't been executed
+		yet. In RUNNABLE a process is scheduled for execution. If a process is executed
+		its state is CURRENT. In every simulation there is no more than one process
+		executed at a time. A process in IDLE state is not scheduled for execution. It is
+		inactive. If a process has finished or is terminated its state is TERMINATED.
+		Such a process is not scheduled for execution and cannot be scheduled
+		anymore.
+	*/
+	enum ProcessState
+	{
+		CREATED,	///< Initial state   0
+		CURRENT,	///< Active state    1
+		RUNNABLE,	///< Scheduled state 2
+		IDLE,		///< Wait state      3
+		TERMINATED	///< Final state     4
+	};
+
+public:
+
+	/**
+		\brief Construction for user-defined Simulation
+		\param s
+			pointer to the Simulation object
+		\param l
+			label of this object
+		\param o
+			initial observer
+	*/
+	Process( Simulation& sim, const data::Label& label, ProcessObserver* obs = 0 );
+
+	/// Destruction
+	~Process();
+
+	/**
+		\brief Get process state
+		\return current process state
+	*/
+	ProcessState getProcessState() const;
+
+	/**
+		\name Process Scheduling
+
+		These functions are used to schedule a process
+		in simulation time.
+
+		@{
+	*/
+	/**
+		\brief Immediate activation
+
+		This function schedules the process at the current time before
+		all other processes with the same priority (LIFO). If the current
+		process (A) does not have a higher priority than the process the
+		function is called for (B) the following will happen:
+		\li B is scheduled before A
+		\li the state of A changes to RUNNABLE while the state
+			of B changes to CURRENT
+		\li the main() function of A is stopped (the point is saved)
+		\li the main() function of B is executed from the point it
+			has been left last time (or from the beginning)
+	*/
+	void activate();
+
+	/**
+		\brief Activation in (relative) time \p t
+		\param t
+			delay for activation
+
+		This function schedules the process at the simtime \c now + \p t
+		before all other processes with the same priority (LIFO). If
+		\p t is 0 this function is equal to activate().
+
+		\sa activate()
+	*/
+	void activateIn( SimTime t );
+
+	/**
+		\brief Activation at (absolute) time \p t
+		\param t
+			time for activation
+
+		This function schedules the process at the simtime \p t
+		before all other processes with the same priority (LIFO). If
+		\p t is \c now this function is equal to activate().
+
+		\sa activate()
+	*/
+	void activateAt( SimTime t );
+
+	/**
+		\brief Activation before process \p p
+		\param p
+			pointer to partner process
+
+		This function schedules the process just before
+		process \p p. If necessary the priority of the process
+		is changed. If \p p is this process this function
+		does nothing. If process \p p is not scheduled ODEMx
+		reports an error.
+	*/
+	void activateBefore( Sched* s );
+
+	/**
+		\brief Activation after process \p p
+		\param p
+			pointer to refrence process
+
+		This function schedules the process just after
+		process \p p. If necessary the priority of this process
+		is changed. If \p p is this process this function
+		does nothing. If process \p p is not scheduled ODEMx
+		reports an error.
+	*/
+	void activateAfter( Sched* s );
+
+	/**
+		\brief Immediate activation (FIFO)
+
+		This function schedules the process at the current time
+		after all other processes with the same priority.
+	*/
+	void hold();
+
+	/**
+		\brief Activation (FIFO) in (relative) time \p t
+
+		This function schedules the process at the time \c now + \p t
+		after all other processes with the same priority. If \p t
+		is 0 this function is equal to hold().
+
+		\sa hold()
+	*/
+	void holdFor( SimTime t );
+
+	/**
+		\brief Activation (FIFO) at (absolute) time \p t
+
+		This function schedules the process at simtime \p t
+		after all other processes with the same priority. If \p t
+		is \c now this function is equal to hold().
+
+		\sa hold()
+	*/
+	void holdUntil( SimTime t );
+
+	/**
+		\brief Deactivation
+
+		This function removes the process from execution schedule
+		and changes its state into IDLE. The next RUNNABLE process
+		in the schedule is than activated.
+	*/
+	void sleep();
+
+	/**
+		\brief Interrupt
+
+		This function interrupts the process, which results in an immediate
+		activation [activate()]. A Process can determine whether it was
+		interrupted by isInterrupted(). A Process must handle interrupts
+		on its own. It should do so after activate... and hold... operation.
+
+		\sa activateAt(), activateUntil(), holdFor() and holdUntil()
+	*/
+	virtual void interrupt();
+
+	/**
+		\brief Termination
+
+		This function terminates the process. The process is than removed from
+		execution schedule and its state is changed to TERMINATED.
+	*/
+	void cancel();
+	//@}
+
+	/**
+		\name Priority
+
+		If the priority is changed the position of the process in the
+		execution schedule and in queues is updated. This can cause a
+		switch to another process.
+
+		@{
+	*/
+	/**
+		\brief Get priority
+		\return
+			process priority
+
+		This function returns the current process priority.
+	*/
+	Priority getPriority() const;
+
+	/**
+		\brief Set new priority
+		\return
+			previous process priority
+
+		This function changes the process priority. The position
+		in the execution schedule is affected by priority changes.
+	*/
+	Priority setPriority( Priority newPriority );
+	//@}
+
+	/**
+		\name Execution Time
+
+		@{
+	*/
+	/**
+		\brief Get execution time
+		\return
+			execution time; 0 if not RUNNABLE or CURRENT
+
+		This function returns the execution time of the process.
+		A process is scheduled for execution at its execution
+		time.
+	*/
+	SimTime getExecutionTime() const;
+	//@}
+
+	/**
+		\name Current System State
+
+		@{
+	*/
+	/**
+		\brief Get currently active Sched object
+		\return
+			pointer to the current Sched object
+
+		This function returns the currently active Sched object.
+	*/
+	Sched* getCurrentSched();
+
+	/**
+		\brief Get currently active process
+		\return
+			pointer to the current process
+
+		This function returns the currently active process (the one
+		in state CURRENT).
+	*/
+	Process* getCurrentProcess();
+
+	/**
+		\brief Get current simtime
+		\deprecated substituted by Sched::getTime ()
+		\return
+			current simulation time
+
+		This function returns the current simulation time by simply calling
+    Process::getTime ().
+	*/
+	DEPRECATED(SimTime getCurrentTime() const);
+
+	/**
+		\name Interrupt handling
+
+		An Interrupt is caused by the scheduling function interrupt().
+		The interrupter (Sched object) is stored. The interrupt-state is
+		automatically reset by the next scheduling function called. If the
+		Process is interrupted but the interrupter is 0, then the Process
+		was interrupted by the simulation (environment).
+
+		@{
+	*/
+	/**
+		\brief Get interrupt state
+		\return
+			interrupt state
+
+		This function returns the interrupt state of the process.
+	*/
+	bool isInterrupted() const;
+
+	/**
+		\brief Get process which called interrupt()
+		\return
+			pointer to process which called interrupt()
+
+		This function returns the process which called interrupt().
+	*/
+	Sched* getInterrupter();
+	
+	//@}
+
+
+	/**
+		\name Suspend and alert
+		\author Ronald Kluth
+
+		A concept of suspending a process until a resource becomes
+		available or a timeout occurs.
+
+		@{
+
+	*/
+
+	/**
+		\brief Suspend process and wait for alert
+		\param m0
+			pointer to object of Memory-derived class, must be given
+		\param m1
+			pointer to object of Memory-derived class, optional
+		\param m2
+			pointer to object of Memory-derived class, optional
+		\param m3
+			pointer to object of Memory-derived class, optional
+		\param m4
+			pointer to object of Memory-derived class, optional
+		\param m5
+			pointer to object of Memory-derived class, optional
+
+		\return
+			pointer to alerting memo object
+
+		This function is used to suspend a process while waiting for
+		one of the given Memory objects to become available.
+		That can either be a PortHead or PortTail, or a Timer event.
+		The function returns the pointer to	the first available Memory object.
+		If the process was interrupted, this function returns 0. Hence,
+		a process should always check for interruption after calling \p wait().
+	*/
+
+	synchronization::IMemory* wait( synchronization::IMemory* m0, synchronization::IMemory* m1 = 0,
+			synchronization::IMemory* m2 = 0, synchronization::IMemory* m3 = 0,
+			synchronization::IMemory* m4 = 0, synchronization::IMemory* m5 = 0 );
+
+	/**
+		\brief Suspend process and wait for alert
+		\param memvec
+			vector containing pointers to objects of Memory-derived classes
+		\return
+			pointer to alerting memo object
+
+		Overloaded version of the above function. Instead of several
+		pointers to Memory objects, a vector containing all the Memory
+		objects can be given as a parameter.
+	*/
+
+	synchronization::IMemory* wait( synchronization::IMemoryVector* memvec );
+
+
+	/**
+		\brief Reschedule process when a Memory object becomes available
+		\param theAlerter
+			pointer to the calling Memory object
+
+		This function is called when Memory-derived objects call alert().
+		It wakes up a suspended process and reschedules it at the
+		current simulation time.
+	*/
+	virtual void alertProcess( synchronization::IMemory* theAlerter );
+
+	/**
+		\brief Check alert state of the process
+		\return
+			Alert state of the process
+
+		This function checks the alert state of the process. It returns
+		true if alertProcess() was called on this object. The library uses
+		it in Process::wait() to determine whether a process was alerted
+		by a Memory object.
+	*/
+	bool isAlerted() const;
+
+	/**
+		\brief Determine who woke the process with an alert
+		\return
+			pointer to the available Memory object
+
+		This function is used in Process::wait() to determine
+		the currently available Memory object.
+	*/
+	synchronization::IMemory* getAlerter() const;
+
+	/**
+		\brief Reset the  values alerted and alerter
+
+		This function is used in Process::wait() to avoid the use
+		of outdated alert state or a previous alerter. It is recommended
+		to call this function before and after waiting and receiving
+		an alert.
+	*/
+	void resetInterrupt();
+
+private:
+	void genericHoldUntil(SimTime t);
+	void resetAlert();
+	//@}
+
+public:
+
+	/**
+		\name Generic condition waiting
+		\author Jonathan Schlue
+
+		A concept of suspending a process until an arbitrary condition turns true.
+		@{
+
+	*/
+
+	/**
+		\brief This function can be used by processes to wait for arbitrary conditions.
+
+	 	\param condition the condition to wait for to become true. This process will be passed as an argument to the condition.
+
+	 	\param controls a list of controlled variables, which inform the Process whenever they get accessed so that the condition turned true
+
+	 	\param label a label for all log entries related to this waitUntil() call
+
+	 	\return
+	 		false if the process was interrupted, otherwise true
+
+	 	Process execution blocks until the provided condition turns true.
+	 	All passed control variables automatically wake up this process on change to let it check its condition again.
+	 	If the condition is evaluated to true, the invoking control variable is set as this process' alerter and the process is marked as alerted.
+	 	This is mainly useful to later find the control variable, which change made the condition turn true.
+	 	However, the process can still be manually instructed to check its condition by scheduling it using methods from the activate- or hold-family.
+	 	This is mainly useful if no control variables were provided.
+
+
+	 	\note Once the condition turned
+
+	 	\sa Control, ControlBase
+
+	*/
+	bool waitUntil(const Condition& condition, const std::string label,
+			const std::vector<std::reference_wrapper<ControlBase>>& controls);
+
+	//@}
+
+public:
+	/**
+		\brief main() function status
+		\return
+			true if the main() function has returned
+
+		This function returns true if the main() function of
+		this process has returned (is finished).
+	*/
+	bool hasReturned() const;
+
+	/**
+		\brief Get return value of main() function
+		\return
+			return value from main()
+
+		This function returns the return value of the main()
+		function. Use the hasReturned() function to check
+		whether the main() function has already returned.
+	*/
+	int getReturnValue() const;
+
+	/**
+		\brief Get pointer to Trace
+		\return
+			pointer to Trace object
+	*/
+	//virtual data::Trace* getTrace() const;
+
+	/** \name Queue management
+
+		Processes can be managed in queues during a simulation.
+		Typically, queues are used with FIFO-strategy. This behavior
+		can be influenced by setting a separate queue priority for
+		a process. However, this instrument should be handled with care
+		as a change in queue priority might lead to a Process always
+		being in first or last position in every queue it enters.
+
+		Currently, each Process object can only be enqueued in one
+		queue at a time.
+
+		@{
+	*/
+	/**
+		\brief Get queue
+		\return
+			pointer to ProcessQueue
+
+		If the process is in a queue this function returns
+		the pointer to the queue.
+	*/
+	synchronization::ProcessQueue* getQueue() const;
+
+	/**
+		\brief Get enqueue-time
+		\return
+			time at which the process entered a queue
+
+		If the process is in a queue this function returns
+		the time at which the process entered the queue. This
+		function is used by synchronisation objects.
+	*/
+	SimTime getEnqueueTime() const;
+
+	/**
+		\brief Get dequeue-time
+		\return
+			time at which the process left a queue
+
+		If the process was in a queue this function returns
+		the time it left the queue. This function is used by
+		synchronisation objects.
+	*/
+	SimTime getDequeueTime() const;
+
+	/**
+		\brief Get queue priority
+		\return
+			queue priority
+
+		This function returns the current queue priority of this process
+	*/
+	Priority getQueuePriority() const;
+
+	/**
+		\brief Set new queue priority
+		\param newQPriority
+			the new priority value
+		\param reactivate
+			set to \c true to immediately activate this process
+		\return
+			previous queue priority
+
+		This function changes the queue priority of this process.
+		The position in queues is affected by changes of this value.
+		The default is 0. If reactivate is set to true, the process
+		will be scheduled and activated immediately. This is useful if
+		a process is enqueued in a queue where it has to meet a certain
+		condition, or if it is moved into first position by this change.
+		The process will still be blocked if a required condition
+		could not be fulfilled.
+	*/
+	Priority setQueuePriority( Priority newQPriority, bool reactivate );
+
+	//@}
+
+
+protected:
+	/**
+		\brief User defined process behaviour
+
+		This function must be implemented by the user to define the
+		behaviour of a process. It is executed by ODEMx when the process
+		becomes the current process. If the process calls a scheduling
+		function (direct or indirect, at itself or another process)
+		the %main() function is delayed until the process is executed
+		again. The sequence in which different processes are executed
+		is determined by the execution schedule.
+
+		\sa Process Scheduling
+	*/
+	virtual int main() = 0;
+
+
+	//  Interface
+
+	friend class ExecutionList;
+	/**
+		\brief Set execution time
+		\return
+			previous execution time
+
+	 	This function is used by the library. Don't
+		call it directly! Use the scheduling functions
+		instead.
+	*/
+	SimTime setExecutionTime( SimTime time );
+
+	friend class Simulation;
+	/**
+		\brief Execution of this process
+
+		This function is used by the library. Don't
+		call it directly! The execution is managed
+		by the process scheduling.
+	*/
+	void execute();
+private:
+
+	/// Coroutine entry-point implementation
+	virtual void run();
+
+	ProcessState processState_; ///< process state
+	Priority priority_; ///< process priority, influences scheduling
+	SimTime executionTime_; ///< process execution time
+	ProcessList::iterator simListIter_; ///< remember position in Simulation lists
+	bool validReturn_; ///< return value is valid
+	int returnValue_; ///< return value of main()
+
+	synchronization::ProcessQueue* queue_; ///< pointer to queue if process is waiting
+	SimTime enqueueTime_; ///< enqueue-time
+	SimTime dequeueTime_; ///< dequeue-time
+	Priority queuePriority_; ///< separate priority setting for queues
+	ProcessList::iterator queueListIter_; ///< remember position in process queues
+
+	bool isInterrupted_; ///< Process was interrupted
+	Sched* interrupter_; ///< Process was interrupted by interrupter (0->by Simulation)
+	bool isAlerted_; ///< Process was alerted
+	synchronization::IMemory* alerter_; ///< Process alerter
+
+private:
+	/**
+		\brief set process state
+		\return true if successful
+	*/
+	bool setProcessState( ProcessState newState );
+
+	friend class synchronization::ProcessQueue;
+	/**
+		\name ProcessQueue Management
+		\note No more than one ProcessQueue at a time is supported. (provisional)
+
+		@{
+	*/
+	void enqueue( synchronization::ProcessQueue* inQueue ); ///< process enters queue \p nq
+	void dequeue( synchronization::ProcessQueue* outQueue ); ///< process leaves queue \p nq
+	//@}
+
+	/**
+		\name Trace help functions
+		@{
+	*/
+	/// log wait to trace with a list of memory objects
+	void traceWait( synchronization::IMemoryVector& memvec );
+	const data::Label& getPartner();
+
+	static std::string stateToString( ProcessState state );
+	//@}
+};
+
+
+/** \interface ProcessObserver
+
+	\author RalfGerstenberger
+
+	\brief Observer for Process specific events.
+
+	\sa Process
+
+	\since 1.0
+*/
+class ProcessObserver:
+	public coroutine::CoroutineObserver
+{
+public:
+	virtual ~ProcessObserver() {}
+//	virtual void onCreate( Process* sender ) {} ///< Construction
+//	virtual void onDestroy( Process* sender ) {} ///< Destruction
+
+	// Activation (LIFO)
+	virtual void onActivate( Process* sender ) {} ///< Immediate activation
+	virtual void onActivateIn( Process* sender, SimTime t ) {} ///< Activation in
+	virtual void onActivateAt( Process* sender, SimTime t ) {} ///< Activation at
+
+	// Activation in Releation to a Partner Process
+	virtual void onActivateBefore( Process* sender, Sched* p ) {} ///< Activation before
+	virtual void onActivateAfter( Process* sender, Sched* p ) {} ///< Activation after
+
+	// Activation (FIFO)
+	virtual void onHold( Process* sender ) {} ///< hold
+	virtual void onHoldFor( Process* sender, SimTime t ) {} ///< Hold for
+	virtual void onHoldUntil( Process* sender, SimTime t ) {} ///< Hold until
+
+	virtual void onInterrupt( Process* sender ) {} ///< Process interrupted
+	virtual void onSleep( Process* sender ) {} ///< Process deactivated
+	virtual void onCancel( Process* sender ) {} ///< Process terminated
+
+	virtual void onExecute( Process* sender ) {} ///< Process execution was started or continued
+	virtual void onReturn( Process* sender ) {} ///< Process successfully returned from main()
+
+	virtual void onWait( Process* sender, synchronization::IMemoryVector* memvec ) {} ///< Process waiting for alert
+	virtual void onAlert( Process* sender, synchronization::IMemory* alerter ) {} ///< Process deactivated
+
+	/// Process state change
+	virtual void onChangeProcessState( Process* sender, Process::ProcessState oldState, Process::ProcessState newState ) {}
+	/// Process priority change
+	virtual void onChangePriority( Process* sender, Priority oldPriority, Priority newPriority ) {}
+	/// Process queue priority change
+	virtual void onChangeQueuePriority( Process* sender, Priority oldQPriority, Priority newQPriority ) {}
+	/// Process execution time change
+	virtual void onChangeExecutionTime( Process* sender, SimTime oldExecutionTime, SimTime newExecutionTime ) {}
+};
+
+} } // namespace odemx::base
+
+#endif /* ODEMX_BASE_PROCESS_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/Sched.h b/odemx-lite/include/odemx/base/Sched.h
new file mode 100644
index 0000000000000000000000000000000000000000..ba16a4cf50d8308356af2912ff95d56779da57cf
--- /dev/null
+++ b/odemx-lite/include/odemx/base/Sched.h
@@ -0,0 +1,226 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2007, 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Sched.h
+ * @author Ronald Kluth
+ * @date created at 2007/01/24
+ * @brief Declaration of odemx::base::Sched
+ * @sa Sched.cpp
+ * @since 2.0
+ */
+
+#ifndef ODEMX_BASE_SCHED_INCLUDED
+#define ODEMX_BASE_SCHED_INCLUDED
+
+#include <odemx/base/SimTime.h>
+#include <odemx/base/TypeDefs.h>
+#include <odemx/data/Producer.h>
+
+namespace odemx {
+
+// forward declaration
+namespace base { class Sched; }
+
+/**
+	\brief Comparison operator for Sched objects
+	\par first
+		first Process
+	\par second
+		second Process
+
+	This operator compares two Sched objects. The
+	operator returns true if the execution time of
+	\p first is less than that of \p second. If both have the same
+	execution time, the priority is used. True is returned if priority
+	of \p first is higher than that of \p second.
+*/
+extern bool operator<( const base::Sched& first, const base::Sched& second );
+
+namespace base {
+
+// forward declaration
+class ExecutionList;
+
+/** \class Sched
+
+	\ingroup base
+
+	\author Ronald Kluth
+
+	\brief %Sched is the interface for all schedulable objects in a model.
+
+	\sa Simulation, ExecutionList, Event, Process
+
+	%Sched is the abstract base class for all schedulable bjects.
+	It declares all functions needed for the scheduling
+	mechanism of ODEMx. This layer of abstraction was inserted to allow
+	scheduling of different kinds of objects. The schedule works on
+	polymorphic pointers of type Sched. The library supports event-based
+	as well as process-based simulation models. Event and Process are
+	Sched-derived classes that implement the interface.
+
+	\since 2.0
+*/
+class Sched
+:	public data::Producer
+{
+public:
+	/**
+		\brief Sched types
+
+		Sched types are a means to handle the execution of different
+		types of simulation objects, in this case Events and Processes.
+		When different kinds of objects can be scheduled, the Simulation
+		has to decide how to proceed when the simulation time reaches the
+		execution time of an object.
+	*/
+	enum SchedType
+	{
+		PROCESS,	///< Simulation must start this process's coroutine
+		EVENT		///< Simulation only needs to execute an event action
+	};
+
+public:
+
+	/**
+		\brief Construction
+		\param st
+			type of the schedulable object, from enum Sched::SchedType
+	*/
+	Sched( Simulation& sim, const data::Label& label, SchedType st );
+
+	/// Destruction
+	virtual ~Sched();
+
+	/**
+		\name Scheduling interface
+
+		These functions are used by the ExecutionList to schedule objects
+		according to their execution time and their priority. Every
+		class of schedulable objects must implement these pure virtual
+		functions.
+
+		@{
+	*/
+	/**
+		\brief Get execution time
+		\return
+			execution time of the object
+
+		This function returns the execution time of the Sched object.
+		Processes and Events are scheduled for execution at their execution
+		time.
+	*/
+	virtual SimTime getExecutionTime() const = 0;
+
+	/**
+		\brief Set execution time
+		\return
+			previous execution time
+
+	 	This internal function is used by the library. It should
+	 	never be called directly! Use scheduling functions instead.
+	*/
+	virtual SimTime setExecutionTime( SimTime time ) = 0;
+
+	/**
+		\brief Get priority
+		\return
+			scheduling priority
+
+		This function returns the current Sched priority.
+		If the priority is changed, the position of the object in the
+		execution schedule and in queues is updated. This can cause a
+		switch to another Sched object.
+	*/
+	virtual Priority getPriority() const = 0;
+
+	/**
+		\brief Set new priority
+		\return
+			previous Sched priority
+
+		This function changes the scheduling priority. The position
+		in the execution schedule and in queues is affected by
+		priority changes.
+	*/
+	virtual Priority setPriority( Priority newPriority ) = 0;
+
+	/**
+		\brief Check if Sched object is in schedule
+
+		This function checks a boolean member which is set to true
+		when a scheduling function was called on this event.
+	*/
+	bool isScheduled() const;
+	//@}
+
+	/**
+		\name Sched execution
+
+		These functions are used to schedule a process
+		in simulation time.
+
+		@{
+	*/
+	/**
+		\brief Determine the Sched object's type
+		\returns
+			SchedType of this schedulable Object
+
+		The type of Sched objects cannot change, it is set in
+		the constructors of Event and Process. This internal
+		function is used during simulation computation to
+		determine the the correct path of execution for this object.
+	*/
+
+	SchedType getSchedType() const;
+
+	/**
+		\brief Execution of Sched object
+
+		This virtual function is used polymorphically by Simulation
+		to execute the current Sched object.
+
+		\sa getSchedType(), Simulation::exec()
+	*/
+	virtual void execute() = 0;
+	//@}
+
+	/**
+		\brief Get current simtime
+		\return
+		current simulation time
+
+		This function returns the current simulation time.
+	*/
+	SimTime getTime() const;
+private:
+	SchedType schedType_; 	///< Event or Process
+	bool scheduled_; 		///< determine whether the object is scheduled
+	std::pair< SimTime, SchedList* > scheduleLoc_;
+	SchedList::iterator execListIter_; ///< remember position in ExecutionList
+
+	friend class ExecutionList;
+	friend bool odemx::operator<( const base::Sched& first, const base::Sched& second );
+};
+
+} } // namespace odemx::base
+
+#endif /* ODEMX_BASE_SCHED_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/Scheduler.h b/odemx-lite/include/odemx/base/Scheduler.h
new file mode 100644
index 0000000000000000000000000000000000000000..1bd757cfa1132ee5bfa6ca44c35a5bfdcf752b51
--- /dev/null
+++ b/odemx-lite/include/odemx/base/Scheduler.h
@@ -0,0 +1,77 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Scheduler.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/12
+ * @brief Declaration of odemx::base::Scheduler
+ * @sa Scheduler.cpp
+ * @since 3.0
+ */
+
+#include <odemx/base/ExecutionList.h>
+#include <odemx/base/SimTime.h>
+#include <odemx/data/Producer.h>
+
+#ifndef ODEMX_BASE_SCHEDULER_INCLUDED
+#define ODEMX_BASE_SCHEDULER_INCLUDED
+
+namespace odemx {
+namespace base {
+
+class Simulation;
+
+/**
+ * @brief Internal class used by the simulation context to manage scheduling and execution
+ */
+class Scheduler
+:	public data::Producer
+{
+public:
+	Scheduler( Simulation& sim, const data::Label& label );
+	~Scheduler();
+
+	void run();
+	void runUntil( SimTime stopTime );
+	void step();
+
+	void addSched( Sched* s );
+	void insertSched( Sched* s );
+	void insertSchedBefore( Sched* s, Sched* partner );
+	void insertSchedAfter( Sched* s, Sched* partner );
+	void removeSched( Sched* s );
+
+	const ExecutionList& getExecutionList() const;
+
+private:
+	Simulation& sim_;
+	ExecutionList executionList_;
+
+protected:
+	// allow Sched-derived classes access to private members
+	friend class Process;
+	friend class Event;
+
+	void inSort( Sched* s );
+	void executeNextSched();
+};
+
+} } // namespace odemx::base
+
+#endif /* ODEMX_BASE_SCHEDULER_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/SimTime.h b/odemx-lite/include/odemx/base/SimTime.h
new file mode 100644
index 0000000000000000000000000000000000000000..c269283b310eae0add066a784c539409eebcb05b
--- /dev/null
+++ b/odemx-lite/include/odemx/base/SimTime.h
@@ -0,0 +1,48 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file SimTime.h
+ * @author Ralf Gerstenberger
+ * @date created at 2002/01/24
+ * @brief TypeDef of odemx::base::SimTime
+ *
+ * The simulation time is an abstraction from real time. It is also referred to
+ * as model time.
+ *
+ * @since 1.0
+ */
+
+#ifndef ODEMX_BASE_SIMTIME_INCLUDED
+#define ODEMX_BASE_SIMTIME_INCLUDED
+
+#include <odemx/setup.h>
+
+namespace odemx {
+namespace base {
+
+#ifdef ODEMX_USE_CONTINUOUS
+	typedef double SimTime; ///< Simulation time type
+#else
+	// changed in odemx-lite, was Poco::UInt64 (this is a platform dependend type.)
+	typedef long long SimTime; ///< Simulation time type
+#endif
+
+} } // namespace odemx::base
+
+#endif /* ODEMX_BASE_SIMTIME_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/Simulation.h b/odemx-lite/include/odemx/base/Simulation.h
new file mode 100644
index 0000000000000000000000000000000000000000..887814ae22178ad026ffd96a875943fedacdbec4
--- /dev/null
+++ b/odemx-lite/include/odemx/base/Simulation.h
@@ -0,0 +1,436 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Simulation.h
+ * @author Ralf Gerstenberger
+ * @date created at 2002/02/22
+ * @brief Declaration of odemx::base::Simulation and observer
+ * @sa Simulation.cpp
+ * @since 1.0
+ */
+
+#ifndef ODEMX_BASE_SIMULATION_INCLUDED
+#define ODEMX_BASE_SIMULATION_INCLUDED
+
+#include <odemx/base/Scheduler.h>
+#include <odemx/base/SimTime.h>
+#include <odemx/coroutine/CoroutineContext.h>
+#include <odemx/data/Label.h>
+#include <odemx/data/Producer.h>
+#include <odemx/data/LoggingManager.h>
+#include <odemx/random/DistContext.h>
+#include <odemx/data/Observable.h>
+#include <odemx/util/attributes.h>
+
+#include <list>
+#ifdef _MSC_VER
+#include <memory>
+#else
+#include <memory>
+#endif
+
+
+// forward declaration, this class is used in unit tests
+class TestSimulation;
+
+namespace odemx {
+namespace base {
+
+// forward declarations
+class Event;
+class Process;
+class DefaultLogConfig;
+class SimulationObserver;
+
+/** \class Simulation
+
+	\ingroup base
+
+	\author Ralf Gerstenberger
+
+	\brief %Simulation is the base class for all user simulations.
+
+	\note %Simulation supports Observation.
+	\note %Simulation supports Trace.
+
+	In a user simulation
+	the method initSimulation() must be implemented to set-up the
+	simulation.	run(), step() or runUntil() can be used to compute the
+	simulation.	run() returns after the simulation has finished. step()
+	returns after each execution of a scheduled object in the simulation.
+	runUntil() returns
+	after simulation time exceeds the given time or the simulation is finished.
+	%Simulation also manages lists of all Process objects in the states
+	CREATED, RUNNABLE, IDLE and TERMINATED.
+
+	\par Example:
+	\include matryoshka.cpp
+
+	\since 1.0
+*/
+class Simulation
+:	public data::LoggingManager // must be initialized first, because
+,	public data::Producer // Producer needs Context for initialization
+,	public coroutine::CoroutineContext
+,	public random::DistContext
+,	public data::Observable< SimulationObserver >
+{
+public:
+	/// Process list identifiers
+	enum List
+	{
+		CREATED, ///< Created processes
+		RUNNABLE, ///< Runnable processes
+		IDLE, ///< Idle processes
+		TERMINATED ///< Terminated processes
+	};
+
+public:
+	/**
+		\brief Construction
+		\param l
+			label of this object
+		\param o
+			initial observer
+	*/
+	Simulation( const data::Label& label = "Simulation", SimulationObserver* obs = 0 );
+
+	/**
+		\brief Construction
+		\param l
+			label of this object
+		\param o
+			initial observer
+	*/
+	Simulation( const data::Label& label, SimTime startTime, SimulationObserver* obs = 0 );
+
+	/// Destruction
+	virtual ~Simulation();
+
+	/// Describe the purpose of the simulation
+	void setDescription( const std::string& description );
+
+	/// Get the simulation description
+	const std::string& getDescription() const;
+
+	/**
+		\name Simulation computing
+
+		The computation of a simulation is started with one of
+		the following functions. A simulation is finished when there is
+		no Sched object left to be executed or the function exitSimulation()
+		was called.
+
+		@{
+	*/
+	/// Run simulation until it is finished
+	void run();
+	/// Execute one scheduled object and return
+	void step();
+	/// Run until the current time reaches the \c stopTime
+	void runUntil( SimTime stopTime );
+
+	/**
+		\brief Simulation status
+		\return
+			true if simulation is finished
+
+		This function returns true if the simulation is finished.
+	*/
+	bool isFinished() const;
+
+	/**
+		\brief Stop simulation
+
+		This function stops the simulation.
+	*/
+	virtual void exitSimulation();
+
+	//@}
+
+	/**
+		\name Process management
+
+		Simulation remembers all process objects. The following
+		functions can be used to get the objects in different
+		process states.
+
+		\sa Process::ProcessState
+
+		@{
+	*/
+	/**
+		\brief Get currently executed process
+		\return
+			pointer to executed process object
+
+		This function returns a pointer to the momentarily
+		executed process (the process in state CURRENT).
+	*/
+	Process* getCurrentProcess();
+
+	/**
+		\brief Get currently executed Sched object
+		\return
+			pointer to executed Sched object
+
+		This function returns a pointer to the momentarily
+		executed object. That can either be the process in
+		state CURRENT, or the currently running event.
+	*/
+	Sched* getCurrentSched();
+
+	void resetCurrentSched();
+	void resetCurrentProcess();
+
+	/**
+		\brief Get list of processes in state CREATED
+		\return
+			list of processes in state CREATED
+
+		This function returns a list of all processes
+		in state CREATED.
+	*/
+	DEPRECATED(ProcessList& getCreatedProcesses());
+	/**
+		\brief Get list of processes in state CREATED
+		\return
+			list of processes in state CREATED
+
+		This function returns a list of all processes
+		in state CREATED.
+	*/
+	const ProcessList& getCreatedProcesses() const;
+	/**
+		\brief Get list of processes in state RUNNABLE
+		\return
+			list of processes in state RUNNABLE
+
+		This function returns a list of all processes
+		in state RUNNABLE.
+	*/
+	DEPRECATED(ProcessList& getRunnableProcesses());
+	/**
+		\brief Get list of processes in state RUNNABLE
+		\return
+			list of processes in state RUNNABLE
+
+		This function returns a list of all processes
+		in state RUNNABLE.
+	*/
+	const ProcessList& getRunnableProcesses() const;
+
+	/**
+		\brief Get list of processes in state IDLE
+		\deprecated Please use the overloads instead.
+		\return
+			list of processes in state IDLE
+
+		This function returns a list of all processes
+		in state IDLE.
+	*/
+	DEPRECATED(ProcessList& getIdleProcesses());
+	/**
+		\brief Get list of processes in state IDLE
+		\return
+			list of processes in state IDLE
+
+		This function returns a list of all processes
+		in state IDLE.
+	*/
+	const ProcessList& getIdleProcesses() const;
+
+	/**
+		\brief Get list of processes in state TERMINATED
+		\return
+			list of processes in state TERMINATED
+
+		This function returns a list of all processes
+		in state TERMINATED.
+	*/
+	DEPRECATED(ProcessList& getTerminatedProcesses());
+	/**
+		\brief Get list of processes in state TERMINATED
+		\return
+			list of processes in state TERMINATED
+
+		This function returns a list of all processes
+		in state TERMINATED.
+	*/
+	const ProcessList& getTerminatedProcesses() const;
+
+	/**
+	 * @brief Controls whether all terminated processes are delete automatically
+	 *
+	 * After each object execution, the scheduler tests if this property is
+	 * activated. In that case, it proceeds by deleting all processes stored
+	 * in the list @c terminatedProcesses_ and clears the list.
+	 *
+	 * @warning This feature MUST NOT be used if you allocate processes objects
+	 * on the runtime stack because @c delete calls are not allowed.
+	 * @warning This feature is unsafe! It should only be used if the memory
+	 * taken up by finished processes is really needed. You will not be able
+	 * to access pointers or references to processes in your simulation program
+	 * after process termination.
+	 */
+	void autoDeleteProcesses( bool value = true );
+	//@}
+
+	/**
+		\brief Get current simulation time
+		\return
+			time now
+
+		This function returns the current simulation time.
+		The current time is determined by the current or
+		last executed process. If a process is executed its
+		execution time becomes the new simulation time.
+	*/
+	SimTime getTime() const;
+
+	/// Used by the Scheduler to adjust the simulation time
+	void setCurrentTime( SimTime newTime );
+
+	/**
+		\brief Get initial simulation time
+		\return
+			time start
+
+		This function returns the initial simulation time, which
+		can only be set in the constructor.
+	*/
+	SimTime getStartTime() const;
+
+	/**
+		\brief Get a reference to the scheduler
+		\return
+			reference to the scheduler
+	*/
+	Scheduler& getScheduler();
+
+	/// Get the unique identifier of a simulation object
+	SimulationId getId() const;
+
+protected:
+	/**
+		\brief Initialization of a simulation
+
+		Implement this method to initialize a simulation.
+		One can create and activate the first processes of
+		a simulation in this function. Inside this
+		function the scheduling operations does not cause
+		an immediate execution of a process. The first process
+		is executed after this function is finished.
+	*/
+	virtual void initSimulation() = 0;
+
+private:
+	// needed for unit testing
+	friend class TestSimulation;
+
+	std::string description_; ///< simulation description
+	bool isInitialized_; ///< simulation is initialized
+	bool isStopped_; ///< simulation is stopped
+	SimTime startTime_; ///< start time offset for simulation, default is 0
+	SimTime currentTime_; ///< current time
+
+	Scheduler scheduler_; ///< manages execution of events and processes
+	Process* currentProcess_; ///< current process on stack
+	Sched* currentSched_; ///< current scheduled object: event or process
+	ProcessList createdProcesses_; ///< CREATED processes
+	ProcessList runnableProcesses_; ///< RUNNABLE processes
+	ProcessList idleProcesses_; ///< IDLE processes
+	ProcessList terminatedProcesses_; ///< TERMINATED processes
+	bool autoDelete_; ///< determines whether finished process objects are deleted
+	SimulationId uniqueId_; ///< stores a unique identifier for each simulation
+
+private:
+
+	friend class Process;
+	friend class Event;
+	friend class Scheduler;
+
+	/**
+		\name Process/Event Management
+		@{
+	*/
+	void setCurrentSched( Sched* s );
+	void setCurrentProcess( Process* p );
+	void setProcessAsCreated( Process* p );
+	void setProcessAsRunnable( Process* p );
+	void setProcessAsIdle( Process* p );
+	void setProcessAsTerminated( Process* p );
+	//@}
+
+	/**
+		\name Help procedures
+		@{
+	*/
+	void init();
+	void removeProcessFromList( Process* p );
+	void checkAutoDelete();
+	//@}
+};
+
+/** \interface SimulationObserver
+
+	\author Ralf Gerstenberger
+
+	\brief Observer for Simulation events
+
+	\since 1.0
+*/
+class SimulationObserver
+:	public coroutine::CoroutineContextObserver
+{
+public:
+	/// Construction
+//	virtual void onCreate( Simulation* sender ) {}
+
+	/// Initialisation
+	virtual void onInitialization( Simulation* sender ) {}
+	/// Termination
+	virtual void onExitSimulation( Simulation* sender ) {}
+	/// Run simulation
+	virtual void onRun( Simulation* sender ) {}
+	/// Step through simulation
+	virtual void onStep( Simulation* sender ) {}
+	/// Run simulation until time t
+	virtual void onRunUntil( Simulation* sender, SimTime t ) {}
+
+	/**
+		\brief Change of current sched
+		\warning
+			\p oldCurrent or \p newCurrent may be 0
+	*/
+	virtual void onChangeCurrentSched( Simulation* sender,
+					Sched* oldCurrent, Sched* newCurrent ) {}
+
+	/// Process changed list
+	virtual void onChangeProcessList( Simulation* sender,
+					Process* p, Simulation::List l ) {}
+
+	/// Time change
+	virtual void onChangeTime( Simulation* sender,
+					SimTime oldTime, SimTime newTime ) {}
+};
+
+} } // namespace odemx::base
+
+#endif /* ODEMX_BASE_SIMULATION_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/TypeDefs.h b/odemx-lite/include/odemx/base/TypeDefs.h
new file mode 100644
index 0000000000000000000000000000000000000000..0c966ef71a28f30e77b24660c7fc6b720fe14f41
--- /dev/null
+++ b/odemx-lite/include/odemx/base/TypeDefs.h
@@ -0,0 +1,123 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file TypeDefs.h
+ * @author Ronald Kluth
+ * @date created at 2009/02/13
+ * @brief Declaration of types SchedList, ProcessList, Priority, SimulationId
+ * @since 3.0
+ */
+
+#ifndef ODEMX_BASE_TYPEDEFS_INCLUDED
+#define ODEMX_BASE_TYPEDEFS_INCLUDED
+
+#include <list>
+#include <functional>
+
+#include <odemx/base/SimTime.h>
+
+//----------------------------------------------------------forward declarations
+
+namespace odemx {
+namespace base {
+
+class Process;
+class Sched;
+
+//-----------------------------------------------------------header declarations
+
+/// List type to hold scheduled objects in order
+typedef std::list< Sched* > SchedList;
+
+/// List type to store process objects
+typedef std::list< Process* > ProcessList;
+
+/// ID type to provide simulation objects with unique IDs
+typedef int SimulationId; // changed in odemx-lite from Poco::UUID
+
+/**
+ * @brief Numeric type to express scheduling and queueing priority
+ *
+ * The type Priority is used to set a priority for processes and events, which
+ * allows users to influence scheduling or queueing order.
+ */
+typedef double Priority;
+
+
+/**
+	\brief Generic function type for coding conditions
+ 	\param subject
+		pointer to process upon which the condition is applied.
+
+	This generic function type is used for coding
+	conditions. The condition-function should return true
+	if the condition is fulfilled.
+
+ 	Usally use the this pointer when a Process itself passes some condition in form of lambda expression.
+*/
+typedef std::function<bool(Process* subject)> Condition;
+
+/**
+	\brief Generic function type for coding selections
+	\param master
+		pointer to master to select
+	\param slave
+		pointer to slave to select
+
+	This Generic function type is used for coding
+	selections. The condition-function should return true
+	if the \p partner process fits the selection concerning \p master.
+*/
+typedef std::function<bool(Process* master, Process* slave)> Selection;
+
+/**
+	\brief Generic function type for coding Process weight functions
+	\param master
+		pointer to master to weight
+	\param slave
+		pointer to slave to weight
+
+	This generic function type is used for coding
+	a weight function to determine the importance of the partner process.
+	The weight function should return a higher number for a higher degree
+	of importance. This type of function is used in the implementation of
+	WaitQ to synchronize processes according to their highest weight in
+	relation to each other.
+*/
+typedef std::function<double(Process* master, Process* slave)> Weight;
+
+/**
+	\brief Generic function type for coding Process weight functions
+	\param master
+		pointer to master to weight
+	\param slave
+		pointer to slave to weight
+
+	This generic function type is used for coding
+	a weight function to determine the importance of the partner process.
+	The weight function should return a higher number for a higher degree
+	of importance. This type of function is used in the implementation of
+	WaitQ to synchronize processes according to their highest weight in
+	relation to each other.
+*/
+typedef std::function<void(odemx::base::SimTime t)> Derivative;
+
+} } // namespace odemx::base
+
+#endif /* ODEMX_BASE_TYPEDEFS_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/cellular_automaton/Cell.h b/odemx-lite/include/odemx/base/cellular_automaton/Cell.h
new file mode 100644
index 0000000000000000000000000000000000000000..620d23420acd75d66286f4fdae2030a19a43cd48
--- /dev/null
+++ b/odemx-lite/include/odemx/base/cellular_automaton/Cell.h
@@ -0,0 +1,555 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Cell.h
+
+ \author Sascha Qualitz
+
+ \date created at 2010/01/05
+
+ \brief Declaration of Cell
+ \sa CellContainer, CellMonitor, Transition
+ \since 3.0
+ */
+
+#ifndef ODEMX_CELL_INCLUDED
+#define ODEMX_CELL_INCLUDED
+
+#include <vector>
+#include <list>
+#include <map>
+#include <string>
+
+namespace odemx {
+	namespace base {
+		namespace cellular {
+
+		class Cell;
+
+		class ComparePositions;
+
+	/** \class CellPosition
+
+		\ingroup base
+
+		\author Sascha Qualitz
+
+		\brief Object for handling the position of one cell in the cellular automaton.
+
+		\sa Cell
+	 */
+	class CellPosition {
+	public:
+		/** \brief Construction
+			\param row
+				row-position of the cell
+			\param column
+				column-position of the cell
+			\param level
+				level-position of the cell
+			\param cellRows
+				number of rows that belong to the grid of the cellular automaton
+			\param cellColumns
+				number of columns that belong to the grid of the cellular automaton
+			\param cellLevel
+				number of levels that belong to the grid of the cellular automaton
+		 */
+		CellPosition(unsigned row, unsigned column, unsigned level, unsigned cellRows, unsigned cellColumns, unsigned cellLevel)
+		: row(row)
+		, column(column)
+		, level(level)
+		, cellRows(cellRows)
+		, cellColumns(cellColumns)
+		, cellLevel(cellLevel)
+		{}
+
+		/** \brief Construction
+		 */
+		CellPosition()
+		: row(0)
+		, column(0)
+		, level(0)
+		, cellRows(0)
+		, cellColumns(0)
+		, cellLevel(0)
+		{}
+
+		/** \brief Sets the position of the cell.
+			\param row
+				row that belongs to the cell
+			\param column
+				column that belongs to the cell
+			\param level
+				level that belongs to the cell
+		 */
+		void setPosition(unsigned row, unsigned column = 0, unsigned level = 0) {
+			this->row = row;
+			this->column = column;
+			this->level = level;
+		}
+
+		/** \brief Sets the grid size of the cellular automaton.
+			\param cellRows
+				number of rows that belong to the grid of the cellular automaton
+			\param cellColumns
+				number of columns that belong to the grid of the cellular automaton
+			\param cellLevel
+				number of levels that belong to the grid of the cellular automaton
+		 */
+		void setGridSize(unsigned cellRows, unsigned cellColumns, unsigned cellLevel) {
+			this->cellRows = cellRows;
+			this->cellColumns = cellColumns;
+			this->cellLevel = cellLevel;
+		}
+
+		/** \brief Returns the row number that belongs to the cell.
+		 */
+		unsigned getRowNumber() {
+			return this->row;
+		}
+		/** \brief Returns the column number that belongs to the cell.
+		 */
+		unsigned getColumnNumber() {
+			return this->column;
+		}
+		/** \brief Returns the level number that belongs to the cell.
+		 */
+		unsigned getLevelNumber() {
+			return this->level;
+		}
+		/** \brief Returns the number of rows that belong to the grid of the cellular automaton.
+		 */
+		unsigned getNumberOfCellRows() {
+			return cellRows;
+		}
+		/** \brief Returns number of columns that belong to the grid of the cellular automaton.
+		 */
+		unsigned getNumberOfCellColumns() {
+			return cellColumns;
+		}
+		/** \brief Returns number of levels that belong to the grid of the cellular automaton.
+		 */
+		unsigned getNumberOfCellLevels() {
+			return cellLevel;
+		}
+	private:
+		/* row of the cell
+		 */
+		unsigned row;
+
+		/* column of the cell
+		 */
+		unsigned column;
+
+		/* level of the cell
+		 */
+		unsigned level;
+
+		/* number of rows of the grid
+		 */
+		unsigned cellRows;
+
+		/* number of columns of the grid
+		 */
+		unsigned cellColumns;
+
+		/* number of levels of the grid
+		 */
+		unsigned cellLevel;
+
+		friend class Cell;
+		friend class ComparePositions;
+	};
+
+	/** \class ComparePositions
+
+		\ingroup base
+
+		\author Sascha Qualitz
+
+		\brief Object for handling comparisons between to CellPosition-objects.
+
+		\sa Cell
+	 */
+	class ComparePositions {
+	public:
+		/** \brief Overrides the ()-operator to compare two CellPosition-objects.
+			\param cellPosition1
+				first object to compare
+			\param cellPosition2
+				second object to compare
+		 */
+		bool operator()(const CellPosition& cellPosition1, const CellPosition& cellPosition2) {
+			return (cellPosition1.cellRows*(cellPosition1.level*cellPosition1.cellColumns + cellPosition1.column) + cellPosition1.row) <
+						(cellPosition2.cellRows*(cellPosition2.level*cellPosition2.cellColumns + cellPosition2.column) + cellPosition2.row);
+		}
+	};
+
+	//forward declaration
+	class CellVariablesContainer;
+	class CellMonitor;
+	class Transition;
+
+	struct typeOfNeighborhood;
+
+		/** \class Cell
+
+			\ingroup base
+
+			\author Sascha Qualitz
+
+			\brief Object for handling one cell in the grid of the cellular automaton.
+
+			\sa CellMonitor, CellVariablesContainer, Transition
+		 */
+		class Cell {
+		public:
+			/** \brief Construction
+				\param row
+					row-position of the cell
+				\param column
+					column-position of the cell
+				\param level
+					level-position of the cell
+				\param dimension
+					number of the state variables of this cell
+				\param inputDimension
+					number of the input variables of this cell
+				\param outputDimension
+					number of the output variables of this cell
+				\param monitor
+					the monitor which manages this cell
+			 */
+			Cell(unsigned row, unsigned column, unsigned level, unsigned dimension, unsigned inputDimension, unsigned outputDimension, CellMonitor* monitor);
+
+			/// destruction
+			virtual ~Cell();
+
+			/** \brief Calculates the cells in the neighborhood of one cell. Different neighborhood types can be used.
+			   	\note See CellMonitor.h for possible neighborhood types.
+			 */
+			void calculateNeighborhood();
+
+			/** \brief Pushes the values for neighbor cells.
+			 */
+			void pushValue();
+
+			/** \brief Returns the output values from neighbor cells.
+			    \param variableIndex
+					index of the variables (range 0...(outputDimension-1))
+			 */
+			std::vector<double> pullValue(unsigned variableIndex);
+
+			/** \brief Sets the value of one state variable.
+				\param variableIndex
+					index of the variable to be set to the \p value (range 0...(stateDimension-1))
+				\param value
+					the value to be set
+			 */
+			void setValue(unsigned variableIndex, double value);
+
+			/** \brief Returns the value of one state variable.
+				\param variableIndex
+					index of the returned variable (range 0...(stateDimension-1))
+			 */
+			double getValue(unsigned variableIndex);
+
+			/** \brief Sets the value of one output variable.
+				\param variableIndex
+					index of the variable to be set to the \p value (range 0...(outputDimension-1))
+				\param value
+					the value to be set
+			 */
+			void setOutputValue(unsigned variableIndex, double value);
+
+			/** \brief Returns the value of one output variable.
+				\param variableIndex
+					index of the returned variable (range 0...(outputDimension-1))
+			 */
+			double getOutputValue(unsigned variableIndex);
+
+			/** \brief Sets the value of one input variable.
+				\param variableIndex
+					index of the variable to be set to the \p value (range 0...(inputDimension-1))
+				\param value
+					the value to be set
+			 */
+			void setInputValue(unsigned variableIndex, double value);
+
+			/** \brief Returns the value of one input variable.
+				\param variableIndex
+					index of the returned variable (range 0...(inputDimension-1))
+			 */
+			double getInputValue(unsigned variableIndex);
+
+			/** \brief Sets the transition object which contains the transition and output function of the cell.
+				\param transition
+					transition and output function of the cell
+			 */
+			void setTransition(Transition* transition);
+
+			/** \brief Deletes transition object which contains the transition and output function of the cell.
+				\param transition
+					transition and output function of the cell
+			 */
+			void deleteTransition(Transition* transition);
+
+			/** \brief Returns the dimension of the state variables.
+			 */
+			unsigned getDimension();
+
+			/** \brief Returns the dimension of the input variables.
+			 */
+			unsigned getInputDimension();
+
+			/** \brief Returns the dimension of the output variables.
+			 */
+			unsigned getOutputDimension();
+
+			/** \brief Makes the cell part of the boundary.
+			 */
+			void setIsBoundary();
+
+			/** \brief Is showing if the cell is part of the boundary or not (true means is part of the boundary and false means regular cell).
+			 */
+			bool isPartOfBoundary();
+
+			/** \brief Sets the position of the cell.
+			    \param row
+					row that belongs to the cell
+				\param column
+					column that belongs to the cell
+				\param level
+					level that belongs to the cell
+			 */
+			void setPosition(unsigned row, unsigned column = 0, unsigned level = 0);
+
+			/** \brief Returns a CellPosition-object-pointer with the position of the cell.
+			 */
+			CellPosition* getPosition();
+
+			/** \brief Sets the settings for the neighborhood.
+				\param neighborhoodType
+					type of the neighborhood
+				\param radius
+					radius of the neighborhood (1,....)
+				\param calcNeighborhood
+					if true the neighborhood must be calculated again after setting
+
+				\note For possible values of neighborhoodType take a look in CellMonitor.h
+					  The default values are neighborhoodType = MOORE and radius = 1.
+			 */
+			void setNeighborhoodSettings(unsigned neighborhoodType, unsigned radius, bool calcNeighborhood = true);
+
+			/** \brief Returns a map with pointers to the cells in the neighborhood of one cell characterized by the position (saved in the key of the map).
+			*/
+			std::map<CellPosition, Cell*, ComparePositions> getNeighbors();
+
+			/** \brief It returns a cell-object-pointer if the cell with given position is in the neighborhood. Otherwise it returns 0.
+				\param row
+						row-position of the cell
+				\param column
+						column-position of the cell
+				\param level
+						level-position of the cell
+			 */
+			Cell* searchNeighbor(unsigned row, unsigned column = 0, unsigned level = 0);
+
+		private:
+			/**
+			   \brief Calculates the Moore neighborhood of the cell.
+			   		  N_(i,j)={(k,l) \in L | |k-i| <= r and |l-j| <= r }
+			   \param radius
+			   		radius of the neighborhood
+			 */
+			void calculateMooreNeighborhood(unsigned radius = 1);
+
+			/**
+			   \brief Calculates the Von-Neumann-neighborhood of the cell.
+			   		  N_(i,j)={(k,l) \in L | |k-i| + |l-j| <= r }
+			   \param radius
+			   		radius of the neighborhood
+			 */
+			void calculateVonNeumannNeighborhood(unsigned radius = 1);
+
+			/**
+			   \brief Calculates the Moore neighborhood of the cell. The grid of the cellular automaton is a 2-d-grid which forms a torus.
+			   	   	  That means along the x-axis and the y-axis the grid has periodic boundaries.
+					  N_(i,j)={(k,l) \in L | |k-i| <= r and |l-j| <= r }
+			   \param radius
+					radius of the neighborhood
+			 */
+			void calculateMoore2DTorusNeighborhood(unsigned radius = 1);
+
+			/**
+			   \brief Calculates the Moore neighborhood of the cell. The grid of the cellular automaton is a 2-d-grid which forms a tube.
+			   	   	  That means along the x-axis the grid has periodic boundaries.
+					  N_(i,j)={(k,l) \in L | |k-i| <= r and |l-j| <= r }
+			   \param radius
+					radius of the neighborhood
+			 */
+			void calculateMoore2DXAxisTubeNeighborhood(unsigned radius = 1);
+
+			/**
+			   \brief Calculates the Moore neighborhood of the cell. The grid of the cellular automaton is a 2-d-grid which forms a tube.
+			   	   	  That means along the y-axis the grid has periodic boundaries.
+					  N_(i,j)={(k,l) \in L | |k-i| <= r and |l-j| <= r }
+			   \param radius
+					radius of the neighborhood
+			 */
+			void calculateMoore2DYAxisTubeNeighborhood(unsigned radius = 1);
+
+			/**
+			   \brief Calculates the Von-Neumann-neighborhood of the cell. The grid of the cellular automaton is a 2-d-grid which forms a torus.
+			   	   	  That means along the x-axis and the y-axis the grid has periodic boundaries.
+					  N_(i,j)={(k,l) \in L | |k-i| + |l-j| <= r }
+			   \param radius
+					radius of the neighborhood
+			 */
+			void calculateNeumann2DTorusNeighborhood(unsigned radius = 1);
+
+			/**
+			   \brief Calculates the Von-Neumann-neighborhood of the cell. The grid of the cellular automaton is a 2-d-grid which forms a tube.
+			   	   	  That means along the x-axis the grid has periodic boundaries.
+					  N_(i,j)={(k,l) \in L | |k-i| + |l-j| <= r }
+			   \param radius
+					radius of the neighborhood
+			 */
+			void calculateNeumann2DXAxisTubeNeighborhood(unsigned radius = 1);
+
+			/**
+			   \brief Calculates the Von-Neumann-neighborhood of the cell. The grid of the cellular automaton is a 2-d-grid which forms a tube.
+			   	   	  That means along the y-axis the grid has periodic boundaries.
+					  N_(i,j)={(k,l) \in L | |k-i| + |l-j| <= r }
+			   \param radius
+					radius of the neighborhood
+			 */
+			void calculateNeumann2DYAxisTubeNeighborhood(unsigned radius = 1);
+
+			/**
+			   \brief Calculates the user-defined-neighborhood of the cell. The user has to define this neighborhood in a class, which is derived from the class Transition.
+			   \param radius
+					radius of the neighborhood
+			 */
+			void calculateAlternativeNeighborhood(unsigned radius = 1);
+
+			/** \brief Checks if an index exceeds the corresponding index boundary and throws an index out of bounds exception.
+			 	\param index
+					the index will be checked using the variable indexBoundary
+				\param indexBoundary
+					the value of the index boundary
+				\param std::string what
+					which index is out of boundary
+			*/
+			void checkIndexBoundary(unsigned index, unsigned indexBoundary, std::string what);
+
+			/** \brief Sets the base index of the state variables of the cell
+				\param baseIndex
+					 state base index of the cell
+			 */
+			void setBaseIndex(unsigned baseIndex);
+
+			/** \brief Sets the input base index of the input variables of the cell.
+				\param baseIndex
+					input base index of the cell
+			 */
+			void setInputBaseIndex(unsigned baseIndex);
+
+			/** \brief Sets the output base index of the output variables of the cell.
+				\param baseIndex
+					output base index of the cell
+			 */
+			void setOutputBaseIndex(unsigned baseIndex);
+
+			/** \brief Returns the base index of the state variables of the cell.
+			 */
+			unsigned getBaseIndex();
+
+			/** \brief Returns the base index of the input variables of the cell.
+			 */
+			unsigned getInputBaseIndex();
+
+			/** \brief Returns the base index of the output variables of the cell.
+			 */
+			unsigned getOutputBaseIndex();
+
+			/** \brief Sets the monitor to whom the Cell-object belongs.
+				\param monitor
+					monitor of the cellular automaton
+			 */
+			void setMonitor(CellMonitor* monitor);
+
+			/** \brief Returns the monitor to whom the Cell-object belongs.
+			 */
+			CellMonitor* getMonitor();
+
+		private:
+
+			// Monitor to whom the cell belongs.
+			CellMonitor* monitor;
+
+			// This object saves the indexes of the cell and the grid size of the cellular automaton.
+			CellPosition* cellPosition;
+
+		   /** \brief This structure saves the settings for the neighborhood of the cell.
+				\param
+					radius of the neighborhood (1,....)
+				\param neighborhoodType
+					type of the neighborhood
+
+				\note For possible values of neighborhoodType take a look in CellMonitor.h
+					  The default values are neighborhoodType = MOORE and radius = 1.
+			 */
+			struct neighborhoodSettings
+			{
+				unsigned neighborhoodType;
+				unsigned radius;
+			} typeOfNeighborhood;
+
+			// Base indexes of the input, output and state variables of the cell.
+			unsigned int stateBaseIndex;
+			unsigned int inputBaseIndex;
+			unsigned int outputBaseIndex;
+
+			// Dimensions of the input, output and state variables of the cell.
+			unsigned int stateDimension;
+			unsigned int inputDimension;
+			unsigned int outputDimension;
+
+			// Map of the Cell-object-pointers in the neighborhood.
+			std::map<CellPosition, Cell*, ComparePositions> neighborhoodCellsMap;
+
+			// List of all transition functions which belong to this instance.
+			std::list<Transition*> transitions;
+
+			/** \brief Transition object to compute state changes and handle alternative neighborhoods.
+			*/
+			//Transition* transition;TODO!!
+
+			// Is showing if the cell is part of the boundary or not.
+			bool isBoundary;
+
+			// Is showing if the cell received values from neighborhood cells.
+			bool pushed;
+
+			friend class CellMonitor;
+		};
+	}
+}
+}
+#endif
diff --git a/odemx-lite/include/odemx/base/cellular_automaton/CellMonitor.h b/odemx-lite/include/odemx/base/cellular_automaton/CellMonitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..3d1423a95815c2bae604d6b9d9ed80bcc4091d14
--- /dev/null
+++ b/odemx-lite/include/odemx/base/cellular_automaton/CellMonitor.h
@@ -0,0 +1,473 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file CellMonitor.h
+
+ \author Sascha Qualitz
+
+ \date created at 2010/01/05
+
+ \brief Declaration of CellMonitor
+
+ \since 3.0
+ */
+
+#ifndef ODEMX_CELLMONITOR_INCLUDED
+#define ODEMX_CELLMONITOR_INCLUDED
+
+#include <list>
+#include <odemx/base/Process.h>
+#include <odemx/base/cellular_automaton/Transition.h>
+
+// Use these macros to define a neighborhood type.
+#define MOORE 0
+#define NEUMANN 1
+#define MOORETORUS 2
+#define NEUMANNTORUS 3
+#define MOOREXTUBE 4
+#define NEUMANNXTUBE 5
+#define MOOREYTUBE 6
+#define NEUMANNYTUBE 7
+#define ALTERNATIVENEIGHBORHOOD 8
+
+#define ROWSPAN(FROM, TO) CellIndexSpan(FROM, TO)
+#define COLUMNSPAN(FROM, TO) CellIndexSpan(FROM, TO)
+#define LEVELSPAN(FROM, TO) CellIndexSpan(FROM, TO)
+
+// Use this macro to set one transition object to the cells given by the from and to parameters of the macro.
+#define _setTransitionToCells(rowIndexSpan, columnIndexSpan, levelIndexSpan, monitorName, transitionType) { \
+	if(rowIndexSpan.getIndexTo() > monitorName->getRowCount()-1) {\
+		throw std::out_of_range("The right side of the row index span is greater than the number of rows");\
+	}\
+	if(rowIndexSpan.getIndexFrom() < 0) {\
+		throw std::out_of_range("The left side of the row index span is less than 0");\
+	}\
+	if(columnIndexSpan.getIndexTo() > monitorName->getColumnCount()-1) {\
+		throw std::out_of_range("The right side the column index span is greater than the number of columns");\
+	}\
+	if(columnIndexSpan.getIndexFrom() < 0) {\
+		throw std::out_of_range("The left side the column index span is less than 0");\
+	}\
+	if(levelIndexSpan.getIndexTo() > monitorName->getLevelCount()-1) {\
+		throw std::out_of_range("The right side the level index span is greater than the number of levels");\
+	}\
+	if(levelIndexSpan.getIndexFrom() < 0) {\
+		throw std::out_of_range("The left side the level index span is less than 0");\
+	}\
+	for (int i = rowIndexSpan.getIndexFrom(); i <= rowIndexSpan.getIndexTo(); i++) { \
+		for (int j = columnIndexSpan.getIndexFrom(); j <= columnIndexSpan.getIndexTo(); j++) { \
+			for (int k = levelIndexSpan.getIndexFrom(); k <= levelIndexSpan.getIndexTo(); k++) { \
+				monitorName->getCell(monitorName->getLevelCount() * (monitorName->getColumnCount() * i + j) + k)->setTransition(new transitionType());\
+			} \
+		} \
+	} \
+}
+
+namespace odemx {
+	namespace base {
+		namespace cellular {
+		/** \class CellPosition
+
+			\ingroup base
+
+			\author Sascha Qualitz
+
+			\brief Object for handling the index span of row, column and level span in the cellular automaton.
+
+			\sa CellMonitor
+		 */
+		class CellIndexSpan {
+		public:
+			/** \brief Construction
+				\param indexFrom
+					start-index of the span
+				\param indexTo
+					end-index of the span
+			 */
+			CellIndexSpan(unsigned indexFrom, unsigned indexTo)
+			: indexFrom(indexFrom)
+			, indexTo(indexTo)
+			{}
+
+			/** \brief Returns the first value of the index span.
+			 */
+			unsigned getIndexFrom() {
+				return this->indexFrom;
+			}
+			/** \brief Returns the second value of the index span.
+			 */
+			unsigned getIndexTo() {
+				return this->indexTo;
+			}
+
+		private:
+			/* row of the cell
+			 */
+			unsigned indexFrom;
+
+			/* column of the cell
+			 */
+			unsigned indexTo;
+		};
+
+		//forward declaration
+		class CellVariablesContainer;
+
+		class Cell;
+
+		class Transition;
+
+		class CellMonitorObserver;
+
+		/** \class CellMonitor
+
+			\ingroup base
+
+			\author Sascha Qualitz
+
+			\note %CellMonitor supports Observation.
+			\note %CellMonitor supports Trace.
+			\note %CellMonitor supports Logging.
+
+			\brief A CellMonitor is used to generate a cellular automaton and manage it during a simulation.
+
+			%One have to use the getter-methods to get one cell object to make changes on it.
+
+			\sa CellularAutomaton, CellVariablesContainer, Cell, Transition, Process
+
+			\since 3.0
+		 */
+		class CellMonitor : public Process, public data::Observable<CellMonitorObserver> {
+		public:
+			/** \brief Construction
+				\param sim
+					reference to one simulation-object
+				\param l
+					label of this object
+				\param variablesInCount
+					number of the input variables of the cells
+				\param variablesOutCount
+					number of the output variables of the cells
+				\param cellRows
+					number of rows of the grid
+				\param cellColumns
+					number of columns of the grid
+				\param cellLevel
+					number of levels of the grid
+				\param timestep
+					size of the time step
+				\param cellDimension
+					number of the state variables of the cells
+				\param o
+					initial observer
+			 */
+			CellMonitor(Simulation& sim, const data::Label& l, unsigned variablesInCount, unsigned variablesOutCount, unsigned cellRows, unsigned cellColumns, unsigned cellLevel, double timestep, unsigned cellDimension, ProcessObserver* o = 0);
+
+			/** \brief Construction used with configuration file
+				\param sim
+					reference to one simulation-object
+				\param l
+					label of this object
+				\param fileName
+					name of the configuration file which contains settings like grid size of the cellular automaton
+				\param o
+					initial observer
+			 */
+			CellMonitor(Simulation& sim, const data::Label& l, const char*const configFileName, ProcessObserver* o = 0);
+
+			/** \brief Construction used with configuration file
+				\param sim
+					reference to one simulation-object
+				\param l
+					label of this object
+				\param configFileName
+					name of the configuration file which contains settings like grid size of the cellular automaton
+				\param startDataFileName
+					name of the configuration file which contains settings like the start values or individual neighborhood settings of all cells
+				\param o
+					initial observer
+			 */
+			CellMonitor(Simulation& sim, const data::Label& l, const char*const configFileName, const char*const startDataFileName, ProcessObserver* o = 0);
+
+			/// destruction
+			~CellMonitor();
+
+			/** \brief Calculating the evolution of the cellular automaton.
+				\note This will be called by the Simulation-object.
+			 */
+			int main();
+
+			/** \brief Sets the time limit when the monitor has to finish the main method.
+				\param time
+					time to stop monitor
+			 */
+			void setTimeLimit(SimTime time);
+
+			/** \brief Returns the time limit.
+			 */
+			SimTime getTimeLimit();
+
+			/** \brief Sets one transition object to all Cell-objects.
+			 */
+			void setTransitionToCells(Transition* transition);
+
+			/** \brief Function for printing values.
+			 */
+			double* getValues();
+
+			/** \brief Returns the number of rows that belong to the grid of the cellular automaton.
+			*/
+			unsigned getRowCount();
+
+			/** \brief Returns the number of columns that belong to the grid of the cellular automaton.
+			*/
+			unsigned getColumnCount();
+
+			/** \brief Returns the number of levels that belong to the grid of the cellular automaton.
+			*/
+			unsigned getLevelCount();
+
+			/** \brief Adds one cell with given coordinates (row, column, level) to the boundary.
+				\param row
+					row that belongs to the cell
+				\param column
+					column that belongs to the cell
+				\param level
+					level that belongs to the cell
+			 */
+			void setIsBoundaryCell(unsigned row, unsigned column, unsigned level);
+
+			/** \brief Sets the state value of one cell with given coordinates (row, column, level).
+				\param row
+					row that belongs to the cell
+				\param column
+					column that belongs to the cell
+				\param level
+					level that belongs to the cell
+				\param variableIndex
+					index of the variable with a range of 0 to dimension-1
+				\param value
+					the value to be set
+			 */
+			void setCellValue(unsigned row, unsigned column, unsigned level, unsigned variableIndex, double value);
+
+			/** \brief Returns the output value of one cell with given coordinates (row, column, level) and given variable index.
+				\param row
+					row that belongs to the cell
+				\param column
+					column that belongs to the cell
+				\param level
+					level that belongs to the cell
+				\param variableIndex
+					index of the variable with a range of 0 to dimension-1
+			 */
+			double getCellValue(unsigned row, unsigned column, unsigned level, unsigned variableIndex);
+			
+			/** \brief Returns the global neighborhood type.
+			 	\note If different cells have different neighborhood types don't use this function.
+			 */
+			unsigned getNeighborhoodType();
+
+			/** \brief Returns the radius of the neighborhood.
+			 	\note If different cells have different neighborhood radiuses don't use this function.
+			 */
+			unsigned getNeighborhoodRadius();
+
+			/** \brief Returns a pointer to one cell-object with given coordinates (row, column, level).
+				\param row
+					row that belongs to the cell
+				\param column
+					column that belongs to the cell
+				\param level
+					level that belongs to the cell
+			 */
+			Cell* getCell(unsigned row, unsigned column = 0, unsigned level = 0);
+
+		private:
+			/** \brief Returns a pointer to one cell with given index in the cell vector.
+				\param cellIndex
+					index of one cell in the cell vector (cellIndex = cellRows * (cellColumns * level + column) + row)
+
+				\note This method is for internal use only.
+			 */
+			Cell* getCell_(unsigned cellIndex);
+
+			/** \brief Sets the settings for the neighborhood.
+				\param neighborhoodType
+					type of the neighborhood
+				\param radius
+					radius of the neighborhood (1,....)
+
+				\note For possible values of neighborhoodType take a look in CellMonitor.h
+					  The default values are neighborhoodType = MOORE and radius = 1.
+			 */
+			void setNeighborhoodSettings(unsigned neighborhoodType, unsigned radius);
+
+			/** \brief Sets parameters used by CellMonitor to create the cellular automaton with given file name.
+				\param fileName
+					name or rather path of the configuration file
+			 */
+			void setParameterFromConfigFile(const std::string fileName = "cellmonitor_config.xml");
+
+			/** \brief Sets parameters of the cellular automaton like start values and neighborhood settings with given file name.
+				\param fileName
+					name or rather path of the configuration file
+			 */
+			void setStartDataFromConfigFile(std::string fileName = "ca_start_data.xml");
+
+			/** \brief Creates a cellular automaton with the given numbers of rows, columns and levels.
+			 	\param rows
+					number of rows that belong to the grid of the cellular automaton
+				\param columns
+					number of columns that belong to the grid of the cellular automaton
+				\param level
+					number of levels that belong to the grid of the cellular automaton
+
+				TODO cellDimension entfernen!!!!
+			 */
+			void generateCellularAutomaton(unsigned rows, unsigned  columns, unsigned level, unsigned cellDimension);
+
+			/** \brief Calculates the neighborhood of all cells.
+			 */
+			void calculateNeighboorhood();
+
+		private:
+			/** \brief This structure saves the settings for the global neighborhood.
+				\param
+					radius of the neighborhood (1,....)
+				\param neighborhoodType
+			   		type of the neighborhood
+
+			   	\note For possible values of neighborhoodType take a look in CellMonitor.h
+					  The default values are neighborhoodType = MOORE and radius = 1.
+			 */
+			struct neighborhoodSettings
+			{
+				unsigned neighborhoodType;
+				unsigned radius;
+			} typeOfNeighborhood;
+
+			// Number of input, output and state variables which belong to a cell of the cellular automaton, stored in the values arrays.
+			unsigned cellDimension;
+			unsigned variablesInCount;
+			unsigned variablesOutCount;
+
+			// Number of rows, columns and levels that belong to the grid of the cellular automaton.
+			unsigned cellRows;
+			unsigned cellColumns;
+			unsigned cellLevel;
+
+			// Variables container used by CellMonitor for managing variables of the cells.
+			CellVariablesContainer* cellVariablesContainer;
+
+			// Vector of all cell objects.
+			std::vector<Cell*> cellVector;
+
+			// Size of every time step.
+			double timestep;
+
+			// The time limit.
+			SimTime timeLimit;
+
+			/** \brief Triggers the observer to write the input, output and state variables.
+			 */
+			void notifyValidState();
+
+			friend class Cell;
+
+			friend class CellMonitorTrace;
+		};
+
+		//forward declaration
+		class CellPosition;
+
+		/** \interface CellMonitorObserver
+
+			\author Sascha Qualitz
+
+			\brief Observer for CellMonitor specific events
+
+			\since 3.0
+		*/
+		class CellMonitorObserver:
+			public ProcessObserver
+		{
+		public:
+			// destruction
+			virtual ~CellMonitorObserver(){};
+
+//			virtual void onCreate( CellMonitor* sender ){} ///< Construction
+
+			virtual void onNewValidState( CellMonitor* sender ){} ///< New valid state
+
+			virtual void onBeginCalcStateChanges( CellMonitor* sender ){} ///< Monitor calculates the state changes
+			virtual void onEndCalcStateChanges( CellMonitor* sender ){} ///< Monitor ended one calculation step
+
+			virtual void onSetTimeLimit(CellMonitor* sender, SimTime time){} ///< time changed
+
+			virtual void onSetTransitionToCells(CellMonitor* sender){} ///< one transition was set to all cells
+			virtual void onSetNeighborhoodSettings(CellMonitor* sender, unsigned neighborhoodType, unsigned radius){} ///< neighborhood settings
+			virtual void onSetNeighborhoodType(CellMonitor* sender, unsigned neighborhoodType, CellPosition* position){} ///< neighborhood type
+			virtual void onSetNeighborhoodRadius(CellMonitor* sender, unsigned neighborhoodRadius, CellPosition* position){} ///< neighborhood radius
+
+			virtual void onGenerateCellularAutomaton(CellMonitor* sender){} ///< generate cellular automaton
+			virtual void onCalculateNeighboorhood(CellMonitor* sender){} ///< calculate neighborhood
+		};
+
+		/** \class CellMonitorTrace
+
+			\author Sascha Qualitz
+
+			\brief Trace for cell state changes of the cellular automaton controlled by the monitor.
+
+			\sa Cell, CellMonitorObserver, CellMonitor
+
+			%CellMonitorTrace logs the state changes of the cells in the cellular automaton
+			into a xml file. The xml file is automatically opened and closed.
+
+			\since 3.0
+		*/
+		class CellMonitorTrace
+		:	public CellMonitorObserver
+		{
+			public:
+				/// Construction
+			CellMonitorTrace( CellMonitor* cellMonitor = 0, const std::string& fileName = "" );
+				/// Destruction
+				virtual ~CellMonitorTrace();
+
+				/// Follow state changes
+				virtual void onNewValidState( CellMonitor* sender );
+
+			private:
+				// Implementation
+				std::ostream* out;
+				bool firstTime;
+				const std::string& fileName;
+
+				CellMonitor* cellMonitor;
+
+				void openFile( const std::string& fileName );
+		};
+
+	}
+}
+}
+
+#endif
+
diff --git a/odemx-lite/include/odemx/base/cellular_automaton/CellVariablesContainer.h b/odemx-lite/include/odemx/base/cellular_automaton/CellVariablesContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..daf6b9b623513f257964b49bb313d4ebe43e05c0
--- /dev/null
+++ b/odemx-lite/include/odemx/base/cellular_automaton/CellVariablesContainer.h
@@ -0,0 +1,163 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file CellVariablesContainer.h
+
+ \author Sascha Qualitz
+
+ \date created at 2010/01/05
+
+ \brief Declaration of CellVariablesContainer
+
+ \since 3.0
+ */
+
+#ifndef ODEMX_CELLVARIABLESCONTAINER_INCLUDED
+#define ODEMX_CELLVARIABLESCONTAINER_INCLUDED
+
+namespace odemx {
+	namespace base {
+		namespace cellular {
+
+		/** \class CellVariablesContainer
+
+			\ingroup base
+
+			\brief Abstract class for implementing memory handling of the cells in a cellular automaton.
+
+			\sa Cell, CellMonitor, Transition
+
+			\since 3.0
+		 */
+		class CellVariablesContainer {
+		private:
+			/** \brief Construction
+				\param cellRows
+					number of rows that belong to the grid of the cellular automaton
+				\param cellColumns
+					number of columns that belong to the grid of the cellular automaton
+				\param cellLevel
+					number of levels that belong to the grid of the cellular automaton
+				\param variablesInCount
+					number of the input variables of the cells
+				\param variablesOutCount
+					number of the output variables of the cells
+				\param cellDimension
+					number of the state variables of the cells
+			*/
+			CellVariablesContainer(unsigned cellRows, unsigned cellColumns, unsigned cellLevel, unsigned variablesInCount, unsigned variablesOutCount, unsigned cellDimension);
+
+			/// destruction
+			virtual ~CellVariablesContainer();
+
+			/** \brief Sets output value of one variable.
+				\param baseIndex
+					base index for variables of cell objects
+				\param variableIndex
+					index of the variable to be set to the \p value
+				\param value
+					the value to be set
+			 */
+			virtual void setOutputValue(unsigned baseIndex, unsigned variableIndex, double value);
+
+			/** \brief Sets state value of one variable.
+				\param baseIndex
+					base index for variables of cell objects
+				\param variableIndex
+					index of the variable to be set to the \p value
+				\param value
+					the value to be set
+			 */
+			virtual void setStateValue(unsigned baseIndex, unsigned variableIndex, double value);
+
+			/** \brief Sets input value of one variable.
+				\param baseIndex
+					base index for variables of cell objects
+				\param variableIndex
+					index of the variable to be set to the \p value
+				\param value
+					the value to be set
+			 */
+			virtual void setInputValue(unsigned baseIndex, unsigned variableIndex, double value);
+
+			/** \brief Returns output value of one variable.
+				\param baseIndex
+					base index for variables of cell objects
+				\param variableIndex
+					index of the returned variable
+			 */
+			virtual double getOutputValue(unsigned baseIndex, unsigned variableIndex);
+
+			/** \brief Returns state value of one variable.
+				\param baseIndex
+					base index for variables of cell objects
+				\param variableIndex
+					index of the returned variable
+			 */
+			virtual double getStateValue(unsigned baseIndex, unsigned variablesIndex);
+
+			/** \brief Returns input value of one variable.
+				\param baseIndex
+					base index for variables of cell objects
+				\param variableIndex
+					index of the returned variable
+			 */
+			virtual double getInputValue(unsigned baseIndex, unsigned variableIndex);
+
+			/** \brief Returns the number of rows that belong to the grid of the cellular automaton.
+			 */
+			unsigned getNumberOfRows();
+
+			/** \brief Returns the number of columns that belong to the grid of the cellular automaton.
+			 */
+			unsigned getNumberOfColumns();
+
+			/** \brief Returns the number of level that belong to the grid of the cellular automaton.
+			 */
+			unsigned getNumberOfLevels();
+
+			/**
+			 * \brief Function for printing values.
+			 */
+			double* getOutputValues();
+
+		private:
+			// Number of rows, columns and levels that belong to the grid of the cellular automaton.
+			unsigned cellRows;
+			unsigned cellColumns;
+			unsigned cellLevel;
+
+			// Number of input, output and state variables which belong to a cell of the cellular automaton, stored in the values arrays.
+			unsigned variablesInCount;
+			unsigned variablesOutCount;
+			unsigned cellDimension;
+
+			// Arrays which stores the input, output and state variables which belong to a cell of the cellular automaton.
+			double* input_values;
+			double* state_values;
+			double* output_values;
+
+			friend class CellMonitor;
+
+			friend class Cell;
+		};
+
+	}
+}
+}
+#endif
diff --git a/odemx-lite/include/odemx/base/cellular_automaton/Transition.h b/odemx-lite/include/odemx/base/cellular_automaton/Transition.h
new file mode 100644
index 0000000000000000000000000000000000000000..914b79a44890d9f4df6b2f72645a860bbf7f595b
--- /dev/null
+++ b/odemx-lite/include/odemx/base/cellular_automaton/Transition.h
@@ -0,0 +1,164 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Transition.h
+
+ \author Sascha Qualitz
+
+ \date created at 2010/01/05
+
+ \brief Abstract class to derive a representation of one transition of a cell in the cellular automaton.
+ \sa Cell, CellMonitor
+ \since 3.0
+ */
+
+#ifndef ODEMX_TRANSITION_INCLUDED
+#define ODEMX_TRANSITION_INCLUDED
+
+#include <string>
+#include <exception>
+#include <map>
+#include <odemx/base/SimTime.h>
+#include <odemx/base/TypeDefs.h>
+#include <odemx/base/cellular_automaton/Cell.h>
+
+using namespace odemx::base;
+
+namespace odemx {
+	namespace base {
+		namespace cellular {
+
+		//forward declaration
+		class CellMonitor;
+
+		class Cell;
+
+		struct typeOfNeighborhood;
+
+		/** \class NotAssignedException
+
+			\ingroup base
+
+			\author Sascha Qualitz
+
+			\brief Exception for methods which fails, because there is missingObject assigned for this object
+
+			\since 3.0
+		 */
+		class NotAssignedException : public std::exception {
+		public:
+			/// Constructor
+			NotAssignedException(const char* missingObject, const char* object);
+
+			/// Destructor
+			~NotAssignedException() throw();
+
+			/// give message for exception
+			const char* what() const throw();
+
+		private:
+			std::string msg;	//saves the Exception message
+		};
+
+			/** \class Transition
+
+				\ingroup base
+
+				\author Sascha Qualitz
+
+				\brief Object for handling a transition function
+
+				%Transition is a base class for all user defined transition functions.
+				It provides the functionality to compute state changes for one cell.
+				In addition one can define an output function here. It configures which
+				state variables other cells can use to compute their state changes.
+
+				\sa CellMonitor, Cell
+
+				\since 3.0
+			 */
+			class Transition
+			{
+			public:
+				/** \brief Construction
+				 */
+				Transition();
+
+				/// destruction
+				virtual ~Transition();
+			protected:
+				/** \brief Calculates the transition function based on the own values and influences of other cells.
+					\param time
+						time
+				 */
+				virtual void transitionFunction(SimTime time) = 0;
+
+				/** \brief Configures which state variables other cells can use to compute their state changes.
+				  	\note Optional one can rewrite this method. Default of this method is copying the state values to the output array.
+				 */
+				virtual void outputFunction();
+
+				/** \brief Calculates an user-defined neighborhood.
+				 	\param radius
+						radius of the neighborhood
+				 */
+				virtual std::map<CellPosition, Cell*, ComparePositions> calculateAlternativeNeighborhood(unsigned radius = 1);
+
+				/** \brief Sets the cell-object.
+					\param cell
+						the cell to set
+				 */
+				void setCell(Cell* cell);
+
+				/** \brief Returns state variable of the cell belonging to this transition object.
+					\param variableIndex
+						index of the variable to get \p value
+				 */
+				double getValue(unsigned variableIndex = 0);
+
+				/** \brief Sets value of one variable of the cell belonging to the transition object
+					\param variableIndex
+						index of the variable to be set to the \p value
+					\param value
+						the value to be set
+				 */
+				void setValue(unsigned variableIndex, double value);
+
+				/** \brief Returns a cell-object-pointer if the cell with given position is in the neighborhood. Otherwise it returns 0.
+					\param row
+							row-position of the cell
+					\param column
+							column-position of the cell
+					\param level
+							level-position of the cell
+				 */
+				Cell* searchNeighbor(unsigned row, unsigned column = 0, unsigned level = 0);
+
+			protected:
+
+				// Cell-object, where the transition function belongs to.
+				Cell* cell;
+
+				friend class Cell;
+
+				friend class CellMonitor;
+			};
+		}
+	}
+}
+#endif
diff --git a/odemx-lite/include/odemx/base/continuous/Continuous.h b/odemx-lite/include/odemx/base/continuous/Continuous.h
new file mode 100644
index 0000000000000000000000000000000000000000..fbb4ac8481387dc3186319c5373820f389b83658
--- /dev/null
+++ b/odemx-lite/include/odemx/base/continuous/Continuous.h
@@ -0,0 +1,410 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004, 2007, 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Continuous.h
+
+ \author Michael Fiedler
+
+ \date created at 2008/11/21
+
+ \brief Declaration of odemx::base::Continuous
+
+ \sa Continuous.cpp
+
+ \since 3.0
+ */
+
+#ifndef ODEMX_CONTINUOUS_INCLUDED
+#define ODEMX_CONTINUOUS_INCLUDED
+
+#include <odemx/setup.h>
+
+// usage of this class requires SimTime type double,
+// which can be switched at compile time by defining
+// ODEMX_USE_CONTINUOUS in file odemx/setup.h
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <odemx/base/continuous/ODEObject.h>
+#include <odemx/base/continuous/VariableContainer.h>
+#include <odemx/data/Producer.h>
+#include <odemx/data/Observable.h>
+
+#include <string>
+#include <vector>
+#include <list>
+
+namespace odemx {
+	namespace base {
+		namespace continuous {
+
+			// forward declarations
+			class Monitor;
+
+			class ODEObject;
+
+			class VariableContainer;
+
+			class ContinuousObserver;
+
+			/** \class Continuous
+
+			 \ingroup base
+
+			 \author Michael Fiedler
+
+			 \brief %Continuous is the class for describing values of a continuous process in the system
+
+			 \note since 3.0 the values and the equations of a continuous process are split in Continuous and ODEObject
+
+			 \note Continuous supports Observation
+
+			 \note Continuous supports Trace
+
+			 \note Continuous supports Logging
+
+			 \sa ODEObject, Monitor, StateEvent, ODESolver
+
+			 The user creates an %Continuous instance for each continuous object in a simulation.
+			 This instance holds dimension continuous values.
+
+			 \since 3.0
+
+			 */
+			class Continuous : public data::Producer, public data::Observable<ContinuousObserver> {
+			public:
+				/** \brief Construction
+				 	\param sim reference to one simulation-object
+				 	\param l label of this object
+				 	\param dimension count of continuous values for the instance (dedicated)
+				 */
+				Continuous(Simulation& sim, const data::Label& label, int dimension);
+
+				/** \brief Construction
+				 \param sim reference to one simulation-object
+				 \param l label of this object
+				 \param monitor the monitor were the continuous object belongs to
+				 \param dimension number of continuous values for the instance (dedicaated)
+				 \param equation first equation in the life cycle of the object this can changed and other equations can be added via addODE(...).
+				 */
+				Continuous(Simulation& sim, const data::Label& label, Monitor* monitor, int dimension, ODEObject* equation = 0);
+
+				/** \brief Construction
+				 \param sim reference to one simulation-object
+				 \param l label of this object
+				 \param monitor the monitor were the continuous object belongs to
+				 \param dimension number of continuous values for the instance (dedicaated)
+				 \param equationList list of equations of the continuous object this can changed and other equations can be added via addODE(...).
+				 */
+				Continuous(Simulation& sim, const data::Label& label, Monitor* monitor, int dimension, std::list<ODEObject*> equationList);
+
+				/// Destruction
+				~Continuous();
+
+				/** \name Equation handling
+
+					These functions manage which equations are currently influencing the continuous values.
+
+					@{
+				 */
+				/** \brief Adds an equation
+					\param equation
+						pointer to an ODEObject describing an equation on the values
+					\note All equations which are added will be used for integration simultaneously and summed up.
+					\note This results in a change of the associated monitor.
+				 */
+				void addODE(ODEObject *equation);
+
+				/** \brief Adds a list of equations
+					\param equation
+						list of pointer to an ODEObject describing the equations on the values
+					\note All equations which are added will be used for integration simultaneously and summed up.
+					\note This results in a change of the associated monitor.
+				 */
+				void addODEList(std::list<ODEObject*> equation);
+
+				/** \brief Remove an equation
+					\param
+						pointer to the ODEObject to be removed
+					\note The equation is only removed from calculation. The object will not be destroyed.
+					\note This results in a change of the associated monitor.
+				 */
+				void removeODE(ODEObject *equation);
+
+				//@}
+
+				/** \name Monitor handling
+
+					These functions are setting and returning the %Monitor, which calculates the evolution of the
+					continuous values of this instance described by the added equations.
+
+					@{
+				 */
+				/** \brief Sets the Monitor in which the Continuous %Process will be integrated
+					\param monitor
+						pointer to the monitor which manages this instance
+					\note The instance will automatically be transferred from another %Monitor, if one was assigned.
+					\note To remove the Continuous object from a %Monitor pass NULL as parameter.
+					\note This results in a change to the involved monitors.
+				 */
+				void setMonitor(Monitor *monitor);
+
+				/** \brief Returns the Monitor which manages this instance
+				 */
+				Monitor* getMonitor();
+				//@}
+
+				/** \brief Returns the dimension of the Continuous %Process
+
+					\note That means the number of variables the %Process has.
+				 */
+				int getDimension();
+
+				/** \name Access to values during integration
+
+					Values should only be changed, when the responsible Monitor is not integrating.
+
+					@{
+				 */
+				/** \brief Sets the value of one variable
+					\param i
+						index of the variable to be set (range 0..(Dimension-1))
+					\param value
+						the value which the variable will be set to
+					\note Should only be used, when responsible %Monitor is not running (that means is not integrating).
+					\note This results in a change of the associated monitor.
+				 */
+				void setValue(int i, double value);
+
+				/** \brief Returns the value of one variable
+					\param i
+						index of the returned variable (range 0..(Dimension-1))
+					\note Should only be used when responsible %Monitor is not running (that means is not integrating)
+					\return the value of the variable accessed by index \p i
+				 */
+				double getValue(int i);
+				//@}
+
+				/**	\name Access to Values in Integration
+
+					These functions are for the evaluation of the differential equations.
+					That means they are used in implementations of the functions derivates and jacobi of the class ODEObject.
+					The user has to use the member function getValueForDerivative to access the value of one variable in such a implementation.
+
+					\note These functions should only be used while integration.
+
+					@{
+				 */
+				/** \brief Returns the value of one variable while integrating
+					\param i
+						index of the returned variable (range 0..(Dimension-1))
+					\return the value of the i-th variable at a possible intermediate step
+
+					\note The user has to use this function to access the value of a variable in an implementation of derivates or
+					jacobi in a derived class of ODEObject
+				 */
+				double getValueForDerivative(int i);
+
+				/** \brief Sets the value for y' = f(y) in the i-th component
+					\param i
+						index of the variable to be set (range 0..(Dimension-1))
+					\param value
+						set y'[i] = \p value
+
+					\note The values of multiple calls will be summed up.
+				 */
+				void setDerivative(int i, double value);
+
+				/** \brief Returns the value of y' = f(y) in the i-th component
+					\param i
+						index of the variable to get (range 0..(Dimension-1))
+
+					\note That means y'[i] will be returned
+				 */
+				double getDerivative(int i);
+
+				/** \brief Sets the value for Df exactly f_i \partial y[j] = value
+					\param i
+						index of the component to differentiate (range 0..(Dimension-1))
+					\param j
+						index of the variable by which will be differentiated (range 0..(Dimension-1))
+
+					For an equation given as y' = f(y) set the result \p value for differentiating
+					the i-th component of f by the j-th component of y.
+
+					\note The values of multiple calls will be summed up.
+				 */
+				void setJacobi(int i, int j, double value);
+
+				/** \brief Sets the value for Df exactly f_i \partial continuous->y[j] = value
+					\param i
+						index of the component to differentiate (range 0..(Dimension-1))
+					\param continuous
+						pointer to a continuous instance which influences the right hand side
+					\param j
+						index of the variable by which will be differentiated (range 0..(continuous->getDimension()-1))
+
+					For an equation given as y' = f(y, x) set the result \p value for differentiating
+					the i-th component of f by the j-th component of x.
+
+					\note The values of multiple calls will be summed up.
+					\note To work correctly this instance and \p continuous have to be managed by the same %Monitor
+				 */
+				void setJacobi(int i, Continuous* continuous, int j, double value);
+
+				/** \brief Returns the value of Df returns f_i \partial y[j]
+					\param i
+						index of the component to get (range 0..(Dimension-1))
+					\param j
+						index of the variable by which will be differentiated (range 0..(Dimension-1))
+
+					For an equation given as y' = f(y) gives the intermediate result for differentiating
+					the i-th component of f by the j-th component of y. The value of result is determined
+					by previous calls to setJacobi.
+				 */
+				double getJacobi(int i, int j);
+
+				/** \brief Returns the value of Df returns f_i \partial continuous->y[j]
+					\param i
+						index of the component to differentiate (range 0..(Dimension-1))
+					\param continuous
+						pointer to a Continuous instance which influences the right hand side
+					\param j
+						index of the variable by which will be differentiated (range 0..(continuous->getDimension()-1))
+
+					For an equation given as y' = f(y, x) set the result \p value for differentiating
+					the i-th component of f by the j-th component of x. The value of result is determined
+					by previous calls to setJacobi.
+
+					\note To work correctly this instance and \p continuous have to be managed by the same %Monitor.
+				 */
+				double getJacobi(int i, Continuous* continuous, int j);
+
+				/** \brief Sets the value for DfDt exactly f_i \partial t = value
+					\param i
+						index of the component to set (range 0..(Dimension-1))
+
+					For an equation given as y' = f(y) set the result \p value for differentiating
+					the i-th component of f by time.
+
+					\note The values of multiple calls will be summed up.
+				 */
+				void setDfDt(int i, double value);
+
+				/** \brief gets the value for DfDt returns f_i \partial t = value
+					\param i
+						index of the component to get (range 0..(Dimension-1))
+
+					For an equation given as y' = f(y) set the result \p value for differentiating
+					the i-th component of f by time. The value of result is determined
+					by previous calls to setDfDt.
+				 */
+				double getDfDt(int i);
+				//@}
+
+				/** \brief Sets changed on true, so that the monitor will call solver->init() before next calculation
+				 */
+				void setChanged();
+
+				/** \brief Triggers the observer to write the state variables
+				 */
+				void notifyValidState();
+
+			private:
+				// List all equations which belong to this instance
+				std::list<ODEObject*> equations;
+
+				// Monitor in which this instance will be integrated
+				Monitor *monitor;
+
+				// Dimension of the instance
+				int dimension;
+
+				// Base index for variables of this continuous object in the variables container of the monitor
+				int baseIndex;
+
+				friend class Monitor;
+			};
+
+			//forward declaration
+			class Monitor;
+
+			/** \interface ContinuousObserver
+
+				\author Sascha Qualitz
+
+				\brief Observer for Continuous specific events
+
+				\sa Monitor
+
+				\since 3.0
+			*/
+			class ContinuousObserver:
+				public ProcessObserver
+			{
+			public:
+				virtual void onCreate( Continuous* sender ) {} ///< Construction
+
+				virtual void onNewValidState( Continuous* sender ) {} ///< New valid state
+
+				virtual void onSetMonitor( Continuous* sender, Monitor* monitor ) {} ///< new Monitor set
+
+				virtual void onAddODE(Continuous* sender, ODEObject* ode) {} ///< new ordinary differential equation added
+				virtual void onRemoveODE(Continuous* sender, ODEObject* ode) {} ///< old ordinary differential equation removed
+			};
+
+			/** \class ContinuousTrace
+
+				\author Sascha Qualitz
+
+				\brief Trace for Continuous state changes of continuous objects controlled by the monitor
+
+				\sa Continuous MonitorObserver
+
+				ContinuousTrace logs the state changes of the Continuous objects
+				into a text file. The text file is automatically opened and closed.
+
+				\since 3.0
+			*/
+			class ContinuousTrace
+			:	public ContinuousObserver
+			{
+				public:
+					/// Construction
+				ContinuousTrace( Continuous* contu = 0, const std::string& fileName = "" );
+					/// Destruction
+					virtual ~ContinuousTrace();
+
+					/// Follow state changes
+					virtual void onNewValidState( Continuous* sender );
+
+				private:
+					// Implementation
+					std::ostream* out;
+					bool firstTime;
+					const std::string& fileName;
+
+					Continuous* continuous;
+
+					void openFile( const std::string& fileName );
+			};
+		}
+	}
+}
+#endif /* ODEMX_USE_CONTINUOUS */
+
+#endif /* ODEMX_CONTINUOUS_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/continuous/DfDt.h b/odemx-lite/include/odemx/base/continuous/DfDt.h
new file mode 100644
index 0000000000000000000000000000000000000000..25f7c8d76bc22621d333f10265ea2439519d9c75
--- /dev/null
+++ b/odemx-lite/include/odemx/base/continuous/DfDt.h
@@ -0,0 +1,150 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file DfDt.h
+
+ \author Sascha Qualitz
+
+ \date created at 2009/10/26
+
+ \brief Declaration of class DfDt
+
+ \since 3.0
+ */
+
+#ifndef ODEMX_DFDT_INCLUDED
+#define ODEMX_DFDT_INCLUDED
+
+#include <odemx/setup.h>
+
+// usage of this class requires SimTime type double,
+// which can be switched at compile time by defining
+// ODEMX_USE_CONTINUOUS in file odemx/setup.h
+#ifdef ODEMX_USE_CONTINUOUS
+
+namespace odemx {
+	namespace base {
+		namespace continuous {
+
+			//Forward declaration
+			class Continuous;
+
+			class ODEObject;
+
+			/** \class DfDt
+
+				\ingroup base
+
+				\author Sascha Qualitz
+
+				\brief Object for handling a derived by time equation-element in the class ODEObject
+					   Used in the jacobi function in a derived class of ODEObject.
+
+				To describe ordinary derived by time equations the user has to use this class.
+
+				\sa JacobiMatrix
+				\sa State
+				\sa Rate
+			 */
+			class DfDt {
+			public:
+				/**
+					\brief Construction
+					\param continuous
+						pointer to the continuous object where the dfdt-element belongs to
+
+					\note The variables continuous and index_ will be set to 0
+				*/
+				DfDt();
+
+				/**
+					\brief Construction
+					\param continuous
+						pointer to the continuous object where the dfdt-element belongs to
+
+					\note The variable index_ will be set to 0
+				*/
+				DfDt(Continuous* continuous);
+
+				/// destruction
+				virtual ~DfDt();
+
+				/**
+					\brief Overrides the converting operator double to convert implicit an object of type DfDt to double
+
+					\note If this operator is called, the double value is the value that is returned by the method
+					getDfDt(index_) of the corresponding continuous-object. The variable index_ is set to an index
+					between 0 and continuous->getDimension before. To set the variables index_ see also the methods
+					operator [].
+				*/
+				operator double() {
+					return this->getValue();
+				}
+
+				/**
+					\brief Overrides the assignment operator to store the value of type double in the variable container
+					\param value
+						value to be set
+				*/
+				DfDt& operator =(const double value);
+
+				/**
+					\brief Overrides the index operator to set the internal variable index_
+					\param index
+						index of the variable to get/set (range 0..(Dimension-1))
+				*/
+				DfDt& operator [](const unsigned i);
+
+				/**
+					\brief Sets the variable continuous
+					\param continuous
+						pointer to the continuous object where the equation-element belongs to
+				*/
+				void setContinuous(Continuous* continuous);
+
+			private:
+
+				/**
+					\brief Returns the value of the dfdt-element with given index index_
+
+					getValue returns the value from the correct index position, because index_ was set by the overwritten operator[] before.
+				*/
+				double getValue() const;
+
+				/**
+					\brief Sets the value of type double at the index index_
+					\param value
+						value to be set
+
+					\note setValue stores the value at the correct index, because index_ was set by the overwritten operator[] before.
+				*/
+				void setValue(double value);
+
+				// pointer to the continuous object where the dfdt-element belongs to
+				Continuous* continuous;
+
+				// index of the variable to get/set (range 0..(Dimension-1))
+				unsigned index_;
+			};
+		}
+	}
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
+
+#endif /* ODEMX_DFDT_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/continuous/JacobiMatrix.h b/odemx-lite/include/odemx/base/continuous/JacobiMatrix.h
new file mode 100644
index 0000000000000000000000000000000000000000..a8031a90ef85010bf4b41b6fefbb967342cfd512
--- /dev/null
+++ b/odemx-lite/include/odemx/base/continuous/JacobiMatrix.h
@@ -0,0 +1,164 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/** \file JacobiMatrix.h
+
+ 	\author Sascha Qualitz
+
+ 	\date created at 2010/2/26
+
+ 	\brief Declaration of class odemx::base::continuous::JacobiMatrix
+
+ 	\sa JacobiMatrix.cpp
+
+    \since 3.0
+ */
+
+#ifndef ODEMX_JACOBIMATRIX_INCLUDED
+#define ODEMX_JACOBIMATRIX_INCLUDED
+
+#include <odemx/setup.h>
+
+// usage of this class requires SimTime type double,
+// which can be switched at compile time by defining
+// ODEMX_USE_CONTINUOUS in file odemx/setup.h
+#ifdef ODEMX_USE_CONTINUOUS
+
+namespace odemx {
+	namespace base {
+		namespace continuous {
+
+			//Forward declaration
+			class Continuous;
+
+			class ODEObject;
+			/** \class JacobiMatrix
+
+				\ingroup base
+
+				\author Sascha Qualitz
+
+				\brief Object for handling the jacobi-matrix in the class ODEObject.
+
+				To describe the jacobi-matrix of ordinary differential equations the user has to use this class.
+				Used in the jacobi function in a derived class of ODEObject.
+
+				\sa Rate
+				\sa State
+				\sa DfDt
+			 */
+
+			class JacobiMatrix {
+			public:
+				/**
+					\brief Construction
+
+					\note The variables continuous, otherContinuous, row_ and column_ will be set to 0.
+				*/
+				JacobiMatrix();
+
+				/**
+					\brief Construction
+					\param continuous
+						pointer to the continuous object where the jacobi-matrix belongs to
+
+					\note The variables row_, column_ and otherContinuous will be set to 0.
+				*/
+				JacobiMatrix(Continuous* continuous);
+
+				/**
+					\brief Construction
+					\param continuous
+						pointer to the continuous object where the jacobi-matrix belongs to
+					\param otherContinuous
+						pointer to a continuous instance which influences the right hand side of the equation
+
+					\note The variables row_ and column_ will be set to 0
+				*/
+				JacobiMatrix(Continuous* continuous, Continuous* otherContinuous);
+
+				/// destruction
+				~JacobiMatrix();
+
+				/**
+					\brief Overrides the assignment operator to store the value of type double in the variable container.
+					\param value
+						value to be set
+				*/
+				JacobiMatrix& operator =(const double value);
+
+				/**
+					\brief Overrides the ()-operator to set the values of row_ and column_.
+					\param row
+						row number of the matrix
+					\param column
+						column number of the matrix
+				*/
+				JacobiMatrix& operator ()(const unsigned row, const unsigned column);
+
+				/**
+					\brief Sets the continuous variable
+					\param continuous
+						pointer to the continuous object where the jacobi-matrix belongs to
+				*/
+				void setContinuous(Continuous* continuous);
+
+				/**
+					\brief Sets the variables continuous and otherContinuous
+					\param continuous
+						pointer to the continuous object where the jacobi-matrix belongs to
+					\param otherContinuous
+						pointer to a continuous instance which influences the right hand side of the equation
+				*/
+				void setContinuous(Continuous* continuous, Continuous* otherContinuous);
+
+			private:
+				/**
+					\brief Returns value of the jacobi-matrix, at the given indexes row_ and column_
+
+					getValue returns the correct value, because row_ and column_ was set by the overwritten ()-operator before.
+				*/
+				double getValue() const;
+
+				/**
+					\brief Sets the value of the jacobi-matrix at the indexes row_ and column_
+					\param value
+						value to be set
+				*/
+				void setValue(double value);
+
+				// pointer to the continuous object where the jacobi-matrix belongs to
+				Continuous* continuous;
+
+				// pointer to a continuous instance which influences the right hand side of the equation
+				Continuous* otherContinuous;
+
+				// row number of the matrix
+				unsigned row_;
+
+				// column number of the matrix
+				unsigned column_;
+			};
+		}
+	}
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
+
+#endif/* ODEMX_JACOBIMATRIX_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/continuous/Monitor.h b/odemx-lite/include/odemx/base/continuous/Monitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..af4c12b73d4322313978c20781c1a018592a02bd
--- /dev/null
+++ b/odemx-lite/include/odemx/base/continuous/Monitor.h
@@ -0,0 +1,444 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Monitor.h
+
+ \author Michael Fiedler
+
+ \date created at 2008/11/21
+
+ \brief Declaration of Monitor
+
+ \since 3.0
+ */
+
+#ifndef ODEMX_MONITOR_INCLUDED
+#define ODEMX_MONITOR_INCLUDED
+
+#include <odemx/setup.h>
+
+// usage of this class requires SimTime type double,
+// which can be switched at compile time by defining
+// ODEMX_USE_CONTINUOUS in file odemx/setup.h
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <odemx/base/Process.h>
+#include <odemx/base/continuous/ODESolver.h>
+#include <odemx/base/continuous/Continuous.h>
+#include <odemx/base/continuous/StateEvent.h>
+#include <odemx/base/continuous/VariableContainer.h>
+#include <list>
+#include <fstream>
+#include <iostream>
+#include <odemx/setup.h>
+#include <odemx/data/Observable.h>
+
+namespace odemx {
+	namespace base {
+		namespace continuous {
+
+			/** Choice if integration is done by interval or by steps
+			 */
+			enum WorkingModes {
+				stepwise, intervall
+			};
+
+			/** Choice how to search for StateEvents. That means if to work on a linear approximation or
+				direct on the solution.
+			 */
+			enum SearchModes {
+				linearization, direct
+			};
+
+			//forward declaration
+			class ODESolver;
+
+			class VariableContainer;
+
+			class Continuous;
+
+			class StateEvent;
+
+			class MonitorObserver;
+
+			/** \class Monitor
+
+				\ingroup base
+
+				\brief A monitor is used to integrate several continuous processes simultaneously,
+				but independent from continuous processes in other monitors of the simulation.
+
+				\sa Continuous, ODEObject, ODESolver, StateEvent, Process
+
+				\since 3.0
+			 */
+			class Monitor : public Process, public data::Observable<MonitorObserver> {
+			public:
+
+				/** \brief Construction
+				 \param variablesArraySize
+					 initial size of data structs
+				 \param s
+					pointer to the Simulation object
+				 \param label
+					label of this object
+				 \param solver
+					the solver for this monitor
+				 \param o
+					initial observer
+				 \note If the data structs are to small on runtime, they will be enlarged automatically at cost of speed
+				 */
+				Monitor(Simulation& s, const data::Label& label, int variablesArraySize, ODESolver* solver, MonitorObserver* o = 0);
+
+				/// destruction
+				~Monitor();
+
+				/** \brief sets how monitor schedules integration
+					\param mode
+						If value is 'stepwise' the %Monitor will be scheduled after every step (as in older version).
+						If value is 'interval' the %Monitor will be scheduled only on known synchronization points.
+
+					\note The synchronization point is the earliest time to which one of the processes in the list wait list is scheduled.
+				 */
+				void setWorkingMode(WorkingModes mode);
+
+				/** \brief Sets the method how to search for StateEvents
+					\param mode
+						value is direct or linearization
+
+					Sets if monitor searches for StateEvents directly on the solution (slower but more accurate) or
+					on a linearization (faster)
+				 */
+				void setSearchMode(SearchModes mode);
+
+				/** \brief Synchronizes this instance to another monitor
+
+					That means the other monitor will be synchronized to the time of this monitor
+
+					\note not implemented now
+				 */
+				void synchronizeToMonitor(Monitor *otherMonitor);
+
+				/** \name handle used solver
+
+					These functions are to control which solving method is used for integration
+
+					@{
+				 */
+				/** \brief Sets the solver for this monitor
+				 */
+				void setODESolver(ODESolver *solver);
+
+				/** \brief Returns the actual solver of this monitor
+				 */
+				ODESolver* getODESolver();
+				//@}
+
+				/** \name Process synchronization
+
+					These functions control with which processes the monitor synchronizes.
+					This means the monitor stops integration at times when one of these processes is scheduled.
+					The integration will be continued after this process has been executed.
+
+					\note This is necessary for time consistent exchange of values between processes and monitors.
+
+					@{
+				 */
+				/** \brief Adds a discrete process to which the monitor will be synchronized
+
+					That means the monitor will only integrate to the next event of one discrete process.
+					The monitor waits till this event is computed.
+				 */
+				void addProcessToWaitList(Process *process);
+
+				/** \brief Removes a discrete process from the monitor to synchronize
+				 */
+				void removeProcessFromWaitList(Process *process);
+				//@}
+
+				/** \name continuous processes and StateEvents
+
+					This functions control which continuous processes are calculated by this monitor and
+					which StateEvents will be checked during integration.
+
+					@{
+				 */
+				/** \brief Adds a continuous process to the monitor
+
+					This process will be integrated by the monitor simultaneously
+					to other continuous processes of the monitor.
+
+					\note This results in a change of the monitor.
+				 */
+				void addContinuous(Continuous *continuous);
+
+				/** \brief Removes a continuous process from the monitor
+
+					\note This results in a change of the monitor.
+				 */
+				void removeContinuous(Continuous *continuous);
+
+				/** \brief Adds a StateEvent to the monitor to watch for
+
+					That means after every step the monitor checks for all StateEvents.
+					If condition() of one StateEvent evaluates to true the point of switching
+					from false to true will be approximated and at this point action of the StateEvent
+					will be executed. The StateEvent will be removed from the monitor afterwards
+
+					\note If condition() evaluates to true while added, then action() is immediately called.
+				 */
+				void addStateEvent(StateEvent *stateEvent);
+
+				/** \brief Removes a StateEvent from the monitor
+				 */
+				void removeStateEvent(StateEvent *stateEvent);
+				//@}
+
+				/** \brief Calculates the evolution of the continuous processes
+
+					\note This will be called by Simulation.
+				 */
+				int main();
+
+				/** \name stop monitor
+
+					These functions are to set the time limit for the main method to work or give a stop command.
+
+					\note The monitor will only integrate, if there is a time limit set or processes to synchronize with or StateEvents to check.
+					\note If there are only StateEvents to check be sure that at least one will evaluate at some point to true or you will have an infinite loop.
+
+					@{
+				 */
+				/** \brief Sets a time limit when the monitor will finish the main method
+					\param time
+						time to stop monitor
+				 */
+				void setTimeLimit(SimTime time);
+
+				/** \brief Returns the time limit
+					\param time
+						the set time limit for this instance, which is only valid if returned true
+				 */
+				bool getTimeLimit(SimTime* time);
+
+				/** \brief Remove time limit
+				 */
+				void removeTimeLimit();
+
+				/** \brief Returns the execution time of the next synchronized process
+				 */
+				SimTime getStepTimeLimit();
+
+				/** \brief Forces the monitor to finish the main method when next time limit is reached
+				 */
+				void stop();
+				//@}
+
+				/** \name internal Time
+
+					To make ODEMx time representation independent of the time representation in the solver
+					(numerical framework) the monitor has an internal timing for conversion.
+					This means the monitor has an internal reference time and an actual time,
+					which is after the reference time.
+
+					@{
+				 */
+				/** \brief Sets internal reference time
+				 	\param time
+						the time limit to be set
+
+					\note That means a change for the calculation and triggers a new initialization for the solver.
+				 */
+				void setInternalTime(SimTime time);
+
+				/** \brief Returns internal reference time
+				 */
+				SimTime getInternalTime();
+
+				/** \brief Returns actual time of monitor
+				 */
+				SimTime getActualInternalTime();
+
+				/** \brief Sets internal reference time to actual time
+
+					Sets internal reference time in a way that actual time and internal
+					reference time are equal for this monitor.
+
+					\note That means a change for the calculation and triggers a new initialization for the solver
+				 */
+				void adaptInternalTime();
+				//@}
+
+				/** \brief Sets the monitor changed
+
+					If the continuous system has a discrete change, the solver has to be newly initialized
+					to guarantee consistency. So it causes a call of solver->init() before next calculation.
+
+					\note As long a user access only objects by supplied functions there is no need to call this.
+				 */
+				void setChanged();
+
+			protected:
+
+				// the solver used by the monitor
+				ODESolver *solver;
+
+				// the working mode in which the monitor runs
+				WorkingModes workingMode;
+
+				// the search mode used by the monitor to search for the appearance of state events
+				SearchModes searchMode;
+
+				// list of the discrete processes which the monitor synchronizes to
+				std::list<Process*> waitForProcesses;
+
+				// list of the continuous processes managed by the monitor
+				std::list<Continuous*> continuousList;
+
+				// list of the StateEvents the monitor watches for
+				std::list<StateEvent*> stateEvents;
+
+				// actual size of the variable structs
+				int variablesArraySize;
+
+				// actual number of variables used
+				int variablesCount;
+
+				// variable container used by monitor for managing variables
+				VariableContainer *variables;
+
+				// the internal reference time value
+				SimTime internalTime;
+
+				// the time limit if set
+				SimTime timeLimit;
+
+				// indicates if a time limit is set
+				bool timeLimitSet;
+
+				// indicates if stop() was called
+				bool hasToStop;
+
+				// actual time of monitor is internalTime + diffTime
+				double diffTime;
+
+				// indicates if the system has changed since the calculation of the last step
+				bool changed;
+
+				/** \brief Integration to \p time
+				 	\param time
+						the time limit to which will be integrated
+
+					\note internal function
+				 */
+				void integrateUntil(SimTime time);
+
+				/** \brief Integration till state event occurs
+
+					\note internal function
+				 */
+				void integrate();
+
+				/** \brief Searches the time when a state event occurs.
+				 	When a known condition is false at internalTime + old_diffTime with values old_variable_values (for all
+				 	state events) and in the actual state there is a state event of the monitor with condition true,
+				 	then the monitor triggers this event (calls the method action()).
+				 	\param old_diffTime
+						initial left bound of the search interval
+					\param old_variable_values
+						initial values for the search
+				 */
+				void searchStateEvent(double old_diffTime, double *old_variable_values);
+
+				/** \brief Evaluates all equations of all continuous processes as one function.
+				 	It will be evaluated as sum of partial functions at time internalTime + time.
+				 	\param time
+						the time limit
+				 */
+				void evalF(double time);
+
+				/** \brief Evaluates all jacobian of all continuous processes as one matrix.
+				 	It will be evaluated as sum of partial matrices at time internalTime + time.
+				 	\param time
+						the time limit
+				 */
+				void evalJacobian(double time);
+
+				friend class Continuous;
+				friend class ODESolver;
+				friend class MonitorTrace;
+			};
+
+			//forward declaration
+			class Monitor;
+
+			class Continuous;
+
+			/** \interface MonitorObserver
+
+				\author Sascha Qualitz
+
+				\brief Observer for monitor specific events
+
+				\sa Continuous
+
+				\since 3.0
+			*/
+			class MonitorObserver:
+				public ProcessObserver
+			{
+			public:
+				virtual ~MonitorObserver(){};
+
+				virtual void onCreate( Monitor* sender ){} ///< Construction
+
+				virtual void onAddProcessToWaitList( Monitor* sender, Process* peer ){} ///< Add peer
+				virtual void onRemoveProcessFromWaitList( Monitor* sender, Process* peer ){} ///< Remove peer
+
+				virtual void onBeginIntegrate( Monitor* sender ){} ///< Begin integrate
+				virtual void onEndIntegrate( Monitor* sender){} ///< End integrate
+
+				virtual void onBeginIntegrateUntil( Monitor* sender ){} ///< Begin integrate
+				virtual void onEndIntegrateUntil( Monitor* sender){} ///< End integrate
+
+				virtual void onNewValidState( Monitor* sender ){} ///< New valid state
+
+				virtual void onAddContinuous( Monitor* sender, Continuous* continuous ){} ///< new continuous object added
+				virtual void onRemoveContinuous( Monitor* sender, Continuous* continuous ){} ///< continuous object removed
+
+				virtual void onAddStateEvent( Monitor* sender, StateEvent* event ){} ///< new state event added
+				virtual void onRemoveStateEvent( Monitor* sender, StateEvent* event ){} ///< state event removed
+
+				virtual void onStop( Monitor* sender){} ///< Monitor stops
+
+				virtual void onSetODESolver( Monitor* sender, ODESolver* solver){} ///< set ODESolver
+
+				virtual void onSetChanged( Monitor* sender){} ///< system changed
+
+				virtual void onSetInternalTime(Monitor* sender, SimTime time){} ///< internal time changed
+
+				virtual void onAdaptInternalTime(Monitor* sender, SimTime time){} ///< adapted internal time
+			};
+		}
+	}
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
+
+#endif /* ODEMX_MONITOR_INCLUDED */
+
diff --git a/odemx-lite/include/odemx/base/continuous/ODEObject.h b/odemx-lite/include/odemx/base/continuous/ODEObject.h
new file mode 100644
index 0000000000000000000000000000000000000000..6f3cbb56197fee22621d69a3764eacca877d4228
--- /dev/null
+++ b/odemx-lite/include/odemx/base/continuous/ODEObject.h
@@ -0,0 +1,189 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file ODEObject.h
+
+ \author Michael Fiedler
+
+ \date created at 2008/11/21
+
+ \brief abstract class to derive a representation of an ordinary differential equation
+ \sa Continuous, Monitor, StateEvent
+ \since 3.0
+ */
+
+#ifndef ODEMX_ODEOBJECT_INCLUDED
+#define ODEMX_ODEOBJECT_INCLUDED
+
+#include <odemx/setup.h>
+
+// usage of this class requires SimTime type double,
+// which can be switched at compile time by defining
+// ODEMX_USE_CONTINUOUS in file odemx/setup.h
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <odemx/base/SimTime.h>
+
+#include <odemx/base/TypeDefs.h>
+
+#include <string>
+#include <exception>
+#include <vector>
+#include <list>
+
+
+namespace odemx {
+namespace base {
+namespace continuous {
+
+//class Monitor; //TODO: really useful?
+
+class Continuous;
+
+
+/** Exception for methods which fails, because there is missingObject assigned for this object
+ */
+class NotAssignedException: public std::exception
+{
+public:
+	/// Constructor
+	NotAssignedException(const char* missingObject, const char* object);
+	/// Destructor
+	~NotAssignedException() throw();
+	/// give message for exception
+	const char* what() const throw();
+
+private:
+	// contains the Exception message
+	std::string msg;
+};
+
+
+/** \class ODEObject
+
+	\ingroup base
+
+	\author Michael Fiedler
+
+	\brief Object for handling an equation
+
+	To describe an ordinary differential equation the user has to implement derivates and jacobi.
+
+	\note In such implementations the user has to use getValueForDerivative to access the variables of
+	the corresponding Continuous instance.
+ */
+class ODEObject
+{
+public:
+	/** \brief Construction
+	 */
+	ODEObject(const Derivative& derivatives, const Derivative& jacobi) :derivatives_{derivatives}, jacobi_{jacobi}, continuous{0}
+	{}
+
+	/** \brief Construction
+	 */
+	ODEObject(Derivative&& derivatives, Derivative&& jacobi) :derivatives_{derivatives}, jacobi_{jacobi}, continuous{0}
+	{}
+
+	/// destruction
+//	virtual ~ODEObject();
+
+	/** \name Handling of corresponding Continuous instance
+
+		These are the functions to set/get the Continuous instance for this equation to work on.
+		If the user wants to have an equation which works on more than one Continuous instance he
+		has to extend this functionality for the extra instances.
+
+		@{
+	 */
+	/** \brief Adds this ODEObject-instance to a Continuous-Object
+		\param continuous
+			pointer to Continuous instance where this equation will be added
+	 */
+	void setContinuous(Continuous* continuous); //TODO: is never used!
+
+	/** \brief Returns the corresponding Continuous instance
+		\note If no corresponding Continuous instance is set, the result will be NULL
+	 */
+	Continuous* getContinuous();
+	//@}
+
+	/** \brief implementation of equation in form y' = f(y)
+
+	 the following is an example for implementation of this function
+
+	 v'[0] = v[1]
+
+	 v'[1] = v[0]
+
+	 in code:
+
+	 DerivatesElement rate(continuous);
+
+	 DerivatesElement state(continuous);
+
+	 rate[0] = state[1];
+
+	 rate[1] = -1 * state[0];
+
+	 \sa Rate, State
+	 */
+	void derivates(SimTime time);
+	/** \brief derivates of implemented equation in form y' = f(y)
+
+	 the following is an example for implementation of this function (fßx means derive f by x):
+
+	 in code:
+
+	 JacobiElement jacobi(continuous);
+
+	 DfDtElement dfdt(continuous);
+
+	 jacobi(0,0) = 0;
+
+	 jacobi(0,1) = 1;
+
+	 jacobi(1,0) = -1;
+
+	 jacobi(1,1) = 0;
+
+	 dfdt[0] = 0;
+
+	 dfdt[1] = 0;
+	 */
+	void jacobi(SimTime time);
+
+//			protected:
+private:
+	// stores the Continuous-Object where equation belongs to
+	Continuous* continuous;
+	Derivative derivatives_;
+	Derivative jacobi_;
+
+//			protected:
+public:
+				friend class Continuous; // FIXME needed?
+
+};
+}
+}
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
+
+#endif /* ODEMX_ODEOBJECT_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/continuous/ODESolver.h b/odemx-lite/include/odemx/base/continuous/ODESolver.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b587924ba101600f9897a77b6b8d10f59c785c6
--- /dev/null
+++ b/odemx-lite/include/odemx/base/continuous/ODESolver.h
@@ -0,0 +1,227 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file ODESolver.h
+
+ \author Michael Fiedler
+
+ \date created at 2008/11/21
+
+ \brief Declaration of ODESolver
+
+ \since 3.0
+ */
+
+#ifndef ODEMX_ODESOLVER_INCLUDED
+#define ODEMX_ODESOLVER_INCLUDED
+
+#include <odemx/setup.h>
+
+// usage of this class requires SimTime type double,
+// which can be switched at compile time by defining
+// ODEMX_USE_CONTINUOUS in file odemx/setup.h
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <odemx/base/continuous/VariableContainer.h>
+#include <odemx/data/Producer.h>
+#include <odemx/data/Observable.h>
+
+namespace odemx {
+	namespace base {
+		namespace continuous {
+
+			/** Choice which error is checked while integration
+			 */
+			enum ErrorType {
+				absolute, relative
+			};
+
+			class Monitor;
+
+			class VariableContainer;
+
+			class ODESolverObserver;
+
+			/** \class ODESolver
+
+				\ingroup base
+
+				\brief Abstract class for implementing a solver
+
+				This class specifies the interface of a solver as seen by the monitor.
+
+				\note ODESolver supports Observation
+
+			    \note ODESolver supports Trace
+
+			    \note ODESolver supports Logging
+
+				\sa Monitor, GSLSolver
+
+				\since 3.0
+			 */
+			class ODESolver : public data::Producer, public data::Observable<ODESolverObserver> {
+			public:
+				/** \brief Construction
+					\param sim
+						reference to one simulation-object
+				 */
+				ODESolver(Simulation& sim);
+				/// destruction
+				virtual ~ODESolver();
+
+				/** \brief Returns a variable container suitable for this Solver
+					\param size
+						initial size of arrays in the variable container
+				 */
+				virtual VariableContainer* getVariableContainer(int size) = 0;
+
+				/** \brief Makes one integration step for monitor
+					\param time
+						internal time of assigned monitor.
+
+					\note \p time is the time from which to do the step.
+				 */
+				virtual void makeStep(double time) = 0;
+
+				/** \brief Initialize the solver
+
+					\note This is also called if the monitor has changed.
+				 */
+				virtual void init() = 0;
+
+				/** \name Monitor handling
+
+					@{
+				 */
+				/** \brief Sets the assigned Monitor
+				 	\param monitor
+						pointer to the monitor which manages this instance
+				 */
+				void setMonitor(Monitor* monitor);
+
+				/** \brief Returns the assigned Monitor
+				 */
+				Monitor* getMonitor();
+				//@}
+
+				/** \name Solving parameters
+
+					@{
+				 */
+				/** \brief Sets the error limit for integration
+				 */
+				void setErrorLimit(double maxError);
+
+				/** \brief Returns the error limit for integration
+				 */
+				double getErrorLimit();
+
+				/** \brief Sets the type of error which will be checked
+					\param type
+						is 'absolute' or 'relative'
+				 */
+				void setErrorType(ErrorType type);
+
+				/** \brief Sets the interval for the step length of one integration step
+					\param min
+						lower bound of step length
+					\param max
+						upper bound of step length
+				 */
+				void setStepLength(double min, double max);
+
+				/** \brief gives the size of the last step done
+				 */
+				double getStepLength();
+				//@}
+
+			protected:
+				// pointer to the Monitor which holds the Continuous objects which will be integrated
+				Monitor* monitor;
+
+				/** \brief Calls all derivates functions of all ODEObject objects assigned to Continuous objects which are managed by the monitor
+
+					\note This function evaluates all equations of all continuous processes as one function
+					   	  as sum of partial functions at time internalTime + time.
+					\note This function is passed to the GSL Library for solving the ordinary differential equations.
+				 */
+				void evalF(double time);
+
+				/** \brief Calls all jacbian functions of all ODEObject objects assigned to Continuous objects which are managed by the monitor
+
+					\note This function evaluates all jacobian functions of all continuous processes as one matrix
+						  as sum of partial matrices at time internalTime + time. Also it evaluates the function for differentiating
+						  the i-th component of f by time
+					\note This function is passed to the GSL Library for solving the ordinary differential equations, if a solving algorithm for
+						  stiff equations is used.
+				 */
+				void evalJacobian(double time);
+
+				/** \brief Returns the variables container of the assigned Monitor
+				 */
+				VariableContainer* getVariableContainerOfMonitor();
+
+				// error type which will be checked after each step to optimize step length
+				ErrorType errorType;
+
+				//error limit which will be checked after each step to optimize step length
+				double errorLimit;
+
+				// minimum step length allowed by user
+				double minStep;
+
+				// maximum step length allowed by user
+				double maxStep;
+
+				// step length of the last step
+				double lastStep;
+
+				friend class Monitor;
+			};
+
+			/** \interface ODESolverObserver
+
+				\author Sascha Qualitz
+
+				\brief Observer for ODESolver specific events
+
+				\sa Continuous
+
+				\since 3.0
+			*/
+			class ODESolverObserver:
+				public ProcessObserver
+			{
+			public:
+				virtual void onCreate( ODESolver* sender ) {} ///< Construction
+				virtual void onDestroy( ODESolver* sender ) {} ///< Destruction
+
+				virtual void onSetMonitor( ODESolver* sender, Monitor* monitor ) {} ///< new Monitor set
+
+				virtual void onGetVariableContainer() {} ///< create new VariableContainer and return a pointer to monitor
+			};
+
+		}
+	}
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
+
+#endif /* ODEMX_ODESOLVER_INCLUDED */
+
diff --git a/odemx-lite/include/odemx/base/continuous/Rate.h b/odemx-lite/include/odemx/base/continuous/Rate.h
new file mode 100644
index 0000000000000000000000000000000000000000..49d252c0497c3945e55f836769449a8e6bae04d5
--- /dev/null
+++ b/odemx-lite/include/odemx/base/continuous/Rate.h
@@ -0,0 +1,138 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/** \file Rate.h
+
+ 	\author Sascha Qualitz
+
+ 	\date created at 2010/2/26
+
+ 	\brief Declaration of class odemx::base::continuous::Rate
+
+ 	\sa Rate.cpp
+
+    \since 3.0
+ */
+#ifndef ODEMX_RATE_INCLUDED
+#define ODEMX_RATE_INCLUDED
+
+#include <odemx/setup.h>
+
+// usage of this class requires SimTime type double,
+// which can be switched at compile time by defining
+// ODEMX_USE_CONTINUOUS in file odemx/setup.h
+#ifdef ODEMX_USE_CONTINUOUS
+
+namespace odemx {
+	namespace base {
+		namespace continuous {
+
+			//Forward declaration
+			class Continuous;
+
+			class ODEObject;
+
+			class State;
+
+			/** \class Rate
+
+				\ingroup base
+
+				\author Sascha Qualitz
+
+				\brief Object for handling an equation-element of the left hand side of an equation.
+					   Used in the derivates function in a derived class of ODEObject.
+
+				To describe ordinary differential equations the user has to use this class.
+
+				\sa State
+				\sa JacobiMatrix
+				\sa DfDt
+			 */
+			class Rate {
+			public:
+				/**
+					\brief Construction
+
+					\note The variables continuous and index_ will be set to 0
+				*/
+				Rate();
+				/**
+					\brief Construction
+					\param continuous
+						pointer to the continuous object where the equation-element belongs to
+
+					\note The variable index_ will be set to 0
+				*/
+				Rate(Continuous* continuous);
+
+				/// destruction
+				virtual ~Rate();
+
+				/**
+					\brief Overrides the assignment operator to store the value of type double in the variable container.
+					\param value
+						value to be set
+				*/
+				Rate& operator =(const double value);
+
+				/**
+					\brief Overrides the index operator to set the internal variable index_
+					\param index
+						index of the variable to get/set (range 0..(Dimension-1))
+				*/
+				Rate& operator [](const unsigned i);
+
+				/**
+					\brief Sets the continuous variable
+					\param continuous
+						pointer to the continuous object where this equation-element belongs to
+				*/
+				void setContinuous(Continuous* continuous);
+
+			private:
+
+				/**
+					\brief Sets the value of type double at index_
+					\param value
+						value to be set
+
+					\note setValue stores the value at the correct index, because index_ was set by the overwritten operator[] before.
+				*/
+				void setValue(double value);
+
+				/**
+					\brief Returns the value of type double with given index index_
+
+					getValue returns the value from the correct index position, because index_ was set by the overwritten operator[] before.
+				*/
+				double getValue();
+
+				// pointer to the continuous object where the equation-element belongs to
+				Continuous* continuous;
+
+				// index of the variable to get/set (range 0..(Dimension-1))
+				unsigned index_;
+			};
+		}
+	}
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
+
+#endif /* ODEMX_RATE_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/continuous/State.h b/odemx-lite/include/odemx/base/continuous/State.h
new file mode 100644
index 0000000000000000000000000000000000000000..904205a724f2ace64b129e4082c579c172c3275e
--- /dev/null
+++ b/odemx-lite/include/odemx/base/continuous/State.h
@@ -0,0 +1,154 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/** \file State.h
+
+ 	\author Sascha Qualitz
+
+ 	\date created at 2010/2/26
+
+ 	\brief Declaration of class odemx::base::continuous::State
+
+ 	\sa State.cpp
+
+    \since 3.0
+ */
+
+#ifndef ODEMX_STATE_INCLUDED
+#define ODEMX_STATE_INCLUDED
+
+#include <odemx/setup.h>
+
+// usage of this class requires SimTime type double,
+// which can be switched at compile time by defining
+// ODEMX_USE_CONTINUOUS in file odemx/setup.h
+#ifdef ODEMX_USE_CONTINUOUS
+
+namespace odemx {
+	namespace base {
+		namespace continuous {
+
+			//Forward declaration
+			class Continuous;
+
+			class ODEObject;
+
+			/** \class State
+
+				\ingroup base
+
+				\author Sascha Qualitz
+
+				\brief Object for handling an equation-element of the right hand side of an equation.
+					   Used in the derivates function in a derived class of ODEObject.
+
+				To describe ordinary differential equations the user has to use this class.
+
+				\sa Rate
+				\sa JacobiMatrix
+				\sa DfDt
+			 */
+			class State {
+			public:
+				/**
+					\brief Construction
+
+					\note The variables continuous and index_ will be set to 0.
+				*/
+				State();
+				/**
+					\brief Construction
+					\param continuous
+						pointer to the continuous object where the equation-element belongs to
+
+					\note The variable index_ will be set to 0.
+				*/
+				State(Continuous* continuous);
+
+				/// destruction
+				virtual ~State();
+
+				/**
+					\brief Overrides the double converting-operator, to convert implicit an object of type state to type double.
+
+					\note If this operator is called, the double value is the value that is returned by the method
+					getValueForDerivative(index_) of the corresponding continuous-object. The variable index_ was
+					set to an index between 0 and continuous->getDimension-1 before. To set the variables index_
+					see also the method	operator [].
+				*/
+				operator double() {
+					return this->getValue();
+				}
+
+				/**
+					\brief Overrides the index operator to set the internal variable index_
+					\param index
+						index of the variable to get/set (range 0..(Dimension-1))
+				*/
+				State& operator [](const unsigned i);
+
+				/**
+					\brief Sets the continuous variable
+					\param continuous
+						pointer to the continuous object where the equation-element belongs to
+				*/
+				void setContinuous(Continuous* continuous);
+
+				/**
+					\brief Overrides the assignment operator to store the value of type double in the variable container
+					\param value
+						value to be set
+
+					\note Values must not be changed while the responsible monitor is integrating.
+				*/
+				State& operator =(const double value);
+
+			private:
+				/**
+					\brief Returns the value of type double with given index index_
+
+					getValue returns the value from the correct index, because index_ was set by the overwritten operator[] before.
+				*/
+				double getValue() const;
+
+				/**
+					\brief Sets the value of type double at index_
+					\param value
+						value to be set
+
+					\note setValue stores the value at the correct index, because index_ was set by the overwritten operator[] before.
+					\note Values must not be changed while the responsible monitor is integrating.
+				*/
+				void setValue(double value);
+
+
+				// pointer to the continuous object where the equation-element belongs to
+				Continuous* continuous;
+
+				// index of the variable to get/set (range 0..(Dimension-1))
+				unsigned index_;
+
+				friend class Rate;
+			};
+		}
+	}
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
+
+#endif /* ODEMX_STATE_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/continuous/StateEvent.h b/odemx-lite/include/odemx/base/continuous/StateEvent.h
new file mode 100644
index 0000000000000000000000000000000000000000..f8f5d7d651a42f2c7f4c5b4e94dca9ee52e46081
--- /dev/null
+++ b/odemx-lite/include/odemx/base/continuous/StateEvent.h
@@ -0,0 +1,117 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file StateEvent.h
+
+ \author Michael Fiedler
+
+ \date created at 2008/11/21
+
+ \brief Declaration of StateEvent
+
+ \sa Monitor
+
+ \since 3.0
+ */
+
+#ifndef ODEMX_STATEEVENT_INCLUDED
+#define ODEMX_STATEEVENT_INCLUDED
+
+#include <odemx/setup.h>
+
+// usage of this class requires SimTime type double,
+// which can be switched at compile time by defining
+// ODEMX_USE_CONTINUOUS in file odemx/setup.h
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <odemx/base/continuous/ODESolver.h>
+#include <odemx/data/Producer.h>
+#include <odemx/data/Observable.h>
+
+namespace odemx {
+	namespace base {
+		namespace continuous {
+
+			//forward declaration
+			class StateEventObserver;
+
+			/** \class StateEvent
+
+				\ingroup base
+
+				\author Michael Fiedler
+
+				\brief Check for conditions while integration and specify action
+
+				The class StateEvent is for checking if continuous processes arrives a special state
+				specified by condition and than triggers an event specified by action
+
+				\since 3.0
+			 */
+			class StateEvent {
+			public:
+				/// destruction
+				virtual ~StateEvent();
+
+				/** \name Handle assigned Monitor
+
+					@{
+				 */
+				/** \brief Sets the Monitor where the StateEvent will be checked
+					\param monitor
+						pointer to the Monitor where it will be checked
+
+					\note If this instance is already assigned to a Monitor it will automatically be transferred.
+					\note If \p monitor is NULL the StateEvent will be removed from an assigned Monitor.
+				 */
+				void setMonitor(Monitor *monitor);
+
+				/** \brief Returns the Monitor where this StateEvent belongs to
+				 */
+				Monitor* getMonitor();
+				//@}
+
+				/** \brief Condition which will be checked
+
+					This is to be implemented by the user. When condition returns true the action will be triggered by the monitor.
+
+					\note If condition is true when added to the Monitor, then the action will be triggered immediately.
+				 */
+				virtual bool condition(SimTime time) = 0;
+
+				/** \brief Action which will be executed when condition occurs
+
+					This is to be implemented by the user. When condition returns true this action will be triggered by the monitor.
+
+					\note If condition is true when added to the Monitor, then action will be triggered immediately.
+				 */
+				virtual void action() = 0;
+
+			private:
+				// Monitor where the StateEvent will be checked
+				Monitor *monitor;
+
+				friend class Monitor;
+			};
+		}
+	}
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
+
+#endif /* ODEMX_STATEEVENT_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/continuous/VariableContainer.h b/odemx-lite/include/odemx/base/continuous/VariableContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..9f8a65ae935d47325882d99d1ad46cc23b4333b6
--- /dev/null
+++ b/odemx-lite/include/odemx/base/continuous/VariableContainer.h
@@ -0,0 +1,208 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file VariableContainer.h
+
+ \author Michael Fiedler
+
+ \date created at 2008/11/21
+
+ \brief Declaration of VariableContainer
+
+ \since 3.0
+ */
+
+#ifndef ODEMX_VARIABLECONTAINER_INCLUDED
+#define ODEMX_VARIABLECONTAINER_INCLUDED
+
+#include <odemx/setup.h>
+
+// usage of this class requires SimTime type double,
+// which can be switched at compile time by defining
+// ODEMX_USE_CONTINUOUS in file odemx/setup.h
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <odemx/base/continuous/Monitor.h>
+
+namespace odemx {
+	namespace base {
+		namespace continuous {
+
+			/** \class VariableContainer
+
+				\ingroup base
+
+				\brief Abstract class for implementing memory handling of a solver.
+
+				\sa ODESolver, Monitor
+
+				\since 3.0
+			 */
+			class VariableContainer {
+			public:
+				/// destruction
+				virtual ~VariableContainer();
+
+				/** \brief Adapts the numbers of variables which can be stored in the container
+					\param newSize
+						new size of container
+
+					\note Old content is preserved as long as it fits in \p newSize, everything over will be truncated.
+				 */
+				virtual void adaptSizeTo(int newSize) = 0;
+
+				/** \name Variables
+
+				 	 Variables are for holding values, while derivatives, jacobi and DfDt are for calculating.
+
+				 @{
+				 */
+				/** \brief Sets all variables to 0.0
+				 */
+				virtual void nullVariables() = 0;
+
+				/** \brief Sets value of one variable
+					\param num
+						index of variable on which \p value is set
+				 */
+				virtual void setVariable(int num, double value) = 0;
+
+				/** \brief Returns the value of one variable
+					\param num
+						index of returned variable
+				 */
+				virtual double getVariable(int num) = 0;
+				//@}
+
+				/** \name temporary values
+
+					These values are used during the calculation of the intermediate steps.
+
+				 @{
+				 */
+				/** \brief Sets all temporary variables to 0.0
+				 */
+				virtual void nullValues() = 0;
+
+				/** \brief Copies values of temporary variables to the corresponding variables
+				 */
+				virtual void copyVariablesToValues() = 0;
+
+				/** \brief Sets value of one temporary variable
+					\param num
+						index of variable on which \p value is set
+				 */
+				virtual void setValue(int num, double value) = 0;
+
+				/** \brief Returns value of one temporary variable
+					\param num
+						index of returned variable
+				 */
+				virtual double getValue(int num) = 0;
+				//@}
+
+				/** \name derivatives
+
+					@{
+				 */
+				/** \brief Sets all derivative values to 0.0
+				 */
+				virtual void nullDerivatives() = 0;
+
+				/** \brief Sets value of one derivative variable
+					\param num
+						index of variable on which \p value is set
+				 */
+				virtual void setDerivative(int num, double value) = 0;
+
+				/** \brief Adds value to one derivative variable
+					\param num
+						index of variable to which \p value will be added
+				 */
+				virtual void addToDerivative(int num, double value) = 0;
+
+				/** \brief Returns value of one derivative variable
+					\param num
+						index of returned variable
+				 */
+				virtual double getDerivative(int num) = 0;
+				//@}
+
+				/** \name jacobi
+
+					@{
+				 */
+				/** \brief Sets all jacobian values to 0.0
+				 */
+				virtual void nullJacobi() = 0;
+
+				/** \brief Sets value of one jacobian variable
+
+						Sets variable(\p i ,\p j ) to \p value.
+				 */
+				virtual void setJacobi(int i, int j, double value) = 0;
+
+				/**  \brief Sets value of one jacobian variable
+
+						Adds \p value to variable(\p i ,\p j ).
+				 */
+				virtual void addToJacobi(int i, int j, double value) = 0;
+
+				/** \brief Returns value of one jacobian variable
+
+					\return variable of index (\p i ,\p j )
+				 */
+				virtual double getJacobi(int i, int j) = 0;
+				//@}
+
+				/** \name DfDt
+
+					right hand side derived by time
+
+				 @{
+				 */
+				/** \brief Sets all derived components to 0.0
+				 */
+				virtual void nullDfDt() = 0;
+
+				/** \brief Sets value of one derived component
+					\param num
+						index of derived component on which \p value is set
+				 */
+				virtual void setDfDt(int num, double value) = 0;
+
+				/** \brief Adds value to one derived component
+					\param num
+						index of derived component to which \p value will be added
+				 */
+				virtual void addToDfDt(int num, double value) = 0;
+
+				/** \brief Returns value of one derived component
+					\param num
+						index of returned derived component
+				 */
+				virtual double getDfDt(int num) = 0;
+				//@}
+			};
+		}
+	}
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
+
+#endif /* ODEMX_VARIABLECONTAINER_INCLUDED */
diff --git a/odemx-lite/include/odemx/base/control/Control.h b/odemx-lite/include/odemx/base/control/Control.h
new file mode 100644
index 0000000000000000000000000000000000000000..78fd5236d844b40808a23cd6eb254373d93c50cd
--- /dev/null
+++ b/odemx-lite/include/odemx/base/control/Control.h
@@ -0,0 +1,239 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2003, 2004, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Control.h
+ * @author Jonathan Schlue
+ * @date created at 2016/10/06
+ * @brief Header declaration and header-only definitions of all class templates for Control Variables for built-in types.
+ * @sa ControlBase.h
+ * @sa ControlBase.cpp
+ * @since 3.1
+ */
+
+#ifndef ODEMX_BASE_CONTROL_INCLUDED
+#define ODEMX_BASE_CONTROL_INCLUDED
+
+#include <type_traits>
+
+#include <odemx/base/control/ControlBase.h>
+
+
+namespace odemx {
+namespace base {
+
+/** \class Control
+	
+	\ingroup base
+	
+	\author Jonathan Schlue
+	
+	\brief %Control represents and acts as a general interface for control variables of built-in types.
+	
+	%Control variables wrap variables of built-in types. All increment, decrement and binary assignment operators are overloaded, so that
+ 	changes to the variable are recognized and registered processes are alerted using ControlBase's signal() method. Apart from that,
+ 	control variables act exactly as their wrapped built-in type. Use "Control<T>" as a type for variable declarations, where T may be any build-in type.
+	
+ 	\note Waiting processes are alerted only if the variable value changes.
+	
+ 	\note All operators are overloaded in a canonical manner. For implementation details please refer to the source code directly.
+	
+	\since 3.1
+*/
+template <typename T>
+class Control: public ControlBase
+{
+	static_assert(
+		std::is_integral<T>::value,
+		"Only integral build-in types may be used as control variables."
+	);
+	
+public:
+	Control() = default;
+	
+	Control(const T& val)
+	: val_(val)
+	{}
+	
+	operator T() const
+	{
+		return val_;
+	}
+	
+	// ASSIGNMENT
+	
+	Control<T>& operator=(const T& other)
+	{
+		if (val_ != other)
+		{
+			val_ = other;
+			signal();
+		}
+		return *this;
+	}
+	
+	// BINARY ASSIGNMENT ARITHMETICS
+	
+	Control<T>& operator+=(const T& other)
+	{
+		if (other != 0)
+		{
+			val_ += other;
+			signal();
+		}
+		return *this;
+	}
+	
+	Control<T>& operator-=(const T& other)
+	{
+		if (other != 0)
+		{
+			val_ -= other;
+			signal();
+		}
+		return *this;
+	}
+	
+	Control<T>& operator*=(const T& other)
+	{
+		if (val_ != 0 && other != 1)
+		{
+			val_ *= other;
+			signal();
+		}
+		return *this;
+	}
+	
+	Control<T>& operator/=(const T& other)
+	{
+		if (val_ != 0 && other != 1)
+		{
+			val_ /= other;
+			signal();
+		}
+		return *this;
+	}
+	
+	// BINARY ASSIGNMENT MODULO
+	
+	std::enable_if<std::is_integral<T>::value, Control<T>&> operator%=(const T& other)
+	{
+		T res = val_ % other;
+		if (res != val_)
+		{
+			val_ = res;
+			signal();
+		}
+		return *this;
+	}
+	
+	// BINARY ASSIGNMENT BITWISE
+	
+	std::enable_if<std::is_integral<T>::value, Control<T>&> operator^=(const T& other)
+	{
+		T res = val_ ^ other;
+		if (val_ != res)
+		{
+			val_ = res;
+			signal();
+		}
+		return *this;
+	}
+	
+	std::enable_if<std::is_integral<T>::value, Control<T>&> operator&=(const T& other)
+	{
+		T res = val_ & other;
+		if (val_ != res)
+		{
+			val_ = res;
+			signal();
+		}
+		return *this;
+	}
+	
+	std::enable_if<std::is_integral<T>::value, Control<T>&> operator|=(const T& other)
+	{
+		T res = val_ | other;
+		if (val_ != res)
+		{
+			val_ = res;
+			signal();
+		}
+		return *this;
+	}
+	
+	std::enable_if<std::is_integral<T>::value, Control<T>&> operator<<=(unsigned shift)
+	{
+		if (shift != 0)
+		{
+			val_ <<= shift;
+			signal();
+		}
+		return *this;
+	}
+	
+	std::enable_if<std::is_integral<T>::value, Control<T>&> operator>>=(unsigned shift)
+	{
+		if (shift != 0)
+		{
+			val_ >>= shift;
+			signal();
+		}
+		return *this;
+	}
+	
+	// INCREMENT
+	
+	std::enable_if<!std::is_same<T,bool>::value, Control<T> > operator++(int)
+	{
+		Control<T> temp = *this;
+		++*this;
+		return temp;
+	}
+	
+	std::enable_if<!std::is_same<T,bool>::value, Control<T>&> operator++()
+	{
+		++val_;
+		signal();
+		return *this;
+	}
+	
+	// DECREMENT
+	
+	std::enable_if<!std::is_same<T,bool>::value, Control<T> > operator--(int)
+	{
+		Control<T> temp = *this;
+		--*this;
+		return temp;
+	}
+	
+	std::enable_if<!std::is_same<T,bool>::value, Control<T>&> operator--()
+	{
+		--val_;
+		signal();
+		return *this;
+	}
+	
+private:
+	T val_;
+};
+
+} // END namespace base
+} // END namespace odemx
+
+#endif //ODEMX_BASE_CONTROL_INCLUDED
diff --git a/odemx-lite/include/odemx/base/control/ControlBase.h b/odemx-lite/include/odemx/base/control/ControlBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..ad97ff506a5e096d81f0e6ccbb996efd9742980d
--- /dev/null
+++ b/odemx-lite/include/odemx/base/control/ControlBase.h
@@ -0,0 +1,110 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2003, 2004, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ControlBase.h
+ * @author Jonathan Schlue
+ * @date created at 2016/10/06
+ * @brief Header declaration of a base a class for all Control variables, signaling informed lambda expressions on change.
+ * @sa Control.h
+ * @sa IMemory.h
+ * @since 3.1
+ */
+
+#ifndef ODEMX_BASE_CONTROLBASE_INCLUDED
+#define ODEMX_BASE_CONTROLBASE_INCLUDED
+
+#include <map>
+
+#include <odemx/base/TypeDefs.h>
+#include <odemx/synchronization/IMemory.h>
+
+
+namespace odemx {
+namespace base {
+
+
+/** \class ControlBase
+	
+	\ingroup base
+	
+	\author Jonathan Schlue
+	
+	\brief ControlBase acts as base class for all control variable types.
+	
+	\note ControlBase supports Process alertion.
+	
+	ControlBase implements the IMemory interface to act as an alerter for remembered, waiting processes.
+ 	Control variables are subclass of ControlBase and alert waiting processes on change.
+ 	ControlBases are not instantiable, only Control variables are.
+	
+	\since 3.1
+*/
+class ControlBase : public odemx::synchronization::IMemory
+{
+public:
+
+	/// Destruction
+	virtual ~ControlBase()
+	{}
+
+	/// Get the Control variable memory type: "CONTROL"
+	virtual Type getMemoryType() const override;
+	friend class Process;
+
+protected:
+
+	/// Protected copy constructor to forbid user instantiation
+	ControlBase(const ControlBase&) = default;
+
+	/// Protected move constructor to forbid user movement
+	ControlBase(ControlBase&&) = default;
+
+	/// Protected compiler generated default constructor
+	ControlBase() = default;
+
+	/// Wake up all waiting processes using FIFO strategy by calling their hold() method
+	void signal();
+
+private:
+	virtual bool isAvailable() override;
+	virtual void alert() override;
+	virtual bool remember(base::Sched* newObject) override;
+	virtual bool forget(base::Sched* rememberedObject) override;
+	virtual void eraseMemory() override;
+
+	/// Private copy assignment to forbid usage
+	ControlBase& operator =(const ControlBase&) = default;
+
+	/// Private move assignment to forbid usage
+	ControlBase& operator =(ControlBase&&) = default;
+
+	/**
+	 * \brief List of all registered, waiting processes
+	 *
+	 * Processe are registed, whenever they wait until an arbitrary condition comes true using their waitUntil() method.
+	 * All involved and explicitely listed control variables then register these processes and alert them on change to eventually
+	 * check their condition again.
+	 */
+	ProcessList waitingProcesses_;
+};
+
+}
+}
+
+#endif //ODEMX_BASE_CONTROLBASE_INCLUDED
diff --git a/odemx-lite/include/odemx/coroutine/Coroutine.h b/odemx-lite/include/odemx/coroutine/Coroutine.h
new file mode 100644
index 0000000000000000000000000000000000000000..7dddc217659fd1bced9d23f71e41a395506bccd2
--- /dev/null
+++ b/odemx-lite/include/odemx/coroutine/Coroutine.h
@@ -0,0 +1,235 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Coroutine.h
+ * @author Ralf Gerstenberger
+ * @date created at 2002/01/22
+ * @brief Declaration of odemx::coroutine::Coroutine and observer
+ * @sa Coroutine.cpp
+ * @since 1.0
+ */
+
+#ifndef ODEMX_CORO_COROUTINE_INCLUDED
+#define ODEMX_CORO_COROUTINE_INCLUDED
+
+#include <odemx/coroutine/System.h>
+#include <odemx/coroutine/CoroutineContext.h>
+#include <odemx/data/Observable.h>
+
+namespace odemx {
+namespace coroutine {
+
+// forward declaration
+class CoroutineObserver;
+
+/** \class Coroutine
+
+	\ingroup coroutine
+
+	\author Ralf Gerstenberger
+
+	\brief Coroutine implements a function capable of switching execution to and back from another Coroutine inside function body.
+
+	\note Coroutine supports Observation.
+
+	Coroutine is a system dependable but portable coroutine implementation. A coroutine is
+	a function capable of switching execution to a point inside another coroutine and back to
+	a point inside its own function body.
+	The implementation is stack-based for Linux (based on concepts from Stroustrup "Task-Library",
+	AT&T 1991 and Hansen "The C++ -Answer Book", Addison Wesley 1990) and Fiber-based for
+	Microsoft Windows 98 and later (based on process implementation in ODEM by Martin von Löwis).
+
+	The stack-based implementation should be portable to any platform using linear, continuous stacks
+	(growing bottom up or top down) with a C++ (and exception handling) compatible setjmp()/longjmp()
+	implementation.
+
+	\warning Sun (Ultra)Sparc platform has a circular stack and is not supported at the moment.
+	\warning IA-64 platform stores the return address of a function in a special branch register; not supported.
+
+	\since 1.0
+*/
+class Coroutine
+:	public data::Observable< CoroutineObserver >
+{
+public:
+	/**
+		\brief Coroutine states
+
+		A Coroutine transits through 3 states during its lifetime.
+		After creation it is in state CREATED. First time the Coroutine
+		is activated it transits to RUNNABLE. When Coroutine returns
+		it becomes TERMINATED.
+	*/
+	enum State
+	{
+		CREATED, ///< initial state
+		RUNNABLE, ///< working state
+		TERMINATED ///< final state
+	};
+
+	/**
+		\brief start/continue execution of this Coroutine.
+		\note The Coroutine will become the active Coroutine in its CoroutineContext.
+		\note There is no more than one Coroutine active in its context at any time.
+	*/
+	void switchTo();
+
+	/**
+		\copydoc Coroutine::switchTo
+	*/
+	void operator()();
+
+	/// Returns control to the parent coroutine, or - if none exists - to the context
+	void yield();
+	
+public:
+	/**
+		\brief Construction
+		\param c
+			pointer to CoroutineContext of this Coroutine
+			(if c==0 a default CoroutineContext is used)
+		\param o
+			pointer to a CoroutineObserver
+
+		\sa DefaultContext
+	*/
+	Coroutine( CoroutineContext* c = 0, CoroutineObserver* o = 0 );
+
+	virtual ~Coroutine(); ///< Destruction
+
+	/**
+		\brief coroutine state
+		\return current state of Coroutine
+		\sa Coroutine::State
+	*/
+	State getState() const;
+
+	/**
+		\brief get CoroutineContext of Coroutine
+		\return CoroutineContext of this Coroutine
+	*/
+	CoroutineContext* getContext();
+
+	/**
+		\brief parent of coroutine
+		\return parent (first caller) of coroutine
+		\retval 0
+			parent is CoroutineContext
+		\retval !=0
+			pointer to parent coroutine
+	*/
+	Coroutine* getParent();
+
+	/**
+		\brief last caller
+		\return last caller of coroutine
+		\retval 0
+			last caller is CoroutineContext
+		\retval !=0
+			pointer to coroutine
+	*/
+	Coroutine* getCaller();
+
+  /// @todo private & Scheduler as friend? -- only Scheduler will call this method!
+  void freeStack ();
+
+protected:
+	// Coroutine entry point
+	virtual void run() = 0; ///< define this method to implement Coroutine behaviour
+	void clear(); ///< called after execution finished in switchTo(), or in destructor
+
+	// Implementation
+private:
+	CoroutineContext* context; ///< CoroutineContext of this Coroutine
+	Coroutine* parent; ///< return point after start() finished
+	Coroutine* caller; ///< last caller of coroutine
+
+	State state; ///< Coroutine state
+
+	void initialize(); ///< called before first execution
+
+	State setState( State newState ); ///< state transitions
+
+	// System dependent
+	/// \name Fiber based implementation
+	//@{
+	LPVOID myFiber;
+	LPVOID fiber;
+	//@}
+
+	/// \name Fiber based implementation
+	//@{
+	/// prepare execution switch (save active fiber).
+	void saveFiber();
+	//@}
+
+	friend VOID CALLBACK ExecFiber( PVOID );
+	friend void FiberSwitch( LPVOID fiber );
+
+};
+
+/** \interface CoroutineObserver
+
+	\author RalfGerstenberger
+
+	\brief Observer for Coroutine specific events.
+
+	\sa Coroutine
+
+	\since 1.0
+*/
+class CoroutineObserver {
+public:
+	virtual ~CoroutineObserver() {}
+
+	virtual void onCreate( Coroutine* sender ) {} ///< creation
+	virtual void onDestroy( Coroutine* sender ) {} ///< destruction
+
+	virtual void onInitialize( Coroutine* sender ) {} ///< initialisation
+	virtual void onClear( Coroutine* sender ) {} ///< Coroutine is cleared
+
+	/// execution switches between Coroutines
+	virtual void onSwitchTo( Coroutine* sender, Coroutine* previousActive ) {}
+	/// execution switches from Context to Coroutine
+	virtual void onSwitchTo( Coroutine* sender, CoroutineContext* previousActive ) {}
+
+	/// state transition
+	virtual void onChangeState( Coroutine* sender, Coroutine::State oldState,
+			Coroutine::State newState ) {}
+};
+
+/**
+	\internal
+	\brief Fiber start function
+	\param p
+		pointer to a Coroutine
+*/
+VOID CALLBACK ExecFiber( PVOID p );
+
+/**
+	\internal
+	\brief encapsulates SwitchToFiber() call
+	\param fiber
+		pointer to fiber
+*/
+void FiberSwitch( LPVOID fiber );
+
+} } // namespace odemx::coroutine
+
+#endif /* ODEMX_CORO_COROUTINE_INCLUDED */
diff --git a/odemx-lite/include/odemx/coroutine/CoroutineContext.h b/odemx-lite/include/odemx/coroutine/CoroutineContext.h
new file mode 100644
index 0000000000000000000000000000000000000000..8c08e63b4784a51e5a48651171165d8a6a85b223
--- /dev/null
+++ b/odemx-lite/include/odemx/coroutine/CoroutineContext.h
@@ -0,0 +1,187 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file CoroutineContext.h
+ * @author Ralf Gerstenberger
+ * @date created at 2002/02/04
+ * @brief Declaration of odemx::coroutine::CoroutineContext, observer, and DefaultContext
+ * @sa CoroutineContext.cpp
+ * @since 1.0
+ */
+
+#ifndef ODEMX_CORO_COROUTINECONTEXT_INCLUDED
+#define ODEMX_CORO_COROUTINECONTEXT_INCLUDED
+
+#include <odemx/coroutine/System.h>
+#include <odemx/data/Observable.h>
+
+#include <cassert>
+#include <typeinfo>
+#include <exception>
+
+namespace odemx {
+namespace coroutine {
+
+// forward declaration
+class Coroutine;
+class CoroutineContextObserver;
+
+/** \class CoroutineContext
+
+	\ingroup coroutine
+
+	\author Ralf Gerstenberger
+
+	\brief Context for executing Coroutines.
+
+	\note CoroutineContext supports Observation.
+
+	\sa CoroutineContextObserver.
+
+	A CoroutineContext encapsulates the main program. It is required for the use of Coroutine.
+	Execution can be switched between Coroutine and CoroutineContext.
+	The implementation is stack-based for Linux (based on concepts from Stroustrup "Task-Library",
+	AT&T 1991 and Hansen "The C++ -Answer Book", Addison Wesley 1990) or Fiber-based
+	for Microsoft Windows 98 and later (based on process implementation in ODEM by Martin von L�wis).
+
+	The stack-based implementation should be portable to any platform using linear, continuous stacks
+	(growing bottom up or top down) with a C++ (and exception handling) compatible setjmp()/longjmp()
+	implementation.
+
+	\since 1.0
+*/
+class CoroutineContext
+:	public data::Observable< CoroutineContextObserver >
+{
+public:
+	/// Construction
+	CoroutineContext( CoroutineContextObserver* o = 0 );
+	/// Destruction
+	virtual ~CoroutineContext();
+
+	/// Call this method to continue execution in the coroutine context
+	void switchTo();
+
+	friend class Coroutine;
+
+protected:
+	/// Get a pointer to the currently running coroutine
+	Coroutine* getActiveCoroutine();
+	/// Get the number of registered coroutines of this context
+	unsigned int getNumberOfCoroutines();
+
+private:
+	Coroutine* activeCoroutine; ///< active Coroutine
+	unsigned int numberOfCoroutines; ///< counter of Coroutines in this context
+
+	/** \brief set active Coroutine
+		\param c
+			pointer to next active Coroutine
+
+		\return previous active Coroutine
+		\note There is no more than one Coroutine active in a context at any time.
+	*/
+	Coroutine* setActiveCoroutine( Coroutine* c );
+
+	/**
+		\brief register new Coroutine in this context
+		\param cr
+			pointer to new Coroutine
+	*/
+	void beginCoroutine( Coroutine* cr );
+
+	/**
+		\brief Coroutine in this context has finished
+		\param cr
+			pointer to finished Coroutine
+	*/
+	void endCoroutine( Coroutine* cr );
+
+	/// \name Fiber based implementation
+	//@{
+	LPVOID fiber; ///< pointer to context Fiber
+	static bool initFibers; ///< ConvertThreadToFiber called
+	//@}
+
+	/// \name Fiber based implementation
+	//@{
+	void saveFiber(); ///< save current execution point
+	//@}
+
+	friend VOID CALLBACK ExecFiber( PVOID );
+	friend void FiberSwitch( LPVOID fiber );
+};
+
+/** \class CoroutineContextObserver
+
+	\author RalfGerstenberger
+
+	\brief Observer for CoroutineContext specific events.
+
+	\sa CoroutineContext
+
+	\since 1.0
+*/
+class CoroutineContextObserver {
+public:
+	virtual ~CoroutineContextObserver() {}
+
+	virtual void onCreate( CoroutineContext* sender ) {} ///< creation
+	virtual void onDestroy( CoroutineContext* sender ) {} ///< destruction
+
+	/// execution switches from Coroutine to CoroutineContext
+	virtual void onSwitchTo( CoroutineContext* sender, Coroutine* previousActive ) {}
+
+	/// active Coroutine changed (oldActive and newActive might be 0)
+	virtual void onChangeActiveCoroutine( CoroutineContext* sender,
+			Coroutine* oldActive, Coroutine* newActive ) {}
+};
+
+/**
+ * @brief Get a default coroutine context
+ * @return	pointer to the DefaultContext
+ * @relates DefaultContext
+ */
+extern CoroutineContext* getDefaultContext();
+
+/** \class DefaultContext
+
+	\author Ralf Gerstenberger
+
+	\brief Default CoroutineContext for convenience.
+
+	The DefaultContext is provided for convenience. You can
+	use this context if you don't want to define your own.
+
+	The DefaultContext is returned by getDefaultContext().
+
+	\since 1.0
+*/
+class DefaultContext
+:	public CoroutineContext
+{
+private:
+	/// Construction only via getDefaultContext
+	DefaultContext();
+	friend CoroutineContext* getDefaultContext();
+};
+
+} } // namespace odemx::coroutine
+
+#endif /* ODEMX_CORO_COROUTINECONTEXT_INCLUDED */
diff --git a/odemx-lite/include/odemx/coroutine/System.h b/odemx-lite/include/odemx/coroutine/System.h
new file mode 100644
index 0000000000000000000000000000000000000000..7d86e5989ce219b8ba588f297dc09e19573e5413
--- /dev/null
+++ b/odemx-lite/include/odemx/coroutine/System.h
@@ -0,0 +1,45 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file System.h
+ * @author Ralf Gerstenberger
+ * @date created at 2002/02/04
+ * @brief OS- and platform-specific includes, defines and types
+ * @since 1.0
+ */
+
+#ifndef ODEMX_CORO_SYSTEM_INCLUDED
+#define ODEMX_CORO_SYSTEM_INCLUDED
+
+#include <odemx/setup.h>
+
+#ifdef _WIN32
+	#ifndef _WIN32_WINNT
+		#define _WIN32_WINNT 0x0400
+	#endif
+	#ifndef WINVER
+		#define WINVER 0x0400
+	#endif
+	#define WIN32_LEAN_AND_MEAN
+	#include <windows.h>
+#else
+	#include <odemx/coroutine/ucFiber.h>
+#endif
+
+#endif /* ODEMX_CORO_SYSTEM_INCLUDED */
diff --git a/odemx-lite/include/odemx/coroutine/ucFiber.h b/odemx-lite/include/odemx/coroutine/ucFiber.h
new file mode 100644
index 0000000000000000000000000000000000000000..50f8dec213717b83341c112cb75f300e5d52cf21
--- /dev/null
+++ b/odemx-lite/include/odemx/coroutine/ucFiber.h
@@ -0,0 +1,125 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ucFiber.h
+ * @author Klaus Ahrens
+ * @date created at 2009/03/16
+ * @brief Declaration of class ucFiber
+ * @sa ucFiber.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_UCFIBER_INCLUDED
+#define ODEMX_UCFIBER_INCLUDED
+
+#ifndef _WIN32
+
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 520
+#endif
+
+// The value SIGSTKSZ is a system default specifying the number of bytes that
+// would be used to cover the usual case when manually allocating an alternate
+// stack area
+// defined in signal.h
+#include <signal.h>
+
+// this is too small an area on a 64 bit system (using 32k fixed size)
+//#ifdef SIGSTKSZ
+//	#define ODEMX_DEFAULT_STACK_SIZE SIGSTKSZ
+//#else
+	#define ODEMX_DEFAULT_STACK_SIZE (32*1024)
+//#endif
+
+// make ucFiber compatible with the Windows API
+#define CALLBACK
+typedef void VOID;
+typedef void* LPVOID;
+typedef int PVOID; // looks strange but is OK, because all coroutines
+		   // pointers are tunneled as indices into a map !
+
+#include <ucontext.h>
+#include <cstdlib>
+#include <map>
+
+
+namespace odemx {
+namespace coroutine {
+
+/**
+ * @brief Fiber implementation wrapping the POSIX user context in a fiber API
+ * @ingroup coroutine
+ * @author Klaus Ahrens
+ * @since 3.0
+ */
+class ucFiber {
+public:
+
+	ucFiber(void* param);
+	ucFiber(std::size_t stacksize, void (*start)(void*), void* param);
+	~ucFiber();
+
+	static ucFiber* current;
+
+	static void* ConvertThreadToFiber(void* param);
+	static void* GetCurrentFiber();
+	static void* CreateFiber(std::size_t stacksize, void (*start)(void*), void* param);
+	static void  DeleteFiber(void* fiber);
+	static void  SwitchToFiber(void* fiber);
+
+	static void  stackcheck();
+	static void* getCoroutine(int nr);
+
+private:
+	ucontext_t* uc_;
+	void* callStack_;
+	enum StackState {mainStack, okStack, noStack} stackState_;
+	void* tos;
+	static std::map<int, void*> allFibers;
+	static int nFibers;
+};
+
+#define GLOBAL_WRAPPERS
+#ifdef GLOBAL_WRAPPERS
+
+inline void* ConvertThreadToFiber(void* param)
+{ return ucFiber::ConvertThreadToFiber(param); }
+
+inline void* GetCurrentFiber()
+{ return ucFiber::GetCurrentFiber(); }
+
+inline void* CreateFiber(std::size_t stacksize, void (*start)(void*), void* param)
+{ return ucFiber::CreateFiber(stacksize, start, param); }
+
+inline void  DeleteFiber(void* fiber)
+{ return ucFiber::DeleteFiber(fiber); }
+
+inline void  SwitchToFiber(void* fiber)
+{ return ucFiber::SwitchToFiber(fiber); }
+
+inline void  stackcheck()
+{ return ucFiber::stackcheck(); }
+
+#endif /* GLOBAL_WRAPPERS */
+
+#endif /* _WIN32 */
+
+} } // namespace odemx::coroutine
+
+#endif /* ODEMX_UCFIBER_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/Label.h b/odemx-lite/include/odemx/data/Label.h
new file mode 100644
index 0000000000000000000000000000000000000000..34bc1905fb207add062ff89c0ff1bb841de392ab
--- /dev/null
+++ b/odemx-lite/include/odemx/data/Label.h
@@ -0,0 +1,49 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Label.h
+ * @author Ronald Kluth
+ * @date created at 2009/09/19
+ * @brief Declaration of type odemx::data::Label
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DATA_LABEL_INCLUDED
+#define ODEMX_DATA_LABEL_INCLUDED
+
+#include <string>
+
+namespace odemx {
+namespace data {
+
+/**
+ * @brief String type used for object labels in ODEMx
+ *
+ * Every model element class that is derived from class @c odemx::data::Producer
+ * provides unique names for its objects. This is ensured by the simulation context,
+ * which must always be provided. Access to the unique name is given with the method
+ * getLabel().
+ *
+ * @see odemx::data::Producer
+ */
+typedef std::string Label;
+
+} } // namespace odemx::data
+
+#endif /* ODEMX_DATA_LABEL_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/LoggingManager.h b/odemx-lite/include/odemx/data/LoggingManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..2081582503e528636204eb3e75697770fee06945
--- /dev/null
+++ b/odemx-lite/include/odemx/data/LoggingManager.h
@@ -0,0 +1,165 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file LoggingManager.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/18
+ * @brief Declaration of odemx::data::LoggingManager
+ * @sa LoggingManager.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DATA_LOGGINGMANAGER_INCLUDED
+#define ODEMX_DATA_LOGGINGMANAGER_INCLUDED
+
+#include <odemx/setup.h>
+#include <odemx/base/SimTime.h>
+#include <odemx/data/ManagedChannels.h>
+#include <odemx/data/SimRecord.h>
+#include <odemx/data/output/DefaultLoggingType.h>
+#include <CppLog/ChannelManager.h>
+
+#include <string>
+
+namespace odemx {
+namespace data {
+
+//----------------------------------------------------------forward declarations
+
+class StatisticsReport;
+struct DefaultLogConfig;
+
+//-----------------------------------------------------------header declarations
+
+/**
+ * @brief Facilitates log channel management, error logging, and default logging
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::data::Producer, ODEMX_DECLARE_DATA_CHANNEL
+ *
+ * The logging manager is a base class for the simulation context. It is
+ * primarily responsible for creating and providing access to the log
+ * channels that ODEMx provides by default:
+ * @li trace
+ * @li debug
+ * @li info
+ * @li warning
+ * @li error
+ * @li fatal
+ * @li statistics
+ *
+ * All of those channels use the record type @c odemx::data::SimRecord.
+ * Access to the channels is automatically provided within subclasses of
+ * @c odemx::data::Producer.
+ *
+ * Another function of this class is the provision of a name scope for
+ * uniquely labeled objects within one simulation context. All data producers
+ * must request a label from the logging manager, which will ensure its
+ * uniqueness by appending numbers if a particular label already exists.
+ *
+ * Finally, the class handles the initialization of error logging components.
+ * The channels warning, error and fatal can be used by data producers to
+ * notify the user of possible problems. Upon initialization of the manager,
+ * it creates an instance of odemx::data::output::ErrorWriter and   registers
+ * it with these channels.
+ *
+ * @note Care must be taken if all consumers are removed from a log channel,
+ * as this will include the error writer as well.
+ */
+class LoggingManager
+:	public Log::ChannelManager< SimRecord >
+{
+public:
+	/// Construction
+	LoggingManager();
+	/// Construction with different default label and spacer for named elements
+	LoggingManager( const std::string& defLabel, const char defSpace );
+	/// Destruction
+	virtual ~LoggingManager();
+
+	/**
+	 * @brief Activates the default logging functionality
+	 * @param type Determines the type of logging consumer used
+	 * @param location Determines the location for XML and database output
+	 * @retval @c true if the activation was successful
+	 * @retval @c false if the the default logging was already enabled
+	 *
+	 * Default logging simply means initializing one log consumer and
+	 * registering that with all provided channels. The type of the log
+	 * consumer can be determined by the first parameter:
+	 * @li STDOUT creates an odemx::data::output::OStreamWriter for the console
+	 * @li XML creates an odemx::data::output::XmlWriter for XML file output.
+	 * This requires the provision of a base name for the files as second argument.
+	 * @li DATABASE creates an odemx::data::output::DatabaseWriter. This also
+	 * requires a second argument, which must be a connection string for the
+	 * target database. In the case of SQLite, this will be a file name.
+	 * When using ODBC, it must specify driver and user settings.
+	 *
+	 * Additionally, an odemx::data::buffer::StatisticsBuffer object is
+	 * registered with the statistics channel in order to automatically
+	 * collect statistical data.
+	 */
+	bool enableDefaultLogging( output::Type type, const std::string& location = "" );
+
+	/**
+	 * @brief Deactivates the default logging functionality
+	 * @retval @c true if the deactivation was successful
+	 * @retval @c false if the the default logging was not enabled
+	 *
+	 * Both, the default writer, and the statistics buffer objects will be
+	 * removed from the channels and thereby be destroyed.
+	 */
+	bool disableDefaultLogging();
+
+	/**
+	 * @brief Reset the data stored in the statistics buffer
+	 * @param currentTime The current simulation time passed to the statistics buffer.
+	 * @retval @c true if the reset was successful
+	 * @retval @c false if the the default logging was disabled
+	 * @note This requires the default logging to be active
+	 */
+	bool resetDefaultStatistics( base::SimTime currentTime );
+
+	/**
+	 * @brief Create a report from the collected statistical data
+	 * @param type SDTOUT or XML to choose where to create the report
+	 * @param location Required when using XML, this will be used as file name.
+	 * @retval @c true if the reset was successful
+	 * @retval @c false if the the default logging was disabled
+	 * @note This requires the default logging to be active
+	 */
+	bool reportDefaultStatistics( output::Type type, const std::string& location = "" );
+
+private:
+	/// Manages the default logging configuration, if one is set
+	std::unique_ptr< DefaultLogConfig > defaultLogConfig_;
+
+private:
+	/**
+	 * @brief Registers an ErrorWriter with channels warning, error and fatal.
+	 *
+	 * This helper method is called automatically during construction.
+	 */
+	void initErrorLogging();
+};
+
+} } // namespace odemx::data
+
+#endif /* ODEMX_DATA_LOGGINGMANAGER_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/ManagedChannels.h b/odemx-lite/include/odemx/data/ManagedChannels.h
new file mode 100644
index 0000000000000000000000000000000000000000..fa21767cb1d510d7856919806f45c5ab01fec5ff
--- /dev/null
+++ b/odemx-lite/include/odemx/data/ManagedChannels.h
@@ -0,0 +1,130 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ManagedChannels.h
+ * @author Ronald Kluth
+ * @date created at 2009/09/05
+ * @brief Declaration of ODEMx default log channels and various macros
+ * @sa ManagedChannels.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DATA_MANAGEDCHANNELS_INCLUDED
+#define ODEMX_DATA_MANAGEDCHANNELS_INCLUDED
+
+#include <CppLog/DeclareChannel.h>
+
+#ifdef ODEMX_USE_MACRO_COUNTER
+
+/**
+ * @def ODEMX_DECLARE_DATA_CHANNEL( PP_IdName )
+ * @brief Declares a managed channel
+ * @see odemx::data::LoggingManager, odemx::data::Producer
+ *
+ * This macro is used internally to create the log channels provided by ODEMx.
+ * It ensures that each channel has a unique ID, and that subclasses of
+ * @c odemx::data::Producer automatically get access to these channels. This
+ * only works for the predefined channels, though.
+ *
+ * @note In case a compiler does not support the macro __COUNTER__ for ID
+ * generation, there is also a manual variant of the macro called
+ * ODEMX_DECLARE_DATA_CHANNEL_WITH_ID.
+ */
+
+// macro for log channel declaration
+#define ODEMX_DECLARE_DATA_CHANNEL( PP_IdName )									\
+	CPPLOG_DECLARE_CHANNEL( odemx_detail, PP_IdName, odemx::data::SimRecord );	\
+	namespace odemx {															\
+	namespace data {															\
+	namespace channel_id {														\
+	using odemx_detail::PP_IdName;												\
+	} } } // namespace odemx::data::channel_id
+
+#else
+
+#define ODEMX_DECLARE_DATA_CHANNEL_WITH_ID( PP_IdName, PP_IdValue )									\
+	CPPLOG_DECLARE_CHANNEL_WITH_ID( odemx_detail, PP_IdName, odemx::data::SimRecord, PP_IdValue );	\
+	namespace odemx {																				\
+	namespace data {																				\
+	namespace channel_id {																					\
+	using odemx_detail::PP_IdName;																	\
+	} } } // namespace odemx::data::id
+
+#endif
+
+//----------------------------------------------------------forward declarations
+
+namespace odemx {
+namespace data {
+class SimRecord;
+} }
+
+//-----------------------------------------------------------header declarations
+
+#ifdef ODEMX_USE_MACRO_COUNTER
+
+ODEMX_DECLARE_DATA_CHANNEL( trace );
+ODEMX_DECLARE_DATA_CHANNEL( debug );
+ODEMX_DECLARE_DATA_CHANNEL( info );
+ODEMX_DECLARE_DATA_CHANNEL( warning );
+ODEMX_DECLARE_DATA_CHANNEL( error );
+ODEMX_DECLARE_DATA_CHANNEL( fatal );
+ODEMX_DECLARE_DATA_CHANNEL( statistics );
+
+#else
+
+ODEMX_DECLARE_DATA_CHANNEL_WITH_ID( trace, 1000 );
+ODEMX_DECLARE_DATA_CHANNEL_WITH_ID( debug, 1001 );
+ODEMX_DECLARE_DATA_CHANNEL_WITH_ID( info, 1002 );
+ODEMX_DECLARE_DATA_CHANNEL_WITH_ID( warning, 1003 );
+ODEMX_DECLARE_DATA_CHANNEL_WITH_ID( error, 1004 );
+ODEMX_DECLARE_DATA_CHANNEL_WITH_ID( fatal, 1005 );
+ODEMX_DECLARE_DATA_CHANNEL_WITH_ID( statistics, 1006 );
+
+#endif
+
+/**
+ * @def ODEMX_TRACE
+ * @brief Macro to be used for trace logging in odemx classes
+ *
+ * This macro allows for ODEMx tracing to be turned on or off. It does so
+ * by wrapping the trace call in a condition that is either always true
+ * or always false. Modern compilers should completely optimize out
+ * code that contains <tt>if( false ) {...}</tt>.
+ */
+#define ODEMX_TRACE \
+	if( ODEMX_TRACE_ENABLED ) this->trace
+
+namespace odemx {
+namespace data {
+namespace channel_id {
+
+/**
+ * @brief Get a string representation of a log channel name
+ * @param id The ID of the log channel
+ * @return The name of the log channel as string
+ *
+ * If other IDs than those know to ODEMx are given as argument, then
+ * the return value will simply state "user-defined".
+ */
+extern const std::string toString( const Log::ChannelId id );
+
+} } } // namespace odemx::data::channel_id
+
+#endif /* ODEMX_DATA_MANAGEDCHANNELS_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/Observable.h b/odemx-lite/include/odemx/data/Observable.h
new file mode 100644
index 0000000000000000000000000000000000000000..18c4979c8e406336b0b087793726420eea698200
--- /dev/null
+++ b/odemx-lite/include/odemx/data/Observable.h
@@ -0,0 +1,225 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Observable.h
+ * @author Ralf Gerstenberger
+ * @date created at 2002/02/11
+ * @brief Declaration and implementation of odemx::data::Observable
+ * @since 1.0
+ */
+
+#if defined(_MSC_VER)
+#pragma warning(disable : 4250 4786)
+#endif
+
+#ifndef ODEMX_OBSERVABLE_INCLUDED
+#define ODEMX_OBSERVABLE_INCLUDED
+
+#include <odemx/setup.h>
+
+#include <algorithm>
+#include <list>
+
+namespace odemx {
+namespace data {
+
+/**
+ * @brief Observable provides management of observers.
+ * @ingroup data
+ * @author Ralf Gerstenberger
+ *
+ * Observation is meant as an association scheme between two
+ * objects, one observed, one observing, that share an individual (observation)
+ * interface. The observed object reports events and attribute changes
+ * of some meaning through the interface to the observer, which implements this
+ * xxxObserver interface. The xxxObserver interface is defined along with the
+ * class of the observed object, where xxx is replaced with the class name.
+ * An Observer is a client to its observed object and managed by the class
+ * template Observable. A class that supports the observation scheme as a type
+ * for observed objects should use Observable as a base class.
+ *
+ * @note If ODEMX_USE_OBSERVATION is not defined in odemx/setup.h,
+ * this class is compiled as empty (base) class.
+ *
+ * @since 1.0
+ */
+template< typename ObserverT >
+class Observable
+{
+
+// this is essentially an empty base class if observation is disabled
+#ifdef ODEMX_USE_OBSERVATION
+
+public:
+	/// Construction
+	Observable( ObserverT* obs = 0 )
+	{
+		if( obs != 0 )
+		{
+			observers.push_back( obs );
+		}
+	}
+
+	/// Get observer list
+	const std::list<ObserverT*>& getObservers()
+	{
+		return observers;
+	}
+
+	/// Add an observer to the list
+	void addObserver( ObserverT* newObserver )
+	{
+		typename std::list< ObserverT* >::iterator found
+			= std::find( observers.begin(), observers.end(), newObserver );
+
+		if( found == observers.end() )
+		{
+			observers.push_back( newObserver );
+		}
+	}
+
+	/// Remove an observer from the list
+	void removeObserver( ObserverT* ob ) {observers.remove(ob);}
+
+private:
+	/// The list of registered observers
+	std::list< ObserverT* > observers;
+
+#else /* ODEMX_USE_OBSERVATION not defined */
+
+public:
+	// for compatibility with derived classes, this empty constructor is needed
+	Observable( ObserverT* obs = 0 ) {}
+
+#endif /* ODEMX_USE_OBSERVATION */
+
+};
+
+#ifdef ODEMX_USE_OBSERVATION
+
+/**
+	\brief Broadcast event
+
+	\ingroup data
+
+	\param ObserverType
+		Type of observer (xxxObserver)
+
+	\param Event
+		Event handler function without on ( Create(this)->onCreate(this) )
+*/
+#define ODEMX_OBS(ObserverType, Event) \
+{\
+	for(std::list<ObserverType* >::const_iterator \
+		i = data::Observable<ObserverType >::getObservers().begin(); \
+		i != data::Observable<ObserverType >::getObservers().end(); ++i) \
+		{ \
+			(*i)->on##Event;\
+		} \
+}
+
+/**
+	\brief Broadcast attribute change
+
+	\ingroup data
+
+	\param ObserverType
+		Type of observer (xxxObserver)
+
+	\param Attribute
+		Changed attribute name
+
+	\param oldValue
+		Old value of attribute
+
+	\param newValue
+		New value of attribute
+*/
+#define ODEMX_OBS_ATTR(ObserverType, Attribute, oldValue, newValue) \
+{\
+	for(std::list<ObserverType* >::const_iterator \
+		i = data::Observable<ObserverType >::getObservers().begin(); \
+		i != data::Observable<ObserverType >::getObservers().end(); ++i) \
+		{ \
+			(*i)->onChange##Attribute(this, oldValue, newValue); \
+		} \
+}
+
+
+/**
+	\brief Broadcast event with observer interface template
+
+	\ingroup data
+
+	\param ObserverType
+		Type of observer (xxxObserver)
+
+	\param Event
+		Event handler function without on ( Create(this)->onCreate(this) )
+*/
+#define ODEMX_OBS_T(ObserverType, Event) \
+{\
+	for( typename std::list<ObserverType* >::const_iterator \
+		i = data::Observable<ObserverType >::getObservers().begin(); \
+		i != data::Observable<ObserverType >::getObservers().end(); ++i) \
+		{ \
+			(*i)->on##Event;\
+		} \
+}
+
+/**
+	\brief Broadcast attribute change with observer interface template
+
+	\ingroup data
+
+	\param ObserverType
+		Type of observer (xxxObserver)
+
+	\param Attribute
+		Changed attribute name
+
+	\param oldValue
+		Old value of attribute
+
+	\param newValue
+		New value of attribute
+*/
+#define ODEMX_OBS_ATTR_T(ObserverType, Attribute, oldValue, newValue) \
+{\
+	for( typename std::list<ObserverType* >::const_iterator \
+		i = data::Observable<ObserverType >::getObservers().begin(); \
+		i != data::Observable<ObserverType >::getObservers().end(); ++i) \
+		{ \
+			(*i)->onChange##Attribute(this, oldValue, newValue); \
+		} \
+}
+
+#else /* ODEMX_USE_OBSERVATION not defined */
+
+// disable all observation macros
+#define ODEMX_OBS(ObserverType, Event)
+#define ODEMX_OBS_ATTR(ObserverType, Attribute, oldValue, newValue)
+#define ODEMX_OBS_T(ObserverType, Event)
+#define ODEMX_OBS_ATTR_T(ObserverType, Attribute, oldValue, newValue)
+
+#endif /* ODEMX_USE_OBSERVATION */
+
+} } // namespace odemx::data
+
+#endif /* ODEMX_OBSERVABLE_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/Producer.h b/odemx-lite/include/odemx/data/Producer.h
new file mode 100644
index 0000000000000000000000000000000000000000..c1c96ed086371502b1d4118a0683542a9d68bf60
--- /dev/null
+++ b/odemx-lite/include/odemx/data/Producer.h
@@ -0,0 +1,269 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file data/Producer.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/18
+ * @brief Declaration of class odemx::data::Producer
+ * @sa Producer.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DATA_PRODUCER_INCLUDED
+#define ODEMX_DATA_PRODUCER_INCLUDED
+
+#include <odemx/setup.h>
+#include <odemx/data/ManagedChannels.h>
+#include <odemx/data/SimRecord.h>
+#include <odemx/data/Label.h>
+
+#include <CppLog/Producer.h>
+
+namespace odemx {
+
+//----------------------------------------------------------forward declarations
+
+namespace base { class Simulation; }
+
+//-----------------------------------------------------------header declarations
+
+namespace data {
+
+/**
+ * @brief Producer base type that enables managed ODEMx log channels
+ * @since 3.0
+ *
+ * The logging library included in ODEMx provides a configurable Producer
+ * template. By passing the IDs of channels (created with macro
+ * ODEMX_DECLARE_DATA_CHANNEL) as Arguments to the template parameter
+ * Enable, the producer class receives shared_ptr members which are
+ * initialized automatically during construction by the logging manager.
+ */
+typedef Log::Producer<
+			Log::Enable<
+				channel_id::trace,
+				channel_id::debug,
+				channel_id::info,
+				channel_id::warning,
+				channel_id::error,
+				channel_id::fatal,
+				channel_id::statistics
+				>
+		> ProducerBase;
+
+/**
+ * @brief Base class for all log-producing classes in ODEMx
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::data::LoggingManager, ODEMX_DECLARE_DATA_CHANNEL
+ *
+ * The class odemx::data::Producer is the base class for all ODEMx components
+ * that produce log records. This includes statistics producers. It is
+ * primarily responsible for enabling access to the log channels that ODEMx
+ * provides by default:
+ * @li trace
+ * @li debug
+ * @li info
+ * @li warning
+ * @li error
+ * @li fatal
+ * @li statistics
+ *
+ * All of those channels use the record type @c odemx::data::SimRecord.
+ * Access to the channels is automatically provided within subclasses of
+ * this class. Channel initialization is based on the cooperation of
+ * producer objects with the logging manager.
+ *
+ * Objects of class odemx::data::Producer are uniquely labeled within one
+ * simulation context because all data producers must request a label from
+ * the logging manager, which is a base class of odemx::base::Simulation.
+ * Uniqueness of labels is ensured by appending numbers if a particular label
+ * already exists within the name scope.
+ *
+ * @note This class replaces the interfaces LabeledObject and TraceProducer
+ * from previous versions of ODEMx.
+ */
+class Producer
+:	public ProducerBase
+{
+public:
+	/// Destruction
+	virtual ~Producer();
+
+	/**
+	 * @brief Enable logging for one producer object
+	 * @see disableLogging
+	 *
+	 * The functionality of enabling and disabling log channels is based on
+	 * shared_ptr members. If the pointer is set, logging is active. Otherwise,
+	 * all logging statements involving a disabled channel are ignored. This
+	 * method reactivates previously disabled log channels.
+	 *
+	 * @note By default, ODEMx logging functionality is enabled for all producers.
+	 * @note The channels @c warning, @c error, and @c fatal are always active.
+	 */
+	void enableLogging();
+
+	/**
+	 * @brief Disable logging for one producer object
+	 * @see enableLogging
+	 *
+	 * Disabling the logging functionality means resetting the shared_ptr
+	 * members which reference the log channels. When sucha  pointer is not
+	 * set all logging statements involving that channel are ignored.
+	 *
+	 * @note This only affects the channels @c trace, @c debug, @c info, and
+	 * @c statistics. The channels @c warning, @c error, and @c fatal are
+	 * always active.
+	 */
+	void disableLogging();
+
+	/// Get the unique label of the object, used for logging and filtering sender names.
+	const Label& getLabel() const;
+
+	/// Get the real type of the object. This is useful for logging and filtering sender types
+	const TypeInfo getType() const;
+
+	/// Get a const reference to the simulation context
+	const base::Simulation& getSimulation() const;
+
+	/// Get a non-const Reference to the simulation context
+	base::Simulation& getSimulation();
+
+protected:
+	/// Construction for subclasses only
+	Producer( base::Simulation& sim, const Label& label );
+
+	/**
+	 * @brief Convenience method to create log records with required parameters
+	 *
+	 * Using this method is the preferred way of creating log records within
+	 * producer classes. Users need only provide the text message of the record
+	 * and additional data such as simulation context, time, and sender
+	 * is added automatically.
+	 *
+	 * Usage:
+	 * @code
+	 *   info << log( "some simulation event" );
+	 * @endcode
+	 */
+	SimRecord log( const StringLiteral& text ) const;
+
+	/**
+	 * @name Statistics convenience methods
+	 *
+	 * Statistical records in ODEMx fall within one of four categories:
+	 * @li countable statistics events
+	 * @li updated sequences of numbers
+	 * @li parameters to be logged only once
+	 * @li reset of accumulated data
+	 *
+	 * The following methods provide quick access to the creation of
+	 * adequate log records for each category.
+	 * @{
+	 */
+	/**
+	 * @brief Log a countable statistics event
+	 * @param name Name of the counted property
+	 * @param value Amount to add to the counter, default is 1
+	 * @return A log record with text "count" and a detail pair of @c name and @c value
+	 */
+	SimRecord count( const StringLiteral& name, std::size_t value = 1 ) const;
+
+	/**
+	 * @brief Log a parameter of a statistics producer
+	 * @tparam ValueT Type of the parameter value
+	 * @param name Name of the parameter
+	 * @param value Value of the parameter, can be of arbitrary simple type
+	 * @return A record with text "parameter" and a detail pair of @c name and @c value
+	 */
+	SimRecord param( const StringLiteral& name, const std::string& value ) const
+	{
+		return log( "parameter" ).detail( name, value );
+	}
+	
+	template < typename ValueT >
+	SimRecord param( const StringLiteral& name, ValueT value ) const
+	{
+		return log( "parameter" ).detail( name, std::to_string(value) ) ;
+	}
+	
+	// old definition - now unsupported
+	/*
+	template < typename ValueT >
+	SimRecord param( const StringLiteral& name, ValueT value ) const
+	{
+		return log( "parameter" ).detail( name, value );
+	}
+	*/
+
+	/**
+	 * @brief Log a record for a sequence of numbers
+	 * @note This method only accepts doubles now. This was done because after switching
+	 * DynamicVar to a POCO-independent type, it doesn't support runtime conversion
+	 * any longer.
+	 * @param name Name of the updated property
+	 * @param value Value of the current update, must be a numeric type
+	 * @return A record with text "update" and a detail pair of @c name and @c value
+	 */
+	SimRecord update( const StringLiteral& name, double value ) const
+	{
+		return log( "update" ).detail( name, value );
+	}
+	
+	// old definition - now unsupported
+	/*
+	template < typename ValueT >
+	SimRecord update( const StringLiteral& name, ValueT value ) const
+	{
+		return log( "update" ).detail( name, value );
+	}
+	*/
+
+	/**
+	 * @brief Log a statistics reset
+	 * @return A record with text "reset" and no additional details
+	 */
+	SimRecord reset() const;
+	//@}
+
+private:
+	/// Pointer to the simulation context
+	base::Simulation* sim_;
+};
+
+/**
+ * @brief Global ostream inserter overload for data producer references
+ *
+ * This makes all data producers string-streamable by writing their label
+ * to the stream.
+ */
+extern std::ostream& operator<<( std::ostream& os, const Producer& obj );
+
+/**
+ * @brief Global ostream inserter overload for data producer pointers
+ *
+ * This operator overload also writes the label of a data producer to the stream.
+ */
+extern std::ostream& operator<<( std::ostream& os, const Producer* obj );
+
+} } // namespace odemx::data
+
+#endif /* ODEMX_DATA_PRODUCER_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/Report.h b/odemx-lite/include/odemx/data/Report.h
new file mode 100644
index 0000000000000000000000000000000000000000..ec5cea4313299efe50e120736a222a67c7d224bc
--- /dev/null
+++ b/odemx-lite/include/odemx/data/Report.h
@@ -0,0 +1,154 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002 - 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Report.h
+ * @author Ralf Gerstenberger
+ * @date created at 2002/06/21
+ * @brief Declaration of class odemx::data::Report
+ * @sa Report.cpp
+ * @since 1.0
+ */
+
+#ifndef ODEMX_DATA_REPORT_INCLUDED
+#define ODEMX_DATA_REPORT_INCLUDED
+
+#include <odemx/data/ReportTable.h>
+
+#include <set>
+#include <string>
+#include <vector>
+
+//----------------------------------------------------------forward declarations
+namespace odemx {
+namespace data {
+
+class ReportProducer;
+
+//-----------------------------------------------------------header declarations
+
+/**
+	\ingroup data
+
+	\author Ralf Gerstenberger
+
+	\brief Base class for special report objects
+
+	\sa ReportTable ReportProducer
+
+	Report is the base class for user defined report objects.
+	Report manages ReportTables, ReportProducers and the report generation.
+	Each Report object represents an individual report. There can be
+	multiple reports in a simulation.
+
+	\since 1.0
+*/
+class Report {
+public:
+
+	/// Destruction
+	virtual ~Report();
+
+	/// \name Reporter handling
+	//@{
+	/// Add a reporter to this Report
+	void addReportProducer( ReportProducer& reporter );
+	/// Remove a reporter from this Report
+	void removeReportProducer( ReportProducer& reporter );
+	//@}
+
+	/// @name ReportTable handling
+	//@{
+	/**
+		\brief Create or retrieve a suitable table by name and definition
+
+		\param name
+			name of new Table
+		\param def
+			TableDefinition of new Table
+
+		\return new Table
+
+		\note If there is already a Table with an equal name and
+		definition it will be returned instead of creating a new Table.
+	*/
+	ReportTable& getTable( const std::string& name, const ReportTable::Definition& def );
+
+	/**
+		\brief generate report by getting data from ReportProducers
+
+		Report generation:
+		@li call all registered ReportProducer objects
+		@li call processTables
+	*/
+	void generateReport();
+
+protected:
+	/**
+		\brief find a Table
+
+		\param name
+			name of Table
+		\param def
+			TableDefinition of Table
+
+		\return found Table or 0
+	*/
+	ReportTable* findTable( const std::string& name, const ReportTable::Definition& def ) const;
+	/**
+	 * @brief Allows defining some actions before the tables get processed
+	 *
+	 * The idea is to give Report specializations a means to do some pre-
+	 * and some post-processing. This can useful for XML output, for example,
+	 * where one might want to start a document.
+	 */
+	virtual void startProcessing() {};
+
+	/**
+		\brief Process arbitrary tables for output
+
+		Report objects have to provide a meaningful processTables() function.
+		This method is responsible for transforming tables from ReportProducers
+		into some output format such as plain text or XML.
+	*/
+	virtual void processTables() = 0;
+
+	/**
+	 * @brief Allows defining some actions after the tables got processed
+	 *
+	 * This method provides the oportunity to do post-processing.
+	 * This can useful for XML output, for example where one might want
+	 * to properly close a document.
+	 */
+	virtual void endProcessing() {};
+	//@}
+
+	/// Vector type to store pointers to generated tables
+	typedef std::vector< ReportTable* > TableVec;
+	/// Vector type to store pointers to registered producers
+	typedef std::set< ReportProducer* > ReportProducerSet;
+
+	/// Contained tables
+	TableVec tables_;
+	/// Associated reporters
+	ReportProducerSet producers_;
+};
+
+} } // namespace odemx::data
+
+#endif /* ODEMX_DATA_REPORT_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/ReportProducer.h b/odemx-lite/include/odemx/data/ReportProducer.h
new file mode 100644
index 0000000000000000000000000000000000000000..b500253c8aa372644bc570af88b276f8c883f911
--- /dev/null
+++ b/odemx-lite/include/odemx/data/ReportProducer.h
@@ -0,0 +1,83 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002 - 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ReportProducer.h
+ * @author Ralf Gerstenberger
+ * @date created at 2002/06/21
+ * @brief Declaration of class odemx::data::ReportProducer
+ * @sa ReportProducer.cpp
+ * @since 1.0
+ */
+
+#ifndef ODEMX_DATA_REPORTER_INCLUDED
+#define ODEMX_DATA_REPORTER_INCLUDED
+
+#include <odemx/data/Label.h>
+#include <CppLog/NamedElement.h>
+
+//----------------------------------------------------------forward declarations
+
+namespace odemx {
+
+namespace base { class Simulation; }
+
+namespace data {
+
+class Report;
+
+//-----------------------------------------------------------header declarations
+
+/** \ingroup data
+
+	\author Ralf Gerstenberger
+
+	\brief A ReportProducer generates data in the form of tables.
+
+	\sa Report ReportTable
+
+	A ReportProducer implementation generates data for reports.
+	It has to implement the pure virtual function report.
+
+	\since 1.0
+*/
+class ReportProducer
+:	public Log::NamedElement
+{
+public:
+	/// Construction with user-defined simulation context
+	ReportProducer( base::Simulation& sim, const Label& label );
+	/// Destruction
+	virtual ~ReportProducer();
+	/// Get the label of the report producer for display in a table column
+	const Label& getLabel() const;
+	/**
+		\brief report generation
+
+		This function is called by a Report object during report generation.
+		A ReportProducer implementation implements this method to
+		provide its data. ReportProducer can be associated to one or
+		more Report objects. A ReportProducer will contribute to each
+		Report it is associated to.
+	*/
+	virtual void report( Report& report ) = 0;
+};
+
+} } // namespace odemx::data
+
+#endif /* ODEMX_DATA_REPORTER_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/ReportTable.h b/odemx-lite/include/odemx/data/ReportTable.h
new file mode 100644
index 0000000000000000000000000000000000000000..0f7645946082f60bdcebdcf9b1bcd98282f422ac
--- /dev/null
+++ b/odemx-lite/include/odemx/data/ReportTable.h
@@ -0,0 +1,360 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ReportTable.h
+ * @author Ronald Kluth
+ * @date created at 2009/12/17
+ * @brief Declaration of class odemx::data::ReportTable
+ * @sa ReportTable.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DATA_REPORTTABLE_INCLUDED
+#define ODEMX_DATA_REPORTTABLE_INCLUDED
+
+#include <odemx/base/SimTime.h>
+#include <odemx/data/Label.h>
+#include <vector>
+
+namespace odemx {
+namespace data {
+
+/**
+ * @brief Container for accumulated data collected from ReportProducers
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see Report ReportProducer
+ *
+ * All data are reported in tables. The structure of a table is defined
+ * by a table definition. A table cannot be created manually. To get a table
+ * object, the user has to request one from a Report object.
+ */
+class ReportTable
+{
+public:
+
+	/**
+	 * @brief Provides column label and type describing column data
+	 *
+	 * All columns in tables are associated to a data type like integer,
+	 * real values or strings, and sometimes represent graphical bars.
+	 */
+	class Column {
+	public:
+		/// Destruction
+		virtual ~Column() {}
+
+		/// Enumeration of the allowed column types in tables
+		enum Type {
+			INTEGER, ///< integer numbers
+			REAL, ///< real numbers
+			STRING, ///< text
+			BAR, ///< graphical representation
+			SIMTIME, ///< used for SimTime
+			INVALID ///< used for undefined columns
+		};
+
+		/// Each column must know its caption label
+		const Label& getLabel() { return label_; }
+		/// Each column must know its type
+		Type getType() { return type_; }
+		/// Get a string representation of the given column type
+		static const std::string typeToString( Type type );
+
+	protected:
+		/// Construction
+		Column( const Label& label, Type type ): label_( label ), type_( type ) {}
+
+	private:
+		/// Each column has a label for the table captions
+		Label label_;
+		/// Each column knows its type
+		Type type_;
+	};
+
+
+	/**
+	 * @brief Representation of a table column that stores data in a vector
+	 *
+	 * ColumnT is the class that stores all table data. It requires a
+	 * label and a column type to be given during construction.
+	 */
+	template < typename DataType >
+	class ColumnT: public Column {
+	public:
+		/// Destructor
+		virtual ~ColumnT() {}
+
+	protected:
+		friend class ReportTable;
+
+		friend ReportTable& operator<<( ReportTable& t, long d );
+		friend ReportTable& operator<<( ReportTable& t, long long d );
+		friend ReportTable& operator<<( ReportTable& t, double d );
+		friend ReportTable& operator<<( ReportTable& t, const std::string& s );
+
+		friend ReportTable& operator>>( ReportTable& t, long& to );
+		friend ReportTable& operator>>( ReportTable& t, long long& to );
+		friend ReportTable& operator>>( ReportTable& t, unsigned long long& to );
+		friend ReportTable& operator>>( ReportTable& t, double& to );
+		friend ReportTable& operator>>( ReportTable& t, std::string& to );
+
+		/// Size type used for column indices
+		typedef typename std::vector< DataType >::size_type SizeType;
+
+		/// Constructor, to be called by Table class only
+		ColumnT( const Label& label, Type type ): Column( label, type ) {}
+
+		/// Append data to column, i.e. add content of next line in table
+		void addData( DataType d ) { data.push_back( d ); }
+
+		/// Read data from column, the given line is range-checked and may throw std::out_of_range
+		const DataType& getData( SizeType line ) const
+		{
+			return data.at( line );
+		}
+	private:
+		/// stores the column data, index represents lines in the Table
+		std::vector< DataType > data;
+	};
+
+	/**
+	 * @brief This class is used to build table definitions at runtime
+	 */
+	class Definition
+	{
+	public:
+		/**
+		 * @brief Control codes used for operator << input into tables
+		 */
+		enum ControlCode
+		{
+			ENDL, ///< end of table line
+			TAB ///< skip column
+		};
+
+		/// Size type used for column indices
+		typedef std::vector< std::string >::size_type SizeType;
+
+		/// Get the number of table columns
+		SizeType getNumberOfColumns() const;
+		/// Get the label of column @c index
+		const std::string& getLabelOfColumn( SizeType index ) const;
+		/// Get the type of column @c index
+		Column::Type getTypeOfColumn( SizeType index ) const;
+
+		/**
+			\brief Add columns to the table definition
+			\param label column label
+			\param type column type
+			Use addColumn() to build a TableDefinition.
+		*/
+		void addColumn( const std::string& label, Column::Type type );
+
+	private:
+		std::vector< std::string > columnLabels_; ///< column labels
+		std::vector< Column::Type > columnTypes_; ///< column types
+	};
+
+	/// Size type used for table indices
+	typedef Definition::SizeType SizeType;
+
+	/// Stores a Table input or output position when streaming data
+	struct Position
+	{
+		Position(): col( 0 ), line( 0 ) {}
+		SizeType col;
+		SizeType line;
+	};
+
+	/// Construction is managed by Report
+	ReportTable( const Label& label, const Definition& def );
+
+	/// Destruction is managed by Report
+	~ReportTable();
+
+	/// \name Table attributes
+	//@{
+	/// Get the name of the table
+	const Label& getLabel() const { return label_; }
+	/// Get the table definition
+	const Definition& getDefinition() const { return def_; }
+
+	/**
+	 * @brief Get number of lines in the table
+	 *
+	 * @note This function returns the number of completely filled lines.
+	 * To finish a line, use Definition::ControlCode.
+	 */
+	SizeType getNumberOfLines() const { return lineCount_; }
+
+	/// Get the number of columns in a table
+	SizeType getNumberOfColumns() const { return columns_.size(); }
+
+	/// Get a specific column label by index
+	const std::string& getLabelOfColumn( SizeType index ) const
+	{
+		return columns_.at( index )->getLabel();
+	}
+
+	/// Get a specific column type by index
+	Column::Type getTypeOfColumn( SizeType index ) const
+	{
+		return columns_.at( index )->getType();
+	}
+	//@}
+
+	/**
+		\name Input streaming
+
+		The data can be entered into a table in a streaming like fashion.
+		The data type has to match the column type. A ControlCode can be
+		used to skip columns or the rest of a line. Skipped columns are
+		filled with default	data <tt>(0, 0.0, "")</tt>.
+
+		@{
+	*/
+	friend ReportTable& operator<<( ReportTable& t, int d );
+	friend ReportTable& operator<<( ReportTable& t, unsigned int d );
+	friend ReportTable& operator<<( ReportTable& t, long d );
+	friend ReportTable& operator<<( ReportTable& t, long long d );
+	friend ReportTable& operator<<( ReportTable& t, unsigned long d );
+	friend ReportTable& operator<<( ReportTable& t, unsigned long long d );
+	friend ReportTable& operator<<( ReportTable& t, float d );
+	friend ReportTable& operator<<( ReportTable& t, double d );
+	friend ReportTable& operator<<( ReportTable& t, const std::string& d );
+	friend ReportTable& operator<<( ReportTable& t, const char* d );
+	friend ReportTable& operator<<( ReportTable& t, Definition::ControlCode d );
+	//@}
+
+	/**
+		\name Output streaming
+
+		The data of a table can be read in a streaming like fashion.
+		The data type has to match the column type.
+		@{
+	*/
+	friend ReportTable& operator>>( ReportTable& t, long& to );
+	friend ReportTable& operator>>( ReportTable& t, long long& to );
+	friend ReportTable& operator>>( ReportTable& t, unsigned long long& to );
+	friend ReportTable& operator>>( ReportTable& t, double& to );
+	friend ReportTable& operator>>( ReportTable& t, std::string& to );
+	//@}
+
+	/**
+		\name Output random access
+
+		Get the data of a specific table cell
+
+		@{
+	*/
+	/**
+		\brief Get SIMTIME value from field (\p col, \p line).
+		\note Column col must be a SIMTIME column.
+	*/
+	base::SimTime getSIMTIME( SizeType col, SizeType line );
+
+	/**
+		\brief Get graphical BAR value from field (\p col, \p line).
+		\note Column col must be a BAR column.
+	*/
+	long getBAR(SizeType col, SizeType line );
+
+	/**
+		\brief Get INTEGER value from field (\p col, \p line).
+		\note Column col must be an INTEGER column.
+	*/
+	long getINTEGER(SizeType col, SizeType line );
+
+	/**
+		\brief Get REAL value from field (\p col, \p line).
+		\note Column col must be an INTEGER or a REAL column.
+	*/
+	double getREAL(SizeType col, SizeType line );
+
+	/**
+		\brief Get a STRING value from field (\p col, \p line).
+		\note Type conversion from BAR, INTEGER and REAL to STRING
+		is done if required.
+	*/
+	std::string getSTRING( SizeType col, SizeType line );
+	//@}
+
+	/// Get the current input column to add data
+	Column* getCurrentInputColumn()
+	{
+		return columns_.at( inputPosition_.col );
+	}
+	/// Get the current output column to read data from
+	Column* getCurrentOutputColumn()
+	{
+		return columns_.at( outputPosition_.col );
+	}
+	/// Get the index of the current output streaming line
+	SizeType getOutputLine() { return outputPosition_.line; }
+
+	/// Add a default value (0, 0.0, "", 0) to the column
+	void addDefaultValue();
+
+private:
+	/// Increment input pointer for streaming, change line if necessary
+	void advanceInputPosition();
+	/// Increment output pointer for streaming, change line if necessary
+	void advanceOutputPosition();
+
+	friend class Report;
+	/// Vector type for storing pointers to table columns
+	typedef std::vector< Column* > ColumnVec;
+
+	Label label_; ///< table label
+	Definition def_; ///< table definition
+	SizeType lineCount_; /// size of table
+	ColumnVec columns_; ///< vector containing pointers to columns
+	Position inputPosition_; ///< input streaming position pointer
+	Position outputPosition_; ///< output streaming position pointer
+};
+
+extern ReportTable& operator<<( ReportTable& t, int d ); ///< enter int value
+extern ReportTable& operator<<( ReportTable& t, unsigned int d ); ///< enter unsigned int value
+extern ReportTable& operator<<( ReportTable& t, long d ); ///< enter long value
+extern ReportTable& operator<<( ReportTable& t, long long d ); ///< enter long long value
+extern ReportTable& operator<<( ReportTable& t, unsigned long d ); ///< enter unsigned long value
+extern ReportTable& operator<<( ReportTable& t, unsigned long long d ); ///< enter unsigned long long value
+extern ReportTable& operator<<( ReportTable& t, float d ); ///< enter float value
+extern ReportTable& operator<<( ReportTable& t, double d ); ///< enter double value
+extern ReportTable& operator<<( ReportTable& t, const std::string& d ); ///< enter std::string value
+extern ReportTable& operator<<( ReportTable& t, const char* d ); ///< enter const char* value
+extern ReportTable& operator<<( ReportTable& t, ReportTable::Definition::ControlCode d ); ///< enter control codes
+
+extern ReportTable& operator>>( ReportTable& t, long& to ); ///< read long value
+extern ReportTable& operator>>( ReportTable& t, long long& to ); ///< read long long value
+extern ReportTable& operator>>( ReportTable& t, unsigned long long& to ); ///< read unsigned long long value
+extern ReportTable& operator>>( ReportTable& t, double& to ); ///< read double value
+extern ReportTable& operator>>( ReportTable& t, std::string& to ); ///< read std::string value
+
+/**
+ * @brief Compare two table definitions, used for grouping ReportProducer results in the same table
+ * @return @c true if number of columns, all labels and all types are equal
+ */
+extern bool operator==( const ReportTable::Definition& lhs, const ReportTable::Definition& rhs );
+
+} } // namespace odemx::data
+
+#endif /* ODEMX_DATA_REPORTTABLE_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/SimRecord.h b/odemx-lite/include/odemx/data/SimRecord.h
new file mode 100644
index 0000000000000000000000000000000000000000..2fa7318597e7333cbf73a4ca43d5d90bfad5afce
--- /dev/null
+++ b/odemx-lite/include/odemx/data/SimRecord.h
@@ -0,0 +1,429 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file SimRecord.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/16
+ * @brief Declaration of class odemx::data::SimRecord
+ * @sa SimRecord.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DATA_SIMRECORD_INCLUDED
+#define ODEMX_DATA_SIMRECORD_INCLUDED
+
+#include <odemx/base/SimTime.h>
+#include <odemx/data/TableKey.h>
+#include <odemx/data/TypeInfo.h>
+#include <odemx/data/Label.h>
+#include <odemx/util/StringConversion.h>
+#include <CppLog/Record.h>
+#include <CppLog/DeclareInfoType.h>
+
+#include <vector>
+#include <utility>
+#include <type_traits>
+#include <typeinfo>
+#include <tuple>
+
+namespace odemx {
+
+//----------------------------------------------------------forward declarations
+
+namespace base { class Simulation; }
+
+namespace data {
+
+class Producer;
+
+//-----------------------------------------------------------header declarations
+
+/**@brief Variable type that can hold and convert many different types.
+ * @ingroup data
+ * @author Dorian Weber
+ * @since ODEMx-lite-1.0 (based on ODEMx-3.0)
+ * 
+ * This is essentially an implementation of the Boost::Any-Type for ODEMx. It
+ * replaces the Dynamic::Var-Type of the POCO-library that was used before.
+ * Unfortunately, this type had internal conversion capabilities that were not
+ * reproduced with this implementation, so bugs were introduced into the report
+ * mechanism that will hopefully be resolved completely with Alexander Walthers
+ * upcoming work.
+ */
+class DynamicVar
+{
+	template <typename T>
+	using decay = typename std::decay<T>::type;
+	
+	template <typename T>
+	using none = typename std::enable_if<!std::is_same<DynamicVar, T>::value>::type;
+	
+	struct base
+	{
+		virtual ~base() { }
+		virtual bool is(const std::type_info& i) const = 0;
+		virtual base* clone() const = 0;
+	} *p;
+	
+	template <typename T>
+	struct data : base, std::tuple<T>
+	{
+		using std::tuple<T>::tuple;
+		
+		T& get()& { return std::get<0>(*this); }
+		
+		T const& get() const& { return std::get<0>(*this); }
+		
+		bool is(const std::type_info& i) const override { return i == typeid(T); }
+		base* clone() const override { return new data{get()}; }
+	};
+	
+	template <typename T>
+	T &stat() { return static_cast<data<T>&>(*p).get(); }
+	
+	template <typename T>
+	T const &stat() const { return static_cast<data<T> const&>(*p).get(); }
+	
+	template <typename T>
+	T &dyn() { return dynamic_cast<data<T>&>(*p).get(); }
+	
+	template <typename T>
+	T const &dyn() const { return dynamic_cast<data<T> const&>(*p).get(); }
+	
+public:
+	DynamicVar(): p() { }
+	~DynamicVar() { delete p; }
+	
+	DynamicVar(DynamicVar&& s)      : p{s.p} { s.p = nullptr; }
+	DynamicVar(DynamicVar const& s) : p{s.p->clone()} { }
+	
+	template <typename T, typename U = decay<T>, typename = none<U>>
+	DynamicVar(T&& x) : p{new data<U>{std::forward<T>(x)}} { }
+	
+	DynamicVar& operator=(DynamicVar s) { swap(*this, s); return *this; }
+	
+	friend void swap(DynamicVar& s, DynamicVar& r) { std::swap(s.p, r.p); }
+	
+	void clear() { delete p; p = nullptr; }
+	
+	bool empty() const { return p; }
+	
+	template <typename T>
+	bool is() const { return p ? p->is(typeid(T)) : false; }
+	
+	template <typename T>
+	T&& cast() && { return std::move(dyn<T>()); }
+	template <typename T>
+	T&  cast() & { return dyn<T>(); }
+	template <typename T>
+	T const& cast() const& { return dyn<T>(); }
+	
+	template <typename T>
+	T&& as() && { return std::move(stat<T>()); }
+	template <typename T>
+	T&  as() & { return stat<T>(); }
+	template <typename T>
+	T const& as() const& { return stat<T>(); }
+	
+	template <typename T>
+	operator T&&() && { return as<T>(); }
+	template <typename T>
+	operator T&() & { return as<T>(); }
+	template <typename T>
+	operator T const&() const& { return as<T>(); }
+};
+
+// typedef std::experimental::any DynamicVar; // changed in odemx-line from Poco::DynamicVar
+/// String literal wrapper type
+typedef Log::StringLiteral StringLiteral;
+
+/**
+ * @brief Record type used for logging ODEMx simulation data
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::data::Producer
+ *
+ * Starting with Version 3.0 ODEMx is based on a separate logging library
+ * to provide for tracing, debug and error output. The record type of the
+ * logging components is configurable. With this class, ODEMx provides its
+ * own class type for logging information.
+ *
+ * SimRecord objects usually describe one notable simulation event, which is
+ * given as a short text message. Other than that, objects of this type always
+ * transport information about the sender, the simulation context and the
+ * simulation time. Optionally, a class scope can be attached, and an arbitrary
+ * number of details can be provided in the form of name-value-pairs.
+ *
+ * Usage within a producer class:
+ * @code
+ *   channel << log( "some event" ).detail( "name", value ).scope( typeid(ClassName) )
+ * @endcode
+ *
+ * The channel is usually one of the seven log channels provided by ODEMx
+ * (see odemx::data::LoggingManager). The method log creates a SimRecord object
+ * with the aformentioned data, and the methods detail and scope can be chained
+ * together in order to add more information to the log record.
+ */
+class SimRecord
+{
+public:
+	/// Vector type for pairs of names and values of various types
+	typedef std::vector< std::pair< StringLiteral, DynamicVar > > DetailVec;
+
+	/**
+	 * @brief Construction
+	 * @param sim The simulation context
+	 * @param sender The sender of the log record
+	 * @param text A description of the simulation event
+	 *
+	 * SimRecord objects are meant to be created within classes derived from
+	 * odemx::data::Producer. Therefore, these log records are usually not
+	 * constructed directly because the class Producer provides several
+	 * convenience methods to deal with the task.
+	 */
+	SimRecord( const base::Simulation& sim, const Producer& sender,
+			const StringLiteral& text );
+
+	/// Destruction
+	virtual ~SimRecord();
+
+	///	Get the text message of the record
+	const StringLiteral& getText() const;
+	/// Get the simulation context the record originated from
+	const base::Simulation& getSimulation() const;
+	/// Get a reference to the sender object of the record
+	const Producer& getSender() const;
+	/// Get the simulation time at which the record was created
+	base::SimTime getTime() const;
+	/// Get the class scope from which the record was sent
+	const TypeInfo& getScope() const;
+	/// Get a vector containing additional details as name-value pairs
+	const DetailVec& getDetails() const;
+	/// Get a @c shared_ptr referencing the detail vector
+	const std::shared_ptr< DetailVec > getDetailPointer() const;
+
+	/// Check whether the class scope of the record is set
+	bool hasScope() const;
+	/// Store the class scope from which this record was sent
+	SimRecord& scope( const TypeInfo& type );
+
+	/// Check whether the record carries additional details
+	bool hasDetails() const;
+	/// Add a detail pair consisting of a name and a value
+	template < typename ValueT >
+	SimRecord& detail( const StringLiteral& name, const ValueT& value )
+	{
+		if( ! details_ )
+		{
+			initDetailVec();
+		}
+		details_->push_back( DetailVec::value_type( name, value ) );
+		return *this;
+	}
+	/// Store two details at once, i.e. pairs for the old and the new value
+	template< typename ValueT >
+	SimRecord& valueChange( const ValueT& oldVal, const ValueT& newVal )
+	{
+		if( ! details_ )
+		{
+			initDetailVec();
+		}
+		details_->push_back( DetailVec::value_type( "old value", oldVal ) );
+		details_->push_back( DetailVec::value_type( "new value", newVal ) );
+		return *this;
+	}
+	
+private:
+	/// Stores the text message of this record
+	StringLiteral text_;
+	/// Pointer to the simulation context of the record
+	const base::Simulation* sim_;
+	/// Pointer to the sender object of the record
+	const Producer* sender_;
+	/// Simulation time at which the record was created
+	base::SimTime time_;
+	/// Class scope the record originated from
+	TypeInfo scope_;
+	/// Stores name-value pairs containing additional record details
+	std::shared_ptr< DetailVec > details_;
+
+private:
+	/// Initialize the shared_ptr holding the detail vector
+	void initDetailVec();
+};
+
+} } // namespace odemx::data
+
+/*
+// necessary specialization for DynamicVar to handle long long SimTime as detail value
+namespace Poco {
+namespace Dynamic {
+
+template <>
+class VarHolderImpl<long long>: public VarHolder
+{
+public:
+	VarHolderImpl(long long val): _val(val)
+	{
+	}
+
+	~VarHolderImpl()
+	{
+	}
+
+	const std::type_info& type() const
+	{
+		return typeid(long long);
+	}
+
+	void convert(Int8& val) const
+	{
+		convertToSmaller(_val, val);
+	}
+
+	void convert(Int16& val) const
+	{
+		convertToSmaller(_val, val);
+	}
+
+	void convert(Int32& val) const
+	{
+		convertToSmaller(_val, val);
+	}
+
+	void convert(Int64& val) const
+	{
+		convertToSmaller(_val, val);
+	}
+
+	void convert(UInt8& val) const
+	{
+		convertSignedToUnsigned(_val, val);
+	}
+
+	void convert(UInt16& val) const
+	{
+		convertSignedToUnsigned(_val, val);
+	}
+
+	void convert(UInt32& val) const
+	{
+		convertSignedToUnsigned(_val, val);
+	}
+
+	void convert(UInt64& val) const
+	{
+		convertSignedToUnsigned(_val, val);
+	}
+
+	void convert(bool& val) const
+	{
+		val = (_val != 0);
+	}
+
+	void convert(float& val) const
+	{
+		val = static_cast<float>(_val);
+	}
+
+	void convert(double& val) const
+	{
+		val = static_cast<double>(_val);
+	}
+
+	void convert(char& val) const
+	{
+		UInt8 tmp;
+		convert(tmp);
+		val = static_cast<char>(tmp);
+	}
+
+	void convert(std::string& val) const
+	{
+		val = odemx::toString( _val );
+		//val = NumberFormatter::format(_val);
+	}
+
+	void convert(DateTime& dt) const
+	{
+		dt = Timestamp(_val);
+	}
+
+	void convert(LocalDateTime& ldt) const
+	{
+		ldt = Timestamp(_val);
+	}
+
+	void convert(Timestamp& val) const
+	{
+		val = Timestamp(_val);
+	}
+
+	VarHolder* clone() const
+	{
+		return new VarHolderImpl(_val);
+	}
+
+	const long long& value() const
+	{
+		return _val;
+	}
+
+	bool isArray() const
+	{
+		return false;
+	}
+
+	bool isStruct() const
+	{
+		return false;
+	}
+
+	bool isInteger() const
+	{
+		return std::numeric_limits<long long>::is_integer;
+	}
+
+	bool isSigned() const
+	{
+		return std::numeric_limits<long long>::is_signed;
+	}
+
+	bool isNumeric() const
+	{
+		return std::numeric_limits<long long>::is_specialized;
+	}
+
+	bool isString() const
+	{
+		return false;
+	}
+
+private:
+	VarHolderImpl();
+	VarHolderImpl(const VarHolderImpl&);
+	VarHolderImpl& operator = (const VarHolderImpl&);
+
+	long long _val;
+};
+
+} } // namespace Poco::Dynamic
+*/
+#endif /* ODEMX_DATA_SIMRECORD_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/SimRecordFilter.h b/odemx-lite/include/odemx/data/SimRecordFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..5bab29a7cc6004150428dca80ade84281a520254
--- /dev/null
+++ b/odemx-lite/include/odemx/data/SimRecordFilter.h
@@ -0,0 +1,254 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file SimRecordFilter.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/18
+ * @brief Declaration of class odemx::data::SimRecordFilter
+ * @sa SimRecordFilter.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DATA_SIMRECORDFILTER_INCLUDED
+#define ODEMX_DATA_SIMRECORDFILTER_INCLUDED
+
+#include <odemx/data/Producer.h>
+#include <CppLog/Filter.h>
+
+namespace Log {
+
+/**
+ * @brief Specialization of class template Filter for simulation records
+ *
+ * This template specialization implements the functionality used by the
+ * class SimRecordFilter. The filtering is based on the concept of filter sets,
+ * meaning that users can add values in several categories, which are checked
+ * for matching values in SimRecord objects. For example, one might want to
+ * filter by producer type and hence adds the typeid of that specific class.
+ * All record originating from objects of that class will then match that
+ * entry in the filter set.
+ *
+ * However, matching records are not necessarily filtered out because the
+ * filter supports two different modes: pass all / pass none. In the first
+ * case, all records may pass, except those with a match, while in the second
+ * case all records are blocked and only those that match filter sets may pass.
+ */
+template <>
+class Filter< odemx::data::SimRecord >
+{
+public:
+	/// Construction
+	Filter()
+	:	isSet_( false )
+	,	passAll_( true )
+	{}
+
+	/// Destruction
+	virtual ~Filter() {}
+
+	/// Only filter out the log records matched by the filter
+	void passAll()
+	{
+		isSet_ = true;
+		passAll_ = true;
+	}
+
+	/// Filter out all log records except those matched by the filter
+	void passNone()
+	{
+		isSet_ = true;
+		passAll_ = false;
+	}
+
+	/**
+	 * @brief Add record text values to the filter
+	 *
+	 * @note The method returns a set inserter object that offers a
+	 * streaming operator overload (<<) so that several values can be
+	 * added in one call.
+	 *
+	 * Usage:
+	 * @code
+	 *   filter->addRecordText() << "create" << "destroy";
+	 * @endcode
+	 */
+	Detail::SetInserter< StringLiteral > addRecordText()
+	{
+		// remember that the filter has been initialized
+		isSet_ = true;
+		return Detail::SetInserter< StringLiteral >( recordTexts_ );
+	}
+
+	/**
+	 * @brief Add producer labels to filter out log data from specific sender objects
+	 * @note The method also returns a set inserter object for streaming values.
+	 * @see addRecordText
+	 */
+	Detail::SetInserter< odemx::data::Label > addProducerLabel()
+	{
+		// remember that the filter has been initialized
+		isSet_ = true;
+		return Detail::SetInserter< odemx::data::Label >( senderLabels_ );
+	}
+
+	/**
+	 * @brief Add producer type IDs to filter out log records from specific classes
+	 * @note The method returns a set inserter object for streaming type IDs.
+	 *
+	 * Usage:
+	 * @code
+	 *   filter->addProducerType() << typeid(SomeProcess) << typeid(SomeEvent);
+	 * @endcode
+	 */
+	Detail::SetInserter< odemx::data::TypeInfo > addProducerType()
+	{
+		// remember that the filter has been initialized
+		isSet_ = true;
+		return Detail::SetInserter< odemx::data::TypeInfo >( senderTypes_ );
+	}
+
+	/**
+	 * @brief Add type IDs to filter out log records from specific class scopes
+	 * @note The method also returns a set inserter object for streaming type IDs.
+	 * @see addProducerType
+	 *
+	 * This is particularly useful for filtering in class hierarchies.
+	 * For example, on might not want to see records produced by a base
+	 * class. This method makes it possible to filter these out as long as
+	 * base class provides scope infomation with its records. All ODEMx
+	 * components do.
+	 */
+	Detail::SetInserter< odemx::data::TypeInfo > addRecordScope()
+	{
+		// remember that the filter has been initialized
+		isSet_ = true;
+		return Detail::SetInserter< odemx::data::TypeInfo >( recordScopes_ );
+	}
+
+	/// Reset filter to default values, which effectively disables it
+	void resetFilter()
+	{
+		senderLabels_.clear();
+		senderTypes_.clear();
+		recordScopes_.clear();
+		recordTexts_.clear();
+		isSet_ = false;
+		passAll_ = true;
+	}
+
+	/**
+	 * @brief This method implements the filter interface
+	 * @param record The currently processed log record
+	 * @return true if the record may pass the filter, false otherwise
+	 *
+	 * If the filter is not set, all records may pass. Otherwise, all four
+	 * filter sets are checked for matching values. Should the record contain
+	 * at least one value that is also stored in a filter set, it further
+	 * depends on the filter mode whether the record may pass, in which case
+	 * the method returns @c true.
+	 */
+	bool pass( const odemx::data::SimRecord& record ) const
+	{
+		if( ! isSet_ )
+		{
+			return true;
+		}
+
+		const odemx::data::Producer& sender = record.getSender();
+
+		// check the record text, sender label, sender type and record scope
+		if( recordTexts_.find( record.getText() ) != recordTexts_.end()
+			|| senderLabels_.find( sender.getLabel() ) != senderLabels_.end()
+			|| senderTypes_.find( sender.getType() ) != senderTypes_.end()
+			|| recordScopes_.find( record.getScope() ) != recordScopes_.end() )
+		{
+			// match found, the record may only pass if passAll_ is false
+			return ! passAll_;
+		}
+
+		// no match found, passing depends on pass mode only
+		return passAll_;
+	}
+
+protected:
+	/// Stores whether the filter is active, i.e. contains filter values or uses pass none
+	bool isSet_;
+	/// Stores the filter mode, the default is pass all
+	bool passAll_;
+	/// Stores text values to be matched when filtering records
+	std::set< StringLiteral > recordTexts_;
+	/// Stores sender labels to match for filtering
+	std::set< odemx::data::Label > senderLabels_;
+	/// Stores type IDs to filter by record sender type
+	std::set< odemx::data::TypeInfo > senderTypes_;
+	/// Stores type IDs for filtering records by the class scope they originated from
+	std::set< odemx::data::TypeInfo > recordScopes_;
+};
+
+} // namespace Log
+
+namespace odemx {
+namespace data {
+
+/**
+ * @brief Specialized filter class that can handle SimRecord objects
+ *
+ * The functionality of this class is provided by the template specialization
+ * Log::Filter<SimRecord>. The filtering is based on the concept of filter sets,
+ * meaning that users can add values in several categories, which are checked
+ * for matching values in SimRecord objects. For example, one might want to
+ * filter by producer type and hence adds the typeid of that specific class.
+ * All record originating from objects of that class will then match that
+ * entry in the filter set.
+ *
+ * However, matching records are not necessarily filtered out because the
+ * filter supports two different modes: pass all / pass none. In the first
+ * case, all records may pass, except those with a match, while in the second
+ * case all records are blocked and only those that match filter sets may pass.
+ *
+ * Usage:
+ * @code
+ *   filter->addRecordText() << "create" << "destroy";
+ *   filter->addProducerType() << typeid(SomeClass);
+ *   filter->addProducerLabel() << "DefaultSimulation";
+ *   filter->addRecordScope() << typeid(Process) << typeid(Event);
+ * @endcode
+ *
+ * @see Log::Filter<SimRecord>
+ */
+class SimRecordFilter
+:	public Log::Filter< SimRecord >
+{
+public:
+	/// Creation via static method to enforce shared_ptr-usage
+	static std::shared_ptr< SimRecordFilter > create();
+	/// Destruction
+	virtual ~SimRecordFilter();
+
+protected:
+	/// Construction private, use create instead
+	SimRecordFilter();
+};
+
+/// Pointer type to manage SimRecordFilter objects
+typedef std::shared_ptr< SimRecordFilter > SimRecordFilterPtr;
+
+} } // namespace odemx::data
+
+#endif /* ODEMX_DATA_SIMRECORDFILTER_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/TableKey.h b/odemx-lite/include/odemx/data/TableKey.h
new file mode 100644
index 0000000000000000000000000000000000000000..3daa0a31adf21a93bd158c9b91ca96a77edb3b86
--- /dev/null
+++ b/odemx-lite/include/odemx/data/TableKey.h
@@ -0,0 +1,38 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file TableKey.h
+ * @author Ronald Kluth
+ * @date created at 2009/09/14
+ * @brief Declaration of type odemx::data::TableKey
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DATA_TABLEKEY_INCLUDED
+#define ODEMX_DATA_TABLEKEY_INCLUDED
+
+namespace odemx {
+namespace data {
+
+/// Integer type for representing primary keys in database-related classes
+typedef int TableKey; // changed in odemx-lite, was Int64 (platform dependend)
+
+} } // namespace odemx::data
+
+#endif /* ODEMX_DATA_TABLEKEY_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/TypeInfo.h b/odemx-lite/include/odemx/data/TypeInfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b510dfac1ac03d4c22743e75ccc040fa8f5814f
--- /dev/null
+++ b/odemx-lite/include/odemx/data/TypeInfo.h
@@ -0,0 +1,40 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file data/TypeInfo.h
+ * @author Ronald Kluth
+ * @date created at 2009/09/05
+ * @brief Declaration of type odemx::data::TypeInfo
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DATA_TYPEINFO_INCLUDED
+#define ODEMX_DATA_TYPEINFO_INCLUDED
+
+#include <CppLog/detail/TypeInfo.h>
+
+namespace odemx {
+namespace data {
+
+/// Wrapper around std::type_info that can be used in containers
+typedef Log::Detail::TypeInfo TypeInfo;
+
+} } // namespace odemx::data
+
+#endif /* ODEMX_DATA_TYPEINFO_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/buffer/SimRecordBuffer.h b/odemx-lite/include/odemx/data/buffer/SimRecordBuffer.h
new file mode 100644
index 0000000000000000000000000000000000000000..e11d1c2788dcc429ce2b1c42346cf7773a0cbe21
--- /dev/null
+++ b/odemx-lite/include/odemx/data/buffer/SimRecordBuffer.h
@@ -0,0 +1,161 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file SimRecordBuffer.h
+ * @author Ronald Kluth
+ * @date created at 2009/09/14
+ * @brief Declaration of class odemx::data::SimRecordBuffer
+ * @sa SimRecordBuffer.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DATA_BUFFER_SIMRECORDBUFFER_INCLUDED
+#define ODEMX_DATA_BUFFER_SIMRECORDBUFFER_INCLUDED
+
+#include <odemx/data/SimRecord.h>
+#include <CppLog/ChannelId.h>
+#include <CppLog/Record.h>
+#include <deque>
+
+namespace odemx {
+namespace data {
+
+// info types needed when buffering records
+// used to prevent dangling pointers and provide additional info
+CPPLOG_DECLARE_INFO_TYPE( ChannelInfo, "channel", std::string );
+CPPLOG_DECLARE_INFO_TYPE( ClassScopeInfo, "class_scope", std::string );
+CPPLOG_DECLARE_INFO_TYPE( SenderLabelInfo, "sender_label", Label );
+CPPLOG_DECLARE_INFO_TYPE( SenderTypeInfo, "sender_type", std::string );
+CPPLOG_DECLARE_INFO_TYPE( StringTimeInfo, "sim_time", std::string );
+CPPLOG_DECLARE_INFO_TYPE( SimIdInfo, "sim_id", TableKey );
+
+namespace buffer {
+
+/**
+ * @brief Buffer for storing SimRecord information to allow deferred handling
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::data::SimRecord odemx::data::output::DatabaseWriter
+ *
+ * As soon as a log consumer needs to buffer data, as is the case with class
+ * odemx::data::output::DatabaseWriter, volatile information must be copied
+ * in order to be stored. Otherwise, there is a possibility for dangling
+ * pointers involved because SimRecords do not copy data for efficiency.
+ * Therefore, ODEMx offers this class in order to support the buffering of
+ * log records.
+ */
+class SimRecordBuffer
+{
+public:
+	/// Record type used by the buffer for storing arbitrary information
+	struct StoredRecord: public Log::Record
+	{
+		/// Construction with record text, and details
+		StoredRecord( const Log::StringLiteral& text, std::shared_ptr< SimRecord::DetailVec > details )
+		:	text_( text )
+		,	details_( details )
+		{}
+
+		/// Access the string literal holding the record's text message
+		const Log::StringLiteral& getText() const
+		{
+			return text_;
+		}
+
+		/// Check whether the record has details
+		bool hasDetails() const
+		{
+			return !! details_;
+		}
+
+		/**
+		 * @brief  Get read access the detail vector
+		 * @note This call will crash if the detail vector pointer is invalid.
+		 * Always check @c hasDetails first.
+		 */
+		const SimRecord::DetailVec& getDetails() const
+		{
+			return *details_;
+		}
+	private:
+		/// A copy of the string literal that was sent as record text
+		Log::StringLiteral text_;
+		/// A copy of the shared_ptr to the detail vector created by SimRecord
+		std::shared_ptr< SimRecord::DetailVec > details_;
+	};
+
+	/// Vector type for storing simulation records
+	typedef std::deque< StoredRecord > StorageType;
+	/// Size type used for this buffer
+	typedef StorageType::size_type SizeType;
+
+	/**
+	 * @brief Construction
+	 * @param limit Maximum number of records to be stored by the buffer
+	 *
+	 * @note The limit provides a means to check whether the buffer is full.
+	 * However, it does not stop users from putting more data into the
+	 * buffer, if necessary.
+	 */
+	SimRecordBuffer( SizeType limit );
+
+	/**
+	 * @brief Add another record to the buffer
+	 * @param channelId The channel over which the record was sent
+	 * @param simRecord The actual record to extract the data from
+	 * @param simId An ID representing the simulaiton context of the record
+	 * @param timeString A string representation of the current SimTime
+	 *
+	 * This method copies all relevant information from the SimRecord
+	 * and keeps it in a StoredRecord object.
+	 */
+	void put( const Log::ChannelId channelId, const SimRecord& simRecord,
+			const TableKey simId, const std::string& timeString );
+
+	/// Empty the buffer and reset size
+	void clear();
+
+	/// Check whether the buffer contains any records
+	bool isEmpty() const;
+
+	/// Check whether the buffer has reached its limit
+	bool isFull() const;
+
+	/// Get the current size of the buffer
+	SizeType getSize() const;
+
+	/// Get the maximum size of the buffer
+	SizeType getLimit() const;
+
+	/// Get a reference to the buffer's record vector
+	const StorageType& getStorage() const;
+
+private:
+	StorageType storage_; ///< Container for storing log records
+	SizeType size_; ///< Size counter to avoid use of size() method
+	SizeType limit_; ///< Maximum number of records the buffer can hold
+
+	SimRecordBuffer( const SimRecordBuffer& ); ///< Non-copyable
+	SimRecordBuffer& operator=( const SimRecordBuffer& ); ///< Non-assignable
+};
+
+} } } // namespace odemx::data::buffer
+
+#endif /* ODEMX_DATA_BUFFER_SIMRECORDBUFFER_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/buffer/StatisticsBuffer.h b/odemx-lite/include/odemx/data/buffer/StatisticsBuffer.h
new file mode 100644
index 0000000000000000000000000000000000000000..f25beacaec016f6ecdb062da0f3ce0998eed2ddd
--- /dev/null
+++ b/odemx-lite/include/odemx/data/buffer/StatisticsBuffer.h
@@ -0,0 +1,187 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file StatisticsBuffer.h
+ * @author Ronald Kluth
+ * @date created at 2009/04/07
+ * @brief Declaration of class odemx::data::buffer::StatisticsBuffer
+ * @sa StatisticsBuffer.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DATA_BUFFER_STATISTICSBUFFER_INCLUDED
+#define ODEMX_DATA_BUFFER_STATISTICSBUFFER_INCLUDED
+
+#include <odemx/data/SimRecord.h>
+#include <odemx/data/ReportProducer.h>
+#include <odemx/statistics/Accumulate.h>
+
+#include <CppLog/Consumer.h>
+
+#ifdef _MSC_VER
+#include <memory>
+#else
+#include <memory>
+#endif
+
+#include <deque>
+#include <map>
+#include <string>
+#include <utility>
+
+//----------------------------------------------------------forward declarations
+
+namespace odemx {
+
+namespace base { class Simulation; }
+
+namespace data {
+namespace buffer {
+
+//-----------------------------------------------------------header declarations
+
+/**
+ * @brief A log consumer class that computes and buffers simulation statistics
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::data::Producer odemx::data::LoggingManager
+ *
+ * In previous ODEMx versions, each @c ReportProducer stored its own
+ * accumulated statistical data. With database connectivity, ODEMx needed
+ * a concept that would allow the logging of each statistically relevant
+ * piece of data. Hence, ODEMx offers the log channel statistics and several
+ * convenience methods to create statistical log records. However, retaining
+ * the previous functionality where accumulated data can be computed without
+ * accessing a database, now requires a special log consumer class.
+ *
+ * The StatisticsBuffer consumes log records sent via channel @c statistics.
+ * Producers create such log records in a specific format (namely counters,
+ * parameters, updates, or resets) so that this consumer class can compute
+ * accumulated data from them. The buffer can also store all updates in memory
+ * so that it can be used later in the simulation programm. One such use is the
+ * computation of a histogram, for example.
+ *
+ * Besices the log consumer interface, this class also implements the report
+ * producer interface, meaning that it can directly be registered with a
+ * Report object in order to produce table-based statistics reports. This
+ * capability is also used when default logging is active.
+ */
+class StatisticsBuffer
+:	public Log::Consumer< SimRecord >
+,	public ReportProducer
+{
+public:
+
+	/// Deque type for storing property updates, i.e. pairs of SimTime and values
+	typedef std::deque< std::pair< base::SimTime, double > > UpdateDeque;
+
+	/// Structure that holds value updates and the accumulated data
+	struct UpdateStats
+	{
+		UpdateStats( base::Simulation& sim, const data::Label& accumLabel )
+		:	accumulate( sim, accumLabel ) {}
+		statistics::Accumulate accumulate;
+		UpdateDeque updates;
+	};
+
+	/// Map type to associate parameter names and values
+	typedef std::map< StringLiteral, DynamicVar > ParamMap;
+	/// Map type to associate counted properties with counter values
+	typedef std::map< StringLiteral, std::size_t > CountMap;
+	/// Map type to associate updated properties with their statistical data
+	typedef std::map< StringLiteral, UpdateStats > UpdateMap;
+
+	/**
+	 * @brief Stores all statistical data of one statistics producer
+	 *
+	 * A @c Producer logs parameters, counters, and property updates,
+	 * all of which can be stored by an object of this class. A
+	 * @c ProducerStats object will be created for each statistics-producing
+	 * object in a simulation.
+	 */
+	struct ProducerStats
+	{
+		base::SimTime resetTime; ///< last reset time
+		data::TypeInfo senderType; ///< sender type
+		ParamMap paramStats; ///< parameters
+		CountMap countStats; ///< counters
+		UpdateMap updateStats; ///< updates
+	};
+
+	/// Pointer type to manage @c ProducerStats
+	typedef std::shared_ptr< ProducerStats > ProducerStatsPtr;
+
+	/// Buffer type for statistical data of many statistics producers
+	typedef std::map< Label, ProducerStatsPtr > StatisticsMap;
+
+	/// Creation via static method to enforce shared_ptr use
+	static std::shared_ptr< StatisticsBuffer > create(
+			base::Simulation& sim, const Label& label, bool bufferUpdates = false );
+
+	/// Destruction
+	virtual ~StatisticsBuffer();
+
+	/// Check if the buffer contains any data
+	bool isEmpty() const;
+
+	/// Get read access to the internal statistics storage
+	const StatisticsMap& getStatistics() const;
+
+	/// Check whether update values are stored in a buffer
+	bool isBufferingUpdates() const;
+
+	/// Get read access to the stored values of a producer's statistics property
+	const UpdateDeque& getUpdates( const Label& producer,
+			const StringLiteral& property ) const;
+
+	/// Reset accumulated data (counters, updates) of all statistics producers
+	void reset( base::SimTime resetTime );
+
+private:
+	/// Stores all statistics computed from simulation components
+	StatisticsMap statistics_;
+	/// Determines whether update values are buffered or not
+	bool bufferUpdates_;
+
+private:
+	/// Construction private, use create instead
+	StatisticsBuffer( base::Simulation& sim, const Label& label, bool bufferUpdates );
+
+	/// Implementation of ReportProducer interface
+	virtual void report( data::Report& report );
+
+	/// Implementation of log consumer interface, ignores all channels except @c statistics
+	virtual void consume( const Log::ChannelId channelId, const SimRecord& record );
+
+	/// Check for existing ProducerStats or create and add a new stats object
+	ProducerStatsPtr getObjectStats( const data::Producer& sender );
+
+	/// Non-copyable
+	StatisticsBuffer( const StatisticsBuffer& );
+	/// Non-assignable
+	StatisticsBuffer& operator=( const StatisticsBuffer& );
+};
+
+/// Smart pointer type to manage StatisticsBuffer objects
+typedef std::shared_ptr< StatisticsBuffer > StatisticsBufferPtr;
+
+} } } // namespace odemx::data::buffer
+
+#endif /* ODEMX_DATA_BUFFER_STATISTICSBUFFER_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/output/DefaultLoggingType.h b/odemx-lite/include/odemx/data/output/DefaultLoggingType.h
new file mode 100644
index 0000000000000000000000000000000000000000..aa6d44e540686013b9f1dde13d8f0377584086f0
--- /dev/null
+++ b/odemx-lite/include/odemx/data/output/DefaultLoggingType.h
@@ -0,0 +1,55 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file DefaultLoggingType.h
+ * @author Ronald Kluth
+ * @date created at 2010/04/12
+ * @brief Declaration of enum odemx::data::output::Type
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DATA_OUTPUT_DEFAULTLOGGINGTYPE_INCLUDED
+#define ODEMX_DATA_OUTPUT_DEFAULTLOGGINGTYPE_INCLUDED
+
+namespace odemx {
+namespace data {
+namespace output {
+
+/**
+ * @brief Determines which output location should be used for default logging
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::data::LoggingManager
+ *
+ * ODEMx supports default logging output. This functionality can be activated
+ * by calling @c enableDefaultLogging on the Simulation object, which is a
+ * subclass of the LoggingManager. One required paramerter is the output type,
+ * i.e. one of the values of this enumeration.
+ */
+enum Type
+{
+	DATABASE = 100000,///< Enable database output, needs connection string
+	STDOUT,           ///< Enable console output
+	XML               ///< Enable XML file output, requires filename prefix
+};
+
+} } } // namespace odemx::data::output
+
+#endif /* ODEMX_DATA_OUTPUT_DEFAULTLOGGINGTYPE_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/output/DefaultTimeFormat.h b/odemx-lite/include/odemx/data/output/DefaultTimeFormat.h
new file mode 100644
index 0000000000000000000000000000000000000000..07f0c374f111b0edd35a164bac78fd5f9d3f798c
--- /dev/null
+++ b/odemx-lite/include/odemx/data/output/DefaultTimeFormat.h
@@ -0,0 +1,73 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file DefaultTimeFormat.h
+ * @author Ronald Kluth
+ * @date created at 2009/04/03
+ * @brief Declaration of class odemx::data::output::DefaultTimeFormat
+ * @since 2.1
+ */
+
+#ifndef ODEMX_DATA_OUTPUT_DEFAULTTIMEFORMAT_INCLUDED
+#define ODEMX_DATA_OUTPUT_DEFAULTTIMEFORMAT_INCLUDED
+
+#include <odemx/data/output/TimeFormat.h>
+#include <odemx/util/StringConversion.h>
+
+namespace odemx {
+namespace data {
+namespace output {
+
+/**
+ * @brief Simple default implementation of a TimeFormat
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 2.1
+ * @see odemx::data::output::TimeFormat odemx::data::output::GermanTime odemx::data::output::Iso8601Time
+ *
+ * The default time formatter is provided for log consumers that convert
+ * their SimTime values to strings. It can be used like any other TimeFormat,
+ * thus making them exchangeable for log consumers. All ODEMx log consumers
+ * have the capability to format SimTime.
+ */
+class DefaultTimeFormat
+:	public TimeFormat
+{
+public:
+	/// Redefines computation function to avoid overhead, simply stores @c t in a member
+	virtual void computeTimeValues( base::SimTime t );
+	/// Converts normal SimTime number to string without computing time units
+	virtual const std::string makeString() const;
+};
+
+//-----------------------------------------------------------------------inlines
+
+inline void DefaultTimeFormat::computeTimeValues( base::SimTime t )
+{
+	simTime = t;
+}
+
+inline const std::string DefaultTimeFormat::makeString() const
+{
+	return toString( simTime );
+}
+
+} } } // namespace odemx::data::output
+
+#endif /* ODEMX_DATA_OUTPUT_DEFAULTTIMEFORMAT_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/output/ErrorWriter.h b/odemx-lite/include/odemx/data/output/ErrorWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..440619a712de1d94ff4086fe4537208d352c2f92
--- /dev/null
+++ b/odemx-lite/include/odemx/data/output/ErrorWriter.h
@@ -0,0 +1,122 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ErrorWriter.h
+ * @author Ronald Kluth
+ * @date created at 2009/09/30
+ * @brief Declaration of class odemx::data::output::ErrorWriter
+ * @sa ErrorWriter.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DATA_OUTPUT_ERRORWRITER_INCLUDED
+#define ODEMX_DATA_OUTPUT_ERRORWRITER_INCLUDED
+
+#include <odemx/data/SimRecord.h>
+#include <CppLog/Consumer.h>
+
+#ifdef _MSC_VER
+#include <memory>
+#else
+#include <memory>
+#endif
+
+//----------------------------------------------------------forward declarations
+
+namespace odemx {
+namespace data {
+namespace output {
+
+class TimeFormat;
+
+//-----------------------------------------------------------header declarations
+
+/**
+ * @brief A log consumer specifically intended for warnings, errors, and fatal errors
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::data::Producer
+ *
+ * This class outputs error messages in a similar way as previous ODEMx
+ * versions. However, with the use of class SimRecord as record type,
+ * much more detailed information can be given about the error condition.
+ *
+ * @note This consumer type is meant to be registered only with the
+ * channels warning, error, and fatal. Otherwise, an error message will
+ * be generated.
+ */
+class ErrorWriter
+:	public Log::Consumer< SimRecord >
+{
+public:
+	/**
+	 * @brief Creation by static method
+	 * @return A shared pointer that manages the consumer object.
+	 *
+	 * This method forces the use of reference-counting pointers to data
+	 * consumer objects in order to avoid manual memory management of these
+	 * resources. ODEMx log channels maintain a set of shared pointers to
+	 * their consumers, which guarantees that consumer objects stay alive while
+	 * they are registered with a channel.
+	 */
+	static std::shared_ptr< ErrorWriter > create();
+
+	/// Destruction
+	virtual ~ErrorWriter();
+
+	/**
+	 * @brief Implementation of the consumer interface, writes records to std::cerr
+	 * @param channelId ID of the forwarding log channel
+	 * @param record A log record describing the detected failure
+	 *
+	 * The output format contains the type of failure (i.e. the channel),
+	 * the message, the SimTime, the sender and its type. Details and class
+	 * scope are optional data.
+	 */
+	virtual void consume( const Log::ChannelId channelId, const SimRecord& record );
+
+	/**
+	 * @brief Set a new time formatter
+	 * @param timeFormat Pointer to a dynamically allocated time formatter
+	 * @see odemx::data::output::GermanTime odemx::data::output::Iso8601Time
+	 *
+	 * The default formatter simply outputs SimTime values, i.e. numbers.
+	 * With this method, the format can be changed. The function takes
+	 * ownership of the pointer and deletes it automatically when the writer is
+	 * destroyed or the format is changed.
+	 */
+	void setTimeFormat( TimeFormat* timeFormat );
+
+private:
+	/// Pointer to the time formatter, if set
+	std::unique_ptr< TimeFormat > format_;
+
+private:
+	/// Construction private, use create instead
+	ErrorWriter();
+	/// Non-copyable
+	ErrorWriter( const ErrorWriter& );
+	/// Non-assignable
+	ErrorWriter& operator=( const ErrorWriter& );
+};
+
+} } } // namespace odemx::data::output
+
+#endif /* ODEMX_DATA_OUTPUT_ERRORWRITER_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/output/GermanTime.h b/odemx-lite/include/odemx/data/output/GermanTime.h
new file mode 100644
index 0000000000000000000000000000000000000000..0ce48015325497dfb95e3881c31a87b5d9340d36
--- /dev/null
+++ b/odemx-lite/include/odemx/data/output/GermanTime.h
@@ -0,0 +1,86 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file GermanTime.h
+ * @author Ronald Kluth
+ * @date created at 2009/04/03
+ * @brief Declaration of class odemx::data::output::GermanTime
+ * @sa GermanTime.cpp
+ * @since 2.1
+ */
+
+#ifndef ODEMX_DATA_OUTPUT_GERMANTIME_INCLUDED
+#define ODEMX_DATA_OUTPUT_GERMANTIME_INCLUDED
+
+#include <odemx/data/output/TimeFormat.h>
+
+#include <string>
+
+//----------------------------------------------------------forward declarations
+
+namespace odemx {
+namespace data {
+namespace output {
+
+struct TimeBase;
+
+//-----------------------------------------------------------header declarations
+
+/**
+ * @brief Implementation of the German time format
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 2.1
+ * @see odemx::data::output::TimeFormat odemx::data::output::Iso8601Time
+ *
+ * This time formatter converts SimTime to the German time format
+ * <tt>YYYY-MM-DD / hh:mm:ss.f</tt>. It uses the predefined computation
+ * function from TimeFormat and merely provides a string conversion
+ * for the computed values.
+ *
+ * The default precision for the generated strings is seconds.
+ * The millisecond part will only be displayed if the given TimeBase
+ * uses the TimeUnit milliseconds.
+ */
+class GermanTime
+:	public TimeFormat
+{
+public:
+	/// Default construction
+	GermanTime();
+	/// Construction with given time base (SimTime 0 represents this time)
+	GermanTime( const TimeBase& base );
+
+protected:
+	// uses predefined computation function from Format()
+
+	/**
+	 * @brief Transforms the computed values to the output format
+	 * @return A formatted time string
+	 *
+	 * This method is called by TimeFormat::timeToString() after the
+	 * values for date and day time have been computed. It merely
+	 * transforms that data into an std::string.
+	 */
+	virtual const std::string makeString() const;
+};
+
+} } } // namespace odemx::data::output
+
+#endif /* ODEMX_DATA_OUTPUT_GERMANTIME_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/output/Iso8601Time.h b/odemx-lite/include/odemx/data/output/Iso8601Time.h
new file mode 100644
index 0000000000000000000000000000000000000000..534e334a521087a6b097350533861461ddb24007
--- /dev/null
+++ b/odemx-lite/include/odemx/data/output/Iso8601Time.h
@@ -0,0 +1,107 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Iso8601Time.h
+ * @author Ronald Kluth
+ * @date created at 2009/04/03
+ * @brief Declaration of class odemx::data::output::Iso8601Time
+ * @sa Iso8601Time.cpp
+ * @since 2.1
+ */
+
+#ifndef ODEMX_DATA_OUTPUT_ISO8601TIME_INCLUDED
+#define ODEMX_DATA_OUTPUT_ISO8601TIME_INCLUDED
+
+#include <odemx/data/output/TimeFormat.h>
+
+//----------------------------------------------------------forward declarations
+
+namespace odemx {
+namespace data {
+namespace output {
+
+struct TimeBase;
+
+//-----------------------------------------------------------header declarations
+
+/**
+ * @brief Implementation of the ISO-8601 time format
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 2.1
+ * @see odemx::data::output::TimeFormat odemx::data::output::Iso8601Time
+ *
+ * This time formatter converts SimTime to the ISO 8601 time format
+ * <tt>YYYY-MM-DDThh:mm:ss.f&plusmn;HH:mm</tt>. It uses the predefined
+ * computation function from TimeFormat and merely provides a string
+ * conversion for the computed values.
+ *
+ * This implementation features a subset, as proposed by the W3C, of the
+ * whole ISO-8601 standard for outputting international dates and time.
+ * It enables output of different time precisions ranging from minutes over
+ * seconds up to milliseconds.
+ *
+ * The default precision for the generated strings is seconds.
+ * The millisecond part will only be displayed if the given TimeBase
+ * uses the unit milliseconds.
+ */
+class Iso8601Time
+:	public TimeFormat
+{
+public:
+	/// Structure that describes the Offset ofa time zone from UTC time
+	struct UtcOffset
+	{
+		/// Construction
+		UtcOffset( short h, unsigned short m );
+
+		short hour; ///< time zone hour offset from UTC
+		unsigned short minute; ///< time zone minute offset from UTC
+	};
+
+	/**
+	 * @brief Construction with TieBase
+	 * @param base The point in time that represents SimTime 0
+	 * @param utcOffsetHour UTC offset hour part
+	 * @param utcOffsetMin UTC offset minute part
+	 *
+	 * The UTC offset is limited to narrow ranges of values.
+	 * The hour part ranges from -12 though 14, and the minute part may
+	 * only contain the values 0, 15, 30, or 45.
+	 */
+	explicit Iso8601Time( const TimeBase& base, short utcOffsetHour = 0,
+			unsigned short utcOffsetMin = 0 );
+
+	// uses predefined computation function from Format()
+
+	/// defines the output format of the time string
+	virtual const std::string makeString() const;
+
+	/// Change to UTC time offset
+	void setUtcOffset( short hour, short minute );
+	/// Get the offset from UTC time
+	const UtcOffset& getUtcOffset() const;
+
+private:
+	UtcOffset utcOffset_; ///< time zone to be added
+};
+
+} } } // namespace odemx::data::output
+
+#endif /* ODEMX_DATA_OUTPUT_ISO8601TIME_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/output/OStreamReport.h b/odemx-lite/include/odemx/data/output/OStreamReport.h
new file mode 100644
index 0000000000000000000000000000000000000000..119c021fbc654dd4d4460820f86be2d967c0bc55
--- /dev/null
+++ b/odemx-lite/include/odemx/data/output/OStreamReport.h
@@ -0,0 +1,78 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file OStreamReport.h
+ * @author Ronald Kluth
+ * @date created at 2009/02/28
+ * @brief Declaration of class odemx::data::output::OStreamReport
+ * @sa OStreamReport.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DATA_OUTPUT_OSTREAMREPORT_INCLUDED
+#define ODEMX_DATA_OUTPUT_OSTREAMREPORT_INCLUDED
+
+#include <odemx/data/Report.h>
+#include <ostream>
+
+namespace odemx {
+namespace data {
+namespace output {
+
+/**
+ * @brief Simple Report implementation that prints statistics tables to a stream
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::data::Report odemx::data::ReportProducer odemx::data::output::XmlReport
+ *
+ * ODEMx can collect statistical data in accumulated form. This is either
+ * done by statistics computing components provided by module statistics,
+ * or with the help of the log consumer odemx::data::buffer::StatisticsBuffer
+ * that collects data from channel statistics.
+ *
+ * This class is mainly used to print accumulated statistical data to the
+ * console by providing std::cout as target stream. However, it is also
+ * possible to use file streams or other subclasses of std::ostream.
+ */
+class OStreamReport
+:	public Report
+{
+public:
+	/// Construction with @c ostream
+	OStreamReport( std::ostream& os );
+	/// Destruction
+	virtual ~OStreamReport();
+
+protected:
+	/// Redefined to output a headline before showing the tables
+	virtual void startProcessing();
+	/// Prints formatted tables from ReportProducers to the stream
+	virtual void processTables();
+	/// Does nothing
+	virtual void endProcessing();
+
+private:
+	/// Reference to the @c ostream the report will be written to
+	std::ostream& os_;
+};
+
+} } } // namespace odemx::data::output
+
+#endif /* ODEMX_DATA_OUTPUT_OSTREAMREPORT_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/output/OStreamWriter.h b/odemx-lite/include/odemx/data/output/OStreamWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..5aaff13f33ab49bb8f2bc825550598b2f3f8d988
--- /dev/null
+++ b/odemx-lite/include/odemx/data/output/OStreamWriter.h
@@ -0,0 +1,124 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file data/output/OStreamWriter.h
+ * @author Ronald Kluth
+ * @date created at 2009/02/09
+ * @brief Declaration of class odemx::data::output::OStreamWriter
+ * @sa OStreamWriter.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_DATA_OUTPUT_OSTREAMWRITER_INCLUDED
+#define ODEMX_DATA_OUTPUT_OSTREAMWRITER_INCLUDED
+
+#include <odemx/data/SimRecord.h>
+#include <CppLog/Consumer.h>
+
+#include <ostream>
+#ifdef _MSC_VER
+#include <memory>
+#else
+#include <memory>
+#endif
+
+//----------------------------------------------------------forward declarations
+
+namespace odemx {
+namespace data {
+namespace output {
+
+class TimeFormat;
+
+//-----------------------------------------------------------header declarations
+
+/**
+ * @brief A simple log consumer implementation for writing plain text
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::data::Producer
+ *
+ * This data consumer accepts a reference to any \c std::ostream object and
+ * immediately writes records to it when \c consume() is called. The time
+ * format of the record output is changeable.
+ */
+class OStreamWriter
+:	public Log::Consumer< SimRecord >
+{
+public:
+	/**
+	 * @brief Creation by static method
+	 * @param os The \c std::ostream to which output will be written
+	 * @return A shared_ptr-managed OStreamWriter object
+	 *
+	 * This method enforces the use of reference-counting pointers to data
+	 * consumer objects in order to avoid manual memory management of these
+	 * resources. ODEMx log channels maintain a set of shared pointers to
+	 * their consumers, which guarantees that consumer objects stay alive while
+	 * they are registered with a channel.
+	 */
+	static std::shared_ptr< OStreamWriter > create( std::ostream& os );
+
+	/// Destruction
+	virtual ~OStreamWriter();
+
+	/**
+	 * @brief Implementation of the consumer interface, writes records to a stream
+	 * @param channelId ID of the forwarding log channel
+	 * @param record A log record describing the current simulation event
+	 *
+	 * Each record is printed on a single line. The output format contains
+	 * the formatted simulation time, the channel name, the producer label,
+	 * and the message text. Additionally, details and scope may be printed,
+	 * if the record contains any.
+	 */
+	virtual void consume( const Log::ChannelId channelId, const SimRecord& record );
+
+	/**
+	 * @brief Set a new time formatter
+	 * @param timeFormat Pointer to a dynamically allocated time formatter
+	 * @see odemx::data::output::GermanTime odemx::data::output::Iso8601Time
+	 *
+	 * The default formatter simply outputs SimTime values. The function takes
+	 * ownership of the pointer and deletes it automatically when the writer is
+	 * destroyed or the format is changed.
+	 */
+	void setTimeFormat( TimeFormat* timeFormat );
+
+private:
+	/// Internal reference to the consuming ostream object.
+	std::ostream& os_;
+	/// Pointer to the time formatter, if set
+	std::unique_ptr< TimeFormat > format_;
+
+	/// Construction only via create()
+	OStreamWriter( std::ostream& os );
+	/// Non-copyable
+	OStreamWriter( const OStreamWriter& );
+	/// Non-assignable
+	OStreamWriter& operator=( const OStreamWriter& );
+};
+
+/// Smart pointer type to manage OStreamWriter objects
+typedef std::shared_ptr< OStreamWriter > OStreamWriterPtr;
+
+} } } // namespace odemx::data::output
+
+#endif /* ODEMX_DATA_OUTPUT_OSTREAMWRITER_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/output/TimeBase.h b/odemx-lite/include/odemx/data/output/TimeBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..6dff1cc0577de0e6463817f4a6e14c5931732ae0
--- /dev/null
+++ b/odemx-lite/include/odemx/data/output/TimeBase.h
@@ -0,0 +1,85 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file TimeBase.h
+ * @author Ronald Kluth
+ * @date created at 2009/04/03
+ * @brief Declaration of class odemx::data::output::TimeBase
+ * @sa TimeBase.cpp
+ * @since 2.1
+ */
+
+#ifndef ODEMX_DATA_OUTPUT_TIMEBASE_INCLUDED
+#define ODEMX_DATA_OUTPUT_TIMEBASE_INCLUDED
+
+#include <odemx/data/output/TimeUnit.h>
+
+namespace odemx {
+namespace data {
+namespace output {
+
+/**
+ * @brief Describes the time base in day, month, year, day time offset and unit
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 2.1
+ * @see odemx::data::output::GermanTime odemx::data::output::Iso8601Time
+ *
+ * SimTime is an abstraction from real time. It always starts at 0, and the
+ * user interprets which time units are used. In order to output formatted
+ * SimTime values, two pieces of information are required: the starting point
+ * in time, and the unit to be used. This class provides both.
+ */
+struct TimeBase
+{
+	/**
+	 * @brief Construction, initializes all members at once
+	 * @param year The year of the start date
+	 * @param month The month of the start date
+	 * @param day The day of the start date
+	 * @param dayTimeOffset The daytime offset on the start date in units
+	 * @param unit The unit to be used when converting SimTime
+	 *
+	 *
+	 */
+	TimeBase( unsigned short year, unsigned short month, unsigned short day,
+			base::SimTime dayTimeOffset, TimeUnit::Type unit );
+
+	unsigned short year; ///< time base year
+	unsigned short month; ///< time base month
+	unsigned short day; ///< time base day
+	base::SimTime offset; ///< time offset on the given day, must respect unit
+	TimeUnit::Type unit; ///< time base unit
+};
+
+//-----------------------------------------------------------------------inlines
+
+inline TimeBase::TimeBase( unsigned short year, unsigned short month,
+		unsigned short day,	base::SimTime dayTimeOffset, TimeUnit::Type unit )
+:	year( year )
+,	month( month )
+,	day( day )
+,	offset( dayTimeOffset )
+,	unit( unit )
+{
+}
+
+} } } // namespace odemx::data::output
+
+#endif /* ODEMX_DATA_OUTPUT_TIMEBASE_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/output/TimeFormat.h b/odemx-lite/include/odemx/data/output/TimeFormat.h
new file mode 100644
index 0000000000000000000000000000000000000000..490b39f7dd9218c19b8b1168c7b186e0ae481ce7
--- /dev/null
+++ b/odemx-lite/include/odemx/data/output/TimeFormat.h
@@ -0,0 +1,126 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file TimeFormat.h
+ * @author Ronald Kluth
+ * @date created at 2008/03/14
+ * @brief Declaration of odemx::data::output::TimeFormat
+ * @sa TimeFormat.cpp
+ * @since 2.1
+ */
+
+#ifndef ODEMX_DATA_OUTPUT_TIMEFORMAT_INCLUDED
+#define ODEMX_DATA_OUTPUT_TIMEFORMAT_INCLUDED
+
+#include <odemx/base/SimTime.h>
+#include <odemx/data/output/TimeBase.h>
+#include <odemx/data/output/TimeUnit.h>
+
+#include <string>
+
+namespace odemx {
+namespace data {
+namespace output {
+
+/**
+ * @brief Abstract base class for formatted simulation time output
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 2.1
+ * @see odemx::data::output::GermanTime odemx::data::output::Iso8601Time
+ *
+ * This abstract base class provides an implementation for time computations.
+ * In order to transform an abstract SimTime value into a concrete time
+ * value, a starting point and a time unit are required. Both are provided
+ * in the form of a TimeBase object.
+ *
+ * This class computes year, month, day, hour minutes, and seconds from SimTime
+ * values and stores them in protected members so that they can be used by
+ * subclasses to produce a formatted time string. The interface for converting
+ * SimTime to string is provided by the member function @c timeToString.
+ */
+class TimeFormat
+{
+public:
+	/// Default construction for uninitialized TimeFormat objects
+	TimeFormat();
+	/// Construction with a given time base and unit
+	TimeFormat( const TimeBase& timeBase );
+	/// Destruction
+	virtual ~TimeFormat();
+
+	/// Set the time base (date, time of day, unit) for the time computation
+	void setTimeBase( unsigned short year, unsigned short month,
+			unsigned short day, base::SimTime dayTimeOffset, TimeUnit::Type unit );
+	/// Set the time base by providing a TimeBase object
+	void setTimeBase( const TimeBase& timeBase );
+	/// Get a reference to the format's time base
+	const TimeBase& getTimeBase() const;
+
+	/**
+	 * @brief Transforms SimTime into a formatted string for logging output
+	 * @param time The SimTime value to be transformed
+	 * @return A string representation of the given SimTime value
+	 *
+	 *  This function can be used by all output components to transform
+	 *  SimTime values into actual dates and points in time. To achieve this,
+	 *  the function uses the virtual function @c computeTimeValues to
+	 *  determine the date and time according to the time base and unit.
+	 *
+	 * 	Finally, this function calls the pure virtual function makeString(),
+	 *  which must be defined by all subclasses in order to produce the
+	 *  formatted string from the internal numeric time representation.
+	 */
+	const std::string timeToString( base::SimTime time );
+
+protected:
+
+	/// Computes a real date and clock time from SimTime, stores values in member data
+	virtual void computeTimeValues( base::SimTime time );
+
+	/**
+	 * @brief Assembles the previously computed values as formatted time string
+	 *
+	 * All subclasses must provide an implementation of this function so that
+	 * @c timeToString can be called for the time transformation.
+	 */
+	virtual const std::string makeString() const = 0;
+
+	/// The starting point of the simulation time, represents SimTime 0
+	TimeBase base;
+
+	// values to be set by computeTimeValues()
+	base::SimTime simTime; ///< The SimTime to be converted considering base
+	unsigned short year; ///< Computed year
+	unsigned short month; ///< Computed month
+	unsigned short day; ///< Computed day
+	unsigned short hour; ///< Computed hour
+	unsigned short min; ///< Computed minutes
+	double sec; ///< Computed seconds and milliseconds
+
+	/// Heper function to get the days of a month, with regard to the year
+	static unsigned short daysOfMonth( unsigned short month, unsigned short year );
+private:
+	/// Reset member data, used for initialization and reset
+	void resetTimeValues();
+};
+
+} } } // namespace odemx::data::output
+
+#endif /* ODEMX_DATA_OUTPUT_TIMEFORMAT_INCLUDED */
diff --git a/odemx-lite/include/odemx/data/output/TimeUnit.h b/odemx-lite/include/odemx/data/output/TimeUnit.h
new file mode 100644
index 0000000000000000000000000000000000000000..c0da935e0c80f15d38f3b1e0f609e12856139a76
--- /dev/null
+++ b/odemx-lite/include/odemx/data/output/TimeUnit.h
@@ -0,0 +1,59 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file TimeUnit.h
+ * @author Ronald Kluth
+ * @date created at 2008/03/14
+ * @brief Declaration of odemx::data::output::TimeUnit
+ * @sa TimeUnit.cpp
+ * @since 2.1
+ */
+
+#ifndef ODEMX_DATA_OUTPUT_TIMEUNIT_INCLUDED
+#define ODEMX_DATA_OUTPUT_TIMEUNIT_INCLUDED
+
+namespace odemx {
+namespace data {
+namespace output {
+
+/**
+ * @brief SimTime always represents one of these time units
+ * @ingroup data
+ * @author Ronald Kluth
+ * @since 2.1
+ * @see odemx::data::output::TimeBase odemx::data::output::TimeFormat
+ *
+ * The computation of real dates from SimTime requires a starting point,
+ * and a time unit. The latter are represented by values of this enumeration.
+ */
+struct TimeUnit
+{
+	enum Type
+	{
+		none,
+		milliseconds,
+		seconds,
+		minutes,
+		hours
+	};
+};
+
+} } } // namspace odemx::data::output
+
+#endif /* ODEMX_DATA_OUTPUT_TIMEUNIT_INCLUDED */
diff --git a/odemx-lite/include/odemx/odemx.h b/odemx-lite/include/odemx/odemx.h
new file mode 100644
index 0000000000000000000000000000000000000000..a887bff8f72b658f8257d20a5a51cc2e4952ddd2
--- /dev/null
+++ b/odemx-lite/include/odemx/odemx.h
@@ -0,0 +1,155 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file odemx.h
+ * @author Ralf Gerstenberger
+ * @date created at 2002/08/05
+ * @brief Includes all ODEMx header files
+ * @since 1.0
+ */
+
+#ifndef ODEMX_ODEMX_INCLUDED
+#define ODEMX_ODEMX_INCLUDED
+
+// base package
+#include <odemx/base/Comparators.h>
+#include <odemx/base/Continuous.h>
+#include <odemx/base/DefaultSimulation.h>
+#include <odemx/base/Event.h>
+#include <odemx/base/ExecutionList.h>
+#include <odemx/base/Process.h>
+#include <odemx/base/Sched.h>
+#include <odemx/base/Scheduler.h>
+#include <odemx/base/SimTime.h>
+#include <odemx/base/Simulation.h>
+#include <odemx/base/TypeDefs.h>
+
+// control package
+#include <odemx/base/control/ControlBase.h>
+#include <odemx/base/control/Control.h>
+
+// continuous package
+// removed in odemx-lite
+
+// cellular automaton package
+#include <odemx/base/cellular_automaton/CellMonitor.h>
+#include <odemx/base/cellular_automaton/Cell.h>
+#include <odemx/base/cellular_automaton/CellVariablesContainer.h>
+
+// coroutine package
+#include <odemx/coroutine/Coroutine.h>
+#include <odemx/coroutine/CoroutineContext.h>
+#include <odemx/coroutine/System.h>
+
+// data package
+#include <odemx/data/LoggingManager.h>
+#include <odemx/data/Label.h>
+#include <odemx/data/ManagedChannels.h>
+#include <odemx/data/Observable.h>
+#include <odemx/data/Producer.h>
+#include <odemx/data/SimRecord.h>
+#include <odemx/data/SimRecordFilter.h>
+#include <odemx/data/TableKey.h>
+#include <odemx/data/TypeInfo.h>
+
+// buffer sub-package
+#include <odemx/data/buffer/SimRecordBuffer.h>
+#include <odemx/data/buffer/StatisticsBuffer.h>
+
+// output sub-package
+// removed in odemx-lite
+// #include <odemx/data/output/DatabaseWriter.h>
+#include <odemx/data/output/DefaultLoggingType.h>
+#include <odemx/data/output/DefaultTimeFormat.h>
+#include <odemx/data/output/ErrorWriter.h>
+#include <odemx/data/output/GermanTime.h>
+#include <odemx/data/output/Iso8601Time.h>
+#include <odemx/data/output/OStreamReport.h>
+#include <odemx/data/output/OStreamWriter.h>
+#include <odemx/data/output/TimeBase.h>
+#include <odemx/data/output/TimeFormat.h>
+#include <odemx/data/output/TimeUnit.h>
+// removed in odemx-lite
+// #include <odemx/data/output/XmlReport.h>
+// #include <odemx/data/output/XmlWriter.h>
+
+// protocol package
+#include <odemx/protocol/Device.h>
+#include <odemx/protocol/Entity.h>
+#include <odemx/protocol/ErrorModel.h>
+#include <odemx/protocol/Layer.h>
+#include <odemx/protocol/Medium.h>
+#include <odemx/protocol/Pdu.h>
+#include <odemx/protocol/Sap.h>
+#include <odemx/protocol/Service.h>
+#include <odemx/protocol/ServiceProvider.h>
+#include <odemx/protocol/Stack.h>
+
+// random package
+#include <odemx/random/ContinuousConst.h>
+#include <odemx/random/ContinuousDist.h>
+#include <odemx/random/DiscreteConst.h>
+#include <odemx/random/DiscreteDist.h>
+#include <odemx/random/Dist.h>
+#include <odemx/random/DistContext.h>
+#include <odemx/random/Draw.h>
+#include <odemx/random/Erlang.h>
+#include <odemx/random/NegativeExponential.h>
+#include <odemx/random/Normal.h>
+#include <odemx/random/Poisson.h>
+#include <odemx/random/RandomInt.h>
+#include <odemx/random/Uniform.h>
+
+// statistics package
+#include <odemx/statistics/Accumulate.h>
+#include <odemx/statistics/Count.h>
+#include <odemx/statistics/Histogram.h>
+#include <odemx/statistics/Regression.h>
+#include <odemx/statistics/Sum.h>
+#include <odemx/statistics/Tab.h>
+#include <odemx/statistics/Tally.h>
+
+// synchronization package
+#include <odemx/synchronization/Bin.h>
+#include <odemx/synchronization/BinT.h>
+#include <odemx/synchronization/CondQ.h>
+#include <odemx/synchronization/IMemory.h>
+#include <odemx/synchronization/Memory.h>
+#include <odemx/synchronization/Port.h>
+#include <odemx/synchronization/ProcessQueue.h>
+#include <odemx/synchronization/Queue.h>
+#include <odemx/synchronization/Res.h>
+#include <odemx/synchronization/ResT.h>
+#include <odemx/synchronization/Timer.h>
+#include <odemx/synchronization/Wait.h>
+#include <odemx/synchronization/WaitQ.h>
+
+// util package
+#include <odemx/util/DeletePtr.h>
+#include <odemx/util/Exceptions.h>
+#include <odemx/util/ListInSort.h>
+#include <odemx/util/StringConversion.h>
+#include <odemx/util/TypeNames.h>
+#include <odemx/util/TypeToString.h>
+#include <odemx/util/Version.h>
+
+// simml package
+// removed in odemx-lite
+
+#endif
diff --git a/odemx-lite/include/odemx/protocol/Device.h b/odemx-lite/include/odemx/protocol/Device.h
new file mode 100644
index 0000000000000000000000000000000000000000..b335485102a42291968e0f184ef22d210a297411
--- /dev/null
+++ b/odemx-lite/include/odemx/protocol/Device.h
@@ -0,0 +1,281 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Device.h
+ * @author Ronald Kluth
+ * @date created at 2009/10/31
+ * @brief Declaration of class odemx::protocol::Device
+ * @sa Device.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_PROTOCOL_DEVICE_INCLUDED
+#define ODEMX_PROTOCOL_DEVICE_INCLUDED
+
+#include <odemx/protocol/ServiceProvider.h>
+#include <odemx/synchronization/Memory.h>
+
+//----------------------------------------------------------forward declarations
+
+namespace odemx {
+namespace protocol {
+
+class Medium;
+
+//-----------------------------------------------------------header declarations
+
+/**
+ * @brief Base class for modeling network interfaces
+ * @ingroup protocol
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::protocol::Medium odemx::protocol::Stack
+ *
+ * A Device object models a network interface in ODEMx protocol stacks. As such
+ * it is a means by which nodes in a network can communicated with each other.
+ * Using a device always requires the use of a transmission medium because
+ * that is needed to transport data from one node to another. Hence, this class
+ * and the class Medium are closely tied.
+ *
+ * In order to build a network topology, all devices that are connected
+ * to a specific medium must explicitly be registered with it by their address.
+ * Links between nodes are formed as links between devices. For this purpose,
+ * their addresses are used. Transmissions from device always pass through the
+ * medium. Whenever a device sends data, the medium schedules transmission
+ * events to notify the neighbors of a node about the start, and the end of each
+ * transmission.
+ *
+ * Using two events for transmissions allows to integrate a collision detection
+ * mechanism. Collisions occur when two connected devices start sending at
+ * roughly the same so that they have not yet received the start events of their
+ * neighbor.
+ */
+class Device
+:	public ServiceProvider
+{
+private:
+	/// Memory type that allows the stopping of a transmission when a collision occurs
+	typedef synchronization::Memory CollisionDetection;
+
+public:
+	/// Address type to be used by device ojects
+	typedef std::string AddressType;
+	
+	/**
+	 * @brief Construction
+	 * @param sim The simulation context
+	 * @param label The label of the object
+	 *
+	 * The constructor initializes an internal SAP that is needed for
+	 * receiving data from the medium. Since devices are service providers,
+	 * they also just listen for input and wait. They must therefore be
+	 * awakened by an internal SAP when data is transmitted via
+	 * the medium
+	 */
+	Device( base::Simulation& sim, const data::Label& label );
+
+	/// Destruction
+	virtual ~Device();
+
+	/**
+	 * @brief Set the address of a device
+	 *
+	 * Normally, there is no need to use this method manually. Upon registration
+	 * with a Medium, the device will automatically receive the address provided
+	 * in the call to @c registerDevice.
+	 */
+	void setAddress( const AddressType& addr );
+
+	/// Read the device address. It may not have been set yet.
+	const AddressType& getAddress() const;
+
+	/// Set the medium that connects the device to its peers
+	void setMedium( Medium& medium );
+
+	/// Reset the internal medium pointer
+	void resetMedium();
+
+	/// Check if the medium is set
+	bool hasMedium() const;
+
+	/**
+	 * @brief Increase the number of active transmissions at the device
+	 * @see decTransmissionCount, busy
+	 *
+	 * This function is called when the device itself begins to transmit, or
+	 * when it is notified by one of its neighbors about a transmission start.
+	 * Keeping track of the active transmissions is important for implementing
+	 * the collision detection mechanism. A collision occurrs when a device's
+	 * active transmission count is greater than one. Depending on the
+	 * implementation of @c hasCollisionDetection, the device may abort
+	 * its own transmission, or it must wait until all of its data is sent.
+	 * The latter functionality is implemented with a duration timer.
+	 */
+	void incTransmissionCount();
+
+	/**
+	 * @brief Decrease the number of active transmissions
+	 * @see incTransmissionCount, busy
+	 *
+	 * Whenever the device or its neighbors finish a transmission, this
+	 * function is called to decrease the transmission counter.
+	 */
+	void decTransmissionCount();
+
+	/// Check the number of active transmissions at the device
+	unsigned int getTransmissionCount() const;
+
+protected:
+
+	/**
+	 * @name Input handling, to be defined by subclasses
+	 * @{
+	 */
+	/**
+	 * @brief Implements the device functionality for sending data
+	 * @param sapName The SAP used to input the data
+	 * @param p The data unit to be transmitted via medium
+	 *
+	 * Whenever data is provided by an SAP other than the internal receive
+	 * SAP, this pure virtual method is called with the name of the SAP
+	 * and the PDU to send. Every device must implement this method in
+	 * order to specify how an what data is to be transmitted via the medium.
+	 * Usually, this method calls @c send.
+	 */
+	virtual void handleSend( const std::string& sapName, PduPtr p ) = 0;
+	/**
+	 * @brief Implement the device functionality for message reception
+	 * @param p The data unit received from the medium
+	 *
+	 * This method gets called whenever data arrives from the medium through
+	 * the internal receive SAP. The device must implement this method to
+	 * define if and how data is to be passed to the upper layer or not.
+	 * Usually, this method calls @c pass.
+	 */
+	virtual void handleReceive( PduPtr p ) = 0;
+	//@}
+
+	/**
+	 * @brief Transmit data via the associated medium
+	 * @param p The protocol data unit to be transmitted
+	 * @see computeTransmissionDuration
+	 *
+	 * Sending data is a complex operation since it involves the interaction
+	 * with the transmission medium. First, the medium is checked if it's busy.
+	 * In that case, the method returns @c false immediately.
+	 *
+	 * Otherwise, a transmission is started by increasing the counter and
+	 * calling @c signalTransmissionStart on the Medium object. This schedules
+	 * TransmissionStart events for all neighbors. Afterwards, the transmission
+	 * duration is calculated dependant on the PDU size by calling
+	 * @c computeTransmissionDuration.
+	 *
+	 * Depending on whether @c hasCollisionDetection returns @c true or
+	 * @c false, an active transmission may be stopped upon collision
+	 * detection or not. In the case of a collision, an empty PDU will
+	 * be delivered to the receivers.
+	 *
+	 * As soon as the wait period ends, the end of the transmission is
+	 * made know to all neighbors by calling @c signalTransmissionEnd on the
+	 * Medium object. This schedules TransmissionEnd events, which decrease
+	 * the counter at the receiver and deliver the PDU.
+	 */
+	bool send( PduPtr p );
+
+	/**
+	 * @brief Pass a message from the medium to the upper layer
+	 * @param upperLayerSap The SAP to which to pass the data unit
+	 * @param p The data unit to pass on
+	 *
+	 * This method simply looks up the SAP in the upper layer and writes
+	 * the given data unit to it. A warning will be issued if the SAP
+	 * is not found.
+	 */
+	void pass( const std::string& upperLayerSap, PduPtr p );
+
+	/**
+	 * @brief Override of the service provider interface
+	 * @param sap The SAP by which the data unit was provided
+	 * @param p The protocol data unit to handle
+	 *
+	 * This function simply calls @c handleReceive if the PDU came from the
+	 * internal SAP. Otherwise, @c handleReceive is called.
+	 */
+	virtual void handleInput( const std::string& sap, PduPtr p );
+
+	/**
+	 * @brief Determine the time it takes to transmit a data unit via medium
+	 * @param pduSize The size of the given data unit
+	 * @return The time duration it will take to put the PDU on the medium
+	 *
+	 * This method is important for the waiting period between transmission
+	 * start and end. It computes the time it takes the device to put a
+	 * given data unit on the medium. Device subclasses must define this
+	 * method in order to provide a sensible implementation depending on
+	 * bandwidth and Ouality of service.
+	 */
+	virtual base::SimTime computeTransmissionDuration( std::size_t pduSize ) = 0;
+
+	/**
+	 * @brief Determines whether a device can detect collision
+	 * @return @c true if the device has collision detection capability, @c false otherwise
+	 *
+	 * Normally, a device has to send all of its data to the medium, not knowing
+	 * whether it actually arrives intact. However, some devices can abort their
+	 * transmission when  a collision is detected on the medium. This method's
+	 * implementation decides whether the device has this ability or not.
+	 */
+	virtual bool hasCollisionDetection();
+	
+public:
+	/**
+	 * @brief Put a data unit into the device's receive SAP
+	 *
+	 * This method should not be called manually. It is part of the interaction
+	 * between Medium and Device, and it is always called by TransmissionEnd
+	 * events to deliver a PDU from the medium.
+	 */
+	void receive( PduPtr p );
+
+private:
+	/// SAP that receives PDUs from the medium
+	Sap* receiveSap_;
+	/// Address of the device
+	AddressType address_;
+	/// Medium used by the device to transmit messages
+	Medium* medium_;
+	/// Counts the number of active transmissions on the device to detect collisions
+	unsigned int transmissionCount_;
+	/// Memory object that can awaken the device early from its transmission wait period
+	CollisionDetection collisionDetection_;
+	/// Stores whether a collision occurred during the last transmission
+	bool collisionOccurred_;
+	
+protected:
+	/// Check if the device finds the medium busy
+	bool busy() const;
+	/// Schedule events for all neighbors to notify them of a transmission start
+	void startTransmission();
+	/// Schedule events for all neighbors to notify them of a transmission end and deliver the PDU
+	void endTransmission( PduPtr p );
+};
+
+} } // namespace odemx::protocol
+
+#endif /* ODEMX_PROTOCOL_DEVICE_INCLUDED */
diff --git a/odemx-lite/include/odemx/protocol/Entity.h b/odemx-lite/include/odemx/protocol/Entity.h
new file mode 100644
index 0000000000000000000000000000000000000000..d4f793b8cfe5d2a6a8b91d5963b6fd6799a1b2aa
--- /dev/null
+++ b/odemx-lite/include/odemx/protocol/Entity.h
@@ -0,0 +1,84 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Entity.h
+ * @author Ronald Kluth
+ * @date created at 2009/10/13
+ * @brief Declaration of class odemx::protocol::Entity
+ * @sa Entity.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_PROTOCOL_ENTITY_INCLUDED
+#define ODEMX_PROTOCOL_ENTITY_INCLUDED
+
+#include <odemx/protocol/ServiceProvider.h>
+#include <odemx/protocol/Sap.h>
+
+namespace odemx {
+namespace protocol {
+
+/**
+ * @brief Base class for modeling all kinds of protocol entities
+ * @ingroup protocol
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::protocol::Device odemx::protocol::Service
+ *
+ * An Entity extends the service provider functionality by the methods
+ * @c send and @c pass, which are used for forwarding protocol data units
+ * between adjacent layers of the protocol stack.
+ */
+class Entity
+:	public ServiceProvider
+{
+public:
+
+	/// Construction
+	Entity( base::Simulation& sim, const data::Label& label );
+	/// Destruction
+	virtual ~Entity();
+
+	/**
+	 * @brief Forward a PDU to the lower layer via the given SAP
+	 * @param lowerLayerSap The target SAP in the lower layer
+	 * @param p The protocol data unit to be forwarded
+	 *
+	 * The function simply requests the given SAP from the lower layer
+	 * and writes the PDU to it.
+	 */
+	void send( const std::string& lowerLayerSap, PduPtr p );
+
+	/**
+	 * @brief Forward a PDU to the upper layer via the given SAP
+	 * @param upperLayerSap The target SAP in the upper layer
+	 * @param p The protocol data unit to be forwarded
+	 *
+	 * The function simply requests the given SAP from the upper layer
+	 * and writes the PDU to it.
+	 */
+	void pass( const std::string& upperLayerSap, PduPtr p );
+
+	/// Service provider interface, must be implemented in subclasses
+	virtual void handleInput( const std::string& sapName, PduPtr ) = 0;
+};
+
+} } // namespace odemx::protocol
+
+#endif /* ODEMX_PROTOCOL_ENTITY_INCLUDED */
diff --git a/odemx-lite/include/odemx/protocol/ErrorModel.h b/odemx-lite/include/odemx/protocol/ErrorModel.h
new file mode 100644
index 0000000000000000000000000000000000000000..be114c23be1d91ab49085cf84b2727f6fa534faf
--- /dev/null
+++ b/odemx-lite/include/odemx/protocol/ErrorModel.h
@@ -0,0 +1,70 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ErrorModel.h
+ * @author Ronald Kluth
+ * @date created at 2009/10/18
+ * @brief Declaration of interface odemx::protocol::ErrorModel
+ * @since 3.0
+ */
+
+#ifndef ODEMX_PROTOCOL_ERRORMODEL_INCLUDED
+#define ODEMX_PROTOCOL_ERRORMODEL_INCLUDED
+
+#include <odemx/protocol/Pdu.h>
+
+namespace odemx {
+namespace protocol {
+
+/**
+ * @brief Interface for error models used by classes Medium and Service
+ * @ingroup protocol
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::protocol::Medium odemx::protocol::Service
+ *
+ * When modeling network simulations, it is also necessary to be able to
+ * create different failure situations. In order to allow the definition of
+ * any kind of failure that can occur during data transmission, the interface
+ * ErrorModel is provided.
+ */
+class ErrorModel
+{
+public:
+	/// Destruction
+	virtual ~ErrorModel() {}
+
+	/**
+	 * @brief Process a transmitted message
+	 * @param The PDU to be evaluated by the error model
+	 * @retval @c true if the PDU may pass (even if it was altered)
+	 * @retval @c false if the PDU shall not arrive at its destination
+	 *
+	 * The method may either drop the data unit completely, or it may
+	 * merely change its contents, for example to model bit errors.
+	 */
+	virtual bool apply( PduPtr p ) = 0;
+};
+
+/// Smart pointer type to manage the lifetime of error model objects
+typedef std::shared_ptr< ErrorModel > ErrorModelPtr;
+
+} } // namespace odemx::protocol
+
+#endif /* ODEMX_PROTOCOL_ERRORMODEL_INCLUDED */
diff --git a/odemx-lite/include/odemx/protocol/ErrorModelDraw.h b/odemx-lite/include/odemx/protocol/ErrorModelDraw.h
new file mode 100644
index 0000000000000000000000000000000000000000..4d484b1028335e4745df2a9f79d7b221387306b2
--- /dev/null
+++ b/odemx-lite/include/odemx/protocol/ErrorModelDraw.h
@@ -0,0 +1,83 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ErrorModelDraw.h
+ * @author Ronald Kluth
+ * @date created at 2010/04/05
+ * @brief Declaration of class odemx::protocol::ErrorModelDraw
+ * @sa ErrorModelDraw.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_PROTOCOL_ERRORMODELDRAW_INCLUDED
+#define ODEMX_PROTOCOL_ERRORMODELDRAW_INCLUDED
+
+#include <odemx/protocol/ErrorModel.h>
+#include <odemx/random/Draw.h>
+
+namespace odemx {
+namespace protocol {
+
+/**
+ * @brief Simle ErrorModel implementation
+ * @ingroup protocol
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::protocol::ErrorModel odemx::random::Draw
+ *
+ * This class provides a random-number-based approach to model transmission
+ * failures. It uses an odemx::random::Draw object in order to simulate
+ * the loss of PDUs during transmission, meaning that PDUs are droppped with
+ * a user-defined probability.
+ */
+class ErrorModelDraw
+:	public ErrorModel
+{
+public:
+	/// Creation via static method to enforce shared_ptr usage
+	static ErrorModelPtr create( base::Simulation& sim, const data::Label& label,
+			double probability );
+
+	/// Destruction
+	virtual ~ErrorModelDraw();
+
+	/**
+	 * @brief Implementation of the error model interface
+	 * @param p The PDU that the error model is applied to
+	 * @return @true if the PDU may be transmitted
+	 *
+	 * The implementation of the error model interface simply calls
+	 * @c sample on the internal @c Draw object, which either returns 0 or 1.
+	 * These value appear with the given probability and are used to
+	 * decide whether PDUs may be received at their destination or not.
+	 */
+	virtual bool apply( PduPtr p );
+
+private:
+	/// Draw object for getting a stream of ones and zeros
+	odemx::random::Draw draw_;
+
+private:
+	/// Construction private, use @c create instead
+	ErrorModelDraw( base::Simulation& sim, const data::Label& label, double probability );
+};
+
+} } // namespace odemx::protocol
+
+#endif /* ODEMX_PROTOCOL_ERRORMODELDRAW_INCLUDED */
diff --git a/odemx-lite/include/odemx/protocol/Layer.h b/odemx-lite/include/odemx/protocol/Layer.h
new file mode 100644
index 0000000000000000000000000000000000000000..fe5c5fba012368715979afb981ccb3a65eb66d22
--- /dev/null
+++ b/odemx-lite/include/odemx/protocol/Layer.h
@@ -0,0 +1,157 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Layer.h
+ * @author Ronald Kluth
+ * @date created at 2009/10/13
+ * @brief Declaration of class odemx::protocol::Layer
+ * @sa Layer.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_PROTOCOL_LAYER_INCLUDED
+#define ODEMX_PROTOCOL_LAYER_INCLUDED
+
+#include <odemx/data/Producer.h>
+
+//---------------------------------------------------------forward decalarations
+
+namespace odemx {
+namespace protocol {
+
+class ServiceProvider;
+class Sap;
+
+//----------------------------------------------------------header decalarations
+
+/**
+ * @brief Models the layers of a protocol stack and contains service providers
+ * @ingroup protocol
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::protocol::Stack odemx::protocol::ServiceProvider odemx::protocol::Sap
+ *
+ * ODEMx protocol stacks consist of a number of layers that each offer services
+ * to the layer above. The services are implemented by ServiceProvider subclasses,
+ * while access to them is provided via service access points (SAPs).
+ *
+ * A Layer can hold an arbitrary number of ServiceProviders while making all
+ * of their SAPs visible to the layers above and below in the stack. Layers
+ * always own their ServiceProvider objects and delete them automatically upon
+ * destruction.
+ */
+class Layer
+:	public data::Producer
+{
+public:
+	/// Vector type to store pointers to all kinds of service providers
+	typedef std::vector< ServiceProvider* > ServiceProviderVec;
+	/// Map type to associate service types with suitable SAPs
+	typedef std::map< std::string, Sap* > SapMap;
+
+	/// Construction
+	Layer( base::Simulation& sim, const data::Label& label );
+
+	/**
+	 * @brief Destruction
+	 *
+	 * As the Layer owns all ServiceProviders, it deletes them here.
+	 */
+	virtual ~Layer();
+
+	/**
+	 * @brief Register a new service provider object
+	 * @param sp The new service provider
+	 *
+	 * This layer is set as the service provider's layer so that it may
+	 * have access to SAPs offered by the upper and lower layer.
+	 * In addition, all SAPs of the new service provider are added to the
+	 * SAP map of this layer so they can be retrieved by name. Finally,
+	 * the service provider is stored in an internal vector.
+	 */
+	void addServiceProvider( ServiceProvider* sp );
+
+	/// Get read access to the internal vector holding service providers
+	const ServiceProviderVec& getServiceProviders() const;
+
+	/// Get a pointer to an SAP by providing its name
+	Sap* getSap( const std::string& sap ) const;
+
+	/// Get a reference to the map containing all registered SAPs
+	SapMap& getSaps();
+
+	/// Get access to the upper layer, usually to access its SAPs
+	Layer* getUpperLayer() const;
+
+	/// Get access to the lower layer, usually to access its SAPs
+	Layer* getLowerLayer() const;
+
+	/**
+	 * @brief Set the layer above this one in the stack's hierarchy
+	 * @param layer The layer above
+	 *
+	 * This method is usually not called manually. It is used when adding
+	 * layers to the protocol stack. In that way, adjacent layers get
+	 * connected automatically.
+	 */
+	void setUpperLayer( Layer* layer );
+
+	/**
+	 * @brief Set the layer below this one in the stack's hierarchy
+	 * @param layer The layer above
+	 *
+	 * This method is usually not called manually. It is used when adding
+	 * layers to the protocol stack. In that way, adjacent layers get
+	 * connected automatically.
+	 */
+	void setLowerLayer( Layer* layer );
+
+	/**
+	 * @brief Add an SAP to the layer
+	 * @param sap The SAP object to be registered
+	 *
+	 * This method is usually not called manually. It is used when adding
+	 * service providers to make their SAPs known to users of this layer.
+	 */
+	void addSap( Sap* sap );
+
+	/**
+	 * @brief Remove a registered SAP from the layer
+	 * @param sap Name of the SAP object to be removed
+	 *
+	 * This method is usually not called manually. It is used when SAPs
+	 * are removed from service providers in order to notify the layer that
+	 * an SAP is no longer available.
+	 */
+	bool removeSap( const std::string& sap );
+
+protected:
+	/// Stores all of the layer's service providers
+	ServiceProviderVec serviceProviders_;
+	/// Stores all of the SAPs offered by the layer's service providers
+	SapMap saps_;
+	/// Stores a pointer to the upper layer in the hierarchy
+	Layer* upperLayer_;
+	/// Stores a pointer to the lower layer in the hierarchy
+	Layer* lowerLayer_;
+};
+
+} } // namespace odemx::protocol
+
+#endif /* ODEMX_PROTOCOL_LAYER_INCLUDED */
diff --git a/odemx-lite/include/odemx/protocol/Medium.h b/odemx-lite/include/odemx/protocol/Medium.h
new file mode 100644
index 0000000000000000000000000000000000000000..83149a4bafd872052c69c64d95355ab243a0ccc0
--- /dev/null
+++ b/odemx-lite/include/odemx/protocol/Medium.h
@@ -0,0 +1,263 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Medium.h
+ * @author Ronald Kluth
+ * @date created at 2009/11/01
+ * @brief Declaration of class odemx::protocol::Medium
+ * @sa Medium.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_PROTOCOL_MEDIUM_INCLUDED
+#define ODEMX_PROTOCOL_MEDIUM_INCLUDED
+
+#include <odemx/data/Producer.h>
+#include <odemx/base/Event.h>
+#include <odemx/protocol/Device.h>
+#include <odemx/protocol/Pdu.h>
+
+//----------------------------------------------------------forward declarations
+
+namespace odemx {
+namespace protocol {
+
+class ErrorModel;
+
+//-----------------------------------------------------------header declarations
+
+/**
+ * @brief Models the transmission medium used by devices to transmit data
+ * @ingroup protocol
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::protocol::Device odemx::protocol::ErrorModel
+ *
+ * The Medium manages the topology of a network in the form of links between
+ * Device objects. All devices must be registered to a medium in order to
+ * be able to send PDUs to their neighbor nodes. Whenever a device transmits
+ * data, the medium is responsible for scheduling the corresponding TransmissionStart
+ * and TransmissionEnd events for all neighbors of a node.
+ *
+ * Furthermore, an error model can be assigned to the medium so that arbitrary
+ * transmission failures may be modeled in a uniform way. If more fine-grained
+ * control is required, each link can also be assigned an error model.
+ *
+ */
+class Medium
+:	public data::Producer
+{
+public:
+	/// Map type to associate addresses with device objects
+	typedef std::map< Device::AddressType, Device* > DeviceMap;
+
+	/// Pointer type to manage ErrorModel object lifetime
+	typedef std::shared_ptr< ErrorModel > ErrorModelPtr;
+
+	/// Structure containing the link properties delay and error model
+	struct LinkInfo
+	{
+		/// Defaut construction
+		LinkInfo();
+		/// Construction with link delay and error model
+		LinkInfo( base::SimTime delay, ErrorModelPtr errorModel );
+		/// The specified link delay
+		base::SimTime delay_;
+		/// The provided error model for this link
+		ErrorModelPtr errorModel_;
+	};
+
+	/// Map type associating device pointers with link info objects
+	typedef std::map< Device*, LinkInfo > LinkInfoMap;
+
+	/// Map type associating device pointers with a link info map (i.e. links to neighbors)
+	typedef std::map< Device*, LinkInfoMap > TopologyMap;
+
+	/// Construction
+	Medium( base::Simulation& sim, const data::Label& label );
+
+	/// Destruction
+	virtual ~Medium();
+
+	/**
+	 * @brief Notify all neighbors of the device that it will start sending
+	 * @param sender The device that starts a transmission
+	 *
+	 * This method is used to signal the start of a transmission to all
+	 * neighbor nodes in the network. This is implemented by scheduling
+	 * TransmissionStart events after the specified link delay for each
+	 * registered link of the sender device.
+	 */
+	void signalTransmissionStart( Device* sender );
+
+	/**
+	 * @brief Notify all neighbors of the device about the transmission end and deliver PDUs
+	 * @param sender The device that finished its transmission
+	 * @param p The PDU to be delivered to receiving nodes
+	 *
+	 * This method is used to signal the end of a transmission to all
+	 * neighbor nodes in the network. This can either mean that the transmission
+	 * was aborted, for example due o collision detection, or that it was
+	 * transmitted to the medium successfully (which not necessarily means
+	 * the PDU arrives at the receivers).
+	 *
+	 * Like @c signalTransmissionStart, this method also schedules events,
+	 * this time of type TransmissionEnd, after the specified link delay
+	 * for each registered link of the sender device. This kind of events
+	 * always transports a PDU, which may or may not contain valid data.
+	 *
+	 * The latter fact is due to the usage of the links' error models.
+	 * If the link has no error model, or the message passes it, then a valid
+	 * PDU is delivered. However, the error model may still have corrupted the
+	 * contained data.
+	 */
+	void signalTransmissionEnd( Device* sender, PduPtr p );
+	
+	/**
+	 * @brief Set the default error model of the medium
+	 * @param errorModel The default error model of the medium
+	 *
+	 * During construction the medium is not assigned an error model.
+	 * So this method must be used in order to activate that functionality.
+	 * The provided error model will then be used as the default error
+	 * model that all Links are initialized with, unless a different error
+	 * model is provided when adding the link.
+	 */
+	void setErrorModel( ErrorModelPtr errorModel );
+
+	/**
+	 * @brief Add a link between two devices
+	 * @param srcAddr Address of the sender device
+	 * @param destAddr Address of the receiver device
+	 * @param delay Time it takes to send data over this link
+	 * @param duplex Determines whether to add the link in both directions
+	 * @param errorModel Provides a link-specific error model
+	 * @return @c true if the link was successfully added
+	 *
+	 * This method wraps the other @c addLink overload by first retrieving
+	 * the pointers to registered devices and then calling the overload.
+	 * By default, the link is unidirectional. Supply @c true for parameter
+	 * @c duplex to have the link added in both directions.
+	 */
+	bool addLink( const Device::AddressType& srcAddr,
+			const Device::AddressType& destAddr,
+			base::SimTime delay, bool duplex = false,
+			ErrorModelPtr errorModel = ErrorModelPtr() );
+
+	/**
+	 * @brief Add a unidirectional link between two devices
+	 * @return @c false if the given devices are the same
+	 *
+	 * This method writes a link info entry to the topology map. If there is a
+	 * pre-existing link, its properties will be overwritten. This method
+	 * also automatically sets the medium for @c src, or both devices in
+	 * case of duplex mode.
+	 */
+	bool addLink( Device* src, Device* dest, base::SimTime delay,
+			ErrorModelPtr errorModel = ErrorModelPtr() );
+
+	/**
+	 * @brief Remove a link between two devices
+	 * @param srcAddr Address of the sender device
+	 * @param destAddr Address of the receiver device
+	 * @param duplex Determines whether to remove the link in both directions
+	 *
+	 * This method simply retrieves the device pointers and
+	 * calls the overload. If @c duplex is true, the link will be
+	 * removed in both directions.
+	 */
+	void removeLink( const Device::AddressType& srcAddr,
+			const Device::AddressType& destAddr, bool duplex = false );
+
+	/**
+	 * @brief Remove a unidirectional link between two devices
+	 *
+	 * The method tries to find the given nodes in the topology map
+	 * end erases the link information between them.
+	 */
+	void removeLink( Device* src, Device* dest );
+
+	/**
+	 * @brief Register a new network device by its address
+	 * @param address The address for the device
+	 * @param device The device object
+	 * @return @c true if the device was inserted successfully
+	 *
+	 * This method sets the device's address, and also registers this medium
+	 * object with the device. Finally, it inserts the address and the device
+	 * pointer in the device lookup map.
+	 */
+	bool registerDevice( const Device::AddressType& address, Device& device );
+
+	/// Get access to a registered device
+	Device* getDevice( const Device::AddressType& address ) const;
+
+	/// Get read access to the topology map
+	const TopologyMap& getTopology() const;
+
+	/// Get read access to the device map
+	const DeviceMap& getDevices() const;
+
+	/// Keep collision statistics
+	void collision() const;
+
+protected:
+	/// Stores the links between all nodes in the network
+	TopologyMap topology_;
+	/// Associates all registered device addresses with Device objects
+	DeviceMap devices_;
+	/// The default error model to be set for links if none is provided
+	ErrorModelPtr defaultErrorModel_;
+
+protected:
+	/// Event type for delayed PDU delivery, models the start of a transmission
+	class TransmissionStart
+	:	public base::Event
+	{
+	public:
+		/// Construction
+		TransmissionStart( base::Simulation& sim, const data::Label& label,
+				Device& device );
+
+		/// Increases the receiving device's transmission count
+		virtual void eventAction();
+	private:
+		Device* device_;
+	};
+
+	/// Event type for delayed PDU delivery, models the end and delivery of a transmission
+	class TransmissionEnd
+	:	public base::Event
+	{
+	public:
+		/// Construction
+		TransmissionEnd( base::Simulation& sim, const data::Label& label,
+				Device& device, PduPtr p );
+
+		/// Delivers a PDU at the receiving device and decreases its transmission count
+		virtual void eventAction();
+	private:
+		Device* device_;
+		PduPtr pdu_;
+	};
+};
+
+} } // namespace odemx::protocol
+
+#endif /* ODEMX_PROTOCOL_MEDIUM_INCLUDED */
diff --git a/odemx-lite/include/odemx/protocol/Pdu.h b/odemx-lite/include/odemx/protocol/Pdu.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea885caeff6f5a5594a9fc3ca0f20e1b5ab60fb5
--- /dev/null
+++ b/odemx-lite/include/odemx/protocol/Pdu.h
@@ -0,0 +1,102 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Pdu.h
+ * @author Ronald Kluth
+ * @date created at 2009/10/31
+ * @brief Declaration of interface odemx::protocol::Pdu
+ * @since 3.0
+ */
+
+#ifndef ODEMX_PROTOCOL_PDU_INCLUDED
+#define ODEMX_PROTOCOL_PDU_INCLUDED
+
+#include <cstddef>
+#ifdef _MSC_VER
+#include <memory>
+#else
+#include <memory>
+#endif
+
+namespace odemx {
+namespace protocol {
+
+class Pdu;
+
+/// Smart pointer type to manage the lifetime of PDUs
+typedef std::shared_ptr< Pdu > PduPtr;
+
+/**
+ * @brief Base class for all protocol data unit types
+ * @ingroup protocol
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::protocol::Sap odemx::protocol::ServiceProvider
+ *
+ * All message queues in ODEMx requires the same polymorphic base type
+ * in order to forward arbitrary messages. Therefore, protocol data units
+ * (PDUs) are represented by this class. The data buffers are held by SAPs
+ * and read by service providers or service users.
+ * 
+ * The interface defined for PDU types is simple. ODEMx needs to know the
+ * size of the data unit when it is transmitted via medium, and the PDUs
+ * must be cloneable in order to avoid side effect when the same PDU
+ * is forwarded to multiple receivers at once.
+ */
+class Pdu
+{
+public:
+	/// Destruction
+	virtual ~Pdu() {}
+
+	/**
+	 * @brief Create a copy of a PDU object
+	 * @return Pointer to a copy of the PDU object
+	 * @see odemx::protocol::Medium
+	 *
+	 * All message types to be used in ODEMx protocol simulations must
+	 * implement a clone method. Sending the same message to a number
+	 * of different receivers requires that each of them work with their
+	 * own copy of the message because it may be altered on its way through
+	 * a network. Merely copying the pointer would likely result in unintended
+	 * changes leading to subtle errors. This method is thus used by the medium
+	 * whenever PDUs are sent to receivers.
+	 */
+	virtual PduPtr clone() const = 0;
+
+	/**
+	 * @brief Get the size of a PDU
+	 * @return Size of the PDU
+	 * @see odemx::protocol::Device
+	 * 
+	 * Determining the time it takes to transmit a message via a medium
+	 * requires knowledge of the message size and the bitrate at which a
+	 * device can send. The latter factor may vary depending on quality of
+	 * service parameters and external influences. Therefore, devices require
+	 * the message size instead of a fixed time duration value in order to
+	 * compute the amount of time it takes to transmit a given message.
+	 * 
+	 * @note The default implementation returns 0
+	 */
+	virtual std::size_t getSize() const = 0;
+};
+
+} } // namespace odemx::protocol
+
+#endif /* ODEMX_PROTOCOL_PDU_INCLUDED */
diff --git a/odemx-lite/include/odemx/protocol/Sap.h b/odemx-lite/include/odemx/protocol/Sap.h
new file mode 100644
index 0000000000000000000000000000000000000000..a217a815b23e1ae9fa34deb0378c6789d9b98912
--- /dev/null
+++ b/odemx-lite/include/odemx/protocol/Sap.h
@@ -0,0 +1,174 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Sap.h
+ * @author Ronald Kluth
+ * @date created at 2009/10/13
+ * @brief Declaration of class odemx::protocol::Sap
+ * @sa Sap.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_PROTOCOL_SAP_INCLUDED
+#define ODEMX_PROTOCOL_SAP_INCLUDED
+
+#include <odemx/protocol/Pdu.h>
+#include <odemx/synchronization/Port.h>
+
+#include <deque>
+#include <string>
+
+//----------------------------------------------------------forward declarations
+
+namespace odemx {
+
+namespace base { class Process; }
+
+namespace protocol {
+
+class ServiceProvider;
+
+//---------------------------------------------------------- header declarations
+
+/**
+ * @brief Service access point (SAP) implementation for protocol service providers
+ * @ingroup protocol
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::protocol::ServiceProvider odemx::protocol::Layer odemx::protocol::Stack
+ *
+ * In ODEMx, protocol services are modeled by ServiceProvider implementations.
+ * SAPs provide a decoupled interface to the services offered by a protocol layer.
+ * By offering access through the same interface, service providers can easily
+ * be exchanged, allowing for top-down refinement by first using an abstract
+ * Service implementation that may then be replaced by a more detailed Entity or
+ * device. The communication of the application layer with the protocol stack
+ * is also implemented with SAPs. Therefore, the protocol stack itself is
+ * replaceable, for example by a simpler Service implementation.
+ *
+ * Sap is compatible with the wait-alert concept that is based on Memory
+ * implementations. For this reason, class Sap has an internal buffer
+ * that is derived from odemx::synchronization::PortHeadT.
+ */
+class Sap
+{
+public:
+
+	/**
+	 * @brief Internal buffer interface
+	 *
+	 * The SAP buffer is implemented using an odemx::synchronization::PortT. This class
+	 * provides the read interface to the buffer. It is required in order
+	 * to query the alerting PortHeadT for its owning SAP.
+	 */
+	class BufferHead: public synchronization::PortHeadT< PduPtr >
+	{
+	public:
+		/// Smart pointer type to manage oject lifetime
+		typedef std::shared_ptr< BufferHead > Ptr;
+
+		/// Creation via static method to enfore shared_ptr usage
+		static Ptr create( base::Simulation& sim, const data::Label& label, Sap& sap );
+
+		/// SAP access
+		Sap& getSap() const;
+
+	private:
+		/// Pointer to the owning SAP
+		Sap* sap_;
+	private:
+		/// Construction private, use @c create instead
+		BufferHead( base::Simulation& sim, const data::Label& label, Sap& sap );
+	};
+
+	/**
+	 * @brief Construction
+	 * @param sim The simulation context
+	 * @param label The label of the owning service provider
+	 * @param name The name to be used for accessing the SAP
+	 *
+	 * The constructor initializes the internal buffer, as well as its
+	 * read and write interfaces (head and tail).
+	 */
+	Sap( base::Simulation& sim, const data::Label& label, const std::string& name );
+
+	/// Destruction
+	virtual ~Sap();
+
+	/// Get the name of the SAP
+	const std::string& getName() const;
+
+	/**
+	 * @brief Get a pointer to the buffer read interface
+	 *
+	 * This method is needed when SAPs are used in calls of Process::wait(),
+	 * which expects a number of IMemory pointers to be passed to it. As soon
+	 * as data becomes available at an SAP, the waiting Process is reactivated
+	 * and can use the BufferHead to check which SAP awoke it.
+	 */
+	BufferHead* getBuffer() const;
+
+	/**
+	 * @brief Send interface for service users
+	 * @param p The data unit to be written to the SAP
+	 *
+	 * This method is used to put data into the SAP's buffer. If there is
+	 * a service provider waiting for input on this SAP, that process will
+	 * immediately activated in order to consume the data.
+	 */
+	void write( PduPtr p );
+
+	/**
+	 * @brief Receive interface for service users
+	 * @return The first data unit stored in the SAPs buffer
+	 *
+	 * This is a blocking call to the SAP's buffer. If there is no data
+	 * available, the calling Process will be put into a wait state
+	 * until @c write is called on the SAP.
+	 */
+	PduPtr read();
+
+private:
+	// The name must not be unique, i.e. no Label, because all ServiceProvider
+	// objects expect to access SAPs by the same names, not unique ones.
+	/// Name of the SAP for access by service providers
+	std::string name_;
+	/// Input buffer read interface
+	BufferHead::Ptr queueHead_;
+	/// Input buffer write interface
+	BufferHead::TailPtr queueTail_;
+
+public:
+	// TODO: turn this into a comparator for std::set and replace SAP vectors with sets
+
+	/// Functor for use with std algorithms to find SAPs by name
+	struct MatchName
+	{
+		const std::string& name_;
+		MatchName( const std::string& name ): name_( name ) {}
+		bool operator()( Sap* sap ) const
+		{
+			return sap->getName() == name_;
+		}
+	};
+};
+
+} } // namespace odemx::protocol
+
+#endif /* ODEMX_PROTOCOL_SAP_INCLUDED */
diff --git a/odemx-lite/include/odemx/protocol/Service.h b/odemx-lite/include/odemx/protocol/Service.h
new file mode 100644
index 0000000000000000000000000000000000000000..f410434e185d56880d134696f403c50758a11394
--- /dev/null
+++ b/odemx-lite/include/odemx/protocol/Service.h
@@ -0,0 +1,302 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Service.h
+ * @author Ronald Kluth
+ * @date created at 2009/10/12
+ * @brief Declaration of class odemx::protocol::Service
+ * @sa Service.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_PROTOCOL_SERVICE_INCLUDED
+#define ODEMX_PROTOCOL_SERVICE_INCLUDED
+
+#include <odemx/protocol/ServiceProvider.h>
+#include <odemx/protocol/Sap.h>
+
+//----------------------------------------------------------forward declarations
+
+namespace odemx {
+namespace protocol {
+
+class ErrorModel;
+	
+//-----------------------------------------------------------header declarations
+
+/**
+ * @brief Base class for modeling simple protocol services
+ * @ingroup protocol
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::protocol::Sap odemx::protocol::Stack odemx::protocol::Layer odemx::protocol::ErrorModel
+ *
+ * A layer in the protocol stack usually offers a specific functionality to
+ * its users as services. An access interface is provided through so-called
+ * service access points (SAP). Users pass service primitives
+ * (i.e. commands and data) to specific SAPs in order to make use of a
+ * service. The functionality the service offers is implemented by service
+ * providers, active objects within the layers of a stack. One such class is
+ * Service.
+ *
+ * This class provides the basis for the implementation of a simple service.
+ * Service is intended to be used inn one of two ways. It can either replace
+ * a stack and provide a very simple communication layer for nodes, or it
+ * can be used in the bottom layer of a protocol stack in order to simplify
+ * the transmission aspect of the network model. All Service objects are
+ * directly linked in order to abstract from the network topology.
+ * All service objects in a simulation are associated with addresses upon
+ * registration. Registering a service object means that a pointer to it
+ * is stored in a map, and it can be accessed by providing the service address.
+ * Subclasses need to define the pure virtual methods @c handleSend and
+ * @c handleReceive in order to define the service behavior.
+ *
+ * Since Service objects may be used as a replacement for @c Stack objects,
+ * they also provide the same functionality with regard to receive SAPs. Users
+ * may create output SAPs they can use to listen for received data by calling
+ * the method @c addReceiveSap.
+ */
+class Service
+:	public ServiceProvider
+{
+public:
+	/// Address type to identify users
+	typedef std::string AddressType;
+	/// Map type to associate user addresses with service objects
+	typedef std::map< AddressType, Service* > AddressMap;
+
+	/**
+	 * @brief Construction
+	 * @param sim The simulation context
+	 * @param label The label of the object
+	 *
+	 * The constructor initializes an internal SAP that is needed for
+	 * receiving data from peer service objects. Since services are service
+	 * providers, they also just listen for input and wait. They must therefore
+	 * be awakened by an internal SAP when data is received from a peer. This
+	 * functionality is analogous to that of class Device.
+	 */
+	Service( base::Simulation& sim, const data::Label& label );
+
+	/**
+	 * @brief Destruction
+	 *
+	 * All receive SAPs that were added as listening interfaces by an
+	 * application layer are automatically deleted.
+	 */
+	virtual ~Service();
+
+	/**
+	 * @name Service user registration and access
+	 * @{
+	 */
+	/**
+	 * @brief Register a user with the service in order to receive messages
+	 * @param address The address to use for accessing the given service
+	 * @param service The service object to be registered
+	 * @return @c true if the map insertion was successful
+	 *
+	 * Service objects are always directly connected within a simulation.
+	 * Therefore, they are all simply registered with a static map and can
+	 * be accessed by their addresses.
+	 */
+	static bool registerService( const AddressType& address, Service& service );
+
+	/**
+	 * @brief Remove a service from the registration map to make a node unavailable
+	 * @param address The address of the service to be removed from the map
+	 * @return @c true of if the removal was successful
+	 *
+	 * Since the nodes of a network may dynamically enter and leave, this method
+	 * provides a means to make Service peers unavailable by simply removing the
+	 * map entries.
+	 */
+	static bool removeService( const AddressType& address );
+
+	/// Get read access to the map holding all registered users
+	static const AddressMap& getAddressMap();
+
+	/**
+	 * @brief Get a pointer to a registered Service object
+	 * @param peer The address under which the peer service is registered
+	 * @return Pointer to the peer object, or 0 if not found
+	 *
+	 * Since the service is an abstraction of the protocol stack or the
+	 * transmission device, and not all configuration data may be contained
+	 * in transmitted messages, it may sometimes be necessary to influence
+	 * the state of a particular service object internally. This method
+	 * provides the means to retrieve any registered service object.
+	 */
+	static Service* getPeer( const AddressType& peer );
+
+	/**
+	 * @brief Set the address of a Service object
+	 *
+	 * Normally, there is no need to use this method manually. Upon registration
+	 * the service will automatically receive the address provided
+	 * in the call to @c registerService.
+	 */
+	void setAddress( const AddressType& addr );
+
+	/// Get the address of the service object
+	const AddressType& getAddress() const;
+	//@}
+
+	/**
+	 * @brief Add an SAP from which to receive data
+	 * @param name The name of the SAP to be created
+	 * @return A pointer to the SAP object
+	 *
+	 * When a Service class is used in place of a Stack, it must be usable
+	 * in the same manner. Since stacks allow for the creation of listening
+	 * SAPs, services do this as well.
+	 *
+	 * @note These objects are managed internally. There is no need
+	 * call delete on them.
+	 */
+	Sap* addReceiveSap( const std::string& name );
+
+	/// Get access to a receive SAP owned by the service
+	Sap* getReceiveSap( const std::string& name );
+
+	/**
+	 * @brief Send a data unit to another registered Service object
+	 * @param peer The service's address
+	 * @param p The data unit to be transmitted
+	 * @return @c true if the receiver was found in the map
+	 *
+	 * This method is used to directly send PDUs from one node to another.
+	 * It looks up the peer in the registration map and calls @c receive
+	 * on the service object. A warning will be issued
+	 * if the peer is not found.
+	 */
+	bool send( const AddressType& peer, PduPtr p ) const;
+
+	/**
+	 * @brief Pass a message from the network to the upper layer
+	 * @param sapName The SAP to which to pass the data unit
+	 * @param p The data unit to pass on
+	 *
+	 * This method simply looks up the SAP in the upper layer, or the receive
+	 * SAPs. It then writes the given data unit to it. A warning will be issued
+	 * if the SAP is not found.
+	 */
+	bool pass( const std::string& sapName, PduPtr p );
+	
+	/**
+	 * @brief Set the error model for the Service class
+	 * @param em The error model to be used by the Service implementation
+	 *
+	 * Since this class is only a simple implementation of a transmission
+	 * service, it can also only provide a simple means of modeling
+	 * errors in the transmission activities.
+	 *
+	 * Only one ErrorModel implementation can be set per Service class
+	 * because it is implemented with a static member. It is checked whenever
+	 * a registered service object receives data from a peer. This way,
+	 * PDUs can be filtered or altered during the transmission period.
+	 */
+	static void setErrorModel( std::shared_ptr< ErrorModel > em );
+	
+protected:
+	/**
+	 * @name Input handling, to be defined by subclasses
+	 * @{
+	 */
+	/**
+	 * @brief Implements the service functionality for sending data
+	 * @param sapName The SAP used to input the data
+	 * @param p The data unit to be transmitted to a peer
+	 *
+	 * Whenever data is provided by an SAP other than the internal receive
+	 * SAP, this pure virtual method is called with the name of the SAP
+	 * and the PDU to send. Every service must implement this method in
+	 * order to specify what data is to be transmitted and how long the
+	 * waiting period is. Usually, this method calls @c send.
+	 */
+	virtual void handleSend( const std::string& sapName, PduPtr p ) = 0;
+
+	/**
+	 * @brief Implement the service functionality for message reception
+	 * @param p The data unit received from the medium
+	 *
+	 * This method gets called whenever data from a peer arrives through
+	 * the internal receive SAP. The service must implement this method to
+	 * define if and how data is to be passed to the upper layer or not.
+	 * Usually, this method calls @c pass.
+	 */
+	virtual void handleReceive( PduPtr p ) = 0;
+
+	/// Implementation of the service provider interface
+	virtual void handleInput( const std::string& sap, PduPtr pdu );
+	//@}
+
+	/**
+	 * @brief Put a data unit into the service's receive SAP
+	 *
+	 * This method should not be called manually. It is part of the interaction
+	 * between peers. As such, it is called from with the method @c send.
+	 */
+	void receive( PduPtr p );
+
+protected:
+	/// Stores the address of a service object
+	AddressType address_;
+	/// Internal SAP for message reception from peers
+	Sap* receiveSap_;
+	/// Stores all registered output SAPs
+	SapVec outputSaps_;
+	/// Associates addresses of service users with pointers to their service objects
+	static AddressMap services_;
+	/// Manages a pointer to the error model, if one is set
+	static std::shared_ptr< ErrorModel > errorModel_;
+};
+
+} } // namespace odemx::protocol
+
+// how to implement global user storage for multiple service classes in the same simulation:
+// make the static map dependent on the derived type of the service
+// each derived type gets its own user storage generated by the compiler
+// when the templates get instantiated
+// service must be implemented via CRTP:
+// class DerivedService: public ServiceT< DerivedService > {};
+/*
+template < typename > class ServiceUserStorage;
+
+template < typename DerivedT >
+class ServiceT
+{
+public: // service impl
+	static ServiceUserStorage< DerivedT > userStorage_;
+};
+
+template < typename DerivedServiceT >
+class ServiceUserStorage
+{
+public:
+	typedef std::string AddressType;
+	typedef std::map< AddressType, Service* > UserMap;
+	static UserMap users_;
+};
+
+template < typename DerivedServiceT >
+ServiceUserStorage< DerivedServiceT >::UserMap ServiceUserStorage< DerivedServiceT >::users_;
+*/
+
+#endif /* ODEMX_PROTOCOL_SERVICE_INCLUDED */
diff --git a/odemx-lite/include/odemx/protocol/ServiceProvider.h b/odemx-lite/include/odemx/protocol/ServiceProvider.h
new file mode 100644
index 0000000000000000000000000000000000000000..beef36ba408e6359a47a677acdc74a30fffeeaa6
--- /dev/null
+++ b/odemx-lite/include/odemx/protocol/ServiceProvider.h
@@ -0,0 +1,151 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ServiceProvider.h
+ * @author Ronald Kluth
+ * @date created at 2009/10/29
+ * @brief Declaration of class odemx::protocol::ServiceProvider
+ * @sa ServiceProvider.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_PROTOCOL_SERVICEPROVIDER_INCLUDED
+#define ODEMX_PROTOCOL_SERVICEPROVIDER_INCLUDED
+
+#include <odemx/base/Process.h>
+#include <odemx/protocol/Pdu.h>
+
+//----------------------------------------------------------forward declarations
+
+namespace odemx {
+namespace protocol {
+
+class Layer;
+class Sap;
+
+//-----------------------------------------------------------header declarations
+
+/**
+ * @brief Abstract base class for service-implementing classes
+ * @ingroup protocol
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::protocol::Sap odemx::protocol::Service odemx::protocol::Entity odemx::protocol::Device
+ *
+ * A service usually offers a specific functionality to its users. An interface
+ * to a service is provided through a so-called service access point (SAP).
+ * Users pass service primitives (i.e. commands with data) to the SAP in order
+ * to make use of the service. In ODEMx, service provider implementations
+ * are the active components in the layers of the protocol stack. Thus
+ * they are derived from class Process.
+ *
+ * Class ServiceProvider provides the basis for the implementation of service
+ * providers. The base functionality includes a vector for an arbitrary number
+ * of SAPs and a pointer the layer of the stack which holds the service provider.
+ *
+ * ServiceProvider objects own their SAPs. Their process behavior is defined as
+ * waiting state until data is ready at one of the SAPs. As soon as data becomes
+ * available, the Process is activated and calls the pure virtual function
+ * @c handleInput. Subclasses must define this to specifiy the service
+ * implementation.
+ */
+class ServiceProvider
+:	public base::Process
+{
+public:
+	/// Vector type to hold pointers to SAPs
+	typedef std::vector< Sap* > SapVec;
+	/// Destruction, deletes all Sap objects owned by the ServiceProvider
+	virtual ~ServiceProvider();
+
+	/// Set the owning layer of this service provider
+	void setLayer( Layer* layer );
+	/// Access the layer, may return 0 if the layer is not set
+	Layer* getLayer() const;
+
+	/**
+	 * @brief Create and add an SAP to the service provider
+	 * @param name The name of the SAP to be created
+	 * @return Pointer to the SAP of that name
+	 *
+	 * If the SAP already exists, a warning will be issued and the existing
+	 * object returned. Otherwise, a new Object will be created and added
+	 * to a vector. If a layer is set, the SAP will also be regstered
+	 * with the layer to make it available to the upper and lower layers.
+	 */
+	Sap* addSap( const std::string& name );
+
+	/**
+	 * @brief Remove an SAP from the service provider
+	 * @param name The name of the SAP
+	 * @return @c true if successful, @c false if not found
+	 *
+	 * This method removes an SAP from the ServiceProvider and also
+	 * from the layer, if one is set.
+	 */
+	bool removeSap( const std::string& name );
+
+	/// Access any SAP by name, returns 0 if the name was not found
+	Sap* getSap( const std::string& name ) const;
+
+	/// Get a list of all SAPs owned by this service provider
+	const SapVec& getSaps() const;
+	
+protected:
+	/**
+	 * @brief Implement the service functionality
+	 * @param sapName The SAP from which input was received
+	 * @param pdu The protocol data unit read from the SAP
+	 *
+	 * This function defines the behavior of a service provider when
+	 * a PDU is input through one of its SAPs. Since the name is provided
+	 * as argument, the service provider can choose the appropriate action
+	 * for the requested service.
+	 */
+	virtual void handleInput( const std::string& sapName, PduPtr pdu ) = 0;
+
+	/**
+	 * @brief Construction
+	 *
+	 * The constructor automatically activates the process so that its
+	 * @c main function gets called as soon as the simulation run starts.
+	 */
+	ServiceProvider( base::Simulation& sim, const data::Label& label );
+
+	/**
+	 * @brief Process behavior definition
+	 *
+	 * The ServiceProvider enters a wait state until it receives input.
+	 * It then calls @c handleInput and returns to the wait state after that
+	 * function call returns.
+	 */
+	virtual int main();
+
+protected:
+	/// Stores a pointer to the layer this service provider belongs to
+	Layer* layer_;
+	/// Stores pointers to all SAPs owned by the service provider
+	SapVec saps_;
+	/// Stores pointers to the SAP's buffers (subclasses of Memory) for wait-alert
+	synchronization::IMemoryVector sapQueues_;
+};
+
+} } // namespace odemx::protocol
+
+#endif /* ODEMX_PROTOCOL_SERVICEPROVIDER_INCLUDED */
diff --git a/odemx-lite/include/odemx/protocol/Stack.h b/odemx-lite/include/odemx/protocol/Stack.h
new file mode 100644
index 0000000000000000000000000000000000000000..529c630fb4c837d147a5cf2a1398f408292a6eba
--- /dev/null
+++ b/odemx-lite/include/odemx/protocol/Stack.h
@@ -0,0 +1,147 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Stack.h
+ * @author Ronald Kluth
+ * @date created at 2009/10/16
+ * @brief Declaration of class odemx::protocol::Stack
+ * @sa Stack.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_PROTOCOL_STACK_INCLUDED
+#define ODEMX_PROTOCOL_STACK_INCLUDED
+
+#include <odemx/data/Producer.h>
+
+#include <map>
+#include <vector>
+
+//----------------------------------------------------------forward declarations
+
+namespace odemx {
+namespace protocol {
+
+class Sap;
+class Layer;
+class Pdu;
+
+//-----------------------------------------------------------header declarations
+
+/**
+ * @brief A class for assembling protocol stacks from layers and service providers
+ * @ingroup protocol
+ * @author Ronald Kluth
+ * @since 3.0
+ * @see odemx::protocol::Layer odemx::protocol::Entity odemx::protocol::Service odemx::protocol::Device
+ *
+ * Protocol stacks are composed of layers that each provide different services
+ * to the layer above. Stack is the class that allows gluing these layers
+ * together. Registered layers are owned by the stack and kept in a vector.
+ * The registration order is important because the layers' internal pointers
+ * to adjacent layers (upper/lower) are set during this phase.
+ *
+ * As the stack provides the means to transmit data between the applications
+ * running on network nodes, it must also provide a means to listen for
+ * incoming data. This is achieved by creating receive SAPs.
+ *
+ * @note It is not always necessary to use a complete protocol stack in order
+ * to model node communication in a network. The simplest way to achieve this
+ * is to use a Service implementation, which can be used as a replacement
+ * for Stack objects as it includes the same interface.
+ */
+class Stack
+:	public data::Producer
+{
+public:
+	/// Vector type to hold pointers to protocol layers
+	typedef std::vector< Layer* > LayerVec;
+
+	/**
+	 * @brief Construction
+	 * @param sim The simulation context
+	 * @param label The label of the object
+	 *
+	 * The constructor initializes an internal layer that is used for storing the
+	 * receive SAPs that stack users can listen on.
+	 */
+	Stack( base::Simulation& sim, const data::Label& label );
+
+	/**
+	 * @brief Destruction
+	 *
+	 * The destructor deletes all receive SAPs and all layers owned by the stack.
+	 */
+	virtual ~Stack();
+
+	/**
+	 * @brief Get access to an SAP from the top layer of the stack hierarchy
+	 *
+	 * In order to use a protocol stack, data must be passed to it by writing
+	 * data units to an SAP. This method is used to retrieve SAPs of the top
+	 * layer in the stack hierarchy. The service providers of the layers will
+	 * then take care of the transmission procedure.
+	 */
+	Sap* getSap( const std::string& name ) const;
+
+	/**
+	 * @brief Add a layer to the protocol stack
+	 * 
+	 * Protocol stacks are composed from layers. Thus, in order to configure a
+	 * stack, one must first create the layers with appropriate service
+	 * providers and then add them to the stack. The layers must be added in 
+	 * order from top to bottom.
+	 */
+	void addLayer( Layer* layer );
+
+	/**
+	 * @brief Get a reference to the vector containing all registered layers
+	 * @return Reference to the internal layer vector
+	 * @note Provided for testing purposes
+	 */
+	const LayerVec& getLayers() const;
+
+	/**
+	 * @brief Add a new SAP to the stack in order to receive output
+	 * @return Pointer to the SAP object, may be newly created or alreaady existing
+	 *
+	 * Users of the stack may need to add SAPs from which to receive data.
+	 * These SAPs are managed by the Stack so users do not need to delete them.
+	 * If the addition of an existing SAP is requested, the method will
+	 * issue a warning message.
+	 */
+	Sap* addReceiveSap( const std::string& name );
+
+	/**
+	 * @brief Get a pointer to one of the protocol stack's SAPs
+	 * @return Pointer to the requested SAP object, or 0 if the SAP does not exist
+	 *
+	 * Users of the stack can get access to receive SAPs by name in order
+	 * to listen for the arrival of data.
+	 */
+	Sap* getReceiveSap( const std::string& name ) const;
+	
+private:
+	/// Stores the layers that compose the protocol stack
+	LayerVec layers_;
+};
+
+} } // namespace odemx::protocol
+
+#endif /* ODEMX_PROTOCOL_STACK_INCLUDED */
diff --git a/odemx-lite/include/odemx/random/ContinuousConst.h b/odemx-lite/include/odemx/random/ContinuousConst.h
new file mode 100644
index 0000000000000000000000000000000000000000..18465359c1333e5c4d2efbb2fbadaddca61ea650
--- /dev/null
+++ b/odemx-lite/include/odemx/random/ContinuousConst.h
@@ -0,0 +1,83 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file ContinuousConst.h
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Declaration of odemx::random::ContinuousConst
+ */
+
+#ifndef CONTINUOUSCONST_H_
+#define CONTINUOUSCONST_H_
+
+#include <odemx/random/ContinuousDist.h>
+
+namespace odemx {
+namespace random {
+
+/** \class ContinuousConst
+
+	\ingroup rdist
+
+	\author Ralf Gerstenberger
+
+	\brief Constant number generator
+
+	\note Rconst from ODEM
+
+	\note supports Report
+
+	ContinuousConst provides a constant number through the
+	ContinuousDist interface.
+
+	\since 1.0
+*/
+class ContinuousConst
+:	public ContinuousDist
+{
+public:
+
+	/**
+		\brief Construction with user-defined DistContext (i.e. Simulation)
+		\param label
+			Label of the generator
+		\param c
+			Pointer to DistContext object
+		\param d
+			constant double returned by sample()
+	*/
+	ContinuousConst( base::Simulation& sim, const data::Label& label, double value );
+
+	/// Destruction
+	virtual ~ContinuousConst();
+
+	/// Get number
+	virtual double sample();
+
+	/// Get parameter d
+	double getValue();
+
+private:
+	const double value_;
+};
+
+} } // namespace odemx::random
+
+#endif /* CONTINUOUSCONST_H_ */
diff --git a/odemx-lite/include/odemx/random/ContinuousDist.h b/odemx-lite/include/odemx/random/ContinuousDist.h
new file mode 100644
index 0000000000000000000000000000000000000000..7fbe9afb4d5e38ca7c41b66b24aba8d819a70bd3
--- /dev/null
+++ b/odemx-lite/include/odemx/random/ContinuousDist.h
@@ -0,0 +1,93 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file ContinuousDist.h
+
+	\author Ralf Gerstenberger
+
+	\date created at 2003/05/09
+
+	\brief Declaration of odemx::random::ContinuousDist
+
+	\sa ContinuousDist.cpp
+
+	Continuous random number generator.
+
+	\since 1.0
+*/
+
+#ifndef ODEMX_RDIST_INCLUDED
+#define ODEMX_RDIST_INCLUDED
+
+#include <odemx/random/Dist.h>
+
+namespace odemx {
+namespace random {
+
+/**
+	\defgroup rdist Continuous distributions
+	\ingroup random
+
+	A group of random number generators which produce continuous (double)
+	random numbers of different distributions.
+*/
+
+/** \interface ContinuousDist
+
+	\ingroup rdist
+
+	\author Ralf Gerstenberger
+
+	\brief Interface for continuous distributions
+
+	%ContinuousDist declares the 'double sample()' method for continuous
+	distribution classes. All derived classes implement this
+	method to provide the random numbers in different distributions.
+
+	\since 1.0
+*/
+class ContinuousDist
+:	public Dist
+{
+public:
+
+	/**
+		\brief Construction with user-defined DistContext (i.e. Simulation)
+		\param label
+			Label of the generator
+		\param c
+			pointer to DistContext object
+	*/
+	ContinuousDist( base::Simulation& sim, const data::Label& label );
+
+	/// Destruction
+	virtual ~ContinuousDist();
+
+	/**
+		\brief Get next random number
+
+		This function returns the next random number.
+		It is implemented in derived classes which generate
+		random numbers in different distributions.
+	*/
+	virtual double sample() = 0;
+};
+
+} } // namespace odemx::random
+
+#endif
diff --git a/odemx-lite/include/odemx/random/DiscreteConst.h b/odemx-lite/include/odemx/random/DiscreteConst.h
new file mode 100644
index 0000000000000000000000000000000000000000..4647c2227fb83e1e24d65dac3c998e2fdb448408
--- /dev/null
+++ b/odemx-lite/include/odemx/random/DiscreteConst.h
@@ -0,0 +1,81 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file DiscreteConst.h
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Declaration of odemx::random::DiscreteConst
+ */
+
+#include <odemx/random/DiscreteDist.h>
+
+namespace odemx {
+namespace random {
+
+/** \class DiscreteConst
+
+	\ingroup idist
+
+	\author Ralf Gerstenberger
+
+	\brief Constant number generator
+
+	\note Iconst from ODEM
+
+	\note supports Report
+
+	DiscreteConst provides a constant integer number through the
+	DiscreteDist interface. The constant number is set in the
+	constructor.
+
+	\since 1.0
+*/
+class DiscreteConst
+:	public DiscreteDist
+{
+public:
+	/**
+		\brief Construction for user-defined DistContext (i.e. Simulation)
+		\param title
+			Label of the generator
+		\param c
+			RNG Context
+		\param i
+			constant integer returned by sample()
+
+		The parameter i defines the number returned
+		by this pseudo generator.
+	*/
+	DiscreteConst( base::Simulation& sim, const data::Label& label, int value );
+
+	/// Destruction
+	virtual ~DiscreteConst();
+
+	/// Get number
+	virtual int sample();
+
+	/// Get the constant value
+	int getValue();
+
+private:
+	const int value_;
+};
+
+} } // namespace odemx::random
diff --git a/odemx-lite/include/odemx/random/DiscreteDist.h b/odemx-lite/include/odemx/random/DiscreteDist.h
new file mode 100644
index 0000000000000000000000000000000000000000..5f77b7d1faa2f41c257ff6aaf80ab749b7813e29
--- /dev/null
+++ b/odemx-lite/include/odemx/random/DiscreteDist.h
@@ -0,0 +1,93 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file DiscreteDist.h
+
+	\author Ralf Gerstenberger
+
+	\date created at 2003/05/09
+
+	\brief Declaration of odemx::random::DiscreteDist
+
+	\sa DiscreteDist.cpp
+
+	Discrete random number generators
+
+	\since 1.0
+*/
+
+#ifndef ODEMX_IDIST_INCLUDED
+#define ODEMX_IDIST_INCLUDED
+
+#include <odemx/random/Dist.h>
+
+namespace odemx {
+namespace random {
+
+/**
+	\defgroup idist Integer distributions
+	\ingroup random
+
+	A group of random number generators which produce integer
+	random numbers in different distributions.
+*/
+
+/** \interface DiscreteDist
+
+	\ingroup idist
+
+	\author Ralf Gerstenberger
+
+	\brief Interface for integer distributions
+
+	%DiscreteDist declares the 'int sample()' method for discrete
+	distribution classes. All derived classes implement this
+	method to provide the random numbers in different distributions.
+
+	\since 1.0
+*/
+class DiscreteDist
+:	public Dist
+{
+public:
+
+	/**
+		\brief Construction for user-defined DistContext (i.e. Simulation)
+		\param title
+			Label of the generator
+		\param c
+			pointer to a DistContext object
+	*/
+	DiscreteDist( base::Simulation& sim, const data::Label& label );
+
+	/// Destruction
+	virtual ~DiscreteDist();
+
+	/**
+		\brief Get next random number
+
+		This function returns the next random number.
+		It is implemented in derived classes which generate
+		random numbers in different distributions.
+	*/
+	virtual int sample() = 0;
+};
+
+} } // namespace odemx::random
+
+#endif
diff --git a/odemx-lite/include/odemx/random/Dist.h b/odemx-lite/include/odemx/random/Dist.h
new file mode 100644
index 0000000000000000000000000000000000000000..a331c452dc7feab1218f99aa7597dde5849eb3db
--- /dev/null
+++ b/odemx-lite/include/odemx/random/Dist.h
@@ -0,0 +1,120 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Dist.h
+
+	\author Ralf Gerstenberger
+
+	\date created at 2003/05/09
+
+	\brief Declaration of odemx::random::Dist
+
+	\sa Dist.cpp
+
+	\since 1.0
+*/
+
+#ifndef ODEMX_DIST_INCLUDED
+#define ODEMX_DIST_INCLUDED
+
+#include <odemx/data/Producer.h>
+
+namespace odemx {
+namespace random {
+
+class DistContext;
+
+/** \class Dist
+
+	\ingroup random
+
+	\author Ralf Gerstenberger
+
+	\brief Linear Random Number Generator
+
+	\note LRNG from ODEM
+
+	%Dist is the base class for all random number generators of
+	ODEMx. It provides an implementation of an integer random
+	number generator using the linear congruential algorithm.
+	This algorithm is known to produce sequences of numbers which
+	are sufficiently random for simulations. \n
+	This class is not used directly. Instead one of the derived
+	classes is used, which provide transformations into sequences
+	of random numbers with different distributions.
+
+	\sa DiscreteDist and ContinuousDist
+
+	\since 1.0
+*/
+class Dist
+:	public data::Producer
+{
+protected:
+
+	/**
+		\brief Construction
+
+		\param label
+			Label of the object
+	*/
+	Dist( base::Simulation& sim, const data::Label& label = "" );
+	/// Destruction
+	virtual ~Dist();
+
+public:
+	/**
+		\brief Set seed for the random number generators
+		\param n
+			new seed
+
+		The new seed will be used for generating
+		new random numbers.
+
+		\warning The quality of the generated random numbers
+		depends on the selected seed!
+	*/
+	virtual void setSeed( int n = 0 );
+
+	/**
+		\brief Get start seed
+
+		This function returns the start seed of
+		the random number generator.
+	*/
+	unsigned long getSeed();
+
+protected:
+	/**
+		\brief Get new random number
+
+		This function returns a new random number. It
+		is used by derived classes.
+	*/
+	double getSample();
+
+private:
+	DistContext& context;
+	unsigned long u;
+	unsigned long ustart;
+	unsigned int antithetics;
+};
+
+} } // namespace odemx::random
+
+#endif
diff --git a/odemx-lite/include/odemx/random/DistContext.h b/odemx-lite/include/odemx/random/DistContext.h
new file mode 100644
index 0000000000000000000000000000000000000000..22aacf1a528539e89a196d91f91ce92af5f62fb2
--- /dev/null
+++ b/odemx-lite/include/odemx/random/DistContext.h
@@ -0,0 +1,121 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file DistContext.h
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Declaration of odemx::random::DistContext
+ */
+
+#ifndef ODEMX_RANDOM_DISTCONTEXT_INCLUDED
+#define ODEMX_RANDOM_DISTCONTEXT_INCLUDED
+
+namespace odemx {
+namespace random {
+
+// forward declaration
+class Dist;
+
+extern const unsigned long zyqmodulo;
+
+/** \class DistContext
+
+	\ingroup random
+
+	\author Ralf Gerstenberger
+
+	\brief %DistContext stores global data for Dist.
+
+	The random number generator (RNG) Dist does need some 'global'
+	data for generating independent random numbers. These data are stored
+	in %DistContext.
+
+	\warning The RNG's in the same DistContext are independent
+	from one another (within the limits of the RNG in Dist). Those RNG's
+	in different DistContexts are NOT independent. Without changing the
+	seed manually one will get the same sequence of random numbers in
+	every DistContext!
+
+	\since 1.0
+*/
+class DistContext
+{
+public:
+	/**
+		\brief Construction
+	*/
+	DistContext ();
+	/// Destruction
+	virtual ~DistContext();
+
+	/**
+		\brief Set start seed for new RNG's
+		\param n
+			new seed
+
+		The new seed will be used for the initialization
+		of new RNG's in this context. Choosing a good seed
+		is not trivial. The one used as default is known
+		to be sufficient for simulations.
+
+		\warning
+			The quality of the random numbers
+			depends on the selected seed!
+	*/
+	void setSeed( int n = 0 );
+
+protected:
+	friend class Dist;
+
+	/**
+		\brief Get current start seed
+
+		This function returns the current seed without
+		generating a new seed value. The returned value
+		was used for the last created RNG in this context.
+
+		\sa getNextSeed()
+	*/
+	unsigned long getSeed();
+
+	/**
+		\brief Get start seed for a new RNG
+
+		This function returns a new seed. The
+		seed is generated by a random number generator
+		different from the one used for ordinary random
+		numbers. That is why the created random number
+		generators in one %DistContext are independent from
+		one another.
+	*/
+	unsigned long getNextSeed();
+
+private:
+	unsigned long zyqSeed_;
+
+	/**
+		\brief generate next start seed
+	*/
+	void computeNextSeed();
+};
+
+} } // namespace odemx::random
+
+#endif /* ODEMX_RANDOM_DISTCONTEXT_INCLUDED */
diff --git a/odemx-lite/include/odemx/random/Draw.h b/odemx-lite/include/odemx/random/Draw.h
new file mode 100644
index 0000000000000000000000000000000000000000..6495c5906600df829155d5f87cda1a06597857c4
--- /dev/null
+++ b/odemx-lite/include/odemx/random/Draw.h
@@ -0,0 +1,87 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file Draw.h
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Declaration of odemx::random::Draw
+ */
+
+#ifndef ODEMX_RANDOM_DRAW_INCLUDED
+#define ODEMX_RANDOM_DRAW_INCLUDED
+
+#include <odemx/random/DiscreteDist.h>
+
+namespace odemx {
+namespace random {
+
+/** \class Draw
+
+	\ingroup idist
+
+	\author Ralf Gerstenberger
+
+	\brief Random series of 0 and 1
+
+	\note Draw from ODEM
+
+	\note supports Report
+
+	Draw provides a random series of 1 and 0. The
+	probability of the 1 against a 0 is set in the
+	constructor.
+
+	\since 1.0
+*/
+class Draw
+:	public DiscreteDist
+{
+public:
+
+	/**
+		\brief Construction for user-defined DistContext (i.e. Simulation)
+		\param title
+			Label of the generator
+		\param c
+			pointer to DistContext object
+		\param da
+			probability of a 1 against a 0
+
+		The parameter \c da defines the probability
+		of a 1 against a 0.
+	*/
+	Draw( base::Simulation& sim, const data::Label& label, double probability );
+
+	/// Destruction
+	virtual ~Draw();
+
+	/// Get next random number
+	virtual int sample();
+
+	/// Get parameter \c da
+	double getProbability();
+
+protected:
+	double probability_;
+};
+
+} } // namespace odemx::random
+
+#endif /* ODEMX_RANDOM_DRAW_INCLUDED */
diff --git a/odemx-lite/include/odemx/random/Erlang.h b/odemx-lite/include/odemx/random/Erlang.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e0974e1dc01047e548150937ef44812d14ca7db
--- /dev/null
+++ b/odemx-lite/include/odemx/random/Erlang.h
@@ -0,0 +1,87 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file Erlang.h
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Declaration of odemx::random::Erlang
+ */
+
+#ifndef ODEMX_RANDOM_ERLANG_INCLUDED
+#define ODEMX_RANDOM_ERLANG_INCLUDED
+
+#include <odemx/random/ContinuousDist.h>
+
+namespace odemx {
+namespace random {
+
+/** \class Erlang
+
+	\ingroup rdist
+
+	\author Ralf Gerstenberger
+
+	\brief %Erlang distribution of random numbers
+
+	\note Erlang from ODEM
+
+	\note supports Report
+
+	Erlang provides a series of Erlang-distributed
+	random numbers. The parameters are set in the
+	constructor.
+
+	\since 1.0
+*/
+class Erlang
+:	public ContinuousDist
+{
+public:
+
+	/**
+		\brief Construction with user-defined DistContext (i.e. Simulation)
+		\param label
+			Label of the generator
+		\param c
+			Pointer to DistContext object
+		\param ea rate, the larger, the more spread out the distribution
+		\param eb shape, affects the shape of the distribution
+	*/
+	Erlang( base::Simulation& sim, const data::Label& label, double rate, int shape );
+
+	/// Destruction
+	virtual ~Erlang();
+
+	/// Get next random number
+	virtual double sample();
+
+	/// Get parameter a
+	double getRate();
+	/// Get parameter b
+	int getShape();
+
+protected:
+	double rate_;
+	int    shape_;
+};
+
+} } // namespace odemx::random
+
+#endif /* ODEMX_RANDOM_ERLANG_INCLUDED */
diff --git a/odemx-lite/include/odemx/random/NegativeExponential.h b/odemx-lite/include/odemx/random/NegativeExponential.h
new file mode 100644
index 0000000000000000000000000000000000000000..8deaf4f6efddbeecc12d5197ba17e32c9840667c
--- /dev/null
+++ b/odemx-lite/include/odemx/random/NegativeExponential.h
@@ -0,0 +1,83 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file NegativeExponential.h
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Declaration of odemx::random::NegativeExponential
+ */
+
+#ifndef ODEMX_RANDOM_NEGATIVEEXPONENTIAL_INCLUDED
+#define ODEMX_RANDOM_NEGATIVEEXPONENTIAL_INCLUDED
+
+#include <odemx/random/ContinuousDist.h>
+
+namespace odemx {
+namespace random {
+
+/** \class NegativeExponential
+
+	\ingroup rdist
+
+	\author Ralf Gerstenberger
+
+	\brief Negative exponential distribution of random numbers
+
+	\note NegativeExponential from ODEM
+
+	\note supports Report
+
+	NegativeExponential provides a series of negative exponential
+	distributed random numbers.
+
+	\since 1.0
+*/
+class NegativeExponential
+:	public ContinuousDist
+{
+public:
+
+	/**
+		\brief Construction with user-defined DistContext (i.e. Simulation)
+		\param label
+			Label of the generator
+		\param c
+			pointer to DistContext object
+		\param na
+			inverse mean (expected) value, meaning <tt>1 / na</tt> will be used
+	*/
+	NegativeExponential( base::Simulation& sim, const data::Label& label, double inverseMean );
+
+	/// Destruction
+	virtual ~NegativeExponential();
+
+	/// Get next random number
+	virtual double sample();
+
+	/// Get parameter \c na
+	double getInverseMean();
+
+protected:
+	double inverseMean_;
+};
+
+} } // namespace odemx::random
+
+#endif /* ODEMX_RANDOM_NEGATIVEEXPONENTIAL_INCLUDED */
diff --git a/odemx-lite/include/odemx/random/Normal.h b/odemx-lite/include/odemx/random/Normal.h
new file mode 100644
index 0000000000000000000000000000000000000000..7986c0affe49ec84a757f61bb1817ea5b34a614e
--- /dev/null
+++ b/odemx-lite/include/odemx/random/Normal.h
@@ -0,0 +1,99 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file Normal.h
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Declaration of odemx::random::Normal
+ */
+
+#ifndef ODEMX_RANDOM_NORMAL_INCLUDED
+#define ODEMX_RANDOM_NORMAL_INCLUDED
+
+#include <odemx/random/ContinuousDist.h>
+
+namespace odemx {
+namespace random {
+
+/** \class Normal
+
+	\ingroup rdist
+
+	\author Ralf Gerstenberger
+
+	\brief %Normal distribution of random numbers
+
+	\note Normal from ODEM
+
+	\note supports Report
+
+	Normal provides a series of normal ('Gauss')
+	distributed random numbers. The parameter mean
+	and deviation are set in the constructor.
+
+	\since 1.0
+*/
+class Normal
+:	public ContinuousDist
+{
+public:
+
+	/**
+		\brief Construction with user-defined DistContext (i.e. Simulation)
+		\param label
+			Label of the generator
+		\param c
+			pointer to DistContext object
+		\param na
+			a mean-value
+		\param nb
+			b deviation
+
+		The parameter \c na and \c nb define the mean-value
+		and the deviation of the normal distribution generated
+		by %Normal.
+	*/
+	Normal( base::Simulation& sim, const data::Label& label, double mean,
+			double deviation );
+
+	/// Destruction
+	virtual ~Normal();
+
+	/// Get next random number
+	virtual double sample();
+
+	/// Get parameter na
+	double getMean();
+	/// Get parameter nb
+	double getDeviation();
+
+private:
+	double zyqu;
+	double zyqv;
+	bool zyqeven;
+
+protected:
+	double mean_;
+	double deviation_;
+};
+
+} } // namespace odemx::random
+
+#endif /* ODEMX_RANDOM_NORMAL_INCLUDED */
diff --git a/odemx-lite/include/odemx/random/Poisson.h b/odemx-lite/include/odemx/random/Poisson.h
new file mode 100644
index 0000000000000000000000000000000000000000..f1e3d28aaea41d12f2f4deb4338d86ae150aa211
--- /dev/null
+++ b/odemx-lite/include/odemx/random/Poisson.h
@@ -0,0 +1,89 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file Poisson.h
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Declaration of odemx::random::Poisson
+ */
+
+#ifndef ODEMX_RANDOM_POISSON_INCLUDED
+#define ODEMX_RANDOM_POISSON_INCLUDED
+
+#include <odemx/random/DiscreteDist.h>
+
+namespace odemx {
+namespace random {
+
+/** \class Poisson
+
+	\ingroup idist
+
+	\author Ralf Gerstenberger
+
+	\brief %Poisson distributed discrete random numbers
+
+	\note Poisson from ODEM
+
+	\note supports Report
+
+	Poisson provides a series of Poisson-distributed
+	discrete random numbers. The parameter \c pa
+	divergence is set in the constructor.
+
+	\since 1.0
+*/
+class Poisson
+:	public DiscreteDist
+{
+public:
+
+	/**
+		\brief Construction for user-defined DistContext (i.e. Simulation)
+		\param title
+			Label of the generator
+		\param c
+			pointer to DistContext object
+		\param pa
+			mean value
+
+		The parameter pa defines the mean value
+		of the Poisson-distribution generated by
+		this random number generator.
+	*/
+	Poisson(  base::Simulation& sim, const data::Label& label, double mean );
+
+	/// Destruction
+	virtual ~Poisson();
+
+	/// Get next random number
+	virtual int sample();
+
+	/// Get parameter pa
+	double getMean();
+
+protected:
+	double mean_;
+};
+
+} } // namespace odemx::random
+
+
+#endif /* ODEMX_RANDOM_POISSON_INCLUDED */
diff --git a/odemx-lite/include/odemx/random/RandomInt.h b/odemx-lite/include/odemx/random/RandomInt.h
new file mode 100644
index 0000000000000000000000000000000000000000..8ee129ab94e3e5171414b5f84d8b8739f736d0cf
--- /dev/null
+++ b/odemx-lite/include/odemx/random/RandomInt.h
@@ -0,0 +1,96 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file RandomInt.h
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Declaration of odemx::random::RandomInt
+ */
+
+#ifndef ODEMX_RANDOM_RANDOMINT_INCLUDED
+#define ODEMX_RANDOM_RANDOMINT_INCLUDED
+
+#include <odemx/random/DiscreteDist.h>
+
+namespace odemx {
+namespace random {
+
+/** \class RandomInt
+
+	\ingroup idist
+
+	\author Ralf Gerstenberger
+
+	\brief %Uniform distributed discrete random numbers
+
+	\note RandomInt from ODEM
+
+	\note supports Report
+
+	RandomInt provides a series of uniformly distributed
+	integer random numbers in the interval [a, b). The
+	parameters a and b are set in the constructor.
+
+	\since 1.0
+*/
+class RandomInt
+:	public DiscreteDist
+{
+public:
+
+	/**
+		\brief Construction for user-defined DistContext (i.e. Simulation)
+		\param title
+			Label of the generator
+		\param c
+			pointer to DistContext object
+		\param ra
+			lower bound - a
+		\param rb
+			upper bound - b
+
+		The parameters a and b define the interval [a, b)
+		of the uniformly distributed random numbers generated
+		by %RandomInt.
+	*/
+	RandomInt( base::Simulation& sim, const data::Label& label, int lowerBound, int upperBound );
+
+	// Destruction
+	virtual ~RandomInt();
+
+	/// Get next random number
+	virtual int sample();
+
+	/// Get parameter a
+	int getLowerBound();
+	/// Get parameter b
+	int getUpperBound();
+
+protected:
+	int lowerBound_;
+	int upperBound_;
+
+private:
+	double zyqSpan_;
+};
+
+} } // namespace odemx::random
+
+#endif /* ODEMX_RANDOM_RANDOMINT_INCLUDED */
diff --git a/odemx-lite/include/odemx/random/Uniform.h b/odemx-lite/include/odemx/random/Uniform.h
new file mode 100644
index 0000000000000000000000000000000000000000..bcd41a100d5a0aa676f30700aeeb691a52c2c15e
--- /dev/null
+++ b/odemx-lite/include/odemx/random/Uniform.h
@@ -0,0 +1,96 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file Uniform.h
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Declaration of odemx::random::Uniform
+ */
+
+#ifndef ODEMX_RANDOM_UNIFORM_INCLUDED
+#define ODEMX_RANDOM_UNIFORM_INCLUDED
+
+#include <odemx/random/ContinuousDist.h>
+
+namespace odemx {
+namespace random {
+
+/** \class Uniform
+
+	\ingroup rdist
+
+	\author Ralf Gerstenberger
+
+	\brief %Uniform distribution of random numbers
+
+	\note Uniform from ODEM
+
+	\note supports Report
+
+	Uniform provides a series of uniform
+	distributed random numbers in the interval [a, b).
+	The parameters a and b are set in the constructor.
+
+	\since 1.0
+*/
+class Uniform
+:	public ContinuousDist
+{
+public:
+
+	/**
+		\brief Construction with user-defined DistContext (i.e. Simulation)
+		\param label
+			Label of the generator
+		\param c
+			pointer to DistContext object
+		\param ua
+			lower bound a
+		\param ub
+			upper bound b
+
+		The parameters \c ua and \c ub define the interval
+		of the distribution.
+	*/
+	Uniform( base::Simulation& sim, const data::Label& label, double lowerBound,
+			double upperBound );
+
+	/// Destruction
+	virtual ~Uniform();
+
+	/// Get next random number
+	virtual double sample();
+
+	/// Get parameter a
+	double getLowerBound();
+	/// Get parameter b
+	double getUpperBound();
+
+private:
+	double  zyqSpan_;
+
+protected:
+	double lowerBound_;
+	double upperBound_;
+};
+
+} } // namespace odemx::random
+
+#endif /* ODEMX_RANDOM_UNIFORM_INCLUDED */
diff --git a/odemx-lite/include/odemx/setup.h b/odemx-lite/include/odemx/setup.h
new file mode 100644
index 0000000000000000000000000000000000000000..1973cffdcce16e8817db9448d7adbfe7f6863701
--- /dev/null
+++ b/odemx-lite/include/odemx/setup.h
@@ -0,0 +1,114 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file odemx/setup.h
+ * @author Ronald Kluth
+ * @date created at 2009/08/02
+ * @brief Contains preprocessor definitions controlling ODEMx build settings
+ * @since 3.0
+ */
+
+#ifndef ODEMX_SETUP_INCLUDED
+#define ODEMX_SETUP_INCLUDED
+
+// NOTE: All defines in this file are guarded with #ifndef in order to avoid
+// multiple definitions of the same macro. This can happen if the macro is
+// given via compiler command line switch, for example.
+
+/**
+ * @name Build Parameters
+ * @brief Default build parameters for ODEMx and dependent projects
+ * @{
+ */
+
+/**
+ * @def ODEMX_USE_CONTINUOUS
+ * @brief Enables continuous processes and influences the type of SimTime
+ *
+ * The default type used for ODEMx @c SimTime is <tt>long long</tt>. However,
+ * continuous processes require floating point precision. Therefore, enabling
+ * this feature will switch the type used for @c SimTime to @c double.
+ */
+#ifndef ODEMX_USE_CONTINUOUS
+#define ODEMX_USE_CONTINUOUS
+#endif
+
+/**
+ * @def ODEMX_USE_TRACE
+ * @brief Enables internal state logging of ODEMx classes
+ *
+ * This define allows users to get detailed logging information about all state
+ * changes occurring within ODEMx classes. This can significantly ease the
+ * debugging of simulation models. As soon as the simulator is working properly,
+ * the logging output can be reduced to show only experiment-related data by
+ * disabling internal traces. This also reduces runtime overhead.
+ */
+#ifndef ODEMX_USE_TRACE
+//#define ODEMX_USE_TRACE
+#endif
+
+/**
+ * @def ODEMX_USE_OBSERVATION
+ * @brief Enables the observation feature of ODEMx
+ *
+ * Observation is an object-object relation with one object taking the role of
+ * the observable and another taking the role of the observer. An observable
+ * can inform multiple registered observers of its state changes. This define
+ * mainly reduces runtime overhead when the feature is not needed.
+ */
+#ifndef ODEMX_USE_OBSERVATION
+//#define ODEMX_USE_OBSERVATION
+#endif
+
+/**
+ * @def ODEMX_USE_ODBC
+ * @brief Enables logging to external databases via ODBC
+ *
+ * ODEMx has the capability to write log records to databases. The default
+ * setup enables the use of SQLite database files. This define
+ * enables the use of external databases by using an ODBC connector. However,
+ * compiling ODEMx with this option requires ODBC development headers to be
+ * installed on the host system.
+ */
+#ifndef ODEMX_USE_ODBC
+//#define ODEMX_USE_ODBC
+#endif
+
+#ifndef ODEMX_USE_MACRO_COUNTER
+//#define ODEMX_USE_MACRO_COUNTER
+#endif
+//@}
+
+//------------------------------------------------------------------dependencies
+
+// Continuous requires observation because ContuTrace is an observer type
+#ifdef ODEMX_USE_CONTINUOUS
+	#ifndef ODEMX_USE_OBSERVATION
+	#define ODEMX_USE_OBSERVATION
+	#endif
+#endif /* ODEMX_USE_CONTINUOUS */
+
+// Tracing checks the boolean value of ODEMX_TRACE_ENABLED in a condition
+#ifdef ODEMX_USE_TRACE
+	#define ODEMX_TRACE_ENABLED true
+#else
+	#define ODEMX_TRACE_ENABLED false
+#endif /* ODEMX_USE_TRACE */
+
+#endif /* ODEMX_SETUP_INCLUDED */
diff --git a/odemx-lite/include/odemx/statistics/Accumulate.h b/odemx-lite/include/odemx/statistics/Accumulate.h
new file mode 100644
index 0000000000000000000000000000000000000000..11221e9fc4a7f51980fdfc68d5f8d8d4ae5d3dd4
--- /dev/null
+++ b/odemx-lite/include/odemx/statistics/Accumulate.h
@@ -0,0 +1,122 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Accumulate.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/01
+ * @brief Declaration of odemx::statistics::Accumulate
+ * @sa Accumulate.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_STATS_ACCUMULATE_INCLUDED
+#define ODEMX_STATS_ACCUMULATE_INCLUDED
+
+#include <odemx/base/SimTime.h>
+#include <odemx/statistics/Tab.h>
+
+namespace odemx {
+namespace statistics {
+
+/** \class Accumulate
+
+	\ingroup statistics
+
+	\author Ralf Gerstenberger
+
+	\brief Compute statistics about provided data
+
+	Accum computes minimum, maximum, mean-value,
+	standard deviation and number of samples (size) according to
+	the simulation time (see Tally).
+
+	Time weighted mean values are computed according to two
+	different approximation stategies:
+
+	\c Accum::stepwise: assumes constant values between samples
+
+		A value of 1 held for 4 time units, followed by a
+		value of 0 for 1 time unit will result in a mean
+		value of (1*4 + 0*1)/5 = 0.8 .
+
+	\c Accum::linear: assumes linear increase/decrease of values
+	between samples
+
+		A value of 1 held for 4 time units, followed by a
+		value of 0 for 1 time unit will result in a mean
+		value of (1*4/2 + 0*1)/5 = 0.4 .
+
+	\note The approximation strategy can be set with the second constructor
+	parameter, which by default is set to \c stepwise.
+
+	\since 1.0
+*/
+class Accumulate
+:	public Tab
+{
+public:
+	/// Approximation strategy
+	enum Approx
+	{
+		stepwise,
+		linear
+	};
+
+	/// Construction
+	Accumulate( base::Simulation& sim, const data::Label& label, Approx app = stepwise );
+	/// Destruction
+	virtual ~Accumulate();
+
+	/// Update statistics (considering time)
+	virtual void update( base::SimTime time, double value );
+	/// Reset statistics
+	virtual void reset( base::SimTime time );
+	/// Get a count of zero-updates
+	std::size_t getZeros() const;
+	/// Get minimum
+	double getMin() const;
+	/// Get maximum
+	double getMax() const;
+	/// Get average
+	double getMean() const;
+	/// Get average (considering time)
+	double getWeightedMean() const;
+	/// Get deviation
+	double getStandardDeviation() const;
+	/// Get deviation (considering time)
+	double getWeightedStandardDeviation() const;
+	/// Implementation of ReportProducer interface
+	virtual void report( data::Report& report );
+protected:
+	Approx approximation_;
+	base::SimTime startTime_;
+	base::SimTime lastTime_;
+	double lastValue_;
+	std::size_t zeros_;
+	double minValue_;
+	double maxValue_;
+	double sum_;
+	double sumSq_;
+	double sumWeight_;
+	double sumSqWeight_;
+};
+
+} } // namespace odemx::statistics
+
+#endif /* ODEMX_STATS_ACCUMULATE_INCLUDED */
diff --git a/odemx-lite/include/odemx/statistics/Count.h b/odemx-lite/include/odemx/statistics/Count.h
new file mode 100644
index 0000000000000000000000000000000000000000..22e5d97d2076e94e9b45a30e57ab59b6ebfebd22
--- /dev/null
+++ b/odemx-lite/include/odemx/statistics/Count.h
@@ -0,0 +1,76 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Count.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/01
+ * @brief Declaration of odemx::statistics::Count
+ * @sa Count.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_STATS_COUNT_INCLUDED
+#define ODEMX_STATS_COUNT_INCLUDED
+
+#include <odemx/statistics/Tab.h>
+
+namespace odemx {
+namespace statistics {
+
+/** \class Count
+
+	\ingroup statistics
+
+	\author Ralf Gerstenberger
+
+	\brief Counter
+
+	Count is counting integers. It can be used also to
+	calculate an integer sum of all provided numbers.
+	To increase the counter use update().
+
+	\since 1.0
+*/
+class Count
+:	public Tab
+{
+public:
+	/// Construction with user-defined simulation context
+	Count( base::Simulation& sim, const data::Label& label );
+
+	/// Destruction
+	virtual ~Count();
+
+	/// Update counter
+	void update( int value = 1 );
+	/// Reset counter and statistics
+	virtual void reset( base::SimTime time );
+	/// Get current counter value
+	int getValue() const;
+	/// Implementation of Reporter interface
+	virtual void report( data::Report& report );
+
+private:
+	/// The counter value
+	int count_;
+};
+
+} } // namespace odemx::statistics
+
+#endif /* ODEMX_STATS_COUNT_INCLUDED */
diff --git a/odemx-lite/include/odemx/statistics/Histogram.h b/odemx-lite/include/odemx/statistics/Histogram.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6d7bffe05d4ca024b21b4e468948a802841a3c3
--- /dev/null
+++ b/odemx-lite/include/odemx/statistics/Histogram.h
@@ -0,0 +1,100 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Histogram.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/01
+ * @brief Declaration of odemx::statistics::Histogram
+ * @sa Histogram.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_STATS_HISTOGRAM_INCLUDED
+#define ODEMX_STATS_HISTOGRAM_INCLUDED
+
+#include <odemx/statistics/Tally.h>
+
+#include <vector>
+
+namespace odemx {
+namespace statistics {
+
+/** \class Histogram
+
+	\ingroup statistics
+
+	\author Ronald Kluth
+
+	\brief Statistical analysis plus histogram
+
+	Histogram computes a statistical analysis like Tally
+	and also generates histogram data.
+
+	\since 1.0
+*/
+class Histogram
+:	public Tally
+{
+public:
+
+	struct Cell
+	{
+		Cell(): count( 0 ), lowerBound( 0 ), upperBound( 0 ), percentage( 0 ) {}
+
+		std::size_t count;
+		double lowerBound;
+		double upperBound;
+		double percentage;
+	};
+
+	typedef std::vector< Cell > CellVec;
+
+	/// Construction with user-defined simulation context
+	Histogram( base::Simulation& sim, const data::Label& label,
+			double lowerBound, double upperBound, unsigned int cellCount );
+	/// Destruction
+	virtual ~Histogram();
+
+	/// Update statistics
+	virtual void update( double value );
+	/// Reset statistics
+	virtual void reset( base::SimTime time );
+	/// Get histogram data
+	const CellVec& getData();
+	/// Implementation of Reporter interface
+	virtual void report( data::Report& report );
+
+private:
+	/// The lower bound for histogram values
+	double lowerBound_;
+	/// The upper bound for histogram values
+	double upperBound_;
+	/// The number of categories for values
+	unsigned int cellCount_;
+	/// The interval width of one value category
+	double cellWidth_;
+	/// The maximum index of the data vector
+	int maxCellIndex_;
+	/// The data vector
+	CellVec cellData_;
+};
+
+} } // namespace odemx::statistics
+
+#endif /* ODEMX_STATS_HISTOGRAM_INCLUDED */
diff --git a/odemx-lite/include/odemx/statistics/Regression.h b/odemx-lite/include/odemx/statistics/Regression.h
new file mode 100644
index 0000000000000000000000000000000000000000..cf7ad0b2f98077923b4f2b38cf392f6fdd3218b7
--- /dev/null
+++ b/odemx-lite/include/odemx/statistics/Regression.h
@@ -0,0 +1,123 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Regression.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/01
+ * @brief Declaration of odemx::statistics::Regression
+ * @sa Regression.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_STATS_REGRESSION_INCLUDED
+#define ODEMX_STATS_REGRESSION_INCLUDED
+
+#include <odemx/statistics/Tab.h>
+
+#include <vector>
+
+namespace odemx {
+namespace statistics {
+
+/** \class Regression
+
+	\ingroup statistics
+
+	\author Ralf Gerstenberger
+
+	\brief %Regression analysis
+
+	\note Regression from ODEM
+	\note Regression supports Report
+
+	Regression computes the linear correlation between
+	provided data X and Y by computing two mean values,
+	whose intersection is the center of rotation, and a slope.
+
+	\since 1.0
+*/
+class Regression
+:	public Tab
+{
+public:
+	/// Construction with user-defined simulation context
+	Regression( base::Simulation& sim, const data::Label& label );
+	/// Destruction
+	virtual ~Regression();
+
+	/// Update statistics
+	void update( double valueX, double valueY );
+	/// Reset statistics
+	virtual void reset( base::SimTime time );
+	/// Check if sufficient data for a regression analysis has been accumulated
+	bool hasSufficientData() const;
+	/// get mean of x update values
+	double getXMean() const;
+	/// get mean of y update values
+	double getYMean() const;
+	///
+	double getDx() const;
+	double getDy() const;
+
+	/**
+	 * @brief Get standard deviation of all residuals
+	 *
+	 * @note Residuals describe the distance of the measured value from
+	 * the estimated linear regression function.
+	 */
+	double getResidualStandardDeviation() const;
+
+	/**
+	 * @brief Get the regression coefficient
+	 *
+	 * @note The regression coefficient describes the slope of the linear
+	 * regression function.
+	 */
+	double getEstimatedRegressionCoefficient() const;
+
+	/// intercept helper value ???
+	double getIntercept() const;
+
+	/**
+	 * @brief Get standard deviation of the regression coefficient estimates
+	 */
+	double getRegressionCoefficientStandardDeviation() const;
+
+	/**
+	 * @brief Get the correlation coefficient
+	 *
+	 * The correlation coefficient is a measure for the relationship of
+	 * x and y. \c 0 means no linear correlation exists, while \c 1 means
+	 * there is a strong linear correlation between these variables.
+	 */
+	double getCorrelationCoefficient() const;
+	/// Implementation of Reporter interface
+	virtual void report( data::Report& report );
+
+protected:
+	double sumX_;
+	double sumY_;
+	double sumSqX_;
+	double sumXMulY_;
+	double sumSqY_;
+};
+
+} } // namespace odemx::statistics
+
+#endif /* ODEMX_STATS_REGRESSION_INCLUDED */
diff --git a/odemx-lite/include/odemx/statistics/Sum.h b/odemx-lite/include/odemx/statistics/Sum.h
new file mode 100644
index 0000000000000000000000000000000000000000..e907825a3b7c07270d711fbf70642dd6a8d5ebe6
--- /dev/null
+++ b/odemx-lite/include/odemx/statistics/Sum.h
@@ -0,0 +1,74 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Sum.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/01
+ * @brief Declaration of odemx::statistics::Sum
+ * @sa Sum.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_STATS_SUM_INCLUDED
+#define ODEMX_STATS_SUM_INCLUDED
+
+#include <odemx/statistics/Tab.h>
+
+namespace odemx {
+namespace statistics {
+
+/** \class Sum
+
+	\ingroup statistics
+
+	\author Ralf Gerstenberger
+
+	\brief Sum
+
+	Sum is used to compute 'double' sums. Use update()
+	to change the sum.
+
+	\since 1.0
+*/
+class Sum
+:	public Tab
+{
+public:
+	/// Construction with user-defined simulation context
+	Sum( base::Simulation& sim, const data::Label& label );
+	/// Destruction
+	virtual ~Sum();
+
+	/// Update sum
+	void update( double value = 1.0 );
+	/// Reset sum and statistics
+	virtual void reset( base::SimTime time );
+	/// Get current value
+	double getValue() const;
+	/// Implementation of Reporter interface
+	virtual void report( data::Report& report );
+
+private:
+	/// The computed sum
+	double sum_;
+};
+
+} } // namespace odemx::statistics
+
+#endif /* ODEMX_STATS_SUM_INCLUDED */
diff --git a/odemx-lite/include/odemx/statistics/Tab.h b/odemx-lite/include/odemx/statistics/Tab.h
new file mode 100644
index 0000000000000000000000000000000000000000..37414528ca762f5fa561d8c69bc09b11f04c2c2d
--- /dev/null
+++ b/odemx-lite/include/odemx/statistics/Tab.h
@@ -0,0 +1,76 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Tab.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/01
+ * @brief Declaration of odemx::statistics::Tab
+ * @sa Tab.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_STATS_TAB_INCLUDED
+#define ODEMX_STATS_TAB_INCLUDED
+
+#include <odemx/base/SimTime.h>
+#include <odemx/data/ReportProducer.h>
+
+#include <cstddef> // size_t
+
+namespace odemx {
+namespace statistics {
+
+/** \class Tab
+
+	\ingroup statistics
+
+	\author Ralf Gerstenberger
+
+	\brief The base for statistics-computing classes.
+
+	\since 1.0
+*/
+class Tab
+:	public data::ReportProducer
+{
+public:
+	/// Construction with user-defined simulation context
+	Tab( base::Simulation& sim, const data::Label& label );
+	/// Destruction
+	virtual ~Tab();
+
+	/// Update usage counter
+	void update();
+	/// Reset usage counter and store reset time
+	virtual void reset( base::SimTime time );
+	/// Get usage counter
+	std::size_t getUpdateCount() const;
+	/// Get last reset time
+	base::SimTime getResetTime() const;
+
+protected:
+	/// The usage counter
+	std::size_t updateCount_;
+	/// The last reset time
+	base::SimTime resetTime_;
+};
+
+} } // namespace odemx::statistics
+
+#endif /*ODEMX_TAB_INCLUDED*/
diff --git a/odemx-lite/include/odemx/statistics/Tally.h b/odemx-lite/include/odemx/statistics/Tally.h
new file mode 100644
index 0000000000000000000000000000000000000000..8d72c09dad8960bcd3d0a92260cd8b8bcb875f87
--- /dev/null
+++ b/odemx-lite/include/odemx/statistics/Tally.h
@@ -0,0 +1,92 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Tally.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/01
+ * @brief Declaration of odemx::statistics::Tally
+ * @sa Tally.cpp
+ * @since 3.0
+ */
+
+#ifndef ODEMX_STATS_TALLY_INCLUDED
+#define ODEMX_STATS_TALLY_INCLUDED
+
+#include <odemx/statistics/Tab.h>
+
+namespace odemx {
+namespace statistics {
+
+/** \class Tally
+
+	\ingroup statistics
+
+	\author Ralf Gerstenberger
+
+	\brief Compute statistics about provided data
+
+	Tally computes minimum, maximum, mean-value,
+	standard deviation and number of samples (size)
+	independent from simulation time (see Accum).
+
+	The average value is computed as follows:
+	A value of 1 for 4 time units together with a value
+	of 0 for 1 time unit will result in a mean value of
+	(1+0)/2 = 0.5.
+
+	\since 1.0
+*/
+class Tally
+:	public Tab
+{
+public:
+	/// Construction with user-defined simulation context
+	Tally( base::Simulation& sim, const data::Label& label );
+	/// Destruction
+	virtual ~Tally();
+
+	/// Update statistics
+	virtual void update( double value );
+	/// Reset statistics
+	virtual void reset( base::SimTime time );
+	/// Get minimum
+	double getMin() const;
+	/// Get maximum
+	double getMax() const;
+	/// Get average
+	double getMean() const;
+	/// Get standard deviation
+	double getStandardDeviation() const;
+	/// Implementation of Reporter interface
+	virtual void report( data::Report& report );
+
+protected:
+	/// The minimum of all update values
+	double minValue_;
+	/// The maximum of all update values
+	double maxValue_;
+	/// The sum of all update values since last reset
+	double sum_;
+	/// The sum of the squares of all update values since last reset
+	double sumSq_;
+};
+
+} } // namespace odemx::statistics
+
+#endif /* ODEMX_STATS_TALLY_INCLUDED */
diff --git a/odemx-lite/include/odemx/synchronization/Bin.h b/odemx-lite/include/odemx/synchronization/Bin.h
new file mode 100644
index 0000000000000000000000000000000000000000..d8cc40d44d6a3de7b0bbfe5e19fb3b5a0c675d9b
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/Bin.h
@@ -0,0 +1,178 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Bin.h
+
+	\author Ralf Gerstenberger
+
+	\date created at 2002/03/26
+
+	\brief Declaration of odemx::synchronization::Bin and observer
+
+	\sa Bin.cpp
+
+	\since 1.0
+*/
+
+#ifndef ODEMX_BIN_INCLUDED
+#define ODEMX_BIN_INCLUDED
+
+#include <odemx/base/SimTime.h>
+#include <odemx/data/Producer.h>
+#include <odemx/synchronization/Queue.h>
+#include <odemx/data/Observable.h>
+
+namespace odemx {
+
+// forward declarations
+namespace base {
+class Process;
+class Simulation;
+}
+
+namespace synchronization {
+
+class BinObserver;
+
+/** \class Bin
+
+	\ingroup synch
+
+	\author Ralf Gerstenberger
+
+	\brief %Bin is a single bounded (number of token greater or
+	equal to zero) token abstract resource.
+
+	\note Bin supports Observation
+	\note Bin supports Trace
+	\note Bin supports Report
+
+	Bin is a low bounded (token number >= 0) token abstract resource
+	for synchronising Process objects. A process is blocked in take()
+	if the requested number of token is greater than the available
+	number of token. It is reactivated when enough token are given (back)
+	to the resource. If multiple processes are waiting for reactivation
+	process-priority and FIFO-strategy are used to choose the process.
+	Bin is generally used for producer and consumer synchronisation.
+
+	\since 1.0
+*/
+class Bin
+:	public data::Producer
+,	public data::Observable< BinObserver >
+{
+public:
+
+	/**
+		\brief Construction for user-defined Simulation
+		\param s
+			pointer to Simulation object
+		\param l
+			label for this object
+		\param startTokenNumber
+			initial number of token in Bin
+		\param o
+			initial observer
+	*/
+	Bin( base::Simulation& sim, const data::Label& label, std::size_t initialTokens,
+			BinObserver* obs = 0 );
+
+	/// Destruction
+	~Bin();
+
+	/**
+		\name Token management
+
+		@{
+	*/
+	/**
+		\brief Take \p n token
+
+		Takes \p n token from resource if possible. Otherwise
+		the current process is blocked until enough token are
+		available. If a blocked process is interrupted it is
+		reactivated and the function returns 0. Without interruption
+		take returns \p n.
+	*/
+	std::size_t take( std::size_t n );
+
+	/**
+		\brief Give \p n token
+
+		Gives \p n token to resource. Blocked process objects
+		could be activated by this call.
+	*/
+	void give( std::size_t n );
+
+	/// Number of tokens available
+	std::size_t getTokenNumber() const;
+	//@}
+
+	/// Get list of blocked processes
+	const base::ProcessList& getWaitingProcesses() const;
+
+private:
+	/// available number of tokens
+	std::size_t tokens_;
+	/// process management
+	Queue takeQueue_;
+
+	/// Helper for quick access to the current simulation time
+	base::SimTime getTime() const;
+	/// Helper for quick access to the currently running object
+	base::Sched* getCurrentSched();
+	/// Helper for quick access to the current process
+	base::Process* getCurrentProcess();
+	/// Get the label of the current context (process or simulation)
+	const data::Label& getPartner();
+};
+
+/** \interface BinObserver
+
+	\author Ralf Gerstenberger
+
+	\brief Observer for Bin-specific events.
+
+	\sa Bin
+
+	\since 1.0
+*/
+class BinObserver
+{
+public:
+	virtual ~BinObserver() {}
+
+	/// Observe construction
+	virtual void onCreate( Bin* sender ) {}
+
+	/// Observe failed attempt to take @c n tokens
+	virtual void onTakeFail( Bin* sender, std::size_t n ) {}
+	/// Observe successful attempt to take @c n tokens
+	virtual void onTakeSucceed( Bin* sender, std::size_t n ) {}
+	/// Observe return of @c n tokens
+	virtual void onGive( Bin* sender, std::size_t n ) {}
+
+	/// Observe change of the number of tokens
+	virtual void onChangeTokenNumber( Bin* sender, std::size_t oldTokenNumber,
+			std::size_t newTokenNumber ) {}
+};
+
+} } // namespace odemx::synchronization
+
+#endif
+
diff --git a/odemx-lite/include/odemx/synchronization/BinT.h b/odemx-lite/include/odemx/synchronization/BinT.h
new file mode 100644
index 0000000000000000000000000000000000000000..efe78dc8cc6ec74a414ff21debb647d30738bb18
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/BinT.h
@@ -0,0 +1,36 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file BinT.h
+ * @author Ronald Kluth
+ * @date created at 2008/02/17
+ * @brief Forwarding header for inclusion of odemx::synchronization::BinT and observer
+ * @since 2.1
+ */
+
+#ifndef ODEMX_SYNC_BIN_TEMPLATE_INCLUDED
+#define ODEMX_SYNC_BIN_TEMPLATE_INCLUDED
+
+// no namespaces here, the implementation is declared inside odemx::synchronization
+
+// template BinT header with implementation
+#include <odemx/synchronization/bin/BinTImpl.h>
+#include <odemx/synchronization/bin/BinTImpl.cpp>
+
+#endif /* ODEMX_SYNC_BIN_TEMPLATE_INCLUDED */
diff --git a/odemx-lite/include/odemx/synchronization/CondQ.h b/odemx-lite/include/odemx/synchronization/CondQ.h
new file mode 100644
index 0000000000000000000000000000000000000000..6c53e78ddbe58b24358b554635b9c05b61b51f1b
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/CondQ.h
@@ -0,0 +1,149 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file CondQ.h
+
+	\author Ralf Gerstenberger
+
+	\date created at 2002/07/11
+
+	\brief Declaration of odemx::synchronization::CondQ and observer
+
+	\sa CondQ.cpp
+
+	\since 1.0
+*/
+
+#ifndef ODEMX_CONDQ_INCLUDED
+#define ODEMX_CONDQ_INCLUDED
+
+#include <odemx/data/Producer.h>
+#include <odemx/synchronization/Queue.h>
+#include <odemx/data/Observable.h>
+
+namespace odemx {
+
+// forward declarations
+namespace base {
+class Process;
+class Sched;
+}
+
+namespace synchronization {
+
+class CondQObserver;
+
+/** \class CondQ
+
+	\ingroup synch
+
+	\author Ralf Gerstenberger
+
+	\brief %CondQ can be used to make a process wait for an
+	arbitrary condition.
+
+	\note CondQ supports Observation
+	\note CondQ supports Trace
+	\note CondQ supports Report
+
+	\since 1.0
+*/
+class CondQ
+:	public data::Producer
+,	public data::Observable< CondQObserver >
+{
+public:
+
+	/**
+		\brief Construction for user-defined Simulation
+		\param s
+			pointer to Simulation object
+		\param l
+			label of this object
+		\param o
+			initial observer
+	*/
+	CondQ( base::Simulation& sim, const data::Label& label, CondQObserver* obs = 0 );
+
+	/// Destruction
+	~CondQ();
+
+	/**
+		\name Synchronisation
+		@{
+	*/
+	/**
+		\brief Wait for cond
+
+		If the supplied condition \p cond is false the current process
+		is blocked until the condition is true and signal() was called.
+		If a blocked process is interrupted, it is reactivated and
+		the function returns false. (An interrupted process has
+		influence on the queue-statistic but not on user and waiting time
+		statistics.)
+	*/
+	bool wait( base::Condition cond );
+
+	/// Trigger condition check
+	void signal();
+	//@}
+
+	/// Get a list of blocked process objects
+	const base::ProcessList& getWaitingProcesses() const;
+
+private:
+	/// process management
+	Queue processes_;
+
+	/// Helper for quick access to the current simulation time
+	base::SimTime getTime() const;
+	/// Helper for quick access to the currently running object
+	base::Sched* getCurrentSched();
+	/// Helper for quick access to the current process
+	base::Process* getCurrentProcess();
+};
+
+/** \interface CondQObserver
+
+	\author Ralf Gerstenberger
+
+	\brief Observer for CondQ-specific events
+
+	\sa CondQ
+
+	\since 1.0
+*/
+class CondQObserver
+{
+public:
+	virtual ~CondQObserver() { }
+
+	/// Observe construction
+	virtual void onCreate( CondQ* sender ) {}
+
+	/// Observe process entering wait phase
+	virtual void onWait( CondQ* sender, base::Process* process ) {}
+	/// Observe process continuation
+	virtual void onContinue( CondQ* sender, base::Process* process ) {}
+	/// Observe triggering of the condition test
+	virtual void onSignal( CondQ* sender, base::Process* process ) {}
+};
+
+} } // namespace odemx::synchronization
+
+#endif
diff --git a/odemx-lite/include/odemx/synchronization/IMemory.h b/odemx-lite/include/odemx/synchronization/IMemory.h
new file mode 100644
index 0000000000000000000000000000000000000000..b44a3d319450245dcc2303e4ba06f0b7ecd04781
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/IMemory.h
@@ -0,0 +1,97 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file IMemory.h
+ * @author Ronald Kluth
+ * @date created at 2009/02/11
+ * @brief Declaration of interface odemx::synchronization::IMemory
+ * @since 3.0
+ */
+
+#ifndef ODEMX_IMEMORY_INCLUDED
+#define ODEMX_IMEMORY_INCLUDED
+
+#include <vector>
+
+//-----------------------------------------------------------forward declaration
+
+namespace odemx {
+
+namespace base { class Sched; }
+
+namespace synchronization {
+
+//------------------------------------------------------------header declaration
+
+/**
+ * @interface IMemory
+ * @brief Interface for process memory objects
+ *
+ * This interface declares the methods used for the implementation
+ * of memory objects.
+ */
+class IMemory
+{
+public:
+	/**
+		\brief IMemory types
+
+		%IMemory implementations can be different types of structures. When
+		a pointer to an %IMemory object is returned, it can be useful to have
+		a means of distinguishing them simply by asking for their type
+		using \p getMemoryType(). Currently timers, ports and collision
+		detection objects are supported by the library. However, users are
+		encouraged to implement IMemory or derive from Memory and
+		create a user-defined memory type.
+	*/
+	enum Type
+	{
+		TIMER,
+		PORTHEAD,
+		PORTTAIL,
+		COLLISION_DETECTION,
+		CONTROL,
+		USER_DEFINED
+	};
+
+	// implicit Default-Constructor
+	
+	/// Destruction
+	virtual ~IMemory();
+
+	/// Get the memory type as stated by enum Type
+	virtual Type getMemoryType() const = 0;
+	/// Check if a memory object is available, if so, processes get alerted
+	virtual bool isAvailable() = 0;
+	/// Wake up the remembered processes
+	virtual void alert() = 0;
+	/// Remember a process
+	virtual bool remember( base::Sched* newObject ) = 0;
+	/// Forget a process
+	virtual bool forget( base::Sched* rememberedObject ) = 0;
+	/// Forget all processes
+	virtual void eraseMemory() = 0;
+};
+
+/// Provided for convenience, used with Process::wait
+typedef std::vector< IMemory* > IMemoryVector;
+
+} } // namespace odemx::synchronization
+
+#endif /*ODEMX_IMEMORY_INCLUDED*/
diff --git a/odemx-lite/include/odemx/synchronization/Memory.h b/odemx-lite/include/odemx/synchronization/Memory.h
new file mode 100644
index 0000000000000000000000000000000000000000..56ca39bbc61b8b05b441f5ad5167080a8f6689c4
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/Memory.h
@@ -0,0 +1,266 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002 - 2008 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Memory.h
+
+	\author Ronald Kluth
+
+	\date created at 2007/04/04
+
+	\brief Declaration of odemx::synchronization::Memory and observer
+
+	\sa Memory.cpp
+
+	\since 2.0
+*/
+
+#ifndef ODEMX_MEMORY_INCLUDED
+#define ODEMX_MEMORY_INCLUDED
+
+#include <odemx/data/Producer.h>
+#include <odemx/base/TypeDefs.h>
+#include <odemx/synchronization/IMemory.h>
+#include <odemx/data/Observable.h>
+
+#include <list>
+#include <vector>
+
+namespace odemx {
+
+//forward declarations
+namespace base {
+class Process;
+class Sched;
+}
+
+namespace synchronization {
+
+class MemoryObserver;
+
+/** \class Memory
+
+	\ingroup synch
+
+	\author Ronald Kluth
+
+	\brief The base class for all structures that need to remember processes
+
+	\sa Process, Timer, PortHead, PortTail, WaitCondition
+
+	%Memory is an abstract base class for all user defined structures
+	in a model that need to store a list of suspended processes in order to wake
+	them when a certain event occurs. This can be the case for timers, but also
+	for structures like buffered communication ports. %Memory offers a
+	means to notify suspended processes of the availability of a resource and
+	reschedule them at that point in simulation time when a resource becomes
+	available or a timeout occurs. The recommended usage with processes is
+	via their \p wait() function.
+
+	\since 2.0
+*/
+class Memory
+:	public IMemory // implements the memory interface
+,	public data::Producer
+,	public data::Observable< MemoryObserver >
+{
+public:
+	friend class base::Process;
+
+	/// Same type as the STL container's size_type
+	typedef base::SchedList::size_type SizeType;
+
+	/**
+	 * @brief Construction for user-defined Simulation
+	 *
+	 * @param sim Reference to the simulation context
+	 * @param label The object's label
+	 * @param type Type of the memory object
+	 * @param obs Pointer to the initial observer of the object
+	*/
+	Memory( base::Simulation& sim, const data::Label& label, Type type,
+			MemoryObserver* obs = 0 );
+
+	/// Destruction
+	virtual ~Memory();
+
+	/**
+	 * @name Process interaction
+	 *
+	 * These functions can be used by processes to interact with
+	 * Memory objects.
+	 * @{
+	 */
+	/**
+	 * @brief Remember a new schedulable object
+	 *
+	 * @param newObject Pointer to a schedulable object to be stored in memory
+	 *
+	 * @return @c true when successfully stored, @c false if @c newObject is
+	 * already stored
+	 *
+	 * This function is used to add processes or, more generally,
+	 * schedulable objects to the internal list.
+	 *
+	 * @sa forget()
+	 */
+	virtual bool remember( base::Sched* newObject );
+
+	/**
+	 * @brief Remove a stored schedulable object
+	 *
+	 * @param rememberedObject Pointer to the object to be removed
+	 *
+	 * @return @c true when successfully removed, @c false if @c rememberedObject
+	 * not found in list
+	 *
+	 * This function is used to remove processes or, more generally,
+	 * schedulable objects from the internal list.
+	 *
+	 * @sa remember()
+	 */
+	virtual bool forget( base::Sched* rememberedObject );
+
+	/**
+	 * @brief Check if a certain process is waiting for this memory object.
+	 *
+	 * @return @c true if the process is waiting, @c false otherwise
+	 *
+	 * @sa remember(), forget()
+	 */
+  bool processIsWaiting (base::Process& process) const;
+
+	/**
+	 * @brief Clear the internal list
+	 *
+	 * This function is used to remove all processes or, more generally,
+	 * schedulable objects from the internal list.
+	 *
+	 * @sa remember(), forget()
+	 */
+	virtual void eraseMemory();
+	//@}
+
+	/**
+	 * @name Memory status information
+	 *
+	 * These functions return information about the Memory object.
+	 * @{
+	 */
+	/**
+	 * @brief Check availability of an Memory object
+	 *
+	 * @return @c true if the memory object is available, @c false otherwise
+	 *
+	 * This virtual function should be implemented by all
+	 * subclasses of %Memory. It is used to check the availability
+	 * of a	resource before suspending the requesting process.
+	 *
+	 * @note Memory objects may always return false (like the default
+	 * implementation) if they use some other means to alert and reschedule
+	 * processes.
+	 *
+	 * @sa Process::wait(), PortHead, PortTail, Timer, WaitCondition
+	 */
+	virtual bool isAvailable();
+
+	/// Check if this Memory object has waiting processes
+	bool waiting() const;
+
+	/// Get the number of waiting processes
+	SizeType countWaiting() const;
+
+	/// Get a reference to the list of waiting objects
+	const base::SchedList& getWaiting() const;
+
+	/**
+	 * @brief Check the type of this Memory object
+	 *
+	 * The memory type is useful when a Memory pointer is returned
+	 * but, depending on the type of this object, different reactions are
+	 * required in the simulator. For example, it is quite a difference if
+	 * a timer is available becuase it was not or a communication port because
+	 * it contains data.
+	 *
+	 * @sa Process::wait()
+	 */
+	virtual Type getMemoryType() const;
+	//@}
+
+	/// Required implementation, simply calls <tt>alert( this )</tt>
+	virtual void alert();
+
+	/**
+	 * @brief Alert and reschedule all stored schedulable objects
+	 * @param caller Pointer to an IMemory object to be passed as process alerter
+	 *
+	 * By default, this function is designed to wake up suspended
+	 * or newly created processes, i.e. reschedule them at the current
+	 * simulation time. In case an IMemory interface is implemented in terms
+	 * a Memory member, it makes sense to pass the owner as alerter in
+	 * order to be able to check against the owner's address instead of the
+	 * member's.
+	 */
+	void alert( IMemory* caller );
+
+
+protected:
+	/**
+	 * @brief Helper for alert() which tests if object @c s is a sleeping Process
+	 * @return @c true if object @c s can be alerted, @false otherwise
+	 */
+	bool checkSchedForAlert( base::Sched* s );
+
+private:
+	/// The object's memo type
+	Type memoryType_;
+	/// Storage for pointers to schedulable objects
+	base::SchedList memoryList_;
+
+	/// Helper to log an alert record with details of the internal memory list
+	void traceAlert();
+};
+
+/** \interface MemoryObserver
+
+	\author Ronald Kluth
+
+	\brief Observer for Memory-specific calls.
+
+	\sa Timer, PortHead, PortTail
+
+	\since 2.0
+*/
+class MemoryObserver
+{
+public:
+	virtual ~MemoryObserver() {}
+
+	/// Observe construction
+	virtual void onCreate( Memory* sender ) {}
+
+	/// Observe addition of a new object to the memory
+	virtual void onRemember( Memory* sender, base::Sched* s ) {}
+	/// Observe removal of a previously stored object from the memory
+	virtual void onForget( Memory* sender, base::Sched* s ) {}
+	/// Observe alert of all stored schedulable objects
+	virtual void onAlert( Memory* sender ) {}
+};
+
+} } // namespace odemx::synchronization
+
+#endif /*ODEMX_MEMORY_INCLUDED*/
diff --git a/odemx-lite/include/odemx/synchronization/Port.h b/odemx-lite/include/odemx/synchronization/Port.h
new file mode 100644
index 0000000000000000000000000000000000000000..e1a3352c7b6b6db97070278812c7ed23c5790dff
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/Port.h
@@ -0,0 +1,52 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002-2008 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**
+ * @file Port.h
+ * @author Ronald Kluth
+ * @date created at 2007/04/04
+ * @brief Port forwarding header and declaration of odemx::PortHead, odemx::PortTail
+ * @see PortImpl.h, PortHeadImpl.h, PortTailImpl.h
+ * @since 2.0
+ */
+
+#ifndef ODEMX_SYNC_PORT_INCLUDED
+#define ODEMX_SYNC_PORT_INCLUDED
+
+// include port template headers with implementation
+#include <odemx/synchronization/port/PortData.h>
+#include <odemx/synchronization/port/PortHeadImpl.h>
+#include <odemx/synchronization/port/PortTailImpl.h>
+
+// type definitions for convenience
+namespace odemx {
+namespace synchronization {
+
+/// Default PortHead supporting elements derived from PortData
+typedef PortHeadT< PortData* > PortHead;
+/// Default PortTail supporting elements derived from PortData
+typedef PortTailT< PortData* > PortTail;
+
+/// Default observer for PortHead
+typedef PortHeadTObserver< PortData* > PortHeadObserver;
+/// Default observer for PortTail
+typedef PortTailTObserver< PortData* > PortTailObserver;
+
+} } // namespace odemx::synchronization
+
+#endif /* ODEMX_SYNC_PORT_INCLUDED */
diff --git a/odemx-lite/include/odemx/synchronization/ProcessQueue.h b/odemx-lite/include/odemx/synchronization/ProcessQueue.h
new file mode 100644
index 0000000000000000000000000000000000000000..c556edfc1983fac721c9fd85e1e77348f699f616
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/ProcessQueue.h
@@ -0,0 +1,126 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ProcessQueue.h
+ * @author Ralf Gerstenberger
+ * @date created at 2002/03/25
+ * @brief Declaration of odemx::synchronization::ProcessQueue
+ * @sa ProcessQueue.cpp
+ * @since 1.0
+ */
+
+#ifndef ODEMX_SYNC_PROCESSQUEUE_INCLUDED
+#define ODEMX_SYNC_PROCESSQUEUE_INCLUDED
+
+#include <odemx/base/TypeDefs.h>
+
+namespace odemx {
+
+// forward declaration
+namespace base {
+class Process;
+}
+
+namespace synchronization {
+
+/** \class ProcessQueue
+
+	\ingroup base
+
+	\author Ralf Gerstenberger
+
+	\brief ProcessQueue is used for process synchronization
+
+	ProcessQueue is a general tool for storing Process objects. It is used
+	by synchronization objects. Every Process can stay in no more than one
+	ProcessQueue at a time (provisional). If the queue priority of a
+	Process in a ProcessQueue is changed, the ProcessQueue is updated.
+
+	\since 1.0
+*/
+class ProcessQueue
+{
+public:
+	typedef base::ProcessList::size_type SizeType;
+
+	/// Constructor
+	ProcessQueue();
+	/// Destructor
+	virtual ~ProcessQueue();
+
+	/* \name Queue access and information methods
+	 * @{
+	 */
+	/// check if the queue is empty
+	bool isEmpty() const;
+	/// get pointer to the first process in the queue
+	base::Process* getTop() const;
+	/// get a reference to the list object representing the queue
+	const base::ProcessList& getList() const;
+	/// get the current queue length, i.e. number of stored processes
+	SizeType getLength() const;
+	/**
+	 * \brief
+	 * 		get the queue position of a specific process
+	 * \param p
+	 * 		Process pointer to be found in queue
+	 * \return
+	 *		Position of \p p, or 0 when not found
+	 * \note
+	 * 		The first queue position is \c 1. \c 0 is reserved for errors.
+	 */
+	SizeType getPosition( base::Process* p ) const;
+	//@}
+
+	/* \name Queue manipulation methods
+	 * @{
+	 */
+	/// remove the first Process from the queue
+	virtual void popQueue();
+	/// remove a specific Process \p p from the queue
+	virtual void remove( base::Process* p );
+	/// add Process \p p to the queue, considering order and priority
+	virtual void inSort( base::Process* p,  bool fifo = true );
+	//@}
+
+protected:
+	/// list of Process pointers representing the queue
+	base::ProcessList processes_;
+	/// size counter for efficiency to avoid calling list::size()
+	SizeType length_;
+};
+
+/**
+ * @brief Awakes, i.e. schedules, all Process objects in queue \p q
+ */
+extern void awakeAll( ProcessQueue* q );
+
+/**
+ * @brief Awakes, i.e. schedules, the first Process object in queue \p q
+ */
+extern void awakeFirst( ProcessQueue* q );
+
+/**
+ * @brief Awakes, i.e. schedules, the Process object that comes after \p p in queue \p q
+ */
+extern void awakeNext( ProcessQueue* q, base::Process* p );
+
+} } // namespace odemx::synchronization
+
+#endif /* ODEMX_SYNC_PROCESSQUEUE_INCLUDED */
diff --git a/odemx-lite/include/odemx/synchronization/Queue.h b/odemx-lite/include/odemx/synchronization/Queue.h
new file mode 100644
index 0000000000000000000000000000000000000000..51f00fe0c554a1a9b79084529350c7b8f402bbfb
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/Queue.h
@@ -0,0 +1,88 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2003, 2004, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Queue.h
+ * @author Ralf Gerstenberger
+ * @date created at 2003/06/28
+ * @brief Declaration of odemx::synchronization::Queue
+ * @sa Queue.cpp
+ * @since 1.0
+ */
+
+#ifndef ODEMX_SYNC_QUEUE_INCLUDED
+#define ODEMX_SYNC_QUEUE_INCLUDED
+
+#include <odemx/data/Producer.h>
+#include <odemx/synchronization/ProcessQueue.h>
+
+namespace odemx {
+
+// forward declarations
+namespace base {
+class Simulation;
+}
+
+namespace synchronization {
+
+/** \class Queue
+
+	\ingroup synch
+
+	\author Ralf Gerstenberger
+
+	\brief Wrapper for ProcessQueue with statistics support
+
+	Queue is a wrapper for ProcessQueue. In addition to the
+	functions of ProcessQueue it also provides statistics about
+	the queue usage.
+
+	\sa ProcessQueue
+
+	\since 1.0
+*/
+class Queue
+:	public data::Producer
+,	public ProcessQueue
+{
+public:
+	/// Same type as the size_type of the used STL container
+	typedef ProcessQueue::SizeType SizeType;
+
+	/// Contruction for user-defined Simulation
+	Queue( base::Simulation& sim, const data::Label& label );
+
+	/// Destruction
+	virtual ~Queue();
+
+	/**
+	 * @name Manipulator methods
+	 * @{
+	 */
+	/// Remove the first process from the queue
+	virtual void popQueue();
+	/// Remove the process @c p from the queue
+	virtual void remove( base::Process* p );
+	/// Insert process @c p into the queue, in fifo (default) or lifo mode
+	virtual void inSort( base::Process* p,  bool fifo = true );
+	//@}
+};
+
+} } // namespace odemx::synchronization
+
+#endif /* ODEMX_SYNC_QUEUE_INCLUDED */
diff --git a/odemx-lite/include/odemx/synchronization/Res.h b/odemx-lite/include/odemx/synchronization/Res.h
new file mode 100644
index 0000000000000000000000000000000000000000..f6c7ff2151b8bca6e0b5d1b417e2fc1c25503aad
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/Res.h
@@ -0,0 +1,202 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Res.h
+
+	\author Ralf Gerstenberger
+
+	\date created at 2002/03/21
+
+	\brief Declaration of odemx::synchronization::Res and observer
+
+	\sa Res.cpp
+
+	\since 1.0
+*/
+
+#ifndef ODEMX_RES_INCLUDED
+#define ODEMX_RES_INCLUDED
+
+#include <odemx/data/Producer.h>
+#include <odemx/synchronization/Queue.h>
+#include <odemx/data/Observable.h>
+
+namespace odemx {
+namespace synchronization {
+
+// forward declaration
+class ResObserver;
+
+/** \class Res
+
+	\ingroup synch
+
+	\author Ralf Gerstenberger
+
+	\brief %Res is a double (n>=0 && n<=max number of token) bounded
+	token abstract resource.
+
+	\note Res supports Observation
+	\note Res supports Trace
+	\note Res supports Report
+
+	\sa ResT, ResTChoice
+
+	Res is a double bounded (n>=0 && n<=max number of token) token abstract
+	resource for synchronising Process objects. A process is blocked if
+	it tries to acquire more token than are left. It is reactivated when
+	enough token are released or acquired. If multiple processes are waiting
+	for reactivation process-priority and FIFO-strategy are used to
+	choose the process.
+	Res is generally used for strong limited resource modelling or producer
+	consumer synchronisation with limited storage capacity.
+
+	\since 1.0
+*/
+class Res
+:	public data::Producer
+,	public data::Observable< ResObserver >
+{
+public:
+
+	/**
+		\brief Construction for user-defined Simulation
+		\param s
+			pointer to Simulation object
+		\param l
+			label of this object
+		\param startTokenNumber
+			initial number of token in Res
+		\param maxTokenNumber
+			max number of token in Res
+		\param o
+			initial observer
+	*/
+	Res( base::Simulation& sim, const data::Label& label, std::size_t initialTokens,
+			std::size_t maxTokens, ResObserver* obs = 0 );
+
+	/// Destruction
+	~Res();
+
+	/**
+		\name Token management
+		@{
+	*/
+	/**
+		\brief Acquire \p n token
+
+		If there aren't enough token in Res the current
+		process is blocked. If a blocked process is interrupted,
+		it is reactivated and acquire() returns 0. Otherwise the
+		function returns \p n.
+	*/
+	std::size_t acquire( std::size_t n );
+
+	/**
+		\brief Release \p n token
+
+		Returns \p n token to resource. If there is not enough
+		room in this resource left an error message is created.
+	*/
+	void release( std::size_t n );
+
+
+	/**
+		\brief Add token to resource
+
+		Add token to the managed token set.
+	*/
+	void control( std::size_t n );
+
+	/**
+		\brief Remove \p n token from resource
+
+		Remove token from the managed token set. If there are not enough
+		token left in the resource, the current process is blocked. When
+		a blocked process is interrupted, the attempt to take token is
+		cancelled and the function returns 0.
+	*/
+	std::size_t unControl( std::size_t n );
+
+	/// Current number of token available
+	std::size_t getTokenNumber() const;
+
+	/// Maximum number of token
+	std::size_t getTokenLimit() const;
+	//@}
+
+	/// Get list of blocked processes
+	const base::ProcessList& getWaitingProcesses() const;
+
+private:
+	/// current number of tokens
+	std::size_t tokens_;
+	/// max number of tokens
+	std::size_t tokenLimit_;
+	/// process management
+	Queue acquireQueue_;
+
+	/// Helper for quick access to the current simulation time
+	base::SimTime getTime() const;
+	/// Helper for quick access to the currently running object
+	base::Sched* getCurrentSched();
+	/// Helper for quick access to the current process
+	base::Process* getCurrentProcess();
+	/// Get the label of the currently active context (process or sim)
+	const data::Label& getPartner();
+};
+
+/** \interface ResObserver
+
+	\author Ralf Gerstenberger
+
+	\brief Observer for Res specific events
+
+	\sa Res
+
+	\since 1.0
+*/
+class ResObserver
+{
+public:
+	virtual ~ResObserver() {}
+
+	/// Observe construction
+	virtual void onCreate( Res* sender ) {}
+
+	/// Observe blocking of acquire
+	virtual void onAcquireFail( Res* sender, std::size_t n ) {}
+	/// Observe successful acquiration of n token
+	virtual void onAcquireSucceed( Res* sender, std::size_t n ) {}
+	/// Blocking release of n token
+	virtual void onReleaseFail( Res* sender, std::size_t n ) {}
+	/// Successful release of n token
+	virtual void onReleaseSucceed( Res* sender, std::size_t n ) {}
+	/// Increased token limit
+	virtual void onControl( Res* sender, std::size_t n ) {}
+	/// Decreased toekn limit
+	virtual void onUnControl( Res* sender, std::size_t n ) {}
+	/// Change of token number
+	virtual void onChangeTokenNumber( Res* sender, std::size_t oldTokenNumber,
+			std::size_t newTokenNumber ) {}
+};
+
+} } // namespace odemx::synchronization
+
+#endif
+
diff --git a/odemx-lite/include/odemx/synchronization/ResT.h b/odemx-lite/include/odemx/synchronization/ResT.h
new file mode 100644
index 0000000000000000000000000000000000000000..a3f9194effcaf6f8d128d72d7c82f13c8598dd0d
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/ResT.h
@@ -0,0 +1,43 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002-2008 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Bin.h
+
+	\author Ronald Kluth
+
+	\date created at 2008/02/17
+
+	\brief Forwarding header for inclusion of odemx::ResT, ResTChoice, and observers
+
+	\since 2.1
+*/
+
+#ifndef ODEMX_RES_TEMPLATE_INCLUDED
+#define ODEMX_RES_TEMPLATE_INCLUDED
+
+// template ResTBase header with implementation
+#include <odemx/synchronization/res/ResTBase.h>
+#include <odemx/synchronization/res/ResTBase.cpp>
+// template ResT header with implementation
+#include <odemx/synchronization/res/ResT.h>
+#include <odemx/synchronization/res/ResT.cpp>
+// template ResTChoice header with implementation
+#include <odemx/synchronization/res/ResTChoice.h>
+#include <odemx/synchronization/res/ResTChoice.cpp>
+
+#endif /* ODEMX_RES_TEMPLATE_INCLUDED */
diff --git a/odemx-lite/include/odemx/synchronization/Timer.h b/odemx-lite/include/odemx/synchronization/Timer.h
new file mode 100644
index 0000000000000000000000000000000000000000..a134f9a23589efbedb186ad68cb9819f41dae024
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/Timer.h
@@ -0,0 +1,277 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2007, 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Timer.h
+
+	\author Ronald Kluth
+
+	\date created at 2007/04/04
+
+	\brief Declaration of odemx::synchronization::Timer and observer
+
+	\sa Timer.cpp
+
+	\since 2.0
+*/
+
+#ifndef ODEMX_TIMER_INCLUDED
+#define ODEMX_TIMER_INCLUDED
+
+#include <odemx/base/Event.h>
+#include <odemx/base/SimTime.h>
+#include <odemx/synchronization/Memory.h>
+
+namespace odemx {
+
+// forward declarations
+namespace base {
+class Process;
+class Sched;
+class Simulation;
+}
+
+namespace synchronization {
+
+class TimerObserver;
+
+/// maximum priority
+extern const int MAX_PRIORITY;
+
+/** \class Timer
+
+	\ingroup synch
+
+	\author Ronald Kluth
+
+	\brief %Timers trigger an event to wake up suspended processes in a model.
+
+	\note %Timer supports Observation.
+	\note %Timer supports Trace.
+
+	\sa Process, Event, Simulation
+
+	%Timer is a class provided for convenience. When processes are suspended
+	using the \p Process::wait() function, a Timer can be used to wake up
+	processes if no other Memory object becomes available within a certain
+	amount of time. Timers should not be used to implement arbitrary events,
+	instead different kinds of events should be derived from the
+	base class Event. By default, Timers have maximum priority of all
+	schedulable objects and as such they will be triggered first when
+	simulation time reaches their execution time.
+
+	\since 2.0
+*/
+
+class Timer
+:	public base::Event // is a DataProducer
+,	public IMemory // derive from interface to avoid DataProducer ambiguity
+,	public data::Observable< TimerObserver >
+{
+public:
+
+	/**
+		\brief Construction for user-defined Simulation
+		\param sim
+			pointer to the Simulation object
+		\param l
+			label of this object
+		\param to
+			initial timer observer
+	*/
+	Timer( base::Simulation& sim, const data::Label& label, TimerObserver* obs = 0 );
+
+	/// Destruction
+	virtual ~Timer();
+
+	/**
+		\name Timer Scheduling
+
+		These functions are used to schedule a timeout event
+		in simulation time. Timers are kept in the same
+		schedule as processes and other events and they follow the
+		same scheduling rules. However, their default priority is
+		set to maximum.
+
+		@{
+	*/
+	/**
+		\brief Trigger the timeout at simulation time \p now + \p t
+
+		This function schedules the timer at time \p now + \p t before
+		all other processes and events at that point in simulation time.
+		Scheduling a
+		%Timer at SimTime \p now will not suspend the execution of
+		the current process . The calling process, however, should suspend
+		its execution via Process::wait(), which will automatically
+		register that process with the Memory objects given as parameters.
+	*/
+	void setIn( base::SimTime t );
+
+	/**
+		\brief Trigger the timeout at absolute simulation time \p t
+
+		This function schedules the timer at the absolute simulation
+		time \p t before all other processes and events with the same
+		execution time.
+		Scheduling a %Timer at SimTime \p now will not suspend the execution of
+		the current process. The calling process, however, should suspend
+		its execution via Process::wait(), which will automatically
+		register that process with the Memory objects given as parameters.
+	*/
+	void setAt( base::SimTime t );
+
+	/**
+		\brief Reschedule the timeout to simulation time \p now + \p t.
+
+		This function reschedules the timer at time \p now + \p t before
+		all other processes with the same execution time
+	*/
+	void reset( base::SimTime t );
+
+	/**
+		\brief Remove the %Timer from the schedule
+
+		This function removes the timer from the execution list
+	*/
+	void stop();
+
+	/**
+		\brief Check if the %Timer is scheduled for execution
+		\return
+			true when listed in schedule
+
+		This function reports whether the time is scheduled or not.
+	*/
+	bool isSet();
+	//@}
+
+	/**
+		\brief Register a process to wake with this timer
+		\return
+			true if sucessfully added \p p to timer memory
+		\param p
+			process to be remembered
+
+		This function stores process \p p in the timer's memory.
+		All the stored processes are rescheduled when the
+		timeout is triggered.
+
+		\sa removeProcess()
+	*/
+	bool registerProcess( base::Process* p );
+
+	/**
+		\brief Remove a registered process from timer's memory
+		\return
+			true if sucessfully remove \p p
+		\param p
+			process to be removed
+
+		This function removes process \p p from the timer's memory.
+
+		\sa registerProcess()
+	*/
+	bool removeProcess( base::Process* p );
+
+	/// Get a list of the waiting processes
+	const base::SchedList& getWaiting() const;
+
+protected:
+
+	/**
+		\brief Reimplemented from Event, schedules all remembered Processes
+
+		This function alerts all processes in the timer's memory.
+		These processes are then rescheduled at time \p now.
+	*/
+	virtual void eventAction();
+
+	/**
+	 * @name IMemory implementation
+	 *
+	 * To preserve a single inheritance line of DataProducer, Timer only
+	 * inherits from IMemory and has to implement its functions almost
+	 * identical to Memory.
+	 * @{
+	 *
+	 * @sa IMemory
+	 */
+public:
+	/// Get memory type
+	virtual IMemory::Type getMemoryType() const;
+	/// Check availability, timers are available when they are not scheduled
+	virtual bool isAvailable();
+	/// Alert all waiting processes after a timeout
+	virtual void alert();
+
+private:
+//	friend class base::Process;
+
+	/// Store a schedulable object
+	virtual bool remember( base::Sched* newObject );
+	/// Remove a schedulable object from memory
+	virtual bool forget( base::Sched* rememberedObject );
+	/// Erase all schedulable objects from memory
+	virtual void eraseMemory();
+
+private:
+	/// Internal memory object to which all IMemory-calls are forwarded
+	Memory memory_;
+	//@}
+};
+
+/** \interface TimerObserver
+
+	\author Ronald Kluth
+
+	\brief Observer for Timer-specific calls.
+
+	\sa Timer, Event
+
+	\since 2.0
+*/
+class TimerObserver
+:	public base::EventObserver
+{
+public:
+	virtual ~TimerObserver() {}
+
+	/// Observe construction
+//	virtual void onCreate( Timer* sender ) {}
+
+	/// Observe activation with relative time
+	virtual void onSetIn( Timer* sender, base::SimTime t ) {}
+	/// Observe activation with absolute time
+	virtual void onSetAt( Timer* sender, base::SimTime t ) {}
+	/// Observe timer reset and rescheduling
+	virtual void onReset( Timer* sender, base::SimTime oldTime, base::SimTime newTime ) {}
+	/// Observe timer stop
+	virtual void onStop( Timer* sender ) {}
+
+	/// Observe process registration
+	virtual void onRegisterProcess( Timer* sender, base::Process* p ) {}
+	/// Observe process removal
+	virtual void onRemoveProcess( Timer* sender, base::Process* p ) {}
+	/// Observe timeout, execution of the timer
+	virtual void onTimeout( Timer* sender ) {}
+};
+
+} } // namespace odemx::synchronization
+
+#endif /*ODEMX_TIMER_INCLUDED*/
+
diff --git a/odemx-lite/include/odemx/synchronization/Wait.h b/odemx-lite/include/odemx/synchronization/Wait.h
new file mode 100644
index 0000000000000000000000000000000000000000..883eaac02fafb52db6048c354cd9dac13c80e919
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/Wait.h
@@ -0,0 +1,211 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Wait.h
+
+	\author Ralf Gerstenberger
+
+	\date created at 2003/06/06
+
+	\brief Declaration of odemx::synchronization::Wait
+
+	\sa Wait.cpp
+
+	\since 1.0
+*/
+
+#ifndef ODEMX_WAIT_INCLUDED
+#define ODEMX_WAIT_INCLUDED
+
+#include <odemx/setup.h>
+
+#ifdef ODEMX_USE_OBSERVATION
+
+#include <odemx/base/Process.h>
+#include <odemx/data/Producer.h>
+
+#include <list>
+
+
+namespace odemx {
+namespace synchronization {
+
+/** \class Wait
+
+	\ingroup synch
+
+	\author Ralf Gerstenberger
+
+	\brief %Wait for termination of a number of process objects
+
+	\note Wait supports Trace
+	@note This class can only be used when ODEMX_USE_OBSERVATION is defined
+	in odemx/setup.h
+
+	%Wait is used to synchronize a process with the termination of
+	one ore more partner processes.
+
+	\since 1.0
+*/
+class Wait
+:	public data::Producer
+,	public base::ProcessObserver
+{
+public:
+
+	/**
+		\brief Construction for user-defined Simulation
+		\param s
+			pointer to Simulation object
+		\param l
+			label of this object
+	*/
+	Wait( base::Simulation& sim, const data::Label& label );
+
+	/**
+		\brief Construction and wait for user-defined Simulation
+		\param s
+			pointer to Simulation object
+		\param l
+			label of this object
+		\param p1
+			process to wait for
+
+		This constructor creates a Wait object and waits for
+		Process \p p1 to finish. If the blocked Process is interrupted,
+		it is reactivated and the constructor returns. To check whether
+		the process was interrupted, use the isInterrupted() method of
+		Process.
+	*/
+	Wait( base::Simulation& sim, const data::Label& label, base::Process* p1 );
+
+	/**
+		\brief Construction for user-defined Simulation
+		\param s
+			pointer to Simulation object
+		\param l
+			label of this object
+		\param p1
+			first process to wait for
+		\param p2
+			second process to wait for
+		\param all
+			wait for \p all processes
+
+		This constructor creates a Wait object and waits for the Process
+		objects \p p1 and (or) \p p2 to finish. If the blocked Process
+		is interrupted, it is reactivated and the constructor returns.
+		To check whether the process was interrupted, use the isInterrupted()
+		method of Process.
+	*/
+	Wait( base::Simulation& sim, const data::Label& label, base::Process* p1,
+			base::Process* p2, bool all = true );
+
+	/**
+		\brief Construction for user-defined Simulation
+		\param s
+			pointer to Simulation object
+		\param l
+			label of this object
+		\param p1
+			first process to wait for
+		\param p2
+			second process to wait for
+		\param p3
+			third process to wait for
+		\param all
+			wait for \p all processes
+
+		This constructor creates a Wait object and waits for the Process
+		objects \p p1, \p p2 and(or) \p p3 to finish. If the blocked Process
+		is interrupted, it is reactivated and the constructor returns.
+		To check whether the process was interrupted, use the isInterrupted()
+		method of Process.
+	*/
+	Wait( base::Simulation& sim, const data::Label& label, base::Process* p1,
+			base::Process* p2, base::Process* p3, bool all = true );
+
+	/**
+		\brief Construction for user-defined Simulation
+		\param s
+			pointer to Simulation object
+		\param l
+			abel of this object
+		\param size
+			number of processes in \p p
+		\param p
+			processes to wait for
+		\param all
+			wait for \p all processes
+
+		This constructor creates a Wait object and waits for the Process
+		objects stored in \p p to finish. If the blocked Process
+		is interrupted, it is reactivated and the constructor returns.
+		To check whether the process was interrupted, use the isInterrupted()
+		method of Process.
+	*/
+	Wait( base::Simulation& sim, const data::Label& label, int size, base::Process* p[],
+			bool all = true );
+
+	/// Destruction
+	virtual ~Wait();
+
+	/// Add process \p p to list of observed processes
+	void addProcess( base::Process* p );
+
+	/// Remove process \p p from list of observed processes
+	void removeProcess( base::Process* p );
+
+	/// Get the list of observed processes
+	const base::ProcessList& getWaitingProcesses() const;
+
+	/// Get Condition (wait for one or all observed Process objects to finish)
+	bool getCondition() const;
+
+	/// Set Condition (wait for one or all observed Process objects to finish)
+	void setCondition( bool all = true );
+
+	/**
+		\brief Wait for one / all observed processes to finish
+
+		Wait for one or all observed processes to finish. If the blocked
+		Process is interrupted it is reactivated and wait() returns false.
+		Otherwise wait() returns true.
+	*/
+	bool wait();
+
+public:
+	// ProcessObserver functions
+	virtual void onChangeProcessState( base::Process* sender,
+			base::Process::ProcessState oldState,
+			base::Process::ProcessState newState );
+
+private:
+	base::Process* waitCaller_; ///< blocked process
+	base::ProcessList observedProcesses_; ///< observed processes
+	bool waitForAll_; ///< condition
+
+	void initObservedList( size_t size, base::Process* p[] ); ///< init observed list
+	bool checkObserved(); ///< check condition
+};
+
+} } // namespace odemx::synchronization
+
+#endif /* ODEMX_USE_OBSERVATION */
+
+#endif
diff --git a/odemx-lite/include/odemx/synchronization/WaitQ.h b/odemx-lite/include/odemx/synchronization/WaitQ.h
new file mode 100644
index 0000000000000000000000000000000000000000..c73224da2312973ff4f0140f47d0a7678a0402ed
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/WaitQ.h
@@ -0,0 +1,249 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file WaitQ.h
+
+	\author Ralf Gerstenberger
+
+	\date created at 2002/03/26
+
+	\brief Declaration of odemx::synchronization::WaitQ and observer
+
+	\sa WaitQ.cpp
+
+	\since 1.0
+*/
+
+#ifndef ODEMX_WAITQ_INCLUDED
+#define ODEMX_WAITQ_INCLUDED
+
+#include <odemx/data/Producer.h>
+#include <odemx/synchronization/Queue.h>
+#include <odemx/data/Observable.h>
+
+namespace odemx {
+
+// forward declarations
+namespace base {
+class Process;
+class Simulation;
+}
+
+namespace synchronization {
+
+class WaitQObserver;
+
+/** \class WaitQ
+
+	\ingroup synch
+
+	\author Ralf Gerstenberger
+
+	\brief %WaitQ realises a master slave synchronisation,
+	where the master gets control after successful synchronisation.
+
+	\note WaitQ supports Observation
+	\note WaitQ supports Trace
+	\note WaitQ supports Report
+
+	WaitQ realises a master slave synchronisation scheme. Two processes
+	are synchronised with each other. One plays the role of a master process
+	and gets control (execution) after successful synchronisation. The other
+	(slave) is frozen and returned to the master process. A master process
+	can provide a selection function to synchronise with particular processes
+	only. If multiple processes could be used for synchronisation process-
+	priority and FIFO-strategy are used to choose the process.
+	WaitQ is used for general process to process synchronisation.
+
+	\since 1.0
+*/
+class WaitQ
+:	public data::Producer
+,	public data::Observable< WaitQObserver >
+{
+public:
+
+	/**
+		\brief Construction for user-defined Simulation
+		\param s
+			pointer to Simulation object
+		\param l
+			label of this object
+		\param o
+			initial observer
+	*/
+	WaitQ( base::Simulation& sim, const data::Label& label, WaitQObserver* obs = 0 );
+
+	/// Destruction
+	~WaitQ();
+
+	/**
+		\name Master-slave synchronisation
+		@{
+	*/
+	/**
+		\brief Wait for activation by a 'master' process
+
+		A process calling wait() is deactivated and passed
+		over to a process synchronising with coopt() or avail(). If
+		a slave process is interrupted before a successful synchronisation
+		it is reactivated and the function returns false. (An interrupted
+		slave process does not change user and waiting time statistics, but has
+		influence on queue statistics.)
+	*/
+	bool wait();
+
+	/**
+		\brief Wait for activation by a 'master' process
+
+		A process calling wait() is deactivated and passed
+		over to a process synchronising with coopt() or avail().
+		This overloaded version requires the master's weight function
+		to properly synchronize a waiting slave with the master for
+		which the weight function returns the highest value.
+		If a slave process is interrupted before a successful synchronisation
+		it is reactivated and the function returns false. (An interrupted
+		slave process does not change user and waiting time statistics, but has
+		influence on queue statistics.)
+	*/
+	bool wait( base::Weight weightFct );
+
+	/**
+		\brief Get a 'slave' process
+
+		A master process uses coopt() to synchronise with a slave process.
+		The master can provide a 'selection function' to synchronise with
+		a specific slave process. Until there is a suitable slave process
+		available the master process is blocked. If a blocked master process
+		is interrupted the synchronisation attempt is cancelled and coopt()
+		returns 0. (An interrupted master process does not change user and wait
+		time statistics, but has influence on queue statistics.)
+
+		\warning A master may not call interrupt() to reactivate a received slave().
+	*/
+	base::Process* coopt( base::Selection sel = 0 );
+
+	/**
+		\brief Get a 'slave' process by evaluating a weight function
+
+		A master process uses coopt() to synchronise with a slave process.
+		The master can also provide a 'weight function' to synchronise with
+		a specific slave process. If there is no slave process
+		available the master process is blocked. If a blocked master process
+		is interrupted the synchronization attempt is cancelled and coopt()
+		returns 0. (An interrupted master process does not change user and wait
+		time statistics, but has influence on queue statistics.)
+
+		\warning A master may not call interrupt() to reactivate a received slave().
+	*/
+	base::Process* coopt( base::Weight weightFct );
+
+	/**
+		\brief Get available slaves without blocking (optional: select slave)
+
+		A master process can use avail() to get a suitable slave process if
+		available. Otherwise avail() returns 0.
+
+		\warning A master may not call interrupt() to reactivate a received slave().
+	*/
+	base::Process* avail( base::Selection sel = 0 );
+	//@}
+
+	/// List of blocked slaves
+	const base::ProcessList& getWaitingSlaves() const;
+	/// List of blocked masters
+	const base::ProcessList& getWaitingMasters() const;
+
+private:
+	/// master management
+	Queue masterQueue_;
+	/// slave management
+	Queue slaveQueue_;
+
+	/// find slave
+	base::Process* getSlave( base::Process* master = 0, base::Selection sel = 0 );
+	/// find slave by weight
+	base::Process* getWeightedSlave( base::Process* master = 0, base::Weight weightFct = 0 );
+	/// statistics
+	void updateStatistics( base::Process* master, base::Process* slave );
+	/// master synch. implementation
+	base::Process* sync( bool wait, base::Selection sel );
+
+	/// Helper for quick access to the current simulation time
+	base::SimTime getTime() const;
+	/// Helper for quick access to the currently running object
+	base::Sched* getCurrentSched();
+	/// Helper for quick access to the current process
+	base::Process* getCurrentProcess();
+};
+
+/** \interface WaitQObserver
+
+	\author Ralf Gerstenberger
+
+	\brief Observer for WaitQ-specific events
+
+	\sa WaitQ
+
+	\since 1.0
+*/
+class WaitQObserver
+{
+public:
+	virtual ~WaitQObserver() {}
+
+	/// Construction
+	virtual void onCreate( WaitQ* sender ) {}
+
+	/// Process is synchronising as slave
+	virtual void onWait( WaitQ* sender, base::Process* slave ) {}
+	/// Process is synchronising as slave
+	virtual void onWaitWeight( WaitQ* sender, base::Process* slave ) {}
+	/// Process is blocked in synchronisation as master
+
+	virtual void onCooptFail( WaitQ* sender, base::Process* master ) {}
+	/// Process succeeds in synchronisation as master, getting slave
+	virtual void onCooptSucceed( WaitQ* sender, base::Process* master,
+			base::Process* slave ) {}
+	/// master Process doesn't find any slave
+	virtual void onAvailFail( WaitQ* sender, base::Process* master ) {}
+	/// master Process find some slave
+	virtual void onAvailSucceed( WaitQ* sender, base::Process* master,
+			base::Process* slave ) {}
+
+	/// Process is blocked in synchronisation as master for a particular slave
+	virtual void onCooptSelFail( WaitQ* sender, base::Process* master ) {}
+	/// Process succeeds in synchronisation as master, getting a particular slave
+	virtual void onCooptSelSucceed( WaitQ* sender, base::Process* master,
+			base::Process* slave ) {}
+	/// master Process doesn't find a particular slave
+	virtual void onAvailSelFail( WaitQ* sender, base::Process* master ) {}
+	/// master Process find a particular slave
+	virtual void onAvailSelSucceed( WaitQ* sender, base::Process* master,
+			base::Process* slave ) {}
+
+	/// Process is blocked in synchronisation as master for a particular slave
+	virtual void onCooptWeightFail( WaitQ* sender, base::Process* master ) {}
+	/// Process succeeds in synchronisation as master, getting a particular slave
+	virtual void onCooptWeightSucceed( WaitQ* sender, base::Process* master,
+			base::Process* slave ) {}
+};
+
+} } // namespace odemx::synchronization
+
+#endif
diff --git a/odemx-lite/include/odemx/synchronization/bin/BinTImpl.cpp b/odemx-lite/include/odemx/synchronization/bin/BinTImpl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ddd211f071941813d488b60836fcf82dd80817ac
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/bin/BinTImpl.cpp
@@ -0,0 +1,259 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file BinTImpl.cpp
+ * @author Ronald Kluth
+ * @date created at 2008/02/18
+ * @brief Implementation of odemx::sync::BinT
+ * @sa BinTImpl.h
+ * @since 2.1
+ */
+
+#include <odemx/util/TypeToString.h>
+#include <odemx/synchronization/bin/BinTImpl.h>
+#include <odemx/base/Sched.h>
+#include <odemx/base/Process.h>
+
+#include <iterator>
+
+namespace odemx {
+namespace synchronization {
+
+template< typename TokenT >
+BinT< TokenT >::BinT( base::Simulation& sim, const data::Label& label,
+		BinTObserver< TokenT >* obs )
+:	data::Producer( sim, label )
+,	data::Observable< BinTObserver< TokenT > >( obs )
+,	tokenStorage_()
+,	tokenCount_( 0 )
+,	takeQueue_( sim, getLabel() + ".queue" )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(BinT< TokenT >) );
+
+	statistics << param( "queue", takeQueue_.getLabel() ).scope( typeid(BinT< TokenT >) );
+	statistics << param( "initial tokens", tokenCount_ ).scope( typeid(BinT< TokenT >) );
+	statistics << param( "token type", odemx::typeToString( typeid(TokenT) ) )
+			.scope( typeid(BinT< TokenT >) );
+	
+	statistics << update( "tokens", tokenCount_ ).scope( typeid(BinT< TokenT >) );
+
+	// observer
+	ODEMX_OBS_T(BinTObserver< TokenT >, Create(this));
+}
+
+template < typename TokenT >
+BinT< TokenT >::BinT( base::Simulation& sim, const data::Label& label,
+		typename BinT< TokenT >::TokenVec& initialTokens,
+		BinTObserver< TokenT >* obs )
+:	data::Producer( sim, label )
+,	data::Observable< BinTObserver< TokenT > >( obs )
+,	tokenStorage_( initialTokens.begin(), initialTokens.end() )
+,	tokenCount_( tokenStorage_.size() )
+,	takeQueue_( sim, getLabel() + ".queue" )
+{
+	ODEMX_TRACE << log( "create and tokens" ).scope( typeid(BinT< TokenT >) );
+
+	statistics << param( "queue", takeQueue_.getLabel() ).scope( typeid(BinT< TokenT >) );
+	statistics << param( "initial tokens", tokenCount_ ).scope( typeid(BinT< TokenT >) );
+	statistics << param( "token type", odemx::typeToString( typeid(TokenT) ) )
+			.scope( typeid(BinT< TokenT >) );
+
+	statistics << update( "tokens", tokenCount_ ).scope( typeid(BinT< TokenT >) );
+
+	// observer
+	ODEMX_OBS_T(BinTObserver< TokenT >, Create(this));
+}
+
+template < typename TokenT >
+BinT< TokenT >::~BinT()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(BinT< TokenT >) );
+}
+
+template < typename TokenT >
+std::unique_ptr< typename BinT< TokenT >::TokenVec >
+BinT< TokenT >::take( size_t n )
+{
+	// resource handling only implemented for processes
+	if( ! getCurrentSched()
+		|| getCurrentSched()->getSchedType() != base::Sched::PROCESS )
+	{
+		error << log( "BinT::take(): called by non-Process object" )
+				.scope( typeid(BinT< TokenT >) );
+		return std::unique_ptr< TokenVec >(nullptr);
+	}
+
+	base::Process* currentProcess = getCurrentProcess();
+
+	// compute order of service
+	takeQueue_.inSort( currentProcess );
+
+	if( n > tokenCount_ || currentProcess != takeQueue_.getTop() )
+	{
+		ODEMX_TRACE << log( "take failed" )
+				.detail( "partner", currentProcess )
+				.detail( "requested tokens", n )
+				.scope( typeid(BinT< TokenT >) );
+
+		// observer
+		ODEMX_OBS_T(BinTObserver< TokenT >, TakeFail(this, n));
+
+		// statistics
+		base::SimTime waitStart = getCurrentTime();
+
+		// block execution
+		while( n > tokenCount_ || currentProcess != takeQueue_.getTop() )
+		{
+			currentProcess->sleep();
+
+			if( currentProcess->isInterrupted() )
+			{
+				takeQueue_.remove( currentProcess );
+				return std::unique_ptr< TokenVec >(nullptr);
+			}
+		}
+		// block released here
+
+		// statistics, log the waiting period
+		base::SimTime waitTime = getCurrentTime() - waitStart;
+		statistics << update( "wait time", waitTime ).scope( typeid(BinT< TokenT >) );
+	}
+
+	// create return vector
+	std::unique_ptr< typename BinT< TokenT >::TokenVec > tokenReturn(
+			new typename BinT< TokenT >::TokenVec(
+					tokenStorage_.begin(), tokenStorage_.begin() + n ) );
+
+	ODEMX_TRACE << log( "change token number" ).valueChange( tokenCount_, tokenCount_ - n )
+			.scope( typeid(BinT< TokenT >) );
+
+	// observer
+	ODEMX_OBS_ATTR_T(BinTObserver< TokenT >, TokenNumber, tokenCount_, tokenCount_ - n);
+
+	// remove tokens from store
+	tokenStorage_.erase( tokenStorage_.begin(), tokenStorage_.begin() + n );
+	tokenCount_ -= n;
+
+	ODEMX_TRACE << log( "take succeeded" )
+			.detail( "partner", currentProcess )
+			.detail( "requested tokens", n )
+			.scope( typeid(BinT< TokenT >) );
+
+	// statistics
+	statistics << count( "users" ).scope( typeid(BinT< TokenT >) );
+	statistics << update( "tokens", tokenCount_ ).scope( typeid(BinT< TokenT >) );
+
+	// observer
+	ODEMX_OBS_T(BinTObserver< TokenT >, TakeSucceed(this, n));
+
+	// remove process from list
+	takeQueue_.remove( currentProcess );
+
+	// awake next
+	awakeFirst( &takeQueue_ );
+
+	// return token
+	return tokenReturn;
+}
+
+template < typename TokenT >
+void BinT< TokenT >::give( const TokenT& token )
+{
+	std::vector< TokenT > tmpVec;
+	tmpVec.push_back( token );
+	give( tmpVec );
+}
+
+template < typename TokenT >
+void BinT< TokenT >::give( const typename BinT< TokenT >::TokenVec& tokens )
+{
+	if ( tokens.empty() )
+	{
+		error << log( "BinT::give(): vector empty; no tokens provided" )
+				.scope( typeid(BinT< TokenT >) );
+		return;
+	}
+
+	std::size_t n = tokens.size();
+
+	ODEMX_TRACE << log( "change token number" ).valueChange( tokenCount_, tokenCount_ + n )
+			.scope( typeid(BinT< TokenT >) );
+
+	// observer
+	ODEMX_OBS_ATTR_T(BinTObserver< TokenT >, TokenNumber, tokenCount_, tokenCount_ + n);
+
+	// transfer token to tokenStore
+	tokenStorage_.insert( tokenStorage_.end(), tokens.begin(), tokens.end() );
+	// set token count
+	tokenCount_ += n;
+
+	ODEMX_TRACE << log( "give" )
+			.detail( "partner", getCurrentProcess() )
+			.detail( "given tokens", n )
+			.scope( typeid(BinT< TokenT >) );
+
+	// statistics
+	statistics << count( "providers" ).scope( typeid(BinT< TokenT >) );
+	statistics << update( "tokens", tokenCount_ ).scope( typeid(BinT< TokenT >) );
+
+	// observer
+	ODEMX_OBS_T(BinTObserver< TokenT >, Give(this, n));
+
+	// wake up wating process objects
+	awakeFirst( &takeQueue_ );
+}
+
+template < typename TokenT >
+std::size_t BinT< TokenT >::getTokenNumber() const
+{
+	return tokenCount_;
+}
+
+template < typename TokenT >
+const typename BinT< TokenT >::StorageType&
+BinT< TokenT >::getTokenStore() const
+{
+	return tokenStorage_;
+}
+
+template < typename TokenT >
+const base::ProcessList& BinT< TokenT >::getWaitingProcesses() const
+{
+	return takeQueue_.getList();
+}
+
+template < typename TokenT >
+base::SimTime BinT< TokenT >::getCurrentTime() const
+{
+	return getSimulation().getTime();
+}
+
+template < typename TokenT >
+base::Sched* BinT< TokenT >::getCurrentSched()
+{
+	return getSimulation().getCurrentSched();
+}
+
+template < typename TokenT >
+base::Process* BinT< TokenT >::getCurrentProcess()
+{
+	return getSimulation().getCurrentProcess();
+}
+
+} } // namespace odemx::sync
diff --git a/odemx-lite/include/odemx/synchronization/bin/BinTImpl.h b/odemx-lite/include/odemx/synchronization/bin/BinTImpl.h
new file mode 100644
index 0000000000000000000000000000000000000000..b0882cf959b35dd16467fd7b59dfe5e8e3073637
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/bin/BinTImpl.h
@@ -0,0 +1,200 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file BinTImpl.h
+ * @author Ronald Kluth
+ * @date created at 2008/02/18
+ * @brief Declaration of odemx::synchronization::BinT and observer
+ * @note Do not include this header directly,
+ * use odemx/synchronization/BinTemplate.h instead.
+ * @sa BinTImpl.cpp
+ * @since 2.1
+ */
+
+#ifndef ODEMX_SYNC_BINT_IMPL_INCLUDED
+#define ODEMX_SYNC_BINT_IMPL_INCLUDED
+
+#include <odemx/data/Producer.h>
+#include <odemx/synchronization/Queue.h>
+#include <odemx/data/Observable.h>
+
+#include <deque>
+#include <memory>
+#include <vector>
+
+namespace odemx {
+
+// forward declarations
+namespace base {
+class Process;
+class Sched;
+class Simulation;
+}
+
+namespace synchronization {
+
+template < typename TokenT > class BinTObserver;
+
+/** \class BinT
+
+	\author Ralf Gerstenberger
+
+	\brief BinT is a resource holding objects of type T.
+
+	\note BinT supports Observation
+
+	\note BinT supports Trace
+
+	BinT is a low bounded (token number >= 0) resource for synchronizing
+	Process objects. A process is blocked in take()	if the requested number
+	of tokens is greater than the available tokens. It is reactivated
+	when enough tokens are given (back) to the resource. If multiple process
+	objects are waiting for reactivation process-priority and FIFO-strategy
+	are used to choose the process.	BinT is generally used for producer and
+	consumer synchronization.
+
+	\since 2.1
+*/
+template < typename TokenT >
+class BinT
+:	public data::Producer
+,	public data::Observable< BinTObserver< TokenT > >
+{
+public:
+
+	typedef TokenT TokenType;
+	typedef std::vector< TokenType > TokenVec;
+	typedef std::deque< TokenType > StorageType;
+	typedef BinTObserver< TokenType > ObserverType;
+
+	/**
+		\brief Construction for user-defined Simulation, no initial tokens
+		\param s
+			pointer to simulation
+		\param l
+			label of BinT object
+		\param o
+			observer of BinT object
+	*/
+	BinT( base::Simulation& sim, const data::Label& label, ObserverType* obs = 0 );
+
+	/**
+		\brief Construction for user-defined Simulation
+		\param s
+			pointer to simulation
+		\param l
+			label of BinT object
+		\param o
+			observer of BinT object
+	*/
+	BinT( base::Simulation& sim, const data::Label& label, TokenVec& initialTokens,
+			ObserverType* obs = 0 );
+
+	/// Destruction
+	virtual ~BinT();
+
+	/**
+		\name Token management
+
+		@{
+	*/
+	/**
+		\brief take \p n tokens
+
+		Takes n tokens from BinT if possible. Otherwise, the
+		current process is blocked until enough tokens become
+		available.
+
+		\note The returned vector is dynamically allocated with \c new,
+		which means that the caller has to call delete on it.
+	*/
+	std::unique_ptr< TokenVec > take( std::size_t n );
+
+	void give( const TokenType& token );
+
+	/**
+		\brief give \p n token back
+
+		Gives n tokens to BinT. Blocked process objects
+		could be activated by this call.
+	*/
+	void give( const TokenVec& tokens );
+
+	/// Number of tokens available
+	std::size_t getTokenNumber() const;
+
+	/// Get a reference to the stored tokens
+	const StorageType& getTokenStore() const;
+	//@}
+
+	/// get list of blocked  process objects
+	const base::ProcessList& getWaitingProcesses() const;
+
+private:
+	/// token storage
+	StorageType tokenStorage_;
+	/// token count
+	std::size_t tokenCount_;
+	/// process management queue
+	Queue takeQueue_;
+
+	/// Helper for quick access to the current simulation time
+	base::SimTime getCurrentTime() const;
+	/// Helper for quick access to the currently running object
+	base::Sched* getCurrentSched();
+	/// Helper for quick access to the current process
+	base::Process* getCurrentProcess();
+};
+
+/** \interface BinTObserver
+
+	\author Ralf Gerstenberger
+
+	\brief Observer for BinT specific events
+
+	\sa BinT
+
+	\since 2.1
+*/
+template < typename TokenT >
+class BinTObserver {
+public:
+
+	typedef BinT< TokenT > BinType;
+
+	virtual ~BinTObserver() {}
+
+	/// Creation
+	virtual void onCreate( BinType* sender ) {}
+
+	/// Failed attempt to take n token
+	virtual void onTakeFail( BinType* sender, std::size_t n ) {}
+	/// Successfull attempt to take n token
+	virtual void onTakeSucceed( BinType* sender, std::size_t n ) {}
+	/// Return of n token
+	virtual void onGive( BinType* sender, std::size_t n ) {}
+
+	/// Change of token number
+	virtual void onChangeTokenNumber( BinType* sender, std::size_t oldTokenCount,
+		std::size_t newTokenCount ) {}
+};
+
+} } // namespace odemx::synchronization
+
+#endif /* ODEMX_SYNC_BINT_IMPL_INCLUDED */
diff --git a/odemx-lite/include/odemx/synchronization/port/PortData.h b/odemx-lite/include/odemx/synchronization/port/PortData.h
new file mode 100644
index 0000000000000000000000000000000000000000..054c458dff3aceeda917e2332caa1b6b80150b67
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/port/PortData.h
@@ -0,0 +1,71 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002-2008 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file PortData.h
+
+	\author Ronald Kluth
+
+	\date created at 2007/04/04
+
+	\brief Declaration of odemx::synchronization::PortData
+
+	\sa PortT.h, PortT.cpp, PortHeadT.cpp, PortTailT.cpp
+
+	\since 2.0
+*/
+
+#ifndef ODEMX_PORTDATA_INCLUDED
+#define ODEMX_PORTDATA_INCLUDED
+
+namespace odemx {
+namespace synchronization {
+
+/** \class PortData
+
+	\ingroup synch
+
+	\author Ronald Kluth
+
+	\brief %PortData is the default base class for port elements.
+
+	\sa PortHeadT, PortTailT, PortT
+
+	%PortData can be used as common base class for all objects that
+	are handled by ports. With default ports, all class types that
+	define elements such as messages to be passed through a port
+	must be derived	from %PortData because default ports can only handle
+	pointers to subclasses of this type.
+
+	\since 2.0
+*/
+class PortData
+{
+protected:
+	/// Construction
+	PortData() {}
+	/// Copy Construction
+	PortData( const PortData& other ) {}
+
+public:
+	/// Destruction
+	virtual ~PortData() {}
+};
+
+} } // namespace odemx::synchronization
+
+#endif /* ODEMX_PORTDATA_INCLUDED */
diff --git a/odemx-lite/include/odemx/synchronization/port/PortHeadImpl.h b/odemx-lite/include/odemx/synchronization/port/PortHeadImpl.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd2410a7904f036974012e19e6b71b5f829de07c
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/port/PortHeadImpl.h
@@ -0,0 +1,791 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2007, 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//------------------------------------------------------------------------------
+/**
+ * @file PortHeadImpl.h
+ * @author Ronald Kluth
+ * @date created at 2007/04/04
+ * @brief Declaration and Implementation of odemx::synchronization::PortHeadT
+ * @see PortImpl.h, PortTailImpl.h
+ * @since 2.0
+ */
+
+#ifndef ODEMX_SYNC_PORTHEAD_IMPL_INCLUDED
+#define ODEMX_SYNC_PORTHEAD_IMPL_INCLUDED
+
+#include <odemx/base/Process.h>
+#include <odemx/base/Simulation.h>
+#include <odemx/base/DefaultSimulation.h>
+#include <odemx/synchronization/Memory.h>
+#include <odemx/synchronization/port/PortMode.h>
+#include <odemx/synchronization/port/PortImpl.h>
+
+#ifdef _MSC_VER
+#include <memory>
+#else
+#include <memory>
+#endif
+
+
+namespace odemx {
+namespace synchronization {
+
+// forward declarations
+template < typename > class PortTailT;
+template < typename > class PortHeadTObserver;
+
+/**
+ * @ingroup synch
+ * @author Ronald Kluth
+ * @brief %PortHeadT provides read access to a port
+ * @see PortTailT, PortT
+ *
+ * This class manages read access to a limited internal buffer.
+ * It can be run in three different error modes according to
+ * PortMode. Calling @c get on an empty port head will either
+ * block the reader (and alert him upon availability), report
+ * an error, or return zero.
+ *
+ * @since 2.0
+ */
+template < typename ElementT >
+class PortHeadT
+:	public Memory	// is a data::Producer
+,	public data::Observable< PortHeadTObserver< ElementT > >
+,	public std::enable_shared_from_this< PortHeadT< ElementT > >
+{
+public:
+	/// Type of the elements the port can store
+	typedef ElementT ElementType;
+	/// Storage type of the internal buffer
+	typedef typename PortT< ElementType >::StorageType StorageType;
+	/// Size type of the internal buffer
+	typedef typename PortT< ElementType >::SizeType SizeType;
+	/// Pointer type to manage port head objects
+	typedef std::shared_ptr< PortHeadT< ElementType > > Ptr;
+	/// Pointer type to manage port tail objects
+	typedef std::shared_ptr< PortTailT< ElementType > > TailPtr;
+	/// Type of the compatible port head observer
+	typedef PortHeadTObserver< ElementType > ObserverType;
+
+  /// Type of a selection function
+  typedef bool( base::Process::*ElementCondition ) ( ElementType );
+
+	/**
+	 * @brief Creation for user-defined Simulation
+	 * @param sim Reference to the simulation context
+	 * @param label Label of the port, the head's label will be set to "label (head)"
+	 * @param mode Port head's mode, default is WAITING_MODE
+	 * @param limit Maximum number of elements, default is 10000
+	 * @param obs Initial observer
+	 * @return Shared pointer to a newly constructed port head
+	 */
+	static Ptr create( base::Simulation& sim, const data::Label& label,
+			PortMode mode = WAITING_MODE, SizeType limit = 10000, ObserverType* obs = 0 )
+	{
+		Ptr rv( new PortHeadT( sim, label, mode, limit, obs ) );
+		rv->initPort();
+//		rv->port_.reset( new PortType( sim, label, limit ) );
+//		rv->port_->setHead( typename PortType::HeadPtr( rv ) );
+		return rv;
+	}
+
+	/// Destruction, managed by @c shared_ptr
+	virtual ~PortHeadT()
+	{
+		ODEMX_TRACE << log( "destroy" ).scope( typeid( PortHeadT< ElementType > ) );
+		ODEMX_OBS_T( ObserverType, Destroy( this ) );
+	}
+
+	/**
+		\brief Port read access
+		\return Pointer holding the first port element, or an empty pointer
+
+		This function is used to read information from a port. It also
+		responds according to the object's PortMode. In @c WAITING_MODE this
+		leads to the suspension of the calling Process. If the caller
+		is interrupted before receiving an element, it is reactivated
+		and the function returns an empty pointer. In @c ZERO_MODE a
+		miss only returns a null pointer, while in @c ERROR_MODE an error
+		will be sent additionally.
+
+		\note The returned object is always dynamically allocated, which
+		is why an \c auto_ptr is used. This way, the caller never needs
+		to delete the return value. Checking for null pointer is done in
+		the following manner:
+		\code
+		std::unique_ptr< int > ptr = port.get();
+		if( ptr.get() == 0 ) {
+			// handle null return value
+		}
+		else {
+			// use ptr like any other pointer
+		}
+		\endcode
+	*/
+	std::unique_ptr< ElementType > get()
+	{
+		ODEMX_TRACE << log( "get" ).detail( "partner", getPartner() )
+				.scope( typeid( PortHeadT< ElementType > ) );
+
+		ODEMX_OBS_T( ObserverType, Get( this ) );
+
+		while( port_->isEmpty() )
+		{
+			base::Sched* caller = getSimulation().getCurrentSched();
+
+			switch( mode_ )
+			{
+			case WAITING_MODE:
+				if( caller == nullptr )
+				{
+					error << log( "PortHeadT::get(): port in waiting mode called from environment" )
+							.scope( typeid( PortHeadT< ElementType > ) );
+
+					return std::unique_ptr< ElementType >( nullptr );
+				}
+
+				if( caller->getSchedType() == base::Sched::PROCESS )
+				{
+
+					Memory::remember( caller );
+					dynamic_cast< base::Process* >( caller )->sleep();
+
+					// PortHeadT::alert doesn't forget any remembered processes by itself. We have
+					// to delete them manually from the inner waiting list.
+					Memory::forget( caller );
+
+					// check for interruption of waiting period
+					if( dynamic_cast< base::Process* >( caller )->isInterrupted() )
+					{
+						return std::unique_ptr< ElementType >( nullptr );
+					}
+				}
+				else if( caller->getSchedType() == base::Sched::EVENT )
+				{
+					// error: cannot send an event to sleep
+					error << log( "PortHeadT::get(): waiting mode not allowed for events" )
+							.scope( typeid( PortHeadT< ElementType > ) );
+
+					return std::unique_ptr< ElementType >( nullptr );
+				}
+				break;
+
+			case ERROR_MODE:
+				error << log( "PortHeadT::get(): called on empty port" )
+						.scope( typeid( PortHeadT< ElementType > ) );
+
+				return std::unique_ptr< ElementType >( nullptr );
+
+			case ZERO_MODE:
+				return std::unique_ptr< ElementType >( nullptr );
+			}
+		}
+
+
+		// the Port was filled to the limit
+		bool wasFull = port_->isFull();
+
+		// remove first element from Port
+		std::unique_ptr< ElementType > first( port_->get() );
+
+		// alert waiting sender if the port was full and a tail is set
+		if( wasFull && port_->hasTail() )
+		{
+			TailPtr tail = getTail();
+			if( tail->waiting() )
+			{
+				tail->alert();
+			}
+		}
+		return first;
+	}
+
+	/**
+		\brief Port read access based on criterion
+		\return Pointer holding the first port element conforming to the given criterion, or an empty pointer
+
+		This function is used to read information from a port. It also
+		responds according to the object's PortMode. In @c WAITING_MODE this
+		leads to the suspension of the calling Process. If the caller
+		is interrupted before receiving an element, it is reactivated
+		and the function returns an empty pointer. In @c ZERO_MODE a
+		miss only returns a null pointer, while in @c ERROR_MODE an error
+		will be sent additionally.
+
+		\note The returned object is always dynamically allocated, see PortHeadT< ElementType >::get() .
+    \since 3.0
+	*/
+  std::unique_ptr< ElementType > get( ElementCondition sel )
+  {
+    ODEMX_TRACE << log( "get" ).detail( "partner", getPartner() )
+      .scope( typeid( PortHeadT< ElementType > ) );
+
+    ODEMX_OBS_T( ObserverType, Get( this ) );
+
+    bool foundSuitableElement = true; // if no sel function is given, every element in the port is fine
+    typename synchronization::PortHeadT< ElementType >::StorageType::iterator element; // remember the element we'll find
+
+    // only Processes can check the elements in the port.
+    if ( sel && this->getSimulation() . getCurrentSched ()->getSchedType () == base::Sched::PROCESS ) {
+      foundSuitableElement = false;
+      
+      // check every element in the port if it confirms to the criterion sel
+      typename synchronization::PortHeadT< ElementType >::StorageType::iterator it;
+
+      base::Process *current_process = static_cast<base::Process*> (this->getSimulation ().getCurrentSched ());
+
+      for (it = this->port_->begin (); ( it != this->port_->end () && !foundSuitableElement ); it++) 
+      {
+        if ( ( foundSuitableElement = (current_process->*sel)(*it) ) ) 
+          element = it;
+      }
+    }
+
+    while( this->port_->isEmpty() || !foundSuitableElement )
+    {
+      base::Sched* caller = this->getSimulation().getCurrentSched();
+
+      switch( this->mode_ )
+      {
+        case WAITING_MODE:
+          if( caller == nullptr )
+          {
+            error << log( "PortHeadT::get( ElementCondition ): port in waiting mode called from environment" )
+                                             .scope( typeid( PortHeadT< ElementType > ) );
+
+            return std::unique_ptr< ElementType >( nullptr );
+          }
+
+          if( caller->getSchedType() == base::Sched::PROCESS )
+          {
+            // unlike Memory::get(), Memory::get ( ElementCondition ) might try to add a
+            // Process more than once to the inner waiting list. We have to avoid that.
+            if (!Memory::processIsWaiting (*(static_cast< base::Process* >( caller )))) 
+                Memory::remember( caller );
+
+            dynamic_cast< base::Process* >( caller )->sleep();
+
+            // check for interruption of waiting period
+            if( dynamic_cast< base::Process* >( caller )->isInterrupted() )
+            {
+              Memory::forget( caller );
+              return std::unique_ptr< ElementType >( nullptr );
+            } 
+
+            // activation happend via Memory::alert ()
+
+            // if no selection function exists, then we handle this process as if it
+            // called get ()
+            if (!sel) {
+              element = this->port_->inspectLastElement (); 
+              foundSuitableElement = true;
+            }
+            else {
+              base::Process *current_process = static_cast<base::Process*> (this->getSimulation ().getCurrentSched ());
+
+              // Is the new element confirming to the criterion sel? If not, wake up other
+              // sleeping processes.
+              if (!(current_process->*sel)(*(this->port_->inspectLastElement ()))) {
+                const base::SchedList& waitingList = this->getWaiting ();
+                base::SchedList::const_iterator found = std::find( waitingList.begin(), waitingList.end(), current_process);
+
+                if (found != waitingList.end ()) {
+                  ++found;
+                  if (found != waitingList.end ()) {
+                    /* We found another waiting process */
+
+                    // we know that this cast is ok, because only processes are allowed to wait
+                    base::Process *next_process = static_cast<base::Process*>(*found); 
+                    next_process->alertProcess (this); 
+                  }
+                } else {
+                  error << log ("PortHeadT: get ( ElementCondition ): Process wasn't in the waiting list")
+                                                                      .scope ( typeid ( PortHeadT< ElementType > ) );
+                }
+              } else {
+                foundSuitableElement = true;
+                element = this->port_->inspectLastElement ();
+                Memory::forget( caller );
+              }
+            }
+          }
+          else if( caller->getSchedType() == base::Sched::EVENT )
+          {
+            // error: cannot send an event to sleep
+            error << log( "PortHeadT::get( ElementCondition ): waiting mode not allowed for events" )
+                                             .scope( typeid( PortHeadT< ElementType > ) );
+
+            return std::unique_ptr< ElementType >( nullptr );
+          }
+          break;
+
+        case ERROR_MODE:
+          error << log( "PortHeadT::get( ElementCondition ): called on empty port" )
+                                           .scope( typeid( PortHeadT< ElementType > ) );
+
+          return std::unique_ptr< ElementType >( nullptr );
+
+        case ZERO_MODE:
+          return std::unique_ptr< ElementType >( nullptr );
+      }
+    }
+
+    // the Port was filled to the limit
+    bool wasFull = this->port_->isFull();
+
+    // remove last element from Port
+    std::unique_ptr< ElementType > ret( this->port_->get (element) );
+
+    // alert waiting sender if the port was full and a tail is set
+    if( wasFull && this->port_->hasTail() )
+    {
+      typename synchronization::PortHeadT< ElementType >::TailPtr tail = this->getTail();
+      if( tail->waiting() )
+      {
+        tail->alert();
+      }
+    }
+    return ret;
+  }
+
+
+  /**
+    \brief Port access, put element back at front
+    \param element The element to put back into the buffer
+    \return @c true if the port element was successfully added at the front
+
+    This function is used to put an element back at the front
+    of the internal port.
+    \note This function doesn't work as intended with PortHeadT< ElementType >::get ( ElementCondition ),
+    as we don't know where to put the given element in the queue.
+    */
+  bool unGet( const ElementType& element )
+  {
+    ODEMX_TRACE << log( "unGet" ).detail( "partner", getPartner() )
+      .scope( typeid( PortHeadT< ElementType > ) );
+
+		ODEMX_OBS_T( ObserverType, UnGet( this, element ) );
+
+		if( port_->isFull() )
+		{
+			switch ( mode_ )
+			{
+			case WAITING_MODE:
+				/* FALL TROUGH */
+			case ERROR_MODE:
+				error << log( "PortHeadT::unGet(): called on full port" )
+						.scope( typeid( PortHeadT< ElementType > ) );
+				/* FALL TROUGH */
+			case ZERO_MODE:
+				return false;
+			}
+		}
+		// insert PortData at the front of the Port queue
+		port_->unGet( element );
+		return true;
+	}
+
+	/**
+		\brief Get corresponding port tail
+		\return Pointer to the corresponding tail of this head
+
+		This function provides access to the tail of a port head.
+		If it does not exist yet, it is created.
+	*/
+	TailPtr getTail()
+	{
+		TailPtr tail = port_->getTail();
+
+		// check if the tail pointer is empty
+		if( ! tail )
+		{
+			// create new Tail
+			tail.reset( new PortTailT< ElementType >( getSimulation(),
+					port_->getLabel(), mode_, port_->getCapacity() ) );
+
+			// register new Tail with Head's Port
+			port_->setTail( typename PortType::TailPtr( tail ) );
+
+			// register Head's internal Port with the Tail
+			tail->port_ = this->port_;
+		}
+		return tail;
+	}
+
+	/**
+		\brief Get maximum capacity of the internal port
+		\return Capacity of the buffer
+
+		This function is used to determine the maximum number of
+		elements that can be buffered by the internal port.
+
+		\sa setMaxCapacity()
+	*/
+	SizeType getMaxCapacity()
+	{
+		return port_->getCapacity();
+	}
+
+	/**
+		\brief Change maximum capacity of the port
+		\param limit The new maximum capacity of the internal port
+
+		This function allows to change the maximum number of elements the
+		internal buffer can hold.
+
+		\sa getMaxCapacity()
+	*/
+	void setMaxCapacity( SizeType limit )
+	{
+		ODEMX_TRACE << log( "change max capacity" )
+				.valueChange( port_->getCapacity(), limit )
+				.scope( typeid( PortHeadT< ElementType > ) );
+
+		ODEMX_OBS_ATTR_T( ObserverType, MaxCapacity, port_->getCapacity(), limit );
+
+		port_->setCapacity( limit );
+	}
+
+	/// Determine the port head's mode
+	PortMode getMode() const
+	{
+		return mode_;
+	}
+
+	/// Change the port head's mode
+	void setMode( PortMode newMode )
+	{
+		ODEMX_TRACE << log( "change mode" ).valueChange( toString( mode_ ), toString( newMode ) )
+				.scope( typeid( PortHeadT< ElementType > ) );
+
+		ODEMX_OBS_ATTR_T( ObserverType, Mode, mode_, newMode );
+
+		mode_ = newMode;
+	}
+
+	/**
+		\brief Get current number of port elements
+		\return Current number of elements
+
+		This method returns the current number of buffered elements.
+	*/
+	SizeType count() const
+	{
+		return port_->getElementCount();
+	}
+
+	/**
+		\brief Check for availability of an element
+		\return @c true if the port is not empty
+
+		This function is used to determine whether an element is
+		available from the internal port.
+	*/
+	virtual bool isAvailable()
+	{
+		return ! port_->isEmpty();
+	}
+
+	/**
+		\brief Cut this port head from its tail
+		\return New port head of the old internal port
+
+		This function will create a	new internal port, which
+		is attached to this head. A new tail for that port must then be
+		requested via getTail(). Furthermore, a new port head will
+		be attached to the old internal port. That new head will be
+		returned.
+
+		This provides the ability to insert a process into
+		the middle of a port connection, for example as a filter.
+
+		\sa splice()
+	*/
+	Ptr cut()
+	{
+		// change
+		//      old_Port_head -- old_Port -- old_Port_tail
+		// into
+		//      old_Port_head -- new_Port (___get new tail___)
+		//      new_Port_head -- old_Port -- old_Port_tail
+		// where
+		//      old_Port_head == this
+		// return
+		//      new_Port_head.
+
+		ODEMX_TRACE << log( "cut" ).detail( "partner", getPartner() )
+				.scope( typeid( PortHeadT< ElementType > ) );
+
+		ODEMX_OBS_T( ObserverType, Cut( this ) );
+
+		// remember old Port
+		PortPtr oldPort = port_;
+
+		// create a new Head and thereby a new Port
+		Ptr newHead( new PortHeadT< ElementType >(
+				getSimulation(),
+				data::Label( "Cut " ) + oldPort->getLabel(),
+				mode_, oldPort->getCapacity() ) );
+
+		// get the new Port
+		PortPtr newPort = newHead->port_;
+
+		// put the new head on the old Port
+		oldPort->setHead( typename PortType::HeadPtr( newHead ) );
+		newHead->port_ = oldPort;
+
+		// put the old head (== this) on the new Port
+		newPort->setHead( typename PortType::HeadPtr( this->shared_from_this() ) );
+		port_ = newPort;
+
+		return newHead;
+	}
+
+	/**
+		\brief Splice two separate ports together
+		\param oldTail The tail of the port to which this head's buffer will be added
+
+		This function is the reverse operation of cut(). It is used to join
+		two ports together. This head must be upstream of, i.e. before,
+		oldTail's port, which this buffer will be joined with.
+		The contents of this Port is added to oldTail's Port. If
+		the new head's buffer becomes non-empty, it is alerted.
+
+		\warning Some objects become invalid with this operation!
+		This head, oldTail, and oldTail's Port should not be accessed anymore
+		after calling this method.
+
+		\note This method does not check the maximum Port capacity before
+		splicing lists.
+
+		\sa cut()
+	*/
+	void splice( TailPtr oldTail )
+	{
+		// this PortHead is supposed to be upstream to the portTail oldTail:
+		// >> headsTail -- headsPort -- thisHead >> oldTail -- tailsPort -- tailsHead >>
+		// what remmains afterwards is this:
+		// >> headstail -- tailsPort -- tailsHead >>
+		//   add the contents of headsPort to tailsPort
+		//   destroy thisHead and oldTail
+		//   alert the spliced PortHead if a significant state change happened
+
+		ODEMX_TRACE << log( "splice" ).detail( "partner", getPartner() )
+				.scope( typeid( PortHeadT< ElementType > ) );
+
+		ODEMX_OBS_T( ObserverType, Splice( this, oldTail ) );
+
+		// remember parts
+		Ptr tailsHead = oldTail->getHead(); // may be 0
+		TailPtr headsTail = port_->getTail(); // may be 0
+		PortPtr tailsPort = oldTail->port_;
+		PortPtr headsPort = port_;
+
+		// and their element counts
+		int tailsCount = tailsPort->getElementCount();
+		int headsCount = headsPort->getElementCount();
+
+		// append head's buffer to tail's buffer via std::list::splice()
+		if( headsCount > 0 )
+		{
+			tailsPort->spliceBuffer( headsPort->getBuffer(), true );
+		}
+
+		// patch the head's tail onto tail's Port, which has it's own head,
+		// this PortHead becomes superfluous, requires pointers in both directions!
+		if( headsTail )
+		{
+			tailsPort->setTail( headsTail );
+			headsTail->port_ = tailsPort;
+		}
+
+		// alert the new head if its Port becomes non-empty
+		if( (tailsCount == 0) && (headsCount > 0) && (tailsHead) )
+		{
+			if( tailsHead->waiting() )
+			{
+				tailsHead->alert();
+			}
+		}
+	}
+
+	/**
+		\brief Splice internal lists of two separate ports together
+		\param tail The tail of the port whose buffer will be added to this
+		\param append Determines whether to append or prepend tail's contents
+
+		This function is used to join two ports' buffer contents together
+		in the same way as std::list::splice(). The contents of the \p
+		tail PortT will be moved to \p this port, where parameter \p append
+		can	be used to specify whether the data will be appended or prepended
+		to this port. Default is append.
+
+		\note This function does not check the maximum Port capacity before
+		splicing lists.
+	*/
+	void cppSplice( TailPtr tail, bool append = true )
+	{
+		ODEMX_TRACE << log( "cpp splice" ).detail( "partner", getPartner() )
+				.scope( typeid( PortHeadT< ElementType > ) );
+
+		ODEMX_OBS_T( ObserverType, CppSplice( this, tail, append ) );
+
+		if( append )
+		{
+			port_->spliceBuffer( tail->port_->getBuffer(), true );
+		}
+		else
+		{
+			port_->spliceBuffer( tail->port_->getBuffer(), false );
+		}
+	}
+
+	/// Get the storage buffer, allows write access for splicing
+	const StorageType& getBuffer() const
+	{
+		return const_cast< const StorageType& >( port_->getBuffer() );
+	}
+private:
+
+	friend class PortTailT< ElementType >;
+
+	/**
+		\brief Alert the first stored process
+
+		This function is designed to wake up suspended processes,
+		i.e. reschedule them at simulation time \c now when they
+		are waiting for an empty port to receive an element. Only
+		the first remembered process is alerted by the %PortHead.
+	*/
+	virtual void alert()
+	{
+		// simpler implementation than in Memory because get() does
+		// some checking already and only the first waiting Process is alerted
+
+		if( ! Memory::waiting() )
+		{
+			// warning: no object to wake
+			if ( mode_ != ZERO_MODE )
+			{
+				warning << log( "PortHeadT::alert(): no process saved" )
+						.scope( typeid( PortHeadT< ElementType > ) );
+			}
+			return;
+		}
+
+		// get() allows WAITING_MODE only for Processes, so cast is okay here
+		base::Process* rememberedObject =
+			static_cast< base::Process* >( Memory::getWaiting().front() );
+
+		ODEMX_TRACE << log( "alert" ).detail( "partner", rememberedObject->getLabel() )
+				.scope( typeid( PortHeadT< ElementType > ) );
+
+		ODEMX_OBS_T( ObserverType, Alert( this, rememberedObject ) );
+
+		// wake up the process
+		rememberedObject->alertProcess( this );
+	}
+
+	/// Get the label of the currently active Sched object, or the simulation
+	const data::Label& getPartner()
+	{
+		// return the current process or event, if one is active
+		if( getSimulation().getCurrentSched() != nullptr )
+		{
+			return getSimulation().getCurrentSched()->getLabel();
+		}
+		else
+		{
+			return getSimulation().getLabel();
+		}
+	}
+
+private:
+	/// Type of the internal port object
+	typedef PortT< ElementType > PortType;
+	/// Pointer type to manage the internal PortT object
+	typedef std::shared_ptr< PortType > PortPtr;
+
+	PortPtr port_; ///< Pointer to the internal port object
+	PortMode mode_; ///< Mode for read requests
+
+protected:
+	/// Construction private, use @c create instead
+	PortHeadT( base::Simulation& sim, const data::Label& label,
+			PortMode mode = WAITING_MODE, SizeType limit = 10000,
+			ObserverType* obs = 0 )
+	:	Memory( sim, label + " (head)", IMemory::PORTHEAD )
+	,	data::Observable< ObserverType >( obs )
+	,	mode_( mode )
+	{
+		ODEMX_TRACE << log( "create" ).scope( typeid( PortHeadT< ElementType > ) );
+		ODEMX_OBS_T( ObserverType, Create( this ) );
+
+		this->port_.reset( new PortType( getSimulation(), label, limit ) );
+	}
+	/// Connect the port head to the internal buffer, needed after construction
+	void initPort()
+	{
+		this->port_->setHead( this->shared_from_this() );
+	}
+private:
+	/// No copying
+	PortHeadT( const PortHeadT& );
+	/// No assignment
+	PortHeadT& operator=( const PortHeadT& );
+};
+
+/**
+ * @interface PortHeadTObserver
+ * @ingroup synch
+ * @author Ronald Kluth
+ * @brief Observer for PortHeadT-specific calls.
+ * @see PortHeadT
+ * @since 2.0
+ */
+template < typename ElementT >
+class PortHeadTObserver: public MemoryObserver {
+public:
+	typedef ElementT ElementType;
+	typedef typename PortT< ElementType >::SizeType SizeType;
+
+	virtual ~PortHeadTObserver() {}
+
+	virtual void onDestroy( PortHeadT< ElementType >* sender ) {} ///< Destruction
+
+	virtual void onGet( PortHeadT< ElementType >* sender ) {}
+	virtual void onUnGet( PortHeadT< ElementType >* sender, const ElementType& newElement ) {}
+	virtual void onCut( PortHeadT< ElementType >* sender ) {}
+	virtual void onSplice( PortHeadT< ElementType >* sender,
+			typename PortHeadT< ElementType >::TailPtr oldTail ) {}
+	virtual void onCppSplice( PortHeadT< ElementType >* sender,
+			typename PortHeadT< ElementType >::TailPtr oldTail, bool append ) {}
+	virtual void onAlert( PortHeadT< ElementType >* sender, base::Sched* alerted ) {}
+
+	/// PortHead mode change
+	virtual void onChangeMode( PortHeadT< ElementType >* sender,
+			PortMode oldMode, PortMode newMode ) {}
+	/// PortHead capacity change
+	virtual void onChangeMaxCapacity( PortHeadT< ElementType >* sender,
+			SizeType oldLimit, SizeType newLimit ) {}
+};
+
+} } // namespace odemx::synchronization
+
+#endif /* ODEMX_SYNC_PORTHEAD_IMPL_INCLUDED */
diff --git a/odemx-lite/include/odemx/synchronization/port/PortImpl.h b/odemx-lite/include/odemx/synchronization/port/PortImpl.h
new file mode 100644
index 0000000000000000000000000000000000000000..e9d4c9739ab3c5025e4e21593f65b2a31fc05979
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/port/PortImpl.h
@@ -0,0 +1,291 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2007, 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//------------------------------------------------------------------------------
+/**
+ * @file PortImpl.h
+ * @author Ronald Kluth
+ * @date created at 2007/04/04
+ * @brief Declaration and Implementation of odemx::synchronization::PortT
+ * @see PortHeadImpl.h, PortTailImpl.h
+ * @since 2.0
+ */
+
+#ifndef ODEMX_SYNC_PORT_IMPL_INCLUDED
+#define ODEMX_SYNC_PORT_IMPL_INCLUDED
+
+#include <odemx/data/Producer.h>
+#include <odemx/util/TypeToString.h>
+
+#include <list>
+
+#ifdef _MSC_VER
+#include <memory>
+#else
+#include <memory>
+#endif
+
+
+namespace odemx {
+
+//----------------------------------------------------------forward declarations
+
+namespace base { class Simulation; }
+
+namespace synchronization {
+
+template < typename > class PortHeadT;
+template < typename > class PortTailT;
+
+//-----------------------------------------------------------header declarations
+
+/**
+ * @ingroup synch
+ * @author Ronald Kluth
+ * @brief %PortT is implements the internal buffer for PortHeadT and PortTailT
+ * @see PortHeadT, PortTailT
+ *
+ * This internal class manages the limited buffer that is the base
+ * for a communications port. It maintains references to its port tail,
+ * which describes the input interface, and its port head, which is the
+ * output interface of a port.
+ *
+ * @note In order to use and access ports, you need to create either a
+ * PortHeadT or PortTailT object, which, respectively, provide the read
+ * and write interface to the buffer.
+ *
+ * @since 2.0
+ */
+template < typename ElementT >
+class PortT
+:	public data::Producer
+{
+public:
+	/// Destruction
+	virtual ~PortT()
+	{
+		if( ! buffer_.empty() )
+		{
+			warning << log( "PortT::~PortT(): port not empty" )
+					.scope( typeid( PortT< ElementType > ) );
+		}
+	}
+
+	/// Type of the buffer elements
+	typedef ElementT ElementType;
+	/// Storage type for the buffer
+	typedef std::list< ElementType > StorageType;
+	/// Storage type for the buffer
+	typedef typename StorageType::size_type SizeType;
+	/// Head pointer type
+	typedef std::weak_ptr< PortHeadT< ElementType > > HeadPtr;
+	/// Tail pointer type
+	typedef std::weak_ptr< PortTailT< ElementType > > TailPtr;
+
+private:
+	friend class PortHeadT< ElementType >;
+	friend class PortTailT< ElementType >;
+
+	/// Construction, used only by head / tail
+	PortT( base::Simulation& sim, const data::Label& label, SizeType limit )
+	:	data::Producer( sim, label )
+	,	maxCapacity_( limit )
+	,	elementCount_( 0 )
+	{
+		// check for invalid port capacity
+		if( limit == 0 )
+		{
+			error << log( "PortT(): attempt to create Port with invalid capacity, using default" )
+					.scope( typeid( PortT< ElementType > ) );
+
+			maxCapacity_ = defaultLimit;
+		}
+
+		statistics << param( "element type", odemx::typeToString( typeid( ElementType ) ) )
+				.scope( typeid( PortT< ElementType > ) );
+		statistics << param( "maximum capacity", maxCapacity_ )
+				.scope( typeid( PortT< ElementType > ) );
+	}
+
+	/// Append an element to the buffer
+	void put( const ElementType& element )
+	{
+		buffer_.push_back( element );
+		++elementCount_;
+
+		statistics << count( "put calls" ).scope( typeid( PortT< ElementType > ) );
+		statistics << update( "buffer size", elementCount_ )
+				.scope( typeid( PortT< ElementType > ) );
+	}
+
+	/// Get the first element from the buffer (and remove it)
+	std::unique_ptr< ElementType > get()
+	{
+		std::unique_ptr< ElementType > rv( new ElementType( buffer_.front() ) );
+		buffer_.pop_front();
+		--elementCount_;
+
+		statistics << count( "get calls" ).scope( typeid( PortT< ElementType > ) );
+		statistics << update( "buffer size", elementCount_ )
+				.scope( typeid( PortT< ElementType > ) );
+		return rv;
+	}
+  
+	/// Get a specific element from the buffer (and remove it)
+	std::unique_ptr< ElementType > get(typename StorageType::iterator it)
+	{
+		std::unique_ptr< ElementType > rv( new ElementType( *it ) );
+		buffer_.erase (it);
+		--elementCount_;
+
+		statistics << count( "get calls" ).scope( typeid( PortT< ElementType > ) );
+		statistics << update( "buffer size", elementCount_ )
+				.scope( typeid( PortT< ElementType > ) );
+		return rv;
+	}
+
+	/// Put an element back at the front of the buffer
+  /// TODO doesn't work, if we can take an arbitrary element
+  /// XXX nochmal darüber nachdenken (generell)
+	void unGet( const ElementType& element )
+	{
+		buffer_.push_front( element );
+		++elementCount_;
+
+		statistics << count( "unGet calls" ).scope( typeid( PortT< ElementType > ) );
+		statistics << update( "buffer size", elementCount_ )
+				.scope( typeid( PortT< ElementType > ) );
+	}
+
+  /// XXX get an iterator to the contained  buffer
+  typename StorageType::iterator begin () {
+    return buffer_.begin ();
+  }
+
+  /// XXX
+  typename StorageType::iterator end () {
+    return buffer_.end ();
+  }
+
+  /// TODO const? Reference?
+  /// TODO note: no error checks! we assume the user isn't dumb
+  typename StorageType::iterator inspectLastElement () {
+    return --(buffer_.end ());
+  }
+
+
+	/// Check whether the buffer contains elements
+	bool isEmpty() const
+	{
+		return buffer_.empty();
+	}
+
+	/// Check whether the internal buffer is already full
+	bool isFull() const
+	{
+		return elementCount_ >= maxCapacity_;
+	}
+
+	/// Check if a head exists
+	bool hasHead() const
+	{
+		return ! head_.expired();
+	}
+
+	/// Set a new head for this port
+	void setHead( HeadPtr head )
+	{
+		head_ = head;
+	}
+
+	/// Get a pointer to the port's head, may be empty
+	std::shared_ptr< PortHeadT< ElementType > > getHead() const
+	{
+		return head_.lock();
+	}
+
+	/// Check if a tail exists
+	bool hasTail() const
+	{
+		return ! tail_.expired();
+	}
+
+	/// Set a new tail for the port
+	void setTail( TailPtr tail )
+	{
+		tail_ = tail;
+	}
+
+	/// Get a pointer to the port's tail, may be empty
+	std::shared_ptr< PortTailT< ElementType > > getTail() const
+	{
+		return tail_.lock();
+	}
+
+	/// Change the maximum capacity of the internal buffer
+	void setCapacity( SizeType limit )
+	{
+		maxCapacity_ = limit;
+	}
+
+	/// Get the maximum allowed capacity of the internal buffer
+	SizeType getCapacity() const
+	{
+		return maxCapacity_;
+	}
+
+	/// Check the number of elements currently stored in the buffer
+	SizeType getElementCount() const
+	{
+		return elementCount_;
+	}
+
+	/// Move items from @c buffer to this port's storage buffer
+	void spliceBuffer( StorageType& buffer, bool append )
+	{
+		elementCount_ += buffer.size();
+		if( append )
+		{
+			buffer_.splice( buffer_.end(), buffer );
+		}
+		else
+		{
+			buffer_.splice( buffer_.begin(), buffer );
+		}
+		statistics << update( "buffer size", elementCount_ )
+				.scope( typeid( PortT< ElementType > ) );
+	}
+
+	/// Get the storage buffer, allows write access for splicing
+	StorageType& getBuffer()
+	{
+		return buffer_;
+	}
+
+private:
+	SizeType maxCapacity_; ///< maximum buffer capacity
+	SizeType elementCount_; ///< current number of elements in the buffer
+	StorageType buffer_; ///< internal buffer for elements of type ElementType
+	HeadPtr head_; ///< corresponding Head interface
+	TailPtr tail_; ///< corresponding Tail interface
+	/// Default value for maximum port capacity
+	static const SizeType defaultLimit = 10000;
+};
+
+} } // namespace odemx::synchronization
+
+#endif /* ODEMX_SYNC_PORT_IMPL_INCLUDED */
diff --git a/odemx-lite/include/odemx/synchronization/port/PortMode.h b/odemx-lite/include/odemx/synchronization/port/PortMode.h
new file mode 100644
index 0000000000000000000000000000000000000000..6120eae25166758eeb740d1d0f86a2956c13ec9d
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/port/PortMode.h
@@ -0,0 +1,65 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//------------------------------------------------------------------------------
+/**
+ * @file PortMode.h
+ * @author Ronald Kluth
+ * @date created at 2009/09/21
+ * @brief Declaration of enum odemx::synchronization::PortMode
+ * @see PortHeadImpl.h, PortTailImpl.h
+ * @since 3.0
+ */
+
+#ifndef ODEMX_SYNC_PORTMODE_INCLUDED
+#define ODEMX_SYNC_PORTMODE_INCLUDED
+
+namespace odemx {
+namespace synchronization {
+
+/**
+ * @ingroup synch
+ * @author Ronald Kluth
+ * @brief Port modes
+ * @see PortHeadT PortTailT
+ *
+ * Since ports implement a limited buffer, a behavior needs to be
+ * defined for when a port is full, but an element is to be inserted,
+ * or when a port is empty and some process is trying to read from it.
+ * Modes for port head and corresponding port tail can differ.
+ */
+enum PortMode
+{
+	ERROR_MODE,		///< error when full/empty
+	WAITING_MODE,	///< context switch when full/empty
+	ZERO_MODE		///< ignore caller when full/empty, return 0
+};
+
+inline std::string toString( const PortMode mode )
+{
+	switch( mode )
+	{
+	case ERROR_MODE: return "ERROR_MODE";
+	case WAITING_MODE: return "WAITING_MODE";
+	case ZERO_MODE: return "ZERO_MODE";
+	}
+	return "ERROR";
+}
+
+} } // namespace odemx::synchronization
+
+#endif /* ODEMX_SYNC_PORTMODE_INCLUDED */
diff --git a/odemx-lite/include/odemx/synchronization/port/PortTailImpl.h b/odemx-lite/include/odemx/synchronization/port/PortTailImpl.h
new file mode 100644
index 0000000000000000000000000000000000000000..4d25c81e881a87413374c720ee16586c5176b052
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/port/PortTailImpl.h
@@ -0,0 +1,546 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2007, 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//------------------------------------------------------------------------------
+/**
+ * @file PortTailImpl.h
+ * @author Ronald Kluth
+ * @date created at 2007/04/04
+ * @brief Declaration and Implementation of odemx::synchronization::PortTailT
+ * @see PortHeadImpl.h, PortImpl.h
+ * @since 2.0
+ */
+
+#ifndef ODEMX_SYNC_PORTTAIL_INCLUDED
+#define ODEMX_SYNC_PORTTAIL_INCLUDED
+
+#include <odemx/base/Process.h>
+#include <odemx/base/Simulation.h>
+#include <odemx/base/DefaultSimulation.h>
+#include <odemx/synchronization/Memory.h>
+#include <odemx/synchronization/port/PortMode.h>
+#include <odemx/synchronization/port/PortImpl.h>
+#include <odemx/data/Observable.h>
+
+namespace odemx {
+namespace synchronization {
+
+// forward declarations
+template < typename > class PortHeadT;
+template < typename > class PortTailTObserver;
+
+/**
+ * @ingroup synch
+ * @author Ronald Kluth
+ * @brief %PortTailT provides write access to a port
+ * @see PortHeadT, PortT
+ *
+ * This class manages write access to a limited internal buffer.
+ * It can be run in three different error modes according to
+ * PortMode. Calling @c put on a full port will either block
+ * the sender (and alert him upon availability), report an error,
+ * or return zero.
+ *
+ * @since 2.0
+ */
+template < typename ElementT >
+class PortTailT
+:	public Memory	// is a data::Producer
+,	public data::Observable< PortTailTObserver< ElementT > >
+,	public std::enable_shared_from_this< PortTailT< ElementT > >
+{
+public:
+	/// Type of the elements the port can store
+	typedef ElementT ElementType;
+	/// Storage type of the internal buffer
+	typedef typename PortT< ElementType >::StorageType StorageType;
+	/// Size type of the internal buffer
+	typedef typename PortT< ElementType >::SizeType SizeType;
+	/// Pointer type to manage port tail objects
+	typedef std::shared_ptr< PortTailT< ElementType > > Ptr;
+	/// Pointer type to manage port head objects
+	typedef std::shared_ptr< PortHeadT< ElementType > > HeadPtr;
+	/// Type of the compatible port head observer
+	typedef PortTailTObserver< ElementType > ObserverType;
+
+	/**
+	 * @brief Creation for user-defined Simulation
+	 * @param sim Reference to the simulation context
+	 * @param label Label of the port, the tail's label will be set to "label (tail)"
+	 * @param mode Port tail's mode, default is WAITING_MODE
+	 * @param limit Maximum number of elements, default is 10000
+	 * @param obs Initial observer
+	 * @return Shared pointer to a newly constructed port tail
+	 */
+	static Ptr create( base::Simulation& sim, const data::Label& label,
+			PortMode mode = WAITING_MODE, SizeType limit = 10000, ObserverType* obs = 0 )
+	{
+		Ptr rv( new PortTailT( sim, label, mode, limit, obs ) );
+		rv->initPort();
+//		rv->port_.reset( new PortType( sim, label, limit ) );
+//		rv->port_->setTail( typename PortType::TailPtr( rv ) );
+		return rv;
+	}
+
+	/// Destruction, managed by @c shared_ptr
+	virtual ~PortTailT()
+	{
+		ODEMX_TRACE << log( "destroy" ).scope( typeid( PortTailT< ElementType > ) );
+		ODEMX_OBS_T( ObserverType, Destroy( this ) );
+	}
+
+	/**
+		\brief Port write access
+		\param newElement The element to be inserted into the port
+		\return @c 1 upon success, @c 0 in @c ZERO_MODE or interrupt(), else @c -1
+
+		This function is used to insert an element into a port. It also
+		responds according to the tail's PortMode. In @c WAITING_MODE, the
+		calling Process will be suspended if the Port is already full. When
+		space becomes available, waiting callers will be alerted in a
+		FIFO-manner. If a blocked caller is interrupted, the Process will be
+		activated immediately and put() returns 0.
+	*/
+	int put( const ElementType& newElement )
+	{
+		ODEMX_TRACE << log( "put" ).detail( "partner", getPartner() )
+				.scope( typeid( PortTailT< ElementType > ) );
+
+		ODEMX_OBS_T( ObserverType, Put( this, newElement ) );
+
+		while( port_->isFull() )
+		{
+			base::Sched* caller = getSimulation().getCurrentSched();
+
+			switch ( mode_ )
+			{
+			case WAITING_MODE:
+				if ( caller == 0 )
+				{
+					error << log( "PortTailT::put(): port in waiting mode called from environment" )
+							.scope( typeid( PortTailT< ElementType > ) );
+					return -1;
+				}
+
+				if ( caller->getSchedType() == base::Sched::PROCESS )
+				{
+					Memory::remember( caller );
+					dynamic_cast< base::Process* >( caller )->sleep();
+
+					// check for interruption of waiting period
+					if( dynamic_cast< base::Process* >( caller )->isInterrupted() )
+					{
+						Memory::forget( caller );
+						return 0;
+					}
+				}
+				else if ( caller->getSchedType() == base::Sched::EVENT )
+				{
+					// error: cannot send an event to sleep
+					error << log( "PortTailT::put(): waiting mode not allowed for events" )
+							.scope( typeid( PortTailT< ElementType > ) );
+					return -1;
+				}
+				break;
+
+			case ERROR_MODE:
+				error << log( "PortTailT::put(): cannot add element to full port" )
+						.scope( typeid( PortTailT< ElementType > ) );
+				return -1;
+
+			case ZERO_MODE:
+				return 0;
+			}
+		}
+
+		// insert new element
+		port_->put( newElement );
+
+		// notify waiting Processes of newly inserted element
+		if( port_->hasHead() )
+		{
+			HeadPtr head = getHead();
+			if( head->waiting() )
+			{
+				head->alert();
+			}
+		}
+		return 1; // success
+	}
+
+	/**
+		\brief Get corresponding port head
+		\return Pointer to the corresponding head to this tail
+
+		This function provides access to the head of a port tail.
+		If it does not exist yet, it is created.
+	*/
+	HeadPtr getHead()
+	{
+		HeadPtr head = port_->getHead();
+
+		// check if the pointer is empty
+		if( ! head )
+		{
+			// create new Head
+			head.reset( new PortHeadT< ElementType >( getSimulation(),
+					port_->getLabel(), mode_, port_->getCapacity() ) );
+
+			// register new Head with Tail's Port
+			port_->setHead( typename PortType::HeadPtr( head ) );
+
+			// register Tail's internal Port with the Head
+			head->port_ = this->port_;
+		}
+		return head;
+	}
+
+	/**
+		\brief Get maximum capacity of the internal port
+		\return Capacity of the buffer
+
+		This function is used to determine the maximum number of
+		elements that can be buffered by the internal port.
+
+		\sa setMaxCapacity()
+	*/
+	SizeType getMaxCapacity()
+	{
+		return port_->getCapacity();
+	}
+
+	/**
+		\brief Change maximum capacity of the port
+		\param limit The new maximum capacity of the internal port
+
+		This function allows to change the maximum number of elements the
+		internal buffer can hold.
+
+		\sa getMaxCapacity()
+	*/
+	void setMaxCapacity( SizeType limit )
+	{
+		ODEMX_TRACE << log( "change max capacity" )
+				.valueChange( port_->getCapacity(), limit )
+				.scope( typeid( PortTailT< ElementType > ) );
+
+		ODEMX_OBS_ATTR_T( ObserverType, MaxCapacity, port_->getCapacity(), limit );
+
+		port_->setCapacity( limit );
+	}
+
+	/// Determine the port tail's mode
+	PortMode getMode() const
+	{
+		return mode_;
+	}
+
+	/// Change the port tail's mode
+	void setMode( PortMode newMode )
+	{
+		ODEMX_TRACE << log( "change mode" ).valueChange( toString( mode_ ), toString( newMode ) )
+				.scope( typeid( PortTailT< ElementType > ) );
+
+		ODEMX_OBS_ATTR_T( ObserverType, Mode, mode_, newMode );
+
+		mode_ = newMode;
+	}
+
+	/**
+		\brief Get current number of port elements
+		\return Current number of elements
+
+		This method returns the current number of buffered elements.
+	*/
+	SizeType count() const
+	{
+		return port_->getElementCount();
+	}
+
+	/**
+		\brief Check for availability of buffer space
+		\return @c true if the port is not full
+
+		This function is used to determine whether there is space
+		available in the internal port.
+	*/
+	virtual bool isAvailable()
+	{
+		return ! port_->isFull();
+	}
+
+	/**
+		\brief Cut this port tail from its head
+		\return New port tail
+
+		This function will create a	new internal port, which
+		is attached to this tail. A new head for that port must then be
+		requested via getHead(). Furthermore, a new port tail will
+		be attached to the old internal port. That new tail will be
+		returned.
+
+		This provides the ability to insert a process into
+		the middle of a port connection, for example as a filter.
+
+		\sa splice()
+	*/
+	Ptr cut()
+	{
+		// change
+		//      old_Port_head -- old_Port -- old_Port_tail
+		// into
+		//      old_Port_head -- old_Port -- new_Port_tail
+		//      (__get new head___) new_Port -- old_Port_tail
+		// where
+		//      old_Port_tail == this
+		// return
+		//      new_Port_tail.
+
+		ODEMX_TRACE << log( "cut" ).detail( "partner", getPartner() )
+				.scope( typeid( PortTailT< ElementType > ) );
+
+		ODEMX_OBS_T( ObserverType, Cut( this ) );
+
+		// remember old Port
+		PortPtr oldPort = port_;
+
+		// create a new Tail and thereby a new Port
+		Ptr newTail( new PortTailT< ElementType >(
+				getSimulation(),
+				data::Label( "Cut " ) + oldPort->getLabel(),
+				mode_, oldPort->getCapacity() ) );
+
+		// get the new Port
+		PortPtr newPort = newTail->port_;
+
+		// put the new tail on the old Port
+		oldPort->setTail( typename PortType::TailPtr( newTail ) );
+		newTail->port_ = oldPort;
+
+		// put the old tail (==this) on the new Port
+		newPort->setTail( typename PortType::TailPtr( this->shared_from_this() ) );
+		port_ = newPort;
+
+		return newTail;
+	}
+
+	/**
+		\brief Splice two separate ports together
+		\param oldHead
+			the tail of the port to which this head's buffer will be attached
+
+		This function is used to join two ports together. This tail must
+		be downstream of, i.e. positioned after, oldHead's port, which
+		this buffer will be joined with. The contents of this Port
+		is added to oldHead's Port.
+
+		\warning Some objects become invalid with this operation!
+		This tail, oldHead, and this Port should not be accessed anymore after
+		calling this method.
+
+		\note This method does not check the maximum Port capacity before
+		splicing lists.
+
+		\sa cut()
+	*/
+	void splice( HeadPtr oldHead )
+	{
+		// this PortTail is supposed to be downstream to the PortHead oldHead:
+		// >> headsTail -- headsPort -- oldHead >> thisTail -- tailsPort -- tailsHead >>
+
+		ODEMX_TRACE << log( "splice" ).detail( "partner", getPartner() )
+				.scope( typeid( PortTailT< ElementType > ) );
+
+		ODEMX_OBS_T( ObserverType, Splice( this, oldHead ) );
+
+		oldHead->splice( this->shared_from_this() );
+	}
+
+	/**
+		\brief Splice internal lists of two separate ports together
+		\param head The head of the port whose buffer will be added to this
+		\param append Determines whether to append or prepend head's contents
+
+		This function is used to join two ports' buffer contents together
+		in the same way as std::list::splice(). The contents of the \p
+		tail PortT will be moved to \p this port, where parameter \p append
+		can	be used to specify whether the data will appended or prepended
+		to this port. Default is append.
+
+		\note This function does not check the maximum Port capacity before
+		splicing lists.
+	*/
+	void cppSplice( HeadPtr head, bool append = true )
+	{
+		ODEMX_TRACE << log( "cpp splice" ).detail( "partner", getPartner() )
+				.scope( typeid( PortTailT< ElementType > ) );
+
+		ODEMX_OBS_T( ObserverType, CppSplice( this, head, append ) );
+
+		if( append )
+		{
+			port_->spliceBuffer( head->port_->getBuffer(), true );
+		}
+		else
+		{
+			port_->spliceBuffer( head->port_->getBuffer(), false );
+		}
+	}
+
+	/**
+		\brief Determine free space of the port
+		\return Number of elements that the port can still take in
+
+		This function returns the remaining available space
+		of the internal buffer.
+	*/
+	SizeType getAvailableSpace()
+	{
+		return port_->getCapacity() - port_->getElementCount();
+	}
+
+	/// Get the storage buffer, allows write access for splicing
+	const StorageType& getBuffer() const
+	{
+		return const_cast< const StorageType& >( port_->getBuffer() );
+	}
+
+private:
+
+	friend class PortHeadT< ElementType >;
+
+	/**
+		\brief Alert the first stored process
+
+		This function is designed to wake up suspended processes,
+		i.e. reschedule them at simulation time \c now when they
+		are waiting for a full port to become available again. Only
+		the first remembered process is alerted by the port tail.
+	*/
+	virtual void alert()
+	{
+		// simpler implementation than in Memory because put() does
+		// some checking already and only the first waiting Process is alerted
+
+		if( ! Memory::waiting() )
+		{
+			// warning: no object to wake
+			if ( mode_ != ZERO_MODE )
+			{
+				warning << log( "PortTailT::alert(): no process saved" )
+						.scope( typeid( PortTailT< ElementType > ) );
+			}
+			return;
+		}
+
+		// put() allows WAITING_MODE only for Processes, so cast is okay here
+		base::Process* rememberedObject =
+			static_cast< base::Process* >( Memory::getWaiting().front() );
+
+		ODEMX_TRACE << log( "alert" ).detail( "partner", rememberedObject->getLabel() )
+				.scope( typeid( PortTailT< ElementType > ) );
+
+		ODEMX_OBS_T( ObserverType, Alert( this, rememberedObject ) );
+
+		// wake up the process
+		rememberedObject->alertProcess( this );
+		Memory::forget( rememberedObject );
+	}
+
+	/// Get the label of the currently active Sched object, or the simulation
+	const data::Label& getPartner()
+	{
+		// return the current process or event, if one is active
+		if( getSimulation().getCurrentSched() != 0 )
+		{
+			return getSimulation().getCurrentSched()->getLabel();
+		}
+		else
+		{
+			return getSimulation().getLabel();
+		}
+	}
+
+private:
+
+	/// Type of the internal port object
+	typedef PortT< ElementType > PortType;
+	/// Pointer type to manage the internal PortT object
+	typedef std::shared_ptr< PortType > PortPtr;
+
+	PortPtr port_; ///< Pointer to the internal port object
+	PortMode mode_; ///< Mode for read requests
+
+protected:
+	/// Construction private, use @c create instead
+	PortTailT( base::Simulation& sim, const data::Label& label,
+			PortMode mode = WAITING_MODE, SizeType limit = 10000,
+			ObserverType* obs = 0 )
+	:	Memory( sim, label + " (tail)", IMemory::PORTTAIL )
+	,	data::Observable< ObserverType >( obs )
+	,	mode_( mode )
+	{
+		ODEMX_TRACE << log( "create" ).scope( typeid( PortTailT< ElementType > ) );
+		ODEMX_OBS_T( ObserverType, Create( this ) );
+
+		this->port_.reset( new PortType( getSimulation(), label, limit ) );
+	}
+	/// Connect the port tail to the internal buffer, needed after construction
+	void initPort()
+	{
+		this->port_->setTail( this->shared_from_this() );
+	}
+private:
+	/// No copying
+	PortTailT( const PortTailT& );
+	/// No assignment
+	PortTailT& operator=( const PortTailT& );
+};
+
+
+/**
+ * @interface PortTailTObserver
+ * @author Ronald Kluth
+ * @brief Observer for PortTailT-specific calls.
+ * @see PortTailT
+ * @since 2.0
+ */
+template < typename ElementT >
+class PortTailTObserver: public MemoryObserver {
+public:
+	typedef ElementT ElementType;
+	typedef typename PortT< ElementType >::SizeType SizeType;
+
+	virtual ~PortTailTObserver() {}
+
+	virtual void onDestroy( PortTailT< ElementType >* sender ) {} ///< Destruction
+
+	virtual void onPut( PortTailT< ElementType >* sender, const ElementType& newElement ) {}
+	virtual void onCut( PortTailT< ElementType >* sender ) {}
+	virtual void onSplice( PortTailT< ElementType >* sender, typename PortTailT< ElementType >::HeadPtr oldHead ) {}
+	virtual void onCppSplice( PortTailT< ElementType >* sender, typename PortTailT< ElementType >::HeadPtr oldHead, bool append ) {}
+	virtual void onAlert( PortTailT< ElementType >* sender, base::Sched* alerted ) {}
+
+	/// PortTail mode change
+	virtual void onChangeMode( PortTailT< ElementType >* sender, PortMode oldMode, PortMode newMode ) {}
+	/// PortTail capacity change
+	virtual void onChangeMaxCapacity( PortTailT< ElementType >* sender, SizeType oldMax, SizeType newMax ) {}
+};
+
+} } // namespace odemx::synchronization
+
+#endif /* ODEMX_SYNC_PORTTAIL_INCLUDED */
diff --git a/odemx-lite/include/odemx/synchronization/res/ResT.cpp b/odemx-lite/include/odemx/synchronization/res/ResT.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f6f46045ec11f5e1b98f6b5d53bca663473c85a0
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/res/ResT.cpp
@@ -0,0 +1,203 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002-2008 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file ResT.cpp
+
+	\author Ronald Kluth
+
+	\date created at 2008/02/18
+
+	\brief Definition of odemx::ResT
+
+	\sa ResT.h
+
+	\since 2.1
+*/
+
+#include <odemx/base/Process.h>
+#include <odemx/synchronization/res/ResT.h>
+
+#include <vector>
+
+namespace odemx {
+namespace synchronization {
+
+template < typename Token >
+ResT< Token >::ResT( base::Simulation& sim,
+					 const data::Label& label,
+					 std::vector< Token >& initialResources,
+					 ResTObserver< Token >* o /* = 0*/ )
+:	ResTBase< Token >( sim, label, initialResources, o ),
+	data::Observable< ResTObserver< Token > >( o )
+{
+	// trace and stats in base class
+
+	// observer
+	ODEMX_OBS_T(ResTObserver<Token>, Create(this));
+}
+
+template < typename Token >
+ResT<Token>::~ResT()
+{
+	// observer
+	ODEMX_OBS_T(ResTObserver<Token>, Destroy(this));
+}
+
+template < typename Token >
+Token* ResT< Token >::acquire()
+{
+	// get a return vector using acquire( n ) below
+	std::vector< Token* > v = acquire( 1 );
+
+	// return the first element of the vector
+	if( ! v.empty() )
+		return v.front();
+
+	// or 0, if nothing was returned (i.e. error or interrupt)
+	return 0;
+}
+
+template < typename Token >
+const std::vector< Token* > ResT< Token >::acquire( std::size_t n )
+{
+	if( ! getCurrentSched() || getCurrentSched()->getSchedType() != base::Sched::PROCESS )
+	{
+		// error: resource handling only implemented for processes
+		error << this->log( "ResT::acquire(): called by non-Process object" ).scope( typeid(ResT<Token>) );
+		return std::vector< Token* >();
+	}
+
+	if( n > ResTBase< Token >::tokenLimit )
+	{
+		warning << this->log( "ResT::acquire(): requesting more than max resources will always block" )
+				.scope( typeid(ResT<Token>) );
+	}
+
+	base::Process* currentProcess = getCurrentProcess();
+	base::SimTime waitTime = 0;
+
+	// compute order of service
+	ResTBase< Token >::acquireWait.inSort( currentProcess );
+
+	if( n > ResTBase< Token >::tokenNumber ||
+		ResTBase< Token >::acquireWait.getTop() != currentProcess )
+	{
+		// not enough tokens or not the first process in queue
+
+		ODEMX_TRACE << this->log( "acquire failed" )
+						.detail( "partner", currentProcess->getLabel() )
+						.detail( "requested tokens", n )
+						.scope( typeid(ResT<Token>) );
+
+		// observer
+		ODEMX_OBS_T(ResTObserver<Token>, AcquireFail(this, n));
+
+		// statistics
+		base::SimTime waitStart = getCurrentTime();
+
+		// block execution
+		while( n > ResTBase< Token >::tokenNumber ||
+			   ResTBase< Token >::acquireWait.getTop() != currentProcess )
+		{
+			currentProcess->sleep();
+
+			// handle interrupt
+			if( currentProcess->isInterrupted() )
+			{
+				ResTBase< Token >::acquireWait.remove( currentProcess );
+				return std::vector< Token* >();
+			}
+		}
+
+		// block released
+		// statistics
+		waitTime = getCurrentTime() - waitStart;
+	}
+
+	ODEMX_TRACE << this->log( "change token number" ).valueChange( ResTBase<Token>::tokenNumber, ResTBase<Token>::tokenNumber - n )
+					.scope( typeid(ResT<Token>) );
+
+	// observer
+	ODEMX_OBS_ATTR_T(ResTObserver<Token>, TokenNumber, ResTBase< Token >::tokenNumber, ResTBase< Token >::tokenNumber-n);
+
+	// acquire token
+	ResTBase< Token >::tokenNumber -= n;
+
+	// fill return vector with pointers to free resource objects
+	typename std::map< Token*, base::Process* >::iterator i;
+	std::vector< Token* > availableTokens;
+
+	std::size_t acquired = 0;
+	for( i = ResTBase< Token >::tokenInfo.begin();
+		 i != ResTBase< Token >::tokenInfo.end() && acquired < n;
+		 ++i )
+	{
+		// if resource available, store the current user in tokenInfo
+		// and add the resource to the return vector
+		if( i->second == 0 )
+		{
+			availableTokens.push_back( i->first );
+			i->second = currentProcess;
+			++acquired;
+		}
+	}
+
+	ODEMX_TRACE << this->log( "acquire succeeded" )
+			.detail( "partner", currentProcess->getLabel() )
+			.detail( "requested tokens", n )
+			.scope( typeid(ResT<Token>) );
+
+	// statistics
+	statistics << this->count( "users" ).scope( typeid(ResT<Token>) );
+	statistics << this->update( "tokens", ResTBase< Token >::tokenNumber ).scope( typeid(ResT<Token>) );
+	statistics << this->update( "wait time", waitTime ).scope( typeid(ResT<Token>) );
+
+	// observer
+	ODEMX_OBS_T(ResTObserver<Token>, AcquireSucceed(this, n));
+
+	// remove process from queue
+	ResTBase< Token >::acquireWait.remove( currentProcess );
+
+	// awake next waiting process
+	awakeFirst( ResTBase< Token >::getAcquireWait() );
+
+	// return tokens
+	return availableTokens;
+}
+
+//-----------------------------------------------------------------------helpers
+
+//template < typename Token >
+//base::SimTime ResT< Token >::getCurrentTime()
+//{
+//	return data::Producer::getSimulation().getTime();
+//}
+//
+//template < typename Token >
+//odemx::base::Process* ResT< Token >::getCurrentProcess()
+//{
+//	return data::Producer::getSimulation().getCurrentProcess();
+//}
+//
+//template < typename Token >
+//odemx::base::Sched* ResT< Token >::getCurrentSched()
+//{
+//	return data::Producer::getSimulation().getCurrentSched();
+//}
+
+} } // namespace odemx::sync
diff --git a/odemx-lite/include/odemx/synchronization/res/ResT.h b/odemx-lite/include/odemx/synchronization/res/ResT.h
new file mode 100644
index 0000000000000000000000000000000000000000..428008cc9c1f1b345e2fb0cf56bd4b4f60c56d91
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/res/ResT.h
@@ -0,0 +1,148 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002-2008 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file res/ResT.h
+
+	\author Ronald Kluth
+
+	\date created at 2008/02/18
+
+	\brief Declaration of odemx::synchronization::ResT and observer
+
+	\note This header file is not meant for inclusion, use
+	odemx/synchronization/ResTemplate.h instead.
+
+	\sa ResT.cpp
+
+	\since 2.1
+*/
+
+#ifndef ODEMX_RES_T_INCLUDED
+#define ODEMX_RES_T_INCLUDED
+
+#include <odemx/synchronization/res/ResTBase.h>
+
+namespace odemx {
+namespace synchronization {
+
+// forward declaration
+template < typename > class ResTObserver;
+
+/** \class ResT
+
+	\author Ronald Kluth
+
+	\brief ResT is a resource holding objects of type Token
+
+	\note ResT supports Observation
+	\note ResT supports Trace
+
+	ResT is a resource for synchronizing Process objects. A process is blocked
+	in acquire() if the requested number of tokens is greater than the available
+	number of tokens. It is reactivated when enough tokens are released to the resource.
+	If multiple process	objects are waiting for reactivation, process-priority and
+	FIFO-strategy are used to choose the process.
+
+	\since 2.1
+*/
+template < typename Token >
+class ResT:
+	public ResTBase< Token >, // is a data producer
+	public data::Observable< ResTObserver< Token > >
+{
+public:
+
+	using data::Producer::trace;
+	using data::Producer::debug;
+	using data::Producer::info;
+	using data::Producer::warning;
+	using data::Producer::error;
+	using data::Producer::fatal;
+	using data::Producer::statistics;
+	using data::Producer::log;
+	using data::Producer::param;
+	using data::Producer::count;
+	using data::Producer::update;
+	using data::Producer::reset;
+
+	using ResTBase<Token>::getCurrentTime;
+	using ResTBase<Token>::getCurrentSched;
+	using ResTBase<Token>::getCurrentProcess;
+
+	/**
+	 * \copydoc ResTBase(Simulation*,Label,std::vector<Token>&,ResTBaseObserver<Token>*)
+	 */
+	ResT( base::Simulation& sim, const data::Label& l,
+			std::vector< Token >& initialResources,
+			ResTObserver< Token >* o = 0 );
+
+	/// Destruction
+	virtual ~ResT();
+
+	/**
+		\name Token usage
+
+		These functions provide access for resource usage by Processes.
+		Tokens can be requested and thus acquired when then are
+		available. When the tokens are not needed anymore, the owning
+		Process	can release them.
+
+		@{
+	*/
+	/**
+		\brief acquire a token
+
+		If there are no tokens in ResT the current process is blocked.
+	*/
+	virtual Token* acquire();
+
+	/**
+		\brief acquire \p n token
+
+		If there are not enough tokens in ResT the current
+		process is blocked.
+	*/
+	const std::vector< Token* > acquire( std::size_t n );
+};
+
+/** \interface ResTObserver
+
+	\author Ronald Kluth
+
+	\brief Observer for ResT specific events
+
+	\sa ResT
+	
+	\since 2.1
+*/
+template < typename Token >
+class ResTObserver: public ResTBaseObserver< Token > {
+public:
+	typedef typename ResTBaseObserver< Token >::ResType ResType;
+
+	virtual ~ResTObserver() {}
+
+	/// Failed attempt to acquire n token
+	virtual void onAcquireFail(ResType* sender, std::size_t n) {}
+	/// Successful attempt to acquire n token
+	virtual void onAcquireSucceed(ResType* sender, std::size_t n) {}
+};
+
+} } // namespace odemx::synchronization
+
+#endif /* ODEMX_RES_T_INCLUDED */
diff --git a/odemx-lite/include/odemx/synchronization/res/ResTBase.cpp b/odemx-lite/include/odemx/synchronization/res/ResTBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7f2ac3daca02afa08586f8952f6f893ec5920959
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/res/ResTBase.cpp
@@ -0,0 +1,446 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002-2008 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file ResTBase.cpp
+
+	\author Ronald Kluth
+
+	\date created at 2008/02/18
+
+	\brief Implementation of odemx::sync::ResTBase
+
+	\sa ResTBase.h
+
+	\since 2.1
+*/
+
+#include <odemx/base/DefaultSimulation.h>
+#include <odemx/synchronization/res/ResTBase.h>
+
+#include <odemx/base/Process.h>
+
+namespace odemx {
+namespace synchronization {
+
+template < typename Token >
+ResTBase< Token >::ResTBase( base::Simulation& sim,
+					 const data::Label& label,
+					 typename ResTBase< Token >::TokenVec& initialResources,
+					 typename ResTBase< Token >::ObserverType* o /* = 0*/ )
+:	data::Producer( sim, label )
+,	data::Observable< ResTBaseObserver< Token > >( o )
+,	tokenLimit( initialResources.size() )
+,	tokenStore( initialResources.begin(), initialResources.end() )
+,	acquireWait( sim, label + " acquire queue" )
+{
+	// tokenStore already filled in initializer list
+
+	// set initial tokenNumber
+	tokenNumber = tokenStore.size();
+
+	// fill map tokenInfo with addresses of tokens and 0's for owner Processes
+	typename std::list< Token >::iterator i;
+	for( i = tokenStore.begin(); i != tokenStore.end(); ++i )
+	{
+		tokenInfo.insert( std::make_pair( &(*i), static_cast< base::Process* >(0) ) );
+	}
+
+	ODEMX_TRACE << this->log( "create" ).scope( typeid(ResTBase<Token>) );
+
+	statistics << this->param( "queue", acquireWait.getLabel() ).scope( typeid(ResTBase<Token>) );
+	statistics << this->param( "initial tokens", tokenStore.size() ).scope( typeid(ResTBase<Token>) );
+	statistics << this->param( "initial token limit", tokenLimit ).scope( typeid(ResTBase<Token>) );
+	statistics << this->update( "tokens", tokenNumber ).scope( typeid(ResTBase<Token>) );
+
+	// observer
+	ODEMX_OBS_T(ResTBaseObserver<Token>, Create(this));
+}
+
+template < typename Token >
+ResTBase< Token >::~ResTBase()
+{
+	ODEMX_TRACE << this->log( "destroy" ).scope( typeid(ResTBase<Token>) );
+
+	// observer
+	ODEMX_OBS_T(ResTBaseObserver<Token>, Destroy(this));
+}
+
+template < typename Token >
+void ResTBase< Token >::release( Token* t )
+{
+	// put free resource into a vector
+	std::vector< TokenType* > vec;
+	vec.push_back( t );
+
+	// handle that with release() below
+	return release( vec );
+}
+
+template < typename Token >
+void ResTBase< Token >::release( std::vector< TokenType* >& releaseVec )
+{
+	base::Process* currentProcess = getCurrentProcess();
+	std::size_t n = releaseVec.size();
+
+	// for each released resource, update the tokenInfo map
+	typename std::vector< Token* >::iterator released;
+	typename std::map< Token*, base::Process* >::iterator stored;
+
+	std::size_t countedReleases = 0;
+	for( released = releaseVec.begin(); released != releaseVec.end(); ++released )
+	{
+		// try to get iterator to released token in tokenInfo
+		stored = tokenInfo.find( *released );
+
+		// check if the iterator is valid and whether
+		// the currentProcess Process really owns that resource
+		if( stored != tokenInfo.end() && stored->second == currentProcess )
+		{
+			// released resource found, set the resource user to 0
+			stored->second = static_cast< base::Process* >(0);
+			++countedReleases;
+			continue;
+		}
+
+		if( stored == tokenInfo.end() )
+		{
+			error << this->log( "ResTBase::release(): token not found in token info" )
+					.scope( typeid(ResTBase<Token>) );
+		}
+		else if( stored->second != currentProcess )
+		{
+			error << this->log( "ResTBase::release(): token returned by wrong user" )
+					.scope( typeid(ResTBase<Token>) );
+		}
+	}
+
+	ODEMX_TRACE << this->log( "change token number" )
+				.valueChange( tokenNumber, tokenNumber + countedReleases )
+				.scope( typeid(ResTBase<Token>) );
+
+	// observer
+	ODEMX_OBS_ATTR_T(ResTBaseObserver<Token>, TokenNumber, tokenNumber, tokenNumber+countedReleases);
+
+	// release token
+	tokenNumber += countedReleases;
+
+	// check for failure
+	if ( countedReleases < n )
+	{
+		warning << this->log( "ResTBase::release(): could not release all tokens" )
+					.scope( typeid(ResTBase<Token>) );
+
+		ODEMX_TRACE << this->log( "release failed" )
+						.detail( "partner", getPartner() )
+						.detail( "released tokens", n - countedReleases )
+						.scope( typeid(ResTBase<Token>) );
+
+		// observer
+		ODEMX_OBS_T(ResTBaseObserver<Token>, ReleaseFail(this, n - countedReleases));
+	}
+
+	ODEMX_TRACE << this->log( "release succeeded")
+					.detail( "partner", getPartner() )
+					.detail( "released tokens", countedReleases )
+					.scope( typeid(ResTBase<Token>) );
+
+	// observer
+	ODEMX_OBS_T(ResTBaseObserver<Token>, ReleaseSucceed(this, countedReleases));
+
+	statistics << this->count( "providers" ).scope( typeid(ResTBase<Token>) );
+	statistics << this->update( "tokens", tokenNumber ).scope( typeid(ResTBase<Token>) );
+
+	// wake up waiting process objects
+	awakeFirst( &acquireWait );
+}
+
+template < typename Token >
+void ResTBase< Token >::transfer( Token* t, base::Process* oldOwner,
+		base::Process* newOwner )
+{
+	std::vector< Token* > v;
+	v.push_back( t );
+	return transfer( v, oldOwner, newOwner );
+}
+
+template < typename Token >
+void ResTBase< Token >::transfer( std::vector< Token* >& v,
+		base::Process* oldOwner, base::Process* newOwner )
+{
+	assert( oldOwner );
+	assert( newOwner );
+
+	typename std::vector< Token* >::iterator transferToken;
+	typename std::map< Token*, base::Process* >::iterator found;
+
+	std::size_t transferCount = 0;
+
+	// set a new owner for the given tokens
+	for( transferToken = v.begin(); transferToken != v.end(); ++transferToken )
+	{
+		found = tokenInfo.find( *transferToken );
+
+		// token not found ?
+		if( found == tokenInfo.end() )
+		{
+			error << this->log( "ResTBase::transfer(): transfer token not found in token info" )
+					.scope( typeid(ResTBase<Token>) );
+			continue;
+		}
+
+		// correct owner ?
+		if( found->second == oldOwner )
+		{
+			found->second = newOwner;
+			++transferCount;
+		}
+		else // oldOwner is different from owner stored in tokenInfo
+		{
+			error << this->log( "ResTBase::transfer(): transfer token owned by another Process" )
+					.scope( typeid(ResTBase<Token>) );
+		}
+	}
+
+	ODEMX_TRACE << this->log( "transfer" )
+					.detail( "amount", transferCount )
+					.detail( "old owner", oldOwner->getLabel() )
+					.detail( "new owner", newOwner->getLabel() )
+					.scope( typeid(ResTBase<Token>) );
+
+	// observer
+	ODEMX_OBS_T(ResTBaseObserver<Token>, Transfer(this, transferCount, oldOwner, newOwner));
+}
+
+template < typename Token >
+void ResTBase< Token >::control( Token t )
+{
+	ODEMX_TRACE << this->log( "add tokens" )
+			.detail( "amount", 1 ).scope( typeid(ResTBase<Token>) );
+
+	// observer
+	ODEMX_OBS_T(ResTBaseObserver<Token>, Control(this, 1));
+
+	// increase max by one
+	++tokenLimit;
+
+	// add token to tokenStore and tokenInfo
+	tokenStore.push_back( t );
+	tokenInfo.insert( std::make_pair( &(tokenStore.back()), static_cast< base::Process* >(0) ) );
+	++tokenNumber;
+
+	// wake up waiting process objects
+	awakeFirst( &acquireWait );
+}
+
+template < typename Token >
+void ResTBase< Token >::control( typename ResTBase< Token >::TokenVec& addVec )
+{
+	std::size_t n = addVec.size();
+
+	ODEMX_TRACE << this->log( "add tokens" )
+			.detail( "amount", n ).scope( typeid(ResTBase<Token>) );
+
+	// observer
+	ODEMX_OBS_T(ResTBaseObserver<Token>, Control(this, n));
+
+	// increase by number of added tokens
+	tokenLimit += n;
+
+	// fill tokenStore and tokenInfo with tokens from addVec
+	// as long as the tokenLimit is not reached yet
+	typename std::vector< Token >::iterator i;
+	for( i = addVec.begin();
+		 i != addVec.end() && tokenStore.size() < tokenLimit;
+		 ++i )
+	{
+		tokenStore.push_back( *i );
+		tokenInfo.insert( std::make_pair( &(tokenStore.back()), static_cast< base::Process* >(0) ) );
+		++tokenNumber;
+	}
+
+	// wake up waiting process objects
+	awakeFirst( &acquireWait );
+}
+
+template < typename Token >
+std::vector< Token > ResTBase< Token >::unControl( std::size_t n /* = 1 */)
+{
+	if( n > tokenStore.size() )
+	{
+		error << this->log( "ResTBase::unControl(): attempt to remove more than max tokens" )
+				.scope( typeid(ResTBase<Token>) );
+		return std::vector< Token >();
+	}
+
+	if( ! getCurrentSched() ||
+		getCurrentSched()->getSchedType() != base::Sched::PROCESS )
+	{
+		error << this->log( "ResTBase::unControl(): called by non-Process object" )
+				.scope( typeid(ResTBase<Token>) );
+		return std::vector< Token >();
+	}
+
+	ODEMX_TRACE << this->log( "remove tokens" )
+			.detail( "amount", n ).scope( typeid(ResTBase<Token>) );
+
+	// observer
+	ODEMX_OBS_T(ResTBaseObserver<Token>, UnControl(this, n));
+
+	base::Process* currentProcess = getCurrentProcess();
+
+	// acquire enough token
+	// compute order of service
+	acquireWait.inSort( currentProcess );
+
+	if( n > tokenNumber ||
+		acquireWait.getTop() != currentProcess )
+	{
+		// not enough tokens or not the first process in queue
+
+		// block execution
+		while( n > tokenNumber ||
+			   acquireWait.getTop() != currentProcess )
+		{
+			currentProcess->sleep();
+
+			// handle interrupt
+			if( currentProcess->isInterrupted() )
+			{
+				acquireWait.remove( currentProcess );
+				return std::vector< Token >();
+			}
+		}
+
+		// block released
+	}
+
+	ODEMX_TRACE << this->log( "change token number" )
+				.valueChange( tokenNumber, tokenNumber - n )
+				.scope( typeid(ResTBase<Token>) );
+
+	// observer
+	ODEMX_OBS_ATTR_T(ResTBaseObserver<Token>, TokenNumber, tokenNumber, tokenNumber-n);
+
+	// fill return vector with the uncontrolled token objects
+	typename std::map< Token*, base::Process* >::iterator tInfo = tokenInfo.begin();
+	std::vector< Token > unControlTokens;
+
+	std::size_t acquired = 0;
+	while( tInfo != tokenInfo.end() && acquired < n )
+	{
+		if( tInfo->second == 0 )
+		{
+			unControlTokens.push_back( *(tInfo->first) );
+			++acquired;
+
+			// remove the uncontrolled token from store
+			tokenStore.remove( *(tInfo->first) );
+
+			// remove the uncontrolled token from managing info map
+			// by using a copy of the non-incremented iterator returned by op++
+			tokenInfo.erase( tInfo++ );
+		}
+		else
+		{
+			++tInfo;
+		}
+	}
+
+	// acquire token
+	tokenNumber -= acquired;
+
+	// adjust token limit
+	tokenLimit -= acquired;
+
+	// remove process from queue
+	acquireWait.remove( currentProcess );
+
+	// awake next waiting process
+	awakeFirst( &acquireWait );
+
+	// return tokens
+	return unControlTokens;
+}
+
+
+template < typename Token >
+std::size_t ResTBase< Token >::getTokenNumber() const
+{
+	return tokenNumber;
+}
+
+template < typename Token >
+std::size_t ResTBase< Token >::getTokenLimit() const
+{
+	return tokenLimit;
+}
+
+template < typename Token >
+const std::map< Token*, base::Process* >& ResTBase< Token >::getTokenInfo() const
+{
+	return tokenInfo;
+}
+
+template < typename Token >
+const std::list< Token >& ResTBase< Token >::getTokenStore() const
+{
+	return tokenStore;
+}
+
+template < typename Token >
+const base::ProcessList& ResTBase< Token >::getWaitingProcesses() const
+{
+	return acquireWait.getList();
+}
+
+template < typename Token >
+Queue* ResTBase< Token >::getAcquireWait()
+{
+	return &acquireWait;
+}
+
+template < typename Token >
+base::SimTime ResTBase< Token >::getCurrentTime()
+{
+	return data::Producer::getSimulation().getTime();
+}
+
+template < typename Token >
+odemx::base::Process* ResTBase< Token >::getCurrentProcess()
+{
+	return data::Producer::getSimulation().getCurrentProcess();
+}
+
+template < typename Token >
+odemx::base::Sched* ResTBase< Token >::getCurrentSched()
+{
+	return data::Producer::getSimulation().getCurrentSched();
+}
+
+template < typename Token >
+const data::Label& ResTBase< Token >::getPartner()
+{
+	if( getSimulation().getCurrentSched() != 0 )
+	{
+		return getSimulation().getCurrentSched()->getLabel();
+	}
+
+	return getSimulation().getLabel();
+}
+
+} } // namespace odemx::sync
diff --git a/odemx-lite/include/odemx/synchronization/res/ResTBase.h b/odemx-lite/include/odemx/synchronization/res/ResTBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..dd0161e8335cba51bff86c7cf6305d52df563d9c
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/res/ResTBase.h
@@ -0,0 +1,296 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002-2008 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file ResTBase.h
+
+	\author Ronald Kluth
+
+	\date created at 2008/02/18
+
+	\brief Declaration of odemx::synchronization::ResTBase and observer
+
+	\note This header file is not meant for inclusion, use
+	odemx/synchronization/ResTemplate.h instead.
+
+	\sa ResTBase.cpp
+
+	\since 2.1
+*/
+
+#ifndef ODEMX_RES_T_BASE_INCLUDED
+#define ODEMX_RES_T_BASE_INCLUDED
+
+#include <odemx/data/Producer.h>
+#include <odemx/data/Observable.h>
+#include <odemx/statistics/Accumulate.h>
+#include <odemx/synchronization/Queue.h>
+
+
+#include <set>
+#include <map>
+
+namespace odemx {
+
+//forward declaration
+namespace base {
+class Process;
+class Simulation;
+}
+
+namespace synchronization {
+
+template < typename > class ResTBaseObserver;
+
+/** \class ResTBase
+
+	\author Ronald Kluth
+
+	\brief ResTBase is an abstract base class for resources holding
+	objects of type Token
+
+	\note ResTBase supports Observation
+	\note ResTBase supports Trace
+
+	\sa Res, ResT, ResTChoice
+
+	ResTBase provides many functions needed in resource classes
+	for synchronizing Process objects.
+
+	\since 2.1
+*/
+template < typename TokenT >
+class ResTBase
+:	public data::Producer
+,	public data::Observable< ResTBaseObserver< TokenT > >
+{
+public:
+
+	using data::Producer::trace;
+	using data::Producer::debug;
+	using data::Producer::info;
+	using data::Producer::warning;
+	using data::Producer::error;
+	using data::Producer::fatal;
+	using data::Producer::statistics;
+
+	typedef TokenT TokenType;
+	typedef std::vector< TokenType > TokenVec;
+	typedef std::map< TokenType*, base::Process* > TokenOwnerMap;
+	typedef std::list< TokenType > StorageType;
+	typedef ResTBaseObserver< TokenType > ObserverType;
+
+	/**
+		\brief Construction for user-defined Simulation
+		\param s
+			pointer to simulation
+		\param l
+			label of ResT object
+		\param initialResources
+			vector containing the initial tokens of the resource
+		\param o
+			observer of ResT object
+
+		\note The Token type must be copyable! The initial resources will
+		be copied into the internal token store of the object.
+
+		\note The token limit is set by the size of the \c initialResources
+		vector. The change it, use control(), or unControl().
+	*/
+	ResTBase( base::Simulation& sim, const data::Label& label,
+			TokenVec& initialResources, ObserverType* obs = 0 );
+
+	/// Destruction
+	virtual ~ResTBase();
+
+	/**
+		\name Token usage
+
+		These functions provide access for resource usage by Processes.
+		Tokens can be requested and thus acquired when then are
+		available. When the tokens are not needed anymore, the owning
+		Process	can release them.
+
+		\note There are different ways to select tokens,
+		this base class only provides a declaration for acquire.
+
+		\note Use the derived classes ResT or ResTChoice
+		@{
+	*/
+	/**
+		\brief forces implementation of acquire
+
+		Pure virtual function which must be implemented in
+		derived classes.
+	*/
+	virtual TokenType* acquire() = 0;
+
+	/**
+		\brief release a token
+
+		Returns a previously acquired token to the resource
+	*/
+	void release( TokenType* e );
+
+	/**
+		\brief release token
+
+		Returns previously acquired tokens to the resource
+	*/
+	void release( std::vector< TokenType* >& s );
+
+	/**
+		\brief transfer control of an acquired token to \p newOwner
+
+		The \p newOwner is registered as holder of token \p e, meaning
+		this info is changed in the internal token info map.
+	*/
+	void transfer( TokenType* t, base::Process* oldOwner,
+			base::Process* newOwner );
+
+	/**
+		\brief transfer control of acquired token to \p newOwner
+
+		The \p newOwner is registered as holder of the tokens in \p s.
+	*/
+	void transfer( std::vector< TokenType* >& v, base::Process* oldOwner,
+			base::Process* newOwner);
+
+	/**
+		\brief add token \p e to ressource
+
+		Add token \p e to the managed token set.
+	*/
+	void control( TokenType t );
+
+	/**
+		\brief add token to ressource
+
+		Add token to the managed token set.
+	*/
+	void control( TokenVec& addVec );
+
+	/**
+		\brief remove \p n token from ressource
+
+		Remove token from the managed token set. If there are not enough
+		token left in the ressource, the current process is blocked.
+	*/
+	TokenVec unControl( std::size_t n = 1 );
+	//@}
+
+	/** \name ResT status information
+
+		The following functions provide access to the ResT object's
+		status during a simulation.
+
+		@{
+	*/
+	/**
+		\brief get number of available token
+
+		Get number of currently avaliable token in ressource
+	*/
+	std::size_t getTokenNumber() const;
+
+	/**
+		\brief get number of managed token
+
+		Get maximum number of tokens managed by this ressource
+	*/
+	std::size_t getTokenLimit() const;
+
+	/**
+		\brief Get token map
+
+		Get info about all tokens and their owning processes.
+	*/
+	const TokenOwnerMap& getTokenInfo() const;
+
+	/// Get a reference to the stored tokens
+	const StorageType& getTokenStore() const;
+
+	/// get list of blocked  process objects
+	const std::list< base::Process* >& getWaitingProcesses() const;
+	//@}
+
+protected:
+
+	/// current time
+	base::SimTime getCurrentTime();
+	/// current process
+	base::Process* getCurrentProcess();
+	/// current scheduled object
+	base::Sched* getCurrentSched();
+	/// get pointer to queue of processes waiting in acquire
+	Queue* getAcquireWait();
+	/// get label of the currently active context (process or sim)
+	const data::Label& getPartner();
+	/// current number of tokens
+	std::size_t tokenNumber;
+	/// maximum number of tokens
+	std::size_t tokenLimit;
+
+	/// token storage
+	StorageType tokenStore;
+	/// token management
+	TokenOwnerMap tokenInfo;
+	/// process management
+	Queue acquireWait;
+};
+
+/** \interface ResTBaseObserver
+
+	\author Ronald Kluth
+
+	\brief Observer for ResT specific events
+
+	\sa ResT
+*/
+template < typename Token >
+class ResTBaseObserver
+{
+public:
+	typedef ResTBase< Token > ResType;
+
+	virtual ~ResTBaseObserver() {}
+
+	/// Creation
+	virtual void onCreate(ResType* sender) {}
+	/// Destruction
+	virtual void onDestroy(ResType* sender) {}
+
+	/// Failed attempt to release n token
+	virtual void onReleaseFail(ResType* sender, std::size_t n) {}
+	/// Release of n token
+	virtual void onReleaseSucceed(ResType* sender, std::size_t n) {}
+	/// Transfer of n token
+	virtual void onTransfer(ResType* sender, std::size_t n,
+			base::Process* oldOwner, base::Process* newOwner) {}
+	/// Add tokens
+	virtual void onControl(ResType* sender, std::size_t n) {}
+	/// Remove tokens
+	virtual void onUnControl(ResType* sender, std::size_t n) {}
+	/// Change of token number
+	virtual void onChangeTokenNumber(ResType* sender,
+			std::size_t oldTokenNumber, std::size_t newTokenNumber) {}
+};
+
+} } // namespace odemx::synchronization
+
+#endif /*ODEMX_RES_T_BASE_INCLUDED*/
+
diff --git a/odemx-lite/include/odemx/synchronization/res/ResTChoice.cpp b/odemx-lite/include/odemx/synchronization/res/ResTChoice.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..01de5ebae6b5af5ffeb8d04f913a8085c830ab26
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/res/ResTChoice.cpp
@@ -0,0 +1,245 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002-2008 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file ResTChoice.cpp
+
+	\author Ronald Kluth
+
+	\date created at 2008/02/18
+
+	\brief Implementation of odemx::sync::ResTChoice
+
+	\sa ResTChoice.h
+
+	\since 2.1
+*/
+
+#include <odemx/synchronization/res/ResTChoice.h>
+#include <odemx/base/Sched.h>
+#include <odemx/base/Process.h>
+
+namespace odemx {
+namespace synchronization {
+
+template < typename Token >
+ResTChoice< Token >::ResTChoice( base::Simulation& sim,
+					 const data::Label& label,
+					 std::vector< Token >& initialResources,
+					 ResTChoiceObserver< Token >* o /* = 0*/ )
+:	ResTBase< Token >( sim, label, initialResources, o ),
+	data::Observable< ResTChoiceObserver< Token > >( o )
+{
+	// observer
+	ODEMX_OBS_T(ResTChoiceObserver<Token>, Create(this));
+}
+
+template < typename Token >
+ResTChoice<Token>::~ResTChoice()
+{
+	// observer
+	ODEMX_OBS_T(ResTChoiceObserver<Token>, Destroy(this));
+}
+
+template < typename Token >
+Token* ResTChoice< Token >::acquire()
+{
+	error << this->log( "ResTChoice::acquire(): selection function required, use overload" )
+			.scope( typeid(ResTChoice<Token>) );
+	return 0;
+}
+
+template < typename Token >
+Token* ResTChoice< Token >::acquire( typename ResTChoice< Token >::Selection select )
+{
+	std::vector< Token* > found = acquire( select, 1 );
+
+	if( ! found.empty() )
+	{
+		return found.front();
+	}
+	return 0;
+}
+
+template < typename Token >
+const std::vector< Token* > ResTChoice< Token >::acquire( 
+		typename ResTChoice< Token >::Selection select, std::size_t n )
+{
+	if( ! getCurrentSched() || getCurrentSched()->getSchedType() != base::Sched::PROCESS )
+	{
+		// error: resource handling only implemented for processes
+		error << this->log( "ResTChoice::acquire(): called by non-Process object" )
+					.scope( typeid(ResTChoice<Token>) );
+		return std::vector< Token* >();
+	}
+
+	if( n > ResTBase< Token >::tokenLimit )
+	{
+		warning << this->log( "ResTChoice::acquire(): requesting more than max tokens will always block" )
+					.scope( typeid(ResTChoice<Token>) );
+	}
+
+	base::Process* currentProcess = getCurrentProcess();
+	base::SimTime waitTime = 0;
+
+	// compute order of service
+	ResTBase< Token >::acquireWait.inSort( currentProcess );
+
+	// the return vector to be filled by getMatchingTokens()
+	std::vector< Token* > matches;
+
+	if( ResTBase< Token >::acquireWait.getTop() != currentProcess ||
+		! getMatchingTokens( select, n, matches ) )
+	{
+		// not enough matching tokens or
+		// not the first process in queue
+
+		ODEMX_TRACE << this->log( "acquire failed" )
+						.detail( "partner", currentProcess->getLabel() )
+						.detail( "requested tokens", n )
+						.scope( typeid(ResTChoice<Token>) );
+		// observer
+		ODEMX_OBS_T(ResTChoiceObserver<Token>, AcquireFail(this, n));
+
+		// statistics
+		base::SimTime waitStart = getCurrentTime();
+
+		do
+		{
+			currentProcess->sleep();
+
+			// handle interrupt
+			if( currentProcess->isInterrupted() )
+			{
+				ResTBase< Token >::acquireWait.remove( currentProcess );
+				return std::vector< Token* >();
+			}
+		}
+		while( ResTBase< Token >::acquireWait.getTop() != currentProcess ||
+				 ! getMatchingTokens( select, n, matches ) );
+
+		// block released
+		// statistics
+		waitTime = getCurrentTime() - waitStart;
+	}
+
+	ODEMX_TRACE << this->log( "change token number" ).valueChange( ResTBase<Token>::tokenNumber, ResTBase<Token>::tokenNumber - n )
+					.scope( typeid(ResTChoice<Token>) );
+
+	// observer
+	ODEMX_OBS_ATTR_T(ResTChoiceObserver<Token>, TokenNumber, ResTBase< Token >::tokenNumber, ResTBase< Token >::tokenNumber-n);
+
+	// acquire token
+	ResTBase< Token >::tokenNumber -= n;
+
+	// fill return vector with pointers to free resource objects
+	typename std::vector< Token* >::iterator i;
+
+	for( i = matches.begin(); i != matches.end(); ++i )
+	{
+		// store the current user of selected resources in ResTBase< Token >::tokenInfo
+
+		if( ResTBase< Token >::tokenInfo[ *i ] == 0 )
+		{
+			ResTBase< Token >::tokenInfo[ *i ] = currentProcess;
+		}
+		else
+		{
+			// this error should never happen
+			error << this->log( "ResTChoice::acquire(): selected token is owned by another Process" )
+					.scope( typeid(ResTChoice<Token>) );
+		}
+	}
+
+	ODEMX_TRACE << this->log( "acquire succeeded" )
+			.detail( "partner", currentProcess->getLabel() )
+			.detail( "requested tokens", n )
+			.scope( typeid(ResTChoice<Token>) );
+
+	// statistics
+	statistics << this->count( "users" ).scope( typeid(ResTChoice<Token>) );
+	statistics << this->update( "tokens", ResTBase< Token >::tokenNumber ).scope( typeid(ResTChoice<Token>) );
+	statistics << this->update( "wait time", waitTime ).scope( typeid(ResTChoice<Token>) );
+
+	// observer
+	ODEMX_OBS_T(ResTChoiceObserver<Token>, AcquireSucceed(this, n));
+
+	// remove process from queue
+	ResTBase< Token >::acquireWait.remove( currentProcess );
+
+	// awake next
+	awakeFirst( ResTBase< Token >::getAcquireWait() );
+
+	return matches;
+}
+
+template < typename Token >
+base::SimTime ResTChoice< Token >::getCurrentTime()
+{
+	return data::Producer::getSimulation().getTime();
+}
+
+template < typename Token >
+base::Process* ResTChoice< Token >::getCurrentProcess()
+{
+	return data::Producer::getSimulation().getCurrentProcess();
+}
+
+template < typename Token >
+base::Sched* ResTChoice< Token >::getCurrentSched()
+{
+	return data::Producer::getSimulation().getCurrentSched();
+}
+
+template < typename Token >
+bool ResTChoice< Token >::getMatchingTokens( 
+		typename ResTChoice< Token >::Selection select,
+		std::size_t n, std::vector< Token* >& result )
+{
+	std::size_t count = 0;
+	result.clear();
+
+	// find matching tokens
+	typename std::map< Token*, base::Process* >::iterator i;
+	for( i = ResTBase< Token >::tokenInfo.begin(); i != ResTBase< Token >::tokenInfo.end(); ++i )
+	{
+		// count all matches
+		if( select( getCurrentProcess(), i->first ) )
+		{
+			count++;
+
+			// store free matches in result vector
+			if( i->second == 0 )
+			{
+				result.push_back( i->first );
+
+				if( result.size() == n )
+					break;
+			}
+		}
+	}
+
+	if( count < n )
+	{
+		warning << this->log( "ResTChoice::getMatchingTokens(): too few matching tokens in resource, will always block" )
+				.scope( typeid(ResTChoice<Token>) );
+	}
+
+	return result.size() == n;
+}
+
+} } // namespace odemx::sync
diff --git a/odemx-lite/include/odemx/synchronization/res/ResTChoice.h b/odemx-lite/include/odemx/synchronization/res/ResTChoice.h
new file mode 100644
index 0000000000000000000000000000000000000000..34a46c285730d789e0da300b77517dee773c6657
--- /dev/null
+++ b/odemx-lite/include/odemx/synchronization/res/ResTChoice.h
@@ -0,0 +1,177 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002-2008 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file ResTChoice.h
+
+	\author Ronald Kluth
+
+	\date created at 2008/02/18
+
+	\brief Declaration of odemx::synchronization::ResTChoice and observer
+
+	\note This header file is not meant for inclusion, use
+	odemx/synchronization/ResTemplate.h instead.
+
+	\sa ResTChoice.cpp
+
+	\since 2.1
+*/
+
+#ifndef ODEMX_RES_T_CHOICE_INCLUDED
+#define ODEMX_RES_T_CHOICE_INCLUDED
+
+#include <odemx/synchronization/res/ResTBase.h>
+
+namespace odemx {
+namespace synchronization {
+
+//forward declaration
+template < typename Token >
+class ResTChoiceObserver;
+
+/** \class ResTChoice
+
+	\author Ronald Kluth
+
+	\brief ResTChoice is an abstract base class for resources holding
+	objects of type Token
+
+	ResTChoice is a resource class for synchronizing Process objects based
+	on the availability of selected resources. A process is blocked in
+	acquire() if not enough tokens matching the selection criteria
+	are available. It is reactivated when enough tokens are released
+	to the resource. If multiple process objects are waiting for
+	reactivation, process queue priority and FIFO-strategy are used to
+	choose the process.
+
+	\note ResTChoice supports Observation
+	\note ResTChoice supports Trace
+
+	\sa Res, ResT
+
+	\since 2.1
+*/
+template < typename Token >
+class ResTChoice:
+	public ResTBase< Token >,
+	public data::Observable< ResTChoiceObserver< Token > >
+{
+public:
+
+	using data::Producer::trace;
+	using data::Producer::debug;
+	using data::Producer::info;
+	using data::Producer::warning;
+	using data::Producer::error;
+	using data::Producer::fatal;
+	using data::Producer::statistics;
+	using data::Producer::log;
+	using data::Producer::param;
+	using data::Producer::count;
+	using data::Producer::update;
+	using data::Producer::reset;
+
+	/// function type for coding selections
+	typedef bool( *Selection )( base::Process* owner, Token* t );
+
+	/**
+	 * \copydoc ResTBase(Simulation*,Label,std::vector<Token>&,ResTBaseObserver<Token>*)
+	 */
+	ResTChoice( base::Simulation& sim, const data::Label& label,
+			std::vector< Token >& initialResources,
+			ResTChoiceObserver< Token >* o = 0 );
+
+	/// Destruction
+	virtual ~ResTChoice();
+
+	/**
+		\name Token usage
+
+		These functions provade access for resource usage by Processes.
+		Tokens can be requested and thus acquired when then are
+		available. When the tokens are not needed anymore, the owning
+		Process	can release them.
+
+		@{
+	*/
+	/**
+		\brief acquire a token
+
+		Required implementation of acquire, will output an error
+		to
+	*/
+	virtual Token* acquire();
+
+	/**
+		\brief find and acquire a token
+
+		If no token matching the Selection condition is available,
+		the current process is blocked
+	*/
+	Token* acquire( typename ResTChoice< Token >::Selection select );
+
+	/**
+		\brief find and acquire token
+
+		If there are not enough tokens matching the Selection condition
+		available, the current process is blocked
+	*/
+	const std::vector< Token* > acquire( Selection select, std::size_t n );
+
+private:
+
+	/// current simulation time
+	base::SimTime getCurrentTime();
+	
+	/// current process
+	base::Process* getCurrentProcess();
+	
+	/// current scheduled object
+	base::Sched* getCurrentSched();
+
+	/// help method to find tokens matching the selection
+	bool getMatchingTokens( Selection select, std::size_t n,
+							std::vector< Token* >& result );
+};
+
+/** \interface ResTChoiceObserver
+
+	\author Ronald Kluth
+
+	\brief Observer for ResTChoice-specific events
+
+	\since 2.1
+
+	\sa ResT
+*/
+template < typename Token >
+class ResTChoiceObserver: public ResTBaseObserver< Token > {
+public:
+	typedef typename ResTBaseObserver< Token >::ResType ResType;
+
+	virtual ~ResTChoiceObserver() {}
+
+	/// Failed attempt to acquire n token
+	virtual void onAcquireFail(ResType* sender, std::size_t n) {}
+	/// Successful attempt to acquire n token
+	virtual void onAcquireSucceed(ResType* sender, std::size_t n) {}
+};
+
+} } // namespace odemx::synchronization
+
+#endif /*ODEMX_RES_T_CHOICE_INCLUDED*/
diff --git a/odemx-lite/include/odemx/util/DeletePtr.h b/odemx-lite/include/odemx/util/DeletePtr.h
new file mode 100644
index 0000000000000000000000000000000000000000..a5f08d1cbd6efe4e6dbf0a6a5491cd3310bf2d8a
--- /dev/null
+++ b/odemx-lite/include/odemx/util/DeletePtr.h
@@ -0,0 +1,51 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file DeletePtr.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/29
+ * @brief Declaration and implementation of functor odemx::DeletePtr
+ * @since 3.0
+ */
+
+#ifndef ODEMX_UTIL_DELETEPTR_INCLUDED
+#define ODEMX_UTIL_DELETEPTR_INCLUDED
+
+namespace odemx {
+
+/**
+ * @brief Delete pointers of any type
+ * @tparam PointerT type of the objects pointed to
+ *
+ * This functor can call delete on any kind of pointer. It is useful in
+ * for_each loops that delete containers with pointers to owned resources.
+ * Each pointer is checked for @c 0 before delete is called on it.
+ */
+template< typename PointerT >
+struct DeletePtr
+{
+	void operator()( PointerT* p )
+	{
+		if( p ) delete p;
+	}
+};
+
+} // namespace odemx
+
+#endif /* ODEMX_UTIL_DELETEPTR_INCLUDED */
diff --git a/odemx-lite/include/odemx/util/Exceptions.h b/odemx-lite/include/odemx/util/Exceptions.h
new file mode 100644
index 0000000000000000000000000000000000000000..c8ab8edfeacd3d6b9de235efcfaa69bb9b38de83
--- /dev/null
+++ b/odemx-lite/include/odemx/util/Exceptions.h
@@ -0,0 +1,99 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Exceptions.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/29
+ * @brief Declaration and implementation of ODEMx exceptions
+ * @since 3.0
+ */
+
+#ifndef ODEMX_EXCEPTIONS_INCLUDED
+#define ODEMX_EXCEPTIONS_INCLUDED
+
+#include <stdexcept>
+#include <string>
+
+namespace odemx {
+
+/** @brief Exception type for the scheduler
+ * @ingroup util
+ */
+class SchedulingException
+:	public std::runtime_error
+{
+public:
+	SchedulingException( const std::string& description );
+};
+
+/** @brief Exception type for reporting queueing problems
+ * @ingroup util
+ */
+class QueueingException
+:	public std::runtime_error
+{
+public:
+	QueueingException( const std::string& description );
+};
+
+/** @brief Exception type for data module problems
+ * @ingroup util
+ */
+class DataException
+:	public std::runtime_error
+{
+public:
+	DataException( const std::string& description );
+};
+
+/** @brief Exception type for problem of output components
+ * @ingroup util
+ */
+class DataOutputException
+:	public std::runtime_error
+{
+public:
+	DataOutputException( const std::string& description );
+};
+
+//-----------------------------------------------------------------------inlines
+
+inline SchedulingException::SchedulingException( const std::string& description )
+:	runtime_error( description )
+{
+}
+
+inline QueueingException::QueueingException( const std::string& description )
+:	runtime_error( description )
+{
+}
+
+inline DataException::DataException( const std::string& description )
+:	runtime_error( description )
+{
+}
+
+inline DataOutputException::DataOutputException( const std::string& description )
+:	runtime_error( description )
+{
+}
+
+} // namespace odemx
+
+#endif /* ODEMX_EXCEPTIONS_INCLUDED */
diff --git a/odemx-lite/include/odemx/util/ListInSort.h b/odemx-lite/include/odemx/util/ListInSort.h
new file mode 100644
index 0000000000000000000000000000000000000000..8ed07289dd4c4072b39f4755f181500e45732331
--- /dev/null
+++ b/odemx-lite/include/odemx/util/ListInSort.h
@@ -0,0 +1,83 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2007, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ListInSort.h
+ * @author Ronald Kluth
+ * @date created at 2007/11/08
+ * @brief Declaration and Implementation of odemx::ListInSort
+ * @since 2.1
+ */
+
+#ifndef ODEMX_UTIL_LISTINSORT_INCLUDED
+#define ODEMX_UTIL_LISTINSORT_INCLUDED
+
+#include <list>
+#include <algorithm>
+
+namespace odemx {
+
+/**
+	\brief Function template for sorted insertion in std::list<> container
+
+	\param list
+		reference to std::list<> container
+
+	\param newElement
+		the element to be sorted into the given list
+
+	\param cmp
+		the chosen comparison functor by which the list is ordered
+
+	\param fifo
+		use FIFO or LIFO strategy
+
+	ListInSort is used for insertion of Sched objects into a
+	std::list< Sched* >	container by the ExecutionList. It is also
+	employed to sort a ProcessQueue of type std::list< Process* >
+	using a user-defined predicate as sorting criterion.
+
+	\sa DefaultCmp, QPriorityCmp
+*/
+template < typename ListElementType, typename ComparisonFunctorType >
+typename std::list< ListElementType >::iterator
+inline ListInSort( std::list< ListElementType >& l,
+				   ListElementType newElement,
+				   ComparisonFunctorType& cmp,
+				   bool fifo = true )
+{
+	// an iterator to store the position
+	// where the new element should be inserted
+	typename std::list< ListElementType >::iterator insertLocation;
+
+	// according to fifo or lifo, the new element is inserted
+	// either at the end or at the beginning of the possible range
+	// the insert location is determined by standard algorithms
+	if( fifo )
+		insertLocation = std::upper_bound( l.begin(), l.end(), newElement, cmp );
+	else // lifo
+		insertLocation = std::lower_bound( l.begin(), l.end(), newElement, cmp );
+
+	// insert returns an iterator to the location
+	// where the new element was placed in the list
+	return l.insert( insertLocation, newElement );
+}
+
+} // namespace odemx
+
+#endif /* ODEMX_UTIL_LISTINSORT_INCLUDED */
diff --git a/odemx-lite/include/odemx/util/StringConversion.h b/odemx-lite/include/odemx/util/StringConversion.h
new file mode 100644
index 0000000000000000000000000000000000000000..3141032a11e7fb6513523f6036c4bfe80f3a0132
--- /dev/null
+++ b/odemx-lite/include/odemx/util/StringConversion.h
@@ -0,0 +1,55 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file StringConversion.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/29
+ * @brief Declaration and implementation of string helpers
+ * @since 3.0
+ */
+
+#ifndef ODEMX_UTIL_STRINGCONVERSION_INCLUDED
+#define ODEMX_UTIL_STRINGCONVERSION_INCLUDED
+
+#include <sstream>
+#include <string>
+
+namespace odemx {
+
+/**
+ * @brief Get a string representation of the given value
+ * @tparam T The type of the given value, automatically deduced by the compiler
+ * @param value Reference to the given value
+ * @return The converted string
+ *
+ * This function converts any streamable C++-type into a string. It uses an
+ * std::ostringstream to do the work. To make this function work with
+ * user-defined types, operator<<() must be implemented for the type.
+ */
+template < typename T >
+inline std::string toString( const T& value )
+{
+	std::ostringstream convert;
+	convert << value;
+	return convert.str();
+}
+
+} // namespace odemx::util
+
+#endif /* ODEMX_UTIL_STRINGCONVERSION_INCLUDED */
diff --git a/odemx-lite/include/odemx/util/TypeNames.h b/odemx-lite/include/odemx/util/TypeNames.h
new file mode 100644
index 0000000000000000000000000000000000000000..6997afbcf104d5664d684a4df49176649c2f5ca6
--- /dev/null
+++ b/odemx-lite/include/odemx/util/TypeNames.h
@@ -0,0 +1,58 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2008 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file TypeNames.h
+ * @author Ronald Kluth
+ * @date created at 2008/02/12
+ * @brief Typedefs to retain backwards-compatibility after changing type names
+ * @since 2.1
+ */
+
+#ifndef ODEMX_TYPENAMES_INCLUDED
+#define ODEMX_TYPENAMES_INCLUDED
+
+#include <odemx/odemx.h>
+
+// for this file to work without inclusion of <odemx/odemx.h>
+// the necessary library headers must be included here:
+
+/*
+#include <odemx/protocol/ProtocolStack.h>
+#include <odemx/random/DiscreteDist.h>
+#include <odemx/random/ContinuousDist.h>
+#include <odemx/synchronization/CondQ.h>
+#include <odemx/synchronization/Memory.h>
+#include <odemx/synchronization/WaitQ.h>
+#include <odemx/util/Table.h>
+*/
+
+namespace odemx
+{
+	typedef random::DiscreteDist Idist;
+	typedef random::DiscreteConst Iconst;
+	typedef random::ContinuousDist Rdist;
+	typedef random::ContinuousConst Rconst;
+	typedef random::NegativeExponential Negexp;
+	typedef random::RandomInt Randint;
+	typedef synchronization::CondQ Condq;
+	typedef synchronization::WaitQ Waitq;
+	typedef synchronization::Memory Memo;
+}
+
+#endif /* ODEMX_TYPENAMES_INCLUDED */
diff --git a/odemx-lite/include/odemx/util/TypeToString.h b/odemx-lite/include/odemx/util/TypeToString.h
new file mode 100644
index 0000000000000000000000000000000000000000..873972c4adae71199872df1763187b5f74116adc
--- /dev/null
+++ b/odemx-lite/include/odemx/util/TypeToString.h
@@ -0,0 +1,51 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file util/TypeToString.h
+ * @author Ronald Kluth
+ * @date created at 2009/03/29
+ * @brief Declaration and implementation of odemx::typeToString()
+ * @since 3.0
+ */
+
+#ifndef ODEMX_UTIL_TYPETOSTRING_INCLUDED
+#define ODEMX_UTIL_TYPETOSTRING_INCLUDED
+
+#include <CppLog/detail/TypeToString.h>
+
+namespace odemx {
+
+/**
+ * @brief Get a string representation of the type name
+ * @param type reference to a type_info object returned by typeid()
+ * @return the type name as string
+ *
+ * The function type_info::name() returns a mangled type name on GCC
+ * and thus needs to be treated differently than on other compilers.
+ * This function applies demangling to retrieve a human-readable
+ * string representation of type names.
+ */
+inline std::string typeToString( const std::type_info& type )
+{
+	return Log::Detail::typeToString( type );
+}
+
+} // namespace odemx
+
+#endif /* ODEMX_UTIL_TYPETOSTRING_INCLUDED */
diff --git a/odemx-lite/include/odemx/util/Version.h b/odemx-lite/include/odemx/util/Version.h
new file mode 100644
index 0000000000000000000000000000000000000000..b7377a5ea07327b0c54ea84b7dbc06eb93b589fe
--- /dev/null
+++ b/odemx-lite/include/odemx/util/Version.h
@@ -0,0 +1,73 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Version.h
+ * @author Ralf Gerstenberger
+ * @date created at 2003/06/10
+ * @brief Declaration and Implementation of odemx::Version
+ * @sa Version.cpp
+ * @since 1.0
+ */
+
+#ifndef ODEMX_UTIL_VERSION_INCLUDED
+#define ODEMX_UTIL_VERSION_INCLUDED
+
+#include <sstream>
+#include <string>
+
+namespace odemx {
+
+/**
+ * @class Version
+ * @ingroup util
+ * @author Ralf Gerstenberger
+ * @brief ODEMx version information
+ * @since 1.0
+ */
+class Version
+{
+private:
+	/// The major version number
+	static const unsigned short major = 3;
+	/// The minor version number
+	static const unsigned short minor = 1;
+
+public:
+	/// Get major version number
+	static unsigned short getMajor() { return major; }
+	/// Get minor version number
+	static unsigned short getMinor() { return minor; }
+	/// Get version string
+	static const std::string getString()
+	{
+		static std::string version;
+
+		if( version.empty() )
+		{
+			std::ostringstream stream;
+			stream << getMajor() << '.' << getMinor();
+			version = stream.str();
+		}
+		return version;
+	}
+};
+
+} // namespace odemx
+
+#endif /* ODEMX_UTIL_VERSION_INCLUDED */
diff --git a/odemx-lite/include/odemx/util/attributes.h b/odemx-lite/include/odemx/util/attributes.h
new file mode 100644
index 0000000000000000000000000000000000000000..282a5b12e9cad3d156ad853575ca933308aea759
--- /dev/null
+++ b/odemx-lite/include/odemx/util/attributes.h
@@ -0,0 +1,47 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file attributes.h
+ * @author Magnus Müller, Toralf Niebuhr
+ * @date created at 2011/04/15
+ * @brief define compilier dependet attrtibutes
+ * @since 3.0
+ */
+
+#ifndef ATTRIBUTES_H
+#define ATTRIBUTES_H
+
+#ifndef __has_attribute         // Optional of course.
+  #define __has_attribute(x) 0  // Compatibility with non-clang compilers.
+#endif
+
+
+#ifdef __GNUC__
+#define DEPRECATED(func) func __attribute__ ((deprecated))
+#elif defined(_MSC_VER)
+#define DEPRECATED(func) __declspec(deprecated) func
+#elif __has_attribute(deprecated)
+#define DEPRECATED(func) func __attribute__ ((deprecated))
+#else
+#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
+#define DEPRECATED(func) func
+#endif
+
+#endif
+
diff --git a/odemx-lite/related documents/DA - Gerstenberger.pdf b/odemx-lite/related documents/DA - Gerstenberger.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..579c6618d44fc7dfef605e9b222ae4e0f2b82a33
Binary files /dev/null and b/odemx-lite/related documents/DA - Gerstenberger.pdf differ
diff --git a/odemx-lite/related documents/DA - Hausding.pdf b/odemx-lite/related documents/DA - Hausding.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..75f4aa68862de81d5d828513c0407162a7dbee52
Binary files /dev/null and b/odemx-lite/related documents/DA - Hausding.pdf differ
diff --git a/odemx-lite/related documents/DA - Kluth.pdf b/odemx-lite/related documents/DA - Kluth.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..02a9edb2b54a8badb210e6641bba29d182588b6f
Binary files /dev/null and b/odemx-lite/related documents/DA - Kluth.pdf differ
diff --git a/odemx-lite/related documents/SA - Integration von C++11-Features.pdf b/odemx-lite/related documents/SA - Integration von C++11-Features.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..a11df63362c22023916132c2b2a9e553392bd06d
Binary files /dev/null and b/odemx-lite/related documents/SA - Integration von C++11-Features.pdf differ
diff --git a/odemx-lite/related documents/SA - Kluth.pdf b/odemx-lite/related documents/SA - Kluth.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..20fe1accceb9ab4379ca6cd7b0cefbd0182f8616
Binary files /dev/null and b/odemx-lite/related documents/SA - Kluth.pdf differ
diff --git a/odemx-lite/related documents/SA - Morozova.pdf b/odemx-lite/related documents/SA - Morozova.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..ba98573db376c6b8e8c10d7ae992cf0f532c93a1
Binary files /dev/null and b/odemx-lite/related documents/SA - Morozova.pdf differ
diff --git a/odemx-lite/related documents/SA - Serialisierung von ODEMx-Simulationsmodellen.pdf b/odemx-lite/related documents/SA - Serialisierung von ODEMx-Simulationsmodellen.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..f145418f8340b36c32a004bbc2a468f78f469be7
Binary files /dev/null and b/odemx-lite/related documents/SA - Serialisierung von ODEMx-Simulationsmodellen.pdf differ
diff --git a/odemx-lite/related documents/WA - Schlue - Kontrollvariablen.pdf b/odemx-lite/related documents/WA - Schlue - Kontrollvariablen.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..f80a07fe5a5beedfe82b40bc99632f769f9029f9
Binary files /dev/null and b/odemx-lite/related documents/WA - Schlue - Kontrollvariablen.pdf differ
diff --git a/odemx-lite/src/base/Comparators.cpp b/odemx-lite/src/base/Comparators.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8bd7951a7eceb4e43a3bb2d273f85b59021b3efa
--- /dev/null
+++ b/odemx-lite/src/base/Comparators.cpp
@@ -0,0 +1,51 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Comparators.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/02/23
+ * @brief Implementation of odemx::base::DefaultCmp and odemx::base::QPriorityCmp
+ * @sa Comparators.h
+ * @since 3.0
+ */
+
+#include <odemx/base/Comparators.h>
+#include <odemx/base/Process.h>
+#include <odemx/base/Sched.h> // Sched op<
+
+namespace odemx {
+namespace base {
+
+bool DefaultCmp::operator()( const Sched* s1, const Sched* s2 ) const
+{
+	return s1->getPriority() > s2->getPriority();
+}
+
+bool QPriorityCmp::operator()( const Process* p1, const Process* p2 ) const
+{
+	return p1->getQueuePriority() > p2->getQueuePriority();
+}
+
+// comparison functor definition, needed for ExecutionList::inSort()
+DefaultCmp defCmp;
+
+// comparison functor definition, needed for ProcessQueue::inSort()
+QPriorityCmp qPrioCmp;
+
+} } // namespace odemx::base
diff --git a/odemx-lite/src/base/Continuous.cpp b/odemx-lite/src/base/Continuous.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..94305a1cb882552dc5d6dbbfb4c4bdafadcbd4f2
--- /dev/null
+++ b/odemx-lite/src/base/Continuous.cpp
@@ -0,0 +1,550 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2003, 2004, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file base/Continuous.cpp
+ * @author Ralf Gerstenberger
+ * @date created at 2003/06/15
+ * @brief Implementation of odemx::base::Continuous
+ * @sa Continuous.h
+ * @since 1.0
+ */
+
+#include <odemx/base/Continuous.h>
+
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <fstream>
+#include <iostream>
+#include <iomanip>
+#include <cmath>
+#include <cassert>
+
+namespace odemx {
+namespace base {
+
+Continuous::Continuous( Simulation& sim, const data::Label& label, int dimension,
+		ContinuousObserver* obs )
+:	Process( sim, label, obs )
+,	data::Observable< ContinuousObserver >( obs )
+,	state( dimension )
+,	rate( dimension )
+,	error_vector( dimension )
+,	initial_state( dimension )
+,	slope_1( dimension )
+,	slope_2( dimension )
+,	slope_3( dimension )
+, dimension( dimension )
+, stepLength( 0.01 )
+, minStepLength( 0.01 )
+, maxStepLength( 0.1 )
+, relative( 0 )
+, errorLimit( 0.1 )
+, stopped( 0 )
+, stopTime( HUGE_VAL )
+, stopCond( 0 )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Continuous) );
+
+	// observer
+	ODEMX_OBS(ContinuousObserver, Create(this));
+}
+
+
+Continuous::~Continuous()
+{
+	ODEMX_TRACE << log( "destroy" );
+}
+
+unsigned int Continuous::getDimension() const
+{
+	return dimension;
+}
+
+void Continuous::interrupt()
+{
+	// stop integration
+	stopped = 2;
+
+	Process::interrupt();
+}
+
+void Continuous::setStepLength(double min, double max)
+{
+	if( ( min <= 0 ) || ( max <= 0 ) || ( min >= max ) )
+	{
+		error << log( "Continuous::setStepLength(): invalid step length boundaries" )
+				.scope( typeid(Continuous) );
+
+		if( min < 0 ) min = -min;
+		if( max < 0 ) max = -max;
+		if( min == 0 ) min = 0.01;
+		if( max == 0 ) max = 0.1;
+		if( min >= max) max *= 10.0;
+	}
+
+	minStepLength = min;
+	maxStepLength = max;
+}
+
+double Continuous::getStepLength() const
+{
+	return stepLength;
+}
+
+void Continuous::setErrorlimit( int type, double limit )
+{
+	relative = type;
+	errorLimit = limit;
+}
+
+void Continuous::addPeer( Process* newPeer )
+{
+	assert( newPeer );
+
+	peers.push_back( newPeer );
+
+	ODEMX_TRACE << log( "add peer" ).detail( "process", newPeer ).scope( typeid(Continuous) );
+
+	// observer
+	ODEMX_OBS(ContinuousObserver, AddPeer(this, newPeer));
+}
+
+void Continuous::delPeer( Process* peer )
+{
+	assert( peer );
+
+	peers.remove( peer );
+
+	ODEMX_TRACE << log( "remove peer" ).detail( "process", peer ).scope( typeid(Continuous) );
+
+	// observer
+	ODEMX_OBS(ContinuousObserver, RemovePeer(this, peer));
+}
+
+int Continuous::integrate( SimTime timeEvent, Condition stateEvent )
+{
+	if( getProcessState() != Process::CURRENT )
+	{
+		error << log( "Continuous::integrate(): object is not the current process" )
+				.scope( typeid(Continuous) );
+	}
+
+	ODEMX_TRACE << log( "begin integrate" ).scope( typeid(Continuous) );
+
+	// observer
+	ODEMX_OBS(ContinuousObserver, BeginIntegrate(this));
+
+	// initialise stop condition
+	stopTime = timeEvent;
+	if( stopTime == 0 )
+	{
+		stopTime = HUGE_VAL;
+	}
+	stopCond = stateEvent;
+
+	stopped = 0;
+	stepLength = maxStepLength;
+	time = getTime();
+
+	// reduce priority
+	setPriority( getPriority() - 1 );
+
+	while( ! stopIntegrate()
+		   && getTime() < stopTime
+		   && ! stopped )
+	{
+		// save initial state
+		initial_state = state;
+
+		// set step length
+		if( stepLength > maxStepLength )
+		{
+			stepLength = maxStepLength;
+		}
+
+		// synchronise with timeEvent
+		SimTime stepTime = getTime() + stepLength;
+		if( stepTime > stopTime )
+		{
+			stepLength = stopTime - stepTime;
+			stepTime = stopTime;
+		}
+
+		// synchronise with peers (reduce stepLength)
+		ProcessList::iterator i;
+		for( i = peers.begin(); i != peers.end(); ++i )
+		{
+			Process* p = *i;
+			if( p->getProcessState() == Process::RUNNABLE )
+			{
+				SimTime et = p->getExecutionTime();
+				if( stepTime > et )
+				{
+					stepTime = et;
+				}
+			}
+
+			if ( stepTime < getTime() ) {
+					error << log( "Continuous::integrate(): stepTime is less than current time. Setting to current time." )
+							.scope( typeid (Continuous) );
+					stepTime = getTime();
+			}
+		}
+		stepLength = stepTime - getTime();
+
+		// integrate
+		takeAStep(stepLength);
+
+		// handle integration errors
+		while( reduce() )
+		{
+			// while integration error to great:
+
+			// reduce stepLength
+			stepLength /= 2.0;
+
+			// reset state
+			state = initial_state;
+
+			// try again
+			takeAStep( stepLength );
+		}
+
+		// handle state events
+		if( stopIntegrate() )
+		{
+			// state event->Binary search for event time
+			binSearch();
+		}
+		else
+		{
+			// waiting time
+			time += stepLength;
+			holdFor( stepLength );
+
+			ODEMX_TRACE << log( "new valid state" ).scope( typeid(Continuous) );
+
+			// observer
+			ODEMX_OBS(ContinuousObserver, NewValidState(this));
+
+			// try to increase stepLength
+			stepLength *= 2.0;
+		}
+	} // end main while loop
+
+	// reset priority
+	setPriority( getPriority() + 1 );
+
+	ODEMX_TRACE << log( "end integrate" ).scope( typeid(Continuous) );
+
+	// observer
+	ODEMX_OBS(ContinuousObserver, EndIntegrate(this, stopped));
+
+	return stopped;
+}
+
+void Continuous::binSearch()
+{
+	// Binary search (BS)
+	double sl = stepLength / 2.0; // step length for BS
+
+	if( sl < minStepLength )
+	{
+		// step length already to small
+		//->accept results
+		stopped = 1;
+
+		// waiting time
+		time += stepLength;
+		holdFor( stepLength );
+
+		ODEMX_TRACE << log( "new valid state" ).scope( typeid(Continuous) );
+
+		// observer
+		ODEMX_OBS(ContinuousObserver, NewValidState(this));
+	}
+	else
+	{
+		state = initial_state; // reset state
+		while( sl >= minStepLength )
+		{
+			// integrate
+			takeAStep( sl );
+
+			if( stopIntegrate() )
+			{
+				// step length still to long
+				// reduce sl and try again
+				sl /= 2.0;
+
+				// reset state
+				state = initial_state;
+			}
+			else
+			{
+				// accept step
+				time += sl;
+				holdFor( sl );
+
+				ODEMX_TRACE << log( "new valid state" ).scope( typeid(Continuous) );
+
+				// observer
+				ODEMX_OBS(ContinuousObserver, NewValidState(this));
+
+				initial_state = state;
+
+				// and try to get closer to the state event
+				sl /= 2.0;
+				
+			}
+		}
+		// final steps if conditions not reached
+		// take several minimal steps until condition reached
+		sl = minStepLength;
+		while (!stopIntegrate()){
+			takeAStep( sl );	
+			time += sl;
+			holdFor( sl );
+			ODEMX_TRACE << log( "new valid state" ).scope( typeid(Continuous) );
+			
+			// observer
+			ODEMX_OBS(ContinuousObserver, NewValidState(this));
+
+			initial_state = state;			
+		}
+		stopped = 1;
+	}
+}
+
+double Continuous::errorNorm()
+{
+	unsigned int i;
+	double keep_value = 0.0;
+
+	for( i = 0; i <= getDimension() - 1; i++ )
+	{
+		if( error_vector[i] > keep_value )
+		{
+			keep_value = error_vector[i];
+		}
+	}
+
+	return keep_value;
+}
+
+int Continuous::reduce()
+{
+	error_value = errorNorm();
+
+	if( error_value <= errorLimit )
+	{
+		return 0;
+	}
+	else
+	{
+		if( stepLength < ( 2.0 * minStepLength ) )
+		{
+			error << log( "Continuous::reduce(): error over limit, but can't reduce step length further" )
+					.scope( typeid(Continuous) );
+
+			return 0;
+		}
+		else
+		{
+			return 1;
+		}
+	}
+	return 0;
+}
+
+void Continuous::takeAStep( double h )
+{
+	double hdiv2, hdiv3, hdiv6, hdiv8;
+	int i;
+	int n = getDimension() - 1;
+	hdiv2 = h / 2.0;
+	hdiv3 = h / 3.0;
+	hdiv6 = h / 6.0;
+	hdiv8 = h / 8.0;
+
+	derivatives( time );
+	for( i = 0; i <= n; i++ )
+	{
+		slope_1[i] = rate[i];
+		state[i] = initial_state[i] + hdiv3 * slope_1[i];
+	}
+
+	derivatives( time + hdiv3 );
+	for( i = 0; i <= n; i++ )
+	{
+		slope_2[i] = rate[i];
+		state[i] = initial_state[i] + hdiv6 * ( slope_1[i] + slope_2[i] );
+	}
+
+	derivatives( time + hdiv3 );
+	for( i = 0; i <= n; i++ )
+	{
+		slope_2[i] = rate[i];
+		state[i] = initial_state[i] + hdiv8 * ( slope_1[i] + 3.0 * slope_2[i] );
+	}
+
+	derivatives( time + hdiv2 );
+	for( i = 0; i <= n; i++ )
+	{
+		slope_3[i] = rate[i];
+		state[i] = initial_state[i] + hdiv2 * ( slope_1[i] - 3.0 * slope_2[i] + 4.0 * slope_3[i] );
+		error_vector[i]= state[i];
+	}
+
+	derivatives( time + h );
+	for( i = 0; i <= n; i++ )
+	{
+		slope_2[i] = rate[i];
+		state[i] = initial_state[i] + hdiv6 * ( slope_1[i] + 4.0 * slope_3[i] + slope_2[i] );
+
+		if( relative )
+		{
+			if( error_vector[i] )
+			{
+				error_vector[i] = fabs( 0.2 * ( 1.0 - state[i] / error_vector[i] ) );
+			}
+		}
+		else
+		{
+			error_vector[i] = fabs( 0.2 * ( error_vector[i] - state[i] ) );
+		}
+	}
+}
+
+bool Continuous::stopIntegrate()
+{
+	bool result = false;
+	if( stopCond != 0 )
+	{
+		result = stopCond(this);
+	}
+
+	return result;
+}
+
+//--------------------------------------------------------------------ContuTrace
+
+ContuTrace::ContuTrace( Continuous* contu, const std::string& fileName )
+:	out( 0 )
+,	firstTime( true )
+{
+	if( contu != 0 )
+	{
+		contu->data::Observable< ContinuousObserver >::addObserver( this );
+	}
+
+	if( ! fileName.empty() )
+	{
+		openFile( fileName );
+	}
+	else if( contu != 0 )
+	{
+		std::string fn = contu->getLabel();
+		fn += "_trace.txt";
+		openFile( fn );
+	}
+}
+
+ContuTrace::~ContuTrace()
+{
+	if( out == 0 || out == &std::cout )
+	{
+		return;
+	}
+
+	static_cast< std::ofstream* >( out )->close();
+	delete out;
+}
+
+void ContuTrace::onNewValidState( Continuous* sender )
+{
+	using namespace std;
+
+	assert( sender != 0 );
+
+	unsigned int i = 0;
+
+	if( firstTime )
+	{
+		if( out == 0 )
+		{
+			std::string fn = sender->getLabel();
+			fn += "_trace.txt";
+			openFile( fn );
+		}
+
+		*out << endl;
+		*out << setw(60) << "T R A C E   F I L E   F O R  " << sender->getLabel() << endl << endl;
+		*out << setw(13) << "Time";
+		*out << setw(13) << "Steplength";
+		*out << setw(13) << "Error";
+
+		for( i = 0; i < sender->getDimension(); ++i )
+		{
+			*out << setw(15) << "state[" << i << "]";
+		}
+
+		for( i = 0; i < sender->getDimension(); ++i )
+		{
+			*out << setw(15) << "rate[" << i << "]";
+		}
+
+		*out << endl;
+
+		firstTime=false;
+	}
+
+	( *out ).setf( std::ios::showpoint );
+	( *out ).setf( std::ios::fixed );
+	*out << setw( 13 ) << setprecision( 7 ) << sender->getTime();
+	*out << setw( 13 ) << setprecision( 7 ) << sender->getStepLength();
+	*out << setw( 13 ) << setprecision( 7 ) << sender->error_value;
+
+	for( i = 0; i < sender->getDimension(); i++ )
+	{
+		*out << setw( 17 ) << setprecision( 7 ) << sender->state[ i ];
+	}
+
+	for( i = 0; i < sender->getDimension(); i++ )
+	{
+		*out << setw(17) << setprecision(7) << sender->rate[i];
+	}
+
+	*out << endl;
+}
+
+void ContuTrace::openFile( const std::string& fileName )
+{
+	out = new std::ofstream( fileName.c_str() );
+	if( out == 0 || !( *out ) )
+	{
+		// Error: cannot open file
+		std::cerr << "ContuTrace::openFile(): cannot open file; sending output to stdout." << std::endl;
+		out = &std::cout;
+	}
+}
+
+} } // namespace odemx::base
+
+#endif /* ODEMX_USE_CONTINUOUS */
diff --git a/odemx-lite/src/base/DefaultSimulation.cpp b/odemx-lite/src/base/DefaultSimulation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f0ba903d22755c8571894658bf6866d8eddc48fe
--- /dev/null
+++ b/odemx-lite/src/base/DefaultSimulation.cpp
@@ -0,0 +1,60 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file DefaultSimulation.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/02/07
+ * @brief Implementation of odemx::base::DefaultSimulation
+ * @sa DefaultSimulation.h, Simulation.h, Simulation.cpp
+ * @since 3.0
+ */
+
+#include <odemx/base/DefaultSimulation.h>
+
+namespace odemx {
+namespace base {
+
+//------------------------------------------------------construction/destruction
+
+DefaultSimulation::DefaultSimulation()
+:	Simulation( "DefaultSimulation" )
+{
+}
+
+DefaultSimulation::~DefaultSimulation()
+{
+}
+
+//----------------------------------------------------------------initialization
+
+void DefaultSimulation::initSimulation()
+{
+}
+
+} // namespace base
+
+//-----------------------------------------------------default simulation access
+
+base::Simulation& getDefaultSimulation()
+{
+	static base::DefaultSimulation defaultSim;
+	return defaultSim;
+}
+
+} // namespace odemx
diff --git a/odemx-lite/src/base/Event.cpp b/odemx-lite/src/base/Event.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2fba4af18117f448d1ed2a8930f3f9320bf017bb
--- /dev/null
+++ b/odemx-lite/src/base/Event.cpp
@@ -0,0 +1,274 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2007, 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Event.cpp
+ * @author Ronald Kluth
+ * @date created at 2007/04/04
+ * @brief Implementation of odemx::base::Event
+ * @sa Event.h
+ * @since 2.0
+ */
+
+#include <odemx/base/Event.h>
+#include <odemx/base/DefaultSimulation.h>
+#include <odemx/base/Simulation.h>
+#include <odemx/util/Exceptions.h>
+
+#include <string>
+#include <cassert>
+
+namespace odemx {
+namespace base {
+
+//------------------------------------------------------construction/destruction
+
+Event::Event( Simulation& sim, const data::Label& label, EventObserver* obs )
+:	Sched( sim, label, EVENT )
+,	data::Observable< EventObserver >( obs )
+,	executionTime_( static_cast< SimTime >( 0 ) )
+,	priority_( 0.0 )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Event) );
+
+	// observer
+	ODEMX_OBS(EventObserver, Create(this));
+}
+
+Event::~Event ()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Event) );
+}
+
+//----------------------------------------------------------------execution time
+
+SimTime Event::getExecutionTime() const
+{
+	return executionTime_;
+}
+
+SimTime Event::setExecutionTime( SimTime newTime )
+{
+        assert(newTime >= getTime());
+	SimTime oldTime = executionTime_;
+	executionTime_ = newTime;
+
+	ODEMX_TRACE << log( "change execution time" )
+			.valueChange( oldTime, newTime )
+			.scope( typeid(Event) );
+
+	// observer
+	ODEMX_OBS_ATTR(EventObserver, ExecutionTime, oldTime, executionTime_);
+
+	return oldTime;
+}
+
+//--------------------------------------------------------------------scheduling
+
+void Event::schedule()
+{
+	ODEMX_TRACE << log( "schedule" )
+			.detail( "partner", getPartner() )
+			.scope( typeid(Event) );
+
+	// observer
+	ODEMX_OBS( EventObserver, Schedule( this ) );
+
+	// scheduling
+	setExecutionTime( getTime() );
+	getSimulation().getScheduler().insertSched( this );
+}
+
+void Event::scheduleIn( SimTime delay )
+{
+	assert( ! (delay < 0) );
+
+	ODEMX_TRACE << log( "schedule in" )
+			.detail( "current", getPartner() )
+			.detail( "relative time", delay )
+			.scope( typeid(Event) );
+
+	// observer
+	ODEMX_OBS( EventObserver, ScheduleIn( this, delay ) );
+
+	// scheduling
+	setExecutionTime( getTime() + delay );
+	getSimulation().getScheduler().insertSched( this );
+}
+
+void Event::scheduleAt( SimTime absoluteTime )
+{
+	assert( ! (absoluteTime < getTime()) );
+
+	ODEMX_TRACE << log( "schedule at" )
+			.detail( "current", getPartner() )
+			.detail( "absolute time", absoluteTime )
+			.scope( typeid(Event) );
+
+	// observer
+	ODEMX_OBS( EventObserver, ScheduleAt( this,  absoluteTime ) );
+
+	// scheduling
+	setExecutionTime( absoluteTime );
+	getSimulation().getScheduler().insertSched( this );
+}
+
+void Event::scheduleAppend()
+{
+	ODEMX_TRACE << log( "schedule append" )
+			.detail( "partner", getPartner() )
+			.scope( typeid(Event) );
+
+	// observer
+	ODEMX_OBS( EventObserver, ScheduleAppend( this ) );
+
+	// scheduling
+	setExecutionTime( getTime() );
+	getSimulation().getScheduler().addSched( this );
+}
+
+void Event::scheduleAppendIn( SimTime delay )
+{
+	assert( ! (delay < 0) );
+
+	ODEMX_TRACE << log( "schedule append in" )
+			.detail( "current", getPartner() )
+			.detail( "relative time", delay )
+			.scope( typeid(Event) );
+
+	// observer
+	ODEMX_OBS( EventObserver, ScheduleAppendIn( this, delay ) );
+
+	// scheduling
+	setExecutionTime( getTime() + delay );
+	getSimulation().getScheduler().addSched( this );
+}
+
+void Event::scheduleAppendAt( SimTime absoluteTime )
+{
+	assert( ! (absoluteTime < getTime()) );
+
+	ODEMX_TRACE << log( "schedule append at" )
+			.detail( "current", getPartner() )
+			.detail( "absolute time", absoluteTime )
+			.scope( typeid(Event) );
+
+	// observer
+	ODEMX_OBS( EventObserver, ScheduleAppendAt( this,  absoluteTime ) );
+
+	// scheduling
+	setExecutionTime( absoluteTime );
+	getSimulation().getScheduler().addSched( this );
+}
+
+void Event::removeFromSchedule()
+{
+	if( isScheduled() )
+	{
+		getSimulation().getScheduler().removeSched( this );
+
+		ODEMX_TRACE << log( "remove from schedule" )
+				.detail( "partner", getPartner() )
+				.scope( typeid(Event) );
+
+		// observer
+		ODEMX_OBS( EventObserver, RemoveFromSchedule( this ) );
+	}
+	else
+	{
+		error << log( "Event::removeFromSchedule(): event is not scheduled" )
+				.detail( "partner", getPartner() )
+				.scope( typeid(Event) );
+	}
+}
+
+//---------------------------------------------------------------------execution
+
+void Event::execute()
+{
+	if( ! isScheduled() )
+	{
+		// error: Event has to be scheduled to be executed
+		fatal << log( "Event::executeEvent(): event is not scheduled" )
+				.scope( typeid(Event) );
+
+		throw SchedulingException( "Event not scheduled" );
+	}
+
+	// remove Event from ExecutionList
+	getSimulation().getScheduler().removeSched( this );
+
+	ODEMX_TRACE << log( "execute event" ).scope( typeid(Event) );
+
+	// observer
+	ODEMX_OBS( EventObserver, ExecuteEvent( this ) );
+
+	// current must be set here, the old value is needed for the trace above
+	getSimulation().setCurrentSched( this );
+
+	// execute the action represented by this Event
+	eventAction();
+}
+
+//----------------------------------------------------------------------priority
+
+Priority Event::setPriority( Priority newPriority )
+{
+	Priority oldPriority = priority_;
+	priority_ = newPriority;
+
+	ODEMX_TRACE << log( "change priority" )
+			.valueChange( oldPriority, newPriority )
+			.scope( typeid(Event) );
+
+	// observer
+	ODEMX_OBS_ATTR( EventObserver, Priority, oldPriority, newPriority );
+
+	if( isScheduled() )
+	{
+		// setPriority() influences ExecutionList ordering
+		getSimulation().getScheduler().inSort( this );
+	}
+
+	return oldPriority;
+}
+
+Priority Event::getPriority() const
+{
+	return priority_;
+}
+
+//-----------------------------------------------------------------------helpers
+
+SimTime Event::getCurrentTime()
+{
+	warning << log( "Event::getCurrentTime(): This method is deprecated. Use Sched::getTime() instead" ).scope( typeid(Event) );
+	return getTime();
+}
+
+const data::Label& Event::getPartner()
+{
+	if( getSimulation().getCurrentSched() != 0 )
+	{
+		return getSimulation().getCurrentSched()->getLabel();
+	}
+
+	return getSimulation().getLabel();
+}
+
+} } // namespace odemx::base
diff --git a/odemx-lite/src/base/ExecutionList.cpp b/odemx-lite/src/base/ExecutionList.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b36d1d5584bdda79bde47874d9bd666132db9b20
--- /dev/null
+++ b/odemx-lite/src/base/ExecutionList.cpp
@@ -0,0 +1,319 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ExecutionList.cpp
+ * @author Ralf Gerstenberger
+ * @date created at 2002/01/25
+ * @brief Implementation of odemx::base::ExecutionList
+ * @sa ExecutionList.h
+ * @since 1.0
+ */
+
+#include <odemx/base/ExecutionList.h>
+#include <odemx/base/Comparators.h>
+#include <odemx/base/Event.h>
+#include <odemx/base/Process.h>
+#include <odemx/base/Simulation.h>
+#include <odemx/util/ListInSort.h>
+
+#include <algorithm>
+#include <cassert>
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+
+#ifdef _MSC_VER
+#include <functional>
+#else
+#include <functional>
+#endif
+
+namespace odemx {
+namespace base {
+
+//------------------------------------------------------construction/destruction
+
+ExecutionList::ExecutionList( Simulation& sim, const data::Label& label )
+:	data::Producer( sim, label )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(ExecutionList) );
+}
+
+ExecutionList::~ExecutionList()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(ExecutionList) );
+}
+
+//---------------------------------------------------------------sched insertion
+
+void ExecutionList::addSched( Sched* s )
+{
+	assert( s );
+
+	ODEMX_TRACE << log( "add" )
+			.detail( "partner", s->getLabel() )
+			.scope( typeid(ExecutionList) );
+
+	// adjust execution time if necessary
+	if ( s->getExecutionTime() < getTime() )
+	{
+		s->setExecutionTime( getTime() );
+	}
+
+	// append Sched s at its ExecutionTime
+	// to ExecutionList (FIFO), considering priority
+	inSort( s );
+}
+
+void ExecutionList::insertSched( Sched* s )
+{
+	assert( s );
+
+	ODEMX_TRACE << log( "insert" )
+			.detail( "partner", s->getLabel() )
+			.scope( typeid(ExecutionList) );
+
+	// adjust execution time
+	if ( s->getExecutionTime() < getTime() )
+	{
+		s->setExecutionTime( getTime() );
+	}
+
+	// insert Sched s at ExecutionTime in
+	// ExecutionList (LIFO), considering priority
+	inSort( s, false );
+}
+
+void ExecutionList::insertSchedAfter( Sched* s, Sched* partner )
+{
+	assert( s && partner );
+
+	if( s == partner )
+	{
+		error << log( "ExecutionList::insertSchedAfter(): "
+				"sched and partner are the same" )
+				.scope( typeid(ExecutionList) );
+		return;
+	}
+
+	if( ! partner->isScheduled() )
+	{
+		error << log( "ExecutionList::insertSchedAfter(): "
+				"partner not scheduled" )
+				.scope( typeid(ExecutionList) );
+		return;
+	}
+
+	// remove Sched s from ExecutionList if scheduled
+	if( s->isScheduled() )
+	{
+		removeSched( s );
+	}
+
+	Priority prevPrio = partner->getPriority();
+
+	// adjust priority so the list order remains correct for s and partner
+	if ( s->getPriority() > prevPrio )
+	{
+		s->setPriority( prevPrio );
+	}
+
+	// set s to execution time of partner
+	s->setExecutionTime( partner->getExecutionTime() );
+
+	// insert Sched s after partner
+	SchedList::iterator pos = partner->execListIter_;
+	++pos;
+	s->execListIter_ = partner->scheduleLoc_.second->insert( pos, s );
+	s->scheduleLoc_ = partner->scheduleLoc_;
+	s->scheduled_ = true;
+
+	ODEMX_TRACE << log( "insert after" )
+			.detail( "partner", s->getLabel() )
+			.detail( "after", partner->getLabel() )
+			.scope( typeid(ExecutionList) );
+}
+
+void ExecutionList::insertSchedBefore( Sched* s, Sched* partner )
+{
+	assert( s && partner );
+
+	if( s == partner )
+	{
+		error << log( "ExecutionList::insertSchedBefore(): "
+				"sched and partner are the same" )
+				.scope( typeid(ExecutionList) );
+		return;
+	}
+
+	if( ! partner->isScheduled() )
+	{
+		error << log( "ExecutionList::insertSchedBefore(): "
+				"partner not scheduled" )
+				.scope( typeid(ExecutionList) );
+		return;
+	}
+
+	// remove Sched s from ExecutionList if scheduled
+	if( s->isScheduled() )
+	{
+		removeSched( s );
+	}
+
+	Priority partnerPrio = partner->getPriority();
+
+	// adjust priority to maintain list order
+	if ( s->getPriority() < partnerPrio )
+	{
+		s->setPriority( partnerPrio );
+	}
+
+	// set s execution time to execution time of partner
+	s->setExecutionTime( partner->getExecutionTime() );
+
+	// insert Sched s before partner
+	assert( partner->scheduleLoc_.second );
+	s->execListIter_ = partner->scheduleLoc_.second->insert( partner->execListIter_, s );
+	s->scheduleLoc_ = partner->scheduleLoc_;
+	s->scheduled_ = true;
+
+	ODEMX_TRACE << log( "insert before" )
+			.detail( "partner", s->getLabel() )
+			.detail( "before", partner->getLabel() )
+			.scope( typeid(ExecutionList) );
+}
+
+void ExecutionList::inSort( Sched* s, bool fifo )
+{
+	assert( s );
+
+	// remove the object from exec list if it is already scheduled
+	if ( s->isScheduled() )
+	{
+		removeSched( s );
+	}
+
+	// insert s into ordered list and store the location as iterator
+	s->scheduleLoc_ = std::make_pair( s->getExecutionTime(),
+			&( schedule_[ s->getExecutionTime() ] ) );
+
+	s->execListIter_ = ListInSort< Sched*, DefaultCmp >(
+						*s->scheduleLoc_.second, s, defCmp, fifo );
+
+	s->scheduled_ = true;
+}
+
+//-----------------------------------------------------------------sched removal
+
+void ExecutionList::removeSched( Sched* s )
+{
+	assert( s );
+
+	if( ! s->isScheduled() )
+	{
+		error << log( "ExecutionList::removeSched(): "
+				"attempt to remove unscheduled object" )
+				.detail( "sched", s->getLabel() )
+				.scope( typeid(ExecutionList) );
+		return;
+	}
+
+	// remove s from its schedule list
+	assert( s->scheduleLoc_.second );
+	s->scheduleLoc_.second->erase( s->execListIter_ );
+
+	// erase the map entry from the list if no other object is scheduled at the time
+	if( s->scheduleLoc_.second->empty() )
+	{
+		schedule_.erase( s->scheduleLoc_.first );
+	}
+
+	// reset members
+	s->scheduleLoc_ = std::make_pair( static_cast< SimTime >( 0 ),
+			static_cast< SchedList* >( 0 ) );
+	s->scheduled_ = false;
+
+	ODEMX_TRACE << log( "remove" )
+			.detail( "sched", s->getLabel() )
+			.scope( typeid(ExecutionList) );
+}
+
+//-------------------------------------------------------------various accessors
+
+Sched* ExecutionList::getNextSched() const
+{
+	if( schedule_.empty() )
+	{
+		return 0;
+	}
+	return schedule_.begin()->second.front();
+}
+
+SimTime ExecutionList::getNextExecutionTime() const
+{
+	if( schedule_.empty() )
+	{
+		return 0;
+	}
+	return schedule_.begin()->first;
+}
+
+bool ExecutionList::isEmpty() const
+{
+	return schedule_.empty();
+}
+
+SimTime ExecutionList::getTime()
+{
+	return getSimulation().getTime();
+}
+
+//-----------------------------------------------------------------------logging
+
+void ExecutionList::logToChannel( const ChannelPtr channel ) const
+{
+	// create record
+	data::SimRecord record = log( "scheduled objects" ).scope( typeid(ExecutionList) );
+	record.detail( "time entries", schedule_.size() );
+
+	// add record details ( Position, Time, Label )
+	std::ostringstream tmpStream;
+	size_t position = 0;
+
+	// iterate over the map
+	for( Schedule::const_iterator iter = schedule_.begin();
+		iter != schedule_.end(); ++iter )
+	{
+		// iterate over each list
+		for( SchedList::const_iterator listIter = iter->second.begin();
+			listIter != iter->second.end(); ++listIter, ++position )
+		{
+			Sched* scheduled = *listIter;
+
+			record.detail( "pos", position )
+				.detail( "time", scheduled->getExecutionTime() )
+				.detail( "obj", scheduled->getLabel() );
+		}
+	}
+
+	// log the whole record to the given channel
+	channel << record;
+}
+
+} } // namespace odemx::base
diff --git a/odemx-lite/src/base/Process.cpp b/odemx-lite/src/base/Process.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d0764c4a6e75708af383defc50b06ea960be469c
--- /dev/null
+++ b/odemx-lite/src/base/Process.cpp
@@ -0,0 +1,1065 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007, 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Process.cpp
+ * @author Ralf Gerstenberger
+ * @date created at 2002/01/30
+ * @brief Implementation of odemx::base::Process
+ * @sa Process.h
+ * @since 1.0
+ */
+
+#include <odemx/base/Process.h>
+#include <odemx/base/Event.h>
+#include <odemx/base/Simulation.h>
+#include <odemx/synchronization/ProcessQueue.h>
+#include <odemx/synchronization/Timer.h>
+#include <odemx/synchronization/Memory.h>
+#include <odemx/util/Exceptions.h>
+
+#include <odemx/base/control/Control.h>
+#include <odemx/base/control/ControlBase.h>
+
+#include <string>
+#include <memory> // auto_ptr
+
+#ifdef _MSC_VER
+#include <functional>
+#else
+#include <functional>
+#endif
+
+
+namespace odemx {
+namespace base {
+
+Process::Process( Simulation& sim, const data::Label& label, ProcessObserver* obs )
+:	Sched( sim, label, PROCESS )
+,	Coroutine( &sim, obs )
+,	data::Observable< ProcessObserver >( obs )
+,	processState_( CREATED )
+,	priority_( 0.0 )
+,	executionTime_( static_cast< SimTime >(0) )
+,	validReturn_( false )
+,	returnValue_( 0 )
+,	queue_( 0 )
+,	enqueueTime_( static_cast< SimTime >(0) )
+,	dequeueTime_( static_cast< SimTime >(0) )
+,	queuePriority_( 0.0 )
+,	isInterrupted_( false )
+,	interrupter_( 0 )
+,	isAlerted_( false )
+,	alerter_( 0 )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS(ProcessObserver, Create(this));
+
+	this->getSimulation().setProcessAsCreated( this );
+}
+
+Process::~Process()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Process) );
+
+	// the simulation must not have a pointer to a destroyed process
+	getSimulation().removeProcessFromList( this );
+}
+
+void Process::activate()
+{
+	ODEMX_TRACE << log( "activate" ).detail( "partner", getPartner() )
+			.scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS(ProcessObserver, Activate(this));
+
+	// state management
+	if( ! setProcessState( RUNNABLE ) )
+	{
+		return;
+	}
+
+	// reset interrupt state
+	resetInterrupt();
+
+	// reset memory alert state
+	resetAlert();
+
+	// scheduling
+	setExecutionTime( getTime() );
+	getSimulation().getScheduler().insertSched( this );
+
+	// continue simulation
+	getSimulation().switchTo();
+}
+
+void Process::activateIn( SimTime t )
+{
+	if ( t < 0 ) {
+		error << log( "Process::activateIn(): Parameter t less than 0 not allowed. Setting it to 0." )
+				.scope( typeid(Process) );
+		t = 0;
+	}
+
+	ODEMX_TRACE << log( "activate in" )
+			.detail( "relative time", t )
+			.detail( "partner", getPartner() )
+			.scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS(ProcessObserver, ActivateIn(this, t));
+
+	// state management
+	if( ! setProcessState( RUNNABLE ) )
+	{
+		return;
+	}
+
+	// reset interrupt state
+	resetInterrupt();
+
+	// reset Memory::alert state
+	resetAlert();
+
+	// scheduling
+	setExecutionTime( getTime() + t );
+	getSimulation().getScheduler().insertSched( this );
+
+	// continue simulation
+	getSimulation().switchTo();
+}
+
+void Process::activateAt( SimTime t )
+{
+	if ( t < getTime () ) {
+		error << log( "Process::activateAt(): Parameter t less than current time not allowed. Setting it to current time." )
+				.scope( typeid(Process) );
+		t = getTime();
+	}
+
+	ODEMX_TRACE << log( "activate at" )
+			.detail( "absolute time", t )
+			.detail( "partner", getPartner() )
+			.scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS(ProcessObserver, ActivateAt(this, t));
+
+	// state management
+	if( ! setProcessState( RUNNABLE ) )
+	{
+		return;
+	}
+
+	// reset interrupt state
+	resetInterrupt();
+
+	// reset Memory::alert state
+	resetAlert();
+
+	// scheduling
+	setExecutionTime( t );
+	getSimulation().getScheduler().insertSched( this );
+
+	// continue simulation
+	getSimulation().switchTo();
+}
+
+void Process::activateBefore( Sched* p )
+{
+	assert( p );
+
+	ODEMX_TRACE << log( "activate before" )
+			.detail( "partner", getPartner() )
+			.detail( "before", p-> getLabel() )
+			.scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS(ProcessObserver, ActivateBefore(this, p));
+
+	// state management
+	if (!setProcessState(RUNNABLE))
+	{
+		return;
+	}
+
+	// reset interrupt state
+	resetInterrupt();
+
+	// reset Memory::alert state
+	resetAlert();
+
+	// scheduling
+	getSimulation().getScheduler().insertSchedBefore( this, p );
+
+	// continue simulation
+	getSimulation().switchTo();
+}
+
+void Process::activateAfter( Sched* p )
+{
+	assert( p );
+
+	ODEMX_TRACE << log( "activate after" )
+			.detail( "partner", getPartner() )
+			.detail( "after", p->getLabel() )
+			.scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS(ProcessObserver, ActivateAfter(this, p));
+
+	// state management
+	if( ! setProcessState( RUNNABLE ) )
+	{
+		return;
+	}
+
+	// reset interrupt state
+	resetInterrupt();
+
+	// reset Memory::alert state
+	resetAlert();
+
+	// scheduling
+	getSimulation().getScheduler().insertSchedAfter( this, p );
+
+	// continue simulation ?
+	// this function should never require a context change
+	// because scheduling after another Sched object requires
+	// for that to be executed first;
+
+	// if compSimulation() is called here, it leads to odd
+	// stepping results because the caller of this function
+	// has to continue its life cycle anyway
+
+	// an attempt to make this work with self-activation:
+	if( this == getCurrentSched() )
+	{
+		getSimulation().switchTo();
+	}
+}
+
+void Process::genericHoldUntil(SimTime t) {
+
+	// state management
+	if( ! setProcessState( RUNNABLE ) )
+	{
+		return;
+	}
+
+	// reset interrupt state
+	resetInterrupt();
+
+	// reset Memory::alert state
+	resetAlert();
+
+	// scheduling
+	setExecutionTime( t );
+	getSimulation().getScheduler().addSched( this );
+
+	// continue simulation
+	getSimulation().switchTo();
+}
+
+void Process::hold()
+{
+	ODEMX_TRACE << log( "hold" )
+			.detail( "partner", getPartner() )
+			.scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS(ProcessObserver, Hold(this));
+	genericHoldUntil(getTime());
+}
+
+void Process::holdFor( SimTime t )
+{
+	if ( t < 0 ) {
+		error << log( "Process::holdFor(): Parameter t less than 0 not allowed. Setting it to 0." )
+				.scope( typeid(Process) );
+		t = 0;
+	}
+
+	ODEMX_TRACE << log( "hold for" ).detail( "relative time", t )
+			.detail( "partner", getPartner() ).scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS(ProcessObserver, HoldFor(this, t));
+
+	genericHoldUntil(getTime() + t);
+}
+
+void Process::holdUntil( SimTime t )
+{
+	if ( t < getTime () ) {
+		error << log( "Process::activateAt(): Parameter t less than current time not allowed. Setting it to current time." )
+				.scope( typeid(Process) );
+		t = getTime();
+	}
+
+	ODEMX_TRACE << log( "hold until" ).detail( "absolute time", t )
+			.detail( "partner", getPartner() ).scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS(ProcessObserver, HoldUntil(this, t));
+
+	genericHoldUntil(t);
+
+}
+
+bool Process::waitUntil(const Condition& condition, const std::string label,
+		const std::vector<std::reference_wrapper<ControlBase>>& controls)
+{
+	if( ! getCurrentSched() || getCurrentSched()->getSchedType() != base::Sched::PROCESS )
+	{
+		error << log( "Process::wait(): called by non-Process object" )
+				.scope( typeid(Process) )
+				.detail( "condition" , label);
+		return false;
+	}
+
+	if (getCurrentProcess() != this) {
+		error << log( "Process::wait(): calling Process must be the current Process")
+	            .scope( typeid(Process) )
+				.detail( "condition" , label);
+		return false;
+	}
+
+	// log
+	ODEMX_TRACE << log( "wait" )
+				.scope( typeid(Process) )
+				.detail( "condition" , label);
+
+	resetAlert();
+
+	if(condition(this)) {
+
+		// shortcut if condition(this) returned true
+
+		// log
+		ODEMX_TRACE << log( "continue" )
+					.scope( typeid(Process) )
+					.detail( "condition turned true immediately" , label);
+
+		// statistics
+		statistics << update( "wait time", 0 ).scope( typeid(Process) );
+
+		return true;
+
+	} else {
+
+		// condition(this) returned false
+
+		// statistics
+		base::SimTime waitStart = getTime();
+
+		// create memory vector representing controls for observation
+		std::unique_ptr< synchronization::IMemoryVector > memoryVector( new synchronization::IMemoryVector );
+		memoryVector->reserve(controls.size());
+
+		// register conditions and build memory vector
+		for(auto& control: controls) {
+			control.get().waitingProcesses_.push_back(this);
+			memoryVector->push_back(&control.get());
+		}
+
+		// observer
+		ODEMX_OBS(ProcessObserver, Wait(this, memoryVector.get()));
+
+		// check condition and block
+		while( ! (isAlerted() || condition(this)) )
+		{
+			this->sleep();
+
+			if( this->isInterrupted() )
+			{
+				// unregister conditions
+				for(auto& control: controls) {
+					control.get().waitingProcesses_.remove(this);
+				}
+				return false;
+			}
+		}
+
+		// block released
+
+		// process observation is handled in alertProcess(), called by ControlBase::signal()
+
+		// unregister this process
+		for(auto& control: controls) {
+			control.get().waitingProcesses_.remove(this);
+		}
+
+		// log
+		ODEMX_TRACE << log( "continue" )
+					.scope( typeid(Process) )
+					.detail( "condition turned true" , label);
+
+		// statistics
+		base::SimTime waitTime = getTime() - waitStart;
+		statistics << update( "wait time", waitTime ).scope( typeid(Process) );
+		statistics << count( "users" ).scope( typeid(ControlBase) );
+
+		return true;
+	}
+}
+
+// m0 always has to be given, else no matching call
+synchronization::IMemory* Process::wait( synchronization::IMemory* m0, synchronization::IMemory* m1,
+		synchronization::IMemory* m2, synchronization::IMemory* m3, synchronization::IMemory* m4, synchronization::IMemory* m5 )
+{
+	assert( m0 );
+
+	// TODO: implement this and the other overload with vector object, not ptr
+	// so the internally created MemoryVector is cleaned up automatically
+	std::unique_ptr< synchronization::IMemoryVector > memvec( new synchronization::IMemoryVector );
+
+	memvec->reserve( 6 );
+	memvec->push_back( m0 );
+
+	// add more parameters to vector, if they are given
+	if( m1 ) memvec->push_back( m1 );
+	if( m2 ) memvec->push_back( m2 );
+	if( m3 ) memvec->push_back( m3 );
+	if( m4 ) memvec->push_back( m4 );
+	if( m5 ) memvec->push_back( m5 );
+
+	synchronization::IMemory* alerter = wait( memvec.get() );
+	return alerter;
+}
+
+synchronization::IMemory* Process::wait( synchronization::IMemoryVector* memvec )
+{
+	assert( memvec );
+
+	if( memvec->empty() )
+	{
+		warning << log( "Process::wait(): no memory objects given" )
+				.scope( typeid(Process) );
+
+		return 0;
+	}
+
+	traceWait( *memvec );
+
+	// observer
+	ODEMX_OBS( ProcessObserver, Wait( this, memvec ) );
+
+	// before suspending, check availability of memory objects
+	synchronization::IMemoryVector::iterator iter;
+	for( iter = memvec->begin(); iter != memvec->end(); ++iter )
+	{
+		synchronization::IMemory* current = *iter;
+
+		if ( current->isAvailable() )
+		{
+			// log the available object
+			data::Producer* labeled = dynamic_cast< data::Producer* >( current );
+			if( labeled != 0 )
+			{
+				ODEMX_TRACE << log( "available" ).detail( "memory object", labeled->getLabel() )
+						.scope( typeid(Process) );
+			}
+			// memory object cannot be cast to labeled object, use address
+			else
+			{
+				ODEMX_TRACE << log( "available" )
+						.detail( "memory object", "no label" )
+						.scope( typeid(Process) );
+			}
+
+			// if a Timer is not set, do not return, it might be set elsewhere
+			if( current->getMemoryType() == synchronization::IMemory::TIMER )
+			{
+				warning << log( "Process::wait(): unset timer available" )
+				.detail( "memory object", static_cast< synchronization::Timer* >( current )->getLabel() )
+				.scope( typeid(Process) );
+			}
+			else // other available Memo objects will be returned
+			{
+				return current;
+			}
+		}
+	}
+
+	// since none are available, register this process with the given Memory objects
+	for( iter = memvec->begin(); iter != memvec->end(); ++iter )
+	{
+		(*iter)->remember( this );
+	}
+
+	// the alert mechanism is normally only used with wait()
+	// reset alerter and alerted anyway, if set somewhere else
+	resetAlert();
+
+	// suspend process
+	sleep();
+
+	// ************* beyond this point, the process was awakened ************
+
+	// trace of alert and interrupt in other methods
+
+	// check for Memory alert
+	if( isAlerted() )
+	{
+		synchronization::IMemory* currentAlerter = getAlerter();
+
+		for( iter = memvec->begin(); iter != memvec->end(); ++iter )
+		{
+			// currentAlerter has already removed this process
+      // Note: We have to check if the process current process is really deleted
+      // from all waiting lists, as PortHeadT doesn't delete on alert.
+
+      // we try to dynamic_cast to Memory*. If it is a Memory object, we know that we can
+      // use its processIsWaiting method.
+      if ( (*iter) != currentAlerter )
+      {
+				(*iter)->forget( this );
+      } 
+      else
+      {
+        odemx::synchronization::Memory *memory = dynamic_cast< odemx::synchronization::Memory* > (*iter);
+        if ( memory && memory -> processIsWaiting ( *this ) ) 
+          (*iter) -> forget ( this );
+      }
+		}
+
+		// reset so outdated alerted/alerter cannot be used elsewhere by accident
+		resetAlert();
+
+		return currentAlerter;
+	}
+	// the sleep() period can be interrupted by other processes
+	else if( isInterrupted() )
+	{
+		// remove this from all Memos
+		for( iter = memvec->begin(); iter != memvec->end(); ++iter )
+		{
+			(*iter)->forget( this );
+		}
+
+		warning << log( "Process::wait(): waiting period ended by interrupt" )
+				.detail( "interrupter", getInterrupter()->getLabel() )
+				.scope( typeid(Process) );
+
+		// when wait returns 0, a Process should check for interrupts
+		return 0;
+	}
+	else
+	{
+		error << log( "Process::wait(): Process awakened without alert or interrupt" )
+				.scope( typeid(Process) );
+	}
+	return 0;
+}
+
+void Process::alertProcess( synchronization::IMemory* alerter )
+{
+	assert( alerter );
+
+	// trace alert and alerter
+	data::Producer* labeled = dynamic_cast< data::Producer* >( alerter );
+	if( labeled != 0 )
+	{
+		ODEMX_TRACE << log( "alert" )
+				.detail( "memory object", labeled->getLabel() )
+				.scope( typeid(Process) );
+	}
+	// memory object cannot be cast to labeled object, use address
+	else
+	{
+		ODEMX_TRACE << log( "alert" )
+				.detail( "memory object", reinterpret_cast<size_t>( alerter ) )
+				.scope( typeid(Process) );
+	}
+
+	// observer
+	ODEMX_OBS( ProcessObserver, Alert( this, alerter ) );
+
+	isAlerted_ = true;
+	alerter_ = alerter;
+
+	// state management
+	if( ! setProcessState( RUNNABLE ) )
+	{
+		return;
+	}
+
+	// scheduling
+	setExecutionTime( getTime() );
+	getSimulation().getScheduler().insertSched( this );
+}
+
+bool Process::isAlerted() const
+{
+	return isAlerted_;
+}
+
+synchronization::IMemory* Process::getAlerter() const
+{
+	return alerter_;
+}
+
+void Process::resetAlert()
+{
+	isAlerted_ = false;
+	alerter_ = 0;
+}
+
+void Process::resetInterrupt()
+{
+	isInterrupted_ = false;
+	interrupter_ = 0;
+}
+
+bool Process::isInterrupted() const
+{
+	return isInterrupted_;
+}
+
+Sched* Process::getInterrupter()
+{
+	return interrupter_;
+}
+
+void Process::interrupt()
+{
+	// ignore self interrupt
+	if( this == getCurrentSched() )
+	{
+		return;
+	}
+
+	if( isInterrupted() )
+	{
+		warning << log( "Process::interrupt(): process is already interrupted" )
+				.scope( typeid(Process) );
+
+		// return; ???
+	}
+
+	ODEMX_TRACE << log( "interrupted by" )
+			.detail( "partner", getPartner() )
+			.scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS(ProcessObserver, Interrupt(this));
+
+	// Set interrupt data
+	isInterrupted_ = true;
+	interrupter_ = getCurrentSched();
+
+	// state management
+	if( ! setProcessState( RUNNABLE ) )
+	{
+		return;
+	}
+
+	// scheduling
+	setExecutionTime( getTime() );
+	getSimulation().getScheduler().insertSched( this );
+
+	// continue simulation
+	getSimulation().switchTo();
+}
+
+void Process::sleep()
+{
+	ODEMX_TRACE << log( "sleep" )
+			.detail( "partner", getPartner() )
+			.scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS(ProcessObserver, Sleep(this));
+
+	// reset interrupt state
+	resetInterrupt();
+
+	// state management
+	if( ! setProcessState( IDLE ) )
+	{
+		return;
+	}
+
+	// scheduling
+	getSimulation().getScheduler().removeSched( this );
+
+	// continue simulation
+	getSimulation().switchTo();
+}
+
+void Process::cancel()
+{
+	ODEMX_TRACE << log( "cancel" )
+			.detail( "partner", getPartner() )
+			.scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS(ProcessObserver, Cancel(this));
+
+	if( setProcessState( TERMINATED ) )
+	{
+		// de-scheduling
+		if( isScheduled() )
+		{
+			getSimulation().getScheduler().removeSched( this );
+		}
+
+		// continue simulation
+		getSimulation().switchTo();
+	}
+}
+
+Sched* Process::getCurrentSched()
+{
+	return getSimulation().getCurrentSched();
+}
+
+Process* Process::getCurrentProcess()
+{
+	return getSimulation().getCurrentProcess();
+}
+
+SimTime Process::getCurrentTime() const
+{
+	warning << log( "Process::getCurrentTime(): This method is deprecated. Use Sched::getTime() instead" ).scope( typeid(Process) );
+	return getTime ();
+}
+
+
+void Process::execute()
+{
+	if( processState_ != RUNNABLE && processState_ != CURRENT )
+	{
+		fatal << log( "Process::execute(): process is not RUNNABLE or CURRENT" )
+				.scope( typeid(Process) );
+
+		throw SchedulingException( "Process::execute(): process state not CURRENT or RUNNABLE" );
+	}
+
+	ODEMX_TRACE << log( "execute process" )
+			.detail( "partner", getPartner() )
+			.scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS(ProcessObserver, Execute(this));
+
+	// old currentSched value is needed in getPartner()
+	setProcessState( CURRENT );
+
+	// switch to Coroutine
+	switchTo();
+}
+
+Process::ProcessState Process::getProcessState() const
+{
+	return processState_;
+}
+
+bool Process::setProcessState( ProcessState newState )
+{
+	if( processState_ == TERMINATED )
+	{
+		error << log( "Process::setProcessState(): attempt to change state of terminated process" )
+				.detail( "partner", getPartner() ).scope( typeid(Process) );
+
+		return false;
+	}
+
+	if( newState == CREATED )
+	{
+		error << log( "Process::setProcessState(): process state is already set as CREATED" )
+				.detail( "partner", getPartner() ).scope( typeid(Process) );
+
+		return false;
+	}
+
+	ProcessState oldState = processState_;
+
+	switch( newState )
+	{
+	case CREATED:
+		getSimulation().setProcessAsCreated( this );
+		break;
+	case RUNNABLE:
+		getSimulation().setProcessAsRunnable( this );
+		break;
+	case CURRENT:
+		getSimulation().setCurrentProcess( this );
+		break;
+	case IDLE:
+		getSimulation().setProcessAsIdle( this );
+		break;
+	case TERMINATED:
+		getSimulation().setProcessAsTerminated( this );
+		break;
+	}
+
+	// must set state here because the old state is still needed
+	// above by getSimulation().setProcessAsXXX
+	processState_ = newState;
+
+	ODEMX_TRACE << log( "change process state" )
+			.valueChange( stateToString( oldState ), stateToString( newState ) )
+			.scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS_ATTR(ProcessObserver, ProcessState, oldState, newState);
+
+	return true;
+}
+
+void Process::run()
+{
+	returnValue_ = main();
+
+	// Process lifeline is finished [returned from main()]
+
+	getSimulation().getScheduler().removeSched( this );
+
+	// The return value is valid now
+	validReturn_ = true;
+
+	ODEMX_TRACE << log( "return" ).detail( "value", returnValue_ ).scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS(ProcessObserver, Return(this));
+
+	setProcessState( TERMINATED );
+
+	// in case the context is switched, this coroutine will not be reactivated
+	// so it must be cleared here
+	Coroutine::clear();
+
+	// continue simulation
+	getSimulation().switchTo();
+}
+
+bool Process::hasReturned() const
+{
+	return validReturn_;
+}
+
+int Process::getReturnValue() const
+{
+	if( ! validReturn_ )
+	{
+		warning << log( "Process::getReturnValue(): return value is not valid" )
+				.scope( typeid(Process) );
+	}
+	return returnValue_;
+}
+
+Priority Process::getPriority() const
+{
+	return priority_;
+}
+
+Priority Process::setPriority( Priority newPriority )
+{
+	Priority oldPriority = priority_;
+	priority_ = newPriority;
+
+	ODEMX_TRACE << log( "change priority" ).valueChange( oldPriority, newPriority )
+			.scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS_ATTR(ProcessObserver, Priority, oldPriority, newPriority);
+
+	// changes in priority may influence ExecutionList
+	if( isScheduled() || getProcessState() == CURRENT )
+	{
+		getSimulation().getScheduler().inSort( this );
+	}
+
+	// precise check for context change because running insertSchedAfter()
+	// creates unexpected stepping if its call to setPriority() causes
+	// compSimulation() to be called without need
+//	if( getCurrentSched()
+//		&& getSimulation().getScheduler().getNextSched() != getCurrentSched() )
+//	{
+		getSimulation().switchTo();
+//	}
+
+	return oldPriority;
+}
+
+SimTime Process::getExecutionTime() const
+{
+	if( processState_ != RUNNABLE && processState_ != CURRENT )
+	{
+		return static_cast< SimTime >(0);
+	}
+	return executionTime_;
+}
+
+SimTime Process::setExecutionTime( SimTime newTime )
+{
+	if ( newTime < getTime() ) {
+			error << log( "Process::setExecutionTime(): newTime is less than current time. Setting to current time." )
+				.scope( typeid(Process) );
+			newTime = getTime();
+	}
+
+	SimTime oldTime = executionTime_;
+	executionTime_ = newTime;
+
+	ODEMX_TRACE << log( "change execution time" ).valueChange( oldTime, newTime )
+			.scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS_ATTR(ProcessObserver, ExecutionTime, oldTime, newTime);
+
+	return oldTime;
+}
+
+void Process::enqueue( synchronization::ProcessQueue* inQueue )
+{
+	assert( inQueue );
+
+	if( queue_ != 0 )
+	{
+		fatal << log( "Process::enqueue(): process already listed in a queue" )
+				.scope( typeid(Process) );
+
+		throw QueueingException( "Process::enqueue(): process already listed in a queue" );
+	}
+
+	queue_ = inQueue;
+	enqueueTime_ = getTime();
+}
+
+SimTime Process::getEnqueueTime() const
+{
+	return enqueueTime_;
+}
+
+void Process::dequeue( synchronization::ProcessQueue* outQueue )
+{
+	assert( outQueue );
+
+	if( queue_ != outQueue )
+	{
+		fatal << log( "Process::dequeue(): process dequeued by wrong queue" )
+				.scope( typeid(Process) );
+
+		throw QueueingException( "Process::dequeue(): process dequeued by wrong queue" );
+	}
+
+	queue_ = 0;
+	dequeueTime_ = getTime();
+}
+
+SimTime Process::getDequeueTime() const
+{
+	return dequeueTime_;
+}
+
+synchronization::ProcessQueue* Process::getQueue() const
+{
+	return queue_;
+}
+
+Priority Process::getQueuePriority() const
+{
+	return queuePriority_;
+}
+
+Priority Process::setQueuePriority( Priority newQPriority, bool reactivate )
+{
+	Priority oldQPriority = queuePriority_;
+	queuePriority_ = newQPriority;
+
+	ODEMX_TRACE << log( "change queue priority" ).valueChange( oldQPriority, newQPriority )
+			.scope( typeid(Process) );
+
+	// observer
+	ODEMX_OBS_ATTR(ProcessObserver, QueuePriority, oldQPriority, newQPriority);
+
+	// check if this Process is in a queue, sort queue again
+	if( queue_ != 0 )
+	{
+		queue_->inSort( this );
+	}
+
+	// this Process might have become the first in a waiting queue,
+	// it will still be blocked in queue if condition not met
+	if( reactivate )
+	{
+		activate();
+		getSimulation().switchTo();
+	}
+	return oldQPriority;
+}
+
+void Process::traceWait( synchronization::IMemoryVector& memvec )
+{
+#ifdef ODEMX_TRACE_ENABLED
+    // create a record object
+    data::SimRecord record = log( "wait" ).scope( typeid(Process) );
+
+    // add details to record:
+    synchronization::IMemoryVector::const_iterator iter;
+    for( iter = memvec.begin(); iter != memvec.end(); ++iter )
+    {
+        data::Producer* labeled = dynamic_cast< data::Producer* >( *iter );
+
+        // memvec contains IMemory*, check if it is castable to labeled object
+        if( labeled )
+        {
+            record.detail( "memory object", labeled->getLabel() );
+        }
+        else // not a labeled object
+        {
+            record.detail( "memory object", "no label" );
+        }
+    }
+
+    // log record to trace channel
+    ODEMX_TRACE << record;
+#endif
+}
+
+const data::Label& Process::getPartner()
+{
+	if( getSimulation().getCurrentSched() != 0 )
+	{
+		return getSimulation().getCurrentSched()->getLabel();
+	}
+
+	return getSimulation().getLabel();
+}
+
+std::string Process::stateToString( ProcessState state )
+{
+	switch( state )
+	{
+	case CREATED: return "CREATED";
+	case RUNNABLE: return "RUNNABLE";
+	case CURRENT: return "CURRENT";
+	case IDLE: return "IDLE";
+	case TERMINATED: return "TERMINATED";
+	}
+	// this will never happen
+	return "THISCANTHAPPEN";
+}
+
+} } // namespace odemx::base
diff --git a/odemx-lite/src/base/Sched.cpp b/odemx-lite/src/base/Sched.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d888aea275b83e1c8136c71a6f2c87c4f94393d2
--- /dev/null
+++ b/odemx-lite/src/base/Sched.cpp
@@ -0,0 +1,78 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2007, 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Sched.cpp
+ * @author Ronald Kluth
+ * @date created at 2007/04/04
+ * @brief Implementation of odemx::base::Sched
+ * @sa Sched.h
+ * @since 2.0
+ */
+
+#include <odemx/base/Sched.h>
+#include <odemx/base/Simulation.h>
+
+namespace odemx {
+namespace base {
+
+//------------------------------------------------------construction/destruction
+
+Sched::Sched( Simulation& sim, const data::Label& label, SchedType st )
+:	data::Producer( sim, label )
+,	schedType_( st )
+,	scheduled_( false )
+{
+}
+
+Sched::~Sched()
+{
+}
+
+//-------------------------------------------------------------------status info
+
+Sched::SchedType Sched::getSchedType() const
+{
+	return schedType_;
+}
+
+bool Sched::isScheduled() const
+{
+	return scheduled_;
+}
+
+SimTime Sched::getTime() const
+{
+	return getSimulation().getTime();
+}
+
+} // namespace base
+
+//--------------------------------------------------------------global operators
+
+// determine order of processes and events in execution list
+// by checking for the earlier (smaller) execution time and
+// in case of equality comparing which has higher priority
+bool operator<( const base::Sched& first, const base::Sched& second )
+{
+	return ( first.getExecutionTime() < second.getExecutionTime() )  ?  (true) :
+ 			 (( first.getExecutionTime() > second.getExecutionTime() )  ?  (false) :
+ 				(first.getPriority() > second.getPriority()));
+}
+
+} // namespace odemx
diff --git a/odemx-lite/src/base/Scheduler.cpp b/odemx-lite/src/base/Scheduler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5cb9cd754df57e0ed07087bb14b18d36f01366b3
--- /dev/null
+++ b/odemx-lite/src/base/Scheduler.cpp
@@ -0,0 +1,175 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Scheduler.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/03/12
+ * @brief Implementation of odemx::base::Scheduler
+ * @sa Scheduler.h
+ * @since 3.0
+ */
+
+#include <odemx/base/Scheduler.h>
+#include <odemx/base/Sched.h>
+#include <odemx/base/Simulation.h>
+#include <odemx/base/Process.h>
+#include <odemx/util/Exceptions.h>
+
+#include <cassert>
+
+namespace odemx {
+namespace base {
+
+//------------------------------------------------------construction/destruction
+
+Scheduler::Scheduler( Simulation& sim, const data::Label& label )
+:	data::Producer( sim, label )
+,	sim_( sim )
+,	executionList_( sim, sim.getLabel() + " execution list" )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Scheduler) );
+}
+
+Scheduler::~Scheduler()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Scheduler) );
+}
+
+//---------------------------------------------------------------execution modes
+
+void Scheduler::run()
+{
+	ODEMX_TRACE << log( "run" ).scope( typeid(Scheduler) );
+
+	while( ! executionList_.isEmpty() && ! sim_.isFinished() )
+	{
+		executeNextSched();
+	}
+}
+
+void Scheduler::runUntil( SimTime stopTime )
+{
+	ODEMX_TRACE << log( "run until" ).detail( "time", stopTime )
+					.scope( typeid(Scheduler) );
+
+	while( ! executionList_.isEmpty()
+			&& executionList_.getNextExecutionTime() <= stopTime
+			&& ! sim_.isFinished() )
+	{
+		executeNextSched();
+	}
+	sim_.setCurrentTime( stopTime );
+}
+
+void Scheduler::step()
+{
+	ODEMX_TRACE << log( "step" ).scope( typeid(Scheduler) );
+
+	if( ! executionList_.isEmpty() && ! sim_.isFinished() )
+	{
+		executeNextSched();
+	}
+}
+
+//---------------------------------------------------------------sched execution
+
+void Scheduler::executeNextSched()
+{
+	// next sched removes itself from list
+	Sched* next = executionList_.getNextSched();
+	assert( next );
+
+	if( next->getExecutionTime() < sim_.getTime() )
+	{
+		fatal << log( "Scheduler::executeNextSched(): "
+				"execution list corrupted; invalid execution time" )
+				.scope( typeid(Scheduler) );
+
+		executionList_.logToChannel( fatal );
+
+		throw SchedulingException( "Execution list corrupted; "
+				"next execution time < current time" );
+	}
+
+	data::StringLiteral recordText;
+	if( next->getSchedType() == Sched::PROCESS )
+	{
+		recordText = "execute process";
+	}
+	else if( next->getSchedType() == Sched::EVENT )
+	{
+		recordText = "execute event";
+	}
+
+	ODEMX_TRACE << log( recordText )
+			.detail( "partner", next->getLabel() )
+			.scope( typeid(Scheduler) );
+
+	sim_.setCurrentTime( next->getExecutionTime() );
+
+	// objects remove themselves from schedule when calling scheduling methods
+	next->execute();
+	sim_.resetCurrentSched();
+	sim_.resetCurrentProcess();
+  if( next->getSchedType() == Sched::PROCESS ) {
+    Process* p = static_cast<Process*>(next);
+    if (p->getProcessState() == Process::TERMINATED)
+      p->freeStack();
+  }
+	sim_.checkAutoDelete();
+}
+
+//------------------------------------------------------execution list interface
+
+void Scheduler::addSched( Sched* s )
+{
+	executionList_.addSched( s );
+}
+
+void Scheduler::insertSched( Sched* s )
+{
+	executionList_.insertSched( s );
+}
+
+void Scheduler::insertSchedBefore( Sched* s, Sched* partner )
+{
+	executionList_.insertSchedBefore( s, partner );
+}
+
+void Scheduler::insertSchedAfter( Sched* s, Sched* partner )
+{
+	executionList_.insertSchedAfter( s, partner );
+}
+
+void Scheduler::removeSched( Sched* s )
+{
+	executionList_.removeSched( s );
+}
+
+void Scheduler::inSort( Sched* s )
+{
+	executionList_.inSort( s );
+}
+
+const ExecutionList& Scheduler::getExecutionList() const
+{
+	return executionList_;
+}
+
+} } // namespace odemx::base
diff --git a/odemx-lite/src/base/Simulation.cpp b/odemx-lite/src/base/Simulation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..03b96f0cacd948a5d0ef69fa2712230d344b5903
--- /dev/null
+++ b/odemx-lite/src/base/Simulation.cpp
@@ -0,0 +1,413 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Simulation.cpp
+ * @author Ralf Gerstenberger
+ * @date created at 2002/02/22
+ * @brief Implementation of class odemx::base::Simulation
+ * @sa Simulation.h
+ * @since 1.0
+ */
+
+#include <odemx/base/Event.h>
+#include <odemx/base/Process.h>
+#include <odemx/base/Simulation.h>
+#include <odemx/util/Exceptions.h>
+
+#include <iostream>
+#include <fstream>
+
+namespace odemx {
+namespace base {
+
+//------------------------------------------------------construction/destruction
+static SimulationId unique_id = 0;
+SimulationId create_unique_id() {
+	return unique_id++;
+}
+
+Simulation::Simulation( const data::Label& label, SimulationObserver* obs )
+:	data::LoggingManager()
+,	data::Producer( *this, label )
+,	coroutine::CoroutineContext( obs )
+,	data::Observable< SimulationObserver >( obs )
+,	description_( "no description" )
+,	isInitialized_( false )
+,	isStopped_( false )
+,	startTime_( 0 )
+,	currentTime_( 0 )
+,	scheduler_( *this, getLabel() + " scheduler" )
+,	currentProcess_( 0 )
+,	currentSched_( 0 )
+,	createdProcesses_()
+,	runnableProcesses_()
+,	idleProcesses_()
+,	terminatedProcesses_()
+,	autoDelete_( false )
+,	uniqueId_( create_unique_id() )
+{
+	// since sim owns the channels, there are no consumers for trace records yet
+	// ODEMX_TRACE << log( "create" ).scope( typeid(Simulation) );
+
+	ODEMX_OBS(SimulationObserver, Create(this));
+}
+
+Simulation::Simulation( const data::Label& label, SimTime startTime, SimulationObserver* obs )
+:	data::LoggingManager()
+,	data::Producer( *this, label )
+,	coroutine::CoroutineContext( obs )
+,	data::Observable< SimulationObserver >( obs )
+,	description_( "no description" )
+,	isInitialized_( false )
+,	isStopped_( false )
+,	startTime_( startTime )
+,	currentTime_( startTime )
+,	scheduler_( *this, getLabel() + " scheduler" )
+,	currentProcess_( 0 )
+,	currentSched_( 0 )
+,	createdProcesses_()
+,	runnableProcesses_()
+,	idleProcesses_()
+,	terminatedProcesses_()
+,	autoDelete_( false )
+,	uniqueId_( create_unique_id() )
+{
+	ODEMX_TRACE << log( "create with start time" ).detail( "time", startTime_ )
+			.scope( typeid(Simulation) );
+
+	ODEMX_OBS(SimulationObserver, Create(this));
+}
+
+Simulation::~Simulation()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Simulation) );
+}
+
+//----------------------------------------------------------------description/ID
+
+SimulationId Simulation::getId() const
+{
+	return uniqueId_;
+}
+
+void Simulation::setDescription( const std::string& description )
+{
+	description_ = description;
+}
+
+const std::string& Simulation::getDescription() const
+{
+	return description_;
+}
+
+//----------------------------------------------------------------initialization
+
+void Simulation::init()
+{
+	if( !isInitialized_ )
+	{
+		ODEMX_TRACE << log( "init" ).scope( typeid(Simulation) );
+
+		// observer
+		ODEMX_OBS(SimulationObserver, Initialization(this));
+
+		initSimulation();
+		isInitialized_ = true;
+	}
+}
+
+//----------------------------------------------------------------simulation run
+
+void Simulation::run()
+{
+	ODEMX_TRACE << log( "run" ).scope( typeid(Simulation) );
+
+	// observer
+	ODEMX_OBS(SimulationObserver, Run(this));
+
+	init();
+	scheduler_.run();
+}
+
+void Simulation::step()
+{
+	ODEMX_TRACE << log( "step" ).scope( typeid(Simulation) );
+
+	// observer
+	ODEMX_OBS(SimulationObserver, Step(this));
+
+	init();
+	scheduler_.step();
+}
+
+void Simulation::runUntil( SimTime stopTime )
+{
+	assert( stopTime >= currentTime_ );
+
+	ODEMX_TRACE << log( "run until" )
+			.detail( "stop time", stopTime )
+			.scope( typeid(Simulation) );
+
+	// observer
+	ODEMX_OBS(SimulationObserver, RunUntil(this, stopTime));
+
+	init();
+	scheduler_.runUntil( stopTime );
+}
+
+//----------------------------------------------------------------simulation end
+
+void Simulation::exitSimulation()
+{
+	ODEMX_TRACE << log( "exit" ).scope( typeid(Simulation) );
+
+	// observer
+	ODEMX_OBS(SimulationObserver, ExitSimulation(this));
+
+	// setting isInitialized may not be formally correct, but it will
+	// effect that isFinished() returns true, which makes sense
+	// after calling exit on a simulation
+	isInitialized_ = true;
+	isStopped_ = true;
+
+	// if this function is called from an active coroutine,
+	// we need to restore the environment
+	switchTo();
+}
+
+bool Simulation::isFinished() const
+{
+	return isInitialized_
+			&& ( isStopped_ || scheduler_.getExecutionList().isEmpty() );
+}
+
+//---------------------------------------------------------------simulation time
+
+SimTime Simulation::getStartTime() const
+{
+	return startTime_;
+}
+
+void Simulation::setCurrentTime( SimTime newTime )
+{
+	ODEMX_TRACE << log( "time" )
+			.valueChange( currentTime_, newTime )
+			.scope( typeid(Simulation) );
+
+	// observer
+	ODEMX_OBS_ATTR( SimulationObserver, Time, currentTime_, newTime );
+
+	currentTime_ = newTime;
+}
+
+SimTime Simulation::getTime() const
+{
+	return currentTime_;
+}
+
+//--------------------------------------------------------------------scheduling
+
+void Simulation::setCurrentSched( Sched* s )
+{
+	assert( s );
+
+	ODEMX_TRACE << log( "set current" )
+			.detail( "partner", s->getLabel() )
+			.scope( typeid(Simulation) );
+
+	// observer
+	ODEMX_OBS_ATTR(SimulationObserver, CurrentSched, currentSched_, s);
+
+	currentSched_ = s;
+}
+
+void Simulation::setCurrentProcess( Process* p )
+{
+	assert( p );
+
+	// erase process from previous state list
+	removeProcessFromList( p );
+
+	currentProcess_ = p;
+	currentSched_ = p;
+}
+
+Scheduler& Simulation::getScheduler()
+{
+	return scheduler_;
+}
+
+Sched* Simulation::getCurrentSched()
+{
+	return currentSched_;
+}
+
+Process* Simulation::getCurrentProcess()
+{
+	return currentProcess_;
+}
+
+void Simulation::resetCurrentSched()
+{
+	currentSched_ = 0;
+}
+
+void Simulation::resetCurrentProcess()
+{
+	currentProcess_ = 0;
+}
+
+//------------------------------------------------------------process management
+
+ProcessList& Simulation::getCreatedProcesses()
+{
+	return createdProcesses_;
+}
+
+const ProcessList& Simulation::getCreatedProcesses() const
+{
+	return createdProcesses_;
+}
+
+ProcessList& Simulation::getRunnableProcesses()
+{
+	return runnableProcesses_;
+}
+
+const ProcessList& Simulation::getRunnableProcesses() const
+{
+	return runnableProcesses_;
+}
+
+ProcessList& Simulation::getIdleProcesses()
+{
+	return idleProcesses_;
+}
+
+const ProcessList& Simulation::getIdleProcesses() const
+{
+	return idleProcesses_;
+}
+
+ProcessList& Simulation::getTerminatedProcesses()
+{
+	return terminatedProcesses_;
+}
+
+const ProcessList& Simulation::getTerminatedProcesses() const
+{
+	return terminatedProcesses_;
+}
+
+void Simulation::setProcessAsCreated( Process* p )
+{
+	assert( p );
+
+	ODEMX_OBS(SimulationObserver, ChangeProcessList(this, p, CREATED));
+
+	// insert p
+	p->simListIter_ = createdProcesses_.insert( createdProcesses_.end(), p );
+}
+
+void Simulation::setProcessAsRunnable( Process* p )
+{
+	assert( p );
+
+	// erase process from previous state list
+	removeProcessFromList( p );
+
+	ODEMX_OBS(SimulationObserver, ChangeProcessList(this, p, RUNNABLE));
+
+	// insert p
+	p->simListIter_ = runnableProcesses_.insert( runnableProcesses_.end(), p );
+}
+
+void Simulation::setProcessAsIdle( Process* p )
+{
+	assert( p );
+
+	// erase process from previous state list
+	removeProcessFromList( p );
+
+	ODEMX_OBS(SimulationObserver, ChangeProcessList(this, p, IDLE));
+
+	// insert p
+	p->simListIter_ = idleProcesses_.insert( idleProcesses_.end(), p );
+}
+
+void Simulation::setProcessAsTerminated( Process* p )
+{
+	assert( p );
+
+	// erase process from previous state list
+	removeProcessFromList( p );
+
+	ODEMX_OBS(SimulationObserver, ChangeProcessList(this, p, TERMINATED));
+
+	// insert p
+	p->simListIter_ = terminatedProcesses_.insert( terminatedProcesses_.end(), p );
+}
+
+void Simulation::removeProcessFromList( Process* p )
+{
+	assert( p );
+
+	switch ( p->getProcessState() )
+	{
+	case Process::CREATED:
+		createdProcesses_.erase( p->simListIter_ );
+		break;
+	case Process::RUNNABLE:
+		runnableProcesses_.erase( p->simListIter_ );
+		break;
+	case Process::IDLE:
+		idleProcesses_.erase( p->simListIter_ );
+		break;
+	case Process::TERMINATED:
+		// usually should not happen, no reactivation after termination
+		// however, this function may be used to remove processes from lists
+		// before their destruction, so no warning or error
+		terminatedProcesses_.erase( p->simListIter_ );
+		break;
+	default: // Process::CURRENT, no list needed
+		break;
+	}
+}
+
+//---------------------------------------------automatic process object deletion
+
+void Simulation::autoDeleteProcesses( bool value )
+{
+	autoDelete_ = value;
+}
+
+void Simulation::checkAutoDelete()
+{
+	if( autoDelete_ )
+	{
+		ProcessList::iterator iter = terminatedProcesses_.begin();
+		while( iter != terminatedProcesses_.end()  )
+		{
+			delete *iter++;
+		}
+		terminatedProcesses_.clear();
+	}
+}
+
+} } // namespace odemx::base
diff --git a/odemx-lite/src/base/cellular_automaton/Cell.cpp b/odemx-lite/src/base/cellular_automaton/Cell.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..554515c09e71fdad133f54bce7801152591dc6f1
--- /dev/null
+++ b/odemx-lite/src/base/cellular_automaton/Cell.cpp
@@ -0,0 +1,515 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Cell.cpp
+
+ \author Sascha Qualitz
+
+ \date created at 2010/01/05
+
+ \brief Implementation of class Cell
+
+ \sa Cell.h
+
+ \since 3.0
+ */
+#include <exception>
+#include <iostream>
+#include <odemx/base/cellular_automaton/Cell.h>
+#include <odemx/base/cellular_automaton/CellMonitor.h>
+#include <odemx/base/cellular_automaton/Transition.h>
+#include <odemx/base/cellular_automaton/CellVariablesContainer.h>
+
+using namespace odemx::base;
+using namespace odemx::base::cellular;
+using namespace std;
+
+//------------------------------------------------------------------------------construction/destruction
+Cell::Cell(unsigned row, unsigned column, unsigned level, unsigned dimension, unsigned inputDimension, unsigned outputDimension, CellMonitor* monitor)
+:	monitor(monitor)
+,	stateDimension(dimension)
+,	inputDimension(inputDimension)
+,	outputDimension(outputDimension)
+,	isBoundary(false)
+,	pushed(false)
+{
+	cellPosition = new CellPosition(row, column, level, monitor->getRowCount(), monitor->getColumnCount(), monitor->getLevelCount());
+
+	typeOfNeighborhood.neighborhoodType = MOORE;
+	typeOfNeighborhood.radius = 1;
+}
+
+Cell::~Cell() {
+
+}
+
+void Cell::calculateNeighborhood() {
+
+	switch (typeOfNeighborhood.neighborhoodType) {
+		case MOORE:
+			calculateMooreNeighborhood(typeOfNeighborhood.radius);
+			break;
+		case NEUMANN:
+			calculateVonNeumannNeighborhood(typeOfNeighborhood.radius);
+			break;
+		case MOORETORUS:
+			calculateMoore2DTorusNeighborhood(typeOfNeighborhood.radius);
+			break;
+		case NEUMANNTORUS:
+			calculateNeumann2DTorusNeighborhood(typeOfNeighborhood.radius);
+			break;
+		case MOOREXTUBE:
+			calculateMoore2DXAxisTubeNeighborhood(typeOfNeighborhood.radius);
+			break;
+		case NEUMANNXTUBE:
+			calculateNeumann2DXAxisTubeNeighborhood(typeOfNeighborhood.radius);
+			break;
+		case MOOREYTUBE:
+			calculateMoore2DYAxisTubeNeighborhood(typeOfNeighborhood.radius);
+			break;
+		case NEUMANNYTUBE:
+			calculateNeumann2DYAxisTubeNeighborhood(typeOfNeighborhood.radius);
+			break;
+		default:
+			calculateMooreNeighborhood(typeOfNeighborhood.radius);
+			break;
+	}
+}
+
+void Cell::pushValue() {
+	this->pushed = true;
+}
+
+std::vector<double> Cell::pullValue(unsigned variableIndex) {
+
+	std::vector<double> neigborhoodCellsValuesVector;
+	try{
+		for (std::map<CellPosition, Cell*, ComparePositions>::iterator iter = neighborhoodCellsMap.begin(); iter != neighborhoodCellsMap.end(); ++iter) {
+			checkIndexBoundary(variableIndex, (iter->second->getDimension() - 1), "Cell::pullValue(unsigned variableIndex)");
+			neigborhoodCellsValuesVector.push_back(monitor->cellVariablesContainer->getOutputValue(iter->second->getOutputBaseIndex(), variableIndex));
+		}
+	} catch(out_of_range e) {
+		std::cerr << e.what() << std::endl;
+	}
+
+	return neigborhoodCellsValuesVector;
+
+}
+
+void Cell::setValue(unsigned variableIndex, double value) {
+	try {
+		checkIndexBoundary(variableIndex, (this->stateDimension - 1), "Cell::setValue(unsigned variableIndex, double value)");
+		this->monitor->cellVariablesContainer->setStateValue(this->stateBaseIndex, variableIndex, value);
+	} catch(out_of_range e) {
+		std::cerr << e.what() << std::endl;
+	}
+}
+
+double Cell::getValue(unsigned variableIndex) {
+	try {
+		checkIndexBoundary(variableIndex, (this->stateDimension - 1), "Cell::getValue(unsigned variableIndex)");
+		return this->monitor->cellVariablesContainer->getStateValue(this->stateBaseIndex, variableIndex);
+	} catch(out_of_range e) {
+			std::cerr << e.what() << std::endl;
+	}
+}
+
+void Cell::setOutputValue(unsigned variableIndex, double value) {
+	try {
+		checkIndexBoundary(variableIndex, (this->outputDimension -1), "Cell::setOutputValue(unsigned variableIndex, double value)");
+		this->monitor->cellVariablesContainer->setOutputValue(this->outputBaseIndex, variableIndex, value);
+	} catch(out_of_range e) {
+			std::cerr << e.what() << std::endl;
+	}
+}
+
+double Cell::getOutputValue(unsigned variableIndex) {
+	try {
+		checkIndexBoundary(variableIndex, (this->outputDimension - 1), "Cell::getOutputValue(unsigned variableIndex)");
+		return this->monitor->cellVariablesContainer->getOutputValue(this->outputBaseIndex, variableIndex);
+	} catch(out_of_range e) {
+			std::cerr << e.what() << std::endl;
+	}
+}
+
+void Cell::setInputValue(unsigned variableIndex, double value) {
+	try {
+		checkIndexBoundary(variableIndex, (this->inputDimension - 1), "Cell::setInputValue(unsigned variableIndex, double value)");
+		this->monitor->cellVariablesContainer->setInputValue(this->inputBaseIndex, variableIndex, value);
+	} catch(out_of_range e) {
+			std::cerr << e.what() << std::endl;
+	}
+}
+
+double Cell::getInputValue(unsigned variableIndex) {
+	try {
+		checkIndexBoundary(variableIndex, (this->inputDimension - 1), "Cell::getInputValue(unsigned variableIndex)");
+		return this->monitor->cellVariablesContainer->getInputValue(this->inputBaseIndex, variableIndex);
+	} catch(out_of_range e) {
+			std::cerr << e.what() << std::endl;
+	}
+}
+
+void Cell::setTransition(Transition* transition) {
+	if(transition) {
+		transition->setCell(this);
+		this->transitions.push_back(transition);
+	}
+	else {
+		throw new NotAssignedException("Transition", "Cell");
+	}
+}
+
+void Cell::deleteTransition(Transition* transition) {
+
+	if(transition) {
+		list<Transition*>::iterator iter = find(this->transitions.begin(),
+														this->transitions.end(), transition);
+		//..and delete
+		if (*iter == transition) {
+			this->transitions.erase(iter);
+		}
+		transition->cell = 0;
+	}
+	else {
+		throw new NotAssignedException("Transition", "Cell");
+	}
+}
+
+unsigned Cell::getDimension() {
+	return this->stateDimension;
+}
+
+unsigned Cell::getInputDimension() {
+	return this->inputDimension;
+}
+
+unsigned Cell::getOutputDimension() {
+	return this->outputDimension;
+}
+
+void Cell::setIsBoundary() {
+	this->isBoundary = true;
+	this->monitor->calculateNeighboorhood();
+}
+
+bool Cell::isPartOfBoundary() {
+	return this->isBoundary;
+}
+
+void Cell::setPosition(unsigned row, unsigned column, unsigned level) {
+	cellPosition->setPosition(row, column, level);
+}
+
+CellPosition* Cell::getPosition() {
+	return this->cellPosition;
+}
+
+void Cell::setNeighborhoodSettings(unsigned neighborhoodType, unsigned radius, bool calcNeighborhood) {
+	this->typeOfNeighborhood.neighborhoodType = neighborhoodType;
+	this->typeOfNeighborhood.radius = radius;
+	if(calcNeighborhood) calculateNeighborhood();
+}
+
+std::map<CellPosition, Cell*, ComparePositions> Cell::getNeighbors() {
+	return neighborhoodCellsMap;
+}
+
+Cell* Cell::searchNeighbor(unsigned row, unsigned column, unsigned level) {
+	CellPosition tempPosition(row, column, level, cellPosition->cellRows, cellPosition->cellColumns, cellPosition->cellLevel);
+	map<CellPosition, Cell*, ComparePositions>::iterator iter = neighborhoodCellsMap.find(tempPosition);
+
+	if(iter != neighborhoodCellsMap.end()) {
+		return iter->second;
+	}
+	else {
+		return 0;
+	}
+}
+
+void Cell::calculateMooreNeighborhood(unsigned radius) {
+
+	unsigned rowCount = monitor->getRowCount();
+	unsigned columnCount = monitor->getColumnCount();
+	unsigned levelCount = monitor->getLevelCount();
+
+	unsigned rowNumberIndex = cellPosition->row;
+	unsigned columnNumberIndex = cellPosition->column;
+	unsigned levelNumberIndex = cellPosition->level;
+
+	CellPosition neighborCellPosition(0, 0, 0, rowCount, columnCount, levelCount);
+
+	for (int i = 0; i < rowCount; ++i) {
+		for (int j = 0; j < columnCount; ++j) {
+			for (int k = 0; k < levelCount; ++k) {
+				if((std::abs(i-(int)rowNumberIndex) <= radius && std::abs(j-(int)columnNumberIndex) <= radius && (std::abs(k-(int)levelNumberIndex) <= radius)) && !monitor->getCell(i,j,k)->isPartOfBoundary()) {
+					if(!(i == rowNumberIndex && j == columnNumberIndex && k == levelNumberIndex)) {
+						neighborCellPosition.setPosition(i,j,k);
+						neighborhoodCellsMap[neighborCellPosition] = monitor->getCell_(rowCount*(k*columnCount + j) + i);
+					}
+				}
+			}
+		}
+	}
+}
+
+void Cell::calculateVonNeumannNeighborhood(unsigned radius) {
+
+	unsigned rowCount = monitor->getRowCount();
+	unsigned columnCount = monitor->getColumnCount();
+	unsigned levelCount = monitor->getLevelCount();
+
+	unsigned rowNumberIndex = cellPosition->row;
+	unsigned columnNumberIndex = cellPosition->column;
+	unsigned levelNumberIndex = cellPosition->level;
+
+	CellPosition neighborCellPosition(0, 0, 0, rowCount, columnCount, levelCount);
+
+	for (int i = 0; i < rowCount; ++i) {
+		for (int j = 0; j < columnCount; ++j) {
+			for (int k = 0; k < levelCount; ++k) {
+				if((std::abs(i-(int)rowNumberIndex) + std::abs(j-(int)columnNumberIndex) + std::abs(k-(int)levelNumberIndex) <= radius) && !monitor->getCell(i,j,k)->isPartOfBoundary()) {
+					if(!(i == rowNumberIndex && j == columnNumberIndex && k == levelNumberIndex))
+						neighborCellPosition.setPosition(i,j,k);
+						neighborhoodCellsMap[neighborCellPosition] = monitor->getCell_(rowCount*(k*columnCount + j) + i);
+				}
+			}
+		}
+	}
+}
+
+void Cell::calculateMoore2DTorusNeighborhood(unsigned radius) {
+
+	unsigned rowCount = monitor->getRowCount();
+	unsigned columnCount = monitor->getColumnCount();
+
+	unsigned actualI = 0, actualJ = 0;
+
+	unsigned rowNumberIndex = cellPosition->row;
+	unsigned columnNumberIndex = cellPosition->column;
+
+	CellPosition neighborCellPosition(0, 0, 0, rowCount, columnCount, 0);
+
+	for (int i = -1*(int)radius; i < rowCount + radius; ++i) {
+		for (int j = -1*(int)radius; j < columnCount + radius; ++j) {
+			if((std::abs(i-(int)rowNumberIndex) <= radius) && (std::abs(j-(int)columnNumberIndex) <= radius) ) {//&& !monitor->getCell(i,j,0)->isPartOfBoundary()) {
+				if(!(rowNumberIndex == i % rowCount && columnNumberIndex == j  % columnCount)) {
+					if(i < 0) actualI = (i + rowCount);
+					else if(i > rowCount) actualI = i % rowCount;
+					else actualI= i;
+					if(j < 0) actualJ = (j + rowCount);
+					else if(j > columnCount) actualJ = j % columnCount;
+					else actualJ = j;
+					neighborCellPosition.setPosition(actualI,actualJ,0);
+					neighborhoodCellsMap[neighborCellPosition] = monitor->getCell_(actualI*columnCount + actualJ);
+				}
+			}
+		}
+	}
+}
+
+void Cell::calculateMoore2DXAxisTubeNeighborhood(unsigned radius) {
+
+	unsigned rowCount = monitor->getRowCount();
+	unsigned columnCount = monitor->getColumnCount();
+
+	unsigned actualJ = 0;
+
+	unsigned rowNumberIndex = cellPosition->row;
+	unsigned columnNumberIndex = cellPosition->column;
+
+	CellPosition neighborCellPosition(0, 0, 0, rowCount, columnCount, 0);
+	for (int i = 0; i < rowCount; ++i) {
+		for (int j = -1*(int)radius; j < (int)columnCount + (int)radius; ++j) {
+			if((std::abs(i-(int)rowNumberIndex) <= radius) && (std::abs(j-(int)columnNumberIndex) <= radius) ) {//&& !monitor->getCell(i,j,0)->isPartOfBoundary()) {
+				if(!(rowNumberIndex == i && columnNumberIndex == j  % (int)columnCount)) {
+					if(j < 0) actualJ = (j + columnCount);
+					else if(j >= columnCount) actualJ = j % columnCount;
+					else actualJ = j;
+					neighborCellPosition.setPosition(i,actualJ,0);
+					neighborhoodCellsMap[neighborCellPosition] = monitor->getCell_(i*columnCount + actualJ);
+				}
+			}
+		}
+	}
+}
+
+void Cell::calculateMoore2DYAxisTubeNeighborhood(unsigned radius) {
+
+	unsigned rowCount = monitor->getRowCount();
+	unsigned columnCount = monitor->getColumnCount();
+
+	unsigned actualI = 0;
+
+	unsigned rowNumberIndex = cellPosition->row;
+	unsigned columnNumberIndex = cellPosition->column;
+
+	CellPosition neighborCellPosition(0, 0, 0, rowCount, columnCount, 0);
+
+	for (int i = -1*(int)radius; i < (int)rowCount + (int)radius; ++i) {
+		for (int j = 0; j < columnCount; ++j) {
+			if((std::abs(i-(int)rowNumberIndex) <= radius) && (std::abs(j-(int)columnNumberIndex) <= radius) ) {//&& !monitor->getCell(i,j,0)->isPartOfBoundary()) {
+				if(!(rowNumberIndex == i % (int)rowCount && columnNumberIndex == j)) {
+					if(i < 0) actualI = (i + rowCount);
+					else if(i >= rowCount) actualI = i % rowCount;
+					else actualI= i;
+					neighborCellPosition.setPosition(actualI,j,0);
+					neighborhoodCellsMap[neighborCellPosition] = monitor->getCell_(actualI*columnCount + j);
+				}
+			}
+		}
+	}
+}
+
+
+void Cell::calculateNeumann2DTorusNeighborhood(unsigned radius) {
+
+	unsigned rowCount = monitor->getRowCount();
+	unsigned columnCount = monitor->getColumnCount();
+
+	unsigned actualI = 0, actualJ = 0;
+
+	unsigned rowNumberIndex = cellPosition->row;
+	unsigned columnNumberIndex = cellPosition->column;
+
+	CellPosition neighborCellPosition(0, 0, 0, rowCount, columnCount, 0);
+
+	for (int i = -1*(int)radius; i < rowCount + radius; ++i) {
+		for (int j = -1*(int)radius; j < columnCount + radius; ++j) {
+			if((std::abs(i-(int)rowNumberIndex) + std::abs(j-(int)columnNumberIndex) <= radius) ) {//&& !monitor->getCell(i,j,0)->isPartOfBoundary()) {
+				if(!(rowNumberIndex == i % rowCount && columnNumberIndex == j  % columnCount)) {
+					if(i < 0) actualI = (i + rowCount);
+					else if(i > rowCount) actualI = i % rowCount;
+					else actualI= i;
+					if(j < 0) actualJ = (j + rowCount);
+					else if(j > columnCount) actualJ = j % columnCount;
+					else actualJ = j;
+					neighborCellPosition.setPosition(actualI,actualJ,0);
+					neighborhoodCellsMap[neighborCellPosition] = monitor->getCell_(actualI*columnCount + actualJ);
+				}
+			}
+		}
+	}
+}
+
+void Cell::calculateNeumann2DXAxisTubeNeighborhood(unsigned radius) {
+
+	unsigned rowCount = monitor->getRowCount();
+	unsigned columnCount = monitor->getColumnCount();
+
+	unsigned actualJ = 0;
+
+	unsigned rowNumberIndex = cellPosition->row;
+	unsigned columnNumberIndex = cellPosition->column;
+
+	CellPosition neighborCellPosition(0, 0, 0, rowCount, columnCount, 0);
+
+	for (int i = 0; i < rowCount; ++i) {
+		for (int j = -1*(int)radius; j < (int)columnCount + (int)radius; ++j) {
+			if((std::abs(i-(int)rowNumberIndex) + std::abs(j-(int)columnNumberIndex) <= radius) ) {//&& !monitor->getCell(i,j,0)->isPartOfBoundary()) {
+				if(!(rowNumberIndex == i && columnNumberIndex == j  % (int)columnCount)) {
+					if(j < 0) actualJ = (j + columnCount);
+					else if(j >= columnCount) actualJ = j % columnCount;
+					else actualJ = j;
+					neighborCellPosition.setPosition(i,actualJ,0);
+					neighborhoodCellsMap[neighborCellPosition] = monitor->getCell_(i*columnCount + actualJ);
+				}
+			}
+		}
+	}
+}
+
+void Cell::calculateNeumann2DYAxisTubeNeighborhood(unsigned radius) {
+
+	unsigned rowCount = monitor->getRowCount();
+	unsigned columnCount = monitor->getColumnCount();
+
+	unsigned actualI = 0;
+
+	unsigned rowNumberIndex = cellPosition->row;
+	unsigned columnNumberIndex = cellPosition->column;
+
+	CellPosition neighborCellPosition(0, 0, 0, rowCount, columnCount, 0);
+
+	for (int i = -1*(int)radius; i < (int)rowCount + (int)radius; ++i) {
+		for (int j = 0; j < columnCount; ++j) {
+			if((std::abs(i-(int)rowNumberIndex) + std::abs(j-(int)columnNumberIndex) <= radius) ) {//&& !monitor->getCell(i,j,0)->isPartOfBoundary()) {
+				if(!(rowNumberIndex == i % (int)rowCount && columnNumberIndex == j)) {
+					if(i < 0) actualI = (i + columnCount);
+					else if(i >= rowCount) actualI = i % rowCount;
+					else actualI= i;
+					neighborCellPosition.setPosition(actualI,j,0);
+					neighborhoodCellsMap[neighborCellPosition] = monitor->getCell_(actualI*columnCount + j);
+				}
+			}
+		}
+	}
+}
+
+void Cell::calculateAlternativeNeighborhood(unsigned radius) {
+	int i = 0;
+	for(list<Transition*>::iterator iter = this->transitions.begin(); iter != this->transitions.end(); ++iter) {
+		neighborhoodCellsMap = (*iter)->calculateAlternativeNeighborhood(radius);
+		i++;
+	}
+	if(i == 0)
+		throw new NotAssignedException("Cell", "Transition");
+}
+
+void Cell::checkIndexBoundary(unsigned index, unsigned indexBoundary, std::string what) {
+	if(index > indexBoundary) {
+		throw std::out_of_range("The index in " + what + " is out of bounds.");
+	}
+}
+
+void Cell::setBaseIndex(unsigned baseIndex) {
+	this->stateBaseIndex = baseIndex;
+}
+
+void Cell::setInputBaseIndex(unsigned baseIndex) {
+	this->inputBaseIndex = baseIndex;
+}
+
+void Cell::setOutputBaseIndex(unsigned baseIndex) {
+	this->outputBaseIndex = baseIndex;
+}
+
+unsigned Cell::getBaseIndex() {
+	return this->stateBaseIndex;
+}
+
+unsigned Cell::getInputBaseIndex() {
+	return this->inputBaseIndex;
+}
+
+unsigned Cell::getOutputBaseIndex() {
+	return this->outputBaseIndex;
+}
+
+void Cell::setMonitor(CellMonitor* monitor) {
+	if(monitor) {
+		this->monitor = monitor;
+	}
+	else {
+		throw new NotAssignedException("Monitor", "Cell");
+	}
+}
+
+CellMonitor* Cell::getMonitor() {
+	return this->monitor;
+}
diff --git a/odemx-lite/src/base/cellular_automaton/CellMonitor.cpp b/odemx-lite/src/base/cellular_automaton/CellMonitor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3c540c6c21ea42c2ae924fe83568c01f7604ffe3
--- /dev/null
+++ b/odemx-lite/src/base/cellular_automaton/CellMonitor.cpp
@@ -0,0 +1,647 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file CellMonitor.cpp
+
+	\author Sascha Qualitz
+
+	\date created at 2010/01/05
+
+	\brief Implementation of class CellMonitor
+
+	\sa CellMonitor.h
+
+	\since 3.0
+*/
+#include <iomanip>
+#include <iostream>
+#include <fstream>
+#include <odemx/base/cellular_automaton/CellMonitor.h>
+#include <odemx/base/cellular_automaton/CellVariablesContainer.h>
+#include <odemx/base/cellular_automaton/Cell.h>
+#include <odemx/base/Scheduler.h>
+#include <odemx/base/Simulation.h>
+
+using namespace odemx::base;
+using namespace odemx::base::cellular;
+using namespace std;
+
+//----------------------------------------------------------------------------------construction/destruction
+CellMonitor::CellMonitor(Simulation& sim, const data::Label& l, unsigned variablesInCount, unsigned variablesOutCount, unsigned cellRows, unsigned cellColumns, unsigned cellLevel, double timestep, unsigned cellDimension, ProcessObserver* o)
+:	Process(sim, l, o)
+, 	cellDimension(cellDimension)
+,	variablesInCount(variablesInCount)
+,	variablesOutCount(variablesOutCount)
+,	cellRows(cellRows)
+,	cellColumns(cellColumns)
+,	cellLevel(cellLevel)
+,	timestep(timestep)
+,	timeLimit(0)
+{
+	typeOfNeighborhood.neighborhoodType = MOORE;
+	typeOfNeighborhood.radius = 1;
+	cellVariablesContainer = new CellVariablesContainer(cellRows, cellColumns, cellLevel, variablesInCount, variablesOutCount, cellDimension);
+	generateCellularAutomaton(cellRows, cellColumns, cellLevel, cellDimension);
+	calculateNeighboorhood();
+
+	ODEMX_TRACE << log( "create" ).scope( typeid(CellMonitor) );
+
+	// observer
+	ODEMX_OBS(CellMonitorObserver, Create(this));
+}
+
+CellMonitor::CellMonitor(Simulation& sim, const data::Label& l, const char*const configFileName, ProcessObserver* o)
+:	Process(sim, l, o)
+,	timeLimit(0)
+{
+	setParameterFromConfigFile(configFileName);
+	cellVariablesContainer = new CellVariablesContainer(cellRows, cellColumns, cellLevel, variablesInCount, variablesOutCount, cellDimension);
+	generateCellularAutomaton(cellRows, cellColumns, cellLevel, cellDimension);
+	calculateNeighboorhood();
+
+	ODEMX_TRACE << log( "create with configuration file" ).scope( typeid(CellMonitor) );
+
+	// observer
+	ODEMX_OBS(CellMonitorObserver, Create(this));
+}
+
+CellMonitor::CellMonitor(Simulation& sim, const data::Label& l, const char*const configFileName, const char*const startDataFileName, ProcessObserver* o)
+:	Process(sim, l, o)
+,	timeLimit(0)
+{
+	setParameterFromConfigFile(configFileName);
+	cellVariablesContainer = new CellVariablesContainer(cellRows, cellColumns, cellLevel, variablesInCount, variablesOutCount, cellDimension);
+	generateCellularAutomaton(cellRows, cellColumns, cellLevel, cellDimension);
+	setStartDataFromConfigFile(startDataFileName);
+	calculateNeighboorhood();
+
+	ODEMX_TRACE << log( "create with configuration file and start data file" ).scope( typeid(CellMonitor) );
+
+	// observer
+	ODEMX_OBS(CellMonitorObserver, Create(this));
+}
+
+CellMonitor::~CellMonitor(){
+	if (cellVariablesContainer) {
+		delete cellVariablesContainer;
+	}
+}
+
+int CellMonitor::main() {
+
+	//initialize arrays
+	for(int i = 0; i < cellVector.size(); ++i){
+		if(cellVector[i]->isPartOfBoundary()) continue;
+		for(std::list<Transition*>::iterator iter = cellVector[i]->transitions.begin(); iter != cellVector[i]->transitions.end(); ++iter) {
+			(*iter)->outputFunction();
+		}
+	}
+
+	while (getTime() < timeLimit) {
+		//notifyValidState();
+
+		ODEMX_TRACE << log( "new valid state" ).scope( typeid(CellMonitor) );
+
+		// observer
+		ODEMX_OBS(CellMonitorObserver, NewValidState(this));
+
+		ODEMX_TRACE << log( "begin calculation of state changes" ).scope( typeid(CellMonitor) );
+
+		// observer
+		ODEMX_OBS(CellMonitorObserver, BeginCalcStateChanges(this));
+
+		for(int i = 0; i < cellVector.size(); ++i) {
+			if(cellVector[i]->isPartOfBoundary()) continue;
+			for(std::list<Transition*>::iterator iter = cellVector[i]->transitions.begin(); iter != cellVector[i]->transitions.end(); ++iter) {
+					(*iter)->transitionFunction(getTime());
+			}
+		}
+
+		for(int i = 0; i < cellVector.size(); ++i){
+			if(cellVector[i]->isPartOfBoundary()) continue;
+			for(std::list<Transition*>::iterator iter = cellVector[i]->transitions.begin(); iter != cellVector[i]->transitions.end(); ++iter) {
+				(*iter)->outputFunction();
+			}
+		}
+
+		ODEMX_TRACE << log( "end calculation of state changes" ).scope( typeid(CellMonitor) );
+
+		// observer
+		ODEMX_OBS(CellMonitorObserver, EndCalcStateChanges(this));
+
+		holdFor(timestep);
+	}
+	return 0;
+}
+
+void CellMonitor::setTimeLimit(SimTime time) {
+	timeLimit = time;
+
+	ODEMX_TRACE << log( "set time limit" ).scope( typeid(CellMonitor) );
+
+	// observer
+	ODEMX_OBS(CellMonitorObserver, SetTimeLimit(this, timeLimit));
+
+}
+
+SimTime CellMonitor::getTimeLimit() {
+	return timeLimit;
+}
+
+void CellMonitor::setTransitionToCells(Transition* transition) {
+
+	for (int i = 0; i < this->cellVector.size(); ++i) {
+		cellVector[i]->setTransition(transition);
+	}
+
+	ODEMX_TRACE << log( "sets transition to all cells" ).scope( typeid(CellMonitor) );
+
+	// observer
+	ODEMX_OBS(CellMonitorObserver, SetTransitionToCells(this));
+}
+
+//----------------------------------------------------------- temp function for printing values
+double* CellMonitor::getValues() {
+	return this->cellVariablesContainer->getOutputValues();
+}
+
+unsigned CellMonitor::getRowCount() {
+	return cellRows;
+}
+
+unsigned CellMonitor::getColumnCount() {
+	return cellColumns;
+}
+
+unsigned CellMonitor::getLevelCount() {
+	return cellLevel;
+}
+
+void CellMonitor::setIsBoundaryCell(unsigned row, unsigned column, unsigned level) {
+	this->cellVector[cellRows * (cellColumns * level + column) + row]->isPartOfBoundary();
+}
+
+void CellMonitor::setCellValue(unsigned row, unsigned column, unsigned level, unsigned variableIndex, double value) {
+	this->cellVector[cellRows * (cellColumns * level + column) + row]->setValue(variableIndex, value);
+}
+
+double CellMonitor::getCellValue(unsigned row, unsigned column, unsigned level, unsigned variableIndex) {
+	this->cellVector[cellRows * (cellColumns * level + column) + row]->getValue(variableIndex);
+}
+
+unsigned CellMonitor::getNeighborhoodType() {
+	return this->typeOfNeighborhood.neighborhoodType;
+}
+
+unsigned CellMonitor::getNeighborhoodRadius() {
+	return this->typeOfNeighborhood.radius;
+}
+
+Cell* CellMonitor::getCell(unsigned row, unsigned column, unsigned level) {
+	return this->cellVector[cellRows * (cellColumns * level + column) + row];
+}
+
+Cell* CellMonitor::getCell_(unsigned cellIndex) {
+	return this->cellVector[cellIndex];
+}
+
+void CellMonitor::setNeighborhoodSettings(unsigned neighborhoodType, unsigned radius) {
+	for (int i = 0; i < this->cellVector.size(); ++i) {
+		getCell_(i)->setNeighborhoodSettings(neighborhoodType, radius);
+	}
+	this->typeOfNeighborhood.neighborhoodType = neighborhoodType;
+	this->typeOfNeighborhood.radius = radius;
+
+	ODEMX_TRACE << log( "sets neighborhood" ).scope( typeid(CellMonitor) );
+
+	// observer
+	ODEMX_OBS(CellMonitorObserver, SetNeighborhoodSettings(this, neighborhoodType, radius));
+}
+
+void CellMonitor::setStartDataFromConfigFile(std::string fileName) {
+
+	string line;
+	ifstream is(fileName.c_str());
+
+	if(!is) {
+		cout << "Could not open file!" << endl;
+		exit(1);
+	}
+
+	unsigned row = 0, column = 0, level = 0, statevariable_index = 0, outputvariable_index = 0, inputvariable_index = 0, radius = 0;
+
+	double statevariable = 0, outputvariable = 0, inputvariable = 0;
+
+	string tempstring = "";
+
+	Cell* cell;
+
+	string::size_type i;
+
+	while(getline(is, line)) {
+
+		while(line.find_first_not_of ( " \t\n\v" ) == string::npos) {
+			getline(is, line);
+		}
+
+		statevariable = -1, outputvariable = -1, inputvariable = -1;
+
+		if(line.find("<cell row-index=\"") != string::npos) {
+			statevariable_index = 0, outputvariable_index = 0, inputvariable_index = 0;
+
+			line.erase(0, line.find('\"')+1);
+			tempstring = line.substr(0, line.find("\" column-index=\"")+1);
+			istringstream row_tmp(tempstring);
+			row_tmp >> row;
+
+			line.erase(0, line.find('\"')+1);
+			line.erase(0, line.find('\"')+1);
+			tempstring = line.substr(0, line.find("\" level-index=\"")+1);
+			istringstream column_tmp(tempstring);
+			column_tmp >> column;
+
+			line.erase(0, line.find('\"')+1);
+			line.erase(0, line.find('\"')+1);
+			tempstring = line.substr(0, line.find("\">")+1);
+			istringstream level_tmp(tempstring);
+			level_tmp >> level;
+			cell = getCell(row, column, level);
+		}
+
+		while(line.find("<statevariable>") != string::npos || line.find("</statevariable>") != string::npos) {
+			if(line.find("</statevariable>") != string::npos) {
+				statevariable_index++;
+				do {
+					getline(is, line);
+				} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+				continue;
+			}
+			do {
+				getline(is, line);
+			} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+			istringstream statevariable_tmp(line);
+			statevariable_tmp >> statevariable;
+			cell->setValue(statevariable_index, statevariable);
+		}
+
+		while(line.find("<outputvariable>") != string::npos || line.find("</outputvariable>") != string::npos) {
+			if(line.find("</outputvariable>") != string::npos) {
+				outputvariable_index++;
+				do {
+					getline(is, line);
+				} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+				continue;
+			}
+			do {
+				getline(is, line);
+			} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+			istringstream outputvariable_tmp(line);
+			outputvariable_tmp >> outputvariable;
+			cell->setOutputValue(outputvariable_index, outputvariable);
+		}
+
+		while(line.find("<inputvariable>") != string::npos || line.find("</inputvariable>") != string::npos) {
+			if(line.find("</inputvariable>") != string::npos) {
+				inputvariable_index++;
+				do {
+					getline(is, line);
+				} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+				continue;
+			}
+			do {
+				getline(is, line);
+			} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+			istringstream inputvariable_tmp(line);
+			inputvariable_tmp >> inputvariable;
+			cell->setInputValue(inputvariable_index, inputvariable);
+		}
+
+		if(line.find("<neighborhoodtype>") != string::npos || line.find("</inputvariable>") != string::npos) {
+			do {
+				getline(is, line);
+			} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+			transform(line.begin(), line.end(), line.begin(), (int(*)(int))toupper);
+			if(line.find("MOORE") != string::npos) cell->typeOfNeighborhood.neighborhoodType = 0;
+			if(line.find("NEUMANN") != string::npos) cell->typeOfNeighborhood.neighborhoodType = 1;
+			if(line.find("MOORETORUS") != string::npos) cell->typeOfNeighborhood.neighborhoodType = 2;
+			if(line.find("NEUMANNTORUS") != string::npos) cell->typeOfNeighborhood.neighborhoodType = 3;
+			if(line.find("MOOREXTUBE") != string::npos) cell->typeOfNeighborhood.neighborhoodType = 4;
+			if(line.find("NEUMANNXTUBE") != string::npos) cell->typeOfNeighborhood.neighborhoodType = 5;
+			if(line.find("MOOREYTUBE") != string::npos) cell->typeOfNeighborhood.neighborhoodType = 6;
+			if(line.find("NEUMANNYTUBE") != string::npos) cell->typeOfNeighborhood.neighborhoodType = 7;
+
+			ODEMX_TRACE << log( "sets neighborhood type for one cell" ).scope( typeid(CellMonitor) );
+
+			// observer
+			ODEMX_OBS(CellMonitorObserver, SetNeighborhoodType(this, typeOfNeighborhood.neighborhoodType, cell->getPosition()));
+		}
+
+		if(line.find("<radius>") != string::npos) {
+			do {
+				getline(is, line);
+			} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+			istringstream tmp(line);
+			tmp >> radius;
+			cell->typeOfNeighborhood.radius = radius;
+
+			ODEMX_TRACE << log( "sets neighborhood radius for one cell" ).scope( typeid(CellMonitor) );
+
+			// observer
+			ODEMX_OBS(CellMonitorObserver, SetNeighborhoodRadius(this, typeOfNeighborhood.radius, cell->getPosition()));
+		}
+
+		if(line.find("<boundary>") != string::npos) {
+			do {
+				getline(is, line);
+			} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+			transform(line.begin(), line.end(), line.begin(), (int(*)(int))toupper);
+			if(line.find("TRUE") != string::npos) cell->setIsBoundary();
+		}
+	}
+}
+
+void CellMonitor::setParameterFromConfigFile(std::string fileName) {
+
+	string line;
+	ifstream is(fileName.c_str());
+	int k = -1;
+
+	bool settedNeighborhoodType = false, settedRadius = false;
+
+	if(!is) {
+		cout << "Could not open file!" << endl;
+		exit(1);
+	}
+
+	while(getline(is, line)) {
+		if(line.find("<rowcount>") != string::npos) {
+			do {
+				getline(is, line);
+			} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+			istringstream tmp(line);
+			tmp >> k;
+			cellRows = k;
+		}
+		if(line.find("<columncount>") != string::npos) {
+			do {
+				getline(is, line);
+			} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+			istringstream tmp(line);
+			tmp >> k;
+			cellColumns = k;
+		}
+		if(line.find("<levelcount>") != string::npos) {
+			do {
+				getline(is, line);
+			} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+			istringstream tmp(line);
+			tmp >> k;
+			cellLevel = k;
+		}
+		if(line.find("<outputvariablesize>") != string::npos) {
+			do {
+				getline(is, line);
+			} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+			istringstream tmp(line);
+			tmp >> k;
+			variablesOutCount = k;
+		}
+		if(line.find("<inputvariablesize>") != string::npos) {
+			do {
+				getline(is, line);
+			} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+			istringstream tmp(line);
+			tmp >> k;
+			variablesInCount = k;
+		}
+		if(line.find("<celldimension>") != string::npos) {
+			do {
+				getline(is, line);
+			} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+			istringstream tmp(line);
+			tmp >> k;
+			cellDimension = k;
+		}
+		if(line.find("<timestep>") != string::npos) {
+			do {
+				getline(is, line);
+			} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+			istringstream tmp(line);
+			tmp >> k;
+			timestep = k;
+		}
+		if(line.find("<neighboorhoodtype>") != string::npos) {
+			do {
+				getline(is, line);
+			} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+			transform(line.begin(), line.end(), line.begin(), (int(*)(int))toupper);
+			if(line.find("MOORE") != string::npos) typeOfNeighborhood.neighborhoodType = 0;
+			if(line.find("NEUMANN") != string::npos) typeOfNeighborhood.neighborhoodType = 1;
+			if(line.find("MOORETORUS") != string::npos) typeOfNeighborhood.neighborhoodType = 2;
+			if(line.find("NEUMANNTORUS") != string::npos) typeOfNeighborhood.neighborhoodType = 3;
+			if(line.find("MOOREXTUBE") != string::npos) typeOfNeighborhood.neighborhoodType = 4;
+			if(line.find("NEUMANNXTUBE") != string::npos) typeOfNeighborhood.neighborhoodType = 5;
+			if(line.find("MOOREYTUBE") != string::npos) typeOfNeighborhood.neighborhoodType = 6;
+			if(line.find("NEUMANNYTUBE") != string::npos) typeOfNeighborhood.neighborhoodType = 7;
+
+			settedNeighborhoodType = true;
+		}
+		if(line.find("<radius>") != string::npos) {
+			do {
+				getline(is, line);
+			} while(line.find_first_not_of ( " \t\n\v" ) == string::npos);
+			istringstream tmp(line);
+			tmp >> k;
+			typeOfNeighborhood.radius = k;
+
+			settedRadius = true;
+		}
+
+		if(settedNeighborhoodType && settedRadius) {
+			ODEMX_TRACE << log( "sets neighborhood" ).scope( typeid(CellMonitor) );
+
+			// observer
+			ODEMX_OBS(CellMonitorObserver, SetNeighborhoodSettings(this, typeOfNeighborhood.neighborhoodType, typeOfNeighborhood.radius));
+		}
+	}
+}
+
+//-----------------------------------------------------------generate cellular automaton
+void CellMonitor::generateCellularAutomaton(unsigned rows, unsigned  columns, unsigned level, unsigned cellDimension){
+
+	Cell* cell;
+	unsigned variablesStateCounts = 0, variablesInCounts = 0, variablesOutCounts = 0;
+	//generate cells and set the parameters
+	for(int k = 0; k < level; ++k){
+		for(int j = 0; j < columns; ++j) {
+			for(int i = 0; i < rows; ++i) {
+				cell = new Cell(i, j, k, this->variablesInCount, this->variablesOutCount, this->cellDimension, this);
+				cell->setBaseIndex(variablesStateCounts);
+				cell->setInputBaseIndex(variablesInCounts);
+				cell->setOutputBaseIndex(variablesOutCounts);
+				cell->setNeighborhoodSettings(typeOfNeighborhood.neighborhoodType, typeOfNeighborhood.radius, false);
+				variablesStateCounts += cell->getDimension();
+				variablesInCounts += cell->getInputDimension();
+				variablesOutCounts += cell->getOutputDimension();
+				this->cellVector.push_back(cell);
+			}
+		}
+	}
+
+	ODEMX_TRACE << log( "generate cellular automaton" ).scope( typeid(CellMonitor) );
+
+	// observer
+	ODEMX_OBS(CellMonitorObserver, GenerateCellularAutomaton(this));
+}
+
+void CellMonitor::calculateNeighboorhood() {
+	for(int i = 0; i < cellColumns*cellRows*cellLevel; ++i) {
+		this->cellVector[i]->calculateNeighborhood();
+	}
+
+	ODEMX_TRACE << log( "calculate neighborhood" ).scope( typeid(CellMonitor) );
+
+	// observer
+	ODEMX_OBS(CellMonitorObserver, CalculateNeighboorhood(this));
+}
+
+CellMonitorTrace::CellMonitorTrace(CellMonitor* cellMonitor, const string & fileName)
+: out(0),
+  firstTime(true),
+  fileName(fileName),
+  cellMonitor(cellMonitor)
+{
+#ifdef ODEMX_USE_OBSERVATION
+	if( cellMonitor != 0 )
+	{
+		cellMonitor->data::Observable< CellMonitorObserver >::addObserver( this );
+	}
+#endif
+
+	if( ! fileName.empty() )
+	{
+		openFile( fileName );
+	}
+	else if( cellMonitor != 0 )
+	{
+		std::string fn = cellMonitor->getLabel();
+		fn += "_trace.xml";
+		openFile( fn );
+	}
+}
+
+CellMonitorTrace::~CellMonitorTrace()
+{
+	if( out == 0 || out == &std::cout )
+	{
+		return;
+	}
+	*out << "</tracefile>" << endl;
+
+	static_cast< std::ofstream* >( out )->close();
+	delete out;
+}
+
+void CellMonitorTrace::onNewValidState( CellMonitor* sender )
+{
+	using namespace std;
+
+	assert( sender != 0 );
+
+	if( firstTime )
+	{
+		if( out == 0 )
+		{
+			std::string fn = fileName;
+			fn += "_trace.xml";
+			openFile( fn );
+		}
+
+		*out << "<?xml version=\"1.0\"?>" << endl;
+		*out << "<!DOCTYPE tracefile [" << endl;
+		*out << "	<!ELEMENT tracefile (ca)+>" << endl;
+		*out << "	<!ELEMENT ca (cell)+>" << endl;
+		*out << endl;
+		*out << "	<!ELEMENT cell (statevariable+, outputvariable+, inputvariable+)>" << endl;
+		*out << endl;
+		*out << "	<!ELEMENT statevariable (#PCDATA)>" << endl;
+		*out << "	<!ELEMENT outputvariable (#PCDATA)>" << endl;
+		*out << "	<!ELEMENT inputvariable (#PCDATA)>" << endl;
+		*out << endl;
+		*out << "	<!ATTLIST tracefile name CDATA #REQUIRED>" << endl;
+		*out << "	<!ATTLIST ca time CDATA #REQUIRED>" << endl;
+		*out << "	<!ATTLIST cell" << endl;
+		*out << "		row-index CDATA #REQUIRED" << endl;
+		*out << "		column-index CDATA #REQUIRED" << endl;
+		*out << "		level-index CDATA #REQUIRED" << endl;
+		*out << "	>" << endl;
+		*out << "]>" << endl;
+
+		*out << endl;
+		*out << endl;
+		*out << "<tracefile name=\"T R A C E   F I L E   F O R  C E L L U L A R   A U T O M A T O N " << sender->getLabel() << "\">" << endl;
+		firstTime=false;
+	}
+
+	( *out ).setf( std::ios::showpoint );
+	( *out ).setf( std::ios::fixed );
+
+	*out << setprecision( 2 ) << "	<ca time=\"" << sender->getTime() << "\">" << endl;
+	for (int k = 0; k < sender->getLevelCount(); ++k) {
+		for (int i = 0; i < sender->getRowCount(); ++i) {
+			for (int j = 0; j < sender->getColumnCount(); ++j) {
+				if(sender->getCell(i,j,k)->isPartOfBoundary()) continue;
+				*out << "		<cell row-index=\"" << sender->getCell(i, j, k)->getPosition()->getRowNumber() << "\""
+						<< " column-index=\"" << sender->getCell(i, j, k)->getPosition()->getColumnNumber() << "\""
+						<< " level-index=\"" << sender->getCell(i, j, k)->getPosition()->getLevelNumber() << "\""
+						<< ">" << endl;
+
+				for( int l = 0; l < sender->getCell(i, j, k)->getDimension(); ++l ) {
+					*out << "			<statevariable>" << endl;
+					*out << "				" << sender->getCell(i, j, k)->getValue(l) << endl;
+					*out << "			</statevariable>" << endl;
+				}
+				for( int l = 0; l < sender->getCell(i, j, k)->getDimension(); ++l ) {
+					*out << "			<outputvariable>" << endl;
+					*out << "				" << sender->getCell(i, j, k)->getOutputValue(l) << endl;
+					*out << "			</outputvariable>" << endl;
+				}
+				for( int l = 0; l < sender->getCell(i, j, k)->getDimension(); ++l ) {
+					*out << "			<inputvariable>" << endl;
+					*out << "				" << sender->getCell(i, j, k)->getValue(l) << endl;
+					*out << "			</inputvariable>" << endl;
+				}
+
+				*out << "		</cell>" << endl;
+			}
+		}
+	}
+	*out << "	</ca>" << endl;
+	*out << endl;
+}
+
+void CellMonitorTrace::openFile( const std::string& fileName )
+{
+	out = new std::ofstream( fileName.c_str() );
+	if( out == 0 || !( *out ) )
+	{
+		// Error: cannot open file
+		std::cerr << "CellMonitorTrace::openFile(): cannot open file; sending output to stdout." << std::endl;
+		out = &std::cout;
+	}
+}
diff --git a/odemx-lite/src/base/cellular_automaton/CellVariablesContainer.cpp b/odemx-lite/src/base/cellular_automaton/CellVariablesContainer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b8bbf63c3316b3cf924b40cb6cfa7e8a6098cf8c
--- /dev/null
+++ b/odemx-lite/src/base/cellular_automaton/CellVariablesContainer.cpp
@@ -0,0 +1,109 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file CellVariablesContainer.cpp
+
+ \author Sascha Qualitz
+
+ \date created at 2010/01/05
+
+ \brief Implementation of class CellVariablesContainer
+
+ \sa CellVariablesContainer.h
+
+ \since 3.0
+ */
+
+#include <odemx/base/cellular_automaton/CellVariablesContainer.h>
+
+using namespace odemx::base;
+using namespace odemx::base::cellular;
+using namespace std;
+
+CellVariablesContainer::CellVariablesContainer(unsigned cellRows, unsigned cellColumns, unsigned cellLevel, unsigned variablesInCount, unsigned variablesOutCount, unsigned cellDimension)
+:  cellRows(cellRows)
+,  cellColumns(cellColumns)
+,  cellLevel(cellLevel)
+,  variablesInCount(variablesInCount)
+,  variablesOutCount(variablesOutCount)
+,  cellDimension(cellDimension)
+{
+	unsigned inputSize = cellRows*cellColumns*cellLevel*variablesInCount;
+	unsigned outputSize = cellRows*cellColumns*cellLevel*variablesOutCount;
+	unsigned stateSize = cellRows*cellColumns*cellLevel*cellDimension;
+
+	input_values = new double[inputSize];
+	state_values = new double[stateSize];
+	output_values = new double[outputSize];
+
+	for (int i = 0; i < stateSize; ++i) {
+		state_values[i] = 0;
+	}
+	for (int i = 0; i < inputSize; ++i) {
+		input_values[i] = 0;
+	}
+	for (int i = 0; i < outputSize; ++i) {
+		output_values[i] = 0;
+	}
+}
+
+CellVariablesContainer::~CellVariablesContainer() {
+	//nothing todo
+}
+
+void CellVariablesContainer::setOutputValue(unsigned baseIndex, unsigned variableIndex, double value) {
+	this->output_values[baseIndex+variableIndex] = value;
+}
+
+double CellVariablesContainer::getOutputValue(unsigned baseIndex, unsigned variableIndex) {
+	return this->output_values[baseIndex+variableIndex];
+}
+
+void CellVariablesContainer::setStateValue(unsigned baseIndex, unsigned variablesIndex, double value) {
+	this->state_values[baseIndex + variablesIndex] = value;
+}
+
+double CellVariablesContainer::getStateValue(unsigned baseIndex, unsigned variablesIndex) {
+	return this->state_values[baseIndex + variablesIndex];
+}
+
+void CellVariablesContainer::setInputValue(unsigned baseIndex, unsigned variableIndex, double value) {
+	this->input_values[baseIndex+variableIndex] = value;
+}
+
+double CellVariablesContainer::getInputValue(unsigned baseIndex, unsigned variableIndex) {
+	return this->input_values[baseIndex+variableIndex];
+}
+
+unsigned CellVariablesContainer::getNumberOfRows() {
+	return this->cellRows;
+}
+
+unsigned CellVariablesContainer::getNumberOfColumns() {
+	return this->cellColumns;
+}
+
+unsigned CellVariablesContainer::getNumberOfLevels() {
+	return this->cellLevel;
+}
+
+//----------------------------------------------------------- temp function for printing values
+
+double* CellVariablesContainer::getOutputValues() {
+	return this->output_values;
+}
diff --git a/odemx-lite/src/base/cellular_automaton/Transition.cpp b/odemx-lite/src/base/cellular_automaton/Transition.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6340aaca753f237364ee4abe1ec2771e9c9df8e9
--- /dev/null
+++ b/odemx-lite/src/base/cellular_automaton/Transition.cpp
@@ -0,0 +1,113 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Transition.cpp
+
+ \author Sascha Qualitz
+
+ \date created at 2010/01/05
+
+ \brief Implementation of class Cell
+
+ \sa Cell.h
+
+ \since 3.0
+ */
+
+#include <odemx/base/cellular_automaton/Transition.h>
+
+using namespace odemx::base;
+using namespace odemx::base::cellular;
+using namespace std;
+
+//------------------------------------------------------------------------------construction/destruction
+Transition::Transition() {
+
+}
+
+Transition::~Transition() {
+
+}
+
+void Transition::setCell(Cell* cell) {
+	if(cell) {
+		this->cell = cell;
+	}
+	else {
+		throw new NotAssignedException("Cell", "Transition");
+	}
+}
+
+void Transition::outputFunction() {
+	// reimplement this
+	for (int i = 0; i < this->cell->getDimension(); ++i) {
+		cell->setOutputValue(i,cell->getValue(i));
+	}
+}
+
+double Transition::getValue(unsigned variableIndex) {
+	 if(cell) {
+		 return cell->getValue(variableIndex);
+	}
+	else {
+		throw new NotAssignedException("Cell", "Transition");
+	}
+}
+
+void Transition::setValue(unsigned variableIndex, double value) {
+	if(cell) {
+		cell->setValue(variableIndex, value);
+	}
+	else {
+		throw new NotAssignedException("Cell", "Transition");
+	}
+}
+
+Cell* Transition::searchNeighbor(unsigned row, unsigned column, unsigned level) {
+	return this->cell->searchNeighbor(row, column, level);
+}
+
+std::map<CellPosition, Cell*, ComparePositions> Transition::calculateAlternativeNeighborhood(unsigned radius) {
+	// reimplement this if needed
+	/**
+	 	 Fill a map with cells which belongs to the neighborhood of the cell.
+	 	 Example:
+
+	 	 CellPosition position(this->cell->cellPosition->row -1, this->cell->cellPosition->column -3, this->cell->cellPosition->level -1, this->cell->monitor->getRowCount(), this->cell->monitor->getColumnCount(), this->cell->monitor->getLevelCount())
+	 	 std::map<CellPosition, Cell*, ComparePositions> map;
+
+	 	 map[position] = this->cell->monitor->getCell(position->row, position->column, position->level);
+
+	 	 One have to check that the chosen cells really exists.
+	 */
+}
+
+//------------------------------------------------------------------------------NotAssignedException
+NotAssignedException::NotAssignedException(const char* missingObject, const char* object) {
+	this->msg = "This ";
+	this->msg += object;
+	this->msg += "-Object has no ";
+	this->msg += missingObject;
+	this->msg += " assigned.";
+}
+
+NotAssignedException::~NotAssignedException() throw() {}
+
+const char* NotAssignedException::what() const throw() {
+	return this->msg.c_str();
+}
diff --git a/odemx-lite/src/base/continuous/.!4415!GSLContainer.o b/odemx-lite/src/base/continuous/.!4415!GSLContainer.o
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/odemx-lite/src/base/continuous/.!4485!GSLContainer.o b/odemx-lite/src/base/continuous/.!4485!GSLContainer.o
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/odemx-lite/src/base/continuous/.!4503!GSLContainer.o b/odemx-lite/src/base/continuous/.!4503!GSLContainer.o
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/odemx-lite/src/base/continuous/Continuous.cpp b/odemx-lite/src/base/continuous/Continuous.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dbb5199b509d4ebbd70c7451ca89100988f7cc86
--- /dev/null
+++ b/odemx-lite/src/base/continuous/Continuous.cpp
@@ -0,0 +1,374 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Continuous.cpp
+
+ \author Michael Fiedler
+
+ \date created at 2009/01/02
+
+ \brief Implementation of class continuous
+
+ \sa Continuous.h
+
+ \since 3.0
+ */
+
+#include <odemx/base/continuous/Continuous.h>
+
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <odemx/base/continuous/Monitor.h>
+#include <odemx/base/TypeDefs.h>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+
+using namespace odemx::base;
+using namespace odemx::base::continuous;
+using namespace std;
+
+//----------------------------------------------------------------construction/destruction
+continuous::Continuous::Continuous(Simulation& sim, const data::Label& label, int dimension)
+:	Producer( sim, label )
+,	monitor(0)
+,	dimension(dimension)
+,	baseIndex(0)
+{
+	//ODEMX_TRACE << log( "create with sim" ).scope( typeid(Continuous) );
+
+	// observer
+	ODEMX_OBS(ContinuousObserver, Create(this));
+}
+
+continuous::Continuous::Continuous(Simulation& sim, const data::Label& label, Monitor* monitor, int dimension, ODEObject* equation)
+:	Producer( sim, label )
+,	monitor(0)
+,	dimension(dimension)
+,	baseIndex(0)
+{
+	setMonitor(monitor);
+	if(equation != 0) addODE(equation);
+
+	//ODEMX_TRACE << log( "create with sim, monitor and equation" ).scope( typeid(Continuous) );
+
+	// observer
+	ODEMX_OBS(ContinuousObserver, Create(this));
+}
+
+continuous::Continuous::Continuous(Simulation& sim, const data::Label& label, Monitor* monitor, int dimension, std::list<ODEObject*> equationList)
+:	Producer( sim, label )
+,	monitor(0)
+,	dimension(dimension)
+,	baseIndex(0)
+{
+	setMonitor(monitor);
+	addODEList(equationList);
+
+	//ODEMX_TRACE << log( "create with sim, monitor and a list of equations" ).scope( typeid(Continuous) );
+
+	// observer
+	ODEMX_OBS(ContinuousObserver, Create(this));
+}
+
+Continuous::~Continuous() {
+	//ODEMX_TRACE << log( "destroy" );
+}
+
+//--------------------------------------------------------------handle responsible Monitor
+void Continuous::setMonitor(Monitor *monitor) {
+	if (this->monitor != 0) { //remove from old
+		this->monitor->removeContinuous(this); //all actions are implemented in Monitor
+	}
+
+	if (monitor != 0) {	//add to new
+		monitor->addContinuous(this); //all actions are implemented in Monitor
+	}
+
+	//ODEMX_TRACE << log( "set new monitor" ).scope( typeid(Continuous) );
+
+	// observer
+	ODEMX_OBS(ContinuousObserver, SetMonitor(this, monitor));
+}
+
+Monitor* Continuous::getMonitor() {
+	return monitor;
+}
+
+//---------------------------------------------------------------handle active equations
+void Continuous::addODEList(std::list<ODEObject*> equationList) {
+	std::list<ODEObject*>::iterator iter;
+	for (iter = equationList.begin(); iter != equationList.end(); iter++)
+		addODE(*iter);
+}
+
+void Continuous::addODE(ODEObject *equation) {
+	if (equation != 0) { //only add real objects
+		if (equation->continuous != 0) { //delete from old Continuous
+			equation->continuous->removeODE(equation);
+		}
+		//add to this Continuous
+		equation->continuous = this;
+		this->equations.push_back(equation);
+		//tell monitor that system changed
+		this->setChanged();
+
+		//ODEMX_TRACE << log( "add ODE" ).scope( typeid(Continuous) );
+
+		// observer
+		//ODEMX_OBS(ContinuousObserver, AddODE(this, equation));
+	}
+}
+
+void Continuous::removeODE(ODEObject *equation) {
+	//go to position..
+	std::list<ODEObject*>::iterator iter = find(this->equations.begin(),
+												this->equations.end(), equation);
+	//..and delete
+	if (*iter == equation) {
+		this->equations.erase(iter);
+	}
+	equation->continuous = 0;
+	//tell monitor that system changed
+	this->setChanged();
+
+	//ODEMX_TRACE << log( "remove ODE" ).scope( typeid(Continuous) );
+
+	// observer
+	//ODEMX_OBS(ContinuousObserver, RemoveODE(this, equation));
+}
+
+//--------------------------------------------------------------------------------stuff
+int Continuous::getDimension() {
+	return dimension;
+}
+
+void Continuous::setChanged() {
+	if (monitor) monitor->setChanged();
+}
+
+//-----------------------------------------------------handle values between integration
+void Continuous::setValue(int i, double value) {
+	if (monitor != 0 && monitor->variables != 0) {
+		monitor->variables->setVariable(this->baseIndex + i, value);
+		//tell monitor that system changed since init value changed
+		this->setChanged();
+	} else {
+		//throw NotAssignedException for missing Monitor
+		throw new NotAssignedException("Monitor", "Continuous");
+	}
+}
+
+double Continuous::getValue(int i) {
+	if (monitor != 0) {
+		return monitor->variables->getVariable(this->baseIndex + i);
+	} else {
+		//throw NotAssignedException for missing Monitor
+		throw new NotAssignedException("Monitor", "Continuous");
+	}
+}
+
+//---------------------------------------------------------handle values in integration
+double Continuous::getValueForDerivative(int i) {
+	if (monitor != 0) {
+		return monitor->variables->getValue(this->baseIndex + i);
+	} else {
+		//throw NotAssignedException for missing Monitor
+		throw new NotAssignedException("Monitor", "Continuous");
+	}
+}
+
+void Continuous::setDerivative(int i, double value) {
+	if (monitor != 0) {
+		monitor->variables->addToDerivative(this->baseIndex + i, value);
+	} else {
+		//throw NotAssignedException for missing Monitor
+		throw new NotAssignedException("Monitor", "Continuous");
+	}
+}
+
+double Continuous::getDerivative(int i) {
+	if (monitor != 0) {
+		return monitor->variables->getDerivative(this->baseIndex + i);
+	} else {
+		//throw NotAssignedException for missing Monitor
+		throw new NotAssignedException("Monitor", "Continuous");
+	}
+}
+
+void Continuous::setJacobi(int i, int j, double value) {
+	if (monitor != 0) {
+		monitor->variables->addToJacobi(this->baseIndex + i, this->baseIndex + j, value);
+	} else {
+		//throw NotAssignedException for missing Monitor
+		throw new NotAssignedException("Monitor", "Continuous");
+	}
+}
+
+double Continuous::getJacobi(int i, int j) {
+	if (monitor != 0) {
+		return monitor->variables->getJacobi(this->baseIndex + i, this->baseIndex + j);
+	} else {
+		//throw NotAssignedException for missing Monitor
+		throw new NotAssignedException("Monitor", "Continuous");
+	}
+}
+
+void Continuous::setJacobi(int i, Continuous* continuous, int j, double value) {
+	if (monitor != 0) {
+		monitor->variables->addToJacobi(this->baseIndex + i, continuous->baseIndex + j, value);
+	} else {
+		//throw NotAssignedException for missing Monitor
+		throw new NotAssignedException("Monitor", "Continuous");
+	}
+}
+
+double Continuous::getJacobi(int i, Continuous* continuous, int j) {
+	if (monitor != 0) {
+		return monitor->variables->getJacobi(this->baseIndex + i, continuous->baseIndex + j);
+	} else {
+		//throw NotAssignedException for missing Monitor
+		throw new NotAssignedException("Monitor", "Continuous");
+	}
+}
+
+void Continuous::setDfDt(int i, double value) {
+	if (monitor != 0) {
+		monitor->variables->addToDfDt(this->baseIndex + i, value);
+	} else {
+		//throw NotAssignedException for missing Monitor
+		throw new NotAssignedException("Monitor", "Continuous");
+	}
+}
+
+double Continuous::getDfDt(int i) {
+	if (monitor != 0) {
+		return monitor->variables->getDfDt(this->baseIndex + i);
+	} else {
+		//throw NotAssignedException for missing Monitor
+		throw new NotAssignedException("Monitor", "Continuous");
+	}
+}
+
+void Continuous::notifyValidState() {
+	//observers
+	ODEMX_OBS(ContinuousObserver, NewValidState(this));
+}
+
+ContinuousTrace::ContinuousTrace(Continuous* contu, const string & fileName)
+: out(0),
+  firstTime(true),
+  fileName(fileName),
+  continuous(contu)
+{
+#ifdef ODEMX_USE_OBSERVATION
+	if( contu != 0 )
+	{
+		contu->data::Observable< ContinuousObserver >::addObserver( this );
+	}
+#endif
+
+	if( ! fileName.empty() )
+	{
+		openFile( fileName );
+	}
+	else if( contu != 0 )
+	{
+		std::string fn = contu->getLabel();
+		fn += "_trace.txt";
+		openFile( fn );
+	}
+}
+
+ContinuousTrace::~ContinuousTrace()
+{
+	if( out == 0 || out == &std::cout )
+	{
+		return;
+	}
+
+	static_cast< std::ofstream* >( out )->close();
+	delete out;
+}
+
+void ContinuousTrace::onNewValidState( Continuous* sender )
+{
+	using namespace std;
+
+	assert( sender != 0 );
+
+	if( firstTime )
+	{
+		if( out == 0 )
+		{
+			std::string fn = fileName;
+			fn += "_trace.txt";
+			openFile( fn );
+		}
+
+		*out << endl;
+		*out << setw(60) << "T R A C E   F I L E   F O R  " << sender->getLabel() << " managed by monitor " << sender->getMonitor()->getLabel() << endl << endl;
+		*out << setw(13) << "Time";
+		*out << setw(13) << "Steplength";
+		*out << setw(13) << "Error";
+
+		for( int i = 0; i < continuous->getDimension(); ++i ) {
+			*out << setw(15) << "state[" << i << "]";
+		}
+
+		for( int i = 0; i < continuous->getDimension(); ++i ) {
+			*out << setw(15) << "rate[" << i << "]";
+		}
+
+		*out << endl;
+
+		firstTime=false;
+	}
+
+	( *out ).setf( std::ios::showpoint );
+	( *out ).setf( std::ios::fixed );
+	*out << setw( 13 ) << setprecision( 10 ) << sender->getMonitor()->getActualInternalTime();
+	*out << setw( 14 ) << setprecision( 10 ) << sender->getMonitor()->getODESolver()->getStepLength();
+	*out << setw( 14 ) << setprecision( 10 ) << sender->getMonitor()->getODESolver()->getErrorLimit();
+
+	//State values
+	for( int i = 0; i < sender->getDimension(); ++i ) {
+		*out << setw( 18 ) << setprecision( 10 ) << sender->getValue(i);
+	}
+
+	//rate values
+	for( int i = 0; i < sender->getDimension(); ++i ) {
+		*out << setw( 18 ) << setprecision( 10 ) << sender->getDerivative(i);
+	}
+
+	*out << endl;
+}
+
+void ContinuousTrace::openFile( const std::string& fileName )
+{
+	out = new std::ofstream( fileName.c_str() );
+	if( out == 0 || !( *out ) )
+	{
+		// Error: cannot open file
+		std::cerr << "MonitorTrace::openFile(): cannot open file; sending output to stdout." << std::endl;
+		out = &std::cout;
+	}
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
+
diff --git a/odemx-lite/src/base/continuous/DfDt.cpp b/odemx-lite/src/base/continuous/DfDt.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..375a27e45ca404a4407c850c3ea624bf2a1c6165
--- /dev/null
+++ b/odemx-lite/src/base/continuous/DfDt.cpp
@@ -0,0 +1,96 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file DfDt.cpp
+
+	\author Sascha Qualitz
+
+	 \date created at 2009/10/26
+
+	 \brief Implementation of DfDt
+
+	\sa DfDt.h
+
+	\since 3.0
+*/
+
+#include <odemx/base/continuous/DfDt.h>
+
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <odemx/base/continuous/Continuous.h>
+#include <odemx/base/continuous/Monitor.h>
+
+using namespace odemx::base;
+using namespace odemx::base::continuous;
+using namespace std;
+
+DfDt::DfDt()
+:	continuous(0),
+	index_(0)
+{}
+
+DfDt::DfDt(Continuous* continuous)
+:	continuous(continuous),
+	index_(0)
+{}
+
+DfDt::~DfDt() {
+	// nothing todo!
+}
+
+DfDt& DfDt::operator =(const double value) {
+	setValue(value);
+	return *this;
+}
+
+DfDt& DfDt::operator [](const unsigned i) {
+	if (continuous != 0) {
+		if(i > continuous->getDimension()-1)
+			throw std::out_of_range("The index in an object of type DfDt is out of bounds");
+
+		index_ = i;
+
+		return *this;
+	} else
+		throw new NotAssignedException("Continuous", "DfDt");
+}
+
+void DfDt::setContinuous(Continuous* continuous) {
+	if (continuous != 0) {
+		this->continuous = continuous;
+	} else
+		throw new NotAssignedException("Continuous", "DfDt");
+}
+
+double DfDt::getValue() const{
+	if (continuous != 0) {
+		return continuous->getDfDt(index_);
+	} else
+		throw new NotAssignedException("Continuous", "DfDt");
+}
+
+void DfDt::setValue(double value) {
+	if (continuous != 0) {
+		continuous->setDfDt(index_, value);
+	} else
+		throw new NotAssignedException("Continuous", "DfDt");
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
+
diff --git a/odemx-lite/src/base/continuous/GSLContainer.o b/odemx-lite/src/base/continuous/GSLContainer.o
new file mode 100644
index 0000000000000000000000000000000000000000..1eda7c2d48cb56a26965e455a7f98a7e64eb718a
Binary files /dev/null and b/odemx-lite/src/base/continuous/GSLContainer.o differ
diff --git a/odemx-lite/src/base/continuous/JacobiMatrix.cpp b/odemx-lite/src/base/continuous/JacobiMatrix.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..46c6e36868183166fc1ab15ca1b404e70b889e32
--- /dev/null
+++ b/odemx-lite/src/base/continuous/JacobiMatrix.cpp
@@ -0,0 +1,128 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file JacobiMatrix.cpp
+
+	\author Sascha Qualitz
+
+	 \date created at 2009/10/26
+
+	 \brief Implementation of JacobiMatrix
+
+	\sa JacobiMatrix.h
+
+	\since 3.0
+*/
+
+#include <odemx/base/continuous/JacobiMatrix.h>
+
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <odemx/base/continuous/Continuous.h>
+#include <odemx/base/continuous/Monitor.h>
+
+using namespace odemx::base;
+using namespace odemx::base::continuous;
+using namespace std;
+
+JacobiMatrix::JacobiMatrix()
+:	continuous(0),
+	otherContinuous(0),
+	row_(0),
+	column_(0)
+{}
+
+JacobiMatrix::JacobiMatrix(Continuous* continuous)
+:	continuous(continuous),
+	otherContinuous(0),
+	row_(0),
+	column_(0)
+{}
+
+JacobiMatrix::JacobiMatrix(Continuous* continuous, Continuous* otherContinuous)
+:	continuous(continuous),
+	otherContinuous(otherContinuous),
+	row_(0),
+	column_(0)
+{}
+
+JacobiMatrix::~JacobiMatrix() {
+	// TODO Auto-generated destructor stub
+}
+
+double JacobiMatrix::getValue() const {
+	if(continuous != 0 || otherContinuous != 0) {
+		if(otherContinuous != 0)
+			return continuous->getJacobi(row_, otherContinuous, column_);
+		else
+			return continuous->getJacobi(row_, column_);
+	} else
+		throw new NotAssignedException("Continuous", "JacobiMatrix");
+
+}
+
+void JacobiMatrix::setValue(double value) {
+	if(continuous != 0 || otherContinuous != 0) {
+		if(otherContinuous != 0)
+			continuous->setJacobi(row_, otherContinuous, column_, value);
+		else
+			continuous->setJacobi(row_, column_, value);
+	} else
+		throw new NotAssignedException("Continuous", "JacobiMatrix");
+}
+
+JacobiMatrix& JacobiMatrix::operator =(const double value) {
+	setValue(value);
+	return *this;
+}
+
+JacobiMatrix& JacobiMatrix::operator ()(const unsigned row, const unsigned column) {
+	if(continuous != 0 || otherContinuous != 0) {
+		if(otherContinuous != 0) {
+			if(row > continuous->getDimension()-1 || column > otherContinuous->getDimension()-1)
+						throw std::out_of_range("An index in an object of type JacobiMatrix is out of bounds");
+		} else {
+			if(row > continuous->getDimension()-1 || column > continuous->getDimension()-1)
+				throw std::out_of_range("An index in an object of type JacobiMatrix is out of bounds");
+		}
+
+		row_ = row;
+		column_ = column;
+
+		return *this;
+	} else
+		throw new NotAssignedException("Continuous", "JacobiMatrix");
+}
+
+void JacobiMatrix::setContinuous(Continuous* continuous) {
+	if(continuous != 0) {
+		this->continuous = continuous;
+	} else
+		throw new NotAssignedException("Continuous", "JacobiMatrix");
+}
+
+void JacobiMatrix::setContinuous(Continuous* continuous, Continuous* otherContinuous) {
+	if(continuous != 0 || otherContinuous != 0) {
+		this->continuous = continuous;
+		this->otherContinuous = otherContinuous;
+	} else
+		throw new NotAssignedException("Continuous", "JacobiMatrix");
+}
+
+
+#endif /* ODEMX_USE_CONTINUOUS */
diff --git a/odemx-lite/src/base/continuous/Monitor.cpp b/odemx-lite/src/base/continuous/Monitor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..edb0c18fa4e62a7f5545e4034f18e7ab29fc2d63
--- /dev/null
+++ b/odemx-lite/src/base/continuous/Monitor.cpp
@@ -0,0 +1,589 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Monitor.cpp
+
+	\author Michael Fiedler
+
+	\date created at 2009/01/02
+
+	\brief Implementation of class Monitor
+
+	\sa Monitor.h
+
+	\since 3.0
+*/
+
+#include <odemx/base/continuous/Monitor.h>
+
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <odemx/base/Scheduler.h>
+#include <odemx/base/Simulation.h>
+#include <typeinfo>
+
+using namespace odemx::base;
+using namespace odemx::base::continuous;
+using namespace std;
+
+#define MIN_MONITOR_ENLARGE( a ) a > 10 ? a : 10
+
+//----------------------------------------------------------------------------------construction/destruction
+
+Monitor::Monitor(Simulation& s, const data::Label& label, int variablesArraySize, ODESolver* solver, MonitorObserver* o)
+:	Process(s, label, o),
+	workingMode(intervall),
+	searchMode(linearization),
+	variablesArraySize(variablesArraySize),
+	variablesCount(0),
+	variables(0),
+	internalTime(0),
+	timeLimit(0),
+	timeLimitSet(false),
+	hasToStop(false),
+	diffTime(0.0),
+	changed(true)
+{
+	setODESolver(solver);
+
+	ODEMX_TRACE << log( "create with sim and solver" ).scope( typeid(Monitor) );
+
+	// observer
+	ODEMX_OBS(MonitorObserver, Create(this));
+}
+
+Monitor::~Monitor(){
+	if (variables) {
+		delete variables;
+	}
+
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Monitor) );
+}
+
+//------------------------------------------------------------------------------stop monitor
+void Monitor::setTimeLimit(SimTime time) {
+	timeLimitSet = true;
+	timeLimit = time;
+}
+
+bool Monitor::getTimeLimit(SimTime* time) {
+	if (timeLimitSet) {
+		*time = timeLimit;
+		return true;
+	} else {
+		return false;
+	}
+}
+
+void Monitor::removeTimeLimit() {
+	timeLimitSet = false;
+}
+
+void Monitor::stop() {
+	hasToStop = true;
+
+	ODEMX_TRACE << log( "Monitor stops" ).scope( typeid(Monitor) );
+
+	// observer
+	ODEMX_OBS(MonitorObserver, Stop(this));
+}
+
+//-------------------------------------------------------------------------------eval system
+void Monitor::evalF(double time) {
+	this->variables->nullDerivatives();
+	SimTime evalTime = (SimTime)(internalTime + time);
+	std::list<Continuous*>::iterator iter;
+	std::list<ODEObject*>::iterator iter2;
+
+	for (iter = this->continuousList.begin(); iter != this->continuousList.end(); iter++)
+		for (iter2 = (*iter)->equations.begin(); iter2 != (*iter)->equations.end(); iter2++)
+			(*iter2)->derivates(evalTime);
+}
+
+void Monitor::evalJacobian(double time) {
+	this->variables->nullJacobi();
+	this->variables->nullDfDt();
+	SimTime evalTime = (SimTime)(internalTime + time);
+	std::list<Continuous*>::iterator iter;
+	std::list<ODEObject*>::iterator iter2;
+	for (iter = this->continuousList.begin(); iter != this->continuousList.end(); iter++)
+		for (iter2 = (*iter)->equations.begin(); iter2 != (*iter)->equations.end(); iter2++)
+			(*iter2)->jacobi(evalTime);
+}
+
+//--------------------------------------------------------------------------handle used solver
+void Monitor::setODESolver(ODESolver *solver) {
+	if (solver) {
+		if (solver->monitor) {
+			solver->monitor->setODESolver(0);
+		}
+		
+		VariableContainer *newVariables = solver->getVariableContainer(variablesArraySize);
+		int lv; //loop variable
+		if (variables) {
+			//copy from old container to new (only variables the rest depend on this)
+			for (lv = 0; lv < variablesCount; lv++)
+				newVariables->setVariable(lv, variables->getVariable(lv));
+			//after copying clean old
+			delete variables;
+		}
+		variables = newVariables;
+		this->solver = solver;
+		solver->monitor = this;
+
+		ODEMX_TRACE << log( "set solver" ).scope( typeid(Monitor) );
+
+		// observer
+		ODEMX_OBS(MonitorObserver, SetODESolver(this, solver));
+
+	} else {
+		this->solver = 0;
+		//keep variables to keep state
+	}
+
+	setChanged();
+}
+
+ODESolver* Monitor::getODESolver() {
+	return solver;
+}
+
+//-----------------------------------------------------------add/remove Continuous and StateEvent
+void Monitor::addContinuous(Continuous *continuous) {
+	if (continuous != 0) { //only add real objects
+		if (continuous->monitor != 0) { //delete from old Monitor
+			continuous->monitor->removeContinuous(continuous);
+		}
+		//add to this Monitor
+		continuous->monitor = this;
+		continuous->baseIndex = this->variablesCount;
+		this->continuousList.push_back(continuous);
+		this->variablesCount += continuous->getDimension();
+		int diffSize = this->variablesCount - this->variablesArraySize;
+		if (diffSize > 0) {
+			this->variablesArraySize += MIN_MONITOR_ENLARGE( diffSize );
+			if (variables)
+				variables->adaptSizeTo(this->variablesArraySize);
+		}
+
+		ODEMX_TRACE << log( "add continuous object" ).scope( typeid(Monitor) );
+
+		// observer
+		ODEMX_OBS(MonitorObserver, AddContinuous(this, continuous));
+	}
+	setChanged();
+}
+
+void Monitor::removeContinuous(Continuous *continuous) {
+	//go to position..
+	std::list<Continuous*>::iterator iter = find(this->continuousList.begin(),
+												this->continuousList.end(), continuous);
+	//..and delete
+	if (*iter == continuous) {
+		this->continuousList.erase(iter);
+
+		ODEMX_TRACE << log( "remove continuous object" ).scope( typeid(Monitor) );
+
+		// observer
+		ODEMX_OBS(MonitorObserver, RemoveContinuous(this, continuous));
+	}
+	continuous->monitor = 0;
+	setChanged();
+}
+
+void Monitor::addStateEvent(StateEvent *stateEvent) {
+	if (stateEvent) { //only add real objects
+		if (stateEvent->monitor) { //delete from old Monitor
+			stateEvent->monitor->removeStateEvent(stateEvent);
+		}
+		//add to this Monitor
+		stateEvent->monitor = this;
+		this->stateEvents.push_back(stateEvent);
+		if (stateEvent->condition(getActualInternalTime())) {
+			//condition holds so trigger action
+			stateEvent->action();
+		}
+
+		ODEMX_TRACE << log( "add StateEvent" ).scope( typeid(Monitor) );
+
+		// observer
+		ODEMX_OBS( MonitorObserver, AddStateEvent( this, stateEvent ) );
+
+	}
+}
+
+void Monitor::removeStateEvent(StateEvent *stateEvent) {
+	//go to position..
+	std::list<StateEvent*>::iterator iter = find(this->stateEvents.begin(),
+												this->stateEvents.end(), stateEvent);
+	//..and delete
+	if (*iter == stateEvent) {
+		this->stateEvents.erase(iter);
+
+		ODEMX_TRACE << log( "remove StateEvent" ).scope( typeid(Monitor) );
+
+		// observer
+		ODEMX_OBS( MonitorObserver, RemoveStateEvent( this, stateEvent ) );
+	}
+	stateEvent->monitor = 0;
+}
+
+//-----------------------------------------------------------add/remove process from synchronisation
+void Monitor::addProcessToWaitList(Process *process) {
+	if (process) { //only add real objects
+		waitForProcesses.push_back(process);
+
+		ODEMX_TRACE << log( "add process to list waitForProcesses" ).detail( "process", process ).scope( typeid(Monitor) );
+
+		// observer
+		ODEMX_OBS(MonitorObserver, AddProcessToWaitList(this, process));
+	}
+}
+
+void Monitor::removeProcessFromWaitList(Process *process) {
+	//go to position
+	std::list<Process*>::iterator iter = find(waitForProcesses.begin(),
+											  waitForProcesses.end(), process);
+	//..and delete
+	if (*iter == process) {
+		waitForProcesses.erase(iter);
+
+		ODEMX_TRACE << log( "remove process from list waitForProcesses" ).detail( "process", process ).scope( typeid(Monitor) );
+
+		// observer
+		ODEMX_OBS(MonitorObserver, RemoveProcessFromWaitList(this, process));
+	}
+}
+
+//-----------------------------------------------------------------------------manage internal time
+void Monitor::setInternalTime(SimTime time) {
+	setChanged();
+	internalTime = time;
+	diffTime = 0.0;
+	//check StateEvents to be sure conditions are false in this state or trigger action
+	std::list<StateEvent*>::iterator iter;
+	for (iter = this->stateEvents.begin(); iter != this->stateEvents.end(); iter++) {
+		if ((*iter)->condition(time)) {
+			(*iter)->action();
+		}
+	}
+
+	ODEMX_TRACE << log( "internal time has changed" ).scope( typeid(Monitor) );
+
+	// observer
+	ODEMX_OBS(MonitorObserver, SetInternalTime(this, time));
+}
+
+SimTime Monitor::getInternalTime() {
+	return internalTime;
+}
+
+SimTime Monitor::getActualInternalTime() {
+	return (SimTime)(internalTime + diffTime);
+}
+
+void Monitor::adaptInternalTime() {
+	setChanged();
+	internalTime = (SimTime)(internalTime + diffTime);
+	diffTime = 0.0;
+
+	ODEMX_TRACE << log( "adapted internal time to actual time" ).scope( typeid(Monitor) );
+
+	// observer
+	ODEMX_OBS(MonitorObserver, AdaptInternalTime(this, internalTime));
+}
+
+SimTime Monitor::getStepTimeLimit() {
+	SimTime limit = waitForProcesses.front()->getExecutionTime();
+
+	for (std::list<Process*>::iterator iter = waitForProcesses.begin(); iter != waitForProcesses.end(); ++iter) {
+		Process* current = *iter;
+		SimTime execTime = current->getExecutionTime();
+		if(current->isScheduled() && execTime < limit) {
+			limit = execTime;
+		}
+	}
+
+	waitForProcesses.pop_front();
+
+	return limit;
+}
+
+//----------------------------------------------------------------------------main and integration
+int Monitor::main() {
+	while (!hasToStop && (!timeLimitSet || getActualInternalTime() < timeLimit) && solver != 0) {
+		SimTime limit = timeLimit;
+		if (!waitForProcesses.empty()) {
+			limit = getStepTimeLimit();
+			if (timeLimitSet) {
+				limit = limit < timeLimit ? limit : timeLimit;
+			}
+			integrateUntil(limit);
+		} else if (timeLimitSet) {
+			integrateUntil(limit);
+		} else if (!stateEvents.empty()) { //only stops if an stateEvent occurs
+			integrate();
+		} else {
+			//no limit for integration intervall, would result in infinite long working
+			hasToStop = true;
+		}
+		holdUntil(getActualInternalTime());
+	}
+	return 0;
+}
+
+void Monitor::integrate() {
+
+	if( getProcessState() != Process::CURRENT )
+	{
+		error << log( "Monitor::integrate(): object is not the current process" )
+				.scope( typeid(Monitor) );
+	}
+
+	if (solver) {
+		if (changed == true) {
+			solver->init();
+			changed = false;
+		}
+
+		ODEMX_TRACE << log( "begin integrate" ).scope( typeid(Monitor) );
+
+		// observer
+		ODEMX_OBS(MonitorObserver, BeginIntegrate(this));
+
+		bool testStateEvents = !stateEvents.empty(); //only to testing if necessary
+		double old_diffTime, *old_variable_values, old_maxStep = solver->maxStep;
+		int lv; //loop variable
+		std::list<StateEvent*>::iterator iter;
+		if (testStateEvents) {
+			//init for first step of while loop
+			old_diffTime = diffTime;
+			old_variable_values = new double[ variablesCount ];
+			for (lv = 0; lv < variablesCount; lv++)
+				old_variable_values[lv] = variables->getVariable(lv);
+		}
+		while (testStateEvents) { //avoid infite loop
+			// observer
+			for (std::list<Continuous*>::iterator observerIter = this->continuousList.begin(); observerIter != this->continuousList.end(); ++observerIter) {
+				(*observerIter)->notifyValidState();
+			}
+
+			//make an integration step
+			solver->makeStep(diffTime);
+			diffTime += solver->getStepLength();
+			//test state events
+			for (iter = this->stateEvents.begin(); iter != this->stateEvents.end(); iter++) {
+				if ((*iter)->condition(getActualInternalTime())) {
+					//search point of change and trigger action
+					searchStateEvent(old_diffTime, old_variable_values);
+					//stop integration
+					break;
+				}
+			}
+			//init for next step of while loop
+			old_diffTime = diffTime;
+			for (lv = 0; lv < variablesCount; lv++)
+				old_variable_values[lv] = variables->getVariable(lv);
+
+			if (workingMode == stepwise) break;
+		}
+		solver->setStepLength(solver->minStep, old_maxStep); //correct stepping limits to old
+		if (testStateEvents) {
+			delete[] old_variable_values;
+		}
+
+		ODEMX_TRACE << log( "end integrate" ).scope( typeid(Monitor) );
+
+		// observer
+		ODEMX_OBS(MonitorObserver, EndIntegrate(this));
+
+	} else {
+		//todo throw exception no solver assigned
+	}
+}
+
+void Monitor::integrateUntil(SimTime time) {
+
+	if( getProcessState() != Process::CURRENT )
+	{
+		error << log( "Monitor::integrateUntil(): object is not the current process" )
+				.scope( typeid(Monitor) );
+	}
+
+	if (solver) {
+		double expectedDiff = (double)(time - internalTime);
+		if (changed == true) {
+			solver->init();
+			changed = false;
+		}
+
+		ODEMX_TRACE << log( "begin integrate until" ).scope( typeid(Monitor) );
+
+		// observer
+		ODEMX_OBS(MonitorObserver, BeginIntegrateUntil(this));
+
+		bool testStateEvents = !stateEvents.empty(); //only to testing if necessary
+		double old_diffTime, *old_variable_values, old_maxStep = solver->maxStep;
+		int lv; //loop variable
+		std::list<StateEvent*>::iterator iter;
+		if (testStateEvents) {
+			//init for first step of while loop
+			old_diffTime = diffTime;
+			old_variable_values = new double[ variablesCount ];
+			for (lv = 0; lv < variablesCount; lv++)
+				old_variable_values[lv] = variables->getVariable(lv);
+		}
+
+		while (diffTime <= expectedDiff) {
+			if (expectedDiff - diffTime <= solver->maxStep) { //make sure intergation does not exceed the limit
+				solver->setStepLength(solver->minStep, expectedDiff - diffTime);
+			}
+
+			// observer
+			for (std::list<Continuous*>::iterator observerIter = this->continuousList.begin(); observerIter != this->continuousList.end(); ++observerIter) {
+				(*observerIter)->notifyValidState();
+			}
+
+			//make an integration step
+			solver->makeStep(diffTime);
+			diffTime += solver->getStepLength();
+			if (testStateEvents) {
+				//test state events
+				for (iter = this->stateEvents.begin(); iter != this->stateEvents.end(); iter++) {
+					if ((*iter)->condition(getActualInternalTime())) {
+						//search point of change and trigger action
+						searchStateEvent(old_diffTime, old_variable_values);
+						//stop integration
+						break;
+					}
+				}
+				//init for next step of while loop
+				old_diffTime = diffTime;
+				for (lv = 0; lv < variablesCount; lv++)
+					old_variable_values[lv] = variables->getVariable(lv);
+			}
+			if (workingMode == stepwise) break;
+		}
+		solver->setStepLength(solver->minStep, old_maxStep); //correct stepping limits to old
+		if (testStateEvents) {
+			delete[] old_variable_values;
+		}
+
+		ODEMX_TRACE << log( "end integrate until" ).scope( typeid(Monitor) );
+
+		// observer
+		ODEMX_OBS(MonitorObserver, EndIntegrateUntil(this));
+
+	} else {
+		//todo throw exception no solver assigned
+	}
+}
+
+//------------------------------------------------------------------------------------------search occurance of StateEvents
+void Monitor::searchStateEvent(double old_diffTime, double *old_variable_values) {
+	double left = old_diffTime; //left time bound
+	double right = diffTime; //right time bound
+	double precision = solver->minStep; //determines how precise the search should be
+	double half = (right - left) / 2;
+	bool isLeft; //is true if at observed time at least one condition is true
+	std::list<StateEvent*>::iterator iter;
+	int lv; // loop variable
+	//search time of first StateEvent
+	switch (searchMode) {
+		case direct: {
+			while (right-left >= precision) {
+				for (lv = 0; lv < variablesCount; lv++) //set initial condition for new shorter step at left
+					variables->setVariable(lv, old_variable_values[lv]);
+				solver->setStepLength(half, half); //set stepLength to be half
+				//errorLimit is proven by greater step done before this function is called
+				solver->makeStep(left);
+				//check conditions
+				isLeft = false;
+				for (iter = this->stateEvents.begin(); iter != this->stateEvents.end(); iter++) {
+					if ((*iter)->condition((SimTime)(internalTime + left + half)))
+						isLeft = true;
+				}
+				//adapt search intervall
+				if (isLeft == true) {
+					right = left + half;
+				} else {
+					left += half;
+					for (lv = 0; lv < variablesCount; lv++)
+						old_variable_values[lv] = variables->getVariable(lv);
+				}
+				half = (right - left) / 2;
+			}
+			//correct diffTime
+			diffTime = right;
+		} break;
+		case linearization:
+		default: {
+			double *right_values = new double[ variablesCount ];
+			for (lv = 0; lv < variablesCount; lv++)
+				right_values[lv] = variables->getVariable(lv);
+			while (right-left >= precision) {
+				for (lv = 0; lv < variablesCount; lv++) { //set linear interpolation value at half
+					variables->setVariable(lv, (old_variable_values[lv] + right_values[lv]) / 2);
+				}
+				//check conditions
+				isLeft = false;
+				for (iter = this->stateEvents.begin(); iter != this->stateEvents.end(); iter++) {
+					if ((*iter)->condition((SimTime)(internalTime + left + half)))
+						 isLeft = true;
+				}
+				//adapt search intervall
+				if (isLeft == true) {
+					right = left + half;
+					for (lv = 0; lv < variablesCount; lv++)
+						right_values[lv] = variables->getVariable(lv);
+				} else {
+					left += half;
+					for (lv = 0; lv < variablesCount; lv++)
+						old_variable_values[lv] = variables->getVariable(lv);
+				}
+				half = (right - left) / 2;
+			}
+			delete[] right_values;
+			//correct diffTime
+			diffTime = right;
+		}
+	}
+	//trigger events
+	for (iter = this->stateEvents.begin(); iter != this->stateEvents.end(); iter++) {
+		if ((*iter)->condition(getActualInternalTime())) {
+			(*iter)->action();
+			removeStateEvent((*iter));
+		}
+	}
+}
+
+//-------------------------------------------------------------------------------------------------others
+void Monitor::setSearchMode(SearchModes mode) {
+	searchMode = mode;
+}
+
+void Monitor::setChanged() {
+	changed = true;
+
+	ODEMX_TRACE << log( "setChanged: system changed" ).scope( typeid(Monitor) );
+
+	// observer
+	ODEMX_OBS(MonitorObserver, SetChanged(this));
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
diff --git a/odemx-lite/src/base/continuous/ODEObject.cpp b/odemx-lite/src/base/continuous/ODEObject.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8ddc31e32765f78f07e9f8490ca584e9dc60a749
--- /dev/null
+++ b/odemx-lite/src/base/continuous/ODEObject.cpp
@@ -0,0 +1,83 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file ODEObject.cpp
+
+ \author Michael Fiedler
+
+ \date created at 2009/01/02
+
+ \brief Implementation of classes in ODEObject.h
+
+ \sa ODEObject.h
+
+ \since 3.0
+ */
+
+#include <odemx/base/continuous/ODEObject.h>
+
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <odemx/base/continuous/Continuous.h>
+#include <odemx/base/continuous/JacobiMatrix.h>
+#include <odemx/base/continuous/DfDt.h>
+
+using namespace odemx::base;
+using namespace odemx::base::continuous;
+using namespace std;
+
+//--------------------------------------------------------------handle corresponding Continuous instance
+void ODEObject::setContinuous(Continuous *continuous) {
+	if (this->continuous != 0) { //remove from old
+		this->continuous->removeODE(this); //all actions are implemented in Continuous
+	}
+	if (continuous != 0) { //add to new
+		continuous->addODE(this); //all actions are implemented in Continuous
+	}
+}
+
+Continuous* ODEObject::getContinuous() {
+	return continuous;
+}
+
+void ODEObject::derivates(SimTime time)
+{
+	derivatives_(time);
+}
+
+void ODEObject::jacobi(SimTime time)
+{
+	jacobi_(time);
+}
+
+//------------------------------------------------------------------------------NotAssignedException
+NotAssignedException::NotAssignedException(const char* missingObject, const char* object) {
+	this->msg = "This ";
+	this->msg += object;
+	this->msg += "-Object has no ";
+	this->msg += missingObject;
+	this->msg += " assigned.";
+}
+
+NotAssignedException::~NotAssignedException() throw() {}
+
+const char* NotAssignedException::what() const throw() {
+	return this->msg.c_str();
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
diff --git a/odemx-lite/src/base/continuous/ODESolver.cpp b/odemx-lite/src/base/continuous/ODESolver.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8192dda683fe86a05b43669fdc57cc91a804d28d
--- /dev/null
+++ b/odemx-lite/src/base/continuous/ODESolver.cpp
@@ -0,0 +1,102 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file ODESolver.cpp
+
+	\author Michael Fiedler
+
+	\date created at 2009/01/02
+
+	\brief Implementation of class ODESolver
+
+	\sa ODESolver.h
+
+	\since 3.0
+*/
+
+#include <odemx/base/continuous/ODESolver.h>
+
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <odemx/base/continuous/Monitor.h>
+
+using namespace odemx::base;
+using namespace odemx::base::continuous;
+using namespace std;
+
+//--------------------------------------------------------------------dConstruction
+ODESolver::ODESolver(Simulation& sim) : Producer(sim, "ODESolver") {
+	//nothing todo
+}
+//--------------------------------------------------------------------destruction
+ODESolver::~ODESolver() {
+	//nothing todo
+}
+
+//--------------------------------------------------------evaluate monitor system
+//this is to pass access to these function to subclasses
+void ODESolver::evalF(double time) {
+	monitor->evalF(time);
+}
+
+void ODESolver::evalJacobian(double time) {
+	monitor->evalJacobian(time);
+}
+
+//-------------------------------------------------------handle assigned monitor
+void ODESolver::setMonitor(Monitor* monitor) {
+	if (monitor) {
+		monitor->setODESolver(this);
+	}
+}
+
+Monitor* ODESolver::getMonitor() {
+	return monitor;
+}
+
+//------------------------------------------------------get variables of monitor
+VariableContainer* ODESolver::getVariableContainerOfMonitor() {
+	return monitor->variables;
+}
+
+//--------------------------------------------------------integration Parameters
+void ODESolver::setErrorLimit(double maxError) {
+	if (maxError > 0) {
+		errorLimit = maxError;
+	}
+}
+
+double ODESolver::getErrorLimit() {
+	return this->errorLimit;
+}
+
+void ODESolver::setErrorType(ErrorType type) {
+	errorType = type;
+}
+
+void ODESolver::setStepLength(double min, double max) {
+	if (min > 0) minStep = min;
+	if (max > 0) maxStep = max;
+	if (maxStep < minStep) maxStep = minStep;
+}
+
+double ODESolver::getStepLength() {
+	return lastStep;
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
diff --git a/odemx-lite/src/base/continuous/Rate.cpp b/odemx-lite/src/base/continuous/Rate.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d0dc2e49ac4e9476b1c2182c01cf5f9d8c8cbd94
--- /dev/null
+++ b/odemx-lite/src/base/continuous/Rate.cpp
@@ -0,0 +1,95 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Rate.cpp
+
+	\author Sascha Qualitz
+
+	 \date created at 2009/10/26
+
+	 \brief Implementation of Rate
+
+	\sa Rate.h
+
+	\since 3.0
+*/
+
+#include <odemx/base/continuous/Rate.h>
+
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <odemx/base/continuous/State.h>
+#include <odemx/base/continuous/Continuous.h>
+#include <odemx/base/continuous/Monitor.h>
+
+using namespace odemx::base;
+using namespace odemx::base::continuous;
+using namespace std;
+
+Rate::Rate()
+:	continuous(0),
+	index_(0)
+{}
+
+Rate::Rate(Continuous* continuous)
+:	continuous(continuous),
+	index_(0)
+{}
+
+Rate::~Rate() {
+	// nothing todo!!
+}
+
+void Rate::setContinuous(Continuous* continuous) {
+	if (continuous != 0) {
+		this->continuous = continuous;
+	} else
+		throw new NotAssignedException("Continuous", "Rate");
+}
+
+void Rate::setValue(double value) {
+	if (continuous != 0) {
+		continuous->setDerivative(index_, value);
+	} else
+		throw new NotAssignedException("Continuous", "Rate");
+}
+
+double Rate::getValue() {
+	if (continuous != 0)
+		return continuous->getDerivative(index_);
+	
+	throw new NotAssignedException("Continuous", "Rate");
+}
+
+Rate& Rate::operator =(const double value) {
+	setValue(value);
+	return *this;
+}
+
+Rate& Rate::operator [](const unsigned i) {
+	if (continuous != 0) {
+		if(i > continuous->getDimension()-1)
+			throw std::out_of_range("The index in an object of type Rate is out of bounds");
+		index_ = i;
+
+		return *this;
+	} else
+		throw new NotAssignedException("Continuous", "Rate");
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
diff --git a/odemx-lite/src/base/continuous/State.cpp b/odemx-lite/src/base/continuous/State.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e7790b81b55a6db52e27c8a8bbbca211bcc479cd
--- /dev/null
+++ b/odemx-lite/src/base/continuous/State.cpp
@@ -0,0 +1,95 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file State.cpp
+
+	\author Sascha Qualitz
+
+	 \date created at 2009/10/26
+
+	 \brief Implementation of State
+
+	\sa State.h
+
+	\since 3.0
+*/
+
+#include <odemx/base/continuous/State.h>
+
+#ifdef ODEMX_USE_CONTINUOUS
+
+#include <odemx/base/continuous/Continuous.h>
+#include <odemx/base/continuous/Monitor.h>
+#include <odemx/base/continuous/ODEObject.h>
+
+using namespace odemx::base;
+using namespace odemx::base::continuous;
+using namespace std;
+
+State::State()
+:	continuous(0),
+	index_(0)
+{}
+
+State::State(Continuous* continuous)
+:	continuous(continuous),
+	index_(0)
+{}
+
+State::~State() {
+	// nothing todo!!
+}
+
+void State::setContinuous(Continuous* continuous) {
+	if (continuous != 0) {
+		this->continuous = continuous;
+	} else
+		throw new NotAssignedException("Continuous", "State");
+}
+
+State& State::operator =(const double value) {
+	setValue(value);
+	return *this;
+}
+
+double State::getValue() const{
+	if (continuous != 0) {
+		return continuous->getValueForDerivative(index_);
+	} else
+		throw new NotAssignedException("Continuous", "State");
+}
+
+void State::setValue(double value) {
+	if (continuous != 0) {
+		continuous->setValue(index_, value);
+	} else
+		throw new NotAssignedException("Continuous", "State");
+}
+
+State& State::operator [](const unsigned i) {
+	if (continuous != 0) {
+		if(i > continuous->getDimension()-1)
+			throw std::out_of_range("The index in an object of type State is out of bounds");
+		index_ = i;
+
+		return *this;
+	} else
+		throw new NotAssignedException("Continuous", "State");
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
diff --git a/odemx-lite/src/base/continuous/StateEvent.cpp b/odemx-lite/src/base/continuous/StateEvent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cc6e3221633f4808bb518b2eca276364117ab04c
--- /dev/null
+++ b/odemx-lite/src/base/continuous/StateEvent.cpp
@@ -0,0 +1,53 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file StateEvent.cpp
+ 
+ \author Michael Fiedler
+ 
+ \date created at 2009/01/02
+ 
+ \brief Implementation of class StateEvent
+ 
+ \sa StateEvent.h
+ 
+ \since 3.0
+ */
+
+#include <odemx/base/continuous/StateEvent.h>
+
+#ifdef ODEMX_USE_CONTINUOUS
+
+using namespace odemx::base;
+using namespace odemx::base::continuous;
+using namespace std;
+
+StateEvent::~StateEvent() {
+
+}
+
+//-----------------------------------------------------------handle assigned monitor
+void StateEvent::setMonitor(Monitor *monitor) {
+	monitor->addStateEvent(this);
+}
+
+Monitor* StateEvent::getMonitor() {
+	return monitor;
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
diff --git a/odemx-lite/src/base/continuous/VariableContainer.cpp b/odemx-lite/src/base/continuous/VariableContainer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f481bd4cc87470ba40068434d470d6deb387dea7
--- /dev/null
+++ b/odemx-lite/src/base/continuous/VariableContainer.cpp
@@ -0,0 +1,44 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\fileVariableContainer.cpp
+ 
+ \author Michael Fiedler
+ 
+ \date created at 2009/01/02
+ 
+ \brief Implementation of class VariableContainer
+ 
+ \sa VariableContainer.h
+ 
+ \since 3.0
+ */
+
+#include <odemx/base/continuous/VariableContainer.h>
+
+#ifdef ODEMX_USE_CONTINUOUS
+
+using namespace odemx::base;
+using namespace odemx::base::continuous;
+using namespace std;
+
+VariableContainer::~VariableContainer() {
+	//nothing todo
+}
+
+#endif /* ODEMX_USE_CONTINUOUS */
diff --git a/odemx-lite/src/base/control/ControlBase.cpp b/odemx-lite/src/base/control/ControlBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e08ffe5141f8a55f735d9a060de192849a66d280
--- /dev/null
+++ b/odemx-lite/src/base/control/ControlBase.cpp
@@ -0,0 +1,44 @@
+#include <odemx/base/control/ControlBase.h>
+#include <odemx/base/Process.h>
+#include <iostream>
+
+
+namespace odemx {
+namespace base {
+
+void ControlBase::signal()
+{
+	for(auto process: waitingProcesses_)
+	{
+		process->hold();
+	}
+}
+
+synchronization::IMemory::Type ControlBase::getMemoryType() const
+{
+	return CONTROL;
+}
+
+bool ControlBase::isAvailable()
+{
+	return false;
+}
+
+void ControlBase::alert()
+{}
+
+bool ControlBase::remember(base::Sched* newObject)
+{
+	return false;
+}
+
+bool ControlBase::forget(base::Sched* rememberedObject)
+{
+	return false;
+}
+
+void ControlBase::eraseMemory()
+{}
+
+}
+}
diff --git a/odemx-lite/src/coroutine/Coroutine.cpp b/odemx-lite/src/coroutine/Coroutine.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..65af561bfc2c294ea9055c7b726133f7f9ca1948
--- /dev/null
+++ b/odemx-lite/src/coroutine/Coroutine.cpp
@@ -0,0 +1,324 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Coroutine.cpp
+ * @author Ralf Gerstenberger
+ * @date created at 2002/01/22
+ * @brief Implementation of odemx::coroutine::Coroutine
+ * @sa Coroutine.h
+ * @since 1.0
+ */
+
+#if defined(_MSC_VER) && defined(ODEMX_USE_SETJUMP)
+#pragma warning(disable : 4530)
+#endif
+
+#include <odemx/coroutine/Coroutine.h>
+
+#include <iostream>
+#include <exception>
+#include <memory.h> // memcpy
+#include <stdexcept>
+
+namespace odemx {
+namespace coroutine {
+
+//------------------------------------------------------construction/destruction
+
+Coroutine::Coroutine( CoroutineContext* c, CoroutineObserver* o )
+:	data::Observable< CoroutineObserver >( o )
+,	context( c )
+,	parent( 0 )
+,	caller( 0 )
+,	state( CREATED )
+{
+	// check for context existence: if 0, set default
+	if( ! context )
+	{
+		context = getDefaultContext();
+	}
+	// register coroutine with context
+	getContext()->beginCoroutine( this );
+
+	ODEMX_OBS(CoroutineObserver, Create(this));
+
+	myFiber = fiber = 0;
+}
+
+Coroutine::~Coroutine()
+{
+	if( context->getActiveCoroutine() == this )
+	{
+		std::cerr << "ODEMx ERROR: Coroutine::~Coroutine():"
+				  << "destruction of active coroutine"
+				  << std::endl;
+	}
+
+	// clear Coroutine if necessary
+	if( getState() != TERMINATED )
+	{
+		clear();
+	}
+
+	ODEMX_OBS(CoroutineObserver, Destroy(this));
+
+  freeStack ();
+}
+
+//----------------------------------------------------------------------clean up
+
+
+void Coroutine::freeStack() {
+  if( fiber != 0 )
+  {
+    DeleteFiber( fiber );
+    fiber = 0;
+  }
+}
+
+void Coroutine::clear()
+{
+	if( state == TERMINATED )
+	{
+		return;
+	}
+	ODEMX_OBS(CoroutineObserver, Clear(this));
+
+	setState( TERMINATED );
+
+	// leave context
+	getContext()->endCoroutine( this );
+}
+
+//----------------------------------------------------------------initialization
+
+void Coroutine::initialize()
+{
+	if( state != CREATED )
+	{
+		throw std::runtime_error( "Coroutine::initialize(): internal error, "
+				"coroutine is already initialized" );
+	}
+
+#ifdef _WIN32
+	myFiber = fiber = CreateFiber( 0, (LPFIBER_START_ROUTINE)ExecFiber, this );
+#else
+	// TODO: fix this -> int cast with map index
+	myFiber = fiber = CreateFiber( 0, (void(*)(void*))ExecFiber, this );
+#endif
+
+	if( fiber == 0 )
+	{
+		throw std::runtime_error( "Coroutine::initialize(): failed to create "
+				"fiber, probably due to memory exhaustion" );
+	}
+
+	ODEMX_OBS(CoroutineObserver, Initialize(this));
+
+	setState( RUNNABLE );
+}
+
+//-----------------------------------------------------------------------getters
+
+CoroutineContext* Coroutine::getContext()
+{
+	return context;
+}
+
+Coroutine* Coroutine::getParent()
+{
+	return parent;
+}
+
+Coroutine* Coroutine::getCaller()
+{
+	return caller;
+}
+
+//-------------------------------------------------switch to coroutine execution
+
+void Coroutine::switchTo()
+{
+	if( state == CREATED )
+	{
+		// store return point
+		parent = context->getActiveCoroutine();
+		initialize();
+	}
+	caller = context->getActiveCoroutine();
+
+	if( caller != 0 )
+	{
+		ODEMX_OBS(CoroutineObserver, SwitchTo(this, caller))
+	}
+	else
+	{
+		ODEMX_OBS(CoroutineObserver, SwitchTo(this, context));
+	}
+
+	if( state != RUNNABLE )
+	{
+		std::cerr << "ODEMx WARNING: Coroutine::switchTo(): switch to coroutine "
+				  << "failed: Coroutine is not RUNNABLE, continue in parent"
+				  << std::endl;
+
+		if( parent != 0 )
+		{
+			parent->switchTo();
+		}
+		else
+		{
+			getContext()->switchTo();
+		}
+	}
+
+	if( context->getActiveCoroutine() == this )
+	{
+		return;
+	}
+
+	Coroutine* oldActive = context->setActiveCoroutine( this );
+
+	if( oldActive != 0 )
+	{
+		// switchTo from Coroutine;
+		// Coroutine has to save 'switch in' point.
+		oldActive->saveFiber();
+	}
+	else
+	{
+		// switchTo from context;
+		// CoroutineContext has to save 'switch out' point.
+		context->saveFiber();
+	}
+
+	FiberSwitch( fiber );
+}
+
+void Coroutine::operator()()
+{
+	switchTo();
+}
+
+void Coroutine::yield()
+{
+	if( parent != 0 )
+	{
+		parent->switchTo();
+	}
+	else
+	{
+		context->switchTo();
+	}
+}
+
+
+//-----------------------------------------------------------------fiber storage
+
+void Coroutine::saveFiber()
+{
+	// get active fiber
+	fiber = GetCurrentFiber();
+
+	if( fiber == 0 )
+	{
+		throw std::runtime_error(
+				"Coroutine::saveFiber(): could not retrieve active fiber" );
+	}
+}
+
+//---------------------------------------------------------------fiber execution
+
+VOID CALLBACK ExecFiber( PVOID param )
+{
+
+#ifdef _WIN32
+	Coroutine *p = static_cast<Coroutine*>( param );
+#else
+	void* theCoroutine = ucFiber::getCoroutine(param);
+	Coroutine* p = static_cast<Coroutine*>(theCoroutine);
+#endif
+
+	try
+	{
+		// start execution
+		p->run();
+	}
+	catch( const std::exception& )
+	{
+		throw; // rethrow anything that is derived from std::exception
+	}
+	catch(...)
+	{
+		// throw a real exception for whatever arrives here
+		throw std::runtime_error(
+				"ExecFiber(): non-exception object thrown in "
+				"coroutine: cannot say what()" );
+	}
+
+	// execution finished
+	p->clear();
+
+	// return
+	if( p->parent != 0 )
+	{
+		p->parent->switchTo();
+	}
+	else
+	{
+		p->context->switchTo();
+	}
+
+	// This point should never be reached.
+	throw std::runtime_error(
+			"ExecFiber(): internal error, return from coroutine failed" );
+}
+
+/**
+	\internal
+	\note FiberSwitch is a 'Work around'.
+
+	In Visual C++ 6.0, when running a debug session,
+	SwitchToFiber() does not restore EIP-register (Instruction pointer). [Maybe correct]
+	FiberSwitch() ensures, that all calls to SwitchToFiber()
+	come from the same instruction point in code.
+*/
+void FiberSwitch( LPVOID fiber )
+{
+	SwitchToFiber( fiber );
+}
+
+//----------------------------------------------------------------state handling
+
+Coroutine::State Coroutine::setState( Coroutine::State newState )
+{
+	Coroutine::State oldState = state;
+	state = newState;
+
+	ODEMX_OBS_ATTR(CoroutineObserver, State, oldState, newState);
+
+	return oldState;
+}
+
+Coroutine::State Coroutine::getState() const
+{
+	return state;
+}
+
+} } // namespace odemx::coroutine
diff --git a/odemx-lite/src/coroutine/CoroutineContext.cpp b/odemx-lite/src/coroutine/CoroutineContext.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f363feea1cb842cdcd652ccbaf3e6e1f8dd44a42
--- /dev/null
+++ b/odemx-lite/src/coroutine/CoroutineContext.cpp
@@ -0,0 +1,156 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file CoroutineContext.cpp
+ * @author Ralf Gerstenberger
+ * @date created at 2002/02/04
+ * @brief Implementation of odemx::coroutine::CoroutineContext and DefaultContextutine
+ * @sa CoroutineContext.h
+ * @since 1.0
+ */
+
+#if defined(_MSC_VER) && defined(ODEMX_USE_SETJUMP)
+#pragma warning(disable : 4530)
+#endif
+
+#include <odemx/coroutine/CoroutineContext.h>
+#include <odemx/coroutine/Coroutine.h>
+
+#include <memory.h> // memcpy
+#include <stdexcept>
+
+namespace odemx {
+namespace coroutine {
+
+//------------------------------------------------------construction/destruction
+
+CoroutineContext::CoroutineContext( CoroutineContextObserver* o )
+:	data::Observable< CoroutineContextObserver >( o )
+,	activeCoroutine( 0 )
+,	numberOfCoroutines( 0 )
+{
+	ODEMX_OBS(CoroutineContextObserver, Create(this));
+
+	fiber = 0;
+}
+
+CoroutineContext::~CoroutineContext()
+{
+	ODEMX_OBS(CoroutineContextObserver, Destroy(this));
+
+	// check number of coroutines ?!?
+	// when the context is destroyed, the program should be finished anyway...
+
+}
+
+//-------------------------------------------------------------switch to context
+
+void CoroutineContext::switchTo()
+{
+	ODEMX_OBS(CoroutineContextObserver, SwitchTo(this, getActiveCoroutine()));
+
+	if( getActiveCoroutine() == 0 )
+	{
+		return; // ignore self-switch
+	}
+
+	setActiveCoroutine( 0 );
+	FiberSwitch( fiber );
+}
+
+//-----------------------------------------------------------------------getters
+
+Coroutine* CoroutineContext::getActiveCoroutine()
+{
+	return activeCoroutine;
+}
+
+unsigned int CoroutineContext::getNumberOfCoroutines()
+{
+	return numberOfCoroutines;
+}
+
+//--------------------------------------------------------------active coroutine
+
+Coroutine* CoroutineContext::setActiveCoroutine( Coroutine* c )
+{
+	Coroutine* oldActiveCoroutine = activeCoroutine;
+	activeCoroutine = c;
+
+	ODEMX_OBS_ATTR(CoroutineContextObserver, ActiveCoroutine,
+			oldActiveCoroutine, activeCoroutine);
+
+	return oldActiveCoroutine;
+}
+
+//---------------------------------------------------coroutine (de-)registration
+
+void CoroutineContext::beginCoroutine( Coroutine* cr )
+{
+	assert( cr->getContext() == this );
+	++numberOfCoroutines;
+}
+
+void CoroutineContext::endCoroutine( Coroutine* cr )
+{
+	assert( cr->getContext() == this );
+	--numberOfCoroutines;
+}
+
+//-----------------------------------------------------------------fiber storage
+
+void CoroutineContext::saveFiber()
+{
+	// Initialize Fibers
+	if( initFibers )
+	{
+		ConvertThreadToFiber( 0 );
+		initFibers = false;
+	}
+
+	// get context
+	fiber = GetCurrentFiber();
+
+	if( fiber == 0 )
+	{
+		throw std::runtime_error(
+				"CoroutineContext::saveFiber(): could not retrieve active fiber" );
+	}
+}
+
+bool CoroutineContext::initFibers = true;
+
+//---------------------------------------------------------------default context
+
+/** \brief Get a default coroutine context
+		\return pointer to the DefaultContext
+		\relates DefaultContext
+*/
+CoroutineContext* getDefaultContext()
+{
+	static DefaultContext defaultContext;
+	return &defaultContext;
+}
+
+DefaultContext::DefaultContext()
+:	CoroutineContext()
+{
+}
+
+} } // namespace odemx::base
diff --git a/odemx-lite/src/coroutine/ucFiber.cpp b/odemx-lite/src/coroutine/ucFiber.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4a2ec924e3dd4ea2f42cc586676f0d561a5dc099
--- /dev/null
+++ b/odemx-lite/src/coroutine/ucFiber.cpp
@@ -0,0 +1,128 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ucFiber.cpp
+ * @author Klaus Ahrens
+ * @date created at 2009/03/16
+ * @brief Implementation of class ucFiber
+ * @sa ucFiber.h
+ * @since 3.0
+ */
+
+#ifndef _WIN32
+
+#include <odemx/coroutine/ucFiber.h>
+#include <cstdio>
+#include <cassert>
+
+namespace odemx {
+namespace coroutine {
+
+std::map<int, void*> ucFiber::allFibers;
+int ucFiber::nFibers = 0;
+
+ucFiber::ucFiber(void* param):
+	uc_(new ucontext_t),
+	callStack_(0),
+	stackState_(mainStack)
+{
+	getcontext(uc_);
+}
+
+ucFiber::ucFiber(std::size_t stacksize, void (*start)(void*), void* param):
+	uc_(new ucontext_t),
+	callStack_(0),
+	stackState_(noStack)
+{
+	getcontext(uc_);
+
+	uc_->uc_stack.ss_flags = 0;
+	if (!stacksize) stacksize = ODEMX_DEFAULT_STACK_SIZE;
+	uc_->uc_stack.ss_size  = stacksize;
+	callStack_ = std::malloc(stacksize);
+	uc_->uc_stack.ss_sp = callStack_;
+
+	if (uc_->uc_stack.ss_sp) {
+		stackState_ = okStack;
+		tos = uc_->uc_stack.ss_sp;
+		allFibers[nFibers]=param;
+		makecontext(uc_, (void(*)())start, 1, nFibers++);
+	}
+}
+
+void* ucFiber::getCoroutine(int nr) {
+	return allFibers[nr];
+}
+
+ucFiber::~ucFiber()
+{
+	// assert(uc_->uc_stack.ss_sp == callStack_);
+	// fails because ss_sp is the stack pointer
+	// points to the current position of the call stack
+
+	// if (stackState_== okStack) std::free(uc_->uc_stack.ss_sp);
+
+	//delete the original stack
+	if (stackState_== okStack) std::free(callStack_);
+
+	delete uc_;
+}
+
+ucFiber* ucFiber::current = 0;
+
+void* ucFiber::ConvertThreadToFiber(void* param) {
+	return current = new ucFiber(param);
+}
+
+void* ucFiber::GetCurrentFiber() {
+		return current;
+}
+
+void* ucFiber::CreateFiber(std::size_t stacksize, void (*start)(void*), void* param) {
+	ucFiber* fiber = new ucFiber(stacksize, start, param);
+	if (fiber->stackState_ == noStack)
+		{ delete fiber;	return 0; } // error, must be handled by caller (Coroutine)
+	else
+		return fiber;
+}
+
+void  ucFiber::DeleteFiber(void* fiber) {
+	delete reinterpret_cast<ucFiber*>(fiber);
+}
+
+void  ucFiber::SwitchToFiber(void* fiber) {
+	ucFiber* from = current;
+	ucFiber* to   = reinterpret_cast<ucFiber*>(fiber);
+
+	current = to;
+
+	swapcontext(from->uc_, to->uc_);
+}
+
+void  ucFiber::stackcheck()  {
+	int probe;
+	char* stackAt = (char*) &probe;
+	ucFiber* f = reinterpret_cast<ucFiber*>(current);
+
+	if ((stackAt - (char*)f->tos) <1024) throw "Fiber: Stack Overflow ahead ...";
+}
+
+} } // namespace odemx::coroutine
+
+#endif /* _WIN32 */
diff --git a/odemx-lite/src/data/LoggingManager.cpp b/odemx-lite/src/data/LoggingManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..56777a587c68ba060d88a51aa3d58d28d0b26ee5
--- /dev/null
+++ b/odemx-lite/src/data/LoggingManager.cpp
@@ -0,0 +1,216 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file LoggingManager.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/03/18
+ * @brief Implementation of odemx::data::LoggingManager
+ * @sa LoggingManager.h
+ * @since 3.0
+ */
+
+#include <odemx/data/LoggingManager.h>
+#include <odemx/base/Simulation.h>
+#include <odemx/data/Producer.h>
+#include <odemx/data/buffer/StatisticsBuffer.h>
+//#include <odemx/data/output/DatabaseWriter.h>
+#include <odemx/data/output/ErrorWriter.h>
+#include <odemx/data/output/OStreamWriter.h>
+//#include <odemx/data/output/XmlWriter.h>
+#include <odemx/data/output/OStreamReport.h>
+//#include <odemx/data/output/XmlReport.h>
+#include <odemx/util/Exceptions.h>
+
+#include <iostream> // std::cout for default logging
+
+namespace odemx {
+namespace data {
+
+//------------------------------------------------------------------local struct
+
+typedef std::shared_ptr< Log::Consumer<SimRecord> > ConsumerPtr;
+
+struct DefaultLogConfig
+{
+	ConsumerPtr writer;
+	std::shared_ptr< data::buffer::StatisticsBuffer > statsBuffer;
+};
+
+//------------------------------------------------------construction/destruction
+
+LoggingManager::LoggingManager()
+:	Log::ChannelManager< SimRecord >()
+,	defaultLogConfig_( nullptr )
+{
+	initErrorLogging();
+}
+
+LoggingManager::LoggingManager( const std::string& defLabel,
+		const char defSpace )
+:	Log::ChannelManager< SimRecord >( defLabel, defSpace )
+,	defaultLogConfig_( nullptr )
+{
+	initErrorLogging();
+}
+
+LoggingManager::~LoggingManager()
+{
+}
+
+//---------------------------------------------------------------default logging
+
+void LoggingManager::initErrorLogging()
+{
+	using namespace std;
+	using namespace output;
+
+	// we don't keep a pointer to the error writer as member
+	// because it is not intended to be accessed by anyone
+	shared_ptr< ErrorWriter > cerrWriter = ErrorWriter::create();
+	getChannel( channel_id::warning )->addConsumer( cerrWriter );
+	getChannel( channel_id::error )->addConsumer( cerrWriter );
+	getChannel( channel_id::fatal )->addConsumer( cerrWriter );
+}
+
+bool LoggingManager::enableDefaultLogging( output::Type type,
+		const std::string& location )
+{
+	using namespace buffer;
+	using namespace output;
+
+	// only initialize once
+	if( ! defaultLogConfig_.get() )
+	{
+		// make sure the channels are initialized
+		// error channels are active due to default error logging
+		getChannel( channel_id::trace );
+		getChannel( channel_id::debug );
+		getChannel( channel_id::info );
+		getChannel( channel_id::statistics );
+
+		// create log config to keep a pointer to the statistics buffer
+		std::unique_ptr< DefaultLogConfig > tmpLogConfig( new DefaultLogConfig );
+
+		switch( type )
+		{
+		case DATABASE:
+//			if( location.empty() )
+//			{
+//				throw DataOutputException( "LogginManager::enableDefaultLogging():"
+//						"database connection string empty" );
+//			}
+//			tmpLogConfig->writer = DatabaseWriter::create( location );
+			break;
+		case STDOUT:
+			tmpLogConfig->writer = OStreamWriter::create( std::cout );
+			break;
+		case XML:
+//			if( location.empty() )
+//			{
+//				throw DataOutputException( "LoggingManager::enableDefaultLogging():"
+//						"XML base file name empty" );
+//			}
+//			tmpLogConfig->writer = XmlWriter::create( location, 1000 );
+			break;
+		default:
+			break;
+		}
+
+		defaultLogConfig_ = std::move(tmpLogConfig);
+
+		// add the default output writer to all log channels
+		addConsumer( defaultLogConfig_->writer );
+
+		// create the default statistics buffer and add it as consumer
+		defaultLogConfig_->statsBuffer =
+				StatisticsBuffer::create(
+						dynamic_cast< base::Simulation& >( *this ),
+						"Default Statistics Buffer" );
+		addConsumer( channel_id::statistics, defaultLogConfig_->statsBuffer );
+
+		return true;
+	}
+	return false;
+}
+
+bool LoggingManager::disableDefaultLogging()
+{
+	using namespace buffer;
+	using namespace output;
+
+	if( defaultLogConfig_.get() )
+	{
+		removeConsumer( defaultLogConfig_->writer );
+		removeConsumer( data::channel_id::statistics, defaultLogConfig_->statsBuffer );
+		defaultLogConfig_.reset( 0 );
+		return true;
+	}
+	return false;
+}
+
+bool LoggingManager::resetDefaultStatistics( base::SimTime currentTime )
+{
+	// check if default logging has been enabled
+	if( ! defaultLogConfig_.get() )
+	{
+		return false;
+	}
+	// reset the statistics buffer
+	defaultLogConfig_->statsBuffer->reset( currentTime );
+	return true;
+}
+
+bool LoggingManager::reportDefaultStatistics( output::Type type,
+		const std::string& location )
+{
+	using namespace data::output;
+
+	// check if default logging has been enabled
+	if( ! defaultLogConfig_.get() )
+	{
+		return false;
+	}
+
+	std::unique_ptr< Report > report;
+	switch( type )
+	{
+	case STDOUT:
+		report.reset( new OStreamReport( std::cout ) );
+		break;
+	case XML:
+//		if( location.empty() )
+//		{
+//			throw DataOutputException( "LoggingManager::reportDefaultStatistics(): "
+//					"XML file name empty" );
+//		}
+//		report.reset( new XmlReport( location ) );
+		break;
+	case DATABASE:
+//		throw DataOutputException( "LoggingManager::reportDefaultStatistics(): "
+//					"database output not supported" );
+		break;
+	}
+
+	// generate report from the default statistics buffer
+	report->addReportProducer( *defaultLogConfig_->statsBuffer );
+	report->generateReport();
+	return true;
+}
+
+} } // namespace odemx::data
diff --git a/odemx-lite/src/data/ManagedChannels.cpp b/odemx-lite/src/data/ManagedChannels.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3cbcea46ae2d66bf24a97622bf56f74d074c0dc7
--- /dev/null
+++ b/odemx-lite/src/data/ManagedChannels.cpp
@@ -0,0 +1,51 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ManagedChannels.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/09/05
+ * @brief Implementation of function odemx::data::channel_id::toString
+ * @sa ManagedChannels.h
+ * @since 3.0
+ */
+
+#include <odemx/data/ManagedChannels.h>
+
+namespace odemx {
+namespace data {
+namespace channel_id {
+
+const std::string toString( const Log::ChannelId id )
+{
+	using namespace Log::Detail;
+
+	switch( id )
+	{
+	case trace: return "trace";
+	case debug: return "debug";
+	case info: return "info";
+	case warning: return "warning";
+	case error: return "error";
+	case fatal: return "fatal";
+	case statistics: return "statistics";
+	default: return "user-defined";
+	}
+}
+
+} } } // namesapce odemx::data::channel_id
diff --git a/odemx-lite/src/data/Producer.cpp b/odemx-lite/src/data/Producer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..78c413fc007a5f5771a1937b412e239d84cc1717
--- /dev/null
+++ b/odemx-lite/src/data/Producer.cpp
@@ -0,0 +1,124 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Producer.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/03/18
+ * @brief Implementation of class odemx::data::Producer
+ * @sa Producer.h
+ * @since 3.0
+ */
+
+#include <odemx/data/Producer.h>
+#include <odemx/base/DefaultSimulation.h>
+#include <odemx/base/Simulation.h>
+
+namespace odemx {
+namespace data {
+
+//------------------------------------------------------construction/destruction
+
+Producer::Producer( base::Simulation& sim, const Label& label )
+:	ProducerBase( sim, label )
+,	sim_( &sim )
+{
+}
+
+Producer::~Producer()
+{
+}
+
+//----------------------------------------------------------------enable/disable
+
+void Producer::enableLogging()
+{
+	trace = sim_->getChannel( channel_id::trace );
+	debug = sim_->getChannel( channel_id::debug );
+	info = sim_->getChannel( channel_id::info );
+	statistics = sim_->getChannel( channel_id::statistics );
+}
+
+void Producer::disableLogging()
+{
+	trace.reset();
+	debug.reset();
+	info.reset();
+	statistics.reset();
+}
+
+//------------------------------------------------------------object information
+
+const Label& Producer::getLabel() const
+{
+	return getName();
+}
+
+const TypeInfo Producer::getType() const
+{
+	return typeid( *this );
+}
+
+//---------------------------------------------------------------record creation
+
+SimRecord Producer::log( const StringLiteral& text ) const
+{
+	return SimRecord( *sim_, *this, text );
+}
+
+//-----------------------------------------------------------convenience methods
+
+SimRecord Producer::reset() const
+{
+	return log( "reset" );
+}
+
+SimRecord Producer::count( const StringLiteral& name, std::size_t value ) const
+{
+	return log( "count" ).detail( name, value );
+}
+
+//-------------------------------------------------------------simulation access
+
+const base::Simulation& Producer::getSimulation() const
+{
+	return *sim_;
+}
+
+base::Simulation& Producer::getSimulation()
+{
+	return *sim_;
+}
+
+//---------------------------------------------------------------------streaming
+
+std::ostream& operator<<( std::ostream& os, const data::Producer& obj )
+{
+	os << obj.getLabel();
+	return os;
+}
+
+std::ostream& operator<<( std::ostream& os, const data::Producer* ptr )
+{
+	assert( ptr );
+
+	os << ptr->getLabel();
+	return os;
+}
+
+} } // namespace odemx::data
diff --git a/odemx-lite/src/data/Report.cpp b/odemx-lite/src/data/Report.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4d5dbd93f6e2a88b7ecbecedd936035c5a36d600
--- /dev/null
+++ b/odemx-lite/src/data/Report.cpp
@@ -0,0 +1,107 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002 - 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Report.cpp
+ * @author Ralf Gerstenberger
+ * @date created at 2002/06/21
+ * @brief Implementation of class odemx::data::Report
+ * @sa Report.h
+ * @since 1.0
+ */
+
+#include <odemx/data/Report.h>
+#include <odemx/data/ReportProducer.h>
+#include <odemx/util/DeletePtr.h>
+
+#include <cassert>
+#include <algorithm>
+
+namespace odemx {
+namespace data {
+
+Report::~Report()
+{
+	std::for_each( tables_.begin(), tables_.end(), DeletePtr< ReportTable >() );
+}
+
+void Report::addReportProducer( ReportProducer& reporter )
+{
+	producers_.insert( &reporter );
+}
+
+void Report::removeReportProducer( ReportProducer& reporter )
+{
+	producers_.erase( &reporter );
+}
+
+ReportTable& Report::getTable( const std::string& name, const ReportTable::Definition& def )
+{
+	ReportTable* tmp = findTable( name, def );
+
+	if( ! tmp )
+	{
+		tmp = new ReportTable( name, def );
+		tables_.push_back( tmp );
+	}
+	return *tmp;
+}
+
+ReportTable* Report::findTable( const std::string& name, const ReportTable::Definition& def ) const
+{
+	assert( ! name.empty() );
+
+	for( TableVec::const_iterator iter = tables_.begin();
+		iter != tables_.end(); ++iter )
+	{
+		ReportTable* current = *iter;
+
+		// compare table def and name to find a matching table
+		if( current->getDefinition() == def
+			&& current->getLabel() == name )
+		{
+			return current;
+		}
+	}
+	return 0;
+}
+
+
+
+void Report::generateReport()
+{
+	if( producers_.empty() )
+	{
+		return;
+	}
+
+	startProcessing();
+
+	// call all report producers to create and fill their tables
+	for( ReportProducerSet::iterator iter = producers_.begin();
+		iter != producers_.end(); ++iter )
+	{
+		( *iter )->report( *this );
+	}
+
+	processTables();
+
+	endProcessing();
+}
+
+} } // namespace odemx::data
diff --git a/odemx-lite/src/data/ReportProducer.cpp b/odemx-lite/src/data/ReportProducer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..aa26bce477fa760f31b54d12095687588293508f
--- /dev/null
+++ b/odemx-lite/src/data/ReportProducer.cpp
@@ -0,0 +1,48 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002 - 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ReportProducer.cpp
+ * @author Ralf Gerstenberger
+ * @date created at 2002/06/21
+ * @brief Implementation of class odemx::data::ReportProducer
+ * @sa ReportProducer.h
+ * @since 1.0
+ */
+
+#include <odemx/data/ReportProducer.h>
+#include <odemx/base/Simulation.h>
+
+namespace odemx {
+namespace data {
+
+ReportProducer::ReportProducer( base::Simulation& sim, const Label& label )
+:	Log::NamedElement( sim, label )
+{
+}
+
+ReportProducer::~ReportProducer()
+{
+}
+
+const Label& ReportProducer::getLabel() const
+{
+	return getName();
+}
+
+} } // namespace odemx::data
diff --git a/odemx-lite/src/data/ReportTable.cpp b/odemx-lite/src/data/ReportTable.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bd4d72d906456825078ae4dca30ad17f803848dc
--- /dev/null
+++ b/odemx-lite/src/data/ReportTable.cpp
@@ -0,0 +1,710 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ReportTable.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/12/17
+ * @brief Implementation of class odemx::data::ReportTable
+ * @sa ReportTable.h
+ * @since 3.0
+ */
+
+#include <odemx/data/ReportTable.h>
+#include <odemx/base/SimTime.h>
+#include <odemx/util/Exceptions.h>
+#include <odemx/setup.h>
+
+#include <stdexcept>
+#include <sstream>
+
+namespace odemx {
+namespace data {
+
+/********************** Column *********************************************/
+
+const std::string ReportTable::Column::typeToString( ReportTable::Column::Type t )
+{
+	switch( t )
+	{
+	case Column::BAR: 		return std::string( "BAR" );
+	case Column::SIMTIME: 	return std::string( "SIMTIME" );
+	case Column::INTEGER: 	return std::string( "INTEGER" );
+	case Column::REAL: 		return std::string( "REAL" );
+	case Column::STRING: 	return std::string( "STRING" );
+	default: return std::string( "UNKNOWN COLUMN TYPE" );
+	}
+}
+
+/********************* Table Definition ***********************************/
+
+// compare table definitions, used to determine if two tables are the same
+bool operator==( const ReportTable::Definition& lhs, const ReportTable::Definition& rhs )
+{
+	ReportTable::SizeType columns = lhs.getNumberOfColumns();
+
+	// check for same column number
+	if( columns != rhs.getNumberOfColumns() )
+	{
+		return false;
+	}
+
+	// compare each column by type and label
+	for( ReportTable::SizeType i = 0; i < columns; ++i )
+	{
+		if( lhs.getTypeOfColumn( i ) != rhs.getTypeOfColumn( i )
+			|| lhs.getLabelOfColumn( i ) != rhs.getLabelOfColumn( i ) )
+		{
+			return false;
+		}
+	}
+	// all checks passed
+	return true;
+}
+
+ReportTable::SizeType ReportTable::Definition::getNumberOfColumns() const
+{
+	return columnLabels_.size();
+}
+
+const std::string& ReportTable::Definition::getLabelOfColumn( ReportTable::SizeType index ) const
+{
+	static const std::string error( "ERROR" );
+	return ( index < columnLabels_.size() ) ?
+			columnLabels_[ index ] : error;
+}
+
+ReportTable::Column::Type ReportTable::Definition::getTypeOfColumn( ReportTable::SizeType index ) const
+{
+	return ( index < columnTypes_.size() ) ?
+			columnTypes_[ index ] : ReportTable::Column::INVALID;
+}
+
+void ReportTable::Definition::addColumn( const std::string& label, ReportTable::Column::Type type )
+{
+	if( label.empty() || type == Column::INVALID )
+	{
+		return;
+	}
+	columnLabels_.push_back( label );
+	columnTypes_.push_back( type );
+}
+
+/********************* Table Functions ***********************************/
+
+/// Construction is managed by Report
+ReportTable::ReportTable( const Label& label, const ReportTable::Definition& def )
+:	label_( label )
+,	def_( def )
+,	lineCount_( 0 )
+{
+	// create vectors for columns according to TableDefinition
+	for( ReportTable::SizeType i = 0; i < def.getNumberOfColumns(); ++i )
+	{
+		Column* newColumn = 0;
+
+		// create each column according to the given type
+		switch( def.getTypeOfColumn(i) )
+		{
+		case Column::BAR:
+			newColumn = new ColumnT< long >( def.getLabelOfColumn( i ), Column::BAR );
+			break;
+		case Column::INTEGER:
+			newColumn = new ColumnT< long >( def.getLabelOfColumn( i ), Column::INTEGER );
+			break;
+		case Column::REAL:
+			newColumn = new ColumnT< double >( def.getLabelOfColumn( i ), Column::REAL );
+			break;
+		case Column::STRING:
+			newColumn = new ColumnT< std::string >( def.getLabelOfColumn( i ), Column::STRING );
+			break;
+		case Column::SIMTIME:
+			newColumn = new ColumnT< base::SimTime >( def.getLabelOfColumn( i ), Column::SIMTIME );
+			break;
+		default: // INVALID
+			throw std::logic_error( "ReportTable::ReportTable(): invalid column type" );
+			break;
+		}
+
+		if( ! newColumn )
+		{
+			throw DataException( "ReportTable::ReportTable(): invalid column type" );
+		}
+		columns_.push_back( newColumn );
+	}
+}
+
+ReportTable::~ReportTable()
+{
+	// clean up columns
+	for( ColumnVec::const_iterator iter = columns_.begin();
+		iter != columns_.end(); ++iter )
+	{
+		delete *iter;
+	}
+}
+
+/********************** Input Streaming **********************************/
+
+// only four functions actually add data, the others are merely
+// wrappers using the three operator << implementations
+
+// this function deals with INTEGER and with BAR column types
+ReportTable& operator<<( ReportTable& t, long d )
+{
+	// try to get the current column according to inputPosition
+	// this also checks for the correct type of column
+	ReportTable::ColumnT< long >* currentColumn =
+		dynamic_cast< ReportTable::ColumnT< long >* >( t.getCurrentInputColumn() );
+
+	// test column type
+	if ( currentColumn )
+	{
+		currentColumn->addData( d );
+	}
+	else
+	{
+		throw DataException( "ReportTable operator<<(long): wrong column "
+				"type at input position; cannot enter data into Table" );
+	}
+
+	// set input pointer to next position for streaming
+	t.advanceInputPosition();
+	return t;
+}
+
+
+ReportTable& operator<<( ReportTable& t, long long d )
+{
+	return t << (long)d;
+#if 0
+	// try to get the current column according to inputPosition
+	// this also checks for the correct type of column
+	ReportTable::ColumnT< long long >* currentColumn =
+		dynamic_cast< ReportTable::ColumnT< long long >* >( t.getCurrentInputColumn() );
+
+	// test column type
+	if( currentColumn )
+	{
+		currentColumn->addData( d );
+	}
+	else
+	{
+		throw DataException( "ReportTable operator<<(long long): "
+				"wrong column type at input position; cannot enter data into Table" );
+	}
+
+	// set input pointer to next position for streaming
+	t.advanceInputPosition();
+	return t;
+#endif
+}
+
+
+// the above function forces use of this one:
+ReportTable& operator<<( ReportTable& t, double d )
+{
+	// try to get the current column according to inputPosition
+	// this also checks for the correct type of column, returns 0 if wrong
+	ReportTable::ColumnT< double >* currentColumn =
+		dynamic_cast< ReportTable::ColumnT< double >* >( t.getCurrentInputColumn() );
+
+	// test column type
+	if( currentColumn )
+	{
+		currentColumn->addData( d );
+	}
+	else
+	{
+		throw DataException( "ReportTable operator<<(double): wrong "
+				"column type at input position; cannot enter data into Table" );
+	}
+
+	// set input pointer to next position for streaming
+	t.advanceInputPosition();
+	return t;
+}
+
+ReportTable& operator<<( ReportTable& t, const std::string& s )
+{
+	// try to get the current column according to inputPosition
+	// this also checks for the correct type of column, returns 0 if wrong
+	ReportTable::ColumnT< std::string >* currentColumn =
+		dynamic_cast< ReportTable::ColumnT< std::string >* >( t.getCurrentInputColumn() );
+
+	// test column type
+	if( currentColumn )
+	{
+		currentColumn->addData( s );
+	}
+	else
+	{
+		throw DataException( "ReportTable operator<<(string): wrong "
+				"column type at input position; cannot enter data into Table" );
+		return t;
+	}
+
+	// set input pointer to next position for streaming
+	t.advanceInputPosition();
+	return t;
+}
+
+ReportTable& operator<<( ReportTable& t, int i )
+{
+	return t << (long)i;
+}
+
+ReportTable& operator<<( ReportTable& t, unsigned int i )
+{
+	return t << (long)i;
+}
+
+ReportTable& operator<<( ReportTable& t, unsigned long i )
+{
+	return t << (long)i;
+}
+
+ReportTable& operator<<( ReportTable& t, unsigned long long i )
+{
+	return t << (long long)i;
+}
+
+ReportTable& operator<<( ReportTable& t, float f )
+{
+	return t << (double)f;
+}
+
+ReportTable& operator<<( ReportTable& t, const char* s )
+{
+	return t << std::string( s );
+}
+
+
+// this function is used to skip table cells or the rest of the line
+ReportTable& operator<<( ReportTable& t, ReportTable::Definition::ControlCode cc )
+{
+	ReportTable::SizeType line;
+
+	// control codes may end a line early
+	// or cause a jump to the next table cell
+	switch( cc )
+	{
+	case ReportTable::Definition::ENDL:
+		// fill line with default values
+		line = t.lineCount_;
+
+		while( line == t.lineCount_ )
+		{
+			// enter default value
+			t.addDefaultValue();
+		}
+		break;
+	case ReportTable::Definition::TAB:
+		// enter default value
+		t.addDefaultValue();
+		break;
+	default:
+		throw DataException( "ReportTable operator<<(ControlCode): unknown "
+				"control code; cannot enter data into table" );
+	}
+	return t;
+}
+
+void ReportTable::addDefaultValue()
+{
+	Column* currentCol = getCurrentInputColumn();
+
+	// enter default value
+	switch( currentCol->getType() )
+	{
+	case Column::SIMTIME:
+		dynamic_cast< ColumnT< base::SimTime >* >( currentCol )->addData( 0 );
+		break;
+	case Column::BAR: // fall through
+	case Column::INTEGER:
+		dynamic_cast< ColumnT< long >* >( currentCol )->addData( 0 );
+		break;
+	case Column::REAL:
+		dynamic_cast< ColumnT< double >* >( currentCol )->addData( 0.0 );
+		break;
+	case Column::STRING:
+		dynamic_cast< ColumnT< std::string >* >( currentCol )->addData( "" );
+		break;
+	default:
+		throw DataException( "ReportTable::addDefaultValue(): invalid "
+				"column type, cannot add data" );
+	}
+
+	// update inputColumnPointer
+	advanceInputPosition();
+}
+
+/******************** Output streaming ************************************/
+
+ReportTable& operator>>( ReportTable& t, long long& to )
+{
+	// try to get the current column according to outputPosition
+	// this also checks for the correct type of column
+	ReportTable::ColumnT< long long >* currentColumn =
+		dynamic_cast< ReportTable::ColumnT< long long >* >( t.getCurrentOutputColumn() );
+
+	// test column type
+	if( currentColumn )
+	{
+		to = currentColumn->getData( t.getOutputLine() );
+	}
+	else
+	{
+		throw DataException( "ReportTable::operator>>(long long): "
+				"wrong column type, cannot extract data" );
+	}
+
+	// set output pointer to next position for streaming
+	t.advanceOutputPosition();
+	return t;
+}
+
+ReportTable& operator>>( ReportTable& t, unsigned long long& to )
+{
+	// try to get the current column according to outputPosition
+	// this also checks for the correct type of column, returns 0 if wrong
+	if( ReportTable::ColumnT< unsigned long long >* currentColumn =
+			dynamic_cast< ReportTable::ColumnT< unsigned long long >* >(
+					t.getCurrentOutputColumn() ) )
+	{
+		to = currentColumn->getData( t.getOutputLine() );
+	}
+	else if( ReportTable::ColumnT< long long >* currentColumn =
+			dynamic_cast< ReportTable::ColumnT< long long >* >(
+					t.getCurrentOutputColumn() ) )
+	{
+		to = currentColumn->getData( t.getOutputLine() );
+	}
+	else
+	{
+		throw DataException( "ReportTable::operator>>(unsigned long long):"
+				"wrong column type, cannot extract data" );
+	}
+
+	// set output pointer to next position for streaming
+	t.advanceOutputPosition();
+	return t;
+}
+
+ReportTable& operator>>( ReportTable& t, long& to )
+{
+	// try to get the current column according to outputPosition
+	// this also checks for the correct type of column, returns 0 if wrong
+	ReportTable::ColumnT< long >* currentColumn =
+		dynamic_cast< ReportTable::ColumnT< long >* >( t.getCurrentOutputColumn() );
+
+	// test column type
+	if ( currentColumn )
+	{
+		to = currentColumn->getData( t.getOutputLine() );
+	}
+	else
+	{
+		throw DataException( "ReportTable::operator>>(long):"
+				"wrong column type, cannot extract data" );
+	}
+
+	// set output pointer to next position for streaming
+	t.advanceOutputPosition();
+	return t;
+}
+
+ReportTable& operator>>( ReportTable& t, double& to )
+{
+	// try to get the current column according to outputPosition
+	// this also checks for the correct type of column, is 0 if wrong
+	ReportTable::ColumnT< double >* currentColumn =
+		dynamic_cast< ReportTable::ColumnT< double >* >( t.getCurrentOutputColumn() );
+
+	// test column type
+	if( currentColumn )
+	{
+		to = currentColumn->getData( t.getOutputLine() );
+	}
+	else
+	{
+		ReportTable::ColumnT< long >* currentColumn =
+			dynamic_cast< ReportTable::ColumnT<long>* >( t.getCurrentOutputColumn() );
+
+		if( currentColumn )
+		{
+			to = (double)currentColumn->getData( t.getOutputLine() );
+		}
+		else
+		{
+			throw DataException( "ReportTable::operator>>(double): "
+					"wrong column type, cannot extract data" );
+		}
+	}
+
+	// set output pointer to next position for streaming
+	t.advanceOutputPosition();
+	return t;
+}
+
+ReportTable& operator>>( ReportTable& t, std::string& to )
+{
+	// any column type accepted, conversion with ostringstream
+	std::ostringstream convert;
+
+	ReportTable::Column* currentColumn = t.getCurrentOutputColumn();
+
+	// try to get the current column according to outputPosition
+	// this also checks for the correct type of column
+	switch( currentColumn->getType() )
+	{
+	case ReportTable::Column::BAR: // fall through
+	case ReportTable::Column::INTEGER:
+		convert << dynamic_cast< ReportTable::ColumnT< long >* >
+				( currentColumn )->getData( t.getOutputLine() );
+		break;
+	case ReportTable::Column::REAL:
+		convert << dynamic_cast< ReportTable::ColumnT< double >* >
+				( currentColumn )->getData( t.getOutputLine() );
+		break;
+	case ReportTable::Column::STRING:
+		convert << dynamic_cast< ReportTable::ColumnT< std::string >* >
+				( currentColumn )->getData( t.getOutputLine() );
+		break;
+	case ReportTable::Column::SIMTIME:
+		convert << dynamic_cast< ReportTable::ColumnT< base::SimTime >* >
+				( currentColumn )->getData( t.getOutputLine() );
+		break;
+	default:
+		DataException( "ReportTable::operator>>(string): "
+				"invalid column type, cannot extract data" );
+	}
+
+	// write string to stream
+	to = convert.str();
+
+	// update outputColumnPointer
+	t.advanceOutputPosition();
+	return t;
+}
+
+
+/****************** Random Access Output **********************************/
+
+base::SimTime ReportTable::getSIMTIME( ReportTable::SizeType col, ReportTable::SizeType line )
+{
+	if( col >= columns_.size() )
+	{
+		throw std::out_of_range( "ReportTable::getSIMTIME(): column out of range" );
+	}
+	if( line >= lineCount_ )
+	{
+		throw std::out_of_range( "ReportTable::getSIMTIME(): line out of range" );
+	}
+
+	// try to get the column col, check for the correct type, is 0 if wrong
+	ReportTable::ColumnT< base::SimTime >* currentColumn =
+		dynamic_cast< ReportTable::ColumnT< base::SimTime >* >( columns_[ col ] );
+
+	// test column type
+	if( currentColumn
+		&& currentColumn->getType() == ReportTable::Column::SIMTIME )
+	{
+		return (base::SimTime) currentColumn->getData( line );
+	}
+	else
+	{
+		throw DataException( "ReportTable::getSIMTIME(): wrong column type; "
+				"cannot extract data" );
+	}
+}
+
+
+long ReportTable::getBAR( ReportTable::SizeType col, ReportTable::SizeType line )
+{
+	if( col >= columns_.size() )
+	{
+		throw std::out_of_range( "ReportTable::getBAR(): column out of range" );
+	}
+	if( line >= lineCount_ )
+	{
+		throw std::out_of_range( "ReportTable::getBAR(): line out of range" );
+	}
+
+	// try to get the column col, check for the correct type, is 0 if wrong
+	ReportTable::ColumnT< long >* currentColumn =
+		dynamic_cast< ReportTable::ColumnT< long >* >( columns_[ col ] );
+
+	// test column type
+	if( currentColumn
+		&& currentColumn->getType() == Column::BAR )
+	{
+		return currentColumn->getData( line );
+	}
+	else
+	{
+		throw DataException( "ReportTable::getBAR(): wrong column type; "
+				"cannot extract data" );
+	}
+}
+
+long ReportTable::getINTEGER( ReportTable::SizeType col, ReportTable::SizeType line )
+{
+	if( col >= columns_.size() )
+	{
+		throw std::out_of_range( "ReportTable::getINTEGER(): column out of range" );
+	}
+	if( line >= lineCount_ )
+	{
+		throw std::out_of_range( "ReportTable::getINTEGER(): line out of range" );
+	}
+
+	// try to get the column col, check for the correct type, is 0 if wrong
+	ReportTable::ColumnT< long >* currentColumn =
+		dynamic_cast< ReportTable::ColumnT< long >* >( columns_[ col ] );
+
+	// test column type
+	if ( currentColumn
+		&& currentColumn->getType() == Column::INTEGER )
+	{
+		return currentColumn->getData( line );
+	}
+	else
+	{
+		throw DataException( "ReportTable::getINTEGER(): wrong column type; "
+				"cannot extract data" );
+	}
+}
+
+double ReportTable::getREAL( ReportTable::SizeType col, ReportTable::SizeType line )
+{
+	if( col >= columns_.size() )
+	{
+		throw std::out_of_range( "ReportTable::getREAL(): column out of range" );
+	}
+	if( line >= lineCount_ )
+	{
+		throw std::out_of_range( "ReportTable::getREAL(): line out of range" );
+	}
+
+	// try to get the column col, check for the correct type, is 0 if wrong
+	ReportTable::ColumnT< double >* currentColumn =
+		dynamic_cast< ReportTable::ColumnT< double >* >( columns_[ col ]  );
+
+	// test column type
+	if( currentColumn
+		&& currentColumn->getType() == Column::REAL )
+	{
+		return currentColumn->getData( line );
+	}
+	else
+	{
+		// cast from long type is also allowed
+		ReportTable::ColumnT< long >* currentColumn =
+			dynamic_cast< ReportTable::ColumnT< long >* >( columns_[ col ] );
+
+		if( currentColumn
+			&& currentColumn->getType() == Column::INTEGER )
+		{
+			return (double)currentColumn->getData( line );
+		}
+		else
+		{
+			throw DataException( "ReportTable::getREAL(): wrong column type; "
+							"cannot extract data" );
+		}
+	}
+}
+
+std::string ReportTable::getSTRING( ReportTable::SizeType col, ReportTable::SizeType line )
+{
+	if( col >= columns_.size() )
+	{
+		throw std::out_of_range( "ReportTable::getSTRING(): column out of range" );
+	}
+	if( line >= lineCount_ )
+	{
+		throw std::out_of_range( "ReportTable::getSTRING(): line out of range" );
+	}
+
+	// any column type accepted, conversion with std::ostringstream
+	std::ostringstream convert;
+	ReportTable::Column* currentColumn = columns_[ col ];
+
+	// checks for the correct type of column, returns 0 if wrong
+	switch( currentColumn->getType() )
+	{
+	case ReportTable::Column::BAR: // fall through
+	case ReportTable::Column::INTEGER:
+		convert << dynamic_cast< ReportTable::ColumnT< long >* >
+				( currentColumn )->getData( line );
+		break;
+	case ReportTable::Column::SIMTIME:
+		convert << dynamic_cast< ReportTable::ColumnT< base::SimTime >* >
+				( currentColumn )->getData( line );
+		break;
+	case ReportTable::Column::REAL:
+		convert << dynamic_cast< ReportTable::ColumnT< double >* >
+				( currentColumn )->getData( line );
+		break;
+	case ReportTable::Column::STRING:
+		convert << dynamic_cast< ReportTable::ColumnT< std::string >* >
+				( currentColumn )->getData( line );
+		break;
+	default:
+		throw DataException( "ReportTable::getSTRING(): unknown column type; "
+						"cannot extract data" );
+	}
+	return convert.str();
+}
+
+// help procedures
+void ReportTable::advanceInputPosition()
+{
+	// advance the inputPosition by one
+	++inputPosition_.col;
+
+	// check for line end
+	if( inputPosition_.col >= getNumberOfColumns() )
+	{
+		inputPosition_.col = inputPosition_.col % getNumberOfColumns();
+		++inputPosition_.line;
+		++lineCount_;
+	}
+}
+
+void ReportTable::advanceOutputPosition()
+{
+	// advance the outputPosition by one
+	++outputPosition_.col;
+
+	// check for line end
+	if( outputPosition_.col >= getNumberOfColumns() )
+	{
+		outputPosition_.col = outputPosition_.col % getNumberOfColumns();
+		++outputPosition_.line;
+	}
+
+	// wrap output streaming at last line to start anew
+	if( outputPosition_.line >= getNumberOfLines() )
+	{
+		outputPosition_.line = 0;
+	}
+}
+
+} } // namespace data
diff --git a/odemx-lite/src/data/SimRecord.cpp b/odemx-lite/src/data/SimRecord.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3154915a12902ee2580d4ae0f9b23ef5c7824acc
--- /dev/null
+++ b/odemx-lite/src/data/SimRecord.cpp
@@ -0,0 +1,119 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file SimRecord.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/03/16
+ * @brief Implementation of class odemx::data::SimRecord
+ * @sa SimRecord.h
+ * @since 3.0
+ */
+
+#include <odemx/data/SimRecord.h>
+#include <odemx/base/Simulation.h>
+#include <odemx/util/Exceptions.h>
+
+namespace odemx {
+namespace data {
+
+//------------------------------------------------------construction/destruction
+
+SimRecord::SimRecord( const base::Simulation& sim, const Producer& sender,
+		const StringLiteral& text )
+:	text_( text )
+,	sim_( &sim )
+,	sender_( &sender )
+,	time_( sim.getTime() )
+,	scope_()
+,	details_()
+{
+}
+
+SimRecord::~SimRecord()
+{
+}
+
+//-------------------------------------------------------------------data checks
+
+bool SimRecord::hasScope() const
+{
+	return scope_.isSet();
+}
+
+bool SimRecord::hasDetails() const
+{
+	return !! details_;
+}
+
+//------------------------------------------------------------class scope setter
+
+SimRecord& SimRecord::scope( const TypeInfo& type )
+{
+	scope_ = type;
+	return *this;
+}
+
+//------------------------------------------------------------------data getters
+
+const StringLiteral& SimRecord::getText() const
+{
+	return text_;
+}
+
+const base::Simulation& SimRecord::getSimulation() const
+{
+	return *sim_;
+}
+
+const Producer& SimRecord::getSender() const
+{
+	return *sender_;
+}
+
+base::SimTime SimRecord::getTime() const
+{
+	return time_;
+}
+
+const TypeInfo& SimRecord::getScope() const
+{
+	return scope_;
+}
+
+const SimRecord::DetailVec& SimRecord::getDetails() const
+{
+	if( ! details_ )
+	{
+		throw DataException( "SimRecord::getDetails(): "
+				"detail vector pointer not initialized, check hasDetails()" );
+	}
+	return *details_;
+}
+
+const std::shared_ptr< SimRecord::DetailVec > SimRecord::getDetailPointer() const
+{
+	return details_;
+}
+
+void SimRecord::initDetailVec()
+{
+	details_.reset( new DetailVec() );
+}
+
+} } // namespace odemx::data
diff --git a/odemx-lite/src/data/SimRecordFilter.cpp b/odemx-lite/src/data/SimRecordFilter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5e4d887393e61e39f3b50fdab08e8b3f79d9878c
--- /dev/null
+++ b/odemx-lite/src/data/SimRecordFilter.cpp
@@ -0,0 +1,52 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file SimRecordFilter.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/03/18
+ * @brief Implementation of class odemx::data::SimRecordFilter
+ * @sa SimRecordFilter.h
+ * @since 3.0
+ */
+
+#include <odemx/data/SimRecordFilter.h>
+
+#include <algorithm>
+#include <iterator>
+#include <sstream>
+
+namespace odemx {
+namespace data {
+
+//------------------------------------------------------construction/destruction
+
+std::shared_ptr< SimRecordFilter > SimRecordFilter::create()
+{
+	return std::shared_ptr< SimRecordFilter >( new SimRecordFilter() );
+}
+
+SimRecordFilter::SimRecordFilter()
+{
+}
+
+SimRecordFilter::~SimRecordFilter()
+{
+}
+
+} } // namespace odemx::data
diff --git a/odemx-lite/src/data/buffer/SimRecordBuffer.cpp b/odemx-lite/src/data/buffer/SimRecordBuffer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bdae1fd82c61e191034c131c9bdd13693188c311
--- /dev/null
+++ b/odemx-lite/src/data/buffer/SimRecordBuffer.cpp
@@ -0,0 +1,99 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file SimRecordBuffer.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/09/14
+ * @brief Implementation of class odemx::data::SimRecordBuffer
+ * @sa SimRecordBuffer.h
+ * @since 3.0
+ */
+
+#include <odemx/data/buffer/SimRecordBuffer.h>
+#include <odemx/data/ManagedChannels.h>
+#include <odemx/data/Producer.h>
+
+namespace odemx {
+namespace data {
+namespace buffer {
+
+SimRecordBuffer::SimRecordBuffer( SizeType limit )
+:	storage_()
+,	size_( 0 )
+,	limit_( limit )
+{
+}
+
+void SimRecordBuffer::put( const Log::ChannelId channelId,
+		const SimRecord& simRecord, const TableKey simId,
+		const std::string& timeString )
+{
+	const Producer& sender = simRecord.getSender();
+
+	// copy volatile and additional information and store it as InfoType
+	StoredRecord record( simRecord.getText(), simRecord.getDetailPointer() );
+	record
+	+ ChannelInfo( channel_id::toString( channelId ) )
+	+ SenderLabelInfo( sender.getLabel() )
+	+ SenderTypeInfo( sender.getType().toString() )
+	+ StringTimeInfo( timeString )
+	+ SimIdInfo( simId );
+
+	if( simRecord.hasScope() )
+	{
+		record + ClassScopeInfo( simRecord.getScope().toString() );
+	}
+
+	// store the extended record
+	storage_.push_back( record );
+	++size_;
+}
+
+void SimRecordBuffer::clear()
+{
+	storage_.clear();
+	size_ = 0;
+}
+
+bool SimRecordBuffer::isEmpty() const
+{
+	return size_ == 0;
+}
+
+bool SimRecordBuffer::isFull() const
+{
+	return size_ >= limit_;
+}
+
+const SimRecordBuffer::StorageType& SimRecordBuffer::getStorage() const
+{
+	return storage_;
+}
+
+SimRecordBuffer::SizeType SimRecordBuffer::getSize() const
+{
+	return size_;
+}
+
+SimRecordBuffer::SizeType SimRecordBuffer::getLimit() const
+{
+	return limit_;
+}
+
+} } } // namespace odemx::data
diff --git a/odemx-lite/src/data/buffer/StatisticsBuffer.cpp b/odemx-lite/src/data/buffer/StatisticsBuffer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f6f50832625b582c7357be15e4a04bdee359c5fa
--- /dev/null
+++ b/odemx-lite/src/data/buffer/StatisticsBuffer.cpp
@@ -0,0 +1,306 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file StatisticsBuffer.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/04/07
+ * @brief Implementation of class odemx::data::buffer::StatisticsBuffer
+ * @sa StatisticsBuffer.h
+ * @since 3.0
+ */
+
+#include <odemx/data/buffer/StatisticsBuffer.h>
+#include <odemx/data/ManagedChannels.h>
+#include <odemx/data/Producer.h>
+#include <odemx/data/Report.h>
+#include <odemx/util/Exceptions.h>
+#include <odemx/util/StringConversion.h>
+
+namespace odemx {
+namespace data {
+namespace buffer {
+
+//------------------------------------------------------construction/destruction
+
+std::shared_ptr< StatisticsBuffer > StatisticsBuffer::create(
+		base::Simulation& sim, const Label& label, bool bufferUpdates )
+{
+	return std::shared_ptr< StatisticsBuffer >(
+			new StatisticsBuffer( sim, label, bufferUpdates ) );
+}
+
+StatisticsBuffer::StatisticsBuffer( base::Simulation& sim, const Label& label,
+		bool bufferUpdates )
+:	ReportProducer( sim, label )
+,	statistics_()
+,	bufferUpdates_( bufferUpdates )
+{
+}
+
+StatisticsBuffer::~StatisticsBuffer()
+{
+}
+
+//---------------------------------------------------------------------accessors
+
+const StatisticsBuffer::StatisticsMap& StatisticsBuffer::getStatistics() const
+{
+	return statistics_;
+}
+
+/// Check for existing ProducerStats or create and add a new stats object
+StatisticsBuffer::ProducerStatsPtr StatisticsBuffer::getObjectStats(
+		const data::Producer& sender )
+{
+	ProducerStatsPtr objectStats;
+	StatisticsMap::iterator found = statistics_.find( sender.getLabel() );
+	if( found != statistics_.end() )
+	{
+		objectStats = found->second;
+	}
+	else
+	{
+		objectStats.reset( new ProducerStats() );
+		statistics_[ sender.getLabel() ] = objectStats;
+		objectStats->resetTime = 0;
+	}
+
+	// store the sender type for report output
+	if( ! objectStats->senderType.isSet() )
+	{
+		objectStats->senderType = sender.getType();
+	}
+	return objectStats;
+}
+
+bool StatisticsBuffer::isBufferingUpdates() const
+{
+	return bufferUpdates_;
+}
+
+const StatisticsBuffer::UpdateDeque& StatisticsBuffer::getUpdates(
+		const Label& producer, const StringLiteral& property ) const
+{
+	StatisticsMap::const_iterator found = statistics_.find( producer );
+
+	if( found != statistics_.end() )
+	{
+		UpdateMap::const_iterator foundProp =
+				found->second->updateStats.find( property );
+
+		if( foundProp != found->second->updateStats.end() )
+		{
+			return foundProp->second.updates;
+		}
+		else
+		{
+			throw DataException( "StatisticsBuffer::getUpdates(): property not found" );
+		}
+	}
+	else
+	{
+		throw DataException( "StatisticsBuffer::getUpdates(): producer not found" );
+	}
+}
+
+bool StatisticsBuffer::isEmpty() const
+{
+	return statistics_.empty();
+}
+
+void StatisticsBuffer::reset( base::SimTime resetTime )
+{
+	for( StatisticsMap::iterator iter = statistics_.begin();
+		iter != statistics_.end(); ++iter )
+	{
+		ProducerStatsPtr objectStats = iter->second;
+		objectStats->resetTime = resetTime;
+		CountMap empty1;
+		UpdateMap empty2;
+		objectStats->countStats.swap( empty1 );
+		objectStats->updateStats.swap( empty2 );
+	}
+}
+
+//---------------------------------------------------------------record handling
+
+void StatisticsBuffer::consume( const Log::ChannelId channelId, const SimRecord& record )
+{
+	// ignore log records from other channels
+	if( channelId != channel_id::statistics )
+	{
+		return;
+	}
+
+	const data::StringLiteral& recordType = record.getText();
+	const data::Producer& sender = record.getSender();
+	base::SimTime time = record.getTime();
+
+	// check the statistics record type and choose the appropriate action
+	if( recordType == "parameter" )
+	{
+		ProducerStatsPtr objectStats = getObjectStats( sender );
+		const SimRecord::DetailVec& details = record.getDetails();
+		for( SimRecord::DetailVec::const_iterator iter = details.begin();
+			 iter != details.end(); ++iter )
+		{
+			// save parameter name and value
+			objectStats->paramStats[ iter->first ] = iter->second;
+		}
+	}
+	else if( recordType == "count" )
+	{
+		ProducerStatsPtr objectStats = getObjectStats( sender );
+		const SimRecord::DetailVec& details = record.getDetails();
+		for( SimRecord::DetailVec::const_iterator iter = details.begin();
+			 iter != details.end(); ++iter )
+		{
+			// add the given value to the counter
+			objectStats->countStats[ iter->first ] += iter->second.as<std::size_t>();
+		}
+	}
+	else if( recordType == "update" )
+	{
+		ProducerStatsPtr objectStats = getObjectStats( sender );
+		const SimRecord::DetailVec& details = record.getDetails();
+		for( SimRecord::DetailVec::const_iterator iter = details.begin();
+			 iter != details.end(); ++iter )
+		{
+			const Log::StringLiteral& property = iter->first;
+
+			// get the updated property
+			UpdateMap::iterator updateIter = objectStats->updateStats.find( property );
+			if( updateIter == objectStats->updateStats.end() )
+			{
+				// create new update stats if necessary
+				std::pair< UpdateMap::iterator, bool> result =
+						objectStats->updateStats.insert(
+								UpdateMap::value_type( property,
+										UpdateStats( const_cast< base::Simulation& >( sender.getSimulation() ),
+												sender.getLabel() + " " + property.c_str() ) ) );
+				assert( result.second );
+				updateIter = result.first;
+			}
+			// get reference to the update stats which must exist now
+			UpdateStats& updateStats = updateIter->second;
+			// store the update time and value and accumulate statistics
+			double value = iter->second.as<double>();
+			// compute accumulated value
+			updateStats.accumulate.update( time, value );
+			// store updates, if enabled
+			if( bufferUpdates_ )
+			{
+				updateStats.updates.push_back( std::make_pair( time, value ) );
+			}
+		}
+	}
+	else if( recordType == "reset" )
+	{
+		ProducerStatsPtr objectStats = getObjectStats( sender );
+		objectStats->resetTime = time;
+		CountMap empty1;
+		UpdateMap empty2;
+		objectStats->countStats.swap( empty1 );
+		objectStats->updateStats.swap( empty2 );
+	}
+}
+
+void StatisticsBuffer::report( data::Report& report )
+{
+	using namespace data;
+
+	// iterate over the statistics data of all senders
+	for( StatisticsMap::const_iterator iter = statistics_.begin();
+		 iter != statistics_.end(); ++iter )
+	{
+		const Label& sender = iter->first;
+		const buffer::StatisticsBuffer::ProducerStatsPtr objectStats = iter->second;
+
+		if( ! ( objectStats->paramStats.empty() && objectStats->countStats.empty() ) )
+		{
+			ReportTable::Definition paramCountTableDef;
+
+			// build table definition for param and counter table
+			paramCountTableDef.addColumn( "Name", ReportTable::Column::STRING );
+			paramCountTableDef.addColumn( "Reset at", ReportTable::Column::SIMTIME );
+
+			for( ParamMap::iterator paramIter = objectStats->paramStats.begin();
+				paramIter != objectStats->paramStats.end(); ++paramIter )
+			{
+				paramCountTableDef.addColumn( paramIter->first.c_str(), ReportTable::Column::STRING );
+			}
+
+			for( CountMap::iterator countIter = objectStats->countStats.begin();
+				countIter != objectStats->countStats.end(); ++countIter )
+			{
+				paramCountTableDef.addColumn( countIter->first.c_str(), ReportTable::Column::INTEGER );
+			}
+
+			// tables are associated with sender types
+			ReportTable& table = report.getTable(
+					objectStats->senderType.toString(), paramCountTableDef );
+
+			table << sender << objectStats->resetTime;
+
+			for( ParamMap::iterator paramIter = objectStats->paramStats.begin();
+				paramIter != objectStats->paramStats.end(); ++paramIter )
+			{
+				table << static_cast<const std::string&>(paramIter->second);
+			}
+
+			for( CountMap::iterator countIter = objectStats->countStats.begin();
+				countIter != objectStats->countStats.end(); ++countIter )
+			{
+				table << countIter->second;
+			}
+		}
+
+		// define accum table
+		ReportTable::Definition def;
+		def.addColumn( "Producer", ReportTable::Column::STRING );
+		def.addColumn( "Property", ReportTable::Column::STRING );
+		def.addColumn( "Updates", ReportTable::Column::INTEGER );
+		def.addColumn( "Min", ReportTable::Column::REAL );
+		def.addColumn( "Max", ReportTable::Column::REAL );
+		def.addColumn( "Mean", ReportTable::Column::REAL );
+		def.addColumn( "Weighted Mean", ReportTable::Column::REAL );
+		def.addColumn( "Std Deviation", ReportTable::Column::REAL );
+		def.addColumn( "Weighted StDev", ReportTable::Column::REAL );
+		ReportTable& table = report.getTable( "odemx::data::buffer::StatisticsBuffer Updates", def );
+
+		// print accum stats
+		for( UpdateMap::iterator updateIter = objectStats->updateStats.begin();
+			updateIter != objectStats->updateStats.end(); ++updateIter )
+		{
+			const statistics::Accumulate& accum = updateIter->second.accumulate;
+			table
+			<< sender
+			<< updateIter->first.c_str()
+			<< accum.getUpdateCount()
+			<< accum.getMin()
+			<< accum.getMax()
+			<< accum.getMean()
+			<< accum.getWeightedMean()
+			<< accum.getStandardDeviation()
+			<< accum.getWeightedStandardDeviation();
+		}
+	}
+}
+
+} } } // namespace odemx::data::buffer
diff --git a/odemx-lite/src/data/output/ErrorWriter.cpp b/odemx-lite/src/data/output/ErrorWriter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b25d793156094a3daafc8fb5637a7fd156281dcc
--- /dev/null
+++ b/odemx-lite/src/data/output/ErrorWriter.cpp
@@ -0,0 +1,111 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ErrorWriter.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/09/30
+ * @brief Implementation of class odemx::data::output::ErrorWriter
+ * @sa ErrorWriter.h
+ * @since 3.0
+ */
+
+#include <odemx/data/output/ErrorWriter.h>
+#include <odemx/data/output/DefaultTimeFormat.h>
+#include <odemx/data/ManagedChannels.h>
+#include <odemx/data/Producer.h>
+
+#include <iostream>
+#include <iomanip>
+
+namespace odemx {
+namespace data {
+namespace output {
+
+//------------------------------------------------------construction/destruction
+
+std::shared_ptr< ErrorWriter > ErrorWriter::create()
+{
+	return std::shared_ptr< ErrorWriter >( new ErrorWriter() );
+}
+
+ErrorWriter::ErrorWriter()
+:	format_( new DefaultTimeFormat() )
+{
+}
+
+ErrorWriter::~ErrorWriter()
+{
+}
+
+//---------------------------------------------------------------record handling
+
+void ErrorWriter::consume( const Log::ChannelId channelId, const SimRecord& record )
+{
+	using namespace std;
+
+	switch( channelId )
+	{
+	case channel_id::warning: cerr << "ODEMx WARNING: "; break;
+	case channel_id::error: cerr << "ODEMx ERROR: "; break;
+	case channel_id::fatal: cerr << "ODEMx FATAL ERROR: "; break;
+	default:
+		cerr << "ODEMx ERROR: ErrorWriter::consume(): "
+				"connected to wrong log channel" << endl;
+		return;
+	}
+
+	const Producer& sender = record.getSender();
+
+	cerr
+	<< record.getText()
+	<< " [Time: " << format_->timeToString( record.getTime() )
+	<< "] [Object: " << sender << " (" << sender.getType().toString() << ")]";
+
+	if( record.hasDetails() )
+	{
+		cerr << " [";
+		for( SimRecord::DetailVec::const_iterator detail = record.getDetails().begin();
+			detail != record.getDetails().end(); ++detail )
+		{
+			if( detail != record.getDetails().begin() )
+			{
+				cerr << " | ";
+			}
+			cerr << detail->first << "="
+				<< detail->second.as<std::string>();
+		}
+		cerr << "]";
+	}
+
+	if( record.hasScope() )
+	{
+		cerr << " [Scope: " << record.getScope().toString() << "]";
+	}
+
+	cerr << std::endl;
+}
+
+//-----------------------------------------------------------------------setters
+
+void ErrorWriter::setTimeFormat( TimeFormat* timeFormat )
+{
+	format_.reset( timeFormat );
+}
+
+} } } // namespace odemx::data::output
diff --git a/odemx-lite/src/data/output/GermanTime.cpp b/odemx-lite/src/data/output/GermanTime.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fdf385d8be923eb9eeb525f49847bc32b24f9830
--- /dev/null
+++ b/odemx-lite/src/data/output/GermanTime.cpp
@@ -0,0 +1,88 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file GermanTime.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/04/03
+ * @brief Implementation of class odemx::data::output::GermanTime
+ * @sa GermanTime.h
+ * @since 2.1
+ */
+
+#include <odemx/data/output/GermanTime.h>
+#include <odemx/data/output/TimeBase.h>
+#include <odemx/data/output/TimeUnit.h>
+
+#include <iomanip>
+#include <string>
+#include <sstream>
+
+namespace odemx {
+namespace data {
+namespace output {
+
+//------------------------------------------------------construction/destruction
+
+GermanTime::GermanTime()
+:	TimeFormat()
+{
+}
+
+GermanTime::GermanTime( const TimeBase& base )
+:	TimeFormat( base )
+{
+}
+
+//----------------------------------------------------------time string creation
+
+const std::string GermanTime::makeString() const
+{
+	using namespace std;
+
+	ostringstream stream;
+	stream.fill('0');
+
+	if( (year - 100) > 0 )
+	{
+		stream << setw(4) << year;
+	}
+	else
+	{
+		stream << setw(2) << year;
+	}
+
+	stream << '-' << setw(2) << month << '-';
+	stream << setw(2) << day;
+
+	stream << " / ";
+	stream << setw(2) << hour << ':';
+	stream << setw(2) << min;
+
+	if( base.unit == TimeUnit::milliseconds )
+	{
+		stream << ':' << setw(6) << fixed << setprecision(3) << sec;
+	}
+	else
+	{
+		stream << ':' << setw(2) << fixed << setprecision(0) << sec;
+	}
+	return stream.str();
+}
+
+} } } // namespace odemx::data::output
diff --git a/odemx-lite/src/data/output/Iso8601Time.cpp b/odemx-lite/src/data/output/Iso8601Time.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7cf95b1c2d71efedb7d98c0318c352af1d6b2ab4
--- /dev/null
+++ b/odemx-lite/src/data/output/Iso8601Time.cpp
@@ -0,0 +1,123 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Iso8601Time.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/04/03
+ * @brief Implementation of class odemx::data::output::Iso8601Time
+ * @sa Iso8601Time.h
+ * @since 2.1
+ */
+
+#include <odemx/data/output/Iso8601Time.h>
+
+#include <cmath>
+#include <iomanip>
+#include <string>
+#include <sstream>
+#include <stdexcept>
+
+namespace odemx {
+namespace data {
+namespace output {
+
+//------------------------------------------------------construction/destruction
+
+Iso8601Time::Iso8601Time( const TimeBase& base, short utcOffsetHour, unsigned short utcOffsetMin )
+:	TimeFormat( base )
+,	utcOffset_( UtcOffset( utcOffsetHour, utcOffsetMin ) )
+{
+}
+
+//----------------------------------------------------------time string creation
+
+const std::string Iso8601Time::makeString() const
+{
+	using namespace std;
+
+	ostringstream stream;
+	stream.fill('0');
+
+	stream
+	<< setw(4) << year << '-'
+	<< setw(2) << month << '-'
+	<< setw(2) << day
+	<< 'T'
+	<< setw(2) << hour << ':'
+	<< setw(2) << min;
+
+	// print seconds or milliseconds
+	if( base.unit == TimeUnit::milliseconds )
+	{
+		stream << ':' << setw(6) << fixed << setprecision(3) << sec;
+	}
+	else
+	{
+		stream << ':' << setw(2) << fixed << setprecision(0) << sec;
+	}
+
+	// print UTC time zone
+	if( utcOffset_.hour || utcOffset_.minute )
+	{
+		stream
+		<< ( utcOffset_.hour > 0 ? '+' : '-' )
+		<< setw(2) << setprecision(0)
+		<< std::abs( static_cast< float >( utcOffset_.hour ) ) << ':'
+		<< setw(2) << utcOffset_.minute;
+	}
+	else
+	{
+		stream << 'Z'; // represents UTC-0
+	}
+
+	return stream.str();
+}
+
+//--------------------------------------------------------------------UTC offset
+
+Iso8601Time::UtcOffset::UtcOffset( short h, unsigned short m )
+{
+	if ( h || m )
+	{
+		if( h < -12 || h > 14 )
+		{
+			throw std::out_of_range(
+					"TimeZone(): hour value range is -12 through 14" );
+		}
+		if( ! ( m == 0 || m == 15 || m == 30 || m == 45 ) )
+		{
+			throw std::out_of_range(
+					"TimeZone(): minute requires values 0, 15, 30, or 45" );
+		}
+	}
+	hour = h;
+	minute = m;
+}
+
+void Iso8601Time::setUtcOffset( short hour, short minute )
+{
+	utcOffset_ = UtcOffset( hour, minute );
+}
+
+const Iso8601Time::UtcOffset& Iso8601Time::getUtcOffset() const
+{
+	return utcOffset_;
+}
+
+} } } // namespace odemx::data::output
diff --git a/odemx-lite/src/data/output/OStreamReport.cpp b/odemx-lite/src/data/output/OStreamReport.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b1aeca9e0361a6d681351beb6c029f607143f111
--- /dev/null
+++ b/odemx-lite/src/data/output/OStreamReport.cpp
@@ -0,0 +1,165 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file OStreamReport.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/02/28
+ * @brief Implementation of class odemx::data::output::OStreamReport
+ * @sa OStreamReport.h
+ * @since 3.0
+ */
+
+#include <odemx/data/output/OStreamReport.h>
+#include <odemx/data/buffer/StatisticsBuffer.h>
+
+#include <iomanip>
+
+namespace odemx {
+namespace data {
+namespace output {
+
+OStreamReport::OStreamReport( std::ostream& os )
+:	os_( os )
+{
+}
+
+OStreamReport::~OStreamReport()
+{
+}
+
+void OStreamReport::startProcessing()
+{
+	os_ << "ODEMx Statistics Report\n"
+		<< "=======================";
+}
+
+void OStreamReport::endProcessing()
+{
+}
+
+void OStreamReport::processTables()
+{
+	using namespace std;
+
+	if( tables_.empty() )
+	{
+		os_ << "\n\n" << "no statistics tables to display\n";
+		return;
+	}
+
+	// write tables
+	for( TableVec::const_iterator iter = tables_.begin();
+		iter != tables_.end(); ++iter )
+	{
+		ReportTable* table = *iter;
+
+		if( ! table )
+		{
+			continue;
+		}
+
+		// title
+		os_ << "\n\n" << table->getLabel() << "\n";
+		os_ << string( table->getLabel().length(), '-' ) << "\n";
+		os_ << left;
+
+		// compute column widths
+		std::deque< std::size_t > colWidths( table->getNumberOfColumns(), 0 );
+
+		for( ReportTable::SizeType col = 0; col < table->getNumberOfColumns(); ++col )
+		{
+			for( ReportTable::SizeType line = 0; line < table->getNumberOfLines(); ++line )
+			{
+				std::size_t currentWidth = 0;
+				switch( table->getTypeOfColumn( col ) )
+				{
+				case ReportTable::Column::REAL: // fall through
+				case ReportTable::Column::STRING:
+				case ReportTable::Column::INTEGER:
+				case ReportTable::Column::SIMTIME:
+					currentWidth = table->getSTRING( col, line ).size();
+					break;
+				case ReportTable::Column::BAR:
+				{
+					long barSize = table->getBAR( col, line );
+					if( barSize < 0 )
+					{
+						currentWidth = 0;
+					}
+					else
+					{
+						currentWidth = barSize;
+					}
+					break;
+				}
+				default:
+					break;
+				}
+				// store max value
+				colWidths[ col ] = std::max( colWidths[ col ], currentWidth );
+				colWidths[ col ] = std::max( colWidths[ col ], table->getLabelOfColumn( col ).size() );
+			}
+
+		}
+
+		// write column labels
+		for( ReportTable::SizeType i = 0; i < table->getNumberOfColumns(); ++i )
+		{
+			os_ << setw( colWidths[ i ] )
+				<< table->getLabelOfColumn( i )
+				<< " | ";
+		}
+
+		// write lines
+		for( ReportTable::SizeType line = 0; line < table->getNumberOfLines(); ++line )
+		{
+			os_ << "\n";
+
+			// write cells
+			for( ReportTable::SizeType col = 0; col < table->getNumberOfColumns(); ++col )
+			{
+				switch( table->getTypeOfColumn( col ) )
+				{
+				case ReportTable::Column::REAL: // fall through
+				case ReportTable::Column::STRING:
+				case ReportTable::Column::INTEGER:
+				case ReportTable::Column::SIMTIME:
+					os_ << setw( colWidths[ col ] )
+						<< table->getSTRING( col, line )
+						<< " | ";
+					break;
+				case ReportTable::Column::BAR:
+				{
+					long barSize = table->getBAR( col, line );
+					if( barSize > 0 )
+					{
+						os_ << left << string( table->getBAR( col, line ), '*' );
+					}
+					break;
+				}
+				default:
+					break;
+				}
+			}
+		}
+	}
+	os_ << "\n" << endl;
+}
+
+} } } // namespace odemx::data::output
diff --git a/odemx-lite/src/data/output/OStreamWriter.cpp b/odemx-lite/src/data/output/OStreamWriter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a68c3ecd25ed1b9ea9a2f0d799f786579cb2c402
--- /dev/null
+++ b/odemx-lite/src/data/output/OStreamWriter.cpp
@@ -0,0 +1,104 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file OStreamWriter.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/02/09
+ * @brief Implementation of class odemx::data::output::OStreamWriter
+ * @sa OStreamWriter.h
+ * @since 3.0
+ */
+
+#include <odemx/data/output/OStreamWriter.h>
+#include <odemx/data/output/DefaultTimeFormat.h>
+#include <odemx/data/ManagedChannels.h>
+#include <odemx/data/Producer.h>
+
+#include <iomanip>
+
+namespace odemx {
+namespace data {
+namespace output {
+
+//------------------------------------------------------construction/destruction
+
+std::shared_ptr< OStreamWriter > OStreamWriter::create( std::ostream& os )
+{
+	return std::shared_ptr< OStreamWriter >( new OStreamWriter( os ) );
+}
+
+OStreamWriter::OStreamWriter( std::ostream& os )
+:	os_( os )
+,	format_( new DefaultTimeFormat() )
+{
+	os_ << "ODEMx Log\n"
+		<< "=========\n";
+}
+
+OStreamWriter::~OStreamWriter()
+{
+}
+
+//---------------------------------------------------------------record handling
+
+void OStreamWriter::consume( const Log::ChannelId channelId, const SimRecord& record )
+{
+	using namespace std;
+
+	std::string timeString = format_->timeToString( record.getTime() );
+	const Producer& sender = record.getSender();
+
+	os_
+	<< timeString << " "
+	<< channel_id::toString( channelId ) << ": "
+	<< sender.getLabel() << "(" << sender.getType().toString() << ") "
+	<< record.getText();
+
+	if( record.hasDetails() )
+	{
+		os_ << " [";
+		for( SimRecord::DetailVec::const_iterator detail = record.getDetails().begin();
+			detail != record.getDetails().end(); ++detail )
+		{
+			if( detail != record.getDetails().begin() )
+			{
+				os_ << " | ";
+			}
+			os_ << detail->first << "="
+				<< detail->second.as<std::string>();
+		}
+		os_ << "]";
+	}
+
+	if( record.hasScope() )
+	{
+		os_ << " [Class Scope: " << record.getScope().toString() << "]";
+	}
+
+	os_ << std::endl;
+}
+
+//-----------------------------------------------------------------------setters
+
+void OStreamWriter::setTimeFormat( TimeFormat* timeFormat )
+{
+	format_.reset( timeFormat );
+}
+
+} } } // namespace odemx::data::output
diff --git a/odemx-lite/src/data/output/TimeFormat.cpp b/odemx-lite/src/data/output/TimeFormat.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..73ed78175fe18eab0b63653c90be6457faa44a5d
--- /dev/null
+++ b/odemx-lite/src/data/output/TimeFormat.cpp
@@ -0,0 +1,210 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file TimeFormat.cpp
+ * @author Ronald Kluth
+ * @date created at 2008/03/14
+ * @brief Implementation of odemx::data::output::TimeFormat
+ * @sa TimeFormat.h
+ * @since 2.1
+ */
+
+#if defined(_MSC_VER)
+#pragma warning(disable : 4244) // conversion of SimTime to double possible data loss
+#endif
+
+#include <odemx/data/output/TimeFormat.h>
+#include <odemx/util/Exceptions.h>
+
+#include <cmath>
+#include <cassert>
+#include <iomanip>
+#include <stdexcept>
+
+namespace odemx {
+namespace data {
+namespace output {
+
+//------------------------------------------------------construction/destruction
+
+TimeFormat::TimeFormat()
+:	base( 0, 0, 0, static_cast< base::SimTime >(0), TimeUnit::none )
+{
+	resetTimeValues();
+}
+
+TimeFormat::TimeFormat( const TimeBase& timeBase )
+:	base( timeBase )
+{
+	resetTimeValues();
+}
+
+TimeFormat::~TimeFormat()
+{
+}
+
+//-----------------------------------------------------------------------setters
+
+void TimeFormat::setTimeBase( unsigned short year, unsigned short month,
+		unsigned short day, base::SimTime dayTimeOffset, TimeUnit::Type unit )
+{
+	base.year = year;
+	base.month = month;
+	base.day = day;
+	base.offset = dayTimeOffset;
+	base.unit = unit;
+}
+
+void TimeFormat::setTimeBase( const TimeBase& timeBase )
+{
+	base = timeBase;
+}
+
+void TimeFormat::resetTimeValues()
+{
+	simTime = static_cast< base::SimTime >(0);
+	year = month = day = hour = min = 0;
+	sec = 0.0;
+}
+
+//-----------------------------------------------------------------------getters
+
+const TimeBase& TimeFormat::getTimeBase() const
+{
+	return base;
+}
+
+//-------------------------------------------------------------string conversion
+
+const std::string TimeFormat::timeToString( base::SimTime time )
+{
+	computeTimeValues( time );
+	return makeString();
+}
+
+unsigned short TimeFormat::daysOfMonth( unsigned short month, unsigned short year )
+{
+	bool leapYear = false;
+
+	if( year % 4 == 0 ) leapYear = true;
+	if( year % 100 == 0 ) leapYear = false;
+	if( year % 400 == 0 ) leapYear = true;
+
+    switch( month )
+    {
+	case 4:
+	case 6:
+	case 9:
+	case 11:
+		return 30;
+
+	case 2:
+		return leapYear ? 29 : 28;
+
+	default:
+		return 31;
+    }
+}
+
+void TimeFormat::computeTimeValues( base::SimTime time )
+{
+	resetTimeValues();
+
+	if( getTimeBase().unit == TimeUnit::none )
+	{
+		throw DataException( "TimeFormat::computeTimeValues():"
+				" cannot compute time, no base unit given" );
+	}
+
+	// store the SimTime in minutes for easy computation
+	double simMinutes = 0.0;
+	// store the daytime offset
+	double dayTimeOffset = 0.0;
+
+	// convert SimTime to minutes for convenience
+	// by evaluating the given Time::unit of the Format definition
+	switch( getTimeBase().unit )
+	{
+	case TimeUnit::milliseconds:
+		simMinutes = time / double(60000);
+		dayTimeOffset = getTimeBase().offset / double(60000);
+		break;
+
+	case TimeUnit::seconds:
+		simMinutes = time / double(60);
+		dayTimeOffset = getTimeBase().offset / double(60);
+		break;
+
+	case TimeUnit::minutes:
+		simMinutes = time;
+		dayTimeOffset = getTimeBase().offset;
+		break;
+
+	case TimeUnit::hours:
+		simMinutes = time * 60;
+		dayTimeOffset = getTimeBase().offset * 60;
+		break;
+
+	case TimeUnit::none:
+		assert(false);
+	}
+
+	// compute number of days from minutes
+	day = (unsigned short) floor( simMinutes / 1440.0 ); // 24h * 60' = 1440'
+	// subtract days from minutes to get the day time
+	simMinutes = simMinutes - ( day * 1440.0 );
+
+	// add time base data representing the starting point of the simulation
+	year += getTimeBase().year;
+	month += getTimeBase().month;
+	day += getTimeBase().day;
+	simMinutes += dayTimeOffset;
+
+	// increase number of days if offset addition put minutes over 1440
+	while( simMinutes > 1440.0 )
+	{
+		++day;
+		simMinutes -= 1440.0;
+	}
+
+	// determine month and year
+	while( day > daysOfMonth( month, year ) )
+	{
+		day -= daysOfMonth( month, year );
+		++month;
+
+		if( month > 12 )
+		{
+			month = 1;
+			++year;
+		}
+	}
+
+	// compute the day time in hours, minutes, seconds and milliseconds
+	hour = (unsigned short) floor( simMinutes / 60.0 );
+	simMinutes -= hour * 60.0;
+
+	// get minutes integer value
+	min = (unsigned short) floor( simMinutes );
+
+	// get seconds with milliseconds as double value
+	sec = ( simMinutes - min ) * 60.0;
+}
+
+} } } // namespace odemx::data::output
diff --git a/odemx-lite/src/protocol/Device.cpp b/odemx-lite/src/protocol/Device.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f3cbd2a8d9ff0bd0ed2ee0c6b7cbbe263d2a77b0
--- /dev/null
+++ b/odemx-lite/src/protocol/Device.cpp
@@ -0,0 +1,273 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Device.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/10/31
+ * @brief Implementation of class odemx::protocol::Device
+ * @sa Device.h
+ * @since 3.0
+ */
+
+#include <odemx/protocol/Device.h>
+#include <odemx/protocol/Layer.h>
+#include <odemx/protocol/Medium.h>
+#include <odemx/protocol/Sap.h>
+#include <odemx/protocol/Pdu.h>
+#include <odemx/synchronization/Timer.h>
+
+namespace odemx {
+namespace protocol {
+
+Device::Device( base::Simulation& sim, const data::Label& label )
+:	ServiceProvider( sim, label )
+,	receiveSap_( 0 )
+,	address_()
+,	medium_( 0 )
+,	transmissionCount_( 0 )
+,	collisionDetection_( sim, label + " collision detection", synchronization::IMemory::COLLISION_DETECTION )
+,	collisionOccurred_( false )
+{
+	receiveSap_ = addSap( "odemx_internal_device_receive_SAP" );
+	assert( receiveSap_ );
+}
+
+Device::~Device()
+{
+}
+
+void Device::setAddress( const AddressType& addr )
+{
+	ODEMX_TRACE << log( "set address" )
+			.detail( "value", addr )
+			.scope( typeid(Device) );
+
+	address_ = addr;
+}
+
+const Device::AddressType& Device::getAddress() const
+{
+	return address_;
+}
+
+void Device::setMedium( Medium& medium )
+{
+	if( medium_ && medium_ != &medium )
+	{
+		error << log( "Device::setMedium():"
+					"attempt to register device with another medium" )
+					.scope( typeid(Device) );
+	}
+	else
+	{
+		ODEMX_TRACE << log( "set medium" )
+					.detail( "label", medium.getLabel() )
+					.scope( typeid(Device) );
+
+		medium_ = &medium;
+	}
+}
+
+void Device::resetMedium()
+{
+	medium_ = 0;
+}
+
+bool Device::hasMedium() const
+{
+	return medium_ != 0;
+}
+
+bool Device::busy() const
+{
+	return transmissionCount_ >= 1;
+}
+
+void Device::incTransmissionCount()
+{
+	++transmissionCount_;
+
+	ODEMX_TRACE << log( "increase transmission count" )
+				.detail( "value", transmissionCount_ )
+				.scope( typeid(Device) );
+
+	if( transmissionCount_ > 1 )
+	{
+		collisionOccurred_ = true;
+		collisionDetection_.alert();
+
+		ODEMX_TRACE << log( "collision occurred" ).scope( typeid(Device) );
+
+		assert( medium_ );
+		medium_->collision();
+	}
+}
+
+void Device::decTransmissionCount()
+{
+	if( transmissionCount_ > 0 )
+	{
+		--transmissionCount_;
+	}
+
+	ODEMX_TRACE << log( "decrease transmission count" )
+				.detail( "value", transmissionCount_ )
+				.scope( typeid(Device) );
+}
+
+unsigned int Device::getTransmissionCount() const
+{
+	return transmissionCount_;
+}
+
+bool Device::hasCollisionDetection()
+{
+	return false;
+}
+
+void Device::startTransmission()
+{
+	ODEMX_TRACE << log( "start transmission" ).scope( typeid(Device) );
+
+	medium_->signalTransmissionStart( this );
+}
+
+void Device::endTransmission( PduPtr p )
+{
+	ODEMX_TRACE << log( "end transmission" ).scope( typeid(Device) );
+
+	medium_->signalTransmissionEnd( this, p );
+}
+
+bool Device::send( PduPtr p )
+{
+	if( ! medium_ )
+	{
+		error << log( "Device::transmit(): device not connected to a medium" )
+				.scope( typeid( Device ) );
+		return false;
+	}
+
+	if( busy() )
+	{
+		ODEMX_TRACE << log( "medium busy" ).scope( typeid(Device) );
+
+		return false;
+	}
+
+	ODEMX_TRACE << log( "send" ).scope( typeid(Device) );
+
+	// start transmission
+	incTransmissionCount();
+	collisionOccurred_ = false;
+
+	base::SimTime duration = computeTransmissionDuration( p->getSize() );
+	synchronization::Timer durationTimer( getSimulation(), getLabel() + " duration timer" );
+	durationTimer.setIn( duration );
+	
+	startTransmission();
+
+	synchronization::IMemory* alerter = 0;
+
+	if( hasCollisionDetection() )
+	{
+		alerter = Process::wait( &durationTimer, &collisionDetection_ );
+	}
+	else
+	{
+		alerter = Process::wait( &durationTimer );
+	}
+
+	if( ! alerter )
+	{
+		warning << log( "Device::send(): wait state ended by non-memory object" )
+					.scope( typeid(Device) );
+	}
+
+	// detected collision, end transmission
+	// in the first case, the waking time is just earlier
+	// invalid data is sent in any case
+	if( alerter == &collisionDetection_ || collisionOccurred_ )
+	{
+		if( alerter == &collisionDetection_ )
+		{
+			ODEMX_TRACE << log( "collision detected" ).scope( typeid(Device) );
+		}
+		else
+		{
+			ODEMX_TRACE << log( "collision occurred" ).scope( typeid(Device) );
+		}
+		endTransmission( PduPtr() );
+		decTransmissionCount();
+		return false;
+	}
+
+	// transmission finished
+	endTransmission( p );
+	decTransmissionCount();
+
+	ODEMX_TRACE << log( "transmission succeeded" ).scope( typeid(Device) );
+
+	return true;
+}
+
+void Device::handleInput( const std::string& sapName, PduPtr p )
+{
+	if( sapName == receiveSap_->getName() )
+	{
+		ODEMX_TRACE << log( "handle receive" ).scope( typeid(Device) );
+
+		handleReceive( p );
+	}
+	else
+	{
+		ODEMX_TRACE << log( "handle send" ).scope( typeid(Device) );
+
+		handleSend( sapName, p );
+	}
+}
+
+	/// Pass a message to the service user, i.e. to the upper layer via the device's SAP
+void Device::pass( const std::string& upperLayerSap, PduPtr p )
+{
+	Sap* sap = getLayer()->getUpperLayer()->getSap( upperLayerSap );
+	if( sap )
+	{
+		ODEMX_TRACE << log( "pass" )
+				.detail( "SAP", upperLayerSap )
+				.scope( typeid(Device) );
+
+		sap->write( p );
+	}
+	else
+	{
+		warning << log( "Device::pass(): upper layer does not offer SAP" )
+				.detail( "name", upperLayerSap )
+				.scope( typeid(Device) );
+	}
+}
+
+void Device::receive( PduPtr p )
+{
+	ODEMX_TRACE << log( "receive" ).scope( typeid(Device) );
+
+	receiveSap_->write( p );
+}
+
+} } // namespace odemx::protocol
diff --git a/odemx-lite/src/protocol/Entity.cpp b/odemx-lite/src/protocol/Entity.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0a664b0358a1a801c1d3d514a00ce1c816b04cbe
--- /dev/null
+++ b/odemx-lite/src/protocol/Entity.cpp
@@ -0,0 +1,81 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Entity.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/10/13
+ * @brief Implementation of class odemx::protocol::Entity
+ * @sa Entity.h
+ * @since 3.0
+ */
+
+#include <odemx/protocol/Entity.h>
+#include <odemx/protocol/Layer.h>
+
+namespace odemx {
+namespace protocol {
+
+Entity::Entity( base::Simulation& sim, const data::Label& label )
+:	ServiceProvider( sim, label )
+{
+}
+
+Entity::~Entity()
+{
+}
+
+void Entity::send( const std::string& lowerLayerSap, PduPtr p )
+{
+	Sap* sap = getLayer()->getLowerLayer()->getSap( lowerLayerSap );
+	if( sap )
+	{
+		ODEMX_TRACE << log( "send" )
+				.detail( "SAP", lowerLayerSap )
+				.scope( typeid(Entity) );
+
+		sap->write( p );
+	}
+	else
+	{
+		warning << log( "Entity::send(): lower layer does not offer SAP" )
+				.detail( "name", lowerLayerSap )
+				.scope( typeid(Entity) );
+	}
+}
+
+void Entity::pass( const std::string& upperLayerSap, PduPtr p )
+{
+	Sap* sap = getLayer()->getUpperLayer()->getSap( upperLayerSap );
+	if( sap )
+	{
+		ODEMX_TRACE << log( "pass" )
+				.detail( "SAP", upperLayerSap )
+				.scope( typeid(Entity) );
+
+		sap->write( p );
+	}
+	else
+	{
+		warning << log( "Entity::pass(): upper layer does not offer SAP" )
+				.detail( "name", upperLayerSap )
+				.scope( typeid(Entity) );
+	}
+}
+
+} } // namespace odemx::protocol
diff --git a/odemx-lite/src/protocol/ErrorModelDraw.cpp b/odemx-lite/src/protocol/ErrorModelDraw.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3cb0493bc1e6175493ee119e31270bc38a792b75
--- /dev/null
+++ b/odemx-lite/src/protocol/ErrorModelDraw.cpp
@@ -0,0 +1,53 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ErrorModelDraw.cpp
+ * @author Ronald Kluth
+ * @date created at 2010/04/05
+ * @brief Implementation of class odemx::protocol::ErrorModelDraw
+ * @sa ErrorModelDraw.h
+ * @since 3.0
+ */
+
+#include <odemx/protocol/ErrorModelDraw.h>
+
+namespace odemx {
+namespace protocol {
+
+ErrorModelDraw::ErrorModelDraw( base::Simulation& sim, const data::Label& label,
+		double probability )
+:	draw_( sim, label + " draw", probability )
+{}
+
+ErrorModelDraw::~ErrorModelDraw()
+{
+}
+
+ErrorModelPtr ErrorModelDraw::create( base::Simulation& sim, const data::Label& label,
+		double probability )
+{
+	return ErrorModelPtr( new ErrorModelDraw( sim, label, probability ) );
+}
+
+bool ErrorModelDraw::apply( PduPtr p )
+{
+	return draw_.sample() == 1;
+}
+
+} } // namespace odemx::protocol
diff --git a/odemx-lite/src/protocol/Layer.cpp b/odemx-lite/src/protocol/Layer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9c100517db6cbd3ad23e2bee028f13035be6da99
--- /dev/null
+++ b/odemx-lite/src/protocol/Layer.cpp
@@ -0,0 +1,159 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Layer.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/10/13
+ * @brief Implementation of class odemx::protocol::Layer
+ * @sa Layer.h
+ * @since 3.0
+ */
+
+#include <odemx/protocol/Layer.h>
+#include <odemx/protocol/Sap.h>
+#include <odemx/protocol/ServiceProvider.h>
+#include <odemx/util/DeletePtr.h>
+
+#include <algorithm> // for_each, find_if
+
+namespace odemx {
+namespace protocol {
+
+Layer::Layer( base::Simulation& sim, const data::Label& label )
+:	data::Producer( sim, label )
+,	serviceProviders_()
+,	saps_()
+,	upperLayer_( 0 )
+,	lowerLayer_( 0 )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Layer) );
+}
+
+Layer::~Layer()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Layer) );
+
+	std::for_each(
+			serviceProviders_.begin(),
+			serviceProviders_.end(),
+			DeletePtr< ServiceProvider >() );
+};
+
+void Layer::addServiceProvider( ServiceProvider* sp )
+{
+	assert( sp );
+
+	ODEMX_TRACE << log( "add service provider" )
+					.detail( "label", sp->getLabel() )
+					.scope( typeid(Layer) );
+
+	sp->setLayer( this );
+	for( ServiceProvider::SapVec::const_iterator iter = sp->getSaps().begin();
+		iter != sp->getSaps().end(); ++iter )
+	{
+		addSap( *iter );
+	}
+	serviceProviders_.push_back( sp );
+}
+
+void Layer::addSap( Sap* sap )
+{
+	assert( sap );
+
+	std::pair< SapMap::iterator, bool > result =
+			saps_.insert( SapMap::value_type( sap->getName(), sap ) );
+
+	if( result.second )
+	{
+		ODEMX_TRACE << log( "add SAP" )
+						.detail( "name", sap->getName() )
+						.scope( typeid(Layer) );
+	}
+	else
+	{
+		warning << log( "Layer::addSap(): SAP already in map, insertion failed")
+				.detail( "name", sap->getName() )
+				.scope( typeid(Layer) );
+	}
+}
+
+bool Layer::removeSap( const std::string& sap )
+{
+	SapMap::iterator found = saps_.find( sap );
+
+	if( found != saps_.end() )
+	{
+		ODEMX_TRACE << log( "remove SAP" )
+						.detail( "name", sap )
+						.scope( typeid(Layer) );
+
+		saps_.erase( found );
+		return true;
+	}
+	else
+	{
+		warning << log( "Layer::removeSap(): SAP not found")
+				.detail( "name", sap )
+				.scope( typeid(Layer) );
+	}
+	return false;
+}
+
+Sap* Layer::getSap( const std::string& sap ) const
+{
+	SapMap::const_iterator found = saps_.find( sap );
+
+	if( found != saps_.end() )
+	{
+		return found->second;
+	}
+	return 0;
+}
+
+Layer::SapMap& Layer::getSaps()
+{
+	return saps_;
+}
+
+void Layer::setUpperLayer( Layer* layer )
+{
+	upperLayer_ = layer;
+}
+
+Layer* Layer::getUpperLayer() const
+{
+	return upperLayer_;
+}
+
+void Layer::setLowerLayer( Layer* layer )
+{
+	lowerLayer_ = layer;
+}
+
+Layer* Layer::getLowerLayer() const
+{
+	return lowerLayer_;
+}
+
+const Layer::ServiceProviderVec& Layer::getServiceProviders() const
+{
+	return serviceProviders_;
+}
+
+} } // namespace odemx::protocol
diff --git a/odemx-lite/src/protocol/Medium.cpp b/odemx-lite/src/protocol/Medium.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..33e8eb17c68ab17959a334bf0d1c1b44c237e871
--- /dev/null
+++ b/odemx-lite/src/protocol/Medium.cpp
@@ -0,0 +1,307 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Medium.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/11/01
+ * @brief Implementation of class odemx::protocol::Medium
+ * @sa Medium.h
+ * @since 3.0
+ */
+
+#include <odemx/protocol/Medium.h>
+#include <odemx/protocol/Device.h>
+#include <odemx/protocol/ErrorModel.h>
+#include <odemx/protocol/Pdu.h>
+#include <odemx/util/TypeToString.h>
+
+namespace odemx {
+namespace protocol {
+
+//---------------------------------------------------------------------link info
+
+Medium::LinkInfo::LinkInfo()
+{
+}
+
+Medium::LinkInfo::LinkInfo( base::SimTime delay, ErrorModelPtr errorModel )
+:	delay_( delay )
+,	errorModel_( errorModel )
+{
+}
+
+//-----------------------------------------------------------transmission events
+
+Medium::TransmissionStart::TransmissionStart( base::Simulation& sim,
+		const data::Label& label, Device& device )
+:	Event( sim, label )
+,	device_( &device )
+{
+}
+
+void Medium::TransmissionStart::eventAction()
+{
+	device_->incTransmissionCount();
+}
+
+Medium::TransmissionEnd::TransmissionEnd( base::Simulation& sim,
+		const data::Label& label, Device& device, PduPtr p )
+:	Event( sim, label )
+,	device_( &device )
+,	pdu_( p )
+{
+}
+
+void Medium::TransmissionEnd::eventAction()
+{
+	device_->decTransmissionCount();
+	if( pdu_ )
+	{
+		device_->receive( pdu_ );
+	}
+}
+
+//------------------------------------------------------construction/destruction
+
+Medium::Medium( base::Simulation& sim, const data::Label& label )
+:	Producer( sim, label )
+,	topology_()
+,	defaultErrorModel_()
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Medium) );
+}
+
+Medium::~Medium()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Medium) );
+}
+
+void Medium::signalTransmissionStart( Device* device )
+{
+	assert( device );
+
+	ODEMX_TRACE << log( "signal transmission start" )
+			.detail( "device", device->getLabel() )
+			.scope( typeid(Medium) );
+
+	LinkInfoMap& receivers = topology_[ device ];
+	for( LinkInfoMap::const_iterator iter = receivers.begin();
+		iter != receivers.end(); ++iter )
+	{
+		// get the neighbor and the link properties
+		Device* peerDevice = iter->first;
+		const LinkInfo& link = iter->second;
+
+		// ignore self-messaging
+		if( device == peerDevice )
+		{
+			continue;
+		}
+		
+		// data is propagated if there is no error model for the link,
+		// or if the data passes the error model
+		base::Event* event = new TransmissionStart( getSimulation(),
+				"Transmission Start", *peerDevice );
+		event->scheduleIn( link.delay_ );
+	}
+}
+
+void Medium::signalTransmissionEnd( Device* device, PduPtr p )
+{
+	ODEMX_TRACE << log( "signal transmission end" )
+			.detail( "device", device->getLabel() )
+			.scope( typeid(Medium) );
+
+	LinkInfoMap& receivers = topology_[ device ];
+	for( LinkInfoMap::const_iterator iter = receivers.begin();
+		iter != receivers.end(); ++iter )
+	{
+		statistics << count( "transmissions" ).scope( typeid(Medium) );
+
+		// get the neighbor and the link properties
+		Device* peerDevice = iter->first;
+		const LinkInfo& link = iter->second;
+
+		// ignore self-messaging
+		if( device == peerDevice )
+		{
+			continue;
+		}
+
+		// the pdu gets clone
+		PduPtr clonePdu;
+		if( p )
+		{
+			clonePdu = p->clone();
+		}
+
+		// data is propagated if there is no error model for the link,
+		// or if the data passes the error model
+		if( ! link.errorModel_ || link.errorModel_->apply( clonePdu ) )
+		{
+			base::Event* event = new TransmissionEnd( getSimulation(),
+					"Transmission End", *peerDevice, clonePdu );
+			event->scheduleIn( link.delay_ );
+
+			statistics << count( "deliveries" ).scope( typeid(Medium) );
+		}
+		else // failed to pass error model, cannot not deliver no PDU
+		{
+			base::Event* event = new TransmissionEnd( getSimulation(),
+					"Transmission End", *peerDevice, PduPtr() );
+			event->scheduleIn( link.delay_ );
+
+			statistics << count( "errors" ).scope( typeid(Medium) );
+		}
+	}
+}
+
+void Medium::collision() const
+{
+	statistics << count( "collisions" ).scope( typeid(Medium) );
+}
+
+void Medium::setErrorModel( ErrorModelPtr errorModel )
+{
+	ODEMX_TRACE << log( "set error model" )
+			.detail( "type", typeToString( typeid( *errorModel ) ) )
+			.scope( typeid(Medium) );
+
+	defaultErrorModel_ = errorModel;
+}
+
+bool Medium::addLink( const Device::AddressType& srcAddr,
+		const Device::AddressType& destAddr, base::SimTime delay,
+		bool duplex, ErrorModelPtr errorModel )
+{
+	ODEMX_TRACE << log( "add link" )
+			.detail( "from", srcAddr )
+			.detail( "to", destAddr )
+			.detail( "delay", delay )
+			.detail( "error model", errorModel ? typeToString( typeid( *errorModel ) ) : "default" )
+			.scope( typeid(Medium) );
+
+	Device* src = getDevice( srcAddr );
+	Device* dest = getDevice( destAddr );
+
+	assert( src );
+	assert( dest );
+
+	bool success = addLink( src, dest, delay, errorModel );
+	if( duplex && success )
+	{
+		return addLink( dest, src, delay, errorModel );
+	}
+	return success;
+}
+
+bool Medium::addLink( Device* src, Device* dest, base::SimTime delay,
+		ErrorModelPtr errorModel )
+{
+	if( src == dest )
+	{
+		warning << log( "Medium::addLink(): the given devices are the same" )
+				.scope( typeid( Medium ) );
+		return false;
+	}
+
+	// overwrite existing entries
+	if( errorModel )
+	{
+		topology_[ src ][ dest ] = LinkInfo( delay, errorModel );
+	}
+	else
+	{
+		topology_[ src ][ dest ] = LinkInfo( delay, defaultErrorModel_ );
+	}
+	return true;
+}
+
+void Medium::removeLink( const Device::AddressType& srcAddr,
+		const Device::AddressType& destAddr, bool duplex )
+{
+	ODEMX_TRACE << log( "remove link" )
+			.detail( "from", srcAddr )
+			.detail( "to", destAddr )
+			.scope( typeid(Medium) );
+
+	Device* src = getDevice( srcAddr );
+	Device* dest = getDevice( destAddr );
+
+	removeLink( src, dest );
+	if( duplex )
+	{
+		return removeLink( dest, src );
+	}
+}
+
+void Medium::removeLink( Device* src, Device* dest )
+{
+	if( src == dest )
+	{
+		warning << log( "Medium::removeLink(): the given devices are the same" )
+				.scope( typeid( Medium ) );
+		return;
+	}
+
+	TopologyMap::iterator foundSrc = topology_.find( src );
+	if( foundSrc != topology_.end() )
+	{
+		LinkInfoMap& links = foundSrc->second;
+		LinkInfoMap::iterator foundDest = links.find( dest );
+		if( foundDest != links.end() )
+		{
+			// found link between both nodes, erase LinkInfo
+			links.erase( foundDest );
+		}
+	}
+}
+
+bool Medium::registerDevice( const Device::AddressType& address, Device& device )
+{
+	device.setAddress( address );
+	device.setMedium( *this );
+	return devices_.insert( DeviceMap::value_type( address, &device ) ).second;
+}
+
+Device* Medium::getDevice( const Device::AddressType& address ) const
+{
+	DeviceMap::const_iterator found = devices_.find( address );
+	if( found != devices_.end() )
+	{
+		return found->second;
+	}
+
+	error << log( "Medium::getDevice(): no device registered" )
+			.detail( "address", address )
+			.scope( typeid(Medium) );
+	return 0;
+}
+
+const Medium::TopologyMap& Medium::getTopology() const
+{
+	return topology_;
+}
+
+const Medium::DeviceMap& Medium::getDevices() const
+{
+	return devices_;
+}
+
+} } // namespace odemx::protocol
diff --git a/odemx-lite/src/protocol/Sap.cpp b/odemx-lite/src/protocol/Sap.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dc1ba8384645e3112a1b39e81d04edabb26e7a6b
--- /dev/null
+++ b/odemx-lite/src/protocol/Sap.cpp
@@ -0,0 +1,95 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Sap.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/10/13
+ * @brief Implementation of class odemx::protocol::Sap
+ * @sa Sap.h
+ * @since 3.0
+ */
+
+#include <odemx/protocol/Sap.h>
+#include <odemx/protocol/ServiceProvider.h>
+
+namespace odemx {
+namespace protocol {
+
+//------------------------------------------------------------buffer definitions
+
+Sap::BufferHead::BufferHead( base::Simulation& sim, const data::Label& label, Sap& sap )
+:	synchronization::PortHeadT< PduPtr >( sim, label + " " + sap.getName() + " buffer",
+		synchronization::WAITING_MODE, 1000, 0 )
+,	sap_( &sap )
+{}
+
+Sap& Sap::BufferHead::getSap() const
+{
+	return *sap_;
+}
+
+Sap::BufferHead::Ptr Sap::BufferHead::create( base::Simulation& sim,
+		const data::Label& label, Sap& sap )
+{
+	Ptr rv( new BufferHead( sim, label, sap ) );
+	rv->initPort();
+	return rv;
+}
+
+//------------------------------------------------------construction/destruction
+
+Sap::Sap( base::Simulation& sim, const data::Label& label, const std::string& name )
+:	name_( name )
+{
+	queueHead_ = BufferHead::create( sim, label, *this );
+	queueTail_ = queueHead_->getTail();
+}
+
+Sap::~Sap()
+{
+}
+
+//-----------------------------------------------------------------public access
+
+const std::string& Sap::getName() const
+{
+	return name_;
+}
+
+Sap::BufferHead* Sap::getBuffer() const
+{
+	return queueHead_.get();
+}
+
+void Sap::write( PduPtr p )
+{
+	queueTail_->put( p );
+}
+
+PduPtr Sap::read()
+{
+	std::unique_ptr< PduPtr > p = queueHead_->get();
+	if( ! p.get() )
+	{
+		return PduPtr();
+	}
+	return *p;
+}
+
+} } // namespace odemx::protocol
diff --git a/odemx-lite/src/protocol/Service.cpp b/odemx-lite/src/protocol/Service.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d50e88e6eb668fb789214620b11f4e154627d0d3
--- /dev/null
+++ b/odemx-lite/src/protocol/Service.cpp
@@ -0,0 +1,237 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Service.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/10/12
+ * @brief Implementation of class odemx::protocol::Service
+ * @sa Service.h
+ * @since 3.0
+ */
+
+#include <odemx/protocol/Service.h>
+#include <odemx/protocol/ErrorModel.h>
+#include <odemx/protocol/Layer.h>
+#include <odemx/util/DeletePtr.h>
+
+namespace odemx {
+namespace protocol {
+
+//------------------------------------------------------static member definition
+
+Service::AddressMap Service::services_;
+std::shared_ptr< ErrorModel > Service::errorModel_;
+
+//------------------------------------------------------construction/destruction
+
+Service::Service( base::Simulation& sim, const data::Label& label )
+:	ServiceProvider( sim, label )
+,	receiveSap_( 0 )
+{
+	receiveSap_ = addSap( "odemx_internal_service_receive_SAP" );
+	assert( receiveSap_ );
+}
+
+Service::~Service()
+{
+	std::for_each( outputSaps_.begin(), outputSaps_.end(), DeletePtr< Sap >() );
+}
+
+//-------------------------------------------------------------user registration
+
+bool Service::registerService( const AddressType& address, Service& service )
+{
+	service.setAddress( address );
+	return services_.insert( AddressMap::value_type( address, &service ) ).second;
+}
+
+bool Service::removeService( const AddressType& address )
+{
+	AddressMap::iterator found = services_.find( address );
+	if( found != services_.end() )
+	{
+		found->second->address_.clear();
+		services_.erase( found );
+		return true;
+	}
+	return false;
+}
+
+const Service::AddressMap& Service::getAddressMap()
+{
+	return services_;
+}
+
+const Service::AddressType& Service::getAddress() const
+{
+	return address_;
+}
+
+void Service::setAddress( const AddressType& addr )
+{
+	ODEMX_TRACE << log( "set address" )
+			.detail( "value", addr )
+			.scope( typeid(Service) );
+
+	address_ = addr;
+}
+
+//--------------------------------------------------------service implementation
+
+Service* Service::getPeer( const AddressType& peer )
+{
+	AddressMap::const_iterator found = services_.find( peer );
+	if( found != services_.end() )
+	{
+		return found->second;
+	}
+	return 0;
+}
+
+bool Service::send( const AddressType& peerAddress, PduPtr p ) const
+{
+	Service* peer = getPeer( peerAddress );
+	if( peer != 0 )
+	{
+		ODEMX_TRACE << log( "send" )
+				.detail( "peer", peerAddress )
+				.scope( typeid(Service) );
+
+		peer->receive( p );
+		return true;
+	}
+	else
+	{
+		warning << log( "Service::send(): peer not registered" )
+				.detail( "address", peerAddress )
+				.scope( typeid(Service) );
+	}
+	return false;
+}
+
+bool Service::pass( const std::string& sapName, PduPtr p )
+{
+	Sap* sap = 0;
+	if( layer_ )
+	{
+		sap = layer_->getUpperLayer()->getSap( sapName );
+	}
+	else
+	{
+		sap = getReceiveSap( sapName );
+	}
+
+	if( sap )
+	{
+		ODEMX_TRACE << log( "pass" )
+				.detail( "SAP", sapName )
+				.scope( typeid(Service) );
+
+		sap->write( p );
+		return true;
+	}
+	else
+	{
+		warning << log( "Service::pass(): output SAP not found" )
+				.detail( "name", sapName )
+				.scope( typeid(Service) );
+	}
+	return false;
+}
+
+Sap* Service::addReceiveSap( const std::string& name )
+{
+	SapVec::iterator found = std::find_if(
+			outputSaps_.begin(), outputSaps_.end(), Sap::MatchName( name ) );
+	
+	if( found != outputSaps_.end() )
+	{
+		warning << log( "Service::addReceiveSap(): SAP already exists" )
+				.detail( "name", name )
+				.scope( typeid(Service) );
+		return *found;
+	}
+
+	ODEMX_TRACE << log( "add receive SAP" )
+			.detail( "name", name )
+			.scope( typeid(Service) );
+
+	Sap* sap = new Sap( getSimulation(), getLabel(), name );
+	outputSaps_.push_back( sap );
+	return sap;
+}
+
+Sap* Service::getReceiveSap( const std::string& name )
+{
+	SapVec::iterator found = std::find_if(
+			outputSaps_.begin(), outputSaps_.end(), Sap::MatchName( name ) );
+
+	if( found != outputSaps_.end() )
+	{
+		return *found;
+	}
+	return 0;
+}
+
+void Service::receive( PduPtr p )
+{
+	bool pass = true;
+
+	if( errorModel_ )
+	{
+		pass = errorModel_->apply( p );
+	}
+
+	if( pass )
+	{
+		ODEMX_TRACE << log( "receive success" ).scope( typeid(Service) );
+
+		receiveSap_->write( p );
+	}
+	else
+	{
+		ODEMX_TRACE << log( "receive failure" ).scope( typeid(Service) );
+	}
+}
+
+void Service::setErrorModel( std::shared_ptr< ErrorModel > em )
+{
+	errorModel_ = em;
+}
+
+//------------------------------------------------------------process life cycle
+
+void Service::handleInput( const std::string& sap, PduPtr pdu )
+{
+	if( sap == receiveSap_->getName() )
+	{
+		ODEMX_TRACE << log( "handle receive" ).scope( typeid(Service) );
+
+		handleReceive( pdu );
+	}
+	else
+	{
+		ODEMX_TRACE << log( "handle send" ).detail( "input SAP", sap )
+						.scope( typeid(Service) );
+
+		handleSend( sap, pdu );
+	}
+}
+
+} } // namespace odemx::protocol
diff --git a/odemx-lite/src/protocol/ServiceProvider.cpp b/odemx-lite/src/protocol/ServiceProvider.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..70ab8d7411bc251ba96e6434cb52b4c06e77f0b4
--- /dev/null
+++ b/odemx-lite/src/protocol/ServiceProvider.cpp
@@ -0,0 +1,177 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ServiceProvider.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/10/29
+ * @brief Implementation of class odemx::protocol::ServiceProvider
+ * @sa ServiceProvider.h
+ * @since 3.0
+ */
+
+#include <odemx/protocol/ServiceProvider.h>
+#include <odemx/protocol/Layer.h>
+#include <odemx/protocol/Sap.h>
+#include <odemx/util/DeletePtr.h>
+
+#include <algorithm> // for_each, find_if
+
+namespace odemx {
+namespace protocol {
+
+//------------------------------------------------------construction/destruction
+
+ServiceProvider::ServiceProvider( base::Simulation& sim, const data::Label& label )
+:	base::Process( sim, label )
+,	layer_( 0 )
+,	saps_()
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(ServiceProvider) );
+	this->activate();
+}
+
+ServiceProvider::~ServiceProvider()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(ServiceProvider) );
+
+	std::for_each( saps_.begin(), saps_.end(), DeletePtr< Sap >() );
+}
+
+//------------------------------------------------------------process life cycle
+
+int ServiceProvider::main()
+{
+	while( true )
+	{
+		if( sapQueues_.empty() )
+		{
+			error << log( "ServiceProvider::main(): "
+					"no SAPs registered, cannot enter wait state" )
+					.scope( typeid(ServiceProvider) );
+			return -1;
+		}
+
+		synchronization::IMemory* alerter = base::Process::wait( &sapQueues_ );
+		if( alerter != 0 )
+		{
+			Sap::BufferHead* sapQ = static_cast< Sap::BufferHead* >( alerter );
+			const std::string& sapName = sapQ->getSap().getName();
+			
+			ODEMX_TRACE << log( "handle input" )
+					.detail( "SAP", sapName )
+					.scope( typeid(ServiceProvider) );
+
+			handleInput( sapName, sapQ->getSap().read() );
+		}
+		else
+		{
+			error << log( "ServiceProvider::main(): alerter is 0" )
+					.scope( typeid(ServiceProvider) );
+		}
+	}
+	return 0;
+}
+
+//-----------------------------------------------------------------member access
+
+void ServiceProvider::setLayer( Layer* layer )
+{
+	assert( layer );
+
+	ODEMX_TRACE << log( "set layer" )
+			.detail( "label", layer->getLabel() )
+			.scope( typeid(ServiceProvider) );
+
+	layer_ = layer;
+}
+
+Layer* ServiceProvider::getLayer() const
+{
+	return layer_;
+}
+
+Sap* ServiceProvider::addSap( const std::string& name )
+{
+	SapVec::iterator found = std::find_if(
+			saps_.begin(), saps_.end(), Sap::MatchName( name ) );
+
+	if( found != saps_.end() )
+	{
+		warning << log( "ServiceProvider::addSap(): SAP already exists" )
+				.detail( "name", name )
+				.scope( typeid(ServiceProvider) );
+		return *found;
+	}
+
+	ODEMX_TRACE << log( "add SAP" )
+			.detail( "name", name )
+			.scope( typeid(ServiceProvider) );
+
+	Sap* sap = new Sap( getSimulation(), getLabel(), name );
+	saps_.push_back( sap );
+	sapQueues_.push_back( sap->getBuffer() );
+
+	if( layer_ )
+	{
+		layer_->addSap( sap );
+	}
+	return sap;
+}
+
+bool ServiceProvider::removeSap( const std::string& name )
+{
+	SapVec::iterator found = std::find_if(
+			saps_.begin(), saps_.end(), Sap::MatchName( name ) );
+
+	if( found != saps_.end() )
+	{
+ 		ODEMX_TRACE << log( "remove SAP" )
+ 				.detail( "name", name )
+ 				.scope( typeid(ServiceProvider) );
+
+ 		if( layer_ )
+ 		{
+ 			layer_->removeSap( name );
+ 		}
+
+ 		delete *found;
+ 		saps_.erase( found );
+ 		return true;
+	}
+ 	return false;
+}
+
+Sap* ServiceProvider::getSap( const std::string& name ) const
+{
+	SapVec::const_iterator found = std::find_if(
+			saps_.begin(), saps_.end(), Sap::MatchName( name ) );
+			
+	if( found != saps_.end() )
+	{
+		return *found;
+	}
+	return 0;
+}
+
+const ServiceProvider::SapVec& ServiceProvider::getSaps() const
+{
+	return saps_;
+}
+
+} } // namespace odemx protocol
diff --git a/odemx-lite/src/protocol/Stack.cpp b/odemx-lite/src/protocol/Stack.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..95af4014b2032047d192c5cc1e6b903d576c297c
--- /dev/null
+++ b/odemx-lite/src/protocol/Stack.cpp
@@ -0,0 +1,130 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009, 2010 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Stack.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/10/16
+ * @brief Implementation of class odemx::protocol::Stack
+ * @sa Stack.h
+ * @since 3.0
+ */
+
+#include <odemx/protocol/Stack.h>
+#include <odemx/protocol/Sap.h>
+#include <odemx/protocol/Layer.h>
+#include <odemx/util/DeletePtr.h>
+
+namespace odemx {
+namespace protocol {
+
+Stack::Stack( base::Simulation& sim, const data::Label& label )
+:	data::Producer( sim, label )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Stack) );
+
+	layers_.push_back( new Layer( sim, label + " internal top layer" ) );
+}
+
+Stack::~Stack()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Stack) );
+
+	// delete SAPs held by top layer
+	// (the layer only deletes its service providers)
+	Layer::SapMap& saps = layers_.front()->getSaps();
+	for( Layer::SapMap::iterator iter = saps.begin(); iter != saps.end(); ++iter )
+	{
+		delete iter->second;
+	}
+
+	// delete all layers
+	std::for_each( layers_.begin(), layers_.end(), DeletePtr< Layer >() );
+}
+
+Sap* Stack::getSap( const std::string& name ) const
+{
+	if( layers_.size() > 1 )
+	{
+		Sap* sap = layers_[ 1 ]->getSap( name );
+		if( sap )
+		{
+			return sap;
+		}
+		else
+		{
+			error << log( "Stack::getSap(): SAP not found in top layer" )
+					.detail( "name", name )
+					.scope( typeid(Stack) );
+		}
+	}
+	else
+	{
+		error << log( "Stack::getSap():"
+				"no service providing layer, cannot access SAP" )
+				.detail( "name", name )
+				.scope( typeid(Stack) );
+	}
+	return 0;
+}
+
+void Stack::addLayer( Layer* layer )
+{
+	ODEMX_TRACE << log( "add layer" )
+					.detail( "label", layer->getLabel() )
+					.scope( typeid(Stack) );
+
+	layers_.back()->setLowerLayer( layer );
+	layer->setUpperLayer( layers_.back() );
+	layers_.push_back( layer );
+}
+
+Sap* Stack::addReceiveSap( const std::string& name )
+{
+	Layer* topLayer = layers_.front();
+	Sap* sap = topLayer->getSap( name );
+
+	if( sap )
+	{
+		warning << log( "Stack::addReceiveSap(): SAP already exists" )
+				.detail( "name", name )
+				.scope( typeid(Stack) );
+	}
+	else
+	{
+		ODEMX_TRACE << log( "add receive SAP" )
+				.detail( "name", name )
+				.scope( typeid(Stack) );
+
+		sap = new Sap( getSimulation(), getLabel(), name );
+		topLayer->addSap( sap );
+	}
+	return sap;
+}
+
+Sap* Stack::getReceiveSap( const std::string& name ) const
+{
+	return layers_.front()->getSap( name );
+}
+
+const Stack::LayerVec& Stack::getLayers() const
+{
+	return layers_;
+}
+
+} } // namespace odemx::protocol
diff --git a/odemx-lite/src/random/ContinuousConst.cpp b/odemx-lite/src/random/ContinuousConst.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5cff2ce94010e8c96e2f3821aebb3822104a257d
--- /dev/null
+++ b/odemx-lite/src/random/ContinuousConst.cpp
@@ -0,0 +1,68 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file ContinuousConst.cpp
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Implementation of odemx::random::ContinuousConst
+ */
+
+#include <odemx/random/ContinuousConst.h>
+
+namespace odemx {
+namespace random {
+
+//------------------------------------------------------construction/destruction
+
+ContinuousConst::ContinuousConst( base::Simulation& sim, const data::Label& label,
+		double value )
+:	ContinuousDist( sim, label )
+,	value_( value )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(ContinuousConst) );
+
+	statistics << param( "seed", Dist::getSeed() ).scope( typeid(ContinuousConst) );
+	statistics << param( "value", value_ ).scope( typeid(ContinuousConst) );
+}
+
+ContinuousConst::~ContinuousConst()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(ContinuousConst) );
+}
+
+//------------------------------------------------------------------------sample
+
+double ContinuousConst::sample()
+{
+	ODEMX_TRACE << log( "sample" ).scope( typeid(ContinuousConst) );
+
+	statistics << count( "uses" ).scope( typeid(ContinuousConst) );
+
+	return value_;
+}
+
+//-----------------------------------------------------------------------getters
+
+double ContinuousConst::getValue()
+{
+	return value_;
+}
+
+} } // namespace odemx::random
diff --git a/odemx-lite/src/random/ContinuousDist.cpp b/odemx-lite/src/random/ContinuousDist.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..09c1e2defc396676f387de02ee5969a901cf57fc
--- /dev/null
+++ b/odemx-lite/src/random/ContinuousDist.cpp
@@ -0,0 +1,48 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file ContinuousDist.cpp
+
+	\author Ralf Gerstenberger
+
+	\date created at 2003/05/09
+
+	\brief Implementation of odemx::random::ContinuousDist
+
+	\sa ContinuousDist.h
+
+	\since 1.0
+*/
+
+#include <odemx/random/ContinuousDist.h>
+
+namespace odemx {
+namespace random {
+
+//------------------------------------------------------construction/destruction
+
+ContinuousDist::ContinuousDist( base::Simulation& sim, const data::Label& label )
+:	Dist( sim, label )
+{
+}
+
+ContinuousDist::~ContinuousDist()
+{
+}
+
+} } // namespace odemx::random
diff --git a/odemx-lite/src/random/DiscreteConst.cpp b/odemx-lite/src/random/DiscreteConst.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dbe1bc64b9c185f6c739d3eb15155dc4aa8773e6
--- /dev/null
+++ b/odemx-lite/src/random/DiscreteConst.cpp
@@ -0,0 +1,67 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file DiscreteConst.cpp
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Implementation of odemx::random::DiscreteConst
+ */
+
+#include <odemx/random/DiscreteConst.h>
+
+namespace odemx {
+namespace random {
+
+//------------------------------------------------------construction/destruction
+
+DiscreteConst::DiscreteConst( base::Simulation& sim, const data::Label& label, int value )
+:	DiscreteDist( sim, label ),
+	value_( value )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(DiscreteConst) );
+
+	statistics << param( "seed", Dist::getSeed() ).scope( typeid(DiscreteConst) );
+	statistics << param( "value", value_ ).scope( typeid(DiscreteConst) );
+}
+
+DiscreteConst::~DiscreteConst()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(DiscreteConst) );
+}
+
+//------------------------------------------------------------------------sample
+
+int DiscreteConst::sample()
+{
+	ODEMX_TRACE << log( "sample" ).scope( typeid(DiscreteConst) );
+
+	statistics << count( "uses" ).scope( typeid(DiscreteConst) );
+
+	return value_;
+}
+
+//-----------------------------------------------------------------------getters
+
+int DiscreteConst::getValue()
+{
+	return value_;
+}
+
+} } // namespace odemx::random
diff --git a/odemx-lite/src/random/DiscreteDist.cpp b/odemx-lite/src/random/DiscreteDist.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ad00dd483948400cd0cda04552f99bb581f658cc
--- /dev/null
+++ b/odemx-lite/src/random/DiscreteDist.cpp
@@ -0,0 +1,46 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file DiscreteDist.cpp
+
+	\author Ralf Gerstenberger
+
+	\date created at 2003/05/09
+
+	\brief Implementation of odemx::random::DiscreteDist
+
+	\sa DiscreteDist.h
+
+	\since 1.0
+*/
+
+#include <odemx/random/DiscreteDist.h>
+
+namespace odemx {
+namespace random {
+
+DiscreteDist::DiscreteDist( base::Simulation& sim, const data::Label& label )
+:	Dist( sim, label )
+{
+}
+
+DiscreteDist::~DiscreteDist()
+{
+}
+
+} } // namespace odemx::random
diff --git a/odemx-lite/src/random/Dist.cpp b/odemx-lite/src/random/Dist.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3e6ca330e54b45664329cbb7048d6ae53e3974e2
--- /dev/null
+++ b/odemx-lite/src/random/Dist.cpp
@@ -0,0 +1,108 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Dist.cpp
+
+	\author Ralf Gerstenberger
+
+	\date created at 2003/05/09
+
+	\brief Implementation of odemx::random::Dist
+
+	\sa Dist.h
+
+	\since 1.0
+*/
+
+#include <odemx/random/Dist.h>
+#include <odemx/random/DistContext.h>
+#include <odemx/base/Simulation.h>
+
+namespace odemx {
+namespace random {
+
+Dist::Dist( base::Simulation& sim, const data::Label& label )
+:	Producer( sim, label )
+,	context( sim )
+,	u( 0 )
+,	ustart( 0 )
+,	antithetics( 0 )
+{
+	u = ustart = context.getNextSeed();
+}
+
+Dist::~Dist()
+{
+}
+
+void Dist::setSeed( int n )
+{
+	if( n < 0 )
+	{
+		n= -n;
+	}
+	if( n >= (int)zyqmodulo )
+	{
+		n = n - ( (int)( n / zyqmodulo ) ) * zyqmodulo;
+	}
+	if( n == 0 )
+	{
+		n = (int)( zyqmodulo / 2 );
+	}
+	u = ustart = n;
+}
+
+unsigned long Dist::getSeed()
+{
+	return ustart;
+}
+
+double Dist::getSample()
+{
+	int k;
+
+	k = 32;
+	u = k * u;
+	if( u >= zyqmodulo )
+	{
+		u =  u- ((int)( u / zyqmodulo ) ) * zyqmodulo;
+	}
+
+	// yes, this is needed twice
+	k = 32;
+	u = k * u;
+	if( u >= zyqmodulo )
+	{
+		u =  u- ((int)( u / zyqmodulo ) ) * zyqmodulo;
+	}
+
+	k = 8;
+	u = k * u;
+	if( u >= zyqmodulo )
+	{
+		u =  u- ((int)( u / zyqmodulo ) ) * zyqmodulo;
+	}
+
+	double help = (double)u / (double)zyqmodulo;
+
+	double zyqSample = antithetics ? 1.0 - help : help;
+
+	return zyqSample;
+}
+
+} } // namespace odemx::random
diff --git a/odemx-lite/src/random/DistContext.cpp b/odemx-lite/src/random/DistContext.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2af6f584df75d859791bcaccb70c6bee553eb1c4
--- /dev/null
+++ b/odemx-lite/src/random/DistContext.cpp
@@ -0,0 +1,107 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file DistContext.cpp
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Implementation of odemx::random::DistContext
+ */
+
+#include <odemx/random/DistContext.h>
+
+namespace odemx {
+namespace random {
+
+const unsigned long zyqmodulo = 67099547;
+
+DistContext::DistContext()
+:	zyqSeed_( 907 )
+{
+}
+
+DistContext::~DistContext()
+{
+}
+
+void DistContext::setSeed( int n )
+{
+	if( n < 0 )
+	{
+		n = -n;
+	}
+
+	if( n >= (int)zyqmodulo )
+	{
+		n = n - ( (int)(n / zyqmodulo) ) * zyqmodulo;
+	}
+
+	if( n == 0 )
+	{
+		n = (int)( zyqmodulo / 2 );
+	}
+
+	zyqSeed_ = n;
+}
+
+unsigned long DistContext::getSeed()
+{
+	return zyqSeed_;
+}
+
+unsigned long DistContext::getNextSeed()
+{
+	computeNextSeed();
+	return zyqSeed_;
+}
+
+void DistContext::computeNextSeed()
+{
+	int k;
+
+	k = 7;
+	zyqSeed_ = zyqSeed_ * k;
+	if( zyqSeed_ >= zyqmodulo )
+	{
+	    zyqSeed_ = zyqSeed_ - ( (int)( zyqSeed_ / zyqmodulo ) ) * zyqmodulo;
+	}
+
+	k = 13;
+	zyqSeed_ = zyqSeed_ * k;
+	if( zyqSeed_ >= zyqmodulo )
+	{
+	    zyqSeed_ = zyqSeed_ - ( (int)( zyqSeed_ / zyqmodulo ) ) * zyqmodulo;
+	}
+
+	k = 15;
+	zyqSeed_ = zyqSeed_ * k;
+	if( zyqSeed_ >= zyqmodulo )
+	{
+	    zyqSeed_ = zyqSeed_ - ( (int)( zyqSeed_ / zyqmodulo ) ) * zyqmodulo;
+	}
+
+	k = 27;
+	zyqSeed_ = zyqSeed_ * k;
+	if( zyqSeed_ >= zyqmodulo )
+	{
+	    zyqSeed_ = zyqSeed_ - ( (int)( zyqSeed_ / zyqmodulo ) ) * zyqmodulo;
+	}
+}
+
+} } // namespace odemx::random
diff --git a/odemx-lite/src/random/Draw.cpp b/odemx-lite/src/random/Draw.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..74865fdc25cf2dcc060ed9095c00880b96b042c1
--- /dev/null
+++ b/odemx-lite/src/random/Draw.cpp
@@ -0,0 +1,68 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file Draw.cpp
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Implementation of odemx::random::Draw
+ */
+
+#include <odemx/random/Draw.h>
+
+namespace odemx {
+namespace random {
+
+//------------------------------------------------------construction/destruction
+
+Draw::Draw( base::Simulation& sim, const data::Label& label, double probability )
+:	DiscreteDist( sim, label )
+{
+	probability_ = probability;
+
+	ODEMX_TRACE << log( "create" ).scope( typeid(Draw) );
+
+	statistics << param( "seed", Dist::getSeed() ).scope( typeid(Draw) );
+	statistics << param( "probability", probability_ ).scope( typeid(Draw) );
+}
+
+Draw::~Draw()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Draw) );
+}
+
+//------------------------------------------------------------------------sample
+
+int Draw::sample()
+{
+	ODEMX_TRACE << log( "sample" ).scope( typeid(Draw) );
+
+	statistics << count( "uses" ).scope( typeid(Draw) );
+
+	return ( probability_ > Dist::getSample() ? 1 : 0 );
+}
+
+//-----------------------------------------------------------------------getters
+
+double Draw::getProbability()
+{
+	return probability_;
+}
+
+} } // namespace odemx::random
diff --git a/odemx-lite/src/random/Erlang.cpp b/odemx-lite/src/random/Erlang.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a7d368e9c0705f929a5086cba452ce728768fb25
--- /dev/null
+++ b/odemx-lite/src/random/Erlang.cpp
@@ -0,0 +1,95 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file Erlang.cpp
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Implementation of odemx::random::Erlang
+ */
+
+#include <odemx/random/Erlang.h>
+
+#include <cmath>
+
+namespace odemx {
+namespace random {
+
+//------------------------------------------------------construction/destruction
+
+Erlang::Erlang( base::Simulation& sim, const data::Label& label, double rate, int shape )
+:	ContinuousDist( sim, label )
+{
+	if( rate <= 0.0 )
+	{
+		rate = ( rate < 0.0 ) ? -rate : 0.01;
+		warning << log( "Erlang(): rate <= 0.0; -rate or 0.01 used" )
+				.scope( typeid(Erlang) );
+	}
+
+	if( shape <= 0 )
+	{
+		shape = ( shape < 0 ) ? -shape : 1;
+		warning << log( "Erlang(): shape <= 0; -shape or 1 used" )
+				.scope( typeid(Erlang) );
+	}
+	rate_ = rate;
+	shape_ = shape;
+
+	ODEMX_TRACE << log( "create" ).scope( typeid(Erlang) );
+
+	statistics << param( "seed", Dist::getSeed() ).scope( typeid(Erlang) );
+	statistics << param( "rate", rate_ ).scope( typeid(Erlang) );
+	statistics << param( "shape", shape_ ).scope( typeid(Erlang) );
+}
+
+Erlang::~Erlang()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Erlang) );
+}
+
+//------------------------------------------------------------------------sample
+
+double Erlang::sample()
+{
+	ODEMX_TRACE << log( "sample" ).scope( typeid(Erlang) );
+
+	statistics << count( "uses" ).scope( typeid(Erlang) );
+
+	double erlangTmp = 0.0;
+	for( int i = 0; i < shape_; ++i )
+	{
+		erlangTmp += -( 1 / rate_ ) * std::log( Dist::getSample() );
+	}
+	return erlangTmp;
+}
+
+//-----------------------------------------------------------------------getters
+
+double Erlang::getRate()
+{
+	return rate_;
+}
+
+int Erlang::getShape()
+{
+	return shape_;
+}
+
+} } // namespace odemx::random
diff --git a/odemx-lite/src/random/NegativeExponential.cpp b/odemx-lite/src/random/NegativeExponential.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9a718d701768bfab7aca3465da039a585652142e
--- /dev/null
+++ b/odemx-lite/src/random/NegativeExponential.cpp
@@ -0,0 +1,78 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file NegativeExponential.cpp
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Implementation of odemx::random::NegativeExponential
+ */
+
+#include <odemx/random/NegativeExponential.h>
+
+#include <cmath>
+
+namespace odemx {
+namespace random {
+
+//------------------------------------------------------construction/destruction
+
+NegativeExponential::NegativeExponential( base::Simulation& sim, const data::Label& label,
+		double inverseMean )
+:	ContinuousDist( sim, label )
+{
+	if( inverseMean <= 0.0 )
+	{
+		inverseMean = ( inverseMean < 0.0 ) ? -inverseMean : 0.001;
+
+		warning << log( "NegativeExponential(): inverseMean <= 0; -inverseMean or 0.001 used")
+				.scope( typeid(NegativeExponential) );
+	}
+	inverseMean_ = inverseMean;
+
+	ODEMX_TRACE << log( "create" ).scope( typeid(NegativeExponential) );
+
+	statistics << param( "seed", Dist::getSeed() ).scope( typeid(NegativeExponential) );
+	statistics << param( "inverse mean", inverseMean_ ).scope( typeid(NegativeExponential) );
+}
+
+NegativeExponential::~NegativeExponential()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(NegativeExponential) );
+}
+
+//------------------------------------------------------------------------sample
+
+double NegativeExponential::sample()
+{
+	ODEMX_TRACE << log( "sample" ).scope( typeid(NegativeExponential) );
+
+	statistics << count( "uses" ).scope( typeid(NegativeExponential) );
+
+	return ( -std::log( Dist::getSample() ) / inverseMean_ );
+}
+
+//-----------------------------------------------------------------------getters
+
+double NegativeExponential::getInverseMean()
+{
+	return inverseMean_;
+}
+
+} } // namespace odemx::random
diff --git a/odemx-lite/src/random/Normal.cpp b/odemx-lite/src/random/Normal.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4140dfff90a84c4d1a570844c61d31756cded026
--- /dev/null
+++ b/odemx-lite/src/random/Normal.cpp
@@ -0,0 +1,101 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file Normal.cpp
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Implementation of odemx::random::Normal
+ */
+
+#include <odemx/random/Normal.h>
+
+#include <cmath>
+
+namespace odemx {
+namespace random {
+
+//------------------------------------------------------construction/destruction
+
+Normal::Normal( base::Simulation& sim, const data::Label& label, double mean,
+		double deviation )
+:	ContinuousDist( sim, label )
+{
+	if( deviation < 0.0 )
+	{
+		deviation = -deviation;
+
+		warning << log( "Normal(): given deviation < 0; changed to -deviation" )
+				.scope( typeid(Normal) );
+	}
+
+	mean_ = mean;
+	deviation_ = deviation;
+	zyqeven = false;
+	zyqu = zyqv = 0.0;
+
+	ODEMX_TRACE << log( "create" ).scope( typeid(Normal) );
+
+	statistics << param( "seed", Dist::getSeed() ).scope( typeid(Normal) );
+	statistics << param( "mean", mean_ ).scope( typeid(Normal) );
+	statistics << param( "deviation", deviation_ ).scope( typeid(Normal) );
+}
+
+Normal::~Normal()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Normal) );
+}
+
+//------------------------------------------------------------------------sample
+
+double Normal::sample()
+{
+	ODEMX_TRACE << log( "sample" ).scope( typeid(Normal) );
+
+	statistics << count( "uses" ).scope( typeid(Normal) );
+
+	double z;
+	if( zyqeven )
+	{
+		zyqeven = false;
+		z = zyqu * std::cos( zyqv );
+	}
+	else
+	{
+		zyqeven = true;
+		zyqu = std::sqrt( -2.0 * std::log( Dist::getSample() ) );
+		zyqv = 6.28318530717958647693 * Dist::getSample();
+		z = zyqu * std::sin( zyqv );
+	};
+	return ( z * deviation_ + mean_ );
+};
+
+//-----------------------------------------------------------------------getters
+
+double Normal::getMean()
+{
+	return mean_;
+}
+
+double Normal::getDeviation()
+{
+	return deviation_;
+}
+
+} } // namespace odemx::random
diff --git a/odemx-lite/src/random/Poisson.cpp b/odemx-lite/src/random/Poisson.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..683cb8dc7015140394f422b883053e5d8b4ef73d
--- /dev/null
+++ b/odemx-lite/src/random/Poisson.cpp
@@ -0,0 +1,90 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file Poisson.cpp
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Implementation of odemx::random::Poisson
+ */
+
+#include <odemx/random/Poisson.h>
+
+#include <cmath>
+
+namespace odemx {
+namespace random {
+
+//------------------------------------------------------construction/destruction
+
+Poisson::Poisson( base::Simulation& sim, const data::Label& label, double mean )
+:	DiscreteDist( sim, label )
+{
+	if( mean <= 0.0 )
+	{
+		mean = ( mean < 0.0 ) ? -mean : 0.0010;
+		warning << log( "Poisson(): mean value is <= 0.0; changed to -mean" )
+				.scope( typeid(Poisson) );
+	}
+	mean_ = mean;
+
+	ODEMX_TRACE << log( "create" ).scope( typeid(Poisson) );
+
+	statistics << param( "seed", Dist::getSeed() ).scope(typeid(Poisson) );
+	statistics << param( "mean", mean_ ).scope(typeid(Poisson) );
+}
+
+Poisson::~Poisson()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Poisson) );
+}
+
+//------------------------------------------------------------------------sample
+
+int Poisson::sample()
+{
+	ODEMX_TRACE << log( "sample" ).scope( typeid(Poisson) );
+
+	statistics << count( "uses" ).scope( typeid(Poisson) );
+
+	double q;
+	double r;
+	int m = 0;
+
+	r = std::exp( -mean_ );
+	q = 1.0;
+
+	while( q >= r )
+	{
+		q *= Dist::getSample();
+		m += 1;
+	};
+
+	m -= 1;
+	return m;
+}
+
+//-----------------------------------------------------------------------getters
+
+double Poisson::getMean()
+{
+	return mean_;
+}
+
+} } // namespace odemx::random
diff --git a/odemx-lite/src/random/RandomInt.cpp b/odemx-lite/src/random/RandomInt.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f0e3e333a900b4b585a8008f0198da4e14bd8338
--- /dev/null
+++ b/odemx-lite/src/random/RandomInt.cpp
@@ -0,0 +1,87 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file RandomInt.cpp
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Implementation of odemx::random::RandomInt
+ */
+
+#include <odemx/random/RandomInt.h>
+
+#include <algorithm>
+#include <cmath>
+
+namespace odemx {
+namespace random {
+
+//------------------------------------------------------construction/destruction
+
+RandomInt::RandomInt( base::Simulation& sim, const data::Label& label, int lowerBound,
+		int upperBound )
+:	DiscreteDist( sim, label )
+{
+	if( lowerBound > upperBound )
+	{
+		std::swap( lowerBound, upperBound );
+		warning << log( "RandomInt(): lower bound greater than upper bound; bounds swapped" )
+				.scope( typeid(RandomInt) );
+	}
+
+	lowerBound_ = lowerBound;
+	upperBound_ = upperBound;
+	zyqSpan_ = upperBound_ - lowerBound_;
+
+	ODEMX_TRACE << log( "create" ).scope( typeid(RandomInt) );
+
+	statistics << param( "seed", Dist::getSeed() ).scope( typeid(RandomInt) );
+	statistics << param( "lower bound", lowerBound_ ).scope( typeid(RandomInt) );
+	statistics << param( "upper bound", upperBound_ ).scope( typeid(RandomInt) );
+}
+
+RandomInt::~RandomInt()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(RandomInt) );
+}
+
+//------------------------------------------------------------------------sample
+
+int RandomInt::sample()
+{
+	ODEMX_TRACE << log( "sample" ).scope( typeid(RandomInt) );
+
+	statistics << count( "uses" ).scope( typeid(RandomInt) );
+
+	return (int)std::floor( zyqSpan_ * DiscreteDist::getSample() ) + lowerBound_;
+}
+
+//-----------------------------------------------------------------------getters
+
+int RandomInt::getLowerBound()
+{
+	return lowerBound_;
+}
+
+int RandomInt::getUpperBound()
+{
+	return upperBound_;
+}
+
+} } // namespace odemx::random
diff --git a/odemx-lite/src/random/Uniform.cpp b/odemx-lite/src/random/Uniform.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8ccc140f057c80b3e8094807985f9c2a2aa4b444
--- /dev/null
+++ b/odemx-lite/src/random/Uniform.cpp
@@ -0,0 +1,85 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+
+/**
+ * @file Uniform.cpp
+ * @date Feb 22, 2009
+ * @author Ronald Kluth
+ * @brief Implementation of odemx::random::Uniform
+ */
+
+#include <odemx/random/Uniform.h>
+
+#include <algorithm>
+
+namespace odemx {
+namespace random {
+
+//------------------------------------------------------construction/destruction
+
+Uniform::Uniform( base::Simulation& sim, const data::Label& label, double lowerBound,
+		double upperBound )
+:	ContinuousDist( sim, label )
+{
+	if( lowerBound > upperBound )
+	{
+		std::swap( lowerBound, upperBound );
+		warning << log( "Uniform(): lower bound greater than upper bound; bounds swapped" )
+				.scope( typeid(Uniform) );
+	}
+	lowerBound_ = lowerBound;
+	upperBound_ = upperBound;
+	zyqSpan_ = upperBound_ - lowerBound_;
+
+	ODEMX_TRACE << log( "create" ).scope( typeid(Uniform) );
+
+	statistics << param( "seed", Dist::getSeed() ).scope( typeid(Uniform) );
+	statistics << param( "lower bound", lowerBound_ ).scope( typeid(Uniform) );
+	statistics << param( "upper bound", upperBound_ ).scope( typeid(Uniform) );
+}
+
+Uniform::~Uniform()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Uniform) );
+}
+
+//------------------------------------------------------------------------sample
+
+double Uniform::sample()
+{
+	ODEMX_TRACE << log( "sample" ).scope( typeid(Uniform) );
+
+	statistics << count( "uses" ).scope( typeid(Uniform) );
+
+	return ( zyqSpan_ * getSample() + lowerBound_ );
+}
+
+//-----------------------------------------------------------------------getters
+
+double Uniform::getLowerBound()
+{
+	return lowerBound_;
+}
+
+double Uniform::getUpperBound()
+{
+	return upperBound_;
+}
+
+} } // namespace odemx::random
diff --git a/odemx-lite/src/statistics/Accumulate.cpp b/odemx-lite/src/statistics/Accumulate.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7f59ed7572ed8e62a5d30864a15f21ac7874cabd
--- /dev/null
+++ b/odemx-lite/src/statistics/Accumulate.cpp
@@ -0,0 +1,224 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Accumulate.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/03/01
+ * @brief Implementation of odemx::statistics::Accumulate
+ * @sa Accumulate.h
+ * @since 3.0
+ */
+
+#include <odemx/statistics/Accumulate.h>
+#include <odemx/data/ReportTable.h>
+#include <odemx/data/Report.h>
+
+#include <cmath>
+
+namespace odemx {
+namespace statistics {
+
+//------------------------------------------------------construction/destruction
+
+Accumulate::Accumulate( base::Simulation& sim, const data::Label& label, Approx app )
+:	Tab( sim, label )
+,	approximation_( app )
+,	startTime_( 0 )
+,	lastTime_( 0 )
+,	lastValue_( 0 )
+,	zeros_( 0 )
+,	minValue_( 0.0 )
+,	maxValue_( 0.0 )
+,	sum_( 0.0 )
+,	sumSq_( 0.0 )
+,	sumWeight_( 0.0 )
+,	sumSqWeight_( 0.0 )
+{
+}
+
+Accumulate::~Accumulate()
+{
+}
+
+//---------------------------------------------------------------------modifiers
+
+void Accumulate::update( base::SimTime time, double value )
+{
+	// set start time for later computation of time span
+	if( getUpdateCount() == 0 )
+	{
+		startTime_ = time;
+	}
+
+	// update usage counter
+	Tab::update();
+
+	// update non-weighted sums
+	sum_ += value;
+	sumSq_ += std::pow( value, 2 );
+
+	// compute time span since last update and save current time
+	base::SimTime lastSpan = time - lastTime_;
+	lastTime_ = time;
+
+	// compute weighted sums according to the approximation mode
+    if( getUpdateCount() > 1 )
+    {
+    	if( approximation_ == linear )
+		{
+	        double mean = ( value + lastValue_ ) / 2;
+	        sumWeight_ += mean * lastSpan;
+	        sumSqWeight_ += std::pow( mean, 2 ) * lastSpan;
+		}
+		else // approximation_ == stepwise
+		{
+	        sumWeight_   += lastValue_ * lastSpan;
+	        sumSqWeight_ += lastValue_ * lastValue_ * lastSpan;
+	    }
+    }
+
+    // remember the current update value
+	lastValue_ = value;
+
+	// update min and max values
+	if( Tab::getUpdateCount() == 1 )
+	{
+		minValue_ = maxValue_ = value;
+	}
+	else if( value < minValue_ )
+	{
+		minValue_ = value;
+	}
+	else if( value > maxValue_ )
+	{
+		maxValue_ = value;
+	}
+
+	if( value == 0 )
+	{
+		++zeros_;
+	}
+}
+
+void Accumulate::reset( base::SimTime time )
+{
+	Tab::reset( time );
+
+	zeros_ = 0;
+	minValue_ = maxValue_ =	sum_ = sumSq_ = sumWeight_ = sumSqWeight_ = lastValue_ = 0.0;
+
+	startTime_ = lastTime_ = time;
+}
+
+//-----------------------------------------------------------------------getters
+
+std::size_t Accumulate::getZeros() const
+{
+	return zeros_;
+}
+
+double Accumulate::getMin() const
+{
+	return minValue_;
+}
+
+double Accumulate::getMax() const
+{
+	return maxValue_;
+}
+
+double Accumulate::getMean() const
+{
+	return getUpdateCount() > 0 ? sum_ / getUpdateCount() : 0.0;
+}
+
+double Accumulate::getWeightedMean() const
+{
+	base::SimTime span = lastTime_ - startTime_;
+
+	// does not consider the last time span till this call,
+	// call update once more before getting the mean value ?!?
+	if( span == 0 )
+	{
+		return 0.0;
+	}
+
+	return sumWeight_ / span;
+}
+
+double Accumulate::getStandardDeviation() const
+{
+	if( getUpdateCount() <= 1 )
+	{
+		return 0.0;
+	}
+
+	double mean = getMean();
+	double variance = std::fabs( sumSq_ / getUpdateCount() - std::pow( mean, 2 ) );
+	return std::sqrt( variance );
+}
+
+double Accumulate::getWeightedStandardDeviation() const
+{
+	if( getUpdateCount() <= 1 )
+	{
+		return 0.0;
+	}
+
+	base::SimTime span = lastTime_ - startTime_;
+
+	if( span == 0 )
+	{
+		return 0.0;
+	}
+
+	double weightedMean = getWeightedMean();
+	double variance = std::fabs( sumSqWeight_ / span - std::pow( weightedMean, 2 ) );
+	return std::sqrt( variance );
+}
+
+//------------------------------------------------------------------------report
+
+void Accumulate::report( data::Report& report )
+{
+	using namespace data;
+	ReportTable::Definition def;
+	def.addColumn( "Name", ReportTable::Column::STRING );
+	def.addColumn( "Reset at", ReportTable::Column::SIMTIME );
+	def.addColumn( "Uses", ReportTable::Column::INTEGER );
+	def.addColumn( "Min", ReportTable::Column::REAL );
+	def.addColumn( "Max", ReportTable::Column::REAL );
+	def.addColumn( "Mean", ReportTable::Column::REAL );
+	def.addColumn( "Weighted Mean", ReportTable::Column::REAL );
+	def.addColumn( "Std Deviation", ReportTable::Column::REAL );
+	def.addColumn( "Weighted StDev", ReportTable::Column::REAL );
+	ReportTable& table = report.getTable( "Accumulate Statistics", def );
+	table
+	<< getLabel()
+	<< getResetTime()
+	<< getUpdateCount()
+	<< getMin()
+	<< getMax()
+	<< getMean()
+	<< getWeightedMean()
+	<< getStandardDeviation()
+	<< getWeightedStandardDeviation();
+}
+
+} } // namespace odemx::statistics
diff --git a/odemx-lite/src/statistics/Count.cpp b/odemx-lite/src/statistics/Count.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4e108087a7fb53cb2e242ae94d233ca2a863073a
--- /dev/null
+++ b/odemx-lite/src/statistics/Count.cpp
@@ -0,0 +1,87 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Count.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/03/01
+ * @brief Implementation of odemx::statistics::Count
+ * @sa Count.h
+ * @since 3.0
+ */
+
+#include <odemx/statistics/Count.h>
+#include <odemx/data/ReportTable.h>
+#include <odemx/data/Report.h>
+
+namespace odemx {
+namespace statistics {
+
+//------------------------------------------------------construction/destruction
+
+Count::Count( base::Simulation& sim, const data::Label& label )
+:	Tab( sim, label )
+,	count_( 0 )
+{
+}
+
+Count::~Count()
+{
+}
+
+//---------------------------------------------------------------------modifiers
+
+void Count::update( int value )
+{
+	Tab::update();
+	count_ += value;
+}
+
+void Count::reset( base::SimTime time )
+{
+	Tab::reset( time );
+	count_ = 0;
+}
+
+//-----------------------------------------------------------------------getters
+
+int Count::getValue() const
+{
+	return count_;
+}
+
+//------------------------------------------------------------------------report
+
+void Count::report( data::Report& report )
+{
+	using namespace data;
+
+	ReportTable::Definition def;
+	def.addColumn( "Name", ReportTable::Column::STRING );
+	def.addColumn( "Reset at", ReportTable::Column::SIMTIME );
+	def.addColumn( "Uses", ReportTable::Column::INTEGER );
+	def.addColumn( "Value", ReportTable::Column::INTEGER );
+	ReportTable& table = report.getTable( "Count Statistics", def );
+	table
+	<< getLabel()
+	<< getResetTime()
+	<< getUpdateCount()
+	<< getValue();
+}
+
+} } // namespace odemx::statistics
diff --git a/odemx-lite/src/statistics/Histogram.cpp b/odemx-lite/src/statistics/Histogram.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7c74eca16c9d651e2a331c47fad9e350ead03b4f
--- /dev/null
+++ b/odemx-lite/src/statistics/Histogram.cpp
@@ -0,0 +1,215 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Histogram.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/03/01
+ * @brief Implementation of odemx::statistics::Histogram
+ * @sa Histogram.h
+ * @since 3.0
+ */
+
+#include <odemx/statistics/Histogram.h>
+#include <odemx/data/Report.h>
+
+#include <cmath>
+
+namespace odemx {
+namespace statistics {
+
+//------------------------------------------------------construction/destruction
+
+Histogram::Histogram( base::Simulation& sim, const data::Label& label,
+		double lowerBound, double upperBound, unsigned int cellCount )
+:	Tally( sim, label )
+,	lowerBound_( lowerBound )
+,	upperBound_( upperBound )
+,	cellCount_( cellCount + 2 )
+{
+	if( upperBound_ == lowerBound_ )
+	{
+		upperBound_ = lowerBound_ + 100.0;
+	}
+
+	if( upperBound_ < lowerBound_ )
+	{
+		std::swap( lowerBound_, upperBound_ );
+	}
+
+	cellWidth_ = ( upperBound_ - lowerBound_ ) / ( cellCount_ - 2 );
+
+	cellData_.resize( cellCount_, Cell() );
+	maxCellIndex_ = cellData_.size() - 1;
+}
+
+Histogram::~Histogram()
+{
+}
+
+//---------------------------------------------------------------------modifiers
+
+void Histogram::update( double value )
+{
+	Tally::update( value );
+
+	// the vector index (cell) to be updated for the given value
+	int cellIndex;
+
+	// correct offset
+	value -= lowerBound_;
+
+	if( value < 0.0 )
+	{
+		cellIndex = 0;
+	}
+	else
+	{
+		cellIndex = (int) (std::floor( value / cellWidth_ ) + 1);
+
+		if( cellIndex > maxCellIndex_ )
+		{
+			cellIndex = maxCellIndex_ ;
+		} else if (cellIndex < 0) {
+			cellIndex = 0;
+		}
+	}
+
+	++( cellData_[ cellIndex ].count );
+}
+
+void Histogram::reset( base::SimTime time )
+{
+	Tally::reset( time );
+
+	// reset cell vector by swapping with a zero-initialized temporary
+	CellVec tmp( cellCount_, Cell() );
+	cellData_.swap( tmp );
+}
+
+//-----------------------------------------------------------------------getters
+
+const Histogram::CellVec& Histogram::getData()
+{
+	// update() only sets the counters,
+	// must compute other cell values here
+
+	// values < lower bound
+	cellData_[ 0 ].lowerBound = std::min( lowerBound_ - cellWidth_, getMin() );
+	cellData_[ 0 ].upperBound = lowerBound_;
+	cellData_[ 0 ].percentage = (double)cellData_[ 0 ].count * 100 / getUpdateCount();
+
+	// regular values within bounds
+	for( size_t i = 1; i < cellCount_ - 1; ++i )
+	{
+		cellData_[ i ].lowerBound = lowerBound_ + (i - 1) * cellWidth_;
+		cellData_[ i ].upperBound = lowerBound_ + i * cellWidth_;
+		cellData_[ i ].percentage = (double)cellData_[ i ].count * 100 / getUpdateCount();
+	}
+
+	// values > upper bound
+	cellData_[ cellCount_ - 1 ].lowerBound = upperBound_;
+	cellData_[ cellCount_ - 1 ].upperBound = std::max( upperBound_ + cellWidth_, getMax() );
+	cellData_[ cellCount_ - 1 ].percentage =
+		(double)cellData_[ cellCount_ - 1 ].count * 100 / getUpdateCount();
+
+	return cellData_;
+}
+
+//------------------------------------------------------------------------report
+
+void Histogram::report( data::Report& report )
+{
+	using namespace data;
+
+	ReportTable::Definition tallyDef;
+	tallyDef.addColumn( "Name", ReportTable::Column::STRING );
+	tallyDef.addColumn( "Reset at", ReportTable::Column::SIMTIME );
+	tallyDef.addColumn( "Uses", ReportTable::Column::INTEGER );
+	tallyDef.addColumn( "Low", ReportTable::Column::REAL );
+	tallyDef.addColumn( "High", ReportTable::Column::REAL );
+	tallyDef.addColumn( "Cells", ReportTable::Column::INTEGER );
+	tallyDef.addColumn( "Min", ReportTable::Column::REAL );
+	tallyDef.addColumn( "Max", ReportTable::Column::REAL );
+	tallyDef.addColumn( "Mean", ReportTable::Column::REAL );
+	tallyDef.addColumn( "Std Deviation", ReportTable::Column::REAL );
+	ReportTable& statsTable = report.getTable( "Histogram Statistics Summary", tallyDef );
+	statsTable
+	<< getLabel()
+	<< getResetTime()
+	<< getUpdateCount()
+	<< lowerBound_
+	<< upperBound_
+	<< cellCount_
+	<< getMin()
+	<< getMax()
+	<< getMean()
+	<< getStandardDeviation();
+
+	ReportTable::Definition visualDef;
+	visualDef.addColumn( "Low", ReportTable::Column::REAL );
+	visualDef.addColumn( "High", ReportTable::Column::REAL );
+	visualDef.addColumn( "Count", ReportTable::Column::INTEGER );
+	visualDef.addColumn( "Percentage", ReportTable::Column::REAL );
+	visualDef.addColumn( "Bar Diagram", ReportTable::Column::BAR );
+
+	std::ostringstream tableName;
+	tableName << "Histogram: " << getLabel() << " [" << getUpdateCount() << " samples]";
+	ReportTable& visualTable = report.getTable( tableName.str(), visualDef );
+
+	const CellVec& data = getData();
+
+	// compute multiplier for graphical representation
+	double maxPercentage = 0;
+	for( CellVec::const_iterator cellIter = data.begin();
+		cellIter != data.end(); ++cellIter )
+	{
+		const Cell& cell = *cellIter;
+		if( cell.percentage > maxPercentage )
+		{
+			maxPercentage = cell.percentage;
+		}
+	}
+	// diagram width should be 100%, i.e. the maximum value should fill it
+	double multiplier = 0;
+	if( 0 < maxPercentage )
+	{
+		multiplier = 100 / maxPercentage;
+	}
+
+	// compute results
+	for( CellVec::const_iterator iter = data.begin(); iter != data.end(); ++iter )
+	{
+		const Cell& current = *iter;
+
+		long bar = (long) std::floor( multiplier * current.percentage );
+		if( current.percentage - bar > 0.5 )
+		{
+			++bar;
+		}
+
+		visualTable
+		<< current.lowerBound
+		<< current.upperBound
+		<< current.count
+		<< current.percentage
+		<< bar;
+	}
+};
+
+} } // namespace odemx::statistics
diff --git a/odemx-lite/src/statistics/Regression.cpp b/odemx-lite/src/statistics/Regression.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0ccc17a80ecd6563090d372e905b23f352071e6a
--- /dev/null
+++ b/odemx-lite/src/statistics/Regression.cpp
@@ -0,0 +1,172 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Regression.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/03/01
+ * @brief Implementation of odemx::statistics::Regression
+ * @sa Regression.h
+ * @since 3.0
+ */
+
+#include <odemx/statistics/Regression.h>
+#include <odemx/data/ReportTable.h>
+#include <odemx/data/Report.h>
+
+#include <cmath>
+
+namespace odemx {
+namespace statistics {
+
+//------------------------------------------------------construction/destruction
+
+Regression::Regression( base::Simulation& sim, const data::Label& label )
+:	Tab( sim, label )
+,	sumX_( 0.0 )
+,	sumY_( 0.0 )
+,	sumSqX_( 0.0 )
+,	sumXMulY_( 0.0 )
+,	sumSqY_( 0.0 )
+{
+}
+
+Regression::~Regression()
+{
+}
+
+//---------------------------------------------------------------------modifiers
+
+void Regression::update( double valueX, double valueY)
+{
+	Tab::update();
+
+	sumX_ += valueX;
+	sumY_ += valueY;
+	sumSqX_ += std::pow( valueX, 2 );
+	sumSqY_ += std::pow( valueY, 2 );
+	sumXMulY_ += valueX * valueY;
+}
+
+void Regression::reset( base::SimTime time )
+{
+	Tab::reset( time );
+	sumX_ = sumY_ = sumSqX_ = sumXMulY_ = sumSqY_ = 0.0;
+}
+
+//-----------------------------------------------------------------------getters
+
+bool Regression::hasSufficientData() const
+{
+	return getUpdateCount() > 5;
+}
+
+double Regression::getXMean() const
+{
+	return getUpdateCount() ? sumX_ / getUpdateCount() : 0.0;
+}
+
+double Regression::getYMean() const
+{
+	return getUpdateCount() ? sumY_ / getUpdateCount() : 0.0;
+}
+
+double Regression::getDx() const
+{
+	return std::fabs( getUpdateCount() * sumSqX_ - std::pow( sumX_, 2 ) );
+}
+
+double Regression::getDy() const
+{
+	return std::fabs( getUpdateCount() * sumSqY_ - std::pow( sumY_, 2 ) );
+}
+
+double Regression::getResidualStandardDeviation() const
+{
+	// RES.ST.DEV
+	double sd = std::sqrt( ( sumSqY_ - getIntercept() * sumY_
+			- getEstimatedRegressionCoefficient() * sumXMulY_ )
+			/ (getUpdateCount() - 2 ) );
+	return sd;
+}
+
+double Regression::getEstimatedRegressionCoefficient() const
+{
+	// EST.REG.COEFF
+	double a1 = ( getUpdateCount() * sumXMulY_ - sumX_ * sumY_ ) / getDx();
+	return a1;
+}
+
+double Regression::getIntercept() const
+{
+	// INTERCEPT
+	double a0 = ( sumY_ * sumSqX_ - sumX_ * sumXMulY_ ) / getDx();
+	return a0;
+}
+
+double Regression::getRegressionCoefficientStandardDeviation() const
+{
+	// ST.DEV.REG.COEFF
+	return ( getUpdateCount() * getResidualStandardDeviation()
+			/ std::sqrt( ( getUpdateCount() - 2 ) * getDx() ) );
+}
+
+double Regression::getCorrelationCoefficient() const
+{
+	// CORR.COEFF
+	double r2 = ( ( getUpdateCount() * sumXMulY_ - sumX_ * sumY_ )
+			* ( getUpdateCount() * sumXMulY_ - sumX_ * sumY_ ) )
+			/ ( getDx() * getDy() );
+	return r2;
+}
+
+//------------------------------------------------------------------------report
+
+void Regression::report( data::Report& report )
+{
+	using namespace data;
+	ReportTable::Definition def;
+	def.addColumn( "Name", ReportTable::Column::STRING );
+	def.addColumn( "Reset at", ReportTable::Column::SIMTIME );
+	def.addColumn( "Uses", ReportTable::Column::INTEGER );
+	def.addColumn( "XBar", ReportTable::Column::REAL );
+	def.addColumn( "YBar", ReportTable::Column::REAL );
+	def.addColumn( "Dx", ReportTable::Column::REAL );
+	def.addColumn( "Dy", ReportTable::Column::REAL );
+	def.addColumn( "Residual StDev", ReportTable::Column::REAL );
+	def.addColumn( "Est Reg Coeff", ReportTable::Column::REAL );
+	def.addColumn( "Intercept", ReportTable::Column::REAL );
+	def.addColumn( "Reg Coeff StDev", ReportTable::Column::REAL );
+	def.addColumn( "Correlation Coeff", ReportTable::Column::REAL );
+	ReportTable& table = report.getTable( "Regression Statistics", def );
+	table
+	<< getLabel()
+	<< getResetTime()
+	<< getUpdateCount()
+	<< getXMean()
+	<< getYMean()
+	<< getDx()
+	<< getDy()
+	<< getResidualStandardDeviation()
+	<< getEstimatedRegressionCoefficient()
+	<< getIntercept()
+	<< getRegressionCoefficientStandardDeviation()
+	<< getCorrelationCoefficient();
+}
+
+} } // namespace odemx::statistics
diff --git a/odemx-lite/src/statistics/Sum.cpp b/odemx-lite/src/statistics/Sum.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..043ab2f18d246515e8a3b9477dc8e8686c7384bd
--- /dev/null
+++ b/odemx-lite/src/statistics/Sum.cpp
@@ -0,0 +1,86 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Sum.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/03/01
+ * @brief Implementation of odemx::statistics::Sum
+ * @sa Sum.h
+ * @since 3.0
+ */
+
+#include <odemx/statistics/Sum.h>
+#include <odemx/data/ReportTable.h>
+#include <odemx/data/Report.h>
+
+namespace odemx {
+namespace statistics {
+
+//------------------------------------------------------construction/destruction
+
+Sum::Sum( base::Simulation& sim, const data::Label& label )
+:	Tab( sim, label )
+,	sum_( 0.0 )
+{
+}
+
+Sum::~Sum()
+{
+}
+
+//---------------------------------------------------------------------modifiers
+
+void Sum::update( double value )
+{
+	Tab::update();
+	sum_ += value;
+}
+
+void Sum::reset( base::SimTime time )
+{
+	Tab::reset( time );
+	sum_ = 0.0;
+}
+
+//-----------------------------------------------------------------------getters
+
+double Sum::getValue() const
+{
+	return sum_;
+}
+
+//------------------------------------------------------------------------report
+
+void Sum::report( data::Report& report )
+{
+	using namespace data;
+	ReportTable::Definition def;
+	def.addColumn( "Name", ReportTable::Column::STRING );
+	def.addColumn( "Reset at", ReportTable::Column::SIMTIME );
+	def.addColumn( "Uses", ReportTable::Column::INTEGER );
+	def.addColumn( "Value", ReportTable::Column::REAL );
+	ReportTable& table = report.getTable( "Sum Statistics", def );
+	table
+	<< getLabel()
+	<< getResetTime()
+	<< getUpdateCount()
+	<< getValue();
+}
+
+} } // namespace odemx::statistics
diff --git a/odemx-lite/src/statistics/Tab.cpp b/odemx-lite/src/statistics/Tab.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..50a0c456e19072ce37dcb82f7d5098f46c8f148f
--- /dev/null
+++ b/odemx-lite/src/statistics/Tab.cpp
@@ -0,0 +1,72 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Tab.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/03/01
+ * @brief Implementation of odemx::statistics::Tab
+ * @sa Tab.h
+ * @since 3.0
+ */
+
+#include <odemx/statistics/Tab.h>
+#include <odemx/base/DefaultSimulation.h>
+
+namespace odemx {
+namespace statistics {
+
+//------------------------------------------------------construction/destruction
+
+Tab::Tab( base::Simulation& sim, const data::Label& label )
+:	ReportProducer( sim, label )
+,	updateCount_( 0 )
+,	resetTime_( sim.getTime() )
+{
+}
+
+Tab::~Tab()
+{
+}
+
+//---------------------------------------------------------------------modifiers
+
+void Tab::update()
+{
+	++updateCount_;
+}
+
+void Tab::reset( base::SimTime time )
+{
+	resetTime_ = time;
+	updateCount_ = 0;
+}
+
+//-----------------------------------------------------------------------getters
+
+std::size_t Tab::getUpdateCount() const
+{
+	return updateCount_;
+}
+
+base::SimTime Tab::getResetTime() const
+{
+	return resetTime_;
+}
+
+} } // namespace odemx::statistics
diff --git a/odemx-lite/src/statistics/Tally.cpp b/odemx-lite/src/statistics/Tally.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..147ed141dae6ee0b4a5f876fc1e97d60113f99b3
--- /dev/null
+++ b/odemx-lite/src/statistics/Tally.cpp
@@ -0,0 +1,134 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Tally.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/03/01
+ * @brief Implementation of odemx::statistics::Tally
+ * @sa Tally.h
+ * @since 3.0
+ */
+
+#include <odemx/statistics/Tally.h>
+#include <odemx/data/ReportTable.h>
+#include <odemx/data/Report.h>
+
+#include <cmath>
+
+namespace odemx {
+namespace statistics {
+
+//------------------------------------------------------construction/destruction
+
+Tally::Tally( base::Simulation& sim, const data::Label& label )
+:	Tab( sim, label )
+,	minValue_( 0.0 )
+,	maxValue_( 0.0 )
+,	sum_( 0.0 )
+,	sumSq_( 0.0 )
+{
+}
+
+Tally::~Tally()
+{
+}
+
+//---------------------------------------------------------------------modifiers
+
+void Tally::update( double value )
+{
+	Tab::update();
+
+	sum_ += value;
+	sumSq_ += std::pow( value, 2 );
+
+	if( getUpdateCount() == 1 )
+	{
+		minValue_ = maxValue_ = value;
+	}
+	else if( value < minValue_ )
+	{
+		minValue_ = value;
+	}
+	else if( value > maxValue_ )
+	{
+		maxValue_ = value;
+	}
+}
+
+void Tally::reset( base::SimTime time )
+{
+	Tab::reset( time );
+	sum_ = sumSq_ = minValue_ = maxValue_ = 0.0;
+}
+
+//-----------------------------------------------------------------------getters
+
+double Tally::getMin() const
+{
+	return minValue_;
+}
+
+double Tally::getMax() const
+{
+	return maxValue_;
+}
+
+double Tally::getMean() const
+{
+	return getUpdateCount() ? sum_ / getUpdateCount() : 0.0;
+}
+
+double Tally::getStandardDeviation() const
+{
+	if( getUpdateCount() <= 1 )
+	{
+		return 0.0;
+	}
+
+	double mean = getMean();
+	double variance = std::fabs( sumSq_ / getUpdateCount() - std::pow( mean, 2 ) );
+	return std::sqrt( variance );
+}
+
+//------------------------------------------------------------------------report
+
+void Tally::report( data::Report& report )
+{
+	using namespace data;
+	ReportTable::Definition def;
+	def.addColumn( "Name", ReportTable::Column::STRING );
+	def.addColumn( "Reset at", ReportTable::Column::SIMTIME );
+	def.addColumn( "Uses", ReportTable::Column::INTEGER );
+	def.addColumn( "Min", ReportTable::Column::REAL );
+	def.addColumn( "Max", ReportTable::Column::REAL );
+	def.addColumn( "Mean", ReportTable::Column::REAL );
+	def.addColumn( "Standard Deviation", ReportTable::Column::REAL );
+	ReportTable& table = report.getTable( "Tally Statistics", def );
+	table
+	<< getLabel()
+	<< getResetTime()
+	<< getUpdateCount()
+	<< getMin()
+	<< getMax()
+	<< getMean()
+	<< getStandardDeviation();
+}
+
+} } // namespace odemx::statistics
diff --git a/odemx-lite/src/synchronization/Bin.cpp b/odemx-lite/src/synchronization/Bin.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6008238502b5d2306d2533a20e6ab8d66adb4288
--- /dev/null
+++ b/odemx-lite/src/synchronization/Bin.cpp
@@ -0,0 +1,201 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Bin.cpp
+
+	\author Ralf Gerstenberger
+
+	\date created at 2002/03/26
+
+	\brief Implementation of odemx::sync::Bin
+
+	\sa Bin.h
+
+	\since 1.0
+*/
+
+#include <odemx/synchronization/Bin.h>
+#include <odemx/base/Process.h>
+#include <odemx/base/Simulation.h>
+
+#include <cassert>
+
+namespace odemx {
+namespace synchronization {
+
+Bin::Bin( base::Simulation& sim, const data::Label& label, std::size_t initialTokens, BinObserver* obs )
+:	data::Producer( sim, label )
+,	data::Observable< BinObserver >( obs )
+,	tokens_( initialTokens )
+,	takeQueue_( sim, getLabel() + " queue" )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Bin) );
+
+	statistics << param( "queue", takeQueue_.getLabel() ).scope( typeid(Bin) );
+	statistics << param( "initial tokens", initialTokens ).scope( typeid(Bin) );
+	statistics << update( "tokens", tokens_ ).scope( typeid(Bin) );
+
+	// observer
+	ODEMX_OBS(BinObserver, Create(this));
+}
+
+Bin::~Bin()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Bin) );
+}
+
+std::size_t Bin::take( std::size_t n )
+{
+	// resource handling only implemented for processes
+	if( ! getCurrentSched()	|| getCurrentSched()->getSchedType() != base::Sched::PROCESS )
+	{
+		error << log( "Bin::take(): called by non-Process object" )
+				.scope( typeid(Bin) );
+		return 0;
+	}
+
+	base::Process* currentProcess = getCurrentProcess();
+
+	// compute order of service, insert the process into the queue
+	takeQueue_.inSort( currentProcess );
+
+	// if not enough tokens or not the first process to serve
+	if( n > tokens_ || currentProcess != takeQueue_.getTop() )
+	{
+		ODEMX_TRACE << log( "take failed" )
+				.detail( "partner", getPartner() )
+				.detail( "requested tokens", n )
+				.scope( typeid(Bin) );
+
+		// observer
+		ODEMX_OBS(BinObserver, TakeFail(this, n));
+
+		// statistics
+		base::SimTime waitStart = getTime();
+
+		// block execution
+		while( n > tokens_ || currentProcess != takeQueue_.getTop() )
+		{
+			currentProcess->sleep();
+
+			if( currentProcess->isInterrupted() )
+			{
+				takeQueue_.remove( currentProcess );
+				return 0;
+			}
+		}
+		// block released here
+
+		// statistics, log the waiting period
+		base::SimTime waitTime = getTime() - waitStart;
+		statistics << update( "wait time", waitTime ).scope( typeid(Bin) );
+	}
+
+	ODEMX_TRACE << log( "change token number" ).valueChange( tokens_, tokens_ - n )
+			.scope( typeid(Bin) );
+
+	// observer
+	ODEMX_OBS_ATTR(BinObserver, TokenNumber, tokens_, tokens_ - n);
+
+	// take tokens
+	tokens_ -= n;
+
+	ODEMX_TRACE << log( "take succeeded" )
+			.detail( "partner", getPartner() )
+			.detail( "requested tokens", n )
+			.scope( typeid(Bin) );
+
+	// statistics
+	statistics << count( "users" ).scope( typeid(Bin) );
+	statistics << update( "tokens", tokens_ ).scope( typeid(Bin) );
+
+	// observer
+	ODEMX_OBS(BinObserver, TakeSucceed(this, n));
+
+	// remove from list
+	takeQueue_.remove( currentProcess );
+
+	// awake next process
+	awakeFirst( &takeQueue_ );
+
+	return n;
+}
+
+void Bin::give( std::size_t n )
+{
+	ODEMX_TRACE << log( "change token number" ).valueChange( tokens_, tokens_ + n )
+			.scope( typeid(Bin) );
+
+	// observer
+	ODEMX_OBS_ATTR(BinObserver, TokenNumber, tokens_, tokens_+n);
+
+	// release tokens
+	tokens_ += n;
+
+	ODEMX_TRACE << log( "give" )
+			.detail( "partner", getPartner() )
+			.detail( "given tokens", n )
+			.scope( typeid(Bin) );
+
+	// statistics
+	statistics << count( "providers" ).scope( typeid(Bin) );
+	statistics << update( "tokens", tokens_ ).scope( typeid(Bin) );
+
+	// observer
+	ODEMX_OBS(BinObserver, Give(this, n));
+
+	// awake next process
+	awakeFirst( &takeQueue_ );
+}
+
+std::size_t Bin::getTokenNumber() const
+{
+	return tokens_;
+}
+
+const base::ProcessList& Bin::getWaitingProcesses() const
+{
+	return takeQueue_.getList();
+}
+
+base::SimTime Bin::getTime() const
+{
+	return getSimulation().getTime();
+}
+
+base::Sched* Bin::getCurrentSched()
+{
+	return getSimulation().getCurrentSched();
+}
+
+base::Process* Bin::getCurrentProcess()
+{
+	return getSimulation().getCurrentProcess();
+}
+
+const data::Label& Bin::getPartner()
+{
+	if( getSimulation().getCurrentSched() != 0 )
+	{
+		return getSimulation().getCurrentSched()->getLabel();
+	}
+
+	return getSimulation().getLabel();
+}
+
+} } // namespace odemx::sync
diff --git a/odemx-lite/src/synchronization/CondQ.cpp b/odemx-lite/src/synchronization/CondQ.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..08098e32ba22414eab1af65559491bbf33cbec91
--- /dev/null
+++ b/odemx-lite/src/synchronization/CondQ.cpp
@@ -0,0 +1,156 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file CondQ.cpp
+
+	\author Ralf Gerstenberger
+
+	\date created at 2002/07/11
+
+	\brief Implementation of odemx::sync::CondQ
+
+	\sa CondQ.h
+
+	\since 1.0
+*/
+
+#include <odemx/synchronization/CondQ.h>
+#include <odemx/base/Process.h>
+#include <odemx/base/Simulation.h>
+
+#include <cassert>
+#include <string>
+
+namespace odemx {
+namespace synchronization {
+
+CondQ::CondQ( base::Simulation& sim, const data::Label& label, CondQObserver* obs )
+:	data::Producer( sim, label )
+,	data::Observable< CondQObserver >( obs )
+,	processes_( sim, getLabel() + ".queue" )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(CondQ) );
+
+	statistics << param( "queue", processes_.getLabel() ).scope( typeid(CondQ) );
+
+	// observer
+	ODEMX_OBS(CondQObserver, Create(this));
+}
+
+CondQ::~CondQ()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(CondQ) );
+}
+
+bool CondQ::wait( base::Condition cond )
+{
+	// resource handling only implemented for processes
+	if( ! getCurrentSched()	|| getCurrentSched()->getSchedType() != base::Sched::PROCESS )
+	{
+		error << log( "CondQ::wait(): called by non-Process object" )
+				.scope( typeid(CondQ) );
+		return false;
+	}
+
+	base::Process* currentProcess = getCurrentProcess();
+
+	ODEMX_TRACE << log( "wait" ).detail( "partner", currentProcess->getLabel() )
+			.scope( typeid(CondQ) );
+
+	// observer
+	ODEMX_OBS(CondQObserver, Wait(this, currentProcess));
+
+	// wait for condition to become true
+	processes_.inSort( currentProcess );
+
+	// statistics
+	base::SimTime waitStart = getTime();
+
+	// check condition and block
+	while( ! cond(currentProcess) )
+	{
+		currentProcess->sleep();
+
+		if( currentProcess->isInterrupted() )
+		{
+			processes_.remove( currentProcess );
+
+			return false;
+		}
+	}
+	// block released
+
+	processes_.remove( currentProcess );
+
+	ODEMX_TRACE << log( "continue" ).detail( "partner", currentProcess->getLabel() )
+			.scope( typeid(CondQ) );
+
+	// statistics
+	base::SimTime waitTime = getTime() - waitStart;
+	statistics << update( "wait time", waitTime ).scope( typeid(CondQ) );
+	statistics << count( "users" ).scope( typeid(CondQ) );
+
+	// observer
+	ODEMX_OBS(CondQObserver, Continue(this, currentProcess));
+
+	return true;
+}
+
+void CondQ::signal()
+{
+	base::Process* current = getCurrentProcess();
+
+	ODEMX_TRACE << log( "signal" )
+			.detail( "partner", ( current ? current->getLabel() : "none" ) )
+			.scope( typeid(CondQ) );
+
+	// observer
+	ODEMX_OBS(CondQObserver, Signal(this, current));
+
+	statistics << count( "signals" ).scope( typeid(CondQ) );
+
+	if( processes_.isEmpty() )
+	{
+		return;
+	}
+
+	// test conditions
+	awakeAll( &processes_ );
+}
+
+const base::ProcessList& CondQ::getWaitingProcesses() const
+{
+	return processes_.getList();
+}
+
+base::SimTime CondQ::getTime() const
+{
+	return getSimulation().getTime();
+}
+
+base::Sched* CondQ::getCurrentSched()
+{
+	return getSimulation().getCurrentSched();
+}
+
+base::Process* CondQ::getCurrentProcess()
+{
+	return getSimulation().getCurrentProcess();
+}
+
+} } // namespace odemx::sync
diff --git a/odemx-lite/src/synchronization/IMemory.cpp b/odemx-lite/src/synchronization/IMemory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..534bd9ab4a60f8b647015dad74a701976494ea26
--- /dev/null
+++ b/odemx-lite/src/synchronization/IMemory.cpp
@@ -0,0 +1,36 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file IMemory.cpp
+ * @author Ronald Kluth
+ * @date created at 2009/02/11
+ * @brief Implementation of odemx::sync::IMemory
+ * @since 3.0
+ */
+
+#include <odemx/synchronization/IMemory.h>
+
+namespace odemx {
+namespace synchronization {
+
+IMemory::~IMemory()
+{
+}
+
+} } // namespace odemx::sync
diff --git a/odemx-lite/src/synchronization/Memory.cpp b/odemx-lite/src/synchronization/Memory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..000b50aacbffb5f29275603e35219721daa799b9
--- /dev/null
+++ b/odemx-lite/src/synchronization/Memory.cpp
@@ -0,0 +1,281 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002 - 2008 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Memory.cpp
+
+	\author Ronald Kluth
+
+	\date created at 2007/04/04
+
+	\brief Implementation of odemx::sync::Memory
+
+	\sa Memory.h
+
+	\since 2.0
+*/
+
+#include <odemx/base/Process.h>
+#include <odemx/base/DefaultSimulation.h>
+#include <odemx/synchronization/Memory.h>
+#include <CppLog/Channel.h>
+
+#include <algorithm>
+#ifdef _MSC_VER
+#include <functional>
+#else
+#include <functional>
+#endif
+
+
+namespace odemx {
+namespace synchronization {
+
+Memory::Memory( base::Simulation& sim, const data::Label& label, Type type,
+		MemoryObserver* obs )
+:	data::Producer( sim, label )
+,	data::Observable< MemoryObserver >( obs )
+,	memoryType_( type )
+,	memoryList_()
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Memory) );
+
+	statistics << update( "waiting", countWaiting() ).scope( typeid(Memory) );
+
+	// observer
+	ODEMX_OBS(MemoryObserver, Create(this));
+}
+
+Memory::~Memory()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Memory) );
+}
+
+bool Memory::remember( base::Sched* newObject )
+{
+	assert( newObject );
+
+	// check if object is already memorized
+	base::SchedList::const_iterator found =
+			std::find( memoryList_.begin(), memoryList_.end(), newObject );
+
+	if ( found != memoryList_.end() )
+	{
+		warning << log( "Memory::remember(): object already stored in list" )
+				.detail( "partner", newObject->getLabel() )
+				.scope( typeid(Memory) );
+
+		return false;
+	}
+
+	// store the new object
+	memoryList_.push_back( newObject );
+
+	ODEMX_TRACE << log( "remember" ).detail( "partner", newObject->getLabel() )
+			.scope( typeid(Memory) );
+
+	statistics << update( "waiting", countWaiting() ).scope( typeid(Memory) );
+
+	// observer
+	ODEMX_OBS( MemoryObserver, Remember( this, newObject ) );
+
+	return true;
+}
+
+bool Memory::forget( base::Sched* rememberedObject )
+{
+	assert( rememberedObject );
+
+	// check if rememberedObject is in memoryList_
+	base::SchedList::iterator found =
+			std::find( memoryList_.begin(), memoryList_.end(), rememberedObject );
+
+	// error if not found
+	if( found == memoryList_.end() )
+	{
+		error << log( "Memory::forget(): object not stored in list" )
+				.detail( "partner", rememberedObject->getLabel() )
+				.scope( typeid(Memory) );
+
+		return false;
+	}
+
+	// remove the object from the list
+	memoryList_.erase( found );
+
+	ODEMX_TRACE << log( "forget" ).detail( "partner", rememberedObject->getLabel() )
+			.scope( typeid(Memory) );
+
+	statistics << update( "waiting", countWaiting() ).scope( typeid(Memory) );
+
+	// observer
+	ODEMX_OBS( MemoryObserver, Forget( this, rememberedObject ) );
+
+	return true;
+}
+
+bool Memory::processIsWaiting (base::Process& process) const {
+	base::SchedList::const_iterator found =
+			std::find( memoryList_.begin(), memoryList_.end(), &process );
+  return found != memoryList_.end ();
+}
+
+void Memory::eraseMemory()
+{
+	memoryList_.clear();
+
+	ODEMX_TRACE << log( "erase" ).scope( typeid(Memory) );
+
+	statistics << update( "waiting", countWaiting() ).scope( typeid(Memory) );
+}
+
+void Memory::alert()
+{
+	alert( this );
+}
+
+void Memory::alert( IMemory* caller )
+{
+	assert( caller );
+
+	// warning if list is empty
+	if( memoryList_.empty() )
+	{
+		warning << log( "Memory::alert(): list empty, cannot alert any object" )
+				.scope( typeid(Memory) );
+		return;
+	}
+
+	// trace record with the whole memory list as details
+	traceAlert();
+
+	// observer
+	ODEMX_OBS( MemoryObserver, Alert( this ) );
+
+	// iterate over memoryList_ and schedule processes
+	base::SchedList::iterator iter;
+	for( iter = memoryList_.begin(); iter != memoryList_.end(); ++iter )
+	{
+		// check if Sched* really is a sleeping process and
+		// reschedule CREATED and IDLE processes in memory
+		if( checkSchedForAlert( *iter ) )
+		{
+			// wake up the process
+			static_cast< base::Process* >( *iter )->alertProcess( caller );
+		}
+		else
+		{
+			warning << log( "Memory::alert(): could not alert Sched object" )
+					.detail( "partner", ( *iter )->getLabel() )
+					.scope( typeid(Memory) );
+		}
+	}
+
+	// remove stored objects from memory
+	eraseMemory();
+}
+
+bool Memory::checkSchedForAlert( base::Sched* s )
+{
+	assert( s );
+
+	// check if s really is a sleeping process
+	if( s->getSchedType() != base::Sched::PROCESS )
+	{
+		warning << log( "Memory::checkSchedForAlert(): object is not a process" )
+				.detail( "partner", s->getLabel() )
+				.scope( typeid(Memory) );
+		return false;
+	}
+
+	base::Process* p = static_cast< base::Process* >( s );
+
+	// only sleeping Processes are allowed to be alerted
+	switch( p->getProcessState() )
+	{
+	case base::Process::CREATED: // fall-through
+	case base::Process::IDLE:
+		return true;
+
+	case base::Process::CURRENT:
+		warning << log( "Memory::checkSchedForAlert(): attempt to alert current process" )
+				.detail( "partner", p->getLabel() )
+				.scope( typeid(Memory) );
+		break;
+
+	case base::Process::RUNNABLE:
+		warning << log( "Memory::checkSchedForAlert(): process already scheduled" )
+				.detail( "partner", p->getLabel() )
+				.scope( typeid(Memory) );
+		break;
+
+	case base::Process::TERMINATED:
+		error << log( "Memory::checkSchedForAlert(): process already terminated" )
+				.detail( "partner", p->getLabel() )
+				.scope( typeid(Memory) );
+		break;
+
+	}
+	return false;
+}
+
+bool Memory::isAvailable()
+{
+	return false;
+}
+
+
+bool Memory::waiting() const
+{
+	return ! memoryList_.empty();
+}
+
+Memory::SizeType Memory::countWaiting() const
+{
+	return memoryList_.size();
+}
+
+const base::SchedList& Memory::getWaiting() const
+{
+	return memoryList_;
+}
+
+IMemory::Type Memory::getMemoryType() const
+{
+	return memoryType_;
+}
+
+void Memory::traceAlert()
+{
+	if( ODEMX_TRACE_ENABLED )
+	{
+		// create record for alert with scope Memory
+		data::SimRecord record = log( "alert" ).scope( typeid(Memory) );
+
+		// add record details: stored objects
+		base::SchedList::const_iterator iter;
+		for( iter = memoryList_.begin(); iter != memoryList_.end(); ++iter )
+		{
+			record.detail( "partner", ( *iter )->getLabel() );
+		}
+
+		// log the record to the trace
+		ODEMX_TRACE << record;
+	}
+}
+
+} } // namespace odemx::sync
diff --git a/odemx-lite/src/synchronization/ProcessQueue.cpp b/odemx-lite/src/synchronization/ProcessQueue.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d059d7126a45ec8c31f2020d9489b0414dc23300
--- /dev/null
+++ b/odemx-lite/src/synchronization/ProcessQueue.cpp
@@ -0,0 +1,232 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004, 2007, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file ProcessQueue.cpp
+ * @author Ralf Gerstenberger
+ * @date created at 2002/03/25
+ * @brief Implementation of odemx::sync::ProcessQueue
+ * @sa ProcessQueue.h
+ * @since 1.0
+ */
+
+#include <odemx/synchronization/ProcessQueue.h>
+#include <odemx/base/Comparators.h>
+#include <odemx/base/Process.h>
+#include <odemx/util/ListInSort.h>
+
+#include <algorithm>
+
+namespace odemx {
+namespace synchronization {
+
+//------------------------------------------------------construction/destruction
+
+ProcessQueue::ProcessQueue()
+:	processes_()
+,	length_( 0 )
+{
+}
+
+ProcessQueue::~ProcessQueue()
+{
+}
+
+//------------------------------------------------------------------queue access
+
+bool ProcessQueue::isEmpty() const
+{
+	return processes_.empty();
+}
+
+base::Process* ProcessQueue::getTop() const
+{
+	return processes_.empty() ? 0 : *processes_.begin();
+}
+
+const base::ProcessList& ProcessQueue::getList() const
+{
+	return processes_;
+}
+
+ProcessQueue::SizeType ProcessQueue::getLength() const
+{
+	return length_; // a lot faster than calling list::size()
+}
+
+ProcessQueue::SizeType ProcessQueue::getPosition( base::Process* p ) const
+{
+	assert( p != 0 );
+
+	SizeType pos = 1;
+
+	base::ProcessList::const_iterator iter = processes_.begin();
+
+	// count positions until p is found
+	while( iter != processes_.end() && ( *iter ) != p )
+	{
+		++pos;
+		++iter;
+	}
+
+	// check if p was found
+	if( iter != processes_.end() && ( *iter ) == p )
+	{
+		return pos;
+	}
+
+	return 0;
+}
+
+//------------------------------------------------------------queue manipulation
+
+void ProcessQueue::popQueue()
+{
+	if( ! processes_.empty() )
+	{
+		ProcessQueue::remove( *processes_.begin() );
+	}
+}
+
+void ProcessQueue::remove( base::Process* p )
+{
+	assert( p != 0 );
+
+	// Process p forgets this queue
+	p->dequeue( this );
+
+	processes_.erase( p->queueListIter_ );
+	--length_;
+}
+
+void ProcessQueue::inSort( base::Process* p,  bool fifo )
+{
+	assert( p != 0 );
+
+	// if already in this queue, remove previous entry of Process* p
+	if( p->queue_ == this )
+	{
+		processes_.erase( p->queueListIter_ );
+		p->queue_ = 0; // queue_ != 0 would cause error in Process::enqueue()
+	}
+	// not yet in queue, increment size
+	else
+	{
+		++length_;
+	}
+
+	// Process p has to remember this queue
+	p->enqueue( this );
+
+	// insert s into ordered list and store the location as iterator
+	p->queueListIter_ =
+		ListInSort< base::Process*, base::QPriorityCmp >(
+				processes_, p, base::qPrioCmp, fifo );
+}
+
+//----------------------------------------------------------free queue functions
+
+void awakeAll( ProcessQueue* q )
+{
+	if( q->isEmpty() )
+	{
+		return;
+	}
+
+	base::Sched* currentlyRunning = q->getTop()->getCurrentSched(); // may return 0 !
+
+	base::ProcessList::const_iterator i;
+	for( i = q->getList().begin(); i != q->getList().end(); ++i )
+	{
+		base::Process* p = *i;
+
+		assert( static_cast< base::Sched* >( p ) != currentlyRunning );
+
+		// cannot activate after current event, must use activate
+		if( ! currentlyRunning || currentlyRunning->getSchedType() == base::Sched::EVENT )
+		{
+			p->activate();
+		}
+		else // a process is currently running
+		{
+			p->activateAfter( currentlyRunning );
+		}
+	}
+}
+
+void awakeFirst( ProcessQueue* q )
+{
+	if( q->isEmpty() )
+	{
+		return;
+	}
+
+	base::Sched* current = q->getTop()->getCurrentSched(); // may return 0 !
+
+	// cannot activate after current event, must use activate
+	if( ! current || current->getSchedType() == base::Sched::EVENT )
+	{
+		q->getTop()->activate();
+	}
+	else
+	{
+		if( q->getTop() != current )
+		{
+			q->getTop()->activateAfter( current );
+		}
+	}
+}
+
+void awakeNext( ProcessQueue* q, base::Process* p )
+{
+	if( q->isEmpty() )
+	{
+		return;
+	}
+
+	base::Sched* current = p->getCurrentSched(); // may return 0 !
+
+	base::ProcessList::const_iterator iter = std::find( q->getList().begin(), q->getList().end(), p );
+
+	// check if p was found
+	if( iter != q->getList().end() )
+	{
+		++iter;
+
+		// check if next position is valid
+		if( iter != q->getList().end() )
+		{
+			base::Process* p = *iter;
+
+			// cannot activate after current event, must use activate
+			if( ! current || current->getSchedType() == base::Sched::EVENT )
+			{
+				p->activate();
+			}
+			else
+			{
+				if( p != current )
+				{
+					p->activateAfter( current );
+				}
+			}
+		}
+	}
+}
+
+} } // namespace odemx::sync
diff --git a/odemx-lite/src/synchronization/Queue.cpp b/odemx-lite/src/synchronization/Queue.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f9aca0bfb6a01cd62a4a63d09df7d5d558a55aee
--- /dev/null
+++ b/odemx-lite/src/synchronization/Queue.cpp
@@ -0,0 +1,104 @@
+//------------------------------------------------------------------------------
+//	Copyright (C) 2003, 2004, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//------------------------------------------------------------------------------
+
+/**
+ * @file Queue.cpp
+ * @author Ralf Gerstenberger
+ * @date created at 2003/06/28
+ * @brief Implementation of odemx::sync::Queue
+ * @sa Queue.h
+ * @since 1.0
+ */
+
+#ifdef _MSC_VER
+#pragma warning (disable : 4786)
+#endif
+
+#include <odemx/synchronization/Queue.h>
+#include <odemx/base/Process.h>
+
+#include <string>
+#include <vector>
+
+namespace odemx {
+namespace synchronization {
+
+//------------------------------------------------------construction/destruction
+
+Queue::Queue( base::Simulation& sim, const data::Label& label )
+:	data::Producer( sim, label )
+,	ProcessQueue()
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Queue) );
+	statistics << update( "length", getLength() ).scope( typeid(Queue) );
+}
+
+Queue::~Queue()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Queue) );
+}
+
+//------------------------------------------------------------queue manipulation
+
+void Queue::popQueue()
+{
+	base::Process* first = ProcessQueue::getTop();
+	ProcessQueue::popQueue();
+
+	if( first != 0 )
+	{
+		ODEMX_TRACE << log( "pop queue" )
+				.detail( "process", first->getLabel() )
+				.scope( typeid(Queue) );
+	}
+	else
+	{
+		warning << log( "Queue::popQueue(): called on empty queue" )
+				.scope( typeid(Queue) );
+	}
+
+	statistics << update( "length", getLength() ).scope( typeid(Queue) );
+}
+
+void Queue::remove( base::Process* p )
+{
+	assert( p );
+
+	ProcessQueue::remove( p );
+
+	ODEMX_TRACE << log( "remove" )
+			.detail( "process", p->getLabel() )
+			.scope( typeid(Queue) );
+
+	statistics << update( "length", getLength() ).scope( typeid(Queue) );
+}
+
+void Queue::inSort( base::Process* p,  bool fifo )
+{
+	assert( p );
+
+	ProcessQueue::inSort( p, fifo );
+
+	ODEMX_TRACE << log( "insert" )
+			.detail( "process", p->getLabel() )
+			.scope( typeid(Queue) );
+
+	statistics << update( "length", getLength() ).scope( typeid(Queue) );
+}
+
+} } // namespace odemx::sync
diff --git a/odemx-lite/src/synchronization/Res.cpp b/odemx-lite/src/synchronization/Res.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f068760ff541f6de93245a77e5f10d871b2472bf
--- /dev/null
+++ b/odemx-lite/src/synchronization/Res.cpp
@@ -0,0 +1,269 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Res.cpp
+
+	\author Ralf Gerstenberger
+
+	\date created at 2002/03/21
+
+	\brief Implementation of odemx::sync::Res
+
+	\sa Res.h
+
+	\since 1.0
+*/
+
+#include <odemx/synchronization/Res.h>
+#include <odemx/base/Process.h>
+#include <odemx/base/Simulation.h>
+
+#include <algorithm>
+#include <cassert>
+#include <string>
+
+namespace odemx {
+namespace synchronization {
+
+Res::Res( base::Simulation& sim, const data::Label& label, std::size_t initialTokens,
+		std::size_t maxTokens, ResObserver* obs )
+:	data::Producer( sim, label )
+,	data::Observable< ResObserver >( obs )
+,	tokens_( initialTokens )
+,	tokenLimit_( maxTokens )
+,	acquireQueue_( sim, getLabel() + ".queue" )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Res) );
+
+	statistics << param( "queue", acquireQueue_.getLabel() ).scope( typeid(Res) );
+	statistics << param( "initial tokens", initialTokens ).scope( typeid(Res) );
+	statistics << param( "initial token limit", tokenLimit_ ).scope( typeid(Res) );
+	statistics << update( "tokens", tokens_ ).scope( typeid(Res) );
+
+	// observer
+	ODEMX_OBS(ResObserver, Create(this));
+}
+
+Res::~Res()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Res) );
+}
+
+std::size_t Res::acquire( std::size_t n )
+{
+	// resource handling only implemented for processes
+	if( ! getCurrentSched() || getCurrentSched()->getSchedType() != base::Sched::PROCESS )
+	{
+		error << log( "Res::acquire(): called by non-Process object" )
+				.scope( typeid(Res) );
+		return 0;
+	}
+
+	if( n > getTokenLimit() )
+	{
+		warning << log( "Res::acquire(): requesting more than max tokens will always block" )
+				.scope( typeid(Res) );
+	}
+
+	base::Process* currentProcess = getCurrentProcess();
+
+	// compute order of service
+	acquireQueue_.inSort( currentProcess );
+
+	// statistics
+	base::SimTime waitTime = 0;
+
+	// if not enough tokens or not the first process to serve
+	if( n > tokens_ || currentProcess != acquireQueue_.getTop() )
+	{
+		ODEMX_TRACE << log( "acquire failed" )
+				.detail( "partner", getPartner() )
+				.detail( "requested tokens", n )
+				.scope( typeid(Res) );
+
+		// observer
+		ODEMX_OBS(ResObserver, AcquireFail(this, n));
+
+		// statistics
+		base::SimTime waitStart = getTime();
+
+		// block execution
+		while( n > tokens_ || currentProcess != acquireQueue_.getTop() )
+		{
+			currentProcess->sleep();
+
+			if( currentProcess->isInterrupted() )
+			{
+				acquireQueue_.remove( currentProcess );
+				return 0;
+			}
+		}
+		// block released here
+
+		// statistics
+		waitTime = getTime() - waitStart;
+	}
+
+	ODEMX_TRACE << log( "change token number" ).valueChange( tokens_, tokens_ - n )
+			.scope( typeid(Res) );
+
+	// observer
+	ODEMX_OBS_ATTR(ResObserver, TokenNumber, tokens_, tokens_-n);
+
+	// acquire tokens
+	tokens_ -= n;
+
+	ODEMX_TRACE << log( "acquire succeeded" )
+			.detail( "partner", getPartner() )
+			.detail( "requested tokens", n )
+			.scope( typeid(Res) );
+
+	// statistics
+	statistics << count( "users" ).scope( typeid(Res) );
+	statistics << update( "tokens", tokens_ ).scope( typeid(Res) );
+	statistics << update( "wait time", waitTime ).scope( typeid(Res) );
+
+	// observer
+	ODEMX_OBS(ResObserver, AcquireSucceed(this, n));
+
+	// remove from list
+	acquireQueue_.remove( currentProcess );
+
+	// awake next process
+	awakeFirst( &acquireQueue_ );
+
+	return n;
+}
+
+void Res::release( std::size_t n )
+{
+	// check for sufficient release space
+	if( ( tokens_ + n ) > tokenLimit_ )
+	{
+		ODEMX_TRACE << log( "release failed" )
+				.detail( "partner", getPartner() )
+				.detail( "released tokens", n )
+				.scope( typeid(Res) );
+
+		// observer
+		ODEMX_OBS(ResObserver, ReleaseFail(this, n));
+
+		error << log( "Res::release(): limit reached, could not release all tokens" )
+				.scope( typeid(Res) );
+
+		// set released token number to whatever space was left
+		n = tokenLimit_ - tokens_;
+	}
+
+	ODEMX_TRACE << log( "change token number" ).valueChange( tokens_, tokens_ + n )
+			.scope( typeid(Res) );
+
+	// observer
+	ODEMX_OBS_ATTR(ResObserver, TokenNumber, tokens_, tokens_ + n);
+
+	// release tokens
+	tokens_ += n;
+
+	statistics << count( "providers" ).scope( typeid(Res) );
+	statistics << update( "tokens", tokens_ ).scope( typeid(Res) );
+
+	ODEMX_TRACE << log( "release succeeded" )
+			.detail( "partner", getPartner() )
+			.detail( "released tokens", n )
+			.scope( typeid(Res) );
+
+	// observer
+	ODEMX_OBS(ResObserver, ReleaseSucceed(this, n));
+
+	// awake process waiting for release
+	awakeFirst( &acquireQueue_ );
+}
+
+void Res::control( std::size_t n )
+{
+	ODEMX_TRACE << log( "increase token limit" )
+			.detail( "amount", n ).scope( typeid(Res) );
+
+	// observer
+	ODEMX_OBS(ResObserver, Control(this, n));
+
+	// change max token limit
+	tokenLimit_ += n;
+
+	// add tokens
+	release( n );
+}
+
+std::size_t Res::unControl( std::size_t n )
+{
+	ODEMX_TRACE << log( "decrease token limit" )
+		.detail( "amount", n ).scope( typeid(Res) );
+
+	// observer
+	ODEMX_OBS(ResObserver, UnControl(this, n));
+
+	// secure enough tokens
+	std::size_t tmp = acquire( n );
+
+	// remove tokens
+	tokenLimit_ -= tmp;
+
+	return tmp;
+}
+
+std::size_t Res::getTokenNumber() const
+{
+	return tokens_;
+}
+
+std::size_t Res::getTokenLimit() const
+{
+	return tokenLimit_;
+}
+
+const base::ProcessList& Res::getWaitingProcesses() const
+{
+	return acquireQueue_.getList();
+}
+
+base::SimTime Res::getTime() const
+{
+	return getSimulation().getTime();
+}
+
+base::Sched* Res::getCurrentSched()
+{
+	return getSimulation().getCurrentSched();
+}
+
+base::Process* Res::getCurrentProcess()
+{
+	return getSimulation().getCurrentProcess();
+}
+
+const data::Label& Res::getPartner()
+{
+	if( getSimulation().getCurrentSched() != 0 )
+	{
+		return getSimulation().getCurrentSched()->getLabel();
+	}
+
+	return getSimulation().getLabel();
+}
+
+} } // namespace odemx::sync
diff --git a/odemx-lite/src/synchronization/Timer.cpp b/odemx-lite/src/synchronization/Timer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..45e880d22a96b82121d56a63d7ce9dfc0ee37c8d
--- /dev/null
+++ b/odemx-lite/src/synchronization/Timer.cpp
@@ -0,0 +1,241 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2007, 2008, 2009 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Timer.cpp
+
+	\author Ronald Kluth
+
+	\date created at 2007/04/04
+
+	\brief Implementation of odemx::sync::Timer
+
+	\sa Timer.h
+
+	\since 2.0
+*/
+
+#include <odemx/synchronization/Timer.h>
+#include <odemx/base/Process.h>
+
+#include <cassert>
+
+namespace odemx {
+namespace synchronization {
+
+const int MAX_PRIORITY = 0xffff;
+
+//------------------------------------------------------construction/destruction
+
+Timer::Timer( base::Simulation& sim, const data::Label& label, TimerObserver* obs )
+:	Event( sim, label, obs )
+,	data::Observable< TimerObserver >( obs )
+,	memory_( sim, getLabel() + ".memory", IMemory::TIMER )
+{
+	setPriority( MAX_PRIORITY );
+
+	ODEMX_TRACE << log( "create" ).scope( typeid(Timer) );
+
+	// observer
+	ODEMX_OBS(TimerObserver, Create(this));
+}
+
+Timer::~Timer()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Timer) );
+
+	// destruction of scheduled timers might crash
+	// the simulation, hence remove them here
+	if( isSet() )
+	{
+		stop();
+	}
+}
+
+//--------------------------------------------------------------------scheduling
+
+void Timer::setIn( base::SimTime t )
+{
+	// cannot schedule Timer
+	if( t < 0 )
+	{
+		error << log( "Timer::setIn(): cannot schedule Timer, invalid SimTime < 0" )
+				.scope( typeid(Timer) );
+		return;
+	}
+
+	ODEMX_TRACE << log( "set in" ).detail( "relative time", t ).scope( typeid(Timer) );
+
+	// observer
+	ODEMX_OBS( TimerObserver, SetIn( this, t ) );
+
+	// scheduling
+	scheduleIn( t );
+}
+
+void Timer::setAt( base::SimTime t )
+{
+	// cannot schedule Timer
+	if ( t < getTime() )
+	{
+		error << log( "Timer::setAt(): cannot schedule Timer, SimTime already passed" )
+				.scope( typeid(Timer) );
+		return;
+	}
+
+	ODEMX_TRACE << log( "set at" ).detail( "absolute time", t ).scope( typeid(Timer) );
+
+	// observer
+	ODEMX_OBS( TimerObserver, SetAt( this, t ) );
+
+	// scheduling
+	scheduleAt( t );
+}
+
+void Timer::reset( base::SimTime t )
+{
+	if( ! isScheduled() )
+	{
+		warning << log( "Timer::reset(): scheduling of idle Timer using reset" )
+				.scope( typeid(Timer) );
+	}
+
+	// cannot schedule Timer
+	if( t < 0 )
+	{
+		error << log( "Timer::reset(): cannot schedule Timer, invalid SimTime < 0" )
+				.scope( typeid(Timer) );
+		return;
+	}
+
+	ODEMX_TRACE << log( "reset" ).detail( "relative time", t ).scope( typeid(Timer) );
+
+	// observer
+	ODEMX_OBS( TimerObserver, Reset( this, getExecutionTime(), t ) );
+
+	// scheduling
+	scheduleIn( t );
+}
+
+void Timer::stop()
+{
+	ODEMX_TRACE << log( "stop" ).scope( typeid(Timer) );
+
+	// observer
+	ODEMX_OBS( TimerObserver, Stop( this ) );
+
+	// error check done in removeFromSchedule
+	removeFromSchedule();
+
+	// remove all waiting processes from Memory
+	eraseMemory();
+}
+
+bool Timer::isSet()
+{
+	return isScheduled();
+}
+
+//-----------------------------------------------------------Process interaction
+
+bool Timer::registerProcess( base::Process* p )
+{
+	assert( p );
+
+	ODEMX_TRACE << log( "register process" )
+			.detail( "partner", p->getLabel() )
+			.scope( typeid(Timer) );
+
+	// observer
+	ODEMX_OBS( TimerObserver, RegisterProcess( this, p ) );
+
+	return remember( p );
+}
+
+bool Timer::removeProcess( base::Process* p )
+{
+	assert( p );
+
+	ODEMX_TRACE << log( "remove process" )
+			.detail( "partner", p->getLabel() )
+			.scope( typeid(Timer) );
+
+	// observer
+	ODEMX_OBS( TimerObserver, RemoveProcess( this, p ) );
+
+	return forget( p );
+}
+
+//----------------------------------------------------------Event implementation
+
+void Timer::eventAction()
+{
+	ODEMX_TRACE << log( "timeout" ).scope( typeid(Timer) );
+
+	// observer
+	ODEMX_OBS( TimerObserver, Timeout( this ) );
+
+	if( ! memory_.waiting() )
+	{
+		warning << log( "Timer::eventAction(): memory empty, cannot alert any process" )
+				.scope( typeid(Timer) );
+	}
+	else
+	{
+		// reschedule registered processes
+		alert();
+	}
+}
+
+//--------------------------------------------------------IMemory implementation
+
+IMemory::Type Timer::getMemoryType() const
+{
+	return memory_.getMemoryType();
+}
+
+bool Timer::isAvailable()
+{
+	return ! Event::isScheduled();
+}
+
+void Timer::alert()
+{
+	memory_.alert( this );
+}
+
+bool Timer::remember( base::Sched* newObject )
+{
+	return memory_.remember( newObject );
+}
+
+bool Timer::forget( base::Sched* rememberedObject )
+{
+	return memory_.forget( rememberedObject );
+}
+
+void Timer::eraseMemory()
+{
+	memory_.eraseMemory();
+}
+
+const base::SchedList& Timer::getWaiting() const
+{
+	return memory_.getWaiting();
+}
+
+} } // namespace odemx::sync
diff --git a/odemx-lite/src/synchronization/Wait.cpp b/odemx-lite/src/synchronization/Wait.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8be0c8990fff879b0a59ca77b7f502ef154b5da0
--- /dev/null
+++ b/odemx-lite/src/synchronization/Wait.cpp
@@ -0,0 +1,261 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file Wait.cpp
+
+	\author Ralf Gerstenberger
+
+	\date created at 2003/06/06
+
+	\brief Implementation of classes in Wait.h
+
+	\sa Wait.h
+
+	\since 1.0
+*/
+
+#include <odemx/setup.h>
+
+#ifdef ODEMX_USE_OBSERVATION
+
+#include <odemx/synchronization/Wait.h>
+#include <odemx/base/Simulation.h>
+
+namespace odemx {
+namespace synchronization {
+
+Wait::Wait( base::Simulation& sim, const data::Label& label )
+:	data::Producer( sim, label )
+,	waitForAll_( true )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Wait) );
+}
+
+Wait::Wait( base::Simulation& sim, const data::Label& label, base::Process* p1 )
+:	data::Producer( sim, label )
+,	waitForAll_( true )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Wait) );
+
+	base::Process* ppP[1] = { p1 };
+	initObservedList( 1, ppP );
+}
+
+Wait::Wait( base::Simulation& sim, const data::Label& label, base::Process* p1,
+		base::Process* p2, bool all )
+:	data::Producer( sim, label )
+,	waitForAll_( all )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Wait) );
+
+	base::Process* ppP[2] = { p1, p2 };
+	initObservedList( 2, ppP );
+}
+
+Wait::Wait( base::Simulation& sim, const data::Label& label, base::Process* p1,
+		base::Process* p2, base::Process* p3, bool all )
+:	data::Producer( sim, label )
+,	waitForAll_( all )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Wait) );
+
+	base::Process* ppP[3] = { p1, p2, p3 };
+	initObservedList( 3, ppP );
+}
+
+Wait::Wait( base::Simulation& sim, const data::Label& label, int size,
+		base::Process* p[], bool all )
+:	data::Producer( sim, label )
+,	waitForAll_( all )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(Wait) );
+
+	initObservedList( size, p );
+}
+
+Wait::~Wait()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(Wait) );
+}
+
+void Wait::addProcess( base::Process* p )
+{
+	assert( p );
+
+	ODEMX_TRACE << log( "add process" ).detail( "partner", p->getLabel() ).scope( typeid(Wait) );
+
+	observedProcesses_.push_back( p );
+}
+
+void Wait::removeProcess( base::Process* p )
+{
+	assert( p );
+
+	ODEMX_TRACE << log( "remove process" ).detail( "partner", p->getLabel() ).scope( typeid(Wait) );
+
+	observedProcesses_.remove(p);
+}
+
+const base::ProcessList& Wait::getWaitingProcesses() const
+{
+	return observedProcesses_;
+}
+
+bool Wait::getCondition() const
+{
+	return waitForAll_;
+}
+
+void Wait::setCondition( bool all )
+{
+	waitForAll_ = all;
+}
+
+void Wait::onChangeProcessState( base::Process* sender,
+		base::Process::ProcessState oldState,
+		base::Process::ProcessState newState )
+{
+	if( newState == base::Process::TERMINATED )
+	{
+		// check condition
+		waitCaller_->activate();
+
+		// remove sender from observed list, no need to check it again
+		observedProcesses_.remove( sender );
+
+		// remove this as observer of the sender
+		sender->data::Observable< base::ProcessObserver >::removeObserver( this );
+	}
+}
+
+bool Wait::wait()
+{
+	// store the caller that wants to be awakened
+	// upon termination of other processes
+	waitCaller_ = getSimulation().getCurrentProcess();
+
+	ODEMX_TRACE << log( "wait" )
+			.detail( "partner", waitCaller_->getLabel() )
+			.scope( typeid(Wait) );
+
+	base::ProcessList::iterator i;
+
+	// first check condition
+	if( ! checkObserved() )
+	{
+		// add this as observer
+		for( i = observedProcesses_.begin(); i != observedProcesses_.end(); ++i )
+		{
+			(*i)->data::Observable< base::ProcessObserver >::addObserver( this );
+		}
+	}
+	else
+	{
+		ODEMX_TRACE << log( "continue" )
+				.detail( "partner", waitCaller_->getLabel() )
+				.scope( typeid(Wait) );
+
+		return true;
+	}
+
+	// Wait for condition, block process execution
+	while( ! checkObserved() )
+	{
+		waitCaller_->sleep();
+
+		// Handle interrupt
+		if( waitCaller_->isInterrupted() )
+		{
+			// Remove this as observer
+			for( i = observedProcesses_.begin(); i != observedProcesses_.end(); ++i )
+			{
+				(*i)->data::Observable< base::ProcessObserver >::removeObserver( this );
+			}
+
+			ODEMX_TRACE << log( "continue" )
+					.detail( "partner", waitCaller_->getLabel() )
+					.scope( typeid(Wait) );
+
+			return false;
+		}
+	}
+	// Condition fulfilled, block released
+
+	// Remove this as observer
+	for( i = observedProcesses_.begin(); i != observedProcesses_.end(); ++i )
+	{
+		(*i)->data::Observable<base::ProcessObserver>::removeObserver( this );
+	}
+
+	ODEMX_TRACE << log( "continue" )
+			.detail( "partner", waitCaller_->getLabel() )
+			.scope( typeid(Wait) );
+
+	return true;
+}
+
+void Wait::initObservedList( size_t size, base::Process* p[] )
+{
+	base::Process* proc = 0;
+
+	// Add entries from p in observedProcesses_
+	for( size_t i = 0; i < size; ++i )
+	{
+		proc = p[i];
+
+		if( proc != 0 )
+		{
+			addProcess( proc );
+		}
+	}
+}
+
+bool Wait::checkObserved()
+{
+	// Check Condition: one(all) observed process(es) TERMINATED
+	base::ProcessList::iterator i;
+
+	if( waitForAll_ )
+	{
+		for( i = observedProcesses_.begin(); i != observedProcesses_.end(); ++i )
+		{
+			// return false if not all processes have terminated
+			if( (*i)->getProcessState() != base::Process::TERMINATED )
+			{
+				return false;
+			}
+		}
+		return true;
+	}
+	else
+	{
+		for( i = observedProcesses_.begin(); i != observedProcesses_.end(); ++i )
+		{
+			// return true if one of the observed processes has terminated
+			if( (*i)->getProcessState() == base::Process::TERMINATED )
+			{
+				return true;
+			}
+		}
+		return false;
+	}
+}
+
+} } // namespace odemx::sync
+
+#endif /* ODEMX_USE_OBSERVATION */
diff --git a/odemx-lite/src/synchronization/WaitQ.cpp b/odemx-lite/src/synchronization/WaitQ.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2f845b822eb5d827af61502539633f1315fe64c6
--- /dev/null
+++ b/odemx-lite/src/synchronization/WaitQ.cpp
@@ -0,0 +1,486 @@
+//----------------------------------------------------------------------------
+//	Copyright (C) 2002, 2004 Humboldt-Universitaet zu Berlin
+//
+//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+//----------------------------------------------------------------------------
+/**	\file WaitQ.cpp
+
+	\author Ralf Gerstenberger
+
+	\date created at 2002/03/26
+
+	\brief Implementation of odemx::sync::WaitQ
+
+	\sa WaitQ.h
+
+	\since 1.0
+*/
+
+#include <odemx/synchronization/WaitQ.h>
+#include <odemx/base/Process.h>
+#include <odemx/base/Sched.h>
+#include <odemx/base/Simulation.h>
+
+#include <string>
+#include <cassert>
+
+namespace odemx {
+namespace synchronization {
+
+WaitQ::WaitQ( base::Simulation& sim, const data::Label& label, WaitQObserver* obs )
+:	data::Producer( sim, label )
+,	data::Observable< WaitQObserver >( obs )
+,	masterQueue_( sim, getLabel() + ".master-queue" )
+,	slaveQueue_( sim, getLabel() + ".slave-queue" )
+{
+	ODEMX_TRACE << log( "create" ).scope( typeid(WaitQ) );
+
+	statistics << param( "master queue", masterQueue_.getLabel() ).scope( typeid(WaitQ) );
+	statistics << param( "slave queue", slaveQueue_.getLabel() ).scope( typeid(WaitQ) );
+
+	// observer
+	ODEMX_OBS(WaitQObserver, Create(this));
+}
+
+WaitQ::~WaitQ()
+{
+	ODEMX_TRACE << log( "destroy" ).scope( typeid(WaitQ) );
+}
+
+bool WaitQ::wait()
+{
+	// WaitQ synchronization only implemented for processes
+	if( ! getCurrentSched() || getCurrentSched()->getSchedType() != base::Sched::PROCESS )
+	{
+		error << log( "WaitQ::wait(): called by non-Process object" )
+				.scope( typeid(WaitQ) );
+		return false;
+	}
+
+	base::Process* slave = getCurrentProcess();
+
+	ODEMX_TRACE << log( "wait" ).detail( "slave", slave->getLabel() ).scope( typeid(WaitQ) );
+
+	// observer
+	ODEMX_OBS(WaitQObserver, Wait(this, slave));
+
+	// awake masters
+	awakeAll( &masterQueue_ );
+
+	// slave waits for master
+	slaveQueue_.inSort( slave );
+
+	// entrance time in queue is stored equal to execution time
+	// sleep
+	slave->sleep();
+
+	if( slave->isInterrupted() )
+	{
+		slaveQueue_.remove( slave );
+		return false;
+	}
+
+	return true;
+}
+
+bool WaitQ::wait( base::Weight weightFct )
+{
+	// WaitQ synchronization only implemented for processes
+	if( ! getCurrentSched() || getCurrentSched()->getSchedType() != base::Sched::PROCESS )
+	{
+		error << log( "WaitQ::wait(): called by non-Process object" )
+				.scope( typeid(WaitQ) );
+		return false;
+	}
+
+	base::Process* slave = getCurrentProcess();
+
+	ODEMX_TRACE << log( "wait weight" ).detail( "slave", slave->getLabel() ).scope( typeid(WaitQ) );
+
+	// observer
+	ODEMX_OBS(WaitQObserver, WaitWeight(this, slave));
+
+	if( ! masterQueue_.isEmpty() )
+	{
+		// evaluate master weight function for this slave
+		base::ProcessList::const_iterator i = masterQueue_.getList().begin();
+		base::ProcessList::const_iterator end = masterQueue_.getList().end();
+
+		// initialize max weighted master variable
+		base::Process* maxWeightMaster = *i;
+		// get weight of slave in relation to first master
+		double maxWeight = weightFct(maxWeightMaster, slave);
+
+		// iterate over master queue to get the master
+		// where this slave's weight is highest
+		for( ++i; i != end; ++i )
+		{
+			// get the slave's weight for the current master
+			double currentWeight = weightFct(*i, slave);
+
+			// if current master's slave weight is highest so far, remember it
+			if( currentWeight > maxWeight )
+			{
+				maxWeight = currentWeight;
+				maxWeightMaster = *i;
+			}
+		}
+		// awaken the master process with the highest weight evaluation
+		maxWeightMaster->activateAfter( slave );
+	}
+
+	// slave waits for master
+	slaveQueue_.inSort( slave );
+
+	// entrance time in queue is stored equal to execution time
+	// sleep
+	slave->sleep();
+
+	if( slave->isInterrupted() )
+	{
+		slaveQueue_.remove( slave );
+		return false;
+	}
+
+	return true;
+}
+
+base::Process* WaitQ::coopt( base::Weight weightFct )
+{
+	// WaitQ synchronization only implemented for processes
+	if( ! getCurrentSched() || getCurrentSched()->getSchedType() != base::Sched::PROCESS )
+	{
+		error << log( "WaitQ::coopt(): called by non-Process object" )
+				.scope( typeid(WaitQ) );
+		return 0;
+	}
+
+	base::Process* master = getCurrentProcess();
+	base::Process* slave = getWeightedSlave( master, weightFct );
+
+	// no slave available
+	if( slave == 0 )
+	{
+		ODEMX_TRACE << log( "coopt weight failed" )
+				.detail( "master", master->getLabel() )
+				.scope( typeid(WaitQ) );
+
+		// observer
+		ODEMX_OBS(WaitQObserver, CooptWeightFail(this, master));
+
+		// master is waiting for slave
+		masterQueue_.inSort( master );
+
+		// this master must wait
+		do
+		{
+			master->sleep();
+
+			if( master->isInterrupted() )
+			{
+				masterQueue_.remove( master );
+				return 0;
+			}
+			slave = getWeightedSlave( master, weightFct );
+		}
+		while( slave == 0 );
+
+		// block released
+
+		masterQueue_.remove( master );
+	}
+
+	// remove chosen slave from queue
+	slaveQueue_.remove( slave );
+
+	// statistics
+	updateStatistics( master, slave );
+
+	ODEMX_TRACE << log( "coopt weight succeeded" )
+			.detail( "master", master->getLabel() )
+			.detail( "slave", slave->getLabel() )
+			.scope( typeid(WaitQ) );
+
+	// observer
+	ODEMX_OBS( WaitQObserver, CooptWeightSucceed( this, master, slave ) )
+
+	return slave;
+}
+
+base::Process* WaitQ::coopt( base::Selection sel )
+{
+	// WaitQ synchronization only implemented for processes
+	if( ! getCurrentSched() || getCurrentSched()->getSchedType() != base::Sched::PROCESS )
+	{
+		error << log( "WaitQ::coopt(): called by non-Process object" )
+				.scope( typeid(WaitQ) );
+		return 0;
+	}
+
+	// attempt blocking synchronization
+	return sync( true, sel );
+}
+
+base::Process* WaitQ::avail( base::Selection sel )
+{
+	// WaitQ synchronization only implemented for processes
+	if( ! getCurrentSched() || getCurrentSched()->getSchedType() != base::Sched::PROCESS )
+	{
+		error << log( "WaitQ::avail(): called by non-Process object" )
+				.scope( typeid(WaitQ) );
+
+		return 0;
+	}
+
+	// attempt non-blocking synchronization
+	return sync( false, sel );
+}
+
+base::Process* WaitQ::sync( bool wait, base::Selection sel )
+{
+	base::Process* master = getCurrentProcess();
+	base::Process* slave = getSlave( master, sel );
+
+	if( slave == 0 )
+	{
+		// trace
+		data::StringLiteral recordText;
+		if( wait )
+		{
+			if( sel ) recordText = "coopt select failed";
+			else recordText = "coopt failed";
+		}
+		else
+		{
+			if( sel ) recordText = "avail select failed";
+			else recordText = "avail failed";
+		}
+
+		ODEMX_TRACE << log( recordText )
+				.detail( "master", master->getLabel() )
+				.scope( typeid(WaitQ) );
+
+		// observer
+		if( wait ) // called from coopt()
+		{
+			if( sel == 0 )
+			{
+				ODEMX_OBS(WaitQObserver, CooptFail(this, master))
+			}
+			else
+			{
+				ODEMX_OBS(WaitQObserver, CooptSelFail(this, master))
+			}
+		}
+		else // called from avail()
+		{
+			if( sel == 0 )
+			{
+				ODEMX_OBS(WaitQObserver, AvailFail(this, master))
+			}
+			else
+			{
+				ODEMX_OBS(WaitQObserver, AvailSelFail(this, master))
+			}
+		}
+
+		if( wait ) // called from coopt()
+		{
+			// master is waiting for slave
+			masterQueue_.inSort( master );
+
+			do
+			{
+				master->sleep();
+
+				if( master->isInterrupted() )
+				{
+					masterQueue_.remove( master );
+					return 0;
+				}
+
+				slave = getSlave( master, sel );
+			}
+			while( slave == 0 );
+
+			// block released
+			masterQueue_.remove( master );
+		}
+		else // called from avail()
+		{
+			return 0;
+		}
+	}
+
+	// get slave
+	slaveQueue_.remove( slave );
+
+	// statistics
+	updateStatistics( master, slave );
+
+	// trace
+	data::StringLiteral recordText;
+	if( wait )
+	{
+		if( sel ) recordText = "coopt select succeeded";
+		else recordText = "coopt succeeded";
+	}
+	else
+	{
+		if( sel ) recordText = "avail select succeeded";
+		else recordText = "avail succeeded";
+	}
+
+	ODEMX_TRACE << log( recordText )
+			.detail( "master", master->getLabel() )
+			.detail( "slave", slave->getLabel() )
+			.scope( typeid(WaitQ) );
+
+	// observer
+	if( wait ) // called from coopt()
+	{
+		if( sel == 0 )
+		{
+			ODEMX_OBS(WaitQObserver, CooptSucceed(this, master, slave))
+		}
+		else
+		{
+			ODEMX_OBS(WaitQObserver, CooptSelSucceed(this, master, slave))
+		}
+	}
+	else // called from avail()
+	{
+		if( sel == 0 )
+		{
+			ODEMX_OBS(WaitQObserver, AvailSucceed(this, master, slave))
+		}
+		else
+		{
+			ODEMX_OBS(WaitQObserver, AvailSelSucceed(this, master, slave))
+		}
+	}
+
+	return slave;
+}
+
+base::Process* WaitQ::getSlave( base::Process* master, base::Selection sel )
+{
+	if( slaveQueue_.isEmpty() || ( master == 0 ) )
+	{
+		return 0;
+	}
+
+	if( sel == 0 )
+	{
+		return slaveQueue_.getTop();
+	}
+
+	base::ProcessList::const_iterator i;
+	base::ProcessList::const_iterator end = slaveQueue_.getList().end();
+
+	for( i = slaveQueue_.getList().begin(); i != end; ++i )
+	{
+		// check if current slave fits the selection
+		if( sel(master, *i) )
+		{
+			return *i;
+		}
+	}
+
+	return 0;
+}
+
+base::Process* WaitQ::getWeightedSlave( base::Process* master, base::Weight weightFct )
+{
+	// nothing to synchronize
+	if( slaveQueue_.isEmpty() || ( master == 0 ) )
+	{
+		return 0;
+	}
+
+	// no weight to evaluate, take first in queue
+	if( weightFct == 0 )
+	{
+		return slaveQueue_.getTop();
+	}
+
+	// evaluate master weight function
+	base::ProcessList::const_iterator i = slaveQueue_.getList().begin();
+	base::ProcessList::const_iterator end = slaveQueue_.getList().end();
+
+	// initialize max weighted slave variable
+	base::Process* maxWeightSlave = *i;
+	// get weight of first slave
+	double maxWeight = weightFct (master, maxWeightSlave);
+
+	// iterate over slave queue to get the maximum weighted slave
+	for( ++i; i != end; ++i )
+	{
+		// get the current slave's weight
+		double currentWeight = weightFct(master, *i);
+
+		// if current slave's weight is highest so far, remember it
+		if( currentWeight > maxWeight )
+		{
+			maxWeight = currentWeight;
+			maxWeightSlave = *i;
+		}
+	}
+
+	return maxWeightSlave;
+}
+
+const base::ProcessList& WaitQ::getWaitingSlaves() const
+{
+	return slaveQueue_.getList();
+}
+
+const base::ProcessList& WaitQ::getWaitingMasters() const
+{
+	return masterQueue_.getList();
+}
+
+void WaitQ::updateStatistics( base::Process* master, base::Process* slave)
+{
+	assert( master && slave );
+
+	// master and slave synchronized (served)
+	statistics << count( "synchronizations" ).scope( typeid(WaitQ) );
+
+	// calculate waiting times
+	base::SimTime masterWaitTime = master->getDequeueTime() - master->getEnqueueTime();
+	base::SimTime slaveWaitTime = slave->getDequeueTime() - slave->getEnqueueTime();
+
+	statistics << update( "master wait time", masterWaitTime ).scope( typeid(WaitQ) );
+	statistics << update( "slave wait time", slaveWaitTime ).scope( typeid(WaitQ) );
+}
+
+base::SimTime WaitQ::getTime() const
+{
+	return getSimulation().getTime();
+}
+
+base::Sched* WaitQ::getCurrentSched()
+{
+	return getSimulation().getCurrentSched();
+}
+
+base::Process* WaitQ::getCurrentProcess()
+{
+	return getSimulation().getCurrentProcess();
+}
+
+} } // namespace odemx::sync