commit 0c286af0558b77324cdcc3f771e0e564e4afd9e5
Author: Simon Schulz <sschulz@cit-ec.uni-bielefeld.de>
Date:   Tue Apr 14 16:09:29 2015 +0200

    init

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..59b9132
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,14 @@
+*~
+*.lock
+*.DS_Store
+*.swp
+*.out
+*.pyc
+.idea
+build
+qtcreator-build
+CMakeLists.txt.user*
+CMakeCache.txt
+CMakeFiles
+core
+.egg*
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/client/cpp/CMakeLists.txt b/client/cpp/CMakeLists.txt
new file mode 100644
index 0000000..3066895
--- /dev/null
+++ b/client/cpp/CMakeLists.txt
@@ -0,0 +1,160 @@
+SET( PROJECT_NAME hlrc_client_cpp )
+PROJECT( ${PROJECT_NAME} )
+
+#debug?
+set(CMAKE_BUILD_TYPE Debug)
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+INCLUDE(FindPkgConfig)
+
+SET(HLRC_CLIENT_LIBNAME "${PROJECT_NAME}")
+SET(HLRC_CLIENT_VERSION_MAJOR    "0")
+SET(HLRC_CLIENT_VERSION_MINOR    "1")
+SET(HLRC_CLIENT_VERSION_REVISION "0")
+SET(HLRC_CLIENT_VERSION   "${HLRC_CLIENT_VERSION_MAJOR}.${HLRC_CLIENT_VERSION_MINOR}.${HLRC_CLIENT_VERSION_REVISION}")
+SET(HLRC_CLIENT_SOVERSION "${HLRC_CLIENT_VERSION_MAJOR}.${HLRC_CLIENT_VERSION_MINOR}")
+SET(HLRC_CLIENT_PACKAGE   "${HLRC_CLIENT_LIBNAME}-${HLRC_CLIENT_VERSION_MAJOR}.${HLRC_CLIENT_VERSION_MINOR}")
+
+SET(PREFIX      ${CMAKE_INSTALL_PREFIX})
+SET(BINDIR     "${PREFIX}/bin")
+SET(INCLUDEDIR "${PREFIX}/include/hlrc_client")
+SET(MANDIR     "${PREFIX}/man")
+SET(LIBDIR     "${PREFIX}/lib")
+SET(PKGDIR     "${PREFIX}/lib/pkgconfig")
+SET(DATADIR    "${PREFIX}/share/hlrc_client")
+
+#######################################
+# check if we have RSB support:
+FIND_PACKAGE(RSB 0.11)
+IF (RSB_FOUND)
+    #RSB
+    SET(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib:\$ORIGIN/")
+    FIND_PACKAGE(RSC 0.11 REQUIRED)
+    FIND_PACKAGE(RSB 0.11 REQUIRED)
+    #RST
+    FIND_PACKAGE(RST REQUIRED COMPONENTS sandbox)
+    INCLUDE_DIRECTORIES(BEFORE SYSTEM ${RST_INCLUDE_DIRS})
+    ADD_DEFINITIONS(${RST_CFLAGS} ${RSTSANDBOX_CFLAGS})
+
+    INCLUDE_DIRECTORIES(BEFORE SYSTEM ${RSB_INCLUDE_DIRS})
+    LIST(INSERT CMAKE_MODULE_PATH 0 ${RSC_CMAKE_MODULE_PATH})
+    #RSB
+    SET(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib:\$ORIGIN/")
+    FIND_PACKAGE(RSC 0.11 REQUIRED)
+    FIND_PACKAGE(RSB 0.11 REQUIRED)
+    #RST
+    FIND_PACKAGE(RST REQUIRED COMPONENTS sandbox)
+    INCLUDE_DIRECTORIES(BEFORE SYSTEM ${RST_INCLUDE_DIRS})
+    ADD_DEFINITIONS(${RST_CFLAGS} ${RSTSANDBOX_CFLAGS})
+
+    INCLUDE_DIRECTORIES(BEFORE SYSTEM ${RSB_INCLUDE_DIRS})
+    LIST(INSERT CMAKE_MODULE_PATH 0 ${RSC_CMAKE_MODULE_PATH})
+
+    message(STATUS "RSB Support is ON")
+    add_definitions(-DRSB_SUPPORT=1)
+ENDIF (RSB_FOUND)
+
+################################################################
+# check for ROS support:
+find_package(catkin)
+IF (catkin_FOUND)
+    SET(ROS_FOUND 1)
+    find_package(catkin REQUIRED COMPONENTS roscpp std_msgs sensor_msgs message_generation genmsg actionlib)
+
+    catkin_package(
+        INCLUDE_DIRS include
+    )
+    
+    message(STATUS "ROS Support is ON")
+    add_definitions(-DROS_SUPPORT=1)
+ENDIF (catkin_FOUND)
+
+add_definitions ("-Wall")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -fstack-protector-all ")
+set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${CMAKE_INSTALL_PREFIX}/lib/pkgconfig" )
+
+#search for Boost 
+find_package( Boost 1.46 REQUIRED COMPONENTS thread program_options system filesystem regex)
+LINK_DIRECTORIES( ${Boost_LIBRARY_DIRS}  )
+include_directories(${Boost_INCLUDE_DIRS} )
+message("-- using ${Boost_LIBRARIES}")
+
+
+# SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+# SET(BINDIR "${PREFIX}/bin")
+# SET(INCLUDEDIR "${PREFIX}/include")
+# SET(MANDIR "${PREFIX}/man")
+# SET(LIBDIR "${PREFIX}/lib")
+# SET(DATADIR "${PREFIX}/share/${NAME}")
+
+#this dummy list will make all header files appear if you use qtcreator to open the cmake project
+file(GLOB HEADER_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} include/*.h  )
+
+SET(LIB_CLASSES
+    src/RobotController.cpp
+    src/Middleware.cpp
+    src/MiddlewareROS.cpp
+    src/MiddlewareRSB.cpp
+)
+
+add_library(${HLRC_CLIENT_LIBNAME} SHARED
+    ${LIB_CLASSES}
+    ${HEADER_LIST}
+)
+
+SET(INSTALL_HEADER_LIST
+    include/RobotController.h
+    include/RobotGaze.h
+    include/RobotMouth.h
+    include/RobotEmotion.h
+    include/RobotHeadAnimation.h
+)
+
+SET_TARGET_PROPERTIES(${HLRC_CLIENT_LIBNAME} PROPERTIES VERSION ${HLRC_CLIENT_VERSION} SOVERSION ${HLRC_CLIENT_SOVERSION})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
+LINK_DIRECTORIES(${LIBDIR})
+IF (ROS_FOUND)
+add_dependencies(${HLRC_CLIENT_LIBNAME} ${catkin_EXPORTED_TARGETS} hlc_server_gencpp)
+ENDIF (ROS_FOUND)
+
+target_link_libraries(${HLRC_CLIENT_LIBNAME} ${RSB_LIBRARIES} ${RST_LIBRARIES} ${catkin_LIBRARIES})
+
+#build & install demo
+#ADD_EXECUTABLE(testMarkerTracker example/testMarkerTracker.cc)
+#TARGET_LINK_LIBRARIES(testMarkerTracker ${OpenCV_LIBS} ${Boost_LIBRARIES} ${Boost_LIBS} bart)
+#install(TARGETS testMarkerTracker DESTINATION bin)
+#build test
+#ADD_EXECUTABLE(testKalmanMarker src/KalmanMarker.cc)
+#TARGET_LINK_LIBRARIES(testKalmanMarker ${OpenCV_LIBS} ${Boost_LIBRARIES} ${Boost_LIBS} bart)
+
+install (TARGETS ${HLRC_CLIENT_LIBNAME} DESTINATION lib )
+INSTALL(FILES ${INSTALL_HEADER_LIST} DESTINATION ${INCLUDEDIR})
+
+set_target_properties(${HLRC_CLIENT_LIBNAME} PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
+set_target_properties(${HLRC_CLIENT_LIBNAME} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
+
+#create package config file
+SET(PKGCONFIG_FILENAME "hlrc_client.pc")
+configure_file("${PKGCONFIG_FILENAME}.in" "${PKGCONFIG_FILENAME}" @ONLY)
+INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILENAME}" DESTINATION "${PKGDIR}")
+
+#create cmake config files
+SET(CMAKECONFIG_FILENAME "hlrc_clientConfig.cmake")
+configure_file("${CMAKECONFIG_FILENAME}.in" "${CMAKECONFIG_FILENAME}" @ONLY)
+INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/${CMAKECONFIG_FILENAME}" DESTINATION "${DATADIR}")
+
+SET(CMAKECONFIGVERSION_FILENAME "hlrc_clientConfigVersion.cmake")
+configure_file("${CMAKECONFIGVERSION_FILENAME}.in" "${CMAKECONFIGVERSION_FILENAME}" @ONLY)
+INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/${CMAKECONFIGVERSION_FILENAME}" DESTINATION "${DATADIR}")
+
+#ADD_EXECUTABLE(${PROJECT_NAME} main.cpp ${SRC_FILES})
+#TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${RSB_LIBRARIES} ${RST_LIBRARIES} ${OpenCV_LIBS} ${Boost_LIBRARIES} ${Boost_LIBS} ${BART_LIBRARIES} ) 
+
+#build & install examples
+ADD_EXECUTABLE(${PROJECT_NAME}_example_random_gaze examples/random_gaze/main.cpp)
+TARGET_LINK_LIBRARIES(${PROJECT_NAME}_example_random_gaze ${HLRC_CLIENT_LIBNAME})
+#install(TARGETS ${PROJECT_NAME}_calibrate_camera DESTINATION bin)
+ADD_EXECUTABLE(${PROJECT_NAME}_example_speech_test examples/speech_test/main.cpp)
+TARGET_LINK_LIBRARIES(${PROJECT_NAME}_example_speech_test ${HLRC_CLIENT_LIBNAME})
+
+
diff --git a/client/cpp/examples/random_gaze/main.cpp b/client/cpp/examples/random_gaze/main.cpp
new file mode 100644
index 0000000..0e9289f
--- /dev/null
+++ b/client/cpp/examples/random_gaze/main.cpp
@@ -0,0 +1,70 @@
+/*
+* This file is part of hlrc_client
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "RobotController.h"
+#include "RobotGaze.h"
+#include <unistd.h>
+
+float rand_float(float min, float max){
+    float f = (float)rand() / RAND_MAX;
+    return min + f * (max - min);
+}
+
+int main (int argc, char **argv){
+    if (argc != 3){
+        printf("usage: %s <middleware> <robot scope>\n", argv[0]);
+        printf("       <middleware> is either ROS or RSB\n");
+	printf("       <robot scope> e.g. /flobi or /icub\n\n");
+        exit(EXIT_FAILURE);
+    }
+
+    RobotController *robot_controller = new RobotController(argv[1], argv[2]); //"/flobi");
+    //robot_controller->set_current_emotion(RobotEmotion(RobotEmotion::NEUTRAL));
+    RobotGaze gaze;
+
+    int count=0;
+
+    while(1){
+        if (count++ >= 50){
+			//a new target every second:
+			gaze.pan  = rand_float(-20.0, 20.0);
+			gaze.tilt = rand_float(-20.0, 20.0);
+			gaze.roll = 0.0;
+			gaze.vergence = 0.0;
+
+            //robot_controller->set_current_emotion(RobotEmotion(RobotEmotion::ANGRY));
+
+			//reset counter
+			count = 0;
+		}
+
+        robot_controller->set_gaze_target(gaze);
+		usleep(1000/50 * 1000 );
+    }	
+
+}
diff --git a/client/cpp/examples/speech_test/main.cpp b/client/cpp/examples/speech_test/main.cpp
new file mode 100644
index 0000000..1631013
--- /dev/null
+++ b/client/cpp/examples/speech_test/main.cpp
@@ -0,0 +1,49 @@
+/*
+* This file is part of hlrc_client
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "RobotController.h"
+#include <unistd.h>
+
+#define BLOCKING true
+
+int main (int argc, char **argv){
+    RobotController *robot_controller = new RobotController("RSB", "/flobi");
+
+    int count=0;
+
+    printf("> speech test starting.\n");
+
+    robot_controller->set_speak("i will start counting now.\n", BLOCKING);
+    while(1){
+        std::string text = std::to_string(count++);
+        printf("> saying '%s'\n",text.c_str());
+        robot_controller->set_speak(text, BLOCKING);
+        sleep(1);
+    }
+
+}
diff --git a/client/cpp/hlrc_client.pc.in b/client/cpp/hlrc_client.pc.in
new file mode 100644
index 0000000..062a802
--- /dev/null
+++ b/client/cpp/hlrc_client.pc.in
@@ -0,0 +1,14 @@
+#pkg config file for @PROJECT_NAME@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: @PROJECT_NAME@
+Description: hlrc client cpp
+Version: 0.1
+Requires: 
+Libs: -L${libdir} -l@PROJECT_NAME@
+Cflags: -I${includedir}
+
+
diff --git a/client/cpp/hlrc_clientConfig.cmake.in b/client/cpp/hlrc_clientConfig.cmake.in
new file mode 100644
index 0000000..41e5270
--- /dev/null
+++ b/client/cpp/hlrc_clientConfig.cmake.in
@@ -0,0 +1,27 @@
+# ### HLRC CLIENT cpp ###
+# ===============================
+# 
+# Sets required variables for finding the hlrc client library:
+#
+# HLRC_CLIENT_FOUND
+# HLRC_CLIENT_INCLUDE_DIRS
+# HLRC_CLIENT_LIBRARY_DIRS
+# HLRC_CLIENT_LIBRARIES
+# HLRC_CLIENT_VERSION
+# 
+# Example:
+# find_package(hlrc_client 0.1)
+#
+# ###############################################################################
+
+INCLUDE(FindPkgConfig)
+
+GET_FILENAME_COMPONENT(CONFIG_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+SET(HLRC_CLIENT_FOUND TRUE)
+SET(HLRC_CLIENT_INCLUDE_DIRS "${CONFIG_DIR}/../../include")
+SET(HLRC_CLIENT_LIBRARY_DIRS "${CONFIG_DIR}/../../lib")
+SET(HLRC_CLIENT_VERSION "@HLRC_CLIENT_VERSION@")
+SET(HLRC_CLIENT_LIBRARIES "${CONFIG_DIR}/../../lib/@CMAKE_SHARED_LIBRARY_PREFIX@@HLRC_CLIENT_LIBNAME@@CMAKE_SHARED_LIBRARY_SUFFIX@")
+
+# TODO: find dependencies here and append their include dirs to HLRC_CLIENT_INCLUDE_DIRS
diff --git a/client/cpp/hlrc_clientConfigVersion.cmake.in b/client/cpp/hlrc_clientConfigVersion.cmake.in
new file mode 100644
index 0000000..0ec5ec2
--- /dev/null
+++ b/client/cpp/hlrc_clientConfigVersion.cmake.in
@@ -0,0 +1,11 @@
+set(PACKAGE_VERSION "@HLRC_CLIENT_VERSION@")
+ 
+# Check whether the requested PACKAGE_FIND_VERSION is compatible
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
+  set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+  set(PACKAGE_VERSION_COMPATIBLE TRUE)
+  if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
+    set(PACKAGE_VERSION_EXACT TRUE)
+  endif()
+endif()
diff --git a/client/cpp/include/Middleware.h b/client/cpp/include/Middleware.h
new file mode 100644
index 0000000..db7d119
--- /dev/null
+++ b/client/cpp/include/Middleware.h
@@ -0,0 +1,78 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+#pragma once
+
+//*********************************************************************************
+//allow direct synthesis using inprotk calls. by default this is disabled
+//until inprotk gets to an usable state (e.g. the completion flag has to work)
+#define USE_INPROTK_SYNTHESIS 0
+//*********************************************************************************
+
+#include <string>
+#include "RobotHeadAnimation.h"
+#include "RobotEmotion.h"
+#include "RobotGaze.h"
+#include "RobotMouth.h"
+
+class Middleware{
+public:
+    Middleware(std::string scope);
+
+    void set_default_emotion(RobotEmotion e, bool blocking);
+    void set_current_emotion(RobotEmotion e, bool blocking);
+    void set_gaze_target(RobotGaze target, bool blocking);
+    void set_mouth_target(RobotMouth target, bool blocking);
+    void set_head_animation(RobotHeadAnimation a, bool blocking);
+    void set_speak(std::string text, bool blocking);
+
+    RobotEmotion get_current_emotion();
+    RobotEmotion get_default_emotion();
+    RobotGaze get_gaze_target();
+
+protected:
+    virtual void init() = 0;
+    virtual void publish_default_emotion(RobotEmotion e, bool blocking) = 0;
+    virtual void publish_current_emotion(RobotEmotion e, bool blocking) = 0;
+    virtual void publish_gaze_target(RobotGaze g, bool blocking) = 0;
+    virtual void publish_mouth_target(RobotMouth m, bool blocking) = 0;
+    virtual void publish_head_animation(RobotHeadAnimation a, bool blocking) = 0;
+    virtual void publish_speech(std::string text, bool blocking) = 0;
+
+    std::string base_scope;
+
+private:
+    RobotEmotion defaultEmotion;
+    RobotEmotion currentEmotion;
+
+    RobotGaze gazeTarget;
+    RobotMouth mouthTarget;
+
+    RobotHeadAnimation headAnimation;
+};
+
+
diff --git a/client/cpp/include/MiddlewareROS.h b/client/cpp/include/MiddlewareROS.h
new file mode 100644
index 0000000..70a09d7
--- /dev/null
+++ b/client/cpp/include/MiddlewareROS.h
@@ -0,0 +1,83 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+
+#include "Middleware.h"
+#if ROS_SUPPORT
+    #include "ros/ros.h"
+    //ros messages
+    #include <hlrc_server/phoneme.h>
+    #include <hlrc_server/soundchunk.h>
+    #include <hlrc_server/gazetargetAction.h>
+    #include <hlrc_server/animationAction.h>
+    #include <hlrc_server/mouthtargetAction.h>
+    #include <hlrc_server/utteranceAction.h>
+    #include <hlrc_server/emotionstateAction.h>
+    #include <hlrc_server/speechAction.h>
+    #include <actionlib/client/simple_action_client.h>
+    #include <actionlib/client/terminal_state.h>
+    #include <boost/shared_ptr.hpp>
+#endif
+
+#define ROS_ACTION_CALL_TIMEOUT 30.0
+
+class MiddlewareROS : public Middleware{
+#ifndef ROS_SUPPORT
+public:
+    MiddlewareRSB(std::string scope){
+        printf("> ERROR: hlrc was compiled without ROS middleware support. Please use MiddlewareRSB() instead!\n\n");
+        exit(EXIT_FAILURE);
+    }
+
+#else
+public:
+    MiddlewareROS(std::string scope);
+
+protected:
+    void init();
+    void publish_current_emotion(RobotEmotion e, bool blocking);
+    void publish_default_emotion(RobotEmotion e, bool blocking);
+    void publish_gaze_target(RobotGaze target, bool blocking);
+    void publish_mouth_target(RobotMouth target, bool blocking);
+    void publish_head_animation(RobotHeadAnimation a, bool blocking);
+    void publish_speech(std::string text, bool blocking);
+
+private:
+    void publish_emotion(std::string scope_target, RobotEmotion e, bool blocking);
+    void check_service(ros::ServiceClient *service);
+
+    actionlib::SimpleActionClient<hlrc_server::animationAction>     *animation_ac;
+    actionlib::SimpleActionClient<hlrc_server::utteranceAction>     *utterance_ac;
+    actionlib::SimpleActionClient<hlrc_server::emotionstateAction>  *default_emotionstate_ac;
+    actionlib::SimpleActionClient<hlrc_server::emotionstateAction>  *current_emotionstate_ac;
+    actionlib::SimpleActionClient<hlrc_server::gazetargetAction>    *gazetarget_ac;
+    actionlib::SimpleActionClient<hlrc_server::mouthtargetAction>    *mouthtarget_ac;
+    actionlib::SimpleActionClient<hlrc_server::speechAction>     *speech_ac;
+#endif
+};
diff --git a/client/cpp/include/MiddlewareRSB.h b/client/cpp/include/MiddlewareRSB.h
new file mode 100644
index 0000000..19613c8
--- /dev/null
+++ b/client/cpp/include/MiddlewareRSB.h
@@ -0,0 +1,90 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "Middleware.h"
+#ifdef RSB_SUPPORT
+    #define BOOST_SIGNALS_NO_DEPRECATION_WARNING //mute warnings from RSB
+    #include <rsb/Factory.h>
+    #include <rsb/Informer.h>
+    #include <rsb/Listener.h>
+
+    #if USE_INPROTK_SYNTHESIS
+    #include <rst/communicationpatterns/TaskState.pb.h>
+    #endif
+#endif
+
+class MiddlewareRSB : public Middleware{
+#ifndef RSB_SUPPORT
+public:
+    MiddlewareRSB(std::string scope){
+        printf("> ERROR: hlrc was compiled without RSB middleware support. Please use MiddlewareROS() instead!\n\n");
+        exit(EXIT_FAILURE);
+    }
+
+#else
+public:
+    MiddlewareRSB(std::string scope);
+
+
+protected:
+    void init();
+    void publish_current_emotion(RobotEmotion e, bool blocking);
+    void publish_default_emotion(RobotEmotion e, bool blocking);
+    void publish_gaze_target(RobotGaze target, bool blocking);
+    void publish_mouth_target(RobotMouth target, bool blocking);
+    void publish_head_animation(RobotHeadAnimation a, bool blocking);
+    void publish_speech(std::string text, bool blocking);
+
+private:
+    void publish_emotion(std::string scope_target, RobotEmotion e, bool blocking);
+
+    //rsb::patterns::RemoteServerPtr inprotk_server;
+    rsb::patterns::RemoteServerPtr hlrc_server;
+    //rsb::patterns::LocalServerPtr inprotk_server;
+#if USE_INPROTK_SYNTHESIS
+    rsb::Informer<rst::communicationpatterns::TaskState>::Ptr inprotk_informer;
+    rsb::ListenerPtr inprotk_listener;
+    rsb::ListenerPtr hack_listener;
+
+    boost::mutex pending_tasks_mutex;
+    std::vector<boost::shared_ptr<rst::communicationpatterns::TaskState>> pending_tasks;
+    unsigned int say_task_active;
+    unsigned int say_task_done;
+
+    boost::mutex current_saytask_mutex;
+    std::string current_saytask;
+    std::string get_current_saytask();
+    void set_current_saytask(std::string text);
+
+    void check_for_inprotk();
+    void incoming_hack(boost::shared_ptr<std::string> finished_task);
+#endif
+#endif
+};
+
diff --git a/client/cpp/include/RobotController.h b/client/cpp/include/RobotController.h
new file mode 100644
index 0000000..43c0af2
--- /dev/null
+++ b/client/cpp/include/RobotController.h
@@ -0,0 +1,58 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include <string>
+#include "RobotEmotion.h"
+#include "RobotGaze.h"
+#include "RobotMouth.h"
+#include "RobotHeadAnimation.h"
+
+class Middleware;
+
+class RobotController{
+public:
+    RobotController(std::string middleware, std::string scope);
+
+    void set_default_emotion(RobotEmotion e, bool blocking=false);
+    void set_current_emotion(RobotEmotion e, bool blocking=false);
+
+    void set_gaze_target(RobotGaze target, bool blocking=false);
+    RobotGaze get_gaze_target();
+
+    void set_mouth_target(RobotMouth target, bool blocking=false);
+
+    void set_head_animation(RobotHeadAnimation a, bool blocking=false);
+    void set_speak(std::string text, bool blocking=false);
+
+private:
+    Middleware *middleware;
+
+};
+
+
diff --git a/client/cpp/include/RobotEmotion.h b/client/cpp/include/RobotEmotion.h
new file mode 100644
index 0000000..b797905
--- /dev/null
+++ b/client/cpp/include/RobotEmotion.h
@@ -0,0 +1,47 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+
+class RobotEmotion{
+public:
+    RobotEmotion(int v=NEUTRAL){
+        value = v;
+        time_ms = 1000;
+    }
+
+    int value;
+    static const int NEUTRAL   = 0;
+    static const int HAPPY     = 1;
+    static const int SAD       = 2;
+    static const int ANGRY     = 3;
+    static const int SURPRISED = 4;
+    static const int FEAR      = 5;
+    int time_ms;
+};
+
diff --git a/client/cpp/include/RobotGaze.h b/client/cpp/include/RobotGaze.h
new file mode 100644
index 0000000..e6f5b37
--- /dev/null
+++ b/client/cpp/include/RobotGaze.h
@@ -0,0 +1,44 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+class RobotGaze{
+public:
+    RobotGaze(){
+        pan = 0.0;
+        tilt = 0.0;
+        roll = 0.0;
+        vergence = 0.0;
+        pan_offset = 0.0;
+        tilt_offset = 0.0;
+    }
+
+    float pan, tilt, roll, vergence;
+    float pan_offset, tilt_offset;
+};
+
diff --git a/client/cpp/include/RobotHeadAnimation.h b/client/cpp/include/RobotHeadAnimation.h
new file mode 100644
index 0000000..b2a333b
--- /dev/null
+++ b/client/cpp/include/RobotHeadAnimation.h
@@ -0,0 +1,54 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+class RobotHeadAnimation{
+public:
+    RobotHeadAnimation(int v=IDLE){
+        value = v;
+        time_ms = 1000;
+        repetitions = 1;
+        scale = 1.0;
+    }
+
+    int value;
+    static const int IDLE            = 0;
+    static const int HEAD_NOD        = 1;
+    static const int HEAD_SHAKE      = 2;
+    static const int EYEBLINK_L      = 3;
+    static const int EYEBLINK_R      = 4;
+    static const int EYEBLINK_BOTH   = 5;
+    static const int EYEBROWS_RAISE  = 6;
+    static const int EYEBROWS_LOWER  = 7;
+
+    int time_ms;
+    int repetitions;
+    float scale;
+
+};
+
diff --git a/client/cpp/include/RobotMouth.h b/client/cpp/include/RobotMouth.h
new file mode 100644
index 0000000..9cb4933
--- /dev/null
+++ b/client/cpp/include/RobotMouth.h
@@ -0,0 +1,44 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+class RobotMouth{
+public:
+    RobotMouth(){
+        opening_left   = 0.0;
+        opening_center = 0.0;
+        opening_right  = 0.0;
+        position_left  = 0.0;
+        position_center = 0.0;
+        position_right = 0.0;
+    }
+
+    float opening_left, opening_right, opening_center;
+    float position_left, position_right, position_center;
+};
+
diff --git a/client/cpp/package.xml b/client/cpp/package.xml
new file mode 100644
index 0000000..9f139b9
--- /dev/null
+++ b/client/cpp/package.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<package>
+  <name>hlrc_client_cpp</name>
+  <version>0.0.1</version>
+  <description>the high level robot control client</description>
+
+  <!-- One maintainer tag required, multiple allowed, one person per tag --> 
+  <maintainer email="sschulz@techfak.uni-bielefeld.de">Simon Schulz</maintainer>
+
+
+  <!-- One license tag required, multiple allowed, one license per tag -->
+  <!-- Commonly used license strings: -->
+  <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
+  <license>GPLv3</license>
+
+
+  <!-- Url tags are optional, but mutiple are allowed, one per tag -->
+  <!-- Optional attribute type can be: website, bugtracker, or repository -->
+  <!-- Example: -->
+  <url type="website">https://opensource.cit-ec.uni-bielefeld.de/hlrc</url> -->
+  <url type="repository">https://opensource.cit-ec.uni-bielefeld.de/git/hlrc.git</url> -->
+
+
+  <!-- Author tags are optional, mutiple are allowed, one per tag -->
+  <!-- Authors do not have to be maintianers, but could be -->
+  <!-- Example: -->
+  <!-- <author email="jane.doe@example.com">Jane Doe</author> -->
+
+
+  <!-- The *_depend tags are used to specify dependencies -->
+  <!-- Dependencies can be catkin packages or system dependencies -->
+  <!-- Examples: -->
+  <!-- Use build_depend for packages you need at compile time: -->
+  <!-- <build_depend>message_generation</build_depend> -->
+  <build_depend></build_depend>
+  <run_depend></run_depend>
+  <!-- Use buildtool_depend for build tool packages: -->
+  <!--   <buildtool_depend>catkin</buildtool_depend> -->
+  <!-- Use run_depend for packages you need at runtime: -->
+  <!-- <run_depend>message_runtime</run_depend> -->
+  <!-- Use test_depend for packages you need only for testing: -->
+  <!--   <test_depend>gtest</test_depend> -->
+  <buildtool_depend>catkin</buildtool_depend>
+  <build_depend>roscpp</build_depend>
+  <build_depend>std_msgs</build_depend>
+  <!-- <run_depend>roscpp</run_depend> -->
+  <!-- <run_depend>std_msgs</run_depend> -->
+
+  <!--<build_depend>actionlib</build_depend>
+  <build_depend>actionlib_msgs</build_depend>
+  <run_depend>actionlib</run_depend> -->
+  <!-- <run_depend>actionlib_msgs</run_depend> -->
+
+  <!-- The export tag contains other, unspecified, tags -->
+  <export>
+    <!-- You can specify that this package is a metapackage here: -->
+    <!-- <metapackage/> -->
+
+    <!-- Other tools can request additional information be placed here -->
+
+  </export>
+</package>
+
diff --git a/client/cpp/src/Middleware.cpp b/client/cpp/src/Middleware.cpp
new file mode 100644
index 0000000..ccbb7f9
--- /dev/null
+++ b/client/cpp/src/Middleware.cpp
@@ -0,0 +1,78 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "Middleware.h"
+
+using namespace std;
+
+Middleware::Middleware(string scope){
+    base_scope = scope;
+}
+
+void Middleware::set_default_emotion(RobotEmotion e, bool blocking){
+    defaultEmotion = e;
+    publish_default_emotion(defaultEmotion, blocking);
+}
+
+void Middleware::set_current_emotion(RobotEmotion e, bool blocking){
+    currentEmotion = e;
+    publish_current_emotion(currentEmotion, blocking);
+}
+
+RobotEmotion Middleware::get_current_emotion(){
+    return currentEmotion;
+}
+
+RobotEmotion Middleware::get_default_emotion(){
+    return defaultEmotion;
+}
+
+void Middleware::set_gaze_target(RobotGaze target, bool blocking){
+    //printf("> Middleware::set_gaze_target({%4.1f %4.1f %4.1f %4.1f}, %s)\n",target.pan,target.roll,target.tilt,target.vergence,blocking?"BLOCKING":"NONBLOCKING");
+    gazeTarget = target;
+    publish_gaze_target(gazeTarget, blocking);
+}
+
+void Middleware::set_mouth_target(RobotMouth target, bool blocking){
+    mouthTarget = target;
+    publish_mouth_target(mouthTarget, blocking);
+}
+
+
+RobotGaze Middleware::get_gaze_target(){
+    return gazeTarget;
+}
+
+void Middleware::set_head_animation(RobotHeadAnimation a, bool blocking){
+    headAnimation = a;
+    publish_head_animation(headAnimation, blocking);
+}
+
+void Middleware::set_speak(string text, bool blocking){
+    publish_speech(text, blocking);
+}
diff --git a/client/cpp/src/MiddlewareROS.cpp b/client/cpp/src/MiddlewareROS.cpp
new file mode 100644
index 0000000..ea22139
--- /dev/null
+++ b/client/cpp/src/MiddlewareROS.cpp
@@ -0,0 +1,255 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#ifdef ROS_SUPPORT
+
+#include "MiddlewareROS.h"
+#include <stdio.h>
+#include <boost/algorithm/string.hpp>
+#include <boost/range/algorithm_ext/erase.hpp>
+#include <boost/range/algorithm/remove_if.hpp>
+
+using namespace std;
+
+MiddlewareROS::MiddlewareROS(string scope) : Middleware(scope) {
+    printf("> new MiddlewareROS() on base scope '%s'\n",base_scope.c_str());
+    init();
+}
+
+template <typename actionspec>
+actionlib::SimpleActionClient<actionspec> * create_action_client(string scope){
+    printf("> starting SimpleActionClient on %s\n",scope.c_str());
+
+    actionlib::SimpleActionClient<actionspec> *ac = new actionlib::SimpleActionClient<actionspec>(scope, true);
+
+    if (!ac->waitForServer(ros::Duration(1))){
+        char buf[256];
+        snprintf(buf, 256, "ERROR: action service %s not ready", scope.c_str());
+        throw runtime_error(buf);
+    }
+    return ac;
+}
+
+void MiddlewareROS::init(void){
+    printf("> MiddlewareROS::init()\n");
+
+    string scope = base_scope + "/set";
+
+    string node_name = "hlrc_client__"+ base_scope;
+    node_name.erase(boost::remove_if(node_name, boost::is_any_of("/")), node_name.end());
+
+    printf("> registering on ROS as node %s, scope = %s\n",node_name.c_str(), scope.c_str());
+    if (!ros::isInitialized()){
+        ros::M_string no_remapping;
+        ros::init(no_remapping, node_name);
+    }
+
+    //create node handle
+    //ros_node_handle = new ros::NodeHandle();
+    //node_handle = boost::shared_ptr<ros::NodeHandle>(new ros::NodeHandle());
+
+    printf("> setting up ROS action clients...\n");
+    animation_ac = create_action_client<hlrc_server::animationAction>(scope + "/animation");
+    utterance_ac = create_action_client<hlrc_server::utteranceAction>(scope + "/utterance");
+    current_emotionstate_ac = create_action_client<hlrc_server::emotionstateAction>(scope + "/currentEmotion");
+    default_emotionstate_ac = create_action_client<hlrc_server::emotionstateAction>(scope + "/defaultEmotion");
+    gazetarget_ac = create_action_client<hlrc_server::gazetargetAction>(scope + "/gaze");
+    mouthtarget_ac = create_action_client<hlrc_server::mouthtargetAction>(scope + "/mouth");
+    speech_ac = create_action_client<hlrc_server::speechAction>(scope + "/speech");
+
+    printf("> init done.\n");
+}
+
+
+void MiddlewareROS::publish_emotion(string scope_target, RobotEmotion e, bool blocking){
+    hlrc_server::emotionstateGoal goal;
+
+    switch(e.value){
+        default:
+            printf("> WANRING: invalid emotion id %d. defaulting to NEUTRAL\n",e.value);
+            //fall through:
+        case(RobotEmotion::NEUTRAL):
+            goal.value = hlrc_server::emotionstateGoal::NEUTRAL;
+            break;
+        case(RobotEmotion::HAPPY):
+            goal.value = hlrc_server::emotionstateGoal::HAPPY;
+            break;
+        case(RobotEmotion::SAD):
+            goal.value = hlrc_server::emotionstateGoal::SAD;
+            break;
+        case(RobotEmotion::ANGRY):
+            goal.value = hlrc_server::emotionstateGoal::ANGRY;
+            break;
+        case(RobotEmotion::SURPRISED):
+            goal.value = hlrc_server::emotionstateGoal::SURPRISED;
+            break;
+        case(RobotEmotion::FEAR):
+            goal.value = hlrc_server::emotionstateGoal::FEAR;
+            break;
+    }
+
+    goal.duration = e.time_ms;
+
+    actionlib::SimpleActionClient<hlrc_server::emotionstateAction>  *ac;
+    if (scope_target == "defaultEmotion"){
+        ac = default_emotionstate_ac;
+    }else{
+        ac = current_emotionstate_ac;
+    }
+
+    //send
+    ac->sendGoal(goal);
+
+    if (blocking){
+        bool finished_before_timeout = ac->waitForResult(ros::Duration(ROS_ACTION_CALL_TIMEOUT));
+        if (!finished_before_timeout){
+            printf("> ERROR: blocking call timed out!\n");
+        }
+    }
+}
+
+
+void MiddlewareROS::publish_current_emotion(RobotEmotion e, bool blocking){
+    publish_emotion("currentEmotion", e, blocking);
+}
+
+void MiddlewareROS::publish_default_emotion(RobotEmotion e, bool blocking){
+    publish_emotion("defaultEmotion", e, blocking);
+}
+
+void MiddlewareROS::publish_gaze_target(RobotGaze target, bool blocking){
+    hlrc_server::gazetargetGoal goal;
+
+    goal.pan = target.pan;
+    goal.tilt = target.tilt;
+    goal.roll = target.roll;
+    goal.vergence = target.vergence;
+
+    goal.tilt_offset = target.tilt_offset;
+    goal.pan_offset = target.pan_offset;
+
+    //send
+    gazetarget_ac->sendGoal(goal);
+
+    if (blocking){
+        bool finished_before_timeout = gazetarget_ac->waitForResult(ros::Duration(ROS_ACTION_CALL_TIMEOUT));
+        if (!finished_before_timeout){
+            printf("> ERROR: blocking call timed out!\n");
+        }
+    }
+}
+
+
+void MiddlewareROS::publish_mouth_target(RobotMouth target, bool blocking){
+    hlrc_server::mouthtargetGoal goal;
+
+    goal.position_left   = target.position_left;
+    goal.position_center = target.position_center;
+    goal.position_right  = target.position_right;
+
+    goal.opening_left   = target.opening_left;
+    goal.opening_center = target.opening_center;
+    goal.opening_right  = target.opening_right;
+
+
+    //send
+    mouthtarget_ac->sendGoal(goal);
+
+    if (blocking){
+        bool finished_before_timeout = mouthtarget_ac->waitForResult(ros::Duration(ROS_ACTION_CALL_TIMEOUT));
+        if (!finished_before_timeout){
+            printf("> ERROR: blocking call timed out!\n");
+        }
+    }
+}
+
+void MiddlewareROS::publish_head_animation(RobotHeadAnimation a, bool blocking){
+    hlrc_server::animationGoal goal;
+
+    switch(a.value){
+        default:
+            printf("> WANRING: invalid animation id %d. defaulting to IDLE",a.value);
+            //fall through:
+        case(RobotHeadAnimation::IDLE):
+            goal.target = hlrc_server::animationGoal::IDLE;
+            break;
+        case(RobotHeadAnimation::HEAD_NOD):
+            goal.target = hlrc_server::animationGoal::HEAD_NOD;
+            break;
+        case(RobotHeadAnimation::HEAD_SHAKE):
+            goal.target = hlrc_server::animationGoal::HEAD_SHAKE;
+            break;
+        case(RobotHeadAnimation::EYEBLINK_L):
+            goal.target = hlrc_server::animationGoal::EYEBLINK_L;
+            break;
+        case(RobotHeadAnimation::EYEBLINK_R):
+            goal.target = hlrc_server::animationGoal::EYEBLINK_R;
+            break;
+        case(RobotHeadAnimation::EYEBLINK_BOTH):
+            goal.target = hlrc_server::animationGoal::EYEBLINK_BOTH;
+            break;
+        case(RobotHeadAnimation::EYEBROWS_RAISE):
+            goal.target = hlrc_server::animationGoal::EYEBROWS_RAISE;
+            break;
+        case(RobotHeadAnimation::EYEBROWS_LOWER):
+            goal.target = hlrc_server::animationGoal::EYEBROWS_LOWER;
+            break;
+    }
+
+    goal.repetitions = a.repetitions;
+    goal.scale       = a.scale;
+    goal.duration_each = a.time_ms;
+
+    //send
+    animation_ac->sendGoal(goal);
+
+    if (blocking){
+        bool finished_before_timeout = animation_ac->waitForResult(ros::Duration(ROS_ACTION_CALL_TIMEOUT));
+        if (!finished_before_timeout){
+            printf("> ERROR: blocking call timed out!\n");
+        }
+    }
+}
+
+void MiddlewareROS::publish_speech(string text, bool blocking){
+    hlrc_server::speechGoal goal;
+
+    goal.text = text;
+
+    //send
+    speech_ac->sendGoal(goal);
+
+    if (blocking){
+        bool finished_before_timeout = speech_ac->waitForResult(ros::Duration(ROS_ACTION_CALL_TIMEOUT));
+        if (!finished_before_timeout){
+            printf("> ERROR: blocking call timed out!\n");
+        }
+    }
+}
+
+#endif
diff --git a/client/cpp/src/MiddlewareRSB.cpp b/client/cpp/src/MiddlewareRSB.cpp
new file mode 100644
index 0000000..21ee922
--- /dev/null
+++ b/client/cpp/src/MiddlewareRSB.cpp
@@ -0,0 +1,227 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#ifdef RSB_SUPPORT
+
+#include "MiddlewareRSB.h"
+#include <rsb/converter/Repository.h>
+#include <rsb/converter/ProtocolBufferConverter.h>
+
+#include <rst/robot/EmotionState.pb.h>
+#include <rst/robot/Animation.pb.h>
+#include <rst/robot/GazeTarget.pb.h>
+#include <rst/robot/MouthTarget.pb.h>
+#include <rst/audition/Utterance.pb.h>
+#include <boost/algorithm/string.hpp>
+#include <boost/range/algorithm_ext/erase.hpp>
+
+using namespace std;
+using namespace rsb;
+using namespace rsb::patterns;
+
+MiddlewareRSB::MiddlewareRSB(string scope) : Middleware(scope) {
+    printf("> new MiddlewareRSB() on base scope '%s'\n",base_scope.c_str());
+    init();
+}
+
+void MiddlewareRSB::init(void){
+    printf("> MiddlewareRSB::init() registering converters\n");
+
+    try{
+        //converter for EmotionState
+        rsb::converter::Converter<string>::Ptr emotionStateConverter(new rsb::converter::ProtocolBufferConverter<rst::robot::EmotionState>());
+        rsb::converter::converterRepository<string>()->registerConverter(emotionStateConverter);
+
+        //converter for Utterance
+        //rsb::converter::Converter<string>::Ptr UtteranceConverter(new rsb::converter::ProtocolBufferConverter<rst::audition::Utterance>());
+        //rsb::converter::converterRepository<string>()->registerConverter(UtteranceConverter);
+
+        //converter for GazeTarget
+        rsb::converter::Converter<string>::Ptr gazeTargetConverter(new rsb::converter::ProtocolBufferConverter<rst::robot::GazeTarget>());
+        rsb::converter::converterRepository<string>()->registerConverter(gazeTargetConverter);
+
+        //converter for MouthTarget
+        rsb::converter::Converter<string>::Ptr mouthTargetConverter(new rsb::converter::ProtocolBufferConverter<rst::robot::MouthTarget>());
+        rsb::converter::converterRepository<string>()->registerConverter(mouthTargetConverter);
+
+
+        //converter for Animation
+        rsb::converter::Converter<string>::Ptr animationConverter(new rsb::converter::ProtocolBufferConverter<rst::robot::Animation>());
+        rsb::converter::converterRepository<string>()->registerConverter(animationConverter);
+
+    }catch(std::invalid_argument e){
+        printf("> converters already registered\n");
+    }
+
+    //first get a factory instance that is used to create RSB domain objects
+    Factory &factory = getFactory();
+
+    //get server
+    string scope = base_scope + "/set/";
+    hlrc_server = factory.createRemoteServer(scope);
+
+    printf("> init done\n");
+
+}
+
+void MiddlewareRSB::publish_emotion(string scope_target, RobotEmotion e, bool blocking){
+    boost::shared_ptr<rst::robot::EmotionState> request(new rst::robot::EmotionState());
+
+    switch(e.value){
+        default:
+            printf("> WANRING: invalid emotion id %d. defaulting to NEUTRAL\n",e.value);
+            //fall through:
+        case(RobotEmotion::NEUTRAL):
+            request->set_value(rst::robot::EmotionState::NEUTRAL);
+            break;
+        case(RobotEmotion::HAPPY):
+            request->set_value(rst::robot::EmotionState::HAPPY);
+            break;
+        case(RobotEmotion::SAD):
+            request->set_value(rst::robot::EmotionState::SAD);
+            break;
+        case(RobotEmotion::ANGRY):
+            request->set_value(rst::robot::EmotionState::ANGRY);
+            break;
+        case(RobotEmotion::SURPRISED):
+            request->set_value(rst::robot::EmotionState::SURPRISED);
+            break;
+        case(RobotEmotion::FEAR):
+            request->set_value(rst::robot::EmotionState::FEAR);
+            break;
+    }
+
+    request->set_duration(e.time_ms);
+
+    if (blocking){
+        hlrc_server->call<rst::robot::EmotionState>(scope_target, request);
+    }else{
+        hlrc_server->callAsync<rst::robot::EmotionState>(scope_target, request);
+    }
+}
+
+
+void MiddlewareRSB::publish_current_emotion(RobotEmotion e, bool blocking){
+    publish_emotion("currentEmotion", e, blocking);
+}
+
+void MiddlewareRSB::publish_default_emotion(RobotEmotion e, bool blocking){
+    publish_emotion("defaultEmotion", e, blocking);
+}
+
+void MiddlewareRSB::publish_gaze_target(RobotGaze target, bool blocking){
+    boost::shared_ptr<rst::robot::GazeTarget> request(new rst::robot::GazeTarget());
+
+    request->set_pan(target.pan);
+    request->set_tilt(target.tilt);
+    request->set_roll(target.roll);
+    request->set_vergence(target.vergence);
+    request->set_pan_offset(target.pan_offset);
+    request->set_tilt_offset(target.tilt_offset);
+
+    if (blocking){
+        hlrc_server->call<rst::robot::GazeTarget>("gaze", request);
+    }else{
+        hlrc_server->callAsync<rst::robot::GazeTarget>("gaze", request);
+    }
+}
+
+void MiddlewareRSB::publish_mouth_target(RobotMouth target, bool blocking){
+    boost::shared_ptr<rst::robot::MouthTarget> request(new rst::robot::MouthTarget());
+
+    request->set_position_left(  target.position_left);
+    request->set_position_center(target.position_center);
+    request->set_position_right( target.position_right);
+
+    request->set_opening_left(  target.opening_left);
+    request->set_opening_center(target.opening_center);
+    request->set_opening_right( target.opening_right);
+
+    if (blocking){
+        hlrc_server->call<rst::robot::MouthTarget>("mouth", request);
+    }else{
+        hlrc_server->callAsync<rst::robot::MouthTarget>("mouth", request);
+    }
+}
+
+void MiddlewareRSB::publish_head_animation(RobotHeadAnimation a, bool blocking){
+    boost::shared_ptr<rst::robot::Animation> request(new rst::robot::Animation());
+
+    switch(a.value){
+        default:
+            printf("> WANRING: invalid animation id %d. defaulting to IDLE",a.value);
+            //fall through:
+        case(RobotHeadAnimation::IDLE):
+            request->set_target(rst::robot::Animation::IDLE);
+            break;
+        case(RobotHeadAnimation::HEAD_NOD):
+            request->set_target(rst::robot::Animation::HEAD_NOD);
+            break;
+        case(RobotHeadAnimation::HEAD_SHAKE):
+            request->set_target(rst::robot::Animation::HEAD_SHAKE);
+            break;
+        case(RobotHeadAnimation::EYEBLINK_L):
+            request->set_target(rst::robot::Animation::EYEBLINK_L);
+            break;
+        case(RobotHeadAnimation::EYEBLINK_R):
+            request->set_target(rst::robot::Animation::EYEBLINK_R);
+            break;
+        case(RobotHeadAnimation::EYEBLINK_BOTH):
+            request->set_target(rst::robot::Animation::EYEBLINK_BOTH);
+            break;
+        case(RobotHeadAnimation::EYEBROWS_RAISE):
+            request->set_target(rst::robot::Animation::EYEBROWS_RAISE);
+            break;
+        case(RobotHeadAnimation::EYEBROWS_LOWER):
+            request->set_target(rst::robot::Animation::EYEBROWS_LOWER);
+            break;
+    }
+
+    request->set_repetitions(a.repetitions);
+    request->set_scale(a.scale);
+    request->set_duration_each(a.time_ms);
+
+    if (blocking){
+        hlrc_server->call<rst::robot::Animation>("animation", request);
+    }else{
+        hlrc_server->callAsync<rst::robot::Animation>("animation", request);
+    }
+}
+
+void MiddlewareRSB::publish_speech(string text, bool blocking){
+    //say it
+    boost::shared_ptr<std::string> request(new string(text));
+
+    if (blocking){
+        hlrc_server->call<std::string>("speech", request);
+    }else{
+        hlrc_server->callAsync<std::string>("speech", request);
+    }
+}
+
+#endif
diff --git a/client/cpp/src/RobotController.cpp b/client/cpp/src/RobotController.cpp
new file mode 100644
index 0000000..5c0c958
--- /dev/null
+++ b/client/cpp/src/RobotController.cpp
@@ -0,0 +1,78 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "RobotController.h"
+#include "Middleware.h"
+#include "MiddlewareRSB.h"
+#include "MiddlewareROS.h"
+using namespace std;
+
+RobotController::RobotController(string mw_name, string base_scope){
+    if (mw_name == "ROS"){
+        //intantiate ROS mw
+        middleware = new MiddlewareROS(base_scope);
+    }else if (mw_name == "RSB"){
+        //intantiate RSB mw
+        middleware = new MiddlewareRSB(base_scope);
+    }else{
+        printf("ERROR: invalid middleware requested (%s). supported: {ROS, RSB}\n\n", mw_name.c_str());
+        exit(EXIT_FAILURE);
+    }
+}
+
+void RobotController::set_current_emotion(RobotEmotion e, bool blocking){
+    middleware->set_current_emotion(e, blocking);
+}
+
+void RobotController::set_default_emotion(RobotEmotion e, bool blocking){
+    middleware->set_default_emotion(e, blocking);
+}
+
+
+void RobotController::set_gaze_target(RobotGaze target, bool blocking){
+    middleware->set_gaze_target(target, blocking);
+}
+
+RobotGaze RobotController::get_gaze_target(){
+    return middleware->get_gaze_target();
+}
+
+void RobotController::set_mouth_target(RobotMouth target, bool blocking){
+    middleware->set_mouth_target(target, blocking);
+}
+
+void RobotController::set_head_animation(RobotHeadAnimation a, bool blocking){
+    middleware->set_head_animation(a, blocking);
+}
+
+void RobotController::set_speak(string text, bool blocking){
+    printf("> DBG: set_speak(%s, %s)\n",text.c_str(),blocking?"blocking":"nonblock");
+    middleware->set_speak(text, blocking);
+}
+
+
diff --git a/client/java/COPYING b/client/java/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/client/java/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/client/java/README.md b/client/java/README.md
new file mode 100644
index 0000000..1139cbe
--- /dev/null
+++ b/client/java/README.md
@@ -0,0 +1,4 @@
+# [h]igh [l]evel [r]obot [c]ontrol client java (hlrc_client_java)
+
+this is the high level robot control client code in java.
+
diff --git a/client/java/nbactions.xml b/client/java/nbactions.xml
new file mode 100644
index 0000000..6b3597e
--- /dev/null
+++ b/client/java/nbactions.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<actions>
+        <action>
+            <actionName>run</actionName>
+            <packagings>
+                <packaging>jar</packaging>
+            </packagings>
+            <goals>
+                <goal>process-classes</goal>
+                <goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec</goal>
+            </goals>
+            <properties>
+                <exec.args>-classpath %classpath de.uni-bielefeld.cit-ec.opensource.hlrc.main.Cmd --idle</exec.args>
+                <exec.executable>java</exec.executable>
+            </properties>
+        </action>
+        <action>
+            <actionName>debug</actionName>
+            <packagings>
+                <packaging>jar</packaging>
+            </packagings>
+            <goals>
+                <goal>process-classes</goal>
+                <goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec</goal>
+            </goals>
+            <properties>
+                <exec.args>-Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -classpath %classpath de.uni-bielefeld.cit-ec.opensource.hlrc.main.Cmd --idle</exec.args>
+                <exec.executable>java</exec.executable>
+                <jpda.listen>true</jpda.listen>
+            </properties>
+        </action>
+        <action>
+            <actionName>profile</actionName>
+            <packagings>
+                <packaging>jar</packaging>
+            </packagings>
+            <goals>
+                <goal>process-classes</goal>
+                <goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec</goal>
+            </goals>
+            <properties>
+                <exec.args>-classpath %classpath de.uni-bielefeld.cit-ec.opensource.hlrc.main.Cmd --idle</exec.args>
+                <exec.executable>java</exec.executable>
+            </properties>
+        </action>
+    </actions>
diff --git a/client/java/pom.xml b/client/java/pom.xml
new file mode 100644
index 0000000..a1d4749
--- /dev/null
+++ b/client/java/pom.xml
@@ -0,0 +1,121 @@
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>de.citec.csra</groupId>
+    <artifactId>hlrc-client</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>jar</packaging>
+    <name>High Level Command Client</name>
+    <url>http://maven.apache.org</url>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.1</version>
+                <configuration>
+                    <source>1.7</source>
+                    <target>1.7</target>
+                    <showDeprecation>true</showDeprecation>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>appassembler-maven-plugin</artifactId>
+                <version>1.8</version>
+                <configuration>
+                    <programs>
+                        <program>
+                            <mainClass>de.uni-bielefeld.cit-ec.opensource.hlrc.main.Cmd</mainClass>
+                            <id>hlrc-client</id>
+                            
+                        </program>
+                    </programs>
+                    <!--                    <assembleDirectory>${project.build.directory}/dist</assembleDirectory>
+                    <repositoryName>lib</repositoryName>
+                    <repositoryLayout>flat</repositoryLayout>-->
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>assemble</id>
+                        <goals>
+                            <goal>assemble</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <licenses>
+        <license>
+            <name>GPLv3</name>
+            <url>http://www.gnu.org/licenses/gpl.html</url>
+        </license>
+    </licenses>
+    <organization>
+        <name>Citec, Bielefeld University</name>
+        <url>http://www.cit-ec.de/</url>
+    </organization>
+    <developers>
+        <developer>
+            <id>flier</id>
+            <name>Florian Lier</name>
+            <email>flier@techfak.uni-bielefeld.de</email>
+            <url>https://www.cit-ec.de/de/users/flier</url>
+            <roles>
+                <role>architect</role>
+                <role>developer</role>
+            </roles>
+            <timezone>+1</timezone>
+        </developer>
+    </developers>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.7</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <version>1.7.7</version>
+        </dependency>            
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.11</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>rsb</groupId>
+            <artifactId>rsb</artifactId>
+            <version>[0.11.0,)</version>
+        </dependency>
+        <dependency>
+            <groupId>rsb</groupId>
+            <artifactId>rst-sandbox-csra</artifactId>
+            <version>0.11-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-cli</groupId>
+            <artifactId>commons-cli</artifactId>
+            <version>1.2</version>
+        </dependency>
+	<dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.6</version>
+        </dependency>
+    </dependencies>
+    <distributionManagement>
+        <repository>
+            <id>citec</id>
+            <name>CITEC Maven Repository Server</name>
+            <url>https://repo.cit-ec.uni-bielefeld.de/content/repositories/releases/</url>
+            <layout>default</layout>
+        </repository>
+    </distributionManagement>
+</project>
diff --git a/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/client/Emotions.java b/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/client/Emotions.java
new file mode 100644
index 0000000..f102f6f
--- /dev/null
+++ b/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/client/Emotions.java
@@ -0,0 +1,38 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) {flier,sschulz} <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+package de.uni-bielefeld.cit-ec.opensource.hlrc.client;
+
+public enum Emotions {
+    NEUTRAL,
+    HAPPY,	
+    SAD,	
+    ANGRY,
+    SURPRISED,	
+    FEAR
+}
diff --git a/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/client/HeadAnimations.java b/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/client/HeadAnimations.java
new file mode 100644
index 0000000..9788b98
--- /dev/null
+++ b/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/client/HeadAnimations.java
@@ -0,0 +1,40 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) {flier,sschulz} <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+package de.uni-bielefeld.cit-ec.opensource.hlrc.client;
+
+public enum HeadAnimations {
+    IDLE,
+    HEAD_NOD,
+    HEAD_SHAKE,
+    EYEBLINK_L,
+    EYEBLINK_R,
+    EYEBLINK_BOTH,
+    EYEBROWS_RAISE,
+    EYEBROWS_LOWER
+}
\ No newline at end of file
diff --git a/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/client/MiddlewareRSB.java b/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/client/MiddlewareRSB.java
new file mode 100644
index 0000000..5dc2573
--- /dev/null
+++ b/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/client/MiddlewareRSB.java
@@ -0,0 +1,358 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) {flier,sschulz} <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+package de.uni-bielefeld.cit-ec.opensource.hlrc.client;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+import rsb.Factory;
+import rsb.RSBException;
+import rsb.converter.DefaultConverterRepository;
+import rsb.converter.ProtocolBufferConverter;
+import rsb.patterns.RemoteServer;
+
+import rst.audition.PhonemeType.Phoneme;
+import rst.audition.SoundChunkType.SoundChunk;
+import rst.audition.UtteranceType.Utterance;
+import rst.robot.AnimationType.Animation;
+import rst.robot.AnimationType.Animation.AnimationType_t;
+import rst.robot.EmotionStateType.EmotionState;
+import rst.robot.EmotionStateType.EmotionState.EmotionType;
+import rst.robot.GazeTargetType.GazeTarget;
+
+import com.google.protobuf.ByteString;
+
+// Create _abstract_ middleware class and function _interface_ for 
+// future integration of additional Middleware implementations...
+
+import rsb.Factory;
+import rsb.Informer;
+
+
+public class MiddlewareRSB {
+
+    final RemoteServer server;
+    final String robotname;
+    static Map<Emotions, EmotionType> emo_map;
+    static Map<HeadAnimations, AnimationType_t> han_map;
+    
+    public class RSBInformer {
+
+    final Factory factory;
+    final Informer<Object> informer;
+        
+    public RSBInformer(String scope) throws Throwable {
+
+        // Get a factory instance to create RSB objects.
+        factory = Factory.getInstance();
+
+        // Create an informer on scope "/exmaple/informer".
+        informer = factory.createInformer(scope);
+
+        // Activate the informer to be ready for work
+        informer.activate();
+
+    }
+    
+    public void pushMsg(){
+        try {
+            // Send and event using a method that accepts the data and
+            // automatically creates an appropriate event internally.
+            this.informer.send("TODO");
+        } catch (RSBException ex) {
+            Logger.getLogger(MiddlewareRSB.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+    
+    public void closeInf() throws InterruptedException {
+        try {
+            // As there is no explicit removal model in java, always manually
+            // deactivate the informer if it is not needed anymore
+            this.informer.deactivate();
+        } catch (RSBException ex) {
+            Logger.getLogger(MiddlewareRSB.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+    
+}
+    
+    
+    @SuppressWarnings("unchecked")
+	public MiddlewareRSB(String robotname) {
+        
+        this.robotname = robotname;
+            
+        server = Factory.getInstance().createRemoteServer(this.robotname+"/set/");
+        System.out.println("--> Robot: Talking to "+this.robotname);
+        try {
+            server.activate();
+        } catch (RSBException ex) {
+            Logger.getLogger(MiddlewareRSB.class.getName()).log(Level.SEVERE, null, ex);
+        }
+
+        {
+            final ProtocolBufferConverter<EmotionState> converter = new ProtocolBufferConverter<>(EmotionState.getDefaultInstance());
+            DefaultConverterRepository.getDefaultConverterRepository().addConverter(converter);
+        }
+        {
+            final ProtocolBufferConverter<GazeTarget> converter = new ProtocolBufferConverter<>(GazeTarget.getDefaultInstance());
+            DefaultConverterRepository.getDefaultConverterRepository().addConverter(converter);
+        }
+        {
+            final ProtocolBufferConverter<Animation> converter = new ProtocolBufferConverter<>(Animation.getDefaultInstance());
+            DefaultConverterRepository.getDefaultConverterRepository().addConverter(converter);
+        }
+        {
+            final ProtocolBufferConverter<Utterance> converter = new ProtocolBufferConverter<>(Utterance.getDefaultInstance());
+            DefaultConverterRepository.getDefaultConverterRepository().addConverter(converter);
+        }
+        {
+            final ProtocolBufferConverter<SoundChunk> converter = new ProtocolBufferConverter<>(SoundChunk.getDefaultInstance());
+            DefaultConverterRepository.getDefaultConverterRepository().addConverter(converter);
+        }
+        {
+            final ProtocolBufferConverter<Phoneme> converter = new ProtocolBufferConverter<>(Phoneme.getDefaultInstance());
+            DefaultConverterRepository.getDefaultConverterRepository().addConverter(converter);
+        }
+
+        emo_map = new HashMap();
+        emo_map.put(Emotions.SAD,       EmotionType.SAD);
+        emo_map.put(Emotions.ANGRY,     EmotionType.ANGRY);
+        emo_map.put(Emotions.FEAR,      EmotionType.FEAR);
+        emo_map.put(Emotions.NEUTRAL,   EmotionType.NEUTRAL);
+        emo_map.put(Emotions.SURPRISED, EmotionType.SURPRISED);
+        emo_map.put(Emotions.HAPPY,     EmotionType.HAPPY);
+
+        han_map = new HashMap();
+        han_map.put(HeadAnimations.HEAD_NOD,       AnimationType_t.HEAD_NOD);
+        han_map.put(HeadAnimations.HEAD_SHAKE,     AnimationType_t.HEAD_SHAKE);
+        han_map.put(HeadAnimations.IDLE,           AnimationType_t.IDLE);
+        han_map.put(HeadAnimations.EYEBLINK_R,     AnimationType_t.EYEBLINK_R);
+        han_map.put(HeadAnimations.EYEBLINK_L,     AnimationType_t.EYEBLINK_L);
+        han_map.put(HeadAnimations.EYEBLINK_BOTH,  AnimationType_t.EYEBLINK_BOTH);
+        han_map.put(HeadAnimations.EYEBROWS_LOWER, AnimationType_t.EYEBROWS_LOWER);
+        han_map.put(HeadAnimations.EYEBROWS_RAISE, AnimationType_t.EYEBROWS_RAISE);
+    }
+
+    private SoundChunk compileSoundChunk(AudioFormat audio, byte[] data) {
+       SoundChunk.Builder sc = SoundChunk.newBuilder();
+        ByteString bs = ByteString.copyFrom(data);
+        boolean isbig = audio.isBigEndian();
+        sc.setChannels(audio.getChannels());
+        sc.setData(bs);
+        sc.setRate((int) audio.getSampleRate());
+
+        if (isbig) {
+            sc.setEndianness(SoundChunk.EndianNess.ENDIAN_BIG);
+        } else {
+            sc.setEndianness(SoundChunk.EndianNess.ENDIAN_LITTLE);
+        }
+
+        sc.setSampleCount(data.length / audio.getFrameSize());
+        Encoding enc = audio.getEncoding();
+
+        if (enc.equals(Encoding.PCM_SIGNED)) {
+            int size = audio.getSampleSizeInBits();
+            if (size == 8) {
+                sc.setSampleType(SoundChunk.SampleType.SAMPLE_S8);
+            } else if (size == 16) {
+                sc.setSampleType(SoundChunk.SampleType.SAMPLE_S16);
+            } else if (size == 24) {
+                sc.setSampleType(SoundChunk.SampleType.SAMPLE_S24);
+            } else {
+                System.err.println("Audio Sample Size Not Valid");
+            }
+        } else if (enc.equals(Encoding.PCM_UNSIGNED)) {
+            int size = audio.getSampleSizeInBits();
+            if (size == 8) {
+                sc.setSampleType(SoundChunk.SampleType.SAMPLE_U8);
+            } else if (size == 16) {
+                sc.setSampleType(SoundChunk.SampleType.SAMPLE_U16);
+            } else if (size == 24) {
+                sc.setSampleType(SoundChunk.SampleType.SAMPLE_U24);
+            } else {
+                System.err.println("Audio Sample Size not valid");
+                // This is too rigorous, maybe.
+                // System.exit(-1);
+            }
+        } else {
+            System.err.println("Audio Encoding is invalid");
+        }
+        return sc.build();
+    }
+
+    public void deactivateServer() throws InterruptedException {
+        try {
+            this.server.deactivate();
+        } catch (RSBException ex) {
+            Logger.getLogger(MiddlewareRSB.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    // OBSOLETE
+    /*
+     public MouthAnimation createMouthAnimationMessage(int duration, boolean active) {
+     MouthAnimation.Builder ma = MouthAnimation.newBuilder();
+     ma.setDuration(duration);
+     ma.setActive(active);
+     return ma.build();
+     }
+     */
+    
+    public Utterance createSetSpeak(SoundChunk soundchunck, ArrayList tuList, String text) {
+        Utterance.Builder ut = Utterance.newBuilder();
+        ut.setAudio(soundchunck);
+        for (int i=0; i< tuList.size();i++) {
+        	Phoneme.Builder ph = Phoneme.newBuilder();
+        	Tuple t = (Tuple) tuList.get(i);
+        	ph.setSymbol(t.s);
+            ph.setDuration(t.d);
+            ut.addPhonemes(i, ph);
+            
+        }
+        System.out.println("Phonem count " + ut.getPhonemesCount() + " Phonem list " + ut.getPhonemesList());
+        ut.setText(text);
+        return ut.build();
+    }
+
+    public Animation createHeadAnimationMessage(HeadAnimations ani, int duration, int repetition, float scale) {
+        Animation.Builder ha = Animation.newBuilder();
+        ha.setRepetitions(repetition);
+        ha.setTarget(han_map.get(ani));
+        ha.setDurationEach(duration);
+        ha.setScale(scale);
+        return ha.build();
+    }
+
+    public EmotionState createCurrentEmotionMessage(Emotions emo, int duration) {
+        EmotionState.Builder es = EmotionState.newBuilder();
+        es.setDuration(duration);
+        es.setValue(emo_map.get(emo));
+        return es.build();
+    }
+
+    public EmotionState createDefaultEmotionMessage(Emotions emo) {
+        EmotionState.Builder es = EmotionState.newBuilder();
+        es.setValue(emo_map.get(emo));
+        return es.build();
+    }
+
+    public GazeTarget createGazeTargetMessage(float pan, float tilt, float roll) {
+        GazeTarget.Builder gt = GazeTarget.newBuilder();
+        gt.setPan(pan);
+        gt.setTilt(tilt);
+        gt.setRoll(roll);
+        return gt.build();
+    }
+
+    public void setSpeak(AudioFormat audio, byte[] bs, ArrayList tu, String text, boolean blocking) throws ExecutionException, TimeoutException {
+        SoundChunk sc;
+        sc = compileSoundChunk(audio, bs);
+        if (blocking) {
+            try {
+                server.call("utterance", createSetSpeak(sc, tu, text));
+                // System.out.println("Server replied: " + server.call("utterance", createSetSpeak(sc, tu)));
+            } catch (RSBException ex) {
+                Logger.getLogger(MiddlewareRSB.class.getName()).log(Level.SEVERE, null, ex);
+            }
+        } else {
+            try {             
+                server.callAsync("utterance", createSetSpeak(sc, tu, text));
+                // System.out.println("Set Mouth Animation non-blocking, not wating for reply");
+            } catch (RSBException ex) {
+                Logger.getLogger(MiddlewareRSB.class.getName()).log(Level.SEVERE, null, ex);
+            }
+        }
+    }
+    
+    public void setCurrentEmotion(Emotions emo, int duration, boolean blocking) throws ExecutionException, TimeoutException {
+        try {
+            if (blocking) {
+                server.call("currentEmotion", createCurrentEmotionMessage(emo, duration));
+                // System.out.println("Server replied: " + server.call("currentEmotion", createEmotionMessage(emo, duration)));
+            } else {        
+                server.callAsync("currentEmotion", createCurrentEmotionMessage(emo, duration));
+                // System.out.println("Set Emotion non-blocking, not wating for reply");
+            }
+
+        } catch (RSBException ex) {
+            Logger.getLogger(MiddlewareRSB.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    public void setGazeTarget(float pan, float tilt, float roll, boolean blocking) throws ExecutionException, TimeoutException {
+        try {
+            if (blocking) {
+                server.call("gaze", createGazeTargetMessage(pan, tilt, roll));
+                // System.out.println("Server replied: " + server.call("gaze", createGazeTargetMessage(pan, tilt, roll)));
+            } else {               
+                server.callAsync("gaze", createGazeTargetMessage(pan, tilt, roll));
+                // System.out.println("Set Gaze non-blocking, not wating for reply");
+            }
+        } catch (RSBException ex) {
+            Logger.getLogger(MiddlewareRSB.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    public void setDefaultEmotion(Emotions emo, boolean blocking) throws ExecutionException, TimeoutException {
+        try {
+            if (blocking) {
+                server.call("defaultEmotion", createDefaultEmotionMessage(emo));
+                // System.out.println("Server replied: " + server.call("defaultEmotion", createDefaultEmotionMessage(emo)));
+            } else {              
+                server.callAsync("defaultEmotion", createDefaultEmotionMessage(emo));
+                // System.out.println("Set Default Emotion non-blocking, not wating for reply");
+            }
+        } catch (RSBException ex) {
+            Logger.getLogger(MiddlewareRSB.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    public void setHeadAnimation(HeadAnimations ani, int duration, int repetitions, float scale, boolean blocking) throws ExecutionException, TimeoutException {
+        try {
+            if (blocking) {
+                server.call("animation", createHeadAnimationMessage(ani, duration, repetitions, scale));
+                // System.out.println("Server replied: " + server.call("animation", createHeadAnimationMessage(ani, duration, repetitions, scale)));
+            } else {
+                server.callAsync("animation", createHeadAnimationMessage(ani, duration, repetitions, scale));
+                // System.out.println("Set Head Animation non-blocking, not wating for reply");
+            }
+        } catch (RSBException ex) {
+            Logger.getLogger(MiddlewareRSB.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+}
diff --git a/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/client/RobotController.java b/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/client/RobotController.java
new file mode 100644
index 0000000..1479912
--- /dev/null
+++ b/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/client/RobotController.java
@@ -0,0 +1,161 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) {flier,sschulz} <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+package de.uni-bielefeld.cit-ec.opensource.hlrc.client;
+
+import java.util.ArrayList;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.sound.sampled.AudioFormat;
+
+public class RobotController {
+
+    private final String name;
+    private final String middlwarename;
+    public final MiddlewareRSB mw;
+
+    
+    /**
+    * 
+    * Create a new RobotController
+    * 
+    * @param name String robot name i.e. "/home/wardrobe/flobi", "/home/kitchen/flobi"
+    * @param middleware String what Middleware Layer to use
+    *
+    */
+    public RobotController(String name, String middleware) {
+        this.name = name;
+        this.middlwarename = middleware;
+        if (middleware.toUpperCase().equals("RSB")) {
+            System.out.println("--> RobotController: "+name+" using middleware: "+middleware+ " has been initialized");
+            this.mw = new MiddlewareRSB(this.name);
+        } else {
+            System.out.println("Only RSB Supported for now. Sorry.");
+            this.mw = new MiddlewareRSB(this.name);
+        }
+    }
+
+    /**
+    * 
+    * Start the RobotController's mouth animation 
+    * 
+    * @param audio Java std auto format
+    * @param bytes Byte Array containing the actual audio stream
+    * @param tuList A list of Tupel phoneme plus duration 
+    * @param blocking invoke the command blocking or non blocking TRUE/FALSE
+    *
+    */
+
+    public void setSpeak(AudioFormat audio, byte[] bytes, ArrayList tuList, String text, boolean blocking) {
+        try {
+            // System.out.println(">> Sending Set Speak: Blocking: " + blocking);
+            mw.setSpeak(audio, bytes, tuList, text, blocking);
+        } catch (ExecutionException | TimeoutException ex) {
+            Logger.getLogger(RobotController.class.getName()).log(Level.SEVERE, null, ex);
+        }
+        
+    }
+
+    public void setGazeTarget(float pan, float tilt, float roll, boolean blocking) {
+        try {
+            // System.out.println(">> Sending Gaze: pan|tilt|roll: " + pan + " / " + tilt + " / " + roll + " / Blocking: " + blocking);
+            mw.setGazeTarget(pan, tilt, roll, blocking);
+        } catch (ExecutionException | TimeoutException ex) {
+            Logger.getLogger(RobotController.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+    
+     /**
+    * 
+    * set robots emotion
+    * 
+    * @param  emo      set the desired EMOTION
+    * @param  duration the length of the animation in MILLISECONDS
+    * @param  blocking invoke the command blocking or non blocking TRUE/FALSE
+    *
+    */
+    public void setCurrentEmotion(Emotions emo, int duration, boolean blocking) {
+        try {
+            // System.out.println(">> Sending Emotion: " + emo + " / duration: " + duration + " / Blocking: " + blocking);
+            mw.setCurrentEmotion(emo, duration, blocking);
+        } catch (ExecutionException | TimeoutException ex) {
+            Logger.getLogger(RobotController.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    public void setDefaultEmotion(Emotions emo, boolean blocking) {
+        try {
+            // System.out.println(">> Sending Default Emotion: " + emo + " / Blocking: " + blocking);
+            mw.setDefaultEmotion(emo, blocking);
+        } catch (ExecutionException | TimeoutException ex) {
+            Logger.getLogger(RobotController.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    public void setHeadAnimation(HeadAnimations ani, int duration, int repetitions, float scale, boolean blocking) {
+        try {
+            // System.out.println(">> Sending Animation: " + ani + " / Duration: " + duration + " / Repetitions: " + repetitions + " / Blocking: " + blocking);
+            mw.setHeadAnimation(ani, duration, repetitions, scale, blocking);
+        } catch (ExecutionException | TimeoutException ex) {
+            Logger.getLogger(RobotController.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    /*
+    public void getMouthAnimation() {
+        System.out.println("Get Mouth Animation - Not implemented.");
+    }
+
+    public void getEmotion() {
+        System.out.println("Get Emotion - Not implemented.");
+    }
+
+    public void getGazeTarget() {
+        System.out.println("Get Gaze Target - Not implemented");
+    }
+
+    public void getDefaultEmotion() {
+        System.out.println("Get Default Emotion - Not implemented");
+    }
+
+    public void getHeadAnimation() {
+        System.out.println("Get Head Animation - Not implemented");
+    }
+    */
+    
+    public String getRobotControllerName() {
+        return this.name;
+    }
+    
+    public String getMiddleware() {
+        return this.middlwarename;
+    }
+
+}
diff --git a/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/client/Tuple.java b/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/client/Tuple.java
new file mode 100644
index 0000000..67089a9
--- /dev/null
+++ b/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/client/Tuple.java
@@ -0,0 +1,46 @@
+/*
+* This file is part of hlrc
+*
+* Copyright(c) {flier,sschulz} <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+package de.uni-bielefeld.cit-ec.opensource.hlrc.client;
+
+/**
+ *
+ * @param <Symbol>
+ * @param <double>
+ * 
+ */
+public class Tuple { 
+  protected final String s; 
+  protected final int d; 
+  
+  public Tuple(String phone, int d) { 
+    this.s = phone; 
+    this.d = d; 
+  } 
+  
+} 
\ No newline at end of file
diff --git a/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/examples/SimpleExample.java b/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/examples/SimpleExample.java
new file mode 100644
index 0000000..83ef90a
--- /dev/null
+++ b/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/examples/SimpleExample.java
@@ -0,0 +1,52 @@
+/*
+* This file is part of hlrc_client_java
+*
+* Copyright(c) {flier,sschulz} <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+package de.uni-bielefeld.cit-ec.opensource.hlrc.examples;
+
+import de.uni-bielefeld.cit-ec.opensource.hlrc.client.Emotions;
+import de.uni-bielefeld.cit-ec.opensource.hlrc.client.RobotController;
+
+public class SimpleExample {
+    
+    public SimpleExample(String robotname, String middleware) {
+        String name = robotname;
+        String mw = middleware;
+        // Create a new Robot
+        RobotController r = new RobotController(name, mw);
+        
+        // Do something HIGH LEVEL with ease!
+        r.setCurrentEmotion(Emotions.SAD, 1000, true);
+        // r.setGazeTarget(70.0f, 50.0f, 40.0f, true);
+    }
+
+    public static void main(String [] args) {
+            SimpleExample se = new SimpleExample("/home/kitchen/flobi", "RSB");
+    }
+    
+}
+
diff --git a/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/main/Cmd.java b/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/main/Cmd.java
new file mode 100644
index 0000000..8ec1b1c
--- /dev/null
+++ b/client/java/src/main/java/de/uni-bielefeld/cit-ec/opensource/hlrc/main/Cmd.java
@@ -0,0 +1,159 @@
+/*
+* This file is part of hlrc_client_java
+*
+* Copyright(c) {flier,sschulz} <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+package de.uni-bielefeld.cit-ec.opensource.hlrc.main;
+
+import de.uni-bielefeld.cit-ec.opensource.hlrc.client.HeadAnimations;
+import de.uni-bielefeld.cit-ec.opensource.hlrc.client.Emotions;
+import de.uni-bielefeld.cit-ec.opensource.hlrc.client.RobotController;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.commons.cli.BasicParser;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+
+import rsb.RSBException;
+
+public class Cmd {
+
+    public static void main(String[] args) throws RSBException {
+
+        try {
+            
+            RobotController robot;
+            CommandLineParser parser = new BasicParser();
+            CommandLine line;
+            
+            Options lvOptions = new Options();
+            lvOptions.addOption("de", "default",       false, "set the robot's default emotion");
+            lvOptions.addOption("ga", "gaze",          false, "make the robot look somewhere");
+            lvOptions.addOption("rg", "resetgaze",     false, "make the robot look towards you");
+            lvOptions.addOption("sa", "sad",           false, "make robot look sad");
+            lvOptions.addOption("ha", "happy",         false, "make robot look happy");
+            lvOptions.addOption("ne", "neutral",       false, "make the robot look neutral");
+            lvOptions.addOption("an", "angry",         false, "make the robot look angry");
+            lvOptions.addOption("su", "surprised",     false, "make the robot look surprised");
+            lvOptions.addOption("fe", "fear",          false, "make the robot look afraid");
+            lvOptions.addOption("id", "idle",          false, "make robot look idle");
+            lvOptions.addOption("no", "nodding",       false, "make the robot nodding his head");
+            lvOptions.addOption("he", "headshake",     false, "make the robot shake his head");
+            lvOptions.addOption("er", "eyeblinkright", false, "make the robot's right eye blink");
+            lvOptions.addOption("el", "eyeblinkleft",  false, "make the robot's left eye blink");
+            lvOptions.addOption("br", "eyebrowsraise", false, "make the robot's brows raise");
+            lvOptions.addOption("bl", "eyebrowslower", false, "make the robot's brows lower");
+            lvOptions.addOption("eb", "eyeblinkboth",  false, "make both robot's eyes blink");
+            lvOptions.addOption("r",  "robotname",     true,  "set the robot name i.e. /home/kitchen/flobi");
+            lvOptions.addOption("h", "help",           false, "show help");
+            
+            System.out.println("-- High Level Control Client successfully initialized --");
+            
+            try {
+                line = parser.parse(lvOptions, args);
+            } catch (ParseException ex) {
+                // Logger.getLogger(Cmd.class.getName()).log(Level.SEVERE, null, ex);
+                System.out.println("--> Unrecognized Option. Exiting...");
+                return;
+            }
+            if (line.hasOption("help")) {
+                HelpFormatter lvFormater = new HelpFormatter();
+                lvFormater.printHelp("High Level Control Client", lvOptions);
+                return;
+            }
+            
+            if (line.getOptionValue("robotname") != null) {
+                robot = new Robot(line.getOptionValue("robotname"), "RSB");
+            } else {
+                System.out.println("--> You need to provide a robot name, see --help");
+                return;
+            }
+            
+            if (line.hasOption("gaze")) {
+                robot.setGazeTarget(35.0f, 20.0f, 10.0f, true);
+            }else if (line.hasOption("resetgaze")) {
+                robot.setGazeTarget(0.0f, 0.0f, 0.0f, true);
+            }else if (line.hasOption("idle")) {
+                robot.setHeadAnimation(HeadAnimations.IDLE, 1000, 1, 1.0f ,true);
+            }else if (line.hasOption("nodding")) {
+                robot.setHeadAnimation(HeadAnimations.HEAD_NOD, 1000, 1, 1.0f, true);
+            }
+            else if (line.hasOption("headshake")) {
+                robot.setHeadAnimation(HeadAnimations.HEAD_SHAKE, 1000, 1, 1.0f, true);
+            }
+            else if (line.hasOption("eyeblinkright")) {
+                robot.setHeadAnimation(HeadAnimations.EYEBLINK_R, 1000, 1, 1.0f, true);
+            }
+            else if (line.hasOption("eyeblinkleft")) {
+                robot.setHeadAnimation(HeadAnimations.EYEBLINK_L, 1000, 1, 1.0f, true);
+            }
+            else if (line.hasOption("eyeblinkboth")) {
+                robot.setHeadAnimation(HeadAnimations.EYEBLINK_BOTH, 1000, 1, 1.0f, true);
+            }
+            else if (line.hasOption("eyebrowsraise")) {
+                robot.setHeadAnimation(HeadAnimations.EYEBROWS_RAISE, 1000, 1, 1.0f, true);
+            }
+            else if (line.hasOption("eyebrowslower")) {
+                robot.setHeadAnimation(HeadAnimations.EYEBROWS_LOWER, 1000, 1, 1.0f, true);
+            }
+            else if (line.hasOption("default")) {
+                robot.setDefaultEmotion(Emotions.NEUTRAL, true);
+            }
+            else if (line.hasOption("sad")) {
+                robot.setCurrentEmotion(Emotions.SAD, 1000, true);
+            }
+            else if (line.hasOption("happy")) {
+                robot.setCurrentEmotion(Emotions.HAPPY, 1000, true);
+            }
+            else if (line.hasOption("neutral")) {
+                robot.setCurrentEmotion(Emotions.NEUTRAL, 1000, true);
+            }
+            else if (line.hasOption("angry")) {
+                robot.setCurrentEmotion(Emotions.ANGRY, 1000, true);
+            }
+            else if (line.hasOption("surprised")) {
+                robot.setCurrentEmotion(Emotions.SURPRISED, 1000, true);
+            }
+            else if (line.hasOption("fear")) {
+                robot.setCurrentEmotion(Emotions.FEAR, 1000, true);
+            }else{
+                System.out.println("--> Invalid Command "+line.toString());
+            }
+            
+            // This is currently mandatory due to
+            // the RSB RemoteServer implementation
+            robot.mw.deactivateServer();
+        } catch (InterruptedException ex) {
+            // Logger.getLogger(Cmd.class.getName()).log(Level.SEVERE, null, ex);
+            System.out.println("Unrecognized Option. Exiting...");
+        }
+    }
+}
diff --git a/client/java/src/test/java/HlrcClientTests.java b/client/java/src/test/java/HlrcClientTests.java
new file mode 100644
index 0000000..f5a8991
--- /dev/null
+++ b/client/java/src/test/java/HlrcClientTests.java
@@ -0,0 +1,100 @@
+/*
+* This file is part of hlrc_client_java
+*
+* Copyright(c) {flier,sschulz} <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+import de.uni-bielefeld.cit-ec.opensource.hlrc.client.HeadAnimations;
+import de.uni-bielefeld.cit-ec.opensource.hlrc.client.Emotions;
+import de.uni-bielefeld.cit-ec.opensource.hlrc.client.RobotController;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+
+/**
+ *
+ * @author flier
+ */
+public class HlrcClientTests {
+    
+    RobotController r;
+    
+    public HlrcClientTests() {
+        //
+    }
+    
+    @BeforeClass
+    public static void setUpClass() {
+        System.out.println("* HLRC CLIENT TESTS: @BeforeClass method");
+    }
+    
+    @AfterClass
+    public static void tearDownClass() {
+        System.out.println("* HLRC CLIENT TESTS: @AfterClass method");
+    }
+    
+    @Before
+    public void setUp() {
+        this.r = new Robot("/home/kitchen/flobi", "RSB");
+        System.out.println("* HLRC CLIENT TESTS: @Before method");
+    }
+    
+    @After
+    public void tearDown() {
+        System.out.println("* HLRC CLIENT TESTS: @After method");
+    }
+
+    @Test
+    public void testConstructor() {
+        System.out.println("Constructor");
+        
+        assertEquals("TestRobot", this.r.getRobotName());
+        assertEquals("RSB", r.getMiddleware());
+    }
+    
+    @Test
+    public void testGazeMsgCreation() {
+        System.out.println("RPC Calls");
+        this.r.mw.createGazeTargetMessage(70.0f, 50.0f, 40.0f);
+    }
+    
+    @Test
+    public void testHeadMsgCreation() {
+        System.out.println("Head Message");
+        this.r.mw.createHeadAnimationMessage(HeadAnimations.HEAD_NOD, 1000, 1, 1.0f);
+    }
+    
+    @Test
+    public void testEmotionCreation() {
+        System.out.println("Emotion Message");
+        this.r.mw.createEmotionMessage(Emotions.SAD, 1000);
+    }
+    
+}
diff --git a/client/python/DESCRIPTION.rst b/client/python/DESCRIPTION.rst
new file mode 100644
index 0000000..81cf6e3
--- /dev/null
+++ b/client/python/DESCRIPTION.rst
@@ -0,0 +1,4 @@
+[h]igh [l]evel [r]obot [c]ontrol client project
+=======================
+
+This is the python implementation of the hlrc_client
diff --git a/client/python/MANIFEST.in b/client/python/MANIFEST.in
new file mode 100644
index 0000000..2d84873
--- /dev/null
+++ b/client/python/MANIFEST.in
@@ -0,0 +1,8 @@
+include DESCRIPTION.rst
+
+# Include the test suite (FIXME: does not work yet)
+# recursive-include tests *
+
+# If using Python 2.6 or less, then have to include package data, even though
+# it's already declared in setup.py
+include hlrc/*.dat
diff --git a/client/python/README.rst b/client/python/README.rst
new file mode 100644
index 0000000..81cf6e3
--- /dev/null
+++ b/client/python/README.rst
@@ -0,0 +1,4 @@
+[h]igh [l]evel [r]obot [c]ontrol client project
+=======================
+
+This is the python implementation of the hlrc_client
diff --git a/client/python/a/test.py b/client/python/a/test.py
new file mode 100644
index 0000000..94015f4
--- /dev/null
+++ b/client/python/a/test.py
@@ -0,0 +1,54 @@
+"""
+This file is part of hlrc
+
+Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+http://opensource.cit-ec.de/projects/hlrc
+
+This file may be licensed under the terms of the
+GNU General Public License Version 3 (the ``GPL''),
+or (at your option) any later version.
+
+Software distributed under the License is distributed
+on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+express or implied. See the GPL for the specific language
+governing rights and limitations.
+
+You should have received a copy of the GPL along with this
+program. If not, go to http://www.gnu.org/licenses/gpl.html
+or write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+The development of this software was supported by the
+Excellence Cluster EXC 277 Cognitive Interaction Technology.
+The Excellence Cluster EXC 277 is a grant of the Deutsche
+Forschungsgemeinschaft (DFG) in the context of the German
+Excellence Initiative.
+"""
+
+import logging
+from hlrc_client import *
+import time
+import sys
+
+if __name__ == "__main__":
+	
+	
+	
+	r = RobotController("RSB", "/flobi", logging.DEBUG)
+	
+	
+	r.set_current_emotion(RobotEmotion(RobotEmotion.SAD))
+	r.set_head_animation(RobotAnimation(RobotAnimation.HEAD_SHAKE))
+	r.set_speak("test 123")
+	
+	g = RobotGaze()
+	
+	while(True):
+		g.pan = g.pan + 5.0;
+		if (g.pan > 20.0):
+			g.pan = -20.0
+		r.set_gaze_target(g)
+		time.sleep(1)
+	#e = RobotAnimation()
+	#print e
+	
diff --git a/client/python/dist/hlrc_client-1.2.0-py2.7.egg b/client/python/dist/hlrc_client-1.2.0-py2.7.egg
new file mode 100644
index 0000000..514d37b
Binary files /dev/null and b/client/python/dist/hlrc_client-1.2.0-py2.7.egg differ
diff --git a/client/python/hlrc_client.egg-info/PKG-INFO b/client/python/hlrc_client.egg-info/PKG-INFO
new file mode 100644
index 0000000..b863850
--- /dev/null
+++ b/client/python/hlrc_client.egg-info/PKG-INFO
@@ -0,0 +1,26 @@
+Metadata-Version: 1.1
+Name: hlrc-client
+Version: 1.2.0
+Summary: [h]igh [l]evel [r]obot [c]ontrol client project
+Home-page: http://opensource.cit-ec.uni-bielefeld.de/hlrc
+Author: Simon Schulz
+Author-email: sschulz@techfak.uni-bielefeld.de
+License: GPLv3
+Description: [h]igh [l]evel [r]obot [c]ontrol client project
+        =======================
+        
+        This is the python implementation of the hlrc_client
+        
+Keywords: sample setuptools development
+Platform: UNKNOWN
+Classifier: Development Status :: 3 - Alpha
+Classifier: Intended Audience :: Developers
+Classifier: Topic :: Scientific/Engineering
+Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
diff --git a/client/python/hlrc_client.egg-info/SOURCES.txt b/client/python/hlrc_client.egg-info/SOURCES.txt
new file mode 100644
index 0000000..9572210
--- /dev/null
+++ b/client/python/hlrc_client.egg-info/SOURCES.txt
@@ -0,0 +1,24 @@
+DESCRIPTION.rst
+MANIFEST.in
+README.rst
+setup.cfg
+setup.py
+hlrc_client/Middleware.py
+hlrc_client/MiddlewareRSB.py
+hlrc_client/RobotAnimation.py
+hlrc_client/RobotController.py
+hlrc_client/RobotEmotion.py
+hlrc_client/RobotGaze.py
+hlrc_client/RobotMouth.py
+hlrc_client/__init__.py
+hlrc_client/hlrc_play_animation.py
+hlrc_client/hlrc_set_emotion.py
+hlrc_client/hlrc_speak_utterance.py
+hlrc_client/hlrc_test_gui.py
+hlrc_client/textgrid_hlrc.py
+hlrc_client.egg-info/PKG-INFO
+hlrc_client.egg-info/SOURCES.txt
+hlrc_client.egg-info/dependency_links.txt
+hlrc_client.egg-info/entry_points.txt
+hlrc_client.egg-info/requires.txt
+hlrc_client.egg-info/top_level.txt
\ No newline at end of file
diff --git a/client/python/hlrc_client.egg-info/dependency_links.txt b/client/python/hlrc_client.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/client/python/hlrc_client.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/client/python/hlrc_client.egg-info/entry_points.txt b/client/python/hlrc_client.egg-info/entry_points.txt
new file mode 100644
index 0000000..3e1605a
--- /dev/null
+++ b/client/python/hlrc_client.egg-info/entry_points.txt
@@ -0,0 +1,3 @@
+[console_scripts]
+
+
diff --git a/client/python/hlrc_client.egg-info/requires.txt b/client/python/hlrc_client.egg-info/requires.txt
new file mode 100644
index 0000000..5026bf1
--- /dev/null
+++ b/client/python/hlrc_client.egg-info/requires.txt
@@ -0,0 +1,7 @@
+peppercorn
+
+[test]
+coverage
+
+[dev]
+check-manifest
\ No newline at end of file
diff --git a/client/python/hlrc_client.egg-info/top_level.txt b/client/python/hlrc_client.egg-info/top_level.txt
new file mode 100644
index 0000000..7087258
--- /dev/null
+++ b/client/python/hlrc_client.egg-info/top_level.txt
@@ -0,0 +1 @@
+hlrc_client
diff --git a/client/python/hlrc_client/Middleware.py b/client/python/hlrc_client/Middleware.py
new file mode 100644
index 0000000..b254ada
--- /dev/null
+++ b/client/python/hlrc_client/Middleware.py
@@ -0,0 +1,146 @@
+"""
+This file is part of hlrc
+
+Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+http://opensource.cit-ec.de/projects/hlrc
+
+This file may be licensed under the terms of the
+GNU General Public License Version 3 (the ``GPL''),
+or (at your option) any later version.
+
+Software distributed under the License is distributed
+on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+express or implied. See the GPL for the specific language
+governing rights and limitations.
+
+You should have received a copy of the GPL along with this
+program. If not, go to http://www.gnu.org/licenses/gpl.html
+or write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+The development of this software was supported by the
+Excellence Cluster EXC 277 Cognitive Interaction Technology.
+The Excellence Cluster EXC 277 is a grant of the Deutsche
+Forschungsgemeinschaft (DFG) in the context of the German
+Excellence Initiative.
+"""
+
+import sys
+import logging
+from RobotEmotion import *
+from RobotGaze import *
+from RobotMouth import *
+from RobotAnimation import *
+
+class Middleware:
+	#######################################################################
+	def __init__(self, scope, loglevel=logging.WARNING):
+		"""initialise
+		:param scope: base scope we want to listen on 
+		"""
+		self.base_scope = scope
+		
+		self.logger = logging.getLogger(__name__)
+		
+		# create nice and actually usable formatter and add it to the handler
+		self.config_logger(loglevel)
+		
+		#initialise defaults
+		self.default_emotion = RobotEmotion()
+		self.current_emotion = RobotEmotion()
+		self.gaze_target = RobotGaze()
+		self.mouth_target = RobotMouth()
+		self.robot_animation = RobotAnimation()
+		
+	
+	def config_logger(self, level):
+		formatter = logging.Formatter('%(asctime)s %(name)-30s %(levelname)-8s > %(message)s')
+		ch = logging.StreamHandler()
+		#ch.setLevel(level)
+		ch.setFormatter(formatter)
+		self.logger.setLevel(level)
+		self.logger.addHandler(ch)
+	
+	#######################################################################
+        #abstract/virtual functions
+        def die_virtual(self, funcname):
+		raise NotImplementedError(funcname + "() is virtual, must be overwritten")
+	
+	def init_middleware(self):
+		self.die_virtual(sys._getframe().f_code.co_name)
+	
+	def publish_default_emotion(self, emotion, blocking):
+		self.die_virtual(sys._getframe().f_code.co_name)
+	
+	def publish_current_emotion(self, emotion, blocking):
+		self.die_virtual(sys._getframe().f_code.co_name)
+	
+	def publish_gaze_target(self, gaze, blocking):
+		self.die_virtual(sys._getframe().f_code.co_name)
+	
+	def publish_mouth_target(self, mouth, blocking):
+		self.die_virtual(sys._getframe().f_code.co_name)
+	
+	def publish_head_animation(self, animation, blocking):
+		self.die_virtual(sys._getframe().f_code.co_name)
+	
+	def publish_speech(self, text, blocking):
+		self.die_virtual(sys._getframe().f_code.co_name)
+	
+	#######################################################################
+        #finally some implemented functions
+        def set_default_emotion(self, emotion, blocking):
+		"""set the default emotion
+		:param emotion: RobotEmotion to set 
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		self.default_emotion = emotion
+		self.publish_default_emotion(emotion, blocking)
+		
+	def set_current_emotion(self, emotion, blocking):
+		"""set a temporary emotion (duration: see emotion.time_ms)
+		:param emotion: RobotEmotion to set temporarily
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		self.current_emotion = emotion
+		self.publish_current_emotion(emotion, blocking)
+	
+	def set_head_animation(self, animation, blocking):
+		"""trigger a head animation
+		:param animation: RobotAnimation to set
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		self.animation = animation
+		self.publish_head_animation(animation, blocking)
+	
+	def set_mouth_target(self, mouth, blocking):
+		"""set a mouth target
+		:param mouth: RobotMouth to set
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		self.mouth_target = mouth
+		self.publish_mouth_target(mouth, blocking)
+
+	def set_speak(self, text, blocking):
+		"""trigger a tts speech output
+		:param text: text to synthesize and speak
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		self.publish_speech(text, blocking)
+	
+	def set_gaze_target(self, gaze, blocking):
+		"""set a new gaze 
+		:param gaze: RobotGaze to set
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		self.gaze_target = gaze
+		self.publish_gaze_target(gaze, blocking)
+		
+	#######################################################################
+	#some get methods
+	#def get_current_emotion(self):
+	#	return self.current_emotion
+	#
+	#def get_default_emotion(self):
+	#	return self.default_emotion
+	#
\ No newline at end of file
diff --git a/client/python/hlrc_client/MiddlewareROS.py b/client/python/hlrc_client/MiddlewareROS.py
new file mode 100644
index 0000000..bd54ea5
--- /dev/null
+++ b/client/python/hlrc_client/MiddlewareROS.py
@@ -0,0 +1,278 @@
+"""
+This file is part of hlrc
+
+Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+http://opensource.cit-ec.de/projects/hlrc
+
+This file may be licensed under the terms of the
+GNU General Public License Version 3 (the ``GPL''),
+or (at your option) any later version.
+
+Software distributed under the License is distributed
+on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+express or implied. See the GPL for the specific language
+governing rights and limitations.
+
+You should have received a copy of the GPL along with this
+program. If not, go to http://www.gnu.org/licenses/gpl.html
+or write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+The development of this software was supported by the
+Excellence Cluster EXC 277 Cognitive Interaction Technology.
+The Excellence Cluster EXC 277 is a grant of the Deutsche
+Forschungsgemeinschaft (DFG) in the context of the German
+Excellence Initiative.
+"""
+
+from Middleware import *
+import errno
+
+try:
+	import roslib; 
+	
+	import rospy 
+	import actionlib
+	from hlrc_server.msg import *
+    
+except ImportError as exception:
+	sys.stderr.write("ImportError: {}\n> HINT: try to export PYTHONPATH=$PYTHONPATH:$YOUR_PREFIX/lib/python2.7/site-packages/\n\n".format(exception))
+	sys.exit(errno.ENOPKG)
+
+class MiddlewareROS(Middleware):
+	#default timeout to wait in case of blocking calls
+	ROS_ACTION_CALL_TIMEOUT = 30.0
+	
+	#######################################################################
+	def __init__(self, scope, loglevel=logging.WARNING):
+		"""initialise
+		:param scope: base scope we want to listen on 
+		"""
+		#init base settings
+		Middleware.__init__(self,scope,loglevel)
+		#call mw init
+		self.init_middleware()
+		
+	#######################################################################
+        def init_middleware(self):
+		"""initialise middleware
+		"""
+		self.logger.info("initialising ROS middleware connection on scope %s" % (self.base_scope))
+		
+		rospy.init_node('hlrc_client', anonymous=True)
+		
+		self.logger.info("creating action clients")
+		
+		self.logger.debug("creating speech action client")
+		self.speech_client = actionlib.SimpleActionClient(self.base_scope + "/set/speech", speechAction)
+		self.speech_client.wait_for_server()
+		
+		self.logger.debug("creating default emotion action client")
+		self.default_emotion_client = actionlib.SimpleActionClient(self.base_scope + "/set/defaultEmotion", emotionstateAction)
+		self.default_emotion_client.wait_for_server()
+		
+		self.logger.debug("creating current emotion action client")
+		self.current_emotion_client = actionlib.SimpleActionClient(self.base_scope + "/set/currentEmotion", emotionstateAction)
+		self.current_emotion_client.wait_for_server()
+		
+		self.logger.debug("creating animation action client")
+		self.animation_client = actionlib.SimpleActionClient(self.base_scope + "/set/animation", animationAction)
+		self.animation_client.wait_for_server()
+		
+		self.logger.debug("creating gazetarget action client")
+		self.gazetarget_client = actionlib.SimpleActionClient(self.base_scope + "/set/gaze", gazetargetAction)
+		self.gazetarget_client.wait_for_server()
+		
+		self.logger.debug("creating mouthtarget action client")
+		self.mouthtarget_client = actionlib.SimpleActionClient(self.base_scope + "/set/mouth", mouthtargetAction)
+		self.mouthtarget_client.wait_for_server()
+		
+		self.logger.info("MiddlewareROS initialised")
+		
+
+	#######################################################################
+	def publish_emotion(self, em_type, emotion, blocking):
+		"""publish an emotion via mw
+		:param em_type: type of emotion (RobotEmotion::TYPE_DEFAULT or RobotEmotion::TYPE_CURRENT)
+		:param emotion: emotion to set
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		self.logger.debug("calling the emotion rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
+		
+		#create a goal to send to the action server.
+		goal = emotionstateGoal()
+		goal.value    = self.convert_emotiontype_to_rosval(emotion.value)
+		goal.duration =  int(emotion.time_ms)
+		
+		#which client do we use?
+		if (em_type == RobotEmotion.TYPE_DEFAULT):
+			client = self.default_emotion_client
+		else:
+			client = self.current_emotion_client
+		
+		#send the goal to the server
+		client.send_goal(goal)
+		
+		#wait for the server to finish 
+		if (blocking):
+			timed_out = client.wait_for_result(rospy.Duration.from_sec(MiddlewareROS.ROS_ACTION_CALL_TIMEOUT))
+			if (timed_out):
+				self.logger.error("%s timed out waiting for result" % (sys._getframe().f_code.co_name))
+		
+	def publish_default_emotion(self, emotion, blocking):
+		self.publish_emotion(RobotEmotion.TYPE_DEFAULT, emotion, blocking)
+	
+	def publish_current_emotion(self, emotion, blocking):
+		self.publish_emotion(RobotEmotion.TYPE_CURRENT, emotion, blocking)
+	
+	def publish_head_animation(self, animation, blocking):
+		"""publish an head animation via mw
+		:param animation: animation to set
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		self.logger.debug("calling the animation rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
+		
+		#create a goal to send to the action server.
+		goal = animationGoal()
+		goal.target = self.convert_animationtype_to_rosval(animation.value)
+		goal.repetitions = animation.repetitions
+		goal.duration_each =  int(animation.time_ms)
+		goal.scale = animation.scale
+		
+		#send the goal to the server
+		self.animation_client.send_goal(goal)
+		
+		#wait for the server to finish 
+		if (blocking):
+			timed_out = self.animation_client.wait_for_result(rospy.Duration.from_sec(MiddlewareROS.ROS_ACTION_CALL_TIMEOUT))
+			if (timed_out):
+				self.logger.error("%s timed out waiting for result" % (sys._getframe().f_code.co_name))
+		
+		self.logger.debug("animation rpc done")
+	
+	def publish_gaze_target(self, gaze, blocking):
+		"""publish a gaze target via mw
+		:param gaze: gaze to set
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		self.logger.debug("calling the gaze rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
+		
+		#create a goal to send to the action server.
+		goal = gazetargetGoal()
+		goal.pan  = gaze.pan
+		goal.tilt = gaze.tilt
+		goal.roll = gaze.roll
+		goal.vergence = gaze.vergence
+		goal.pan_offset  = gaze.pan_offset
+		goal.tilt_offset = gaze.tilt_offset
+		
+		#send the goal to the server
+		self.gazetarget_client.send_goal(goal)
+		
+		#wait for the server to finish 
+		if (blocking):
+			timed_out = self.gazetarget_client.wait_for_result(rospy.Duration.from_sec(MiddlewareROS.ROS_ACTION_CALL_TIMEOUT))
+			if (timed_out):
+				self.logger.error("%s timed out waiting for result" % (sys._getframe().f_code.co_name))
+		
+		
+		self.logger.debug("gaze rpc done")
+	
+	def publish_mouth_target(self, mouth, blocking):
+		"""publish a mouth target via mw
+		:param mouth: mouth value to set
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		self.logger.debug("calling the mouth rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
+		
+		#create a goal to send to the action server.
+		goal = mouthtargetGoal()
+		goal.opening_left  = mouth.opening_left
+		goal.opening_center = mouth.opening_center
+		goal.opening_right = mouth.opening_right
+		goal.position_left = mouth.position_left
+		goal.position_center  = mouth.position_center
+		goal.position_right = mouth.position_right
+		
+		#send the goal to the server
+		self.mouthtarget_client.send_goal(goal)
+		
+		#wait for the server to finish 
+		if (blocking):
+			timed_out = self.mouthtarget_client.wait_for_result(rospy.Duration.from_sec(MiddlewareROS.ROS_ACTION_CALL_TIMEOUT))
+			if (timed_out):
+				self.logger.error("%s timed out waiting for result" % (sys._getframe().f_code.co_name))
+		
+		self.logger.debug("mouth rpc done")
+	
+	def publish_speech(self, text_, blocking):
+		"""publish a tts request via mw
+		:param text_: text to synthesize and speak
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		self.logger.debug("calling the speech rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
+		
+		#create a goal to send to the action server.
+		goal = speechGoal(text=text_)
+		
+		#send the goal to the server
+		self.speech_client.send_goal(goal)
+		
+		#wait for the server to finish 
+		if (blocking):
+			timed_out = self.speech_client.wait_for_result(rospy.Duration.from_sec(MiddlewareROS.ROS_ACTION_CALL_TIMEOUT))
+			if (timed_out):
+				self.logger.error("%s timed out waiting for result" % (sys._getframe().f_code.co_name))
+				
+		self.logger.debug("speech rpc done")
+	
+	#######################################################################
+	# some helpers
+	def convert_animationtype_to_rosval(self, value):
+		"""convert RobotAnimation.value to ROS animation value
+		:param value: RobotAnimation.* id to convert to rsb id
+		"""
+		#NOTE: this convertion is important as the actual integer values of
+		#      thy python api and the protobuf might be different
+		if (value == RobotAnimation.IDLE):
+			return animationGoal.IDLE
+		elif (value == RobotAnimation.HEAD_NOD):
+			return animationGoal.HEAD_NOD
+		elif (value == RobotAnimation.HEAD_SHAKE):
+			return animationGoal.HEAD_SHAKE
+		elif (value == RobotAnimation.EYEBLINK_L):
+			return animationGoal.EYEBLINK_L
+		elif (value == RobotAnimation.EYEBLINK_R):
+			return  animationGoal.EYEBLINK_R
+		elif (value == RobotAnimation.EYEBLINK_BOTH):
+			return  animationGoal.EYEBLINK_BOTH
+		elif (value == RobotAnimation.EYEBROWS_RAISE):
+			return  animationGoal.EYEBROWS_RAISE
+		elif (value == RobotAnimation.EYEBROWS_LOWER):
+			return  animationGoal.EYEBROWS_LOWER
+		else:
+			self.logger.error("invalid animation type %d\n" % (value))
+			return  animationGoal.NEUTRAL
+		
+	def convert_emotiontype_to_rosval(self, value):
+		"""convert RobotEmotion.value to ROS animation value
+		:param value: RobotEmotion.* id to convert to ros id
+		"""
+		#NOTE: this convertion is important as the actual integer values of
+		#      thy python api and the protobuf might be different
+
+		if (value == RobotEmotion.NEUTRAL):
+			return emotionstateGoal.NEUTRAL
+		elif (value == RobotEmotion.HAPPY):
+			return emotionstateGoal.HAPPY
+		elif (value == RobotEmotion.SAD):
+			return emotionstateGoal.SAD
+		elif (value == RobotEmotion.ANGRY):
+			return emotionstateGoal.ANGRY
+		elif (value == RobotEmotion.SURPRISED):
+			return  emotionstateGoal.SURPRISED
+		elif (value == RobotEmotion.FEAR):
+			return emotionstateGoal.FEAR
+		else:
+			self.logger.error("invalid emotion type %d\n" % (value))
+			return  emotionstateGoal.NEUTRAL
\ No newline at end of file
diff --git a/client/python/hlrc_client/MiddlewareRSB.py b/client/python/hlrc_client/MiddlewareRSB.py
new file mode 100644
index 0000000..9c0442d
--- /dev/null
+++ b/client/python/hlrc_client/MiddlewareRSB.py
@@ -0,0 +1,283 @@
+"""
+This file is part of hlrc
+
+Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+http://opensource.cit-ec.de/projects/hlrc
+
+This file may be licensed under the terms of the
+GNU General Public License Version 3 (the ``GPL''),
+or (at your option) any later version.
+
+Software distributed under the License is distributed
+on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+express or implied. See the GPL for the specific language
+governing rights and limitations.
+
+You should have received a copy of the GPL along with this
+program. If not, go to http://www.gnu.org/licenses/gpl.html
+or write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+The development of this software was supported by the
+Excellence Cluster EXC 277 Cognitive Interaction Technology.
+The Excellence Cluster EXC 277 is a grant of the Deutsche
+Forschungsgemeinschaft (DFG) in the context of the German
+Excellence Initiative.
+"""
+
+from Middleware import *
+import errno
+
+try:
+    import rsb
+    import rsb.converter
+    import rst
+    import rstsandbox
+    from   rst.robot.EmotionState_pb2 import EmotionState
+    from   rst.robot.Animation_pb2    import Animation
+    from   rst.robot.GazeTarget_pb2   import GazeTarget
+    from   rst.robot.MouthTarget_pb2  import MouthTarget
+    
+except ImportError as exception:
+    sys.stderr.write("ImportError: {}\n> HINT: try to export PYTHONPATH=$PYTHONPATH:$YOUR_PREFIX/lib/python2.7/site-packages/\n\n".format(exception))
+    sys.exit(errno.ENOPKG)
+
+class MiddlewareRSB(Middleware):
+	#######################################################################
+	def __init__(self, scope, loglevel=logging.WARNING):
+		"""initialise
+		:param scope: base scope we want to listen on 
+		"""
+		#init base settings
+		Middleware.__init__(self,scope,loglevel)
+		#call mw init
+		self.init_middleware()
+		
+	#######################################################################
+        def init_middleware(self):
+		"""initialise middleware
+		"""
+		#mute rsb logging:
+		logging.getLogger("rsb").setLevel(logging.ERROR)
+		
+		#initialise RSB stuff
+		self.logger.info("initialising RSB middleware connection on scope %s, registering rst converters..." % (self.base_scope))
+		
+		self.emotionstate_converter = rsb.converter.ProtocolBufferConverter(messageClass = EmotionState)
+		rsb.converter.registerGlobalConverter(self.emotionstate_converter)
+		
+		self.animation_converter = rsb.converter.ProtocolBufferConverter(messageClass = Animation)
+		rsb.converter.registerGlobalConverter(self.animation_converter)
+		
+		self.gaze_converter = rsb.converter.ProtocolBufferConverter(messageClass = GazeTarget)
+		rsb.converter.registerGlobalConverter(self.gaze_converter)
+
+		self.mouth_converter = rsb.converter.ProtocolBufferConverter(messageClass = MouthTarget)
+		rsb.converter.registerGlobalConverter(self.mouth_converter)
+
+		try:
+			self.server = rsb.createRemoteServer(self.base_scope + '/set')
+		except ValueError:
+			self.logger.error("ERROR: invalid scope given. server deactivated")
+			self.server.deactivate()
+			sys.exit(errno.EINVAL)
+
+	#######################################################################
+	def publish_emotion(self, em_type, emotion, blocking):
+		"""publish an emotion via mw
+		:param em_type: type of emotion (RobotEmotion::TYPE_DEFAULT or RobotEmotion::TYPE_CURRENT)
+		:param emotion: emotion to set
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		
+		#create emotion & fill it with values:
+		rsb_em = EmotionState()
+
+		#set value
+		rsb_em.value = self.convert_emotiontype_to_rsbval(emotion.value)
+		
+		#set duration
+		rsb_em.duration = int(emotion.time_ms)
+
+		with rsb.createRemoteServer(self.base_scope + '/set') as server:
+			self.logger.debug("calling the emotion rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
+				
+			if (blocking):
+				#blocking rpc call:
+				if (em_type == RobotEmotion.TYPE_DEFAULT):
+					result = server.defaultEmotion(rsb_em)
+				else:
+					result = server.currentEmotion(rsb_em)
+					
+				self.logger.debug("server reply: '%s'" % result)
+			else:
+				if (em_type == RobotEmotion.TYPE_DEFAULT):
+					future = server.defaultEmotion.async(rsb_em)
+				else:
+					future = server.currentEmotion.async(rsb_em)
+			
+				#we could block here for a incoming result with a timeout in s
+				#print '> server reply: "%s"' % future.get(timeout = 10);
+			self.logger.debug("emotion rpc done")
+	
+	def publish_head_animation(self, animation, blocking):
+		"""publish an head animation via mw
+		:param animation: animation to set
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		
+		self.logger.debug("calling the animation rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
+		
+		#create animation & fill it with values:
+		rsb_ani = Animation()
+	
+		#select ani
+		rsb_ani.target = self.convert_animationtype_to_rsbval(animation.value)
+		rsb_ani.repetitions = animation.repetitions
+		rsb_ani.duration_each = animation.time_ms
+		rsb_ani.scale       = animation.scale
+	
+		if (blocking):
+			#blocking:
+			result = self.server.animation(rsb_ani)
+			self.logger.debug("server reply: '%s'" % result)
+		else:
+			future = self.server.animation.async(rsb_ani)
+			#we can block here for a incoming result with a timeout in s
+			#print '> server reply: "%s"' % future.get(timeout = 10);
+		
+		self.logger.debug("animation rpc done")
+	
+	def publish_default_emotion(self, emotion, blocking):
+		self.publish_emotion(RobotEmotion.TYPE_DEFAULT, emotion, blocking)
+	
+	def publish_current_emotion(self, emotion, blocking):
+		self.publish_emotion(RobotEmotion.TYPE_CURRENT, emotion, blocking)
+	
+	def publish_gaze_target(self, gaze, blocking):
+		"""publish a gaze target via mw
+		:param gaze: gaze to set
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		self.logger.debug("calling the gaze rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
+		
+		#create gaze target & fill it with values:
+		rsb_gaze = GazeTarget()
+	
+		#fill proto
+		rsb_gaze.pan  = gaze.pan
+		rsb_gaze.tilt = gaze.tilt
+		rsb_gaze.roll = gaze.roll
+		rsb_gaze.vergence = gaze.vergence
+		rsb_gaze.pan_offset  = gaze.pan_offset
+		rsb_gaze.tilt_offset = gaze.tilt_offset
+		
+		if (blocking):
+			#blocking:
+			result = self.server.gaze(rsb_gaze)
+			self.logger.debug("server reply: '%s'" % result)
+		else:
+			future = self.server.gaze.async(rsb_gaze)
+			#we can block here for a incoming result with a timeout in s
+			#print '> server reply: "%s"' % future.get(timeout = 10);
+		
+		self.logger.debug("gaze rpc done")
+	
+	def publish_mouth_target(self, mouth, blocking):
+		"""publish a mouth target via mw
+		:param mouth: mouth value to set
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		self.logger.debug("calling the mouth rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
+		
+		#create mouth state & fill it with values:
+		rsb_mouth = MouthTarget()
+		
+		#fill proto
+		rsb_mouth.opening_left   = mouth.opening_left
+		rsb_mouth.opening_center = mouth.opening_center
+		rsb_mouth.opening_right  = mouth.opening_right
+		rsb_mouth.position_left  = mouth.position_left
+		rsb_mouth.position_center = mouth.position_center
+		rsb_mouth.position_right = mouth.position_right
+		
+		if (blocking):
+			#blocking:
+			result = self.server.mouth(rsb_mouth)
+			self.logger.debug("server reply: '%s'" % result)
+		else:
+			future = self.server.mouth.async(rsb_mouth)
+			#we can block here for a incoming result with a timeout in s
+			#print '> server reply: "%s"' % future.get(timeout = 10);
+		
+		self.logger.debug("mouth rpc done")
+	
+	def publish_speech(self, text, blocking):
+		"""publish a tts request via mw
+		:param text: text to synthesize and speak
+		:param blocking: True if this call should block until execution finished on robot
+		"""
+		self.logger.debug("calling the speech rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
+		
+		if (blocking):
+			#blocking:
+			result = self.server.speech(text)
+			self.logger.debug("server reply: '%s'" % result)
+		else:
+			future = self.server.speech.async(text)
+			#we can block here for a incoming result with a timeout in s
+			#print '> server reply: "%s"' % future.get(timeout = 10);
+		
+		self.logger.debug("speech rpc done")
+	
+	#######################################################################
+	# some helpers
+	def convert_animationtype_to_rsbval(self, value):
+		"""convert RobotAnimation.value to RSB animation value
+		:param value: RobotAnimation.* id to convert to rsb id
+		"""
+		#NOTE: this convertion is important as the actual integer values of
+		#      thy python api and the protobuf might be different
+
+		if (value == RobotAnimation.IDLE):
+			return Animation().IDLE
+		elif (value == RobotAnimation.HEAD_NOD):
+			return Animation().HEAD_NOD
+		elif (value == RobotAnimation.HEAD_SHAKE):
+			return Animation().HEAD_SHAKE
+		elif (value == RobotAnimation.EYEBLINK_L):
+			return Animation().EYEBLINK_L
+		elif (value == RobotAnimation.EYEBLINK_R):
+			return  Animation().EYEBLINK_R
+		elif (value == RobotAnimation.EYEBLINK_BOTH):
+			return  Animation().EYEBLINK_BOTH
+		elif (value == RobotAnimation.EYEBROWS_RAISE):
+			return  Animation().EYEBROWS_RAISE
+		elif (value == RobotAnimation.EYEBROWS_LOWER):
+			return  Animation().EYEBROWS_LOWER
+		else:
+			self.logger.error("invalid animation type %d\n" % (value))
+			return  Animation().NEUTRAL
+		
+	def convert_emotiontype_to_rsbval(self, value):
+		"""convert RobotEmotion.value to RSB animation value
+		:param value: RobotEmotion.* id to convert to rsb id
+		"""
+		#NOTE: this convertion is important as the actual integer values of
+		#      thy python api and the protobuf might be different
+
+		if (value == RobotEmotion.NEUTRAL):
+			return EmotionState().NEUTRAL
+		elif (value == RobotEmotion.HAPPY):
+			return EmotionState().HAPPY
+		elif (value == RobotEmotion.SAD):
+			return EmotionState().SAD
+		elif (value == RobotEmotion.ANGRY):
+			return EmotionState().ANGRY
+		elif (value == RobotEmotion.SURPRISED):
+			return  EmotionState().SURPRISED
+		elif (value == RobotEmotion.FEAR):
+			return EmotionState().FEAR
+		else:
+			self.logger.error("invalid emotion type %d\n" % (value))
+			return  EmotionState().NEUTRAL
\ No newline at end of file
diff --git a/client/python/hlrc_client/RobotAnimation.py b/client/python/hlrc_client/RobotAnimation.py
new file mode 100644
index 0000000..809d77f
--- /dev/null
+++ b/client/python/hlrc_client/RobotAnimation.py
@@ -0,0 +1,66 @@
+"""
+This file is part of hlrc
+
+Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+http://opensource.cit-ec.de/projects/hlrc
+
+This file may be licensed under the terms of the
+GNU General Public License Version 3 (the ``GPL''),
+or (at your option) any later version.
+
+Software distributed under the License is distributed
+on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+express or implied. See the GPL for the specific language
+governing rights and limitations.
+
+You should have received a copy of the GPL along with this
+program. If not, go to http://www.gnu.org/licenses/gpl.html
+or write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+The development of this software was supported by the
+Excellence Cluster EXC 277 Cognitive Interaction Technology.
+The Excellence Cluster EXC 277 is a grant of the Deutsche
+Forschungsgemeinschaft (DFG) in the context of the German
+Excellence Initiative.
+"""
+
+class RobotAnimation:
+	IDLE            = 0
+	HEAD_NOD        = 1
+	HEAD_SHAKE      = 2
+	EYEBLINK_L      = 3
+	EYEBLINK_R      = 4
+	EYEBLINK_BOTH   = 5
+	EYEBROWS_RAISE  = 6
+	EYEBROWS_LOWER  = 7
+
+	def __init__(self, v = IDLE):
+		self.value = v
+		self.time_ms = 1000
+		self.repetitions = 1
+		self.scale = 1.0
+
+	def value_as_str(self):
+		if (self.value == RobotAnimation.IDLE):
+			return "idle"
+		elif (self.value == RobotAnimation.HEAD_NOD):
+			return "head nod"
+		elif (self.value == RobotAnimation.HEAD_SHAKE):
+			return "head shake"
+		elif (self.value == RobotAnimation.EYEBLINK_L):
+			return "eyeblink l"
+		elif (self.value == RobotAnimation.EYEBLINK_R):
+			return "eyeblink r"
+		elif (self.value == RobotAnimation.EYEBROWS_RAISE):
+			return "eyebrows raise"
+		elif (self.value == RobotAnimation.EYEBROWS_LOWER):
+			return "eyebrows lower"
+		else:
+			return "INVALID ANIMATION TYPE"
+		
+	def __str__(self):
+		return "RobotAnimation = { value='%s', time_ms=%d repetitions=%d scale=%6.2f }" % \
+			(self.value_as_str(), self.time_ms, self.repetitions, self.scale)
+
+
diff --git a/client/python/hlrc_client/RobotController.py b/client/python/hlrc_client/RobotController.py
new file mode 100644
index 0000000..19a9c37
--- /dev/null
+++ b/client/python/hlrc_client/RobotController.py
@@ -0,0 +1,87 @@
+"""
+This file is part of hlrc
+
+Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+http://opensource.cit-ec.de/projects/hlrc
+
+This file may be licensed under the terms of the
+GNU General Public License Version 3 (the ``GPL''),
+or (at your option) any later version.
+
+Software distributed under the License is distributed
+on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+express or implied. See the GPL for the specific language
+governing rights and limitations.
+
+You should have received a copy of the GPL along with this
+program. If not, go to http://www.gnu.org/licenses/gpl.html
+or write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+The development of this software was supported by the
+Excellence Cluster EXC 277 Cognitive Interaction Technology.
+The Excellence Cluster EXC 277 is a grant of the Deutsche
+Forschungsgemeinschaft (DFG) in the context of the German
+Excellence Initiative.
+"""
+
+import logging
+from MiddlewareRSB import *
+from MiddlewareROS import *
+
+class RobotController:
+	def __init__(self, mw_name, scope, loglevel=logging.WARNING):
+		self.logger = logging.getLogger(__name__)
+		
+		# create nice and actually usable formatter and add it to the handler
+		self.config_logger(loglevel)
+		
+		#store scope
+		self.scope = scope
+		
+		if (mw_name.upper() == "RSB"):
+			self.logger.info("creating new middleware connection via RSB")
+			self.middleware = MiddlewareRSB(self.scope, loglevel)
+		elif (mw_name.upper() == "ROS"):
+			self.logger.info("creating new middleware connection via ROS")
+			self.middleware = MiddlewareROS(self.scope, loglevel)
+		else:
+			self.logger.error("invalid middleware requested (%s). supported: {ROS, RSB}\n\n" % (mw_name))
+			sys.exit(errno.EINVAL)
+	
+	def config_logger(self, level):
+		formatter = logging.Formatter('%(asctime)s %(name)-30s %(levelname)-8s > %(message)s')
+		ch = logging.StreamHandler()
+		#ch.setLevel(level)
+		ch.setFormatter(formatter)
+		self.logger.setLevel(level)
+		self.logger.addHandler(ch)
+
+	def set_current_emotion(self, robot_emotion, blocking = False):
+		self.logger.debug("set_current_emotion(%s) %s" % (robot_emotion, ("BLOCKING" if blocking else "NON_BLOCKING")))
+		self.middleware.set_current_emotion(robot_emotion, blocking)
+		
+	def set_default_emotion(self, robot_emotion, blocking = False):
+		self.logger.debug("set_default_emotion(%s) %s" % (robot_emotion, ("BLOCKING" if blocking else "NON_BLOCKING")))
+		self.middleware.set_default_emotion(robot_emotion, blocking)
+	
+	def set_gaze_target(self, robot_gaze, blocking = False):
+		self.logger.debug("set_gaze_target(%s) %s" % (robot_gaze, ("BLOCKING" if blocking else "NON_BLOCKING")))
+		self.middleware.set_gaze_target(robot_gaze, blocking)
+	
+	def set_mouth_target(self, robot_mouth, blocking = False):
+		self.logger.debug("set_mouth_target(%s) %s" % (robot_mouth, ("BLOCKING" if blocking else "NON_BLOCKING")))
+		self.middleware.set_mouth_target(robot_mouth, blocking)
+	
+	def set_head_animation(self, robot_animation, blocking = False):
+		self.logger.debug("set_head_animation(%s) %s" % (robot_animation, ("BLOCKING" if blocking else "NON_BLOCKING")))
+		self.middleware.set_head_animation(robot_animation, blocking)
+	
+	def set_speak(self, text, blocking = False):
+		self.logger.debug("set_speak(%s) %s" % (text, ("BLOCKING" if blocking else "NON_BLOCKING")))
+		self.middleware.set_speak(text, blocking)
+
+	def get_gaze_target(self):
+		result = self.middleware.get_gaze_target()
+		self.logger.debug("get_gaze_target() returned %s" % (result))
+		return self.middleware.get_gaze_target()
diff --git a/client/python/hlrc_client/RobotEmotion.py b/client/python/hlrc_client/RobotEmotion.py
new file mode 100644
index 0000000..b1a0940
--- /dev/null
+++ b/client/python/hlrc_client/RobotEmotion.py
@@ -0,0 +1,61 @@
+"""
+This file is part of hlrc
+
+Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+http://opensource.cit-ec.de/projects/hlrc
+
+This file may be licensed under the terms of the
+GNU General Public License Version 3 (the ``GPL''),
+or (at your option) any later version.
+
+Software distributed under the License is distributed
+on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+express or implied. See the GPL for the specific language
+governing rights and limitations.
+
+You should have received a copy of the GPL along with this
+program. If not, go to http://www.gnu.org/licenses/gpl.html
+or write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+The development of this software was supported by the
+Excellence Cluster EXC 277 Cognitive Interaction Technology.
+The Excellence Cluster EXC 277 is a grant of the Deutsche
+Forschungsgemeinschaft (DFG) in the context of the German
+Excellence Initiative.
+"""
+
+class RobotEmotion:
+	TYPE_DEFAULT = 0
+	TYPE_CURRENT = 1
+	
+	NEUTRAL   = 0
+	HAPPY     = 1
+	SAD       = 2
+	ANGRY     = 3
+	SURPRISED = 4
+	FEAR      = 5
+
+	def __init__(self, emotion = NEUTRAL):
+		self.value = emotion
+		self.time_ms = 1000
+
+	def value_as_str(self):
+		if (self.value == RobotEmotion.NEUTRAL):
+			return "neutral"
+		elif (self.value == RobotEmotion.HAPPY):
+			return "happy"
+		elif (self.value == RobotEmotion.SAD):
+			return "sad"
+		elif (self.value == RobotEmotion.ANGRY):
+			return "angry"
+		elif (self.value == RobotEmotion.SURPRISED):
+			return "surprised"
+		elif (self.value == RobotEmotion.FEAR):
+			return "fear"
+		else:
+			return "INVALID EMOTION TYPE"
+		
+	def __str__(self):
+		return "RobotEmotion = { value='%s', time_ms=%d }" % (self.value_as_str(), self.time_ms)
+
diff --git a/client/python/hlrc_client/RobotGaze.py b/client/python/hlrc_client/RobotGaze.py
new file mode 100644
index 0000000..3975b8d
--- /dev/null
+++ b/client/python/hlrc_client/RobotGaze.py
@@ -0,0 +1,39 @@
+"""
+This file is part of hlrc
+
+Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+http://opensource.cit-ec.de/projects/hlrc
+
+This file may be licensed under the terms of the
+GNU General Public License Version 3 (the ``GPL''),
+or (at your option) any later version.
+
+Software distributed under the License is distributed
+on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+express or implied. See the GPL for the specific language
+governing rights and limitations.
+
+You should have received a copy of the GPL along with this
+program. If not, go to http://www.gnu.org/licenses/gpl.html
+or write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+The development of this software was supported by the
+Excellence Cluster EXC 277 Cognitive Interaction Technology.
+The Excellence Cluster EXC 277 is a grant of the Deutsche
+Forschungsgemeinschaft (DFG) in the context of the German
+Excellence Initiative.
+"""
+
+class RobotGaze:
+	def __init__(self):
+		self.pan = 0.0
+		self.tilt = 0.0
+		self.roll = 0.0
+		self.vergence = 0.0
+		self.pan_offset = 0.0
+		self.tilt_offset = 0.0
+		
+	def __str__(self):
+		return "RobotGaze = { PTR={%6.2f %6.2f %6.2f} vergence=%6.2f PT_offset={%6.2f %6.2f} }"  \
+			% (self.pan, self.tilt,self.roll,self.vergence,self.pan_offset,self.tilt_offset)
diff --git a/client/python/hlrc_client/RobotMouth.py b/client/python/hlrc_client/RobotMouth.py
new file mode 100644
index 0000000..761222a
--- /dev/null
+++ b/client/python/hlrc_client/RobotMouth.py
@@ -0,0 +1,40 @@
+"""
+This file is part of hlrc
+
+Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+http://opensource.cit-ec.de/projects/hlrc
+
+This file may be licensed under the terms of the
+GNU General Public License Version 3 (the ``GPL''),
+or (at your option) any later version.
+
+Software distributed under the License is distributed
+on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+express or implied. See the GPL for the specific language
+governing rights and limitations.
+
+You should have received a copy of the GPL along with this
+program. If not, go to http://www.gnu.org/licenses/gpl.html
+or write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+The development of this software was supported by the
+Excellence Cluster EXC 277 Cognitive Interaction Technology.
+The Excellence Cluster EXC 277 is a grant of the Deutsche
+Forschungsgemeinschaft (DFG) in the context of the German
+Excellence Initiative.
+"""
+
+class RobotMouth:
+	def __init__(self):
+		self.opening_left   = 0.0
+		self.opening_center = 0.0
+		self.opening_right  = 0.0
+		self.position_left  = 0.0
+		self.position_center = 0.0
+		self.position_right = 0.0
+
+	def __str__(self):
+		return "RobotMouth = { opening={%6.2f %6.2f %6.2f} offset={%6.2f %6.2f %6.2f} }" \
+			% (self.opening_left, self.opening_center, self.opening_right, \
+				self.position_left, self.position_center, self.position_right)
diff --git a/client/python/hlrc_client/__init__.py b/client/python/hlrc_client/__init__.py
new file mode 100644
index 0000000..73d051f
--- /dev/null
+++ b/client/python/hlrc_client/__init__.py
@@ -0,0 +1,8 @@
+from Middleware import Middleware
+from MiddlewareRSB import MiddlewareRSB
+from MiddlewareROS import MiddlewareROS
+from RobotEmotion import RobotEmotion
+from RobotController import RobotController
+from RobotGaze import RobotGaze
+from RobotAnimation import RobotAnimation
+from RobotMouth import RobotMouth
diff --git a/client/python/hlrc_client/hlrc_play_animation.py b/client/python/hlrc_client/hlrc_play_animation.py
new file mode 100755
index 0000000..53abd7f
--- /dev/null
+++ b/client/python/hlrc_client/hlrc_play_animation.py
@@ -0,0 +1,84 @@
+#!/usr/bin/python
+#PYTHONPATH="/opt/ros/groovy/lib/python2.7/dist-packages:/vol/csra/releases/nightly/lib/python2.7/:/vol/csra/releases/nightly/lib/python2.7/site-packages/
+import sys
+import logging
+import errno
+
+try:
+    import rsb
+    import rsb.converter
+    import rst
+    import rstsandbox
+    from rst.robot.Animation_pb2 import Animation
+except ImportError as exception:
+    sys.stderr.write("ImportError: {}\n> HINT: try to export PYTHONPATH=$PYTHONPATH:$YOUR_PREFIX/lib/python2.7/site-packages/\n\n".format(exception))
+    sys.exit(errno.ENOPKG)
+
+class hlrc_animation():
+    def __init__(self, _base_scope):
+        #print "> registering rst converter"
+        converter = rsb.converter.ProtocolBufferConverter(messageClass = Animation)
+        rsb.converter.registerGlobalConverter(converter)
+        self.server = None	
+        self.set_scope(_base_scope);
+
+    def __del__(self):
+        if (not self.server is None):
+            self.server.deactivate()
+
+    def set_scope(self, scope):
+        self.base_scope = str(scope) #NOTE: str() is important here, scope is a qstring (?) and gets deleted during call
+        print "> setting scope to '%s'" % self.base_scope
+	if (not self.server is None):
+            self.server.deactivate()
+	try:
+            self.server = rsb.createRemoteServer(self.base_scope + '/set')
+        except ValueError:
+            print "> invalid scope given. server deactivated"
+            self.server.deactivate()
+
+    def trigger_animation(self, ani_id, repetitions, duration_each, scale, blocking):
+        if (self.server is None):
+            print("> invalid server")
+            return
+        #create animation & fill it with values:
+        ani = Animation()
+
+        #select ani
+        ani.target = ani_id
+        ani.repetitions = repetitions
+        ani.duration_each = duration_each
+        ani.scale       = scale
+
+        if (blocking):
+            #blocking:
+            print "> calling the animation rpc (blocking until we finished talking)..."
+            print '> server reply: "%s"' % self.server.animation(ani)
+        else:
+            print "> calling the animation rpc (NON-BLOCKING)..."
+            return self.server.animation.async(ani)
+            #we can block here for a incoming result with a timeout in s
+            #print '> server reply: "%s"' % future.get(timeout = 10);
+
+        print "> blocking call done"
+    
+def main():
+    if (len(sys.argv) != 5):
+        print "> usage: %s <base scope> <animation id> <dur each> <repetitions>\n>     example: %s /flobi1 1 1000 1" % (sys.argv[0] , sys.argv[0])
+        sys.exit(0)
+
+    # Pacify logger.
+    #logging.basicConfig()
+    scope  = sys.argv[1]
+    ani_id = int(sys.argv[2])
+    dur    = int(sys.argv[3])
+    rep    = int(sys.argv[4])
+    scale  = 1.0
+
+    hani = hlrc_animation(scope)
+    hani.trigger_animation(ani_id, rep, dur, scale, 1)
+
+if __name__ == '__main__':
+    main()
+
+
diff --git a/client/python/hlrc_client/hlrc_set_emotion.py b/client/python/hlrc_client/hlrc_set_emotion.py
new file mode 100755
index 0000000..49d30e4
--- /dev/null
+++ b/client/python/hlrc_client/hlrc_set_emotion.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+#PYTHONPATH="/opt/ros/groovy/lib/python2.7/dist-packages:/vol/csra/releases/nightly/lib/python2.7/:/vol/csra/releases/nightly/lib/python2.7/site-packages/
+import sys
+import logging
+import errno
+
+try:
+    import rsb
+    import rsb.converter
+    import rst
+    import rstsandbox
+    from rst.robot.EmotionState_pb2 import EmotionState
+except ImportError as exception:
+    sys.stderr.write("ImportError: {}\n> HINT: try to export PYTHONPATH=$PYTHONPATH:$YOUR_PREFIX/lib/python2.7/site-packages/\n\n".format(exception))
+    sys.exit(errno.ENOPKG)
+
+class hlrc_emotion():
+    def __init__(self, _base_scope):
+        #print "> registering rst converter"
+        converter = rsb.converter.ProtocolBufferConverter(messageClass = EmotionState)
+        rsb.converter.registerGlobalConverter(converter)
+	self.set_scope( _base_scope);
+
+    def set_scope(self, scope):
+        self.base_scope = str(scope) #NOTE: str() is important here, scope is a qstring (?) and gets deleted during call
+        print "> setting scope to '%s'" % self.base_scope
+        try:
+            self.server = rsb.createRemoteServer(self.base_scope + '/set')
+        except ValueError:
+            print "> invalid scope given. server deactivated"
+            self.server.deactivate()
+
+    def set_emotion(self, emotion_id, duration_each, blocking):
+        if (self.server is None):
+            print("> invalid server")
+            return
+
+        #create emotion & fill it with values:
+        em = EmotionState()
+
+        #select ani
+        em.value    = emotion_id
+        em.duration = duration_each
+
+        with rsb.createRemoteServer(self.base_scope + '/set') as server:
+            if (blocking):
+                #blocking:
+                print "> calling the emotion rpc (blocking until we finished talking)..."
+                print '> server reply: "%s"' % server.currentEmotion(em)
+            else:
+               print "> calling the animation rpc (NON-BLOCKING)..."
+               future = server.currentEmotion.async(em)
+               #we can block here for a incoming result with a timeout in s
+               #print '> server reply: "%s"' % future.get(timeout = 10);
+
+        print "> done"
+    
+def main():
+    if (len(sys.argv) != 4):
+        print "> usage: %s <base scope> <emotion id> <duration>\n>     example: %s /flobi1 1 1000" % (sys.argv[0] , sys.argv[0])
+        sys.exit(0)
+
+    # Pacify logger.
+    #logging.basicConfig()
+    em_id = int(sys.argv[2])
+    dur    = int(sys.argv[3])
+    base   = sys.argv[1]
+
+    hlrc_emotion(base).set_emotion(em_id, dur, 1)
+
+if __name__ == '__main__':
+    main()
+
+
diff --git a/client/python/hlrc_client/hlrc_speak_utterance.py b/client/python/hlrc_client/hlrc_speak_utterance.py
new file mode 100755
index 0000000..ba8c988
--- /dev/null
+++ b/client/python/hlrc_client/hlrc_speak_utterance.py
@@ -0,0 +1,120 @@
+#!/usr/bin/python
+#PYTHONPATH="/opt/ros/groovy/lib/python2.7/dist-packages:/vol/csra/releases/nightly/lib/python2.7/:/vol/csra/releases/nightly/lib/python2.7/site-packages/
+import sys
+import wave
+
+from textgrid_hlc import *
+import logging
+import errno
+import os.path
+
+try:
+    import rsb
+    import rsb.converter
+    import rst
+    import rstsandbox
+    from rst.audition.Utterance_pb2 import Utterance
+    from rst.audition.SoundChunk_pb2 import SoundChunk
+except ImportError as exception:
+    sys.stderr.write("ImportError: {}\n> HINT: try to export PYTHONPATH=$PYTHONPATH:$YOUR_PREFIX/lib/python2.7/site-packages/\n\n".format(exception))
+    sys.exit(errno.ENOPKG)
+
+class hlrc_utterance():
+    def __init__(self, _base_scope):
+        #print "> registering rst converter"
+        converter = rsb.converter.ProtocolBufferConverter(messageClass = Utterance)
+        rsb.converter.registerGlobalConverter(converter)
+	self.set_scope(_base_scope)
+
+    def set_scope(self, scope):
+        self.base_scope = str(scope) #NOTE: str() is important here, scope is a qstring (?) and gets deleted during call
+        print "> setting scope to '%s'" % self.base_scope
+        try:
+            self.server = rsb.createRemoteServer(self.base_scope + '/set')
+        except ValueError:
+            print "> invalid scope given. server deactivated"
+            self.server.deactivate()
+
+    def trigger_utterance(self, filename_praat, filename_wav, blocking):
+        if (self.server is None):
+            print("> invalid server")
+            return
+
+        if (not os.path.isfile(filename_praat)):
+            print "can not open file '%s'" % (filename_praat)
+            return 0
+
+        if (not os.path.isfile(filename_wav)):
+            print "can not open file '%s'" % (filename_wav)
+            return 0
+
+        print "> reading wave file '%s'" % (filename_wav)
+        wav = wave.open(filename_wav, "r")
+
+    
+        print "> parsing praat file '%s'" % (filename_praat)
+        tgrid = TextGrid.load(filename_praat)
+    
+    
+        #create utterance & fill it with values:
+        ut = Utterance()
+    
+        #textual description of audio file
+        ut.text = filename_praat
+        
+        ut.audio.data = wav.readframes(-1)
+        ut.audio.sample_count = wav.getnframes()
+        ut.audio.channels = wav.getnchannels()
+        ut.audio.rate = wav.getframerate()
+    
+        if (wav.getsampwidth() == 1):
+            ut.audio.sample_type = SoundChunk.SAMPLE_U8
+        elif (wav.getsampwidth() == 2):
+            ut.audio.sample_type = SoundChunk.SAMPLE_S16
+        else:
+            print "> invalid sample type. py doc says wave files are either u8 or s16"
+            exit(0)
+    
+        #wave spec says always little endian
+        ut.audio.endianness = SoundChunk.ENDIAN_LITTLE
+    
+        print "> filling phones with data from praat"
+        for tier in tgrid.tiers:
+            idx = (tgrid.tiers.index(tier)) + 1
+            transcript = tier.simple_transcript
+            for (xmin, xmax, utt) in transcript:
+                phoneme = ut.phonemes.add()
+                phoneme.symbol = utt
+                phoneme.duration = int(1000.0*(float(xmax)-float(xmin)))
+    
+        with rsb.createRemoteServer(self.base_scope + '/set') as server:
+            
+            if (blocking):
+                #blocking:
+                print "> calling the utterance rpc (blocking until we finished talking)..."
+                print '> server reply: "%s"' % server.utterance(ut)
+            else:
+               print "> calling the utterance rpc (NON-BLOCKING)..."
+               future = server.utterance.async(ut)
+               #we can block here for a incoming result with a timeout in seconds
+               #print '> server reply: "%s"' % future.get(timeout = 10);
+    
+        print "> done"
+        return 1
+
+def main():
+    # Pacify logger.
+    #logging.basicConfig()
+    if (len(sys.argv) != 4):
+        print "> usage: %s <base_scope> file.praat file.wav\n>     example: %s /flobi1 hello.praat hello.wav" % (sys.argv[0] , sys.argv[0])
+        sys.exit(0)
+
+    filename_praat = sys.argv[2]
+    filename_wav = sys.argv[3]
+    base = sys.argv[1]
+
+    hlc = hlrc_utterance(base)
+    hlc.trigger_utterance(filename_praat, filename_wav, 1)
+
+if __name__ == '__main__':
+    main()
diff --git a/client/python/hlrc_client/hlrc_test_gui.py b/client/python/hlrc_client/hlrc_test_gui.py
new file mode 100755
index 0000000..06e7933
--- /dev/null
+++ b/client/python/hlrc_client/hlrc_test_gui.py
@@ -0,0 +1,248 @@
+#!/usr/bin/python
+import sys
+import os.path
+from PyQt4 import QtGui, QtCore
+from PyQt4.QtCore import SIGNAL
+from hlrc_speak_utterance import hlrc_utterance
+from hlrc_play_animation import hlrc_animation
+from hlrc_set_emotion import hlrc_emotion
+
+class Example(QtGui.QWidget):
+    
+    def __init__(self, _scope):
+        super(Example, self).__init__()
+        self.scope = _scope
+        self.initUI()
+	scope = self.scope_lineedit.text()
+        self.hlrc_utterance = hlrc_utterance(scope)
+        self.hlrc_animation = hlrc_animation(scope)
+        self.hlrc_emotion   = hlrc_emotion(scope)
+
+    def scopeChanged(self):
+	self.scope = self.scope_lineedit.text()
+        print "> changed scope to %s" % self.scope
+        self.hlrc_utterance.set_scope(self.scope)
+        self.hlrc_animation.set_scope(self.scope)
+        self.hlrc_emotion.set_scope(self.scope)
+
+    def initUtteranceUI(self):
+        groupBox = QtGui.QGroupBox("utterances")
+
+        hello = QtGui.QPushButton("hello...")
+        hello.clicked.connect(self.utterance_button_clicked)
+
+        count = QtGui.QPushButton("12345...")
+        count.clicked.connect(self.utterance_button_clicked)
+
+
+        vbox = QtGui.QVBoxLayout()
+        vbox.addWidget(hello)
+        vbox.addWidget(count)
+        vbox.addStretch(1)
+        groupBox.setLayout(vbox)
+
+        return groupBox
+
+    def initSpinbox(self, _min, _max, _init, double):
+        if (double): 
+            s = QtGui.QDoubleSpinBox()
+        else:
+            s = QtGui.QSpinBox()
+
+        s.setMinimum(_min)
+        s.setMaximum(_max)
+        s.setValue(_init)
+        return s
+
+    def initEmotionUI(self):
+        groupBox = QtGui.QGroupBox("emotion")
+        neutral   = QtGui.QPushButton("neutral")
+        neutral.clicked.connect(self.emotion_button_clicked)
+        surprised = QtGui.QPushButton("surprise")
+        surprised.clicked.connect(self.emotion_button_clicked)
+        angry     = QtGui.QPushButton("angry")
+        angry.clicked.connect(self.emotion_button_clicked)
+        happy     = QtGui.QPushButton("happy")
+        happy.clicked.connect(self.emotion_button_clicked)
+        sad     = QtGui.QPushButton("sad")
+        sad.clicked.connect(self.emotion_button_clicked)
+        fear      = QtGui.QPushButton("fear")
+        fear.clicked.connect(self.emotion_button_clicked)
+
+        self.duration_spinbox = self.initSpinbox(100, 10000, 1000, 0)
+
+        vbox = QtGui.QVBoxLayout()
+        vbox.addWidget(self.duration_spinbox)
+        vbox.addWidget(neutral)
+        vbox.addWidget(surprised)
+        vbox.addWidget(angry)
+        vbox.addWidget(happy)
+        vbox.addWidget(sad)
+        vbox.addWidget(fear)
+        vbox.addStretch(1)
+        groupBox.setLayout(vbox)
+        return groupBox
+
+
+    def initAnimationButton(self, name):
+        b = QtGui.QPushButton(name)
+        b.clicked.connect(self.animation_button_clicked)
+        return b
+
+    def initAnimUI(self):
+        groupBox = QtGui.QGroupBox("animations")
+  
+        #options
+        options = QtGui.QHBoxLayout()
+        vbox_r = QtGui.QVBoxLayout()
+        vbox_r.addWidget(QtGui.QLabel("repetitions"))
+        self.repetitions_spinbox = self.initSpinbox(1,10,1,0)
+        vbox_r.addWidget(self.repetitions_spinbox)
+
+        vbox_d = QtGui.QVBoxLayout()
+        vbox_d.addWidget(QtGui.QLabel("duration/ms (each)"))
+        self.duration_each_spinbox = self.initSpinbox(100,10000,1000,0)
+        vbox_d.addWidget(self.duration_each_spinbox)
+
+        vbox_s = QtGui.QVBoxLayout()
+        vbox_s.addWidget(QtGui.QLabel("scale"))
+        self.scale_spinbox = self.initSpinbox(0.1, 5.0, 1.0, 1)
+        vbox_s.addWidget(self.scale_spinbox)
+
+
+        options.addLayout(vbox_r)
+        options.addLayout(vbox_d)        
+        options.addLayout(vbox_s)
+
+        #buttons
+        vbox = QtGui.QVBoxLayout()
+        vbox.addLayout(options)
+        vbox.addWidget(self.initAnimationButton("head shake"))
+        vbox.addWidget(self.initAnimationButton("head nod"))
+        vbox.addWidget(self.initAnimationButton("eyeblink left"))
+        vbox.addWidget(self.initAnimationButton("eyeblink right"))
+        vbox.addWidget(self.initAnimationButton("eyeblink both"))
+	vbox.addWidget(self.initAnimationButton("eyebrows raise"))
+	vbox.addWidget(self.initAnimationButton("eyebrows lower"))
+        vbox.addStretch(1)
+        groupBox.setLayout(vbox)
+
+        return groupBox
+
+    def initUI(self):        
+
+        self.scope_lineedit = QtGui.QLineEdit(self.scope);
+        self.connect(self.scope_lineedit, SIGNAL("editingFinished()"),self.scopeChanged)
+
+	vbox = QtGui.QVBoxLayout();
+	
+	hboxl = QtGui.QHBoxLayout();
+	hboxl.addWidget(QtGui.QLabel("base scope: "));
+	hboxl.addWidget(self.scope_lineedit);
+	vbox.addLayout(hboxl);
+
+        hbox = QtGui.QHBoxLayout()
+	vbox.addLayout(hbox);
+	
+        #emotion
+        hbox.addWidget(self.initEmotionUI())
+
+        #utterance:
+        hbox.addWidget(self.initUtteranceUI())
+
+        #animations:
+        hbox.addWidget(self.initAnimUI())
+
+        self.setLayout(vbox)
+        #sld.valueChanged.connect(lcd.display)
+        
+        self.setGeometry(400, 100, 250, 150)
+        self.setWindowTitle("HLC Server test GUI")
+        self.show()
+
+    def utterance_button_clicked(self):
+        button = self.sender().text()
+        
+        fn_praat = "b.praat"
+        fn_wav   = "b.wav"
+
+        if (button == "12345..."):
+            print("123")
+            fn_praat = "1234.praat"
+            fn_wav   = "1234.wav"
+
+        elif (button == "hello..."):
+            print "hello"
+            fn_praat = "hello_my_name.praat"
+            fn_wav   = "hello_my_name.wav"
+
+        else:
+            print "invalid button '%s'" % (button)
+            return
+
+        #try to find the wav/praat files:
+        path = os.path.dirname(os.path.realpath(__file__)) + "/../share/hlrc_server/examples/"
+        if (not os.path.isfile(path + fn_wav)):
+            #try fallback solution for running from current folder:
+            path = "examples/"
+
+        self.hlrc_utterance.trigger_utterance(path + fn_praat, path + fn_wav, 0)
+
+    def emotion_button_clicked(self):
+        button = self.sender().text()
+        duration = self.duration_spinbox.value()
+
+
+        if (button == "angry"):
+            self.hlrc_emotion.set_emotion(3, duration, 0)
+        elif (button == "neutral"):
+            self.hlrc_emotion.set_emotion(0, duration, 0)
+        elif (button == "happy"):
+            self.hlrc_emotion.set_emotion(1, duration, 0)
+        elif (button == "sad"):
+            self.hlrc_emotion.set_emotion(2, duration, 0)
+        elif (button == "surprise"):
+            self.hlrc_emotion.set_emotion(4, duration, 0)
+        elif (button == "fear"):
+            self.hlrc_emotion.set_emotion(5, duration, 0)
+        else:
+            print "invalid emotion id '%s'" % (button)
+            return
+
+    def animation_button_clicked(self):
+        button = self.sender().text()
+
+        repetitions = self.repetitions_spinbox.value()
+        duration_each = self.duration_each_spinbox.value()
+        scale = self.scale_spinbox.value()
+
+        if (button == "head nod"):
+            self.hlrc_animation.trigger_animation(1, repetitions, duration_each, scale, 0)
+        elif (button == "head shake"):
+            self.hlrc_animation.trigger_animation(2, repetitions, duration_each, scale, 0)
+        elif (button == "eyeblink left"):
+            self.hlrc_animation.trigger_animation(3, repetitions, duration_each, scale, 0)
+        elif (button == "eyeblink right"):
+            self.hlrc_animation.trigger_animation(4, repetitions, duration_each, scale, 0)
+        elif (button == "eyeblink both"):
+            self.hlrc_animation.trigger_animation(5, repetitions, duration_each, scale, 0)
+        elif (button == "eyebrows raise"):
+            self.hlrc_animation.trigger_animation(6, repetitions, duration_each, scale, 0)
+        elif (button == "eyebrows lower"):
+            self.hlrc_animation.trigger_animation(7, repetitions, duration_each, scale, 0)
+        else:
+            print "invalid button '%s'" % (button)
+            return
+
+def main():
+    scope = "/home/wardrobe/flobi"
+    if (len(sys.argv) == 2):
+	scope = sys.argv[1]
+
+    app = QtGui.QApplication(sys.argv)
+    ex = Example(scope)
+    sys.exit(app.exec_())
+
+
+if __name__ == '__main__':
+    main()
diff --git a/client/python/hlrc_client/textgrid_hlrc.py b/client/python/hlrc_client/textgrid_hlrc.py
new file mode 100644
index 0000000..2a0e09b
--- /dev/null
+++ b/client/python/hlrc_client/textgrid_hlrc.py
@@ -0,0 +1,657 @@
+# Natural Language Toolkit: TextGrid analysis
+#
+# Copyright (C) 2001-2011 NLTK Project
+# Author: Margaret Mitchell <itallow@gmail.com>
+#         Steven Bird <sb@csse.unimelb.edu.au> (revisions)
+# URL: <http://www.nltk.org>
+# For license information, see LICENSE.TXT
+#
+
+"""
+Tools for reading TextGrid files, the format used by Praat.
+
+Module contents
+===============
+
+The textgrid corpus reader provides 4 data items and 1 function
+for each textgrid file.  For each tier in the file, the reader
+provides 10 data items and 2 functions.
+ 
+For the full textgrid file: 
+
+  - size
+    The number of tiers in the file.
+
+  - xmin
+    First marked time of the file.
+
+  - xmax
+    Last marked time of the file.
+
+  - t_time
+    xmax - xmin.
+
+  - text_type
+    The style of TextGrid format:
+        - ooTextFile:  Organized by tier.
+        - ChronTextFile:  Organized by time.
+        - OldooTextFile:  Similar to ooTextFile.
+
+  - to_chron()
+    Convert given file to a ChronTextFile format.
+
+  - to_oo()
+    Convert given file to an ooTextFile format.
+
+For each tier:
+
+  - text_type
+    The style of TextGrid format, as above.
+
+  - classid
+    The style of transcription on this tier:
+        - IntervalTier:  Transcription is marked as intervals.
+        - TextTier:  Transcription is marked as single points.
+
+  - nameid
+    The name of the tier.
+
+  - xmin
+    First marked time of the tier.
+
+  - xmax
+    Last marked time of the tier.
+
+  - size
+    Number of entries in the tier.
+
+  - transcript
+    The raw transcript for the tier.
+
+  - simple_transcript
+    The transcript formatted as a list of tuples: (time1, time2, utterance).
+
+  - tier_info
+    List of (classid, nameid, xmin, xmax, size, transcript).
+
+  - min_max()
+    A tuple of (xmin, xmax).  
+
+  - time(non_speech_marker)
+    Returns the utterance time of a given tier.
+    Excludes entries that begin with a non-speech marker.
+
+"""
+
+# needs more cleanup, subclassing, epydoc docstrings
+
+import sys
+import re
+
+TEXTTIER = "TextTier"
+INTERVALTIER = "IntervalTier"
+
+OOTEXTFILE = re.compile(r"""(?x)
+            xmin\ =\ (.*)[\r\n]+
+            xmax\ =\ (.*)[\r\n]+
+            [\s\S]+?size\ =\ (.*)[\r\n]+ 
+""")
+
+CHRONTEXTFILE = re.compile(r"""(?x)
+            [\r\n]+(\S+)\ 
+            (\S+)\ +!\ Time\ domain.\ *[\r\n]+
+            (\S+)\ +!\ Number\ of\ tiers.\ *[\r\n]+"
+""")
+
+OLDOOTEXTFILE = re.compile(r"""(?x)
+            [\r\n]+(\S+)
+            [\r\n]+(\S+)
+            [\r\n]+.+[\r\n]+(\S+)
+""")
+
+
+
+#################################################################
+# TextGrid Class
+#################################################################
+
+class TextGrid(object):
+    """
+    Class to manipulate the TextGrid format used by Praat.
+    Separates each tier within this file into its own Tier
+    object.  Each TextGrid object has
+    a number of tiers (size), xmin, xmax, a text type to help
+    with the different styles of TextGrid format, and tiers with their
+    own attributes.
+    """
+
+    def __init__(self, read_file):
+        """
+        Takes open read file as input, initializes attributes 
+        of the TextGrid file.
+        @type read_file: An open TextGrid file, mode "r".
+        @param size:  Number of tiers.
+        @param xmin: xmin.
+        @param xmax: xmax.
+        @param t_time:  Total time of TextGrid file.
+        @param text_type:  TextGrid format.
+        @type tiers:  A list of tier objects.
+        """
+
+        self.read_file = read_file
+        self.size = 0
+        self.xmin = 0
+        self.xmax = 0
+        self.t_time = 0
+        self.text_type = self._check_type()
+        self.tiers = self._find_tiers()
+
+    def __iter__(self):
+        for tier in self.tiers:
+            yield tier
+
+    def next(self):
+        if self.idx == (self.size - 1):
+            raise StopIteration
+        self.idx += 1
+        return self.tiers[self.idx]
+
+    @staticmethod
+    def load(file):
+        """
+        @param file: a file in TextGrid format
+        """
+
+        return TextGrid(open(file).read())
+
+    def _load_tiers(self, header):
+        """
+        Iterates over each tier and grabs tier information.
+        """ 
+
+        tiers = []
+        if self.text_type == "ChronTextFile":
+            m = re.compile(header)
+            tier_headers = m.findall(self.read_file)
+            tier_re = " \d+.?\d* \d+.?\d*[\r\n]+\"[^\"]*\""
+            for i in range(0, self.size):
+                tier_info = [tier_headers[i]] + \
+                re.findall(str(i + 1) + tier_re, self.read_file)
+                tier_info = "\n".join(tier_info)
+                tiers.append(Tier(tier_info, self.text_type, self.t_time))
+            return tiers
+        
+        tier_re = header + "\d+[\s\S]+?(?=" + header + "|$$)"
+        m = re.compile(tier_re)
+        tier_iter = m.finditer(self.read_file)
+        for iterator in tier_iter:
+            (begin, end) = iterator.span()
+            tier_info = self.read_file[begin:end]
+            tiers.append(Tier(tier_info, self.text_type, self.t_time))
+        return tiers
+    
+    def _check_type(self):
+        """
+        Figures out the TextGrid format.
+        """
+
+        m = re.match("(.*)[\r\n](.*)[\r\n](.*)[\r\n](.*)", self.read_file)
+        try:
+            type_id = m.group(1).strip()
+        except AttributeError:
+            raise TypeError("Cannot read file -- try TextGrid.load()")
+        xmin = m.group(4)
+        if type_id == "File type = \"ooTextFile\"":
+            if "xmin" not in xmin:
+                xmin = m.group(3)
+                if "xmin" not in xmin:
+                    text_type = "OldooTextFile"
+                else:
+                    text_type = "ooTextFile"
+            else:
+                text_type = "ooTextFile"
+        elif type_id == "\"Praat chronological TextGrid text file\"":
+            text_type = "ChronTextFile"
+        else: 
+            raise TypeError("Unknown format '(%s)'", (type_id))
+        return text_type
+        
+    def _find_tiers(self):
+        """
+        Splits the textgrid file into substrings corresponding to tiers. 
+        """
+
+        if self.text_type == "ooTextFile":
+            m = OOTEXTFILE
+            header = " *item \["
+        elif self.text_type == "ChronTextFile":
+            m = CHRONTEXTFILE
+            header = "\"\S+\" \".*\" \d+\.?\d* \d+\.?\d*"
+        elif self.text_type == "OldooTextFile":
+            m = OLDOOTEXTFILE
+            header = "\".*\"[\r\n]+\".*\""
+
+        file_info = m.findall(self.read_file)[0]
+        self.xmin = float(file_info[0])
+        self.xmax = float(file_info[1])
+        self.t_time = self.xmax - self.xmin
+        self.size = int(file_info[2])
+        tiers = self._load_tiers(header)
+        return tiers
+
+    def to_chron(self):
+        """ 
+        @return:  String in Chronological TextGrid file format.
+        """
+
+        chron_file = ""
+        chron_file += "\"Praat chronological TextGrid text file\"\n"
+        chron_file += str(self.xmin) + " " + str(self.xmax)
+        chron_file += "   ! Time domain.\n"
+        chron_file += str(self.size) + "   ! Number of tiers.\n"
+        for tier in self.tiers:
+            idx = (self.tiers.index(tier)) + 1
+            tier_header = "\"" + tier.classid + "\" \"" \
+                          + tier.nameid + "\" " + str(tier.xmin) \
+                          + " " + str(tier.xmax)
+            chron_file += tier_header + "\n"
+            transcript = tier.simple_transcript
+            for (xmin, xmax, utt) in transcript:
+                chron_file += str(idx) + " " + str(xmin) 
+                chron_file += " " + str(xmax) +"\n"
+                chron_file += "\"" + utt + "\"\n"
+        return chron_file
+
+    def to_oo(self):
+        """ 
+        @return:  A string in OoTextGrid file format.
+        """
+   
+        oo_file = ""
+        oo_file += "File type = \"ooTextFile\"\n"
+        oo_file += "Object class = \"TextGrid\"\n\n"
+        oo_file += "xmin = ", self.xmin, "\n"
+        oo_file += "xmax = ", self.xmax, "\n"
+        oo_file += "tiers? <exists>\n"
+        oo_file += "size = ", self.size, "\n"
+        oo_file += "item []:\n"
+        for i in range(len(self.tiers)):
+            oo_file += "%4s%s [%s]" % ("", "item", i + 1)
+            _curr_tier = self.tiers[i]
+            for (x, y) in _curr_tier.header:
+                oo_file += "%8s%s = \"%s\"" % ("", x, y)
+            if _curr_tier.classid != TEXTTIER:
+                for (xmin, xmax, text) in _curr_tier.simple_transcript:
+                    oo_file += "%12s%s = %s" % ("", "xmin", xmin)
+                    oo_file += "%12s%s = %s" % ("", "xmax", xmax)
+                    oo_file += "%12s%s = \"%s\"" % ("", "text", text)
+            else:
+                for (time, mark) in _curr_tier.simple_transcript:
+                    oo_file += "%12s%s = %s" % ("", "time", time)
+                    oo_file += "%12s%s = %s" % ("", "mark", mark)
+        return oo_file
+
+
+#################################################################
+# Tier Class
+#################################################################
+
+class Tier(object):
+    """ 
+    A container for each tier.
+    """
+
+    def __init__(self, tier, text_type, t_time):
+        """
+        Initializes attributes of the tier: class, name, xmin, xmax
+        size, transcript, total time.  
+        Utilizes text_type to guide how to parse the file.
+        @type tier: a tier object; single item in the TextGrid list.
+        @param text_type:  TextGrid format
+        @param t_time:  Total time of TextGrid file.
+        @param classid:  Type of tier (point or interval).
+        @param nameid:  Name of tier.
+        @param xmin:  xmin of the tier.
+        @param xmax:  xmax of the tier.
+        @param size:  Number of entries in the tier
+        @param transcript:  The raw transcript for the tier.
+        """
+
+        self.tier = tier
+        self.text_type = text_type
+        self.t_time = t_time
+        self.classid = ""
+        self.nameid = ""
+        self.xmin = 0
+        self.xmax = 0
+        self.size = 0
+        self.transcript = ""
+        self.tier_info = ""
+        self._make_info()
+        self.simple_transcript = self.make_simple_transcript()
+        if self.classid != TEXTTIER:
+            self.mark_type = "intervals"
+        else:
+            self.mark_type = "points"
+            self.header = [("class", self.classid), ("name", self.nameid), \
+            ("xmin", self.xmin), ("xmax", self.xmax), ("size", self.size)]
+
+    def __iter__(self):
+        return self
+  
+    def _make_info(self):
+        """
+        Figures out most attributes of the tier object:
+        class, name, xmin, xmax, transcript.
+        """
+
+        trans = "([\S\s]*)"
+        if self.text_type == "ChronTextFile":
+            classid = "\"(.*)\" +"
+            nameid = "\"(.*)\" +"
+            xmin = "(\d+\.?\d*) +"
+            xmax = "(\d+\.?\d*) *[\r\n]+"
+            # No size values are given in the Chronological Text File format.
+            self.size = None
+            size = ""
+        elif self.text_type == "ooTextFile":
+            classid = " *class = \"(.*)\" *[\r\n]+"
+            nameid = " *name = \"(.*)\" *[\r\n]+"
+            xmin = " *xmin = (\d+\.?\d*) *[\r\n]+"
+            xmax = " *xmax = (\d+\.?\d*) *[\r\n]+"
+            size = " *\S+: size = (\d+) *[\r\n]+"
+        elif self.text_type == "OldooTextFile":
+            classid = "\"(.*)\" *[\r\n]+"
+            nameid = "\"(.*)\" *[\r\n]+"
+            xmin = "(\d+\.?\d*) *[\r\n]+"
+            xmax = "(\d+\.?\d*) *[\r\n]+"
+            size = "(\d+) *[\r\n]+"
+        m = re.compile(classid + nameid + xmin + xmax + size + trans)
+        self.tier_info = m.findall(self.tier)[0]
+        self.classid = self.tier_info[0]
+        self.nameid = self.tier_info[1]
+        self.xmin = float(self.tier_info[2])
+        self.xmax = float(self.tier_info[3])
+        if self.size != None:
+            self.size = int(self.tier_info[4])
+        self.transcript = self.tier_info[-1]
+            
+    def make_simple_transcript(self):
+        """ 
+        @return:  Transcript of the tier, in form [(start_time end_time label)]
+        """
+
+        if self.text_type == "ChronTextFile":
+            trans_head = ""
+            trans_xmin = " (\S+)"
+            trans_xmax = " (\S+)[\r\n]+"
+            trans_text = "\"([\S\s]*?)\""
+        elif self.text_type == "ooTextFile":
+            trans_head = " *\S+ \[\d+\]: *[\r\n]+"
+            trans_xmin = " *\S+ = (\S+) *[\r\n]+"
+            trans_xmax = " *\S+ = (\S+) *[\r\n]+"
+            trans_text = " *\S+ = \"([^\"]*?)\""    
+        elif self.text_type == "OldooTextFile":
+            trans_head = ""
+            trans_xmin = "(.*)[\r\n]+"
+            trans_xmax = "(.*)[\r\n]+"
+            trans_text = "\"([\S\s]*?)\""
+        if self.classid == TEXTTIER:
+            trans_xmin = ""
+        trans_m = re.compile(trans_head + trans_xmin + trans_xmax + trans_text)
+        self.simple_transcript = trans_m.findall(self.transcript)
+        return self.simple_transcript
+
+    def transcript(self):
+        """
+        @return:  Transcript of the tier, as it appears in the file.
+        """
+       
+        return self.transcript
+
+    def time(self, non_speech_char="."):
+        """
+        @return: Utterance time of a given tier.
+        Screens out entries that begin with a non-speech marker.        
+        """
+
+        total = 0.0
+        if self.classid != TEXTTIER:
+            for (time1, time2, utt) in self.simple_transcript:
+                utt = utt.strip()
+                if utt and not utt[0] == ".":
+                    total += (float(time2) - float(time1))
+        return total
+                    
+    def tier_name(self):
+        """
+        @return:  Tier name of a given tier.
+        """
+
+        return self.nameid
+
+    def classid(self):
+        """
+        @return:  Type of transcription on tier.
+        """
+
+        return self.classid
+
+    def min_max(self):
+        """
+        @return:  (xmin, xmax) tuple for a given tier.
+        """
+
+        return (self.xmin, self.xmax)
+
+    def __repr__(self):
+        return "<%s \"%s\" (%.2f, %.2f) %.2f%%>" % (self.classid, self.nameid, self.xmin, self.xmax, 100*self.time()/self.t_time)
+
+    def __str__(self):
+        return self.__repr__() + "\n  " + "\n  ".join(" ".join(row) for row in self.simple_transcript)
+
+def demo_TextGrid(demo_data):
+    print "** Demo of the TextGrid class. **"
+
+    fid = TextGrid(demo_data)
+    print "Tiers:", fid.size
+
+    for i, tier in enumerate(fid):
+        print "\n***"
+        print "Tier:", i + 1
+        print tier
+
+def demo():
+    # Each demo demonstrates different TextGrid formats.
+    print "Format 1"
+    demo_TextGrid(demo_data1)
+    print "\nFormat 2"
+    demo_TextGrid(demo_data2)
+    print "\nFormat 3"
+    demo_TextGrid(demo_data3)
+
+
+demo_data1 = """File type = "ooTextFile"
+Object class = "TextGrid"
+
+xmin = 0 
+xmax = 2045.144149659864
+tiers? <exists> 
+size = 3 
+item []: 
+    item [1]:
+        class = "IntervalTier" 
+        name = "utterances" 
+        xmin = 0 
+        xmax = 2045.144149659864 
+        intervals: size = 5 
+        intervals [1]:
+            xmin = 0 
+            xmax = 2041.4217474125382 
+            text = "" 
+        intervals [2]:
+            xmin = 2041.4217474125382 
+            xmax = 2041.968276643991 
+            text = "this" 
+        intervals [3]:
+            xmin = 2041.968276643991 
+            xmax = 2042.5281632653062 
+            text = "is" 
+        intervals [4]:
+            xmin = 2042.5281632653062 
+            xmax = 2044.0487352585324 
+            text = "a" 
+        intervals [5]:
+            xmin = 2044.0487352585324 
+            xmax = 2045.144149659864 
+            text = "demo" 
+    item [2]:
+        class = "TextTier" 
+        name = "notes" 
+        xmin = 0 
+        xmax = 2045.144149659864 
+        points: size = 3 
+        points [1]:
+            time = 2041.4217474125382 
+            mark = ".begin_demo"
+        points [2]:
+            time = 2043.8338291031832
+            mark = "voice gets quiet here" 
+        points [3]:
+            time = 2045.144149659864
+            mark = ".end_demo" 
+    item [3]:
+        class = "IntervalTier" 
+        name = "phones" 
+        xmin = 0 
+        xmax = 2045.144149659864
+        intervals: size = 12
+        intervals [1]:
+            xmin = 0 
+            xmax = 2041.4217474125382 
+            text = "" 
+        intervals [2]:
+            xmin = 2041.4217474125382 
+            xmax = 2041.5438290324326 
+            text = "D"
+        intervals [3]:
+            xmin = 2041.5438290324326
+            xmax = 2041.7321032910372
+            text = "I"
+        intervals [4]:
+            xmin = 2041.7321032910372            
+            xmax = 2041.968276643991 
+            text = "s" 
+        intervals [5]:
+            xmin = 2041.968276643991 
+            xmax = 2042.232189031843
+            text = "I"
+        intervals [6]:
+            xmin = 2042.232189031843
+            xmax = 2042.5281632653062 
+            text = "z" 
+        intervals [7]:
+            xmin = 2042.5281632653062 
+            xmax = 2044.0487352585324 
+            text = "eI" 
+        intervals [8]:
+            xmin = 2044.0487352585324 
+            xmax = 2044.2487352585324
+            text = "dc"
+        intervals [9]:
+            xmin = 2044.2487352585324
+            xmax = 2044.3102321849011
+            text = "d"
+        intervals [10]:
+            xmin = 2044.3102321849011
+            xmax = 2044.5748932104329
+            text = "E"
+        intervals [11]:
+            xmin = 2044.5748932104329
+            xmax = 2044.8329108578437
+            text = "m"
+        intervals [12]:
+            xmin = 2044.8329108578437
+            xmax = 2045.144149659864 
+            text = "oU" 
+"""
+
+demo_data2 = """File type = "ooTextFile"
+Object class = "TextGrid"
+
+0
+2.8
+<exists>
+2
+"IntervalTier"
+"utterances"
+0
+2.8
+3
+0
+1.6229213249309031
+""
+1.6229213249309031
+2.341428074708195
+"demo"
+2.341428074708195
+2.8
+""
+"IntervalTier"
+"phones"
+0
+2.8
+6
+0
+1.6229213249309031
+""
+1.6229213249309031
+1.6428291382019483
+"dc"
+1.6428291382019483
+1.65372183721983721
+"d"
+1.65372183721983721
+1.94372874328943728
+"E"
+1.94372874328943728
+2.13821938291038210
+"m"
+2.13821938291038210
+2.341428074708195
+"oU"
+2.341428074708195
+2.8
+""
+"""
+
+demo_data3 = """"Praat chronological TextGrid text file"
+0 2.8   ! Time domain.
+2   ! Number of tiers.
+"IntervalTier" "utterances" 0 2.8
+"IntervalTier" "utterances" 0 2.8
+1 0 1.6229213249309031
+""
+2 0 1.6229213249309031
+""
+2 1.6229213249309031 1.6428291382019483
+"dc"
+2 1.6428291382019483 1.65372183721983721
+"d"
+2 1.65372183721983721 1.94372874328943728
+"E"
+2 1.94372874328943728 2.13821938291038210
+"m"
+2 2.13821938291038210 2.341428074708195
+"oU"
+1 1.6229213249309031 2.341428074708195
+"demo"
+1 2.341428074708195 2.8
+""
+2 2.341428074708195 2.8
+""
+"""
+
+if __name__ == "__main__":
+    demo()
+
diff --git a/client/python/hlrc_set_emotion.py b/client/python/hlrc_set_emotion.py
new file mode 100644
index 0000000..49d30e4
--- /dev/null
+++ b/client/python/hlrc_set_emotion.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+#PYTHONPATH="/opt/ros/groovy/lib/python2.7/dist-packages:/vol/csra/releases/nightly/lib/python2.7/:/vol/csra/releases/nightly/lib/python2.7/site-packages/
+import sys
+import logging
+import errno
+
+try:
+    import rsb
+    import rsb.converter
+    import rst
+    import rstsandbox
+    from rst.robot.EmotionState_pb2 import EmotionState
+except ImportError as exception:
+    sys.stderr.write("ImportError: {}\n> HINT: try to export PYTHONPATH=$PYTHONPATH:$YOUR_PREFIX/lib/python2.7/site-packages/\n\n".format(exception))
+    sys.exit(errno.ENOPKG)
+
+class hlrc_emotion():
+    def __init__(self, _base_scope):
+        #print "> registering rst converter"
+        converter = rsb.converter.ProtocolBufferConverter(messageClass = EmotionState)
+        rsb.converter.registerGlobalConverter(converter)
+	self.set_scope( _base_scope);
+
+    def set_scope(self, scope):
+        self.base_scope = str(scope) #NOTE: str() is important here, scope is a qstring (?) and gets deleted during call
+        print "> setting scope to '%s'" % self.base_scope
+        try:
+            self.server = rsb.createRemoteServer(self.base_scope + '/set')
+        except ValueError:
+            print "> invalid scope given. server deactivated"
+            self.server.deactivate()
+
+    def set_emotion(self, emotion_id, duration_each, blocking):
+        if (self.server is None):
+            print("> invalid server")
+            return
+
+        #create emotion & fill it with values:
+        em = EmotionState()
+
+        #select ani
+        em.value    = emotion_id
+        em.duration = duration_each
+
+        with rsb.createRemoteServer(self.base_scope + '/set') as server:
+            if (blocking):
+                #blocking:
+                print "> calling the emotion rpc (blocking until we finished talking)..."
+                print '> server reply: "%s"' % server.currentEmotion(em)
+            else:
+               print "> calling the animation rpc (NON-BLOCKING)..."
+               future = server.currentEmotion.async(em)
+               #we can block here for a incoming result with a timeout in s
+               #print '> server reply: "%s"' % future.get(timeout = 10);
+
+        print "> done"
+    
+def main():
+    if (len(sys.argv) != 4):
+        print "> usage: %s <base scope> <emotion id> <duration>\n>     example: %s /flobi1 1 1000" % (sys.argv[0] , sys.argv[0])
+        sys.exit(0)
+
+    # Pacify logger.
+    #logging.basicConfig()
+    em_id = int(sys.argv[2])
+    dur    = int(sys.argv[3])
+    base   = sys.argv[1]
+
+    hlrc_emotion(base).set_emotion(em_id, dur, 1)
+
+if __name__ == '__main__':
+    main()
+
+
diff --git a/client/python/setup.cfg b/client/python/setup.cfg
new file mode 100644
index 0000000..79bc678
--- /dev/null
+++ b/client/python/setup.cfg
@@ -0,0 +1,5 @@
+[bdist_wheel]
+# This flag says that the code is written to work on both Python 2 and Python
+# 3. If at all possible, it is good practice to do this. If you cannot, you
+# will need to generate wheels for each Python version that you support.
+universal=1
diff --git a/client/python/setup.py b/client/python/setup.py
new file mode 100644
index 0000000..bcb63d2
--- /dev/null
+++ b/client/python/setup.py
@@ -0,0 +1,110 @@
+"""[h]igh [l]evel [r]obot [c]ontrol client project
+
+
+See:
+http://opensource.cit-ec.uni-bielefeld.de/hlrc
+"""
+
+# Always prefer setuptools over distutils
+from setuptools import setup, find_packages
+# To use a consistent encoding
+from codecs import open
+from os import path
+
+here = path.abspath(path.dirname(__file__))
+
+# Get the long description from the relevant file
+with open(path.join(here, 'DESCRIPTION.rst'), encoding='utf-8') as f:
+    long_description = f.read()
+
+setup(
+    name='hlrc_client',
+
+    # Versions should comply with PEP440.  For a discussion on single-sourcing
+    # the version across setup.py and the project code, see
+    # https://packaging.python.org/en/latest/single_source_version.html
+    version='1.2.0',
+
+    description='[h]igh [l]evel [r]obot [c]ontrol client project',
+    long_description=long_description,
+
+    # The project's main homepage.
+    url='http://opensource.cit-ec.uni-bielefeld.de/hlrc',
+
+    # Author details
+    author='Simon Schulz',
+    author_email='sschulz@techfak.uni-bielefeld.de',
+
+    # Choose your license
+    license='GPLv3',
+
+    # See https://pypi.python.org/pypi?%3Aaction=list_classifiers
+    classifiers=[
+        # How mature is this project? Common values are
+        #   3 - Alpha
+        #   4 - Beta
+        #   5 - Production/Stable
+        'Development Status :: 3 - Alpha',
+
+        # Indicate who your project is intended for
+        'Intended Audience :: Developers',
+        'Topic :: Scientific/Engineering',
+
+        # Pick your license as you wish (should match "license" above)
+        'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
+
+        # Specify the Python versions you support here. In particular, ensure
+        # that you indicate whether you support Python 2, Python 3 or both.
+        'Programming Language :: Python :: 2',
+        'Programming Language :: Python :: 2.6',
+        'Programming Language :: Python :: 2.7',
+        'Programming Language :: Python :: 3',
+        'Programming Language :: Python :: 3.2',
+        'Programming Language :: Python :: 3.3',
+        'Programming Language :: Python :: 3.4',
+    ],
+
+    # What does your project relate to?
+    keywords='sample setuptools development',
+
+    # You can just specify the packages manually here if your project is
+    # simple. Or you can use find_packages().
+    packages=find_packages(exclude=['contrib', 'docs', 'tests*']),
+
+    # List run-time dependencies here.  These will be installed by pip when
+    # your project is installed. For an analysis of "install_requires" vs pip's
+    # requirements files see:
+    # https://packaging.python.org/en/latest/requirements.html
+    install_requires=['peppercorn'],
+
+    # List additional groups of dependencies here (e.g. development
+    # dependencies). You can install these using the following syntax,
+    # for example:
+    # $ pip install -e .[dev,test]
+    extras_require={
+        'dev': ['check-manifest'],
+        'test': ['coverage'],
+    },
+
+    # If there are data files included in your packages that need to be
+    # installed, specify them here.  If using Python 2.6 or less, then these
+    # have to be included in MANIFEST.in as well.
+    package_data={
+        #'sample': ['package_data.dat'],
+    },
+
+    # Although 'package_data' is the preferred approach, in some case you may
+    # need to place data files outside of your packages. See:
+    # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa
+    # In this case, 'data_file' will be installed into '<sys.prefix>/my_data'
+    data_files=[], #('my_data', ['data/data_file'])],
+
+    # To provide executable scripts, use entry points in preference to the
+    # "scripts" keyword. Entry points provide cross-platform support and allow
+    # pip to create the appropriate form of executable for the target platform.
+    entry_points={
+        'console_scripts': [
+            #'sample=sample:main',
+        ],
+    },
+)
diff --git a/client/python/test.py b/client/python/test.py
new file mode 100644
index 0000000..feee123
--- /dev/null
+++ b/client/python/test.py
@@ -0,0 +1,59 @@
+"""
+This file is part of hlrc
+
+Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+http://opensource.cit-ec.de/projects/hlrc
+
+This file may be licensed under the terms of the
+GNU General Public License Version 3 (the ``GPL''),
+or (at your option) any later version.
+
+Software distributed under the License is distributed
+on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+express or implied. See the GPL for the specific language
+governing rights and limitations.
+
+You should have received a copy of the GPL along with this
+program. If not, go to http://www.gnu.org/licenses/gpl.html
+or write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+The development of this software was supported by the
+Excellence Cluster EXC 277 Cognitive Interaction Technology.
+The Excellence Cluster EXC 277 is a grant of the Deutsche
+Forschungsgemeinschaft (DFG) in the context of the German
+Excellence Initiative.
+"""
+
+import logging
+from hlrc_client import *
+import time
+import sys
+
+if __name__ == "__main__":
+	
+	
+	
+	r = RobotController("ROS", "/flobi", logging.DEBUG)
+	
+	
+	r.set_current_emotion(RobotEmotion(RobotEmotion.SAD))
+	r.set_head_animation(RobotAnimation(RobotAnimation.HEAD_SHAKE))
+	r.set_speak("test 123")
+	
+	g = RobotGaze()
+
+        m = RobotMouth()
+	m.position_center = 10.0
+        m.opening_center = 15.0
+        r.set_mouth_target(m)
+	
+	while(True):
+		g.pan = g.pan + 5.0;
+		if (g.pan > 20.0):
+			g.pan = -20.0
+		r.set_gaze_target(g)
+		time.sleep(1)
+	#e = RobotAnimation()
+	#print e
+	
diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt
new file mode 100644
index 0000000..7e9c443
--- /dev/null
+++ b/server/CMakeLists.txt
@@ -0,0 +1,172 @@
+cmake_minimum_required(VERSION 2.8.3)
+project(hlrc_server)
+
+## System dependencies are found with CMake's conventions
+# find_package(Boost REQUIRED COMPONENTS system)
+
+INCLUDE(FindPkgConfig)
+
+find_package(Boost REQUIRED COMPONENTS system thread)
+
+#######################################
+# check if we have RSB support:
+FIND_PACKAGE(RSB 0.11)
+IF (RSB_FOUND)
+    #RSB
+    SET(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib:\$ORIGIN/")
+    FIND_PACKAGE(RSC 0.11 REQUIRED)
+    FIND_PACKAGE(RSB 0.11 REQUIRED)
+    #RST
+    FIND_PACKAGE(RST REQUIRED COMPONENTS sandbox)
+    INCLUDE_DIRECTORIES(BEFORE SYSTEM ${RST_INCLUDE_DIRS})
+    ADD_DEFINITIONS(${RST_CFLAGS} ${RSTSANDBOX_CFLAGS})
+
+    INCLUDE_DIRECTORIES(BEFORE SYSTEM ${RSB_INCLUDE_DIRS})
+    LIST(INSERT CMAKE_MODULE_PATH 0 ${RSC_CMAKE_MODULE_PATH})
+    #RSB
+    SET(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib:\$ORIGIN/")
+    FIND_PACKAGE(RSC 0.11 REQUIRED)
+    FIND_PACKAGE(RSB 0.11 REQUIRED)
+    #RST
+    FIND_PACKAGE(RST REQUIRED COMPONENTS sandbox)
+    INCLUDE_DIRECTORIES(BEFORE SYSTEM ${RST_INCLUDE_DIRS})
+    ADD_DEFINITIONS(${RST_CFLAGS} ${RSTSANDBOX_CFLAGS})
+
+    INCLUDE_DIRECTORIES(BEFORE SYSTEM ${RSB_INCLUDE_DIRS})
+    LIST(INSERT CMAKE_MODULE_PATH 0 ${RSC_CMAKE_MODULE_PATH})
+
+    message(STATUS "RSB Support is ON")
+    add_definitions(-DRSB_SUPPORT=1)
+ENDIF (RSB_FOUND)
+
+################################################################
+# check for ROS support:
+find_package(catkin)
+IF (catkin_FOUND)
+    SET(ROS_FOUND 1)
+
+    find_package(catkin REQUIRED COMPONENTS roscpp std_msgs sensor_msgs message_generation genmsg actionlib_msgs actionlib)
+
+    message(STATUS "ROS Support is ON")
+    add_definitions(-DROS_SUPPORT=1)
+
+    add_message_files(
+        FILES
+        phoneme.msg
+        soundchunk.msg
+    )
+
+    add_service_files(
+        FILES
+    )
+
+    add_action_files(
+        DIRECTORY action
+        FILES
+        animation.action
+        speech.action
+        utterance.action
+        emotionstate.action
+        gazetarget.action
+        mouthtarget.action
+    )
+
+    generate_messages(
+        DEPENDENCIES
+        actionlib_msgs
+        std_msgs
+        hlrc_server
+    )
+
+    catkin_package(
+        INCLUDE_DIRS include
+        LIBRARIES hlrc_server
+        CATKIN_DEPENDS actionlib_msgs
+        #CATKIN_DEPENDS message_runtime
+        #DEPENDS system_lib
+    )
+ENDIF (catkin_FOUND)
+
+add_definitions ("-Wall")
+
+###################################
+# humotion
+INCLUDE(FindPkgConfig)
+find_package(humotion 0.0.1)
+IF (humotion_FOUND)
+        message("> using humotion includes from " ${humotion_INCLUDE_DIRS})
+ELSE (humotion_FOUND)
+        message(FATAL_ERROR "> error: can not find libhumotion")
+
+endif (humotion_FOUND)
+
+###################################
+# libao audio
+PKG_CHECK_MODULES(AO REQUIRED ao>=1.1.0)
+IF (AO_FOUND)
+  SET(AO_LIBRARY_DIRS "${AO_PREFIX}/lib")
+  SET(AO_INCLUDE_DIRS "${AO_PREFIX}/include")
+  SET(AO_LIBRARIES "ao")
+  MESSAGE("using libao version ${AO_VERSION} from ${AO_PREFIX}")
+ELSE (AO_FOUND)
+  message(FATAL_ERROR "Error: Cannot find libao")
+ENDIF (AO_FOUND)
+
+#build 
+include_directories(include ${catkin_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${humotion_INCLUDE_DIRS} ${AO_INCLUDE_DIRS})
+link_directories(${catkin_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS} ${AO_LIBRARY_DIRS})
+
+#build dummy list of header files
+file(GLOB DUMMY_HEADER_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} include/*.h include/RSB/*.h include/ROS/*.h)
+
+# declare library
+add_executable(${PROJECT_NAME}
+    src/main.cpp
+    src/MiddlewareRSB.cpp
+    src/MiddlewareROS.cpp
+    src/Arbiter.cpp
+    src/Utterance.cpp
+    src/Animation.cpp
+    src/AudioPlayer.cpp
+    src/AudioPlayerRSB.cpp
+    src/AudioPlayerLibAO.cpp
+    src/MouthConfig.cpp
+    src/EmotionState.cpp
+    src/EmotionConfig.cpp
+    src/Middleware.cpp
+    ${MIDDLEWARE_SOURCES}
+    ${DUMMY_HEADER_LIST}
+)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+
+#create example:
+target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} ${RSB_LIBRARIES}  ${catkin_LIBRARIES} ${RST_LIBRARIES} ${humotion_LIBRARIES} ${AO_LIBRARIES})
+
+IF (catkin_FOUND)
+add_dependencies(${PROJECT_NAME} ${catkin_EXPORTED_TARGETS} hlrc_server_gencpp)
+ENDIF (catkin_FOUND)
+
+#    install(TARGETS ${PROJECT_NAME}
+#        ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
+#        LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
+#        RUNTIME DESTINATION bin
+#    )
+
+install(TARGETS ${PROJECT_NAME} DESTINATION bin)
+install(PROGRAMS tools/hlrc_test_gui.py DESTINATION bin)
+install(FILES tools/hlrc_play_animation.py  DESTINATION lib/python2.7/site-packages)
+install(FILES tools/hlrc_speak_utterance.py DESTINATION lib/python2.7/site-packages)
+
+#workaround to keep functionallity of old py scripts:
+install(PROGRAMS tools/hlrc_speak_utterance.py DESTINATION bin)
+install(PROGRAMS tools/hlrc_play_animation.py DESTINATION bin)
+install(PROGRAMS tools/hlrc_set_emotion.py DESTINATION bin)
+
+install(FILES tools/textgrid_hlrc.py DESTINATION lib/python2.7/site-packages)
+
+FILE(GLOB example_files_wav   "${CMAKE_CURRENT_SOURCE_DIR}/tools/examples/*.wav")
+FILE(GLOB example_files_praat "${CMAKE_CURRENT_SOURCE_DIR}/tools/examples/*.praat")
+LIST(APPEND example_files ${example_files_wav} ${example_files_praat})
+install(FILES ${example_files} DESTINATION share/hlrc_server/examples)
+
diff --git a/server/COPYING b/server/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/server/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/server/README.md b/server/README.md
new file mode 100644
index 0000000..b2bff3f
--- /dev/null
+++ b/server/README.md
@@ -0,0 +1,6 @@
+# [h]igh [l]evel [r]obot [c]ontrol server (hlrc_server)
+
+this is the high level robot control server code. this relies
+on a working humotion implementation for your low-level robot control
+framework. see humotion project for further information
+
diff --git a/server/action/animation.action b/server/action/animation.action
new file mode 100644
index 0000000..0eb3ec7
--- /dev/null
+++ b/server/action/animation.action
@@ -0,0 +1,32 @@
+#robot head animation
+
+uint8 IDLE  = 0
+uint8 HEAD_NOD   = 1
+uint8 HEAD_SHAKE = 2
+uint8 EYEBLINK_L = 3
+uint8 EYEBLINK_R = 4
+uint8 EYEBLINK_BOTH  = 5
+uint8 EYEBROWS_RAISE = 6
+uint8 EYEBROWS_LOWER = 7
+uint8 ENGAGEMENT_LEFT = 8
+uint8 ENGAGEMENT_RIGHT = 9
+uint8 target
+
+uint32 repetitions
+
+#in milliseconds
+uint32 duration_each
+
+#influence how pronounced the animation should be executed
+#]0, 1[  => less pronounced
+#[1, 1]  => normal version
+#]1, n]  => over pronounced
+#[-n, 0] => undefined / ignored
+float32  scale
+
+---
+#response
+uint32 result
+
+---
+uint32 result
diff --git a/server/action/emotionstate.action b/server/action/emotionstate.action
new file mode 100644
index 0000000..be757b7
--- /dev/null
+++ b/server/action/emotionstate.action
@@ -0,0 +1,20 @@
+#emotionstate
+
+uint8 NEUTRAL  = 0
+uint8 HAPPY    = 1
+uint8 SAD      = 2
+uint8 ANGRY    = 3
+uint8 SURPRISED = 4
+uint8 FEAR     = 5
+
+uint8 value
+
+#in milliseconds
+uint32 duration
+
+---
+#response
+uint32 result
+
+---
+uint32 result
diff --git a/server/action/gazetarget.action b/server/action/gazetarget.action
new file mode 100644
index 0000000..d1d9122
--- /dev/null
+++ b/server/action/gazetarget.action
@@ -0,0 +1,23 @@
+#pan  angle (left/right)
+float32 pan 
+
+#tilt angle (up/down)
+float32 tilt 
+
+#roll angle (sideway movement)
+float32 roll 
+
+#vergence angle (angle difference from straight view, defaults to 0.0 for straight)
+float32 vergence 
+
+#offsets
+float32 pan_offset
+float32 tilt_offset
+
+---
+#result
+uint32 result
+
+---
+#feedback
+uint32 result
diff --git a/server/action/mouthtarget.action b/server/action/mouthtarget.action
new file mode 100644
index 0000000..d6f1eb3
--- /dev/null
+++ b/server/action/mouthtarget.action
@@ -0,0 +1,16 @@
+float32 opening_left
+float32 opening_right
+float32 opening_center
+
+float32 position_left
+float32 position_center
+float32 position_right
+
+---
+#result
+uint32 result
+
+---
+#feedback
+uint32 result
+
diff --git a/server/action/speech.action b/server/action/speech.action
new file mode 100644
index 0000000..6245a66
--- /dev/null
+++ b/server/action/speech.action
@@ -0,0 +1,8 @@
+string text
+
+---
+#response
+uint32 result
+
+---
+uint32 result
diff --git a/server/action/utterance.action b/server/action/utterance.action
new file mode 100644
index 0000000..e3e31e0
--- /dev/null
+++ b/server/action/utterance.action
@@ -0,0 +1,18 @@
+#utterance
+
+#list of symbol/duration pairs
+phoneme[] phonemes
+
+#sound data (raw data, similar to a wave file)
+soundchunk audio
+
+#textual description
+string text
+
+---
+#response
+uint32 result
+
+---
+uint32 result
+
diff --git a/server/include/Animation.h b/server/include/Animation.h
new file mode 100644
index 0000000..ef7c19e
--- /dev/null
+++ b/server/include/Animation.h
@@ -0,0 +1,97 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include <humotion/gaze_state.h>
+#include "boost/date_time/posix_time/posix_time.hpp"
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/thread.hpp>
+
+class Animation{
+public:
+    Animation();
+    ~Animation();
+
+    void apply_on_gazestate(humotion::GazeState *gaze);
+    void start();
+    bool is_active();
+    bool collides_with(Animation *ani);
+
+
+    typedef enum {
+        IDLE  = 0,
+        HEAD_NOD,
+        HEAD_SHAKE,
+        EYEBLINK_L,
+        EYEBLINK_R,
+        EYEBLINK_BOTH,
+        EYEBROWS_RAISE,
+        EYEBROWS_LOWER,
+        ENGAGEMENT_LEFT,
+        ENGAGEMENT_RIGHT
+    } AnimationType_t;
+
+    AnimationType_t target;
+    unsigned int repetitions;
+    unsigned int duration_each; //in ms
+    float  scale;
+
+    std::string type_as_string(){
+        switch ((int)target){
+            case(IDLE):        return "IDLE";
+            case(HEAD_NOD):    return "HEAD_NOD";
+            case(HEAD_SHAKE):  return "HEAD_SHAKE";
+            case(EYEBLINK_L):  return "EYEBLINK_L";
+            case(EYEBLINK_R):  return "EYEBLINK_R";
+            case(EYEBLINK_BOTH): return "EYEBLINK_BOTH";
+            case(EYEBROWS_RAISE): return "EYEBROWS_RAISE";
+            case(EYEBROWS_LOWER): return "EYEBROWS_LOWER";
+            case(ENGAGEMENT_LEFT): return "ENGAGEMENT_LEFT";
+            case(ENGAGEMENT_RIGHT): return "ENGAGEMENT_RIGHT";
+            default: return "INVALID ID!";
+        }
+    }
+
+    std::string as_string(){
+        char buf[256];
+        snprintf(buf, 255, "Animation: %d times %s (duration each = %dms)", repetitions, type_as_string().c_str(), duration_each);
+        return buf;
+    }
+
+private:
+    float apply_motion_profile_positive(float tn);
+    float apply_motion_profile_symmetric(float tn, unsigned int rep);
+    float apply_motion_profile_asymmetric(float tn, unsigned int rep);
+
+    bool active;
+    unsigned int repetition_now;
+    boost::system_time end_time;
+    boost::system_time start_time;
+};
+
+
diff --git a/server/include/Arbiter.h b/server/include/Arbiter.h
new file mode 100644
index 0000000..9304e8e
--- /dev/null
+++ b/server/include/Arbiter.h
@@ -0,0 +1,101 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include <string>
+#include <humotion/client/client.h>
+#include "EmotionState.h"
+#include "EmotionConfig.h"
+#include "MouthConfig.h"
+#include "Utterance.h"
+#include "AudioPlayer.h"
+#include "Animation.h"
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+class Arbiter{
+public:
+    Arbiter(std::string audio_output);
+    ~Arbiter();
+
+    void arbitrate();
+
+    void set_default_emotion(EmotionState e);
+    void set_current_emotion(EmotionState e);
+    void set_mouth_config(MouthConfig m);
+    void speak(Utterance u);
+    bool speak_active();
+
+    void set_gaze_target(humotion::GazeState g);
+    void set_mouth_target(humotion::MouthState target);
+    void play_animation(boost::shared_ptr<Animation> ani);
+
+    humotion::GazeState  get_gaze_state();
+    humotion::MouthState get_mouth_state();
+
+private:
+    void override_by_emotion();
+    void override_by_gaze();
+    void override_by_animation();
+    void override_by_utterance();
+    void override_by_mouth();
+
+    EmotionConfig emotion_config_current;
+    EmotionConfig emotion_config_default;
+
+    humotion::MouthState mouth_state;
+    humotion::GazeState gaze_state;
+
+    MouthConfig mouth_config;
+
+    Utterance utterance;
+
+    humotion::GazeState requested_gaze_state;
+    humotion::MouthState requested_mouth_state;
+
+
+    boost::mutex emotion_config_default_mutex;
+    boost::mutex emotion_config_current_mutex;
+    boost::mutex mouth_config_override_mutex;
+    boost::mutex utterance_mutex;
+    boost::mutex requested_gaze_state_mutex;
+    boost::mutex requested_mouth_state_mutex;
+    boost::mutex audio_player_mutex;
+
+    boost::mutex animation_mutex;
+    Animation active_animation;
+
+    typedef std::vector<boost::shared_ptr<Animation>> active_animation_vector_t;
+    boost::mutex active_animation_vector_mutex;
+    active_animation_vector_t active_animation_vector;
+
+
+    AudioPlayer *audio_player;
+};
+
+
diff --git a/server/include/AudioData.h b/server/include/AudioData.h
new file mode 100644
index 0000000..03abf3e
--- /dev/null
+++ b/server/include/AudioData.h
@@ -0,0 +1,55 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include <vector>
+#include <string>
+
+class AudioData{
+public:
+    AudioData(){};
+    ~AudioData(){};
+
+    std::vector<char> samples;
+    unsigned int sample_bit;  //8, 16, 24 bits per sample
+    unsigned int sample_rate; //e.g. 44800hz
+    unsigned int sample_channels; //1= mono, 2=stereo etc
+
+    bool sample_big_endian; //true = big endian, false=little endian
+    bool sample_signed;
+
+    std::string to_string(){
+        return "AudioData[ sample_size=" +
+                std::to_string(samples.size()) +
+                " " + std::to_string(sample_bit) + "bits " +
+                " " + std::to_string(sample_rate) + "hz " +
+                std::to_string(sample_channels) + "ch " +
+                (sample_signed?"SIGNED ":"UNSIGNED ") +
+                (sample_big_endian?"BIG ENDIAN ":"LITTLE ENDIAN ") + "]";
+    }
+};
diff --git a/server/include/AudioPlayer.h b/server/include/AudioPlayer.h
new file mode 100644
index 0000000..9182a48
--- /dev/null
+++ b/server/include/AudioPlayer.h
@@ -0,0 +1,62 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include <string>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/shared_ptr.hpp>
+#include "AudioData.h"
+
+class AudioPlayer{
+public:
+
+    AudioPlayer(std::string driver);
+    ~AudioPlayer();
+
+    typedef enum{
+        INITIALIZING=0,
+        IDLE,
+        LOADING,
+        PLAYING,
+        ERROR,
+        EXITING,
+        CLOSED
+    } PLAYBACKSTATE_T;
+
+    virtual void play(AudioData audio) = 0;
+    bool is_playing();
+
+protected:
+    AudioData audio_data;
+    PLAYBACKSTATE_T playback_state;
+    std::string audio_driver;
+    bool playback_requested;
+    bool playback_active;
+};
+
diff --git a/server/include/AudioPlayerLibAO.h b/server/include/AudioPlayerLibAO.h
new file mode 100644
index 0000000..e745308
--- /dev/null
+++ b/server/include/AudioPlayerLibAO.h
@@ -0,0 +1,56 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "AudioPlayer.h"
+#include <ao/ao.h>
+
+class AudioPlayerLibAO : public AudioPlayer{
+public:
+
+    AudioPlayerLibAO(std::string driver);
+    ~AudioPlayerLibAO();
+
+    void playback_thread();
+    void play(AudioData audio);
+    bool is_playing();
+
+
+
+private:
+    ao_sample_format extract_ao_format(AudioData audio);
+    boost::thread *playback_thread_ptr;
+
+    //std::vector<char> audio_data;
+    ao_sample_format  audio_format;
+
+    ao_device *device;
+    int driver;
+
+};
+
diff --git a/server/include/AudioPlayerRSB.h b/server/include/AudioPlayerRSB.h
new file mode 100644
index 0000000..3aadeae
--- /dev/null
+++ b/server/include/AudioPlayerRSB.h
@@ -0,0 +1,55 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "AudioPlayer.h"
+
+#ifdef RSB_SUPPORT
+
+#define BOOST_SIGNALS_NO_DEPRECATION_WARNING 1
+#include <rsb/Informer.h>
+#include <rst/audition/SoundChunk.pb.h>
+
+class AudioPlayerRSB : public AudioPlayer{
+public:
+
+    AudioPlayerRSB(std::string driver);
+    ~AudioPlayerRSB();
+
+    void playback_thread();
+    void play(AudioData audio);
+    bool is_playing();
+
+private:
+    boost::thread *playback_thread_ptr;
+    void publish_audio_data();
+    rsb::Informer<rst::audition::SoundChunk>::DataPtr audio_data_ptr;
+    rsb::Informer<rst::audition::SoundChunk>::Ptr informer;
+};
+
+#endif
diff --git a/server/include/EmotionConfig.h b/server/include/EmotionConfig.h
new file mode 100644
index 0000000..edbe745
--- /dev/null
+++ b/server/include/EmotionConfig.h
@@ -0,0 +1,78 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include <humotion/client/client.h>
+#include "boost/date_time/posix_time/posix_time.hpp"
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/thread.hpp>
+
+
+class EmotionConfig{
+public: 
+
+    typedef enum{
+        NEUTRAL  = 0,
+        HAPPY    = 1,
+        SAD      = 2,
+        ANGRY    = 3,
+        SURPRISED = 4,
+        FEAR     = 5
+    } EmotionType;
+
+
+    EmotionConfig();
+    EmotionConfig(EmotionType e);
+	~EmotionConfig();
+
+    void set_duration(unsigned long ms);
+
+    void select_config(EmotionType e);
+
+    void init_neutral();
+    void init_happy();
+    void init_sad();
+    void init_angry();
+    void init_surprised();
+    void init_fear();
+
+    bool is_active();
+
+
+	//override/influence the gaze state
+	// -> override neck angles (will be added to neck ptr)
+	// -> set eyelid opening (rel to moving eyeball)
+	// -> force eyebrows
+	humotion::GazeState gaze_override;
+
+	//override mouth
+	humotion::MouthState mouth_override;
+private:
+     boost::system_time end_time;
+};
+
diff --git a/server/include/EmotionState.h b/server/include/EmotionState.h
new file mode 100644
index 0000000..08975e8
--- /dev/null
+++ b/server/include/EmotionState.h
@@ -0,0 +1,43 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "EmotionConfig.h"
+
+
+class EmotionState{
+public:
+    EmotionState();
+    ~EmotionState();
+
+    EmotionConfig::EmotionType value;
+    unsigned int duration;
+
+};
+
+
diff --git a/server/include/Middleware.h b/server/include/Middleware.h
new file mode 100644
index 0000000..d6a792c
--- /dev/null
+++ b/server/include/Middleware.h
@@ -0,0 +1,59 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#define BOOST_SIGNALS_NO_DEPRECATION_WARNING 1
+
+#include <string>
+#include "EmotionState.h"
+#include "Arbiter.h"
+
+class Middleware {
+public:
+    Middleware(Arbiter *arbiter, std::string _base_scope);
+    ~Middleware();
+    virtual void init() = 0;
+    virtual void tick() = 0;
+
+    void speak_callback(std::string text);
+    void utterance_callback(Utterance u);
+    void gaze_callback(humotion::GazeState gaze);
+    void mouth_callback(humotion::MouthState mouth);
+    void default_emotion_callback(EmotionState emotion_state);
+    void current_emotion_callback(EmotionState emotion_state);
+    void animation_callback(boost::shared_ptr<Animation> ani);
+
+    virtual Utterance tts_call(std::string text) = 0;
+
+protected:
+    Arbiter *arbiter;
+    std::string base_scope;
+};
+
+
+
diff --git a/server/include/MiddlewareROS.h b/server/include/MiddlewareROS.h
new file mode 100644
index 0000000..5b1a13e
--- /dev/null
+++ b/server/include/MiddlewareROS.h
@@ -0,0 +1,95 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "Middleware.h"
+#ifdef ROS_SUPPORT
+    #include "ros/ros.h"
+    //messages
+    #include "hlrc_server/phoneme.h"
+    #include "hlrc_server/soundchunk.h"
+    //actions
+    #include "hlrc_server/gazetargetAction.h"
+
+    #include "ROS/GazeCallbackWrapperROS.h"
+    #include "ROS/MouthCallbackWrapperROS.h"
+    #include "ROS/UtteranceCallbackWrapperROS.h"
+    #include "ROS/EmotionCallbackWrapperROS.h"
+    #include "ROS/AnimationCallbackWrapperROS.h"
+    #include "ROS/SpeechCallbackWrapperROS.h"
+#endif
+#include <boost/shared_ptr.hpp>
+
+
+class MiddlewareROS : public Middleware{
+#ifndef ROS_SUPPORT
+public:
+    MiddlewareROS(Arbiter *a, std::string _base_scope) : Middleware(a, _base_scope){
+        printf("> ERROR: hlrc was compiled without ROS middleware support. Please use MiddlewareRSB() instead!\n\n");
+        exit(EXIT_FAILURE);
+    }
+
+    ~MiddlewareROS(){}
+    void init(){};
+    void tick(){};
+
+    Utterance tts_call(std::string text){
+        return Utterance();
+    }
+
+#else
+public:
+    MiddlewareROS(Arbiter *a, std::string _base_scope);
+    ~MiddlewareROS();
+    void init();
+    void tick();
+    Utterance tts_call(std::string text);
+
+private:
+    //boost::shared_ptr<ros::NodeHandle> node_handle;
+    ros::NodeHandle *ros_node_handle;
+    bool tick_necessary;
+    /*ros::ServiceServer animation_service;
+    ros::ServiceServer utterance_service;
+    ros::ServiceServer default_emotion_service;
+    ros::ServiceServer current_emotion_service;
+    ros::ServiceServer gaze_service;
+    ros::ServiceServer tts_service;*/
+    AnimationCallbackWrapper *animation_action_server;
+    UtteranceCallbackWrapper *utterance_action_server;
+    EmotionCallbackWrapper *current_emotion_action_server;
+    EmotionCallbackWrapper *default_emotion_action_server;
+    GazeCallbackWrapper *gaze_action_server;
+    MouthCallbackWrapper *mouth_action_server;
+    SpeechCallbackWrapper *speech_action_server;
+#endif
+};
+
+
+
+
diff --git a/server/include/MiddlewareRSB.h b/server/include/MiddlewareRSB.h
new file mode 100644
index 0000000..4e8dca7
--- /dev/null
+++ b/server/include/MiddlewareRSB.h
@@ -0,0 +1,74 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "Middleware.h"
+#ifdef RSB_SUPPORT
+    #define BOOST_SIGNALS_NO_DEPRECATION_WARNING 1
+    #include <rsb/Listener.h>
+    #include <rsb/patterns/LocalServer.h>
+    #include <rsb/patterns/RemoteServer.h>
+#endif
+
+class MiddlewareRSB : public Middleware{
+#ifndef RSB_SUPPORT
+public:
+    MiddlewareRSB(Arbiter *a, std::string _base_scope) : Middleware(a, _base_scope){
+        printf("> ERROR: hlrc was compiled without RSB middleware support. Please use MiddlewareROS() instead!\n\n");
+        exit(EXIT_FAILURE);
+    }
+
+    ~MiddlewareRSB(){}
+    void init(){};
+    void tick(){};
+    Utterance tts_call(std::string text){
+        return Utterance();
+    }
+
+#else
+public:
+    MiddlewareRSB(Arbiter *a, std::string _base_scope);
+    ~MiddlewareRSB();
+    void init();
+    void tick();
+    Utterance tts_call(std::string text);
+
+private:
+    void init_callbacks();
+    void init_callback(std::string name, rsb::patterns::LocalServer::CallbackPtr callback_ptr);
+
+    rsb::patterns::LocalServerPtr server;
+    rsb::patterns::LocalServerPtr server_parallel;
+    rsb::patterns::RemoteServerPtr tts_server;
+    rsb::ListenerPtr speak_listener;
+#endif
+};
+
+
+
+
diff --git a/server/include/MouthConfig.h b/server/include/MouthConfig.h
new file mode 100644
index 0000000..0c0516f
--- /dev/null
+++ b/server/include/MouthConfig.h
@@ -0,0 +1,55 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include <humotion/client/client.h>
+
+class MouthConfig{
+public:
+
+    MouthConfig();
+    MouthConfig(std::string symbol);
+    ~MouthConfig();
+
+    void apply_on_mouth_state(humotion::MouthState *m);
+    void init_by_symbol(std::string symbol);
+
+private:
+
+
+    enum side_t{
+        LEFT=0,
+        CENTER=1,
+        RIGHT=2
+    };
+
+    float opening[3];
+    bool  override[3];
+
+};
+
diff --git a/server/include/ROS/AnimationCallbackWrapperROS.h b/server/include/ROS/AnimationCallbackWrapperROS.h
new file mode 100644
index 0000000..e2ae4fa
--- /dev/null
+++ b/server/include/ROS/AnimationCallbackWrapperROS.h
@@ -0,0 +1,88 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "hlrc_server/animationAction.h"
+#include "CallbackWrapperROS.h"
+
+//callback handler incoming gaze requests:
+class AnimationCallbackWrapper : CallbackWrapper<hlrc_server::animationAction>{
+protected:
+    hlrc_server::animationFeedback feedback;
+    hlrc_server::animationResult result;
+
+public:
+    AnimationCallbackWrapper(Middleware *mw, std::string scope, std::string name) : CallbackWrapper<hlrc_server::animationAction>(mw, scope, name, boost::bind(&AnimationCallbackWrapper::call, this, _1)){
+        //
+    };
+
+    void call(const GoalConstPtr &goal){
+        hlrc_server::animationGoalConstPtr request = goal;
+        printf("> incoming animation (%d)\n", (int)request->target);
+
+        boost::shared_ptr<Animation> ani(new Animation());
+
+        //everything is ok, will be cleared on failures
+        feedback.result = 1;
+
+        switch ((int) request->target){
+            case(hlrc_server::animationGoal::IDLE):          ani->target = Animation::IDLE; break;
+            case(hlrc_server::animationGoal::HEAD_NOD):      ani->target = Animation::HEAD_NOD; break;
+            case(hlrc_server::animationGoal::HEAD_SHAKE):    ani->target = Animation::HEAD_SHAKE; break;
+            case(hlrc_server::animationGoal::EYEBLINK_L):    ani->target = Animation::EYEBLINK_L; break;
+            case(hlrc_server::animationGoal::EYEBLINK_R):    ani->target = Animation::EYEBLINK_R; break;
+            case(hlrc_server::animationGoal::EYEBLINK_BOTH): ani->target = Animation::EYEBLINK_BOTH; break;
+            case(hlrc_server::animationGoal::EYEBROWS_RAISE):ani->target = Animation::EYEBROWS_RAISE;break;
+            case(hlrc_server::animationGoal::EYEBROWS_LOWER):ani->target = Animation::EYEBROWS_LOWER;break;
+            default:
+                ani->target = Animation::IDLE;
+                printf("> unhandled animatin target %d\n",(int)request->target);
+                //throw std::runtime_error("AnimationCallback: invalid animation id");
+                feedback.result = 0;
+        }
+
+       ani->repetitions   = request->repetitions;
+       ani->duration_each = request->duration_each;
+       ani->scale         = request->scale;
+
+       printf("> new Animation: %s\n", ani->as_string().c_str());
+
+       //send to application
+       mw->animation_callback(ani);
+
+        if (feedback.result){
+            result.result = 1;
+            as_.setSucceeded(result);
+        }else{
+            as_.setAborted(result);
+        }
+
+    }
+};
+
+
diff --git a/server/include/ROS/CallbackWrapperROS.h b/server/include/ROS/CallbackWrapperROS.h
new file mode 100644
index 0000000..b91e2f0
--- /dev/null
+++ b/server/include/ROS/CallbackWrapperROS.h
@@ -0,0 +1,65 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "Middleware.h"
+#include "ros/ros.h"
+#include <actionlib/server/simple_action_server.h>
+#include <actionlib/action_definition.h>
+
+template <typename actionspec> class CallbackWrapper{
+    protected:
+        //NODEHANDLE has to be created before evrything else, otherwise really strange things happen (really!)
+        //ros::NodeHandle nh_;
+
+    public:
+        //get nice macros
+        ACTION_DEFINITION(actionspec);
+
+        CallbackWrapper(Middleware *_mw, std::string scope, std::string _name, boost::function<void (const GoalConstPtr&)> cb = 0) : as_(scope + "/" + _name, cb, false){
+            name = _name;
+            mw = _mw;
+            as_.start();
+        }
+
+        ~CallbackWrapper(){}
+
+
+    protected:
+        double get_timestamp(){
+            //fetch time
+            struct timespec tp;
+            clock_gettime(CLOCK_REALTIME, &tp);
+            return tp.tv_sec+tp.tv_nsec/1000000000.0;
+        };
+
+        actionlib::SimpleActionServer<actionspec> as_;
+
+        std::string name;
+        Middleware *mw;
+};
diff --git a/server/include/ROS/EmotionCallbackWrapperROS.h b/server/include/ROS/EmotionCallbackWrapperROS.h
new file mode 100644
index 0000000..3e7f4ec
--- /dev/null
+++ b/server/include/ROS/EmotionCallbackWrapperROS.h
@@ -0,0 +1,91 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "hlrc_server/emotionstateAction.h"
+#include "CallbackWrapperROS.h"
+
+//callback handler incoming gaze requests:
+class EmotionCallbackWrapper : CallbackWrapper<hlrc_server::emotionstateAction>{
+protected:
+    hlrc_server::emotionstateFeedback feedback;
+    hlrc_server::emotionstateResult result;
+
+
+public:
+
+    EmotionCallbackWrapper(Middleware *mw, std::string scope, std::string name) : CallbackWrapper<hlrc_server::emotionstateAction>(mw, scope, name, boost::bind(&EmotionCallbackWrapper::call, this, _1)){
+        //
+    };
+
+    void call(const GoalConstPtr &goal){
+        hlrc_server::emotionstateGoalConstPtr request = goal;
+        printf("> incoming emotion (%s = %d)\n", name.c_str(), (int)request->value);
+        feedback.result = 1;
+
+        EmotionState emotion_state;
+
+        //extract data & copy it to our datatype (might be good when we allow multiple middlewares in the feature)
+        switch ((int)request->value){
+            case(hlrc_server::emotionstateGoal::NEUTRAL):   emotion_state.value = EmotionConfig::NEUTRAL; break;
+            case(hlrc_server::emotionstateGoal::HAPPY):     emotion_state.value = EmotionConfig::HAPPY; break;
+            case(hlrc_server::emotionstateGoal::SAD):       emotion_state.value = EmotionConfig::SAD; break;
+            case(hlrc_server::emotionstateGoal::ANGRY):     emotion_state.value = EmotionConfig::ANGRY; break;
+            case(hlrc_server::emotionstateGoal::SURPRISED): emotion_state.value = EmotionConfig::SURPRISED; break;
+            case(hlrc_server::emotionstateGoal::FEAR):      emotion_state.value = EmotionConfig::FEAR; break;
+            default:
+                printf("> invalid EmotionState value. exiting\n");
+                feedback.result = 0;
+                return;
+        }
+
+        emotion_state.duration = request->duration;
+
+        //send to application
+        if (name == "defaultEmotion"){
+            //set default emotion:
+            mw->default_emotion_callback(emotion_state);
+        }else if (name == "currentEmotion"){
+            //set current emotion:
+            mw->current_emotion_callback(emotion_state);
+        }else{
+            printf("> invalid method called '%s'\n",name.c_str());
+            return;
+        }
+
+        if (feedback.result){
+            result.result = 1;
+            as_.setSucceeded(result);
+        }else{
+            as_.setAborted(result);
+        }
+
+    }
+};
+
+
diff --git a/server/include/ROS/GazeCallbackWrapperROS.h b/server/include/ROS/GazeCallbackWrapperROS.h
new file mode 100644
index 0000000..bdb33ef
--- /dev/null
+++ b/server/include/ROS/GazeCallbackWrapperROS.h
@@ -0,0 +1,82 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "hlrc_server/gazetargetAction.h"
+#include "CallbackWrapperROS.h"
+
+//callback handler incoming gaze requests:
+class GazeCallbackWrapper : CallbackWrapper<hlrc_server::gazetargetAction>{
+protected:
+    hlrc_server::gazetargetFeedback feedback;
+    hlrc_server::gazetargetResult result;
+
+public:
+
+    GazeCallbackWrapper(Middleware *mw, std::string scope, std::string name) : CallbackWrapper<hlrc_server::gazetargetAction>(mw, scope, name, boost::bind(&GazeCallbackWrapper::call, this, _1)){
+        //
+    };
+
+    void call(const GoalConstPtr &goal){
+        feedback.result = 1;
+
+        hlrc_server::gazetargetGoalConstPtr request = goal;
+        //printf("> incoming gaze (p=%3.1f t=%3.1f r=%3.1f / v=%3.1f)\n", request->pan, request->tilt, request->roll, request->vergence);
+
+        humotion::GazeState gaze_state;
+
+        //fill in gaze
+        gaze_state.pan   = request->pan;
+        gaze_state.tilt  = request->tilt;
+        gaze_state.roll  = request->roll;
+
+        gaze_state.timestamp = get_timestamp(); //FIXME!!
+
+        //default:
+        gaze_state.vergence  = request->vergence;
+
+        gaze_state.pan_offset = request->pan_offset;
+        gaze_state.tilt_offset = request->tilt_offset;
+
+        //processing
+        feedback.result = 1;
+        as_.publishFeedback(feedback);
+
+        //send to application:
+        mw->gaze_callback(gaze_state);
+
+        if (feedback.result){
+            result.result = feedback.result;
+            as_.setSucceeded(result);
+        }else{
+            as_.setAborted(result);
+        }
+
+
+    }
+};
diff --git a/server/include/ROS/MouthCallbackWrapperROS.h b/server/include/ROS/MouthCallbackWrapperROS.h
new file mode 100644
index 0000000..373d2c7
--- /dev/null
+++ b/server/include/ROS/MouthCallbackWrapperROS.h
@@ -0,0 +1,77 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "hlrc_server/mouthtargetAction.h"
+#include "CallbackWrapperROS.h"
+
+//callback handler incoming gaze requests:
+class MouthCallbackWrapper : CallbackWrapper<hlrc_server::mouthtargetAction>{
+protected:
+    hlrc_server::mouthtargetFeedback feedback;
+    hlrc_server::mouthtargetResult result;
+
+public:
+
+    MouthCallbackWrapper(Middleware *mw, std::string scope, std::string name) : CallbackWrapper<hlrc_server::mouthtargetAction>(mw, scope, name, boost::bind(&MouthCallbackWrapper::call, this, _1)){
+        //
+    };
+
+    void call(const GoalConstPtr &goal){
+        feedback.result = 1;
+
+        hlrc_server::mouthtargetGoalConstPtr request = goal;
+
+        humotion::MouthState mouth_state;
+
+        //fill in mouth
+        //#include "RSB/SpeechCallbackWrapper.h".opening_left   = request->opening_left;
+        mouth_state.opening_center = request->opening_center;
+        mouth_state.opening_right  = request->opening_right;
+
+        mouth_state.position_left   = request->position_left;
+        mouth_state.position_center = request->position_center;
+        mouth_state.position_right  = request->position_right;
+
+        //processing
+        feedback.result = 1;
+        as_.publishFeedback(feedback);
+
+        //send to application:
+        mw->mouth_callback(mouth_state);
+
+        if (feedback.result){
+            result.result = feedback.result;
+            as_.setSucceeded(result);
+        }else{
+            as_.setAborted(result);
+        }
+
+
+    }
+};
diff --git a/server/include/ROS/SpeechCallbackWrapperROS.h b/server/include/ROS/SpeechCallbackWrapperROS.h
new file mode 100644
index 0000000..deb7adb
--- /dev/null
+++ b/server/include/ROS/SpeechCallbackWrapperROS.h
@@ -0,0 +1,70 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "hlrc_server/speechAction.h"
+#include "CallbackWrapperROS.h"
+
+//callback handler incoming gaze requests:
+class SpeechCallbackWrapper : CallbackWrapper<hlrc_server::speechAction>{
+protected:
+    hlrc_server::speechFeedback feedback;
+    hlrc_server::speechResult result;
+
+public:
+
+    SpeechCallbackWrapper(Middleware *mw, std::string scope, std::string name) : CallbackWrapper<hlrc_server::speechAction>(mw, scope, name, boost::bind(&SpeechCallbackWrapper::call, this, _1)){
+        //
+    };
+
+    void call(const GoalConstPtr &goal){
+        feedback.result = 1;
+
+        hlrc_server::speechGoalConstPtr request = goal;
+
+        std::string text = request->text;
+
+        //processing
+        feedback.result = 1;
+        as_.publishFeedback(feedback);
+
+        //send to application:
+        text = "<maryxml version=\"0.4\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \
+               c xmlns=\"http://mary.dfki.de/2002/MaryXML\" xml:lang=\"en_US\">" +
+                text +
+                "</maryxml>";
+        mw->speak_callback(text);
+
+        if (feedback.result){
+            result.result = feedback.result;
+            as_.setSucceeded(result);
+        }else{
+            as_.setAborted(result);
+        }
+    }
+};
diff --git a/server/include/ROS/UtteranceCallbackWrapperROS.h b/server/include/ROS/UtteranceCallbackWrapperROS.h
new file mode 100644
index 0000000..918b95c
--- /dev/null
+++ b/server/include/ROS/UtteranceCallbackWrapperROS.h
@@ -0,0 +1,146 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "hlrc_server/utteranceAction.h"
+#include "CallbackWrapperROS.h"
+#include "hlrc_server/phoneme.h"
+#include "hlrc_server/soundchunk.h"
+
+//callback handler incoming gaze requests:
+class UtteranceCallbackWrapper : CallbackWrapper<hlrc_server::utteranceAction>{
+protected:
+    hlrc_server::utteranceFeedback feedback;
+    hlrc_server::utteranceResult result;
+
+public:
+
+    UtteranceCallbackWrapper(Middleware *mw, std::string scope, std::string name) : CallbackWrapper<hlrc_server::utteranceAction>(mw, scope, name, boost::bind(&UtteranceCallbackWrapper::call, this, _1)){
+        //
+    };
+
+    void call(const GoalConstPtr &goal){
+        hlrc_server::utteranceGoalConstPtr request = goal;
+        printf("> incoming utterance '%s' (%d phone symbols)\n", request->text.c_str(), (int)request->phonemes.size());
+
+        //everything is ok, will be cleared on failures
+        feedback.result = 1;
+
+        Utterance utterance;
+
+        //copy values:
+        utterance.set_text(request->text);
+        AudioData audio_data;
+        if (!extract_audio(request->audio, &audio_data)){
+            feedback.result = 0;
+        }
+
+        utterance.set_audio_data(audio_data);
+        utterance.set_phoneme_vector(extract_phoneme_vector(request->phonemes));
+
+        //send to application;
+        mw->utterance_callback(utterance);
+
+
+        if (feedback.result){
+            result.result = 1;
+            as_.setSucceeded(result);
+        }else{
+            as_.setAborted(result);
+        }
+    }
+
+
+    //convert ros message audio data to our own implementation
+    bool extract_audio(hlrc_server::soundchunk sound_chunk, AudioData *audio_data){
+        //extract data:
+        unsigned int audio_len = sound_chunk.data.size();
+        char *audio_data_char = (char *)sound_chunk.data.data();
+
+        //audio.samples = vector<char>(audio_data_char, audio_data_char+audio_len);
+        audio_data->samples.resize(audio_len);
+        audio_data->samples.assign(audio_data_char, audio_data_char+audio_len);
+
+        printf("audio samplesize is %d bytes\n",(int)audio_data->samples.size());
+
+        //extract format:
+        audio_data->sample_signed = true;
+        switch (sound_chunk.sample_type){
+            case(hlrc_server::soundchunk::SAMPLE_U8):  audio_data->sample_signed = false; //and fall through:
+            case(hlrc_server::soundchunk::SAMPLE_S8):  audio_data->sample_bit =  8; break;
+
+            case(hlrc_server::soundchunk::SAMPLE_U16): audio_data->sample_signed = false; //and fall through:
+            case(hlrc_server::soundchunk::SAMPLE_S16): audio_data->sample_bit = 16; break;
+
+            case(hlrc_server::soundchunk::SAMPLE_U24): audio_data->sample_signed = false; //and fall through:
+            case(hlrc_server::soundchunk::SAMPLE_S24): audio_data->sample_bit = 24; break;
+
+            default:
+                printf("> invalid sample type %d in SoundChunk! ignoring request!\n", sound_chunk.sample_type);
+                return false;
+                //throw runtime_error("UtteranceRSB::convert_audio_data() unsupported sample type in soundchunk");
+        }
+
+        //bitrate
+        audio_data->sample_rate = sound_chunk.rate;
+
+        //endianness
+        if (sound_chunk.endianess == hlrc_server::soundchunk::ENDIAN_LITTLE){
+            audio_data->sample_big_endian = false;
+        }else if (sound_chunk.endianess == hlrc_server::soundchunk::ENDIAN_BIG){
+            audio_data->sample_big_endian = true;
+        }else{
+            printf("> invalid SoundChunk byte_format");
+            throw std::runtime_error("UtteranceRSB::convert_audio_data() unsupported byte_format in soundchunk");
+        }
+
+        //number of channels
+        audio_data->sample_channels = sound_chunk.channels;
+
+        printf("> new AudioData: %s\n",audio_data->to_string().c_str());
+
+        return true;
+    }
+
+    //convert ros phoneme vector to out own implementation
+    Utterance::phonemes_vector_t extract_phoneme_vector(std::vector<hlrc_server::phoneme> pv){
+        Utterance::phonemes_vector_t result;
+
+        //extract phoneme vector
+        for(unsigned int i=0; i<pv.size(); i++){
+            hlrc_server::phoneme ros_phoneme = pv[i];
+            Utterance::symbol_duration_pair_t phoneme = make_pair(ros_phoneme.symbol, ros_phoneme.duration);
+            result.push_back(phoneme);
+        }
+
+        return result;
+    }
+
+};
+
+
diff --git a/server/include/RSB/AnimationCallbackWrapper.h b/server/include/RSB/AnimationCallbackWrapper.h
new file mode 100644
index 0000000..50bfeff
--- /dev/null
+++ b/server/include/RSB/AnimationCallbackWrapper.h
@@ -0,0 +1,69 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "CallbackWrapper.h"
+#include "Animation.h"
+
+//callback handler incoming animation requests:
+class AnimationCallbackWrapper : public CallbackWrapper<rst::robot::Animation>{
+    public:
+       AnimationCallbackWrapper(Middleware *mw) : CallbackWrapper(mw){}
+
+       void call(const std::string& method_name, boost::shared_ptr<rst::robot::Animation> input){
+           printf("> incomint animation (method = %s)\n",method_name.c_str());
+
+           //fetch animation passed by rsb:
+           rst::robot::Animation *rst_ani = input.get();
+           boost::shared_ptr<Animation> ani(new Animation());
+
+           switch ((int) rst_ani->target()){
+               case(rst_ani->IDLE):         ani->target = Animation::IDLE; break;
+               case(rst_ani->HEAD_NOD):     ani->target = Animation::HEAD_NOD; break;
+               case(rst_ani->HEAD_SHAKE):   ani->target = Animation::HEAD_SHAKE; break;
+               case(rst_ani->EYEBLINK_L):   ani->target = Animation::EYEBLINK_L; break;
+               case(rst_ani->EYEBLINK_R):   ani->target = Animation::EYEBLINK_R; break;
+               case(rst_ani->EYEBLINK_BOTH):ani->target = Animation::EYEBLINK_BOTH; break;
+               case(rst_ani->EYEBROWS_RAISE):ani->target = Animation::EYEBROWS_RAISE;break;
+               case(rst_ani->EYEBROWS_LOWER):ani->target = Animation::EYEBROWS_LOWER;break;
+               default:
+                   ani->target = Animation::IDLE;
+                   printf("> unhandled animatin target %d\n",(int)rst_ani->target());
+                   throw std::runtime_error("AnimationCallback: invalid animation id");
+                   return;
+           }
+           ani->repetitions   = rst_ani->repetitions();
+           ani->duration_each = rst_ani->duration_each();
+           ani->scale         = rst_ani->scale();
+
+           printf("> new Animation: %s\n", ani->as_string().c_str());
+
+           //send to application
+           mw->animation_callback(ani);
+       }
+};
diff --git a/server/include/RSB/CallbackWrapper.h b/server/include/RSB/CallbackWrapper.h
new file mode 100644
index 0000000..5ce7424
--- /dev/null
+++ b/server/include/RSB/CallbackWrapper.h
@@ -0,0 +1,53 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "Middleware.h"
+#include <rst/robot/EmotionState.pb.h>
+#include <rst/robot/GazeTarget.pb.h>
+#include <rst/robot/MouthTarget.pb.h>
+#include <rst/robot/Animation.pb.h>
+#include <rst/audition/Utterance.pb.h>
+#include <rst/audition/SoundChunk.pb.h>
+#include <rsb/Factory.h>
+
+template <typename T>
+class CallbackWrapper : public rsb::patterns::LocalServer::Callback<T, void>{
+    public:
+        CallbackWrapper(Middleware *_mw){
+            mw = _mw;
+        }
+
+
+        ~CallbackWrapper(){}
+
+        virtual void call(const std::string&, boost::shared_ptr<T> param) = 0;
+
+    protected:
+        Middleware *mw;
+};
diff --git a/server/include/RSB/EmotionCallbackWrapper.h b/server/include/RSB/EmotionCallbackWrapper.h
new file mode 100644
index 0000000..3e4319e
--- /dev/null
+++ b/server/include/RSB/EmotionCallbackWrapper.h
@@ -0,0 +1,69 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "CallbackWrapper.h"
+
+//callback handler incoming emotion requests:
+class EmotionCallbackWrapper : public CallbackWrapper<rst::robot::EmotionState>{
+    public:
+       EmotionCallbackWrapper(Middleware *mw) : CallbackWrapper(mw){}
+
+       void call(const std::string& method_name, boost::shared_ptr<rst::robot::EmotionState> input){
+           printf("> incoming emotion (%s = %d)\n", method_name.c_str(),(int)input->value());
+
+           EmotionState emotion_state;
+           rst::robot::EmotionState *emotion = input.get();
+
+           //extract data & copy it to our datatype (might be good when we allow multiple middlewares in the feature)
+           switch ((int)emotion->value()){
+               case(rst::robot::EmotionState_EmotionType_NEUTRAL):   emotion_state.value = EmotionConfig::NEUTRAL; break;
+               case(rst::robot::EmotionState_EmotionType_HAPPY):     emotion_state.value = EmotionConfig::HAPPY; break;
+               case(rst::robot::EmotionState_EmotionType_SAD):       emotion_state.value = EmotionConfig::SAD; break;
+               case(rst::robot::EmotionState_EmotionType_ANGRY):     emotion_state.value = EmotionConfig::ANGRY; break;
+               case(rst::robot::EmotionState_EmotionType_SURPRISED): emotion_state.value = EmotionConfig::SURPRISED; break;
+               case(rst::robot::EmotionState_EmotionType_FEAR):      emotion_state.value = EmotionConfig::FEAR; break;
+               default:
+               printf("> invalid EmotionState value. exiting\n"); exit(EXIT_FAILURE);
+           }
+
+           emotion_state.duration = emotion->duration();
+
+           //send to application
+           if (method_name == "defaultEmotion"){
+               //set default emotion:
+               mw->default_emotion_callback(emotion_state);
+           }else if (method_name == "currentEmotion"){
+               //set current emotion:
+               mw->current_emotion_callback(emotion_state);
+           }else{
+               printf("> invalid method called '%s'\n",method_name.c_str());
+               exit(EXIT_FAILURE);
+           }
+        }
+};
diff --git a/server/include/RSB/GazeCallbackWrapper.h b/server/include/RSB/GazeCallbackWrapper.h
new file mode 100644
index 0000000..2d1abab
--- /dev/null
+++ b/server/include/RSB/GazeCallbackWrapper.h
@@ -0,0 +1,56 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "CallbackWrapper.h"
+
+//callback handler incoming gaze requests:
+class GazeCallbackWrapper : public CallbackWrapper<rst::robot::GazeTarget>{
+    public:
+        GazeCallbackWrapper(Middleware *mw) : CallbackWrapper(mw){}
+        void call(const std::string& method_name, boost::shared_ptr<rst::robot::GazeTarget> input){
+            rst::robot::GazeTarget *gaze = input.get();
+            //printf("> incoming gaze (p=%3.1f t=%3.1f r=%3.1f / v=%3.1f)\n", gaze->pan(), gaze->tilt(), gaze->roll(), gaze->vergence());
+
+            humotion::GazeState gaze_state;
+
+            //fill in gaze
+            gaze_state.pan   = gaze->pan();
+            gaze_state.tilt  = gaze->tilt();
+            gaze_state.roll  = gaze->roll();
+            gaze_state.timestamp = 123.45; //FIXME!!
+            //vergence
+            gaze_state.vergence  = (gaze->has_vergence())?gaze->vergence():0.0;
+            //offsets
+            gaze_state.pan_offset  = (gaze->has_pan_offset())?gaze->pan_offset():0.0;
+            gaze_state.tilt_offset = (gaze->has_tilt_offset())?gaze->tilt_offset():0.0;
+            
+            //send to application:
+            mw->gaze_callback(gaze_state);
+        }
+};
diff --git a/server/include/RSB/MouthCallbackWrapper.h b/server/include/RSB/MouthCallbackWrapper.h
new file mode 100644
index 0000000..766e050
--- /dev/null
+++ b/server/include/RSB/MouthCallbackWrapper.h
@@ -0,0 +1,53 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "CallbackWrapper.h"
+
+//callback handler incoming gaze requests:
+class MouthCallbackWrapper : public CallbackWrapper<rst::robot::MouthTarget>{
+    public:
+        MouthCallbackWrapper(Middleware *mw) : CallbackWrapper(mw){}
+        void call(const std::string& method_name, boost::shared_ptr<rst::robot::MouthTarget> input){
+            rst::robot::MouthTarget *mouth = input.get();
+
+            humotion::MouthState mouth_state;
+
+            //fill in mouth
+            mouth_state.opening_left   = mouth->opening_left();
+            mouth_state.opening_center = mouth->opening_center();
+            mouth_state.opening_right  = mouth->opening_right();
+
+            mouth_state.position_left   = mouth->position_left();
+            mouth_state.position_center = mouth->position_center();
+            mouth_state.position_right  = mouth->position_right();
+
+            //send to application:
+            mw->mouth_callback(mouth_state);
+        }
+};
diff --git a/server/include/RSB/SpeechCallbackWrapper.h b/server/include/RSB/SpeechCallbackWrapper.h
new file mode 100644
index 0000000..f642e83
--- /dev/null
+++ b/server/include/RSB/SpeechCallbackWrapper.h
@@ -0,0 +1,48 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "CallbackWrapper.h"
+
+//callback handler incoming speech requests:
+class SpeechCallbackWrapper : public CallbackWrapper<std::string>{
+    public:
+       SpeechCallbackWrapper(Middleware *mw) : CallbackWrapper(mw){}
+
+       void call(const std::string&, boost::shared_ptr<std::string> _text){
+            //send to application
+           std::string text = *_text.get();
+   	   //<voice effect=\"Rate(durScale:1.5) + TractScaler(durScale:1.1)\">" +
+
+           text = "<maryxml version=\"0.4\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \
+                  c xmlns=\"http://mary.dfki.de/2002/MaryXML\" xml:lang=\"en_US\">" +
+                   text + 
+                   "</maryxml>";
+            mw->speak_callback(text);
+        }
+};
diff --git a/server/include/RSB/UtteranceCallbackWrapper.h b/server/include/RSB/UtteranceCallbackWrapper.h
new file mode 100644
index 0000000..bd45e11
--- /dev/null
+++ b/server/include/RSB/UtteranceCallbackWrapper.h
@@ -0,0 +1,50 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "CallbackWrapper.h"
+#include "UtteranceRSB.h"
+
+//callback handler incoming Utterance requests:
+class UtteranceCallbackWrapper : public CallbackWrapper<rst::audition::Utterance>{
+    public:
+        UtteranceCallbackWrapper(Middleware *mw) : CallbackWrapper(mw){}
+        void call(const std::string&, boost::shared_ptr<rst::audition::Utterance> param){
+            //convert rsb utterance to out own:
+            rst::audition::Utterance *rst_utterance = param.get();
+            printf("> incoming utterance '%s' (%d phone symbols)\n", param->text().c_str(), (int)rst_utterance->phonemes().size());
+
+            Utterance utterance = UtteranceRSB(*rst_utterance);
+
+            //send to application;
+            mw->utterance_callback(utterance);
+        }
+
+    private:
+
+};
diff --git a/server/include/RSB/UtteranceRSB.h b/server/include/RSB/UtteranceRSB.h
new file mode 100644
index 0000000..5e43ee9
--- /dev/null
+++ b/server/include/RSB/UtteranceRSB.h
@@ -0,0 +1,110 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include "AudioData.h"
+#include <rst/audition/SoundChunk.pb.h>
+#include <rst/audition/Utterance.pb.h>
+using namespace std;
+
+//converter from rsb utterance
+class UtteranceRSB : public Utterance {
+    public:
+        UtteranceRSB(rst::audition::Utterance rst_utterance){
+            //set text:
+            set_text(rst_utterance.text());
+
+            //convert soundchunk to audio data:
+            extract_audio_data(rst_utterance.audio());
+
+            //convert phonemes:
+            extract_phonemes(rst_utterance);
+        }
+
+        ~UtteranceRSB(){};
+
+        void extract_audio_data(rst::audition::SoundChunk sound_chunk){
+            //cout << sound_chunk.DebugString();
+
+            //extract data:
+            unsigned int audio_len = sound_chunk.data().length();
+            char *audio_data_char = (char *)sound_chunk.data().c_str();
+
+            //audio.samples = vector<char>(audio_data_char, audio_data_char+audio_len);
+            audio_data.samples.resize(audio_len);
+            audio_data.samples.assign(audio_data_char, audio_data_char+audio_len);
+
+            printf("audio samplesize is %d bytes\n",(unsigned int)audio_data.samples.size());
+
+            //extract format:
+            audio_data.sample_signed = true;
+            switch (sound_chunk.sample_type()){
+                case(rst::audition::SoundChunk::SAMPLE_U8):  audio_data.sample_signed = false; //and fall through:
+                case(rst::audition::SoundChunk::SAMPLE_S8):  audio_data.sample_bit =  8; break;
+
+                case(rst::audition::SoundChunk::SAMPLE_U16): audio_data.sample_signed = false; //and fall through:
+                case(rst::audition::SoundChunk::SAMPLE_S16): audio_data.sample_bit = 16; break;
+
+                case(rst::audition::SoundChunk::SAMPLE_U24): audio_data.sample_signed = false; //and fall through:
+                case(rst::audition::SoundChunk::SAMPLE_S24): audio_data.sample_bit = 24; break;
+
+                default:
+                    printf("> invalid sample type %d in RST SoundChunk! ignoring request!\n", sound_chunk.sample_type());
+                    throw runtime_error("UtteranceRSB::convert_audio_data() unsupported sample type in rst::audition::SoundChunk");
+            }
+
+            //bitrate
+            audio_data.sample_rate = sound_chunk.rate();
+
+        //endianness
+        if (sound_chunk.endianness() == rst::audition::SoundChunk::ENDIAN_LITTLE){
+            audio_data.sample_big_endian = false;
+        }else if (sound_chunk.endianness() == rst::audition::SoundChunk::ENDIAN_BIG){
+            audio_data.sample_big_endian = true;
+        }else{
+            printf("> invalid SoundChunk byte_format");
+            throw runtime_error("UtteranceRSB::convert_audio_data() unsupported byte_format in rst::audition::SoundChunk");
+        }
+
+        //number of channels
+        audio_data.sample_channels = sound_chunk.channels();
+
+        printf("> new AudioData: %s\n",audio_data.to_string().c_str());
+    }
+
+    void extract_phonemes(rst::audition::Utterance rst_utterance){
+        //extract phoneme vector
+        phonemes_vector.clear();
+        for(int i=0; i<rst_utterance.phonemes().size(); i++){
+            rst::audition::Phoneme rst_phoneme = rst_utterance.phonemes().Get(i);
+            Utterance::symbol_duration_pair_t phoneme = make_pair(rst_phoneme.symbol(), rst_phoneme.duration());
+            phonemes_vector.push_back(phoneme);
+        }
+    }
+};
+
diff --git a/server/include/Utterance.h b/server/include/Utterance.h
new file mode 100644
index 0000000..3525731
--- /dev/null
+++ b/server/include/Utterance.h
@@ -0,0 +1,67 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#pragma once
+#include <string>
+#include <vector>
+#include "boost/date_time/posix_time/posix_time.hpp"
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/thread.hpp>
+#include "AudioData.h"
+
+class Utterance{
+public:
+    typedef std::pair<std::string, unsigned int> symbol_duration_pair_t;
+    typedef std::vector<symbol_duration_pair_t> phonemes_vector_t;
+
+    Utterance();
+    ~Utterance();
+
+    void set_phoneme_vector(phonemes_vector_t p);
+    void set_text(std::string t);
+    void set_audio_data(AudioData a);
+
+    void start_playback();
+    bool is_playing();
+    std::string currently_active_phoneme();
+    AudioData get_audio_data();
+    std::string get_text();
+
+protected:
+    AudioData audio_data;
+    std::string text;
+    phonemes_vector_t phonemes_vector;
+
+private:
+    phonemes_vector_t::iterator phonemes_vector_iterator;
+    boost::system_time symbol_end_time;
+
+    bool playing;
+
+};
+
diff --git a/server/msg/phoneme.msg b/server/msg/phoneme.msg
new file mode 100644
index 0000000..f7b745d
--- /dev/null
+++ b/server/msg/phoneme.msg
@@ -0,0 +1,7 @@
+#phoneme descriprion
+
+#a phone symbol
+string symbol
+#and a duration in ms
+uint32 duration 
+
diff --git a/server/msg/soundchunk.msg b/server/msg/soundchunk.msg
new file mode 100644
index 0000000..a49b7d6
--- /dev/null
+++ b/server/msg/soundchunk.msg
@@ -0,0 +1,33 @@
+#sound chunk
+
+#sample type constants:
+uint8 SAMPLE_S8 = 0
+uint8 SAMPLE_U8 = 1
+uint8 SAMPLE_S16 = 2
+uint8 SAMPLE_U16 = 4
+uint8 SAMPLE_S24 = 8
+uint8 SAMPLE_U24 = 16
+
+#endianess constants:
+uint8 ENDIAN_LITTLE = 0
+uint8 ENDIAN_BIG    = 1
+
+#raw audio data
+uint8[] data
+
+#sample count
+uint32 samplecount
+
+#channel count
+uint32 channels
+
+#sampling rate in hz
+uint32 rate
+
+#sample type (SAMPLE_S8, ...)
+uint8 sample_type
+
+#endianess (ENDIAN_LITTLE or ENDIAN_BIG)
+uint8 endianess
+
+
diff --git a/server/package.xml b/server/package.xml
new file mode 100644
index 0000000..e02a809
--- /dev/null
+++ b/server/package.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+<package>
+  <name>hlrc_server</name>
+  <version>0.0.1</version>
+  <description>the high level robot control server</description>
+
+  <!-- One maintainer tag required, multiple allowed, one person per tag --> 
+  <maintainer email="sschulz@techfak.uni-bielefeld.de">Simon Schulz</maintainer>
+
+
+  <!-- One license tag required, multiple allowed, one license per tag -->
+  <!-- Commonly used license strings: -->
+  <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
+  <license>GPLv3</license>
+
+
+  <!-- Url tags are optional, but mutiple are allowed, one per tag -->
+  <!-- Optional attribute type can be: website, bugtracker, or repository -->
+  <!-- Example: -->
+  <url type="website">https://opensource.cit-ec.uni-bielefeld.de/hlrc</url> -->
+  <url type="repository">https://opensource.cit-ec.uni-bielefeld.de/git/hlrc.git</url> -->
+
+  <!-- Author tags are optional, mutiple are allowed, one per tag -->
+  <!-- Authors do not have to be maintianers, but could be -->
+  <!-- Example: -->
+  <!-- <author email="jane.doe@example.com">Jane Doe</author> -->
+
+
+  <!-- The *_depend tags are used to specify dependencies -->
+  <!-- Dependencies can be catkin packages or system dependencies -->
+  <!-- Examples: -->
+  <!-- Use build_depend for packages you need at compile time: -->
+  <!-- <build_depend>message_generation</build_depend> -->
+  <build_depend></build_depend>
+  <run_depend>actionlib_msgs</run_depend>
+  <!-- Use buildtool_depend for build tool packages: -->
+  <!--   <buildtool_depend>catkin</buildtool_depend> -->
+  <!-- Use run_depend for packages you need at runtime: -->
+  <!-- <run_depend>message_runtime</run_depend> -->
+  <!-- Use test_depend for packages you need only for testing: -->
+  <!--   <test_depend>gtest</test_depend> -->
+  <buildtool_depend>catkin</buildtool_depend>
+  <build_depend>roscpp</build_depend>
+  <build_depend>std_msgs</build_depend>
+  <!-- <run_depend>roscpp</run_depend> -->
+  <!-- <run_depend>std_msgs</run_depend> -->
+  <build_depend>actionlib_msgs</build_depend>
+  <!--<build_depend>actionlib</build_depend>
+  <build_depend>actionlib_msgs</build_depend>
+  <run_depend>actionlib</run_depend> -->
+  <!-- <run_depend>actionlib_msgs</run_depend> -->
+
+  <!-- The export tag contains other, unspecified, tags -->
+  <export>
+    <!-- You can specify that this package is a metapackage here: -->
+    <!-- <metapackage/> -->
+
+    <!-- Other tools can request additional information be placed here -->
+
+  </export>
+</package>
diff --git a/server/src/Animation.cpp b/server/src/Animation.cpp
new file mode 100644
index 0000000..3012e8a
--- /dev/null
+++ b/server/src/Animation.cpp
@@ -0,0 +1,286 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "Animation.h"
+using namespace std;
+using namespace boost;
+
+Animation::Animation(){
+    active = false;
+    repetitions = 1;
+    duration_each = 1000.0; //in ms
+    scale = 1.0;
+}
+
+Animation::~Animation(){
+}
+
+void Animation::start(){
+    if (active){
+        printf("> Animation already active. ignored play() call\n");
+        return;
+    }
+
+    active = true;
+    repetition_now = 0;
+
+    //Set up end time
+    int duration = duration_each * repetitions;
+    start_time = get_system_time(); //posix_time::microsec_clock::local_time();
+    end_time   = start_time + boost::posix_time::milliseconds(duration);
+}
+
+bool Animation::is_active(){
+    return active;
+}
+
+//! calculate motion profile based on constant acceleration
+//! \param  tn time now (normalized to [0...1[)
+//! \return value [0...1], f[tn=0] = 0
+float Animation::apply_motion_profile_positive(float tn){
+    float result;
+
+    if ((tn < 0.0) || (tn > 1.0)){
+        printf("> Animation::apply_motion_profile(%4.2f) called with invalid input (allowed is [0..1])\n",tn);
+        return 0.0;
+    }
+
+    if (tn <= 0.5){
+        //accelerated motion
+        result = (2.0 * pow(tn, 2));
+    }else if (tn <= 1.0){
+        //deaccelerate
+        result = (1.0 - 2.0 * pow(1.0 - tn, 2));
+    }
+    return result;
+}
+
+//start from 0, go to +1, go to -1, ... , -1 to 0
+float Animation::apply_motion_profile_symmetric(float tn, unsigned int rep){
+    unsigned int phases = 2*rep + 1;
+    float fstep = 1.0 / phases;
+    float result = 0.0;
+
+    if (tn > 1.0){
+        printf("> apply_motion_profile_symmetric(%f, %d) -> invalid tn > 1.0!\n",tn,rep);
+        exit(1);
+    }else if (tn <= fstep){
+        //first slow advance to +1.0
+        result = apply_motion_profile_positive(tn / (fstep));
+    }else if (tn >= 1.0-fstep){
+        //last slow return from -1 to 0
+        result = -1.0 + apply_motion_profile_positive((tn-(1.0-fstep)) / (fstep));
+    }else{
+        //motion in between, alternating between +1,-1,+1,...,-1
+        //convert to ]0,phases-fstep]
+        float tnn = tn - fstep;
+        //convert to (multiples) ]0,fstep]
+        tnn = fmod(tnn, 2*fstep);
+        //result has to be from+1 to -1
+        if (tnn <= fstep){
+            //+1 -> -1
+            result = 1.0 - 2.0 * apply_motion_profile_positive(tnn/fstep);
+        }else{
+            //-1 -> +1
+            result = -1.0 + 2.0 * apply_motion_profile_positive((tnn-fstep)/fstep);
+        }
+    }
+    return result;
+}
+
+//start from 0, go to +1, goto 0, ... , +1 to 0
+float Animation::apply_motion_profile_asymmetric(float tn, unsigned int rep){
+    unsigned int phases = 2*rep;
+    float fstep = 1.0 / phases;
+    float result = 0.0;
+
+    //motion in between, alternating between 0,1,0,1...
+    //convert to (multiples) ]0,2*fstep]
+    float tnn = fmod(tn, 2*fstep);
+
+    //result has to be from+1 to -1
+    if (tnn <= fstep){
+        //0->1
+        result = apply_motion_profile_positive(tnn/fstep);
+    }else{
+        //1->0
+        result = 1.0 - apply_motion_profile_positive((tnn-fstep)/fstep);
+    }
+    return result;
+}
+
+void Animation::apply_on_gazestate(humotion::GazeState *gaze){
+    //first check: active?
+    if (!active){
+        return;
+    }
+
+    //now check if this animation ended:
+    system_time now = get_system_time(); //posix_time::microsec_clock::local_time();
+    if (now > end_time){
+        active = false;
+        return;
+    }
+
+    //milliseconds from the beginning of this ani:
+    posix_time::time_duration diff = now - start_time;
+    float elapsed_ms = diff.total_milliseconds();
+    //printf("mili %f\n",elapsed_ms);
+
+    float max_elongation = 0.0;
+    float profile = 0.0;
+
+
+    //TODO: animation subclasses instead of switch() !!!
+    switch((int)target){
+        case(IDLE):
+            //nothing to do!
+            break;
+
+        case(HEAD_SHAKE):
+            max_elongation = scale * 15.0;
+            profile = apply_motion_profile_symmetric(elapsed_ms / (repetitions * duration_each), repetitions);
+            gaze->pan_offset = 0.5 * max_elongation * profile;
+            //printf("%f %f %f %f DDD\n",elapsed_ms,elapsed_ms / (repetitions * duration_each), profile, gaze->pan_offset);fflush(stdout);
+            break;
+
+
+        case(HEAD_NOD):
+            max_elongation = scale * 10.0;
+            profile = apply_motion_profile_asymmetric(elapsed_ms / (repetitions * duration_each), repetitions);
+            gaze->tilt_offset = - max_elongation * profile;
+            break;
+
+        case(EYEBLINK_L):
+            if(elapsed_ms >= repetition_now*duration_each){
+                //NOTE: duration/2 because we close the eye for 0.5x the time and keep it open for 0.5x time ;)
+                //      scale can influence this 0.5/0.5 divider. i.e. scale = 0.5 -> 0.25*t closed & 0.75*t open
+                gaze->eyeblink_request_left = scale * duration_each/2;
+                repetition_now++;
+            }
+            break;
+
+        case(EYEBLINK_R):
+            if(elapsed_ms >= repetition_now*duration_each){
+                //NOTE: see EYEBLINK_L for formula description
+                gaze->eyeblink_request_right = scale * duration_each/2;
+                repetition_now++;
+            }
+            break;
+
+        case(EYEBLINK_BOTH):
+            if(elapsed_ms >= repetition_now*duration_each){
+                //NOTE: see EYEBLINK_L for formula description
+                gaze->eyeblink_request_left  = scale * duration_each/2;
+                gaze->eyeblink_request_right = scale * duration_each/2;
+                repetition_now++;
+            }
+            break;
+
+        case(ENGAGEMENT_LEFT):
+            //TODO: use smooth animation instead of step like change
+            gaze->pan_offset = scale * -10.0;
+            break;
+
+        case(ENGAGEMENT_RIGHT):
+            //TODO: use smooth animation instead of step like change
+            gaze->pan_offset = scale * 10.0;
+            break;
+
+        case(EYEBROWS_RAISE):
+            profile = 15.0 * scale * apply_motion_profile_asymmetric(elapsed_ms / (repetitions * duration_each), repetitions);
+            gaze->eyebrow_left   += -profile;
+            gaze->eyebrow_right  +=  profile;
+            break;
+
+        case(EYEBROWS_LOWER):
+            profile = 15.0 * scale * apply_motion_profile_asymmetric(elapsed_ms / (repetitions * duration_each), repetitions);
+            gaze->eyebrow_left   +=  profile;
+            gaze->eyebrow_right  += -profile;
+            break;
+
+
+
+        default:
+            printf("> invalid animation target id (%d)\n",(int)target);
+            active = false;
+            throw runtime_error("unsupported animation id requested");
+            break;
+    }
+
+
+    //ok, currently active. overwrite values:
+    //gaze->tilt_offset = 20;
+    //gaze->roll_offset = 20;
+
+}
+
+
+bool Animation::collides_with(Animation *ani){
+    //same type -> always bad
+    if (ani->target == target) return true;
+
+    switch((int)target){
+        case(IDLE):
+            break;
+
+        default:
+            throw runtime_error("missing collides_with() case for animation");
+            break;
+
+        case(HEAD_SHAKE):
+            break;
+
+
+        case(HEAD_NOD):
+            break;
+
+        case(EYEBLINK_L):
+            if (ani->target == EYEBLINK_BOTH) return true;
+            break;
+
+        case(EYEBLINK_R):
+            if (ani->target == EYEBLINK_BOTH) return true;
+            break;
+
+        case(EYEBLINK_BOTH):
+            if (ani->target == EYEBLINK_L) return true;
+            if (ani->target == EYEBLINK_R) return true;
+            break;
+
+        case(EYEBROWS_RAISE):
+            break;
+
+        case(EYEBROWS_LOWER):
+            break;
+    }
+
+    //fine
+    return false;
+
+}
diff --git a/server/src/Arbiter.cpp b/server/src/Arbiter.cpp
new file mode 100644
index 0000000..335612a
--- /dev/null
+++ b/server/src/Arbiter.cpp
@@ -0,0 +1,292 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "Arbiter.h"
+#include "AudioPlayerLibAO.h"
+#include "AudioPlayerRSB.h"
+#include <boost/algorithm/string/predicate.hpp>
+
+using namespace boost;
+using namespace std;
+
+
+Arbiter::Arbiter(std::string audio_output){
+    //initialize audio player:
+    if (iequals(audio_output.substr(0,3), "rsb")){
+        #ifdef RSB_SUPPORT
+            audio_player = new AudioPlayerRSB(audio_output);
+        #else
+            printf("> ERROR: hlc is compiled without RSB support, RSB audio transport not available, defaulting to libao (default output!)\n");
+            audio_player = new AudioPlayerLibAO("");
+        #endif
+    }else{
+        audio_player = new AudioPlayerLibAO(audio_output);
+    }
+
+    //set default emotion:
+    emotion_config_current.init_sad();
+    emotion_config_current.set_duration(2000);
+    emotion_config_default.init_neutral();
+}
+
+Arbiter::~Arbiter(){
+}
+
+void Arbiter::set_default_emotion(EmotionState e){
+    //lock access
+    mutex::scoped_lock scoped_lock(emotion_config_default_mutex);
+
+    //update our config, ignore duration as this is the default emotion
+    emotion_config_default.select_config(e.value);
+
+    printf("> stored default emotion\n");
+}
+
+void Arbiter::set_current_emotion(EmotionState e){
+    //lock access
+    mutex::scoped_lock scoped_lock(emotion_config_current_mutex);
+
+    //this will set a emotion override for a given time, after the timeout
+    //we will return to the default emotion state:
+    emotion_config_current.select_config(e.value);
+    emotion_config_current.set_duration(e.duration);
+
+    printf("> stored current emotion (val=%d, duration = %dms)\n",e.value, e.duration);
+}
+
+void Arbiter::set_mouth_config(MouthConfig m){
+    //lock access
+    mutex::scoped_lock scoped_lock(mouth_config_override_mutex);
+
+    mouth_config = m;
+}
+
+void Arbiter::set_gaze_target(humotion::GazeState target){
+    //lock access
+    mutex::scoped_lock scoped_lock(requested_gaze_state_mutex);
+
+    requested_gaze_state = target;
+}
+
+void Arbiter::set_mouth_target(humotion::MouthState target){
+    //lock access
+    mutex::scoped_lock scoped_lock(requested_mouth_state_mutex);
+
+    requested_mouth_state = target;
+}
+
+//! note: this is blocking!
+void Arbiter::play_animation(boost::shared_ptr<Animation> incoming_animation){
+    //incoming animation, check if this would conflict with any pending animations:
+    //lock access & iterate over vector:
+    mutex::scoped_lock lock_av(active_animation_vector_mutex);
+    active_animation_vector_t::iterator it;
+    for(it = active_animation_vector.begin(); it<active_animation_vector.end(); it++){
+        boost::shared_ptr<Animation> current_ani = *it;
+        //check if the running animation collides with the incoming animation:
+        if (current_ani->collides_with(incoming_animation.get())){
+            //this would fail, we can not play this animation right now!
+            throw runtime_error("incoming animation collides with unfinished active animation");
+            return;
+        }
+    }
+
+    //ok, fine. no other animations are active that would collide with the new request
+    //thus it is safe to enqueue this item:
+    active_animation_vector.push_back(incoming_animation);
+
+    //unlock mutex
+    lock_av.unlock();
+
+    //start playback!
+    incoming_animation->start();
+
+    //block until ani was played back
+    while(incoming_animation->is_active()){
+        //printf("A"); fflush(stdout);
+        usleep(1*1000); //1ms, save cpu cycles
+    }
+
+    //ok, it finished. we can safely remove it now:
+    lock_av.lock();
+    for(it = active_animation_vector.begin(); it<active_animation_vector.end();){
+        boost::shared_ptr<Animation> current_ani = *it;
+        if (*it == incoming_animation){
+            //printf(">match -> remove incoming ani again\n");
+            it = active_animation_vector.erase(it);
+          }else{
+            ++it;
+          }
+    }
+}
+
+void Arbiter::speak(Utterance u){ //, ao_sample_format audio_format, char *audio_data, unsigned int audio_len){
+    //lock audio playback as such:
+    mutex::scoped_lock scoped_lock_audio(audio_player_mutex);
+
+    //lock utterance & store data:
+    mutex::scoped_lock scoped_lock(utterance_mutex);
+    utterance = u;
+    scoped_lock.unlock();
+
+    //start audio playback, this function returns once we started playback
+    audio_player->play(utterance.get_audio_data());
+    utterance.start_playback();
+
+    //wait until audio playback was finished:
+    while(audio_player->is_playing()){
+        //save some cpu cycles:
+        usleep(1*1000); //1ms
+    }
+    //in case the audio output fails, we end up here before the utterance is finished.
+    //so check now if the utterance finished as well:
+    while (utterance.is_playing()){
+        //save some cpu cycles:
+        usleep(1*1000); //1ms
+    }
+
+}
+
+bool Arbiter::speak_active(){
+    return audio_player->is_playing();
+}
+
+void Arbiter::arbitrate(){
+    //handle arbitration, DO NOT RE-ORDER these calls!
+
+    //try to process all incoming requests
+    override_by_emotion();
+
+    //overwrite with mouth targets from outside:
+    override_by_mouth();
+
+    //lip animation
+    override_by_utterance();
+
+    //animations
+    override_by_animation();
+
+    //gaze target is set by requested_gaze_target
+    override_by_gaze();
+}
+
+void Arbiter::override_by_utterance(){
+    //fetch MouthState by utterance:
+    if (!utterance.is_playing()){
+        //not playing -> return
+        return;
+    }
+
+    //fetch symbol
+    string symbol = utterance.currently_active_phoneme();
+    if ((symbol.empty()) || (symbol == "")){
+        return;
+    }
+
+    //fetch config
+    mouth_config.init_by_symbol(symbol);
+
+    //overwrite mouth with offsets from utterance player
+    mouth_config.apply_on_mouth_state(&mouth_state);
+}
+
+void Arbiter::override_by_mouth(){
+    //external mouth requests can overwrite the mouth targets!
+    if ((requested_mouth_state.position_center + requested_mouth_state.position_left + requested_mouth_state.position_right) > 0.0){
+        //values given -> override emotion data
+        mouth_state = requested_mouth_state;
+    }
+    //requested_mouth_state.dump();
+    //mouth_state.dump();
+}
+
+void Arbiter::override_by_gaze(){
+    //copy from requested target:
+    gaze_state.pan   = requested_gaze_state.pan;
+    gaze_state.tilt  = requested_gaze_state.tilt;
+    gaze_state.roll  = requested_gaze_state.roll;
+
+    gaze_state.timestamp = requested_gaze_state.timestamp;
+    gaze_state.vergence  = requested_gaze_state.vergence;
+
+    //add offset values from user:
+    gaze_state.pan_offset  += requested_gaze_state.pan_offset;
+    gaze_state.tilt_offset += requested_gaze_state.tilt_offset;
+
+}
+
+void Arbiter::override_by_emotion(){
+    //lock access
+    mutex::scoped_lock scoped_lock1(emotion_config_default_mutex);
+    mutex::scoped_lock scoped_lock2(emotion_config_current_mutex);
+
+    EmotionConfig *emotion_target = &emotion_config_default;
+
+    //which emotion is active?
+    if (emotion_config_current.is_active()){
+        //current emotion is not timed out, override default
+        emotion_target = &emotion_config_current;
+    }
+
+    //emotions will set the mouth state here (will be overwritten by speak)
+    mouth_state = emotion_target->mouth_override;
+
+    //emotions will add an offset to the gaze state:
+    //pan,tilt,roll will be overwritten by override_by_gaze() we only keep the offset values from this!
+    //FIXME: change to eyelid opening  upper/lower once humotion supports it
+    //eyebrow angles come from this
+    gaze_state = emotion_target->gaze_override;
+    //gaze_state.dump();
+
+    //IMPORTANT: clear request from emotion target:
+    emotion_target->gaze_override.eyeblink_request_left = 0;
+    emotion_target->gaze_override.eyeblink_request_right = 0;
+
+}
+
+
+void Arbiter::override_by_animation(){
+    //lock access & iterate over vector:
+    mutex::scoped_lock lock_av(active_animation_vector_mutex);
+    active_animation_vector_t::iterator it;
+    for(it = active_animation_vector.begin(); it<active_animation_vector.end(); it++){
+        boost::shared_ptr<Animation> current_ani = *it;
+
+        //gaze_state.dump();
+        current_ani->apply_on_gazestate(&gaze_state);
+        //gaze_state.dump();
+    }
+}
+
+humotion::GazeState Arbiter::get_gaze_state(){
+    return gaze_state;
+}
+
+humotion::MouthState Arbiter::get_mouth_state(){
+    return mouth_state;
+}
diff --git a/server/src/AudioPlayer.cpp b/server/src/AudioPlayer.cpp
new file mode 100644
index 0000000..a5db3eb
--- /dev/null
+++ b/server/src/AudioPlayer.cpp
@@ -0,0 +1,54 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "AudioPlayer.h"
+
+using namespace std;
+
+//new audio player with given driver type
+AudioPlayer::AudioPlayer(string driver){
+    audio_driver = driver;
+    playback_state = INITIALIZING;
+    playback_requested = false;
+    playback_active = false;
+
+    printf("> AudioPlayer(driver=%s)\n",audio_driver.c_str());
+}
+
+bool AudioPlayer::is_playing(){
+    return playback_active;
+}
+
+AudioPlayer::~AudioPlayer(){
+    playback_state = EXITING;
+
+    while(playback_state != CLOSED){
+        printf("> waiting for end of audio playback\n");
+        usleep(1000);
+    }
+}
diff --git a/server/src/AudioPlayerLibAO.cpp b/server/src/AudioPlayerLibAO.cpp
new file mode 100644
index 0000000..d91818f
--- /dev/null
+++ b/server/src/AudioPlayerLibAO.cpp
@@ -0,0 +1,189 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "AudioPlayerLibAO.h"
+
+using namespace std;
+using namespace boost;
+
+//new audio player with gievn device type (default is pulse)
+AudioPlayerLibAO::AudioPlayerLibAO(string driver): AudioPlayer(driver){
+    printf("> using libao for playback\n");
+
+    //initialize
+    ao_initialize();
+
+    //configure driver
+    if (audio_driver.empty()){
+        //use default:
+        driver = ao_default_driver_id();
+    }else{
+        driver = ao_driver_id(audio_driver.c_str());
+    }
+
+    //start audio playback thread:
+    playback_thread_ptr = new boost::thread(boost::bind(&AudioPlayerLibAO::playback_thread, this));
+}
+
+
+//this will return once we start playing
+void AudioPlayerLibAO::play(AudioData audio){
+    audio_data = audio;
+
+    printf("> AudioPlayerLibAO: play() %d samples requested\n",(int)audio_data.samples.size());
+
+    //skip empty audio data
+    if (audio_data.samples.size() == 0){
+        printf("> warning: empty audio data - skipped.\n");
+        return;
+    }
+
+    //check if we can play this file:
+    while(playback_state != IDLE){
+        printf("> player not ready yet, waiting for 10ms\n");
+        usleep(10*1000);
+    }
+
+    audio_format = extract_ao_format(audio_data);
+
+    playback_requested = true;
+
+    //wait for playback to start:
+    printf("> waiting for playback start...\n");
+    while(playback_requested){
+        usleep(1*1000);
+    }
+    printf("> playback running.\n");
+}
+
+
+ao_sample_format AudioPlayerLibAO::extract_ao_format(AudioData audio){
+    ao_sample_format ao_format;
+
+    //get bits per sample
+    ao_format.bits = audio.sample_bit;
+    //bitrate
+    ao_format.rate = audio.sample_rate;
+    //endianess
+    ao_format.byte_format = audio.sample_big_endian?AO_FMT_BIG:AO_FMT_LITTLE;
+    //number of channels
+    ao_format.channels = audio.sample_channels;
+
+    //format matrix:
+    if (ao_format.channels == 1){
+        ao_format.matrix = (char *)"L";
+    }else if(ao_format.channels == 2){
+        ao_format.matrix = (char *)"L,R";
+    }else{
+        printf("> invalid AudioData channel count given. ignoring request\n");
+        throw runtime_error("AudioPlayerLibAO::extract_ao_format() unsupported number of audio channels given in AudioData");
+    }
+
+    return ao_format;
+}
+
+
+
+void AudioPlayerLibAO::playback_thread(){
+    printf("> playback thread started\n");
+    playback_state = IDLE;
+
+    while(playback_state != EXITING){
+        switch (playback_state){
+            default:
+            case(INITIALIZING):
+                //waiting to be ready
+                break;
+
+            case(IDLE):
+                //nothing to do, wait here until we are triggered to play!
+                if (playback_requested){
+                    printf("> AudioPlayer: loading\n");
+                    playback_state = LOADING;
+                }
+                break;
+
+            case(LOADING):
+                //check if we can play that format:
+                device = ao_open_live(driver, &audio_format, NULL /* no options */);
+
+                if (device == NULL){
+                    printf("> AudioPlayer: WARNING: can not open requested audio device. trying to fall back to default driver\n");
+                    driver = ao_default_driver_id();
+                    device = ao_open_live(driver, &audio_format, NULL /* no options */);
+                }
+
+                if (device == NULL){
+                    //failed to init device for format:
+                    printf("> AudioPlayer: WARNING: can not open audio device, not playing audio file!\n");
+                    playback_active = false;
+                    playback_requested = false;
+                    playback_state = IDLE;
+                    break;
+                }else{
+                    //ok we can now play the data
+                    printf("> AudioPlayer: playback started\n");
+                    //mark request as beeing processed
+                    playback_requested = false;
+                    //enter actual playing state
+                    playback_state = PLAYING;
+                    playback_active = true;
+                    ao_play(device, audio_data.samples.data(), audio_data.samples.size());
+                    printf("> AudioPlayer: finished playback\n");
+                }
+                break;
+
+            case(PLAYING):
+                //when we reach this case, the ao_play() call finished
+                //-> we can close this now:
+                ao_close(device);
+                playback_state = IDLE;
+                playback_active = false;
+                printf("> AudioPlayer: device closed\n");
+                break;
+
+            case(ERROR):
+                printf("> AudioPlayer ERROR! exiting\n");
+                exit(EXIT_FAILURE);
+                break;
+        }
+
+        //1ms delay to safe cpu time
+        usleep(1000);
+    }
+
+    //shutdown audio!
+    ao_shutdown();
+
+    //done
+    playback_state = CLOSED;
+
+}
+
+AudioPlayerLibAO::~AudioPlayerLibAO(){
+}
diff --git a/server/src/AudioPlayerRSB.cpp b/server/src/AudioPlayerRSB.cpp
new file mode 100644
index 0000000..6da3b3b
--- /dev/null
+++ b/server/src/AudioPlayerRSB.cpp
@@ -0,0 +1,191 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "AudioPlayerRSB.h"
+
+#ifdef RSB_SUPPORT
+#include <rsb/converter/Repository.h>
+#include <rsb/converter/ProtocolBufferConverter.h>
+#include <rsb/Factory.h>
+#include <boost/make_shared.hpp>
+using namespace std;
+using namespace rsb;
+using namespace boost;
+
+
+//new audio player with gievn device type (default is pulse)
+AudioPlayerRSB::AudioPlayerRSB(string driver): AudioPlayer(driver){
+    assert(driver.length() > 3);
+
+    string scope = driver.substr(3);
+
+    printf("> using rsb for playback, scope = '%s'\n", scope.c_str());
+
+
+    printf("> registering converters\n");
+    rsb::converter::Converter<string>::Ptr soundChunkConverter(new rsb::converter::ProtocolBufferConverter<rst::audition::SoundChunk>());
+    rsb::converter::converterRepository<string>()->registerConverter(soundChunkConverter);
+
+    //first get a factory instance that is used to create RSB domain objects
+    Factory &factory = getFactory();
+
+    //create informer
+    informer = factory.createInformer<rst::audition::SoundChunk> (scope);
+
+    //start audio playback thread:
+    playback_thread_ptr = new boost::thread(boost::bind(&AudioPlayerRSB::playback_thread, this));
+}
+
+
+//this will return once we start playing
+void AudioPlayerRSB::play(AudioData _audio_data){
+    audio_data = _audio_data;
+
+    printf("> AudioPlayerRSB: play() %d samples requested\n",(int)audio_data.samples.size());
+
+    //check if we can play this file:
+    while(playback_state != IDLE){
+        printf("> player not ready yet, waiting for 10ms\n");
+        usleep(10*1000);
+    }
+
+    //ok, we can play the audio. copy/setup data:
+    //audio_data_ptr = boost::shared_ptr<rst::audition::SoundChunk>(boost::make_shared<rst::audition::SoundChunk>(*audio_chunk));
+    playback_requested = true;
+}
+
+
+void AudioPlayerRSB::playback_thread(){
+    printf("> playback thread started\n");
+    playback_state = IDLE;
+
+    while(playback_state != EXITING){
+        switch (playback_state){
+            default:
+            case(INITIALIZING):
+                //waiting to be ready
+                break;
+
+            case(IDLE):
+                //nothing to do, wait here until we are triggered to play!
+                if (playback_requested){
+                    printf("> AudioPlayerRSB: loading\n");
+                    playback_state = LOADING;
+                }
+                break;
+
+            case(LOADING):{
+                //send the data
+                try{
+                    publish_audio_data();
+                }catch (std::exception e) {
+                        printf("> AudioPlayerRSB: WARNING: failed to call informer. audio playback probably failed\n> error message = %s",e.what());
+                        playback_active = false;
+                        playback_requested = false;
+                        playback_state = IDLE;
+                        break;
+                }
+
+                //add some delay to meet the delay until playback starts (FIXME: this should be determined!)
+                //usleep(100*1000); //100ms
+
+                //ok we can now play the data
+                printf("> AudioPlayer: playback started\n");
+                //mark request as beeing processed
+                playback_requested = false;
+                //enter actual playing state
+                playback_state = PLAYING;
+                playback_active = true;
+
+                //now we have to wait until the audio playback finished....
+                long sample_count = audio_data_ptr->sample_count();
+                int sampling_rate  = audio_data_ptr->rate();
+                double playback_time = (double)sample_count / (double)sampling_rate;
+                printf("> AudioPlayerRSB estimated playbacktine to %5.3lf seconds. will wait now...",playback_time);
+                boost::this_thread::sleep(boost::posix_time::milliseconds(1000.0 * playback_time));
+                printf("> AudioPlayerRSB finished waiting...\n");
+                break;
+            }
+
+            case(PLAYING):
+                //when we reach this case, the playback finshed
+                playback_state = IDLE;
+                playback_active = false;
+                printf("> AudioPlayerRSB: finished playback");
+                break;
+
+            case(ERROR):
+                printf("> AudioPlayerRSB ERROR! exiting\n");
+                exit(EXIT_FAILURE);
+                break;
+        }
+
+        //1ms delay to safe cpu time
+        usleep(1000);
+    }
+
+    //done
+    playback_state = CLOSED;
+}
+
+void AudioPlayerRSB::publish_audio_data(){
+    boost::shared_ptr<rst::audition::SoundChunk> request(new rst::audition::SoundChunk());
+
+    request->set_channels(audio_data.sample_channels);
+    request->set_data(audio_data.samples.data());
+/*
+    if (audio_data.sample_big_endian){
+        request->set_endianness(rst::audition::SoundChunk_EndianNess_ENDIAN_BIG);
+    }else{
+        request->set_endianness(rst::audition::SoundChunk_EndianNess_ENDIAN_LITTLE);
+    }
+
+    request->set_rate(audio_data.sample_rate);
+    request->set_sample_count(audio_data.samples.size() / audio_data.sample_channels / (audio_data.sample_bit/8));
+
+    switch (audio_data.sample_bit){
+        case(8):
+            request->set_sample_type(audio_data.sample_signed?(rst::audition::SoundChunk::SAMPLE_S8):(rst::audition::SoundChunk::SAMPLE_U8));
+            break;
+        case(16):
+            request->set_sample_type(audio_data.sample_signed?(rst::audition::SoundChunk::SAMPLE_S16):(rst::audition::SoundChunk::SAMPLE_U16));
+            break;
+        case(24):
+            request->set_sample_type(audio_data.sample_signed?(rst::audition::SoundChunk::SAMPLE_S24):(rst::audition::SoundChunk::SAMPLE_U24));
+            break;
+        default:
+            throw runtime_error("AudioPlayerRSB::publish_audio_data() unsupported sample type bit width");
+    }
+*/
+    informer->publish(request);
+}
+
+AudioPlayerRSB::~AudioPlayerRSB(){
+}
+
+#endif
diff --git a/server/src/EmotionConfig.cpp b/server/src/EmotionConfig.cpp
new file mode 100644
index 0000000..f1e852d
--- /dev/null
+++ b/server/src/EmotionConfig.cpp
@@ -0,0 +1,247 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "EmotionConfig.h"
+using namespace boost;
+
+EmotionConfig::EmotionConfig(){
+    select_config(NEUTRAL);
+}
+
+EmotionConfig::EmotionConfig(EmotionType e){
+    select_config(e);
+}
+
+EmotionConfig::~EmotionConfig(){
+}
+
+
+bool EmotionConfig::is_active(){
+    if (get_system_time() >= end_time){
+        return false;
+    }
+
+    return true;
+}
+
+void EmotionConfig::set_duration(unsigned long ms){
+    //set a timeout:
+    end_time = get_system_time() + posix_time::milliseconds(ms);
+}
+
+void EmotionConfig::select_config(EmotionType e){
+    switch((int) e){
+        default:
+        case(NEUTRAL): init_neutral(); break;
+        case(HAPPY  ): init_happy(); break;
+        case(SAD    ): init_sad(); break;
+        case(ANGRY  ): init_angry(); break;
+        case(SURPRISED): init_surprised(); break;
+        case(FEAR):      init_fear(); break;
+    }
+}
+
+void EmotionConfig::init_neutral(){
+    //neutral = look straight
+    gaze_override.pan_offset = 0.0;
+    gaze_override.tilt_offset = 0.0;
+    gaze_override.roll_offset = 0.0;
+    gaze_override.type = humotion::GazeState::OVERRIDE;
+
+    //not setable right now
+    gaze_override.vergence = 0.0;
+
+    gaze_override.eyelid_opening_upper = 35.0;
+    gaze_override.eyelid_opening_lower = 40.0;
+
+    //eyebrow angles
+    gaze_override.eyebrow_left = -3.0;
+    gaze_override.eyebrow_right = 3.0;
+
+    //eyeblink request
+    gaze_override.eyeblink_request_left  = 0;
+    gaze_override.eyeblink_request_right = 0;
+
+    //mouth:
+    mouth_override.position_left   = 14.7;
+    mouth_override.opening_left    = 0.0;
+    mouth_override.position_center = 16.0;
+    mouth_override.opening_center  = 1.0;
+    mouth_override.position_right  = 14.7;
+    mouth_override.opening_right   = 0.0;
+
+}
+
+void EmotionConfig::init_happy(){
+    //neutral = look straight
+    gaze_override.pan_offset = 0.0;
+    gaze_override.tilt_offset = 0.0;
+    gaze_override.roll_offset = 0.0;
+    gaze_override.type = humotion::GazeState::OVERRIDE;
+
+    //not setable right now
+    gaze_override.vergence = 0.0;
+
+    gaze_override.eyelid_opening_upper = 40.0;
+    gaze_override.eyelid_opening_lower = 40.0;
+
+    //eyebrow angles
+    gaze_override.eyebrow_left = -1.0;
+    gaze_override.eyebrow_right = 1.0;
+
+    //eyeblink request
+    gaze_override.eyeblink_request_left  = humotion::GazeState::EYEBLINK_TIME_DEFAULT;
+    gaze_override.eyeblink_request_right = humotion::GazeState::EYEBLINK_TIME_DEFAULT;
+
+    //mouth:
+    mouth_override.position_left   = 12.5;
+    mouth_override.opening_left    = 0.0;
+    mouth_override.position_center = 14.88;
+    mouth_override.opening_center  = 7.4;
+    mouth_override.position_right  = 12.5;
+    mouth_override.opening_right   = 0.0;
+
+}
+
+void EmotionConfig::init_sad(){
+    gaze_override.pan_offset = 0.0;
+    gaze_override.tilt_offset = -3.0;
+    gaze_override.roll_offset = -3.0;
+    gaze_override.type = humotion::GazeState::OVERRIDE;
+
+    //not setable right now
+    gaze_override.vergence = 0.0;
+
+    gaze_override.eyelid_opening_upper = 15.0;
+    gaze_override.eyelid_opening_lower = 40.0;
+
+    //eyebrow angles
+    gaze_override.eyebrow_left = -20.0;
+    gaze_override.eyebrow_right = 20.0;
+
+    //eyeblink request
+    gaze_override.eyeblink_request_left  = 3 * humotion::GazeState::EYEBLINK_TIME_DEFAULT;
+    gaze_override.eyeblink_request_right = 3 * humotion::GazeState::EYEBLINK_TIME_DEFAULT;
+
+    //mouth:
+    mouth_override.position_left   = 20.0;
+    mouth_override.opening_left    = 0.0;
+    mouth_override.position_center = 16.1;
+    mouth_override.opening_center  = 4.0;
+    mouth_override.position_right  = 20.0;
+    mouth_override.opening_right   = 0.0;
+}
+
+void EmotionConfig::init_angry(){
+    gaze_override.pan_offset = 0.0;
+    gaze_override.tilt_offset = -5.0;
+    gaze_override.roll_offset = 0.0;
+    gaze_override.type = humotion::GazeState::OVERRIDE;
+
+    //not setable right now
+    gaze_override.vergence = 0.0;
+
+    gaze_override.eyelid_opening_upper = 18.0;
+    gaze_override.eyelid_opening_lower = 18.0;
+
+    //eyebrow angles
+    gaze_override.eyebrow_left =  21.0;
+    gaze_override.eyebrow_right = -21.0;
+
+    //eyeblink request
+    gaze_override.eyeblink_request_left  = 0;
+    gaze_override.eyeblink_request_right = 0;
+
+    //mouth:
+    mouth_override.position_left   = 12.5;
+    mouth_override.opening_left    = 0.0;
+    mouth_override.position_center = 16.3;
+    mouth_override.opening_center  = 2.0;
+    mouth_override.position_right  = 17.5;
+    mouth_override.opening_right   = 0.0;
+}
+
+void EmotionConfig::init_surprised(){
+    gaze_override.pan_offset  = 0.0;
+    gaze_override.tilt_offset = 8.0;
+    gaze_override.roll_offset = 0.0;
+    gaze_override.type = humotion::GazeState::OVERRIDE;
+
+    //not setable right now
+    gaze_override.vergence = 0.0;
+
+    //eyelids
+    gaze_override.eyelid_opening_upper = 60.0;
+    gaze_override.eyelid_opening_lower = 60.0;
+
+    //eyebrow angles
+    gaze_override.eyebrow_left =  -2.0;
+    gaze_override.eyebrow_right =  2.0;
+
+    //eyeblink request
+    gaze_override.eyeblink_request_left  = humotion::GazeState::EYEBLINK_TIME_DEFAULT;
+    gaze_override.eyeblink_request_right = humotion::GazeState::EYEBLINK_TIME_DEFAULT;
+
+    //mouth:
+    mouth_override.position_left   = 12.5;
+    mouth_override.opening_left    = 0.0;
+    mouth_override.position_center = 16.3;
+    mouth_override.opening_center  = 9.0;
+    mouth_override.position_right  = 12.5;
+    mouth_override.opening_right   = 0.0;
+}
+
+void EmotionConfig::init_fear(){
+    gaze_override.pan_offset  = 5.0;
+    gaze_override.tilt_offset = 0.0;
+    gaze_override.roll_offset = 0.0;
+    gaze_override.type = humotion::GazeState::ABSOLUTE;
+
+    //not setable right now
+    gaze_override.vergence = 0.0;
+
+    gaze_override.eyelid_opening_upper = 50.0;
+    gaze_override.eyelid_opening_lower = 50.0;
+
+
+    //eyebrow angles
+    gaze_override.eyebrow_left =  -23.0;
+    gaze_override.eyebrow_right =  23.0;
+
+    //eyeblink request
+    gaze_override.eyeblink_request_left  = 0;
+    gaze_override.eyeblink_request_right = 0;
+
+    //mouth:
+    mouth_override.position_left   = 18.9;
+    mouth_override.opening_left    = 0.0;
+    mouth_override.position_center = 16.3;
+    mouth_override.opening_center  = 2.2;
+    mouth_override.position_right  = 18.9;
+    mouth_override.opening_right   = 0.0;
+}
diff --git a/server/src/EmotionState.cpp b/server/src/EmotionState.cpp
new file mode 100644
index 0000000..0ed242d
--- /dev/null
+++ b/server/src/EmotionState.cpp
@@ -0,0 +1,40 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "EmotionState.h"
+#include "EmotionConfig.h"
+
+
+EmotionState::EmotionState(){
+    value = EmotionConfig::NEUTRAL;
+	duration = 0;
+}
+
+EmotionState::~EmotionState(){
+}
+
diff --git a/server/src/Middleware.cpp b/server/src/Middleware.cpp
new file mode 100644
index 0000000..cbc2a7f
--- /dev/null
+++ b/server/src/Middleware.cpp
@@ -0,0 +1,87 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "Middleware.h"
+using namespace std;
+
+Middleware::Middleware(Arbiter *_arbiter, std::string scope){
+    base_scope = scope;
+    arbiter = _arbiter;
+
+    printf("> new Middleware on base scope '%s'\n", base_scope.c_str());
+}
+
+
+Middleware::~Middleware(){
+}
+
+void Middleware::speak_callback(string text){
+    printf("> %s(%s) called\n", __FUNCTION__,text.c_str());
+
+    //call a tts system to convert the text to an utterance:
+    Utterance utterance = tts_call(text);
+
+    //and then process it
+    utterance_callback(utterance);
+}
+
+void Middleware::utterance_callback(Utterance utterance){
+    printf("> %s(text=%s) called\n", __FUNCTION__,utterance.get_text().c_str());
+
+    //can we speak this now?
+    if (arbiter->speak_active()){
+        //we can not start to speak!
+        printf("> still speaking, fixme\n");
+        throw runtime_error("UtteranceCallback: audio playback already running");
+    }else{
+        //fine, play this now, this will block until we finished speaking!
+        arbiter->speak(utterance);
+    }
+}
+
+void Middleware::gaze_callback(humotion::GazeState gaze){
+    //printf("> %s() called\n", __FUNCTION__);
+    arbiter->set_gaze_target(gaze);
+}
+
+void Middleware::mouth_callback(humotion::MouthState mouth){
+    //printf("> %s() called\n", __FUNCTION__);
+    arbiter->set_mouth_target(mouth);
+}
+
+void Middleware::default_emotion_callback(EmotionState emotion_state){
+    arbiter->set_default_emotion(emotion_state);
+}
+
+void Middleware::current_emotion_callback(EmotionState emotion_state){
+    arbiter->set_current_emotion(emotion_state);
+}
+
+void Middleware::animation_callback(boost::shared_ptr<Animation> ani){
+    arbiter->play_animation(ani);
+}
diff --git a/server/src/MiddlewareROS.cpp b/server/src/MiddlewareROS.cpp
new file mode 100644
index 0000000..6c16b33
--- /dev/null
+++ b/server/src/MiddlewareROS.cpp
@@ -0,0 +1,127 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "MiddlewareROS.h"
+
+#ifdef ROS_SUPPORT
+
+#include <cstdio>
+
+//CallbackWrapper:
+#include <boost/range/algorithm/remove_if.hpp>
+#include <boost/algorithm/string/classification.hpp>
+
+using namespace std;
+using namespace hlrc_server;
+
+MiddlewareROS::MiddlewareROS(Arbiter *arbiter, std::string scope) : Middleware(arbiter, scope){
+    init();
+}
+
+MiddlewareROS::~MiddlewareROS(){
+
+}
+
+void MiddlewareROS::init(){
+    string scope = base_scope + "/set/";
+
+    string node_name = "hlrc_server__"+ base_scope;
+    node_name.erase(boost::remove_if(node_name, boost::is_any_of("/")), node_name.end());
+
+    printf("> registering on ROS as node %s\n",node_name.c_str());
+    if (ros::isInitialized()){
+        //ros is already active, no need to take care of that
+        tick_necessary = false;
+    }else{
+        printf("> ROS not initialized, calling ros::init()\n");
+        ros::M_string no_remapping;
+        ros::init(no_remapping, node_name);
+        tick_necessary = true;
+    }
+
+    //create node handle
+    //printf("> creating ros node handle\n");
+    //ros::NodeHa
+    ros::NodeHandle n;
+
+    printf("> setting up ROS services...\n");
+    //FIXME//init_callback("speech",    LocalServer::CallbackPtr(new SpeechCallbackWrapper(this)));
+
+    //ros::AsyncSpinner *spinner = new ros::AsyncSpinner(4); // Use 4 threads
+    //spinner->start();
+
+    animation_action_server = new AnimationCallbackWrapper(this, scope, "animation");
+    utterance_action_server = new UtteranceCallbackWrapper(this, scope, "utterance");
+    current_emotion_action_server = new EmotionCallbackWrapper(this, scope, "currentEmotion");
+    default_emotion_action_server = new EmotionCallbackWrapper(this, scope, "defaultEmotion");
+    gaze_action_server = new GazeCallbackWrapper(this, scope, "gaze");
+    mouth_action_server = new MouthCallbackWrapper(this, scope, "mouth");
+    speech_action_server = new SpeechCallbackWrapper(this, scope, "speech");
+
+    printf("> init done\n");
+}
+
+void MiddlewareROS::tick(){
+    if (tick_necessary){
+        ros::spinOnce();
+    }
+}
+
+//call a tts system to convert a string to an utterance
+Utterance MiddlewareROS::tts_call(string text){
+    //double tts_timeout = 1.0; //seconds. DO NOT CHANGE THIS!
+
+    Utterance utterance;
+
+    printf("> WARNING: ros tts call not implemented yet\n");
+
+/*
+    //build request
+    boost::shared_ptr<std::string> request(new string(text));
+
+    //try to fetch it asynchronously:
+    try{
+        RemoteServer::DataFuture<rst::audition::Utterance> future_ptr = tts_server->callAsync<rst::audition::Utterance>("create_utterance", request);
+
+        //try to fetch the result
+        boost::shared_ptr<rst::audition::Utterance> utterance_ptr = future_ptr.get(tts_timeout);
+        utterance = UtteranceRSB(*(utterance_ptr.get()));
+
+    }catch(rsc::threading::FutureTimeoutException e){
+        printf("> error: tts_call timed out after %3.1f seconds.\n", tts_timeout);
+    }catch(rsc::threading::FutureTaskExecutionException e){
+        printf("> error: tts_call failed: %s\n", e.what());
+    }
+
+    printf("> done. got utterance (text=%s)\n",utterance.get_text().c_str());
+    */
+    return utterance;
+}
+
+
+#endif
diff --git a/server/src/MiddlewareRSB.cpp b/server/src/MiddlewareRSB.cpp
new file mode 100644
index 0000000..2ce7116
--- /dev/null
+++ b/server/src/MiddlewareRSB.cpp
@@ -0,0 +1,165 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "MiddlewareRSB.h"
+
+#ifdef RSB_SUPPORT
+#include <rsb/converter/Repository.h>
+#include <rsb/converter/ProtocolBufferConverter.h>
+#include <cstdio>
+
+//CallbackWrapper:
+#include "RSB/GazeCallbackWrapper.h"
+#include "RSB/MouthCallbackWrapper.h"
+#include "RSB/SpeechCallbackWrapper.h"
+#include "RSB/UtteranceCallbackWrapper.h"
+#include "RSB/EmotionCallbackWrapper.h"
+#include "RSB/AnimationCallbackWrapper.h"
+#include "RSB/UtteranceRSB.h"
+using namespace std;
+using namespace rsb;
+using namespace rsb::patterns;
+
+MiddlewareRSB::MiddlewareRSB(Arbiter *arbiter, std::string scope) : Middleware(arbiter, scope){
+    init();
+}
+
+MiddlewareRSB::~MiddlewareRSB(){
+
+}
+
+void MiddlewareRSB::tick(){
+    //nothing to do
+}
+
+void MiddlewareRSB::init(){
+    printf("> registering converters\n");
+
+    //converter for EmotionState
+    rsb::converter::Converter<string>::Ptr emotionStateConverter(new rsb::converter::ProtocolBufferConverter<rst::robot::EmotionState>());
+    rsb::converter::converterRepository<string>()->registerConverter(emotionStateConverter);
+
+    //converter for SoundChunk
+    rsb::converter::Converter<string>::Ptr SoundChunkConverter(new rsb::converter::ProtocolBufferConverter<rst::audition::SoundChunk>());
+    rsb::converter::converterRepository<string>()->registerConverter(SoundChunkConverter);
+
+    //converter for Utterance
+    rsb::converter::Converter<string>::Ptr UtteranceConverter(new rsb::converter::ProtocolBufferConverter<rst::audition::Utterance>());
+    rsb::converter::converterRepository<string>()->registerConverter(UtteranceConverter);
+
+    //converter for GazeTarget
+    rsb::converter::Converter<string>::Ptr gazeTargetConverter(new rsb::converter::ProtocolBufferConverter<rst::robot::GazeTarget>());
+    rsb::converter::converterRepository<string>()->registerConverter(gazeTargetConverter);
+
+    //converter for MouthTarget
+    rsb::converter::Converter<string>::Ptr mouthTargetConverter(new rsb::converter::ProtocolBufferConverter<rst::robot::MouthTarget>());
+    rsb::converter::converterRepository<string>()->registerConverter(mouthTargetConverter);
+
+    //converter for Animation
+    rsb::converter::Converter<string>::Ptr animationConverter(new rsb::converter::ProtocolBufferConverter<rst::robot::Animation>());
+    rsb::converter::converterRepository<string>()->registerConverter(animationConverter);
+
+    //first get a factory instance that is used to create RSB domain objects
+    Factory &factory = getFactory();
+
+    //scope to listen on:
+    string scope = base_scope + "/set/";
+
+    //get server
+    server = factory.createLocalServer(scope);
+
+    //get tts server:
+    string tts_scope = base_scope + "/tts_provider";
+    printf("> registering remote server on %s\n",tts_scope.c_str());
+    tts_server = factory.createRemoteServer(tts_scope);
+
+
+    //create local server with parallel exec strategy (HACK!)
+    rsb::ParticipantConfig config = factory.getDefaultParticipantConfig();
+    rsc::runtime::Properties &properties = config.mutableEventReceivingStrategy().mutableOptions();
+    properties.set<string>("parallelhandlercalls", "1");
+
+    //now we can create a server with parallel execution:
+    server_parallel = factory.createLocalServer(scope, config);
+
+    //this server will now handle/call these methods in multiple threads:
+    server_parallel->registerMethod("animation", LocalServer::CallbackPtr(new AnimationCallbackWrapper(this)));
+
+    //initialise callbacks:
+    init_callbacks();
+
+    //informer->publish(gaze_target);
+    printf("> MiddlewareRSB initialised\n");
+}
+
+void MiddlewareRSB::init_callback(string name, LocalServer::CallbackPtr callback_ptr){
+    printf("> init_callback(%s%s)\n", server->getScope()->toString().c_str(), name.c_str());
+    server->registerMethod(name, callback_ptr);
+}
+
+void MiddlewareRSB::init_callbacks(){
+    printf("> registering callbacks (rpc methods)\n");
+
+    init_callback("speech",    LocalServer::CallbackPtr(new SpeechCallbackWrapper(this)));
+    init_callback("utterance", LocalServer::CallbackPtr(new UtteranceCallbackWrapper(this)));
+    init_callback("gaze",      LocalServer::CallbackPtr(new GazeCallbackWrapper(this)));
+    init_callback("mouth",     LocalServer::CallbackPtr(new MouthCallbackWrapper(this)));
+
+    EmotionCallbackWrapper *emotion_cb = new EmotionCallbackWrapper(this);
+    init_callback("defaultEmotion", LocalServer::CallbackPtr(emotion_cb));
+    init_callback("currentEmotion", LocalServer::CallbackPtr(emotion_cb));
+}
+
+//call a tts system to convert a string to an utterance
+Utterance MiddlewareRSB::tts_call(string text){
+    double tts_timeout = 1.0; //seconds. DO NOT CHANGE THIS!
+
+    Utterance utterance;
+
+    //build request
+    boost::shared_ptr<std::string> request(new string(text));
+
+    //try to fetch it asynchronously:
+    try{
+        RemoteServer::DataFuture<rst::audition::Utterance> future_ptr = tts_server->callAsync<rst::audition::Utterance>("create_utterance", request);
+
+        //try to fetch the result
+        boost::shared_ptr<rst::audition::Utterance> utterance_ptr = future_ptr.get(tts_timeout);
+        utterance = UtteranceRSB(*(utterance_ptr.get()));
+
+    }catch(rsc::threading::FutureTimeoutException e){
+        printf("> error: tts_call timed out after %3.1f seconds.\n", tts_timeout);
+    }catch(rsc::threading::FutureTaskExecutionException e){
+        printf("> error: tts_call failed: %s\n", e.what());
+    }
+
+    printf("> done. got utterance (text=%s)\n",utterance.get_text().c_str());
+    return utterance;
+}
+
+#endif
diff --git a/server/src/MouthConfig.cpp b/server/src/MouthConfig.cpp
new file mode 100644
index 0000000..b13f06c
--- /dev/null
+++ b/server/src/MouthConfig.cpp
@@ -0,0 +1,280 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "MouthConfig.h"
+using namespace std;
+
+MouthConfig::MouthConfig(){
+    init_by_symbol("");
+}
+
+MouthConfig::MouthConfig(string symbol){
+    init_by_symbol(symbol);
+}
+
+
+MouthConfig::~MouthConfig(){
+}
+
+void MouthConfig::init_by_symbol(string symbol){
+    //default is no change:
+    for(int i=0; i<2; i++){
+        opening[i] = 0.0;
+        override[i] = 0.0;
+    }
+
+    //default?
+    if (symbol.length() == 0){
+        return;
+    }
+
+    //see http://www.phon.ucl.ac.uk/home/sampa/german.htm
+    if (symbol.length() ==1){
+        //single digit phonemes:
+        unsigned char sc = symbol.c_str()[0];
+        switch(sc){
+            default:
+                printf("> ignoring unknown phoneme '%c'\n",sc);
+                break;
+
+            case('_'): //pause
+                break;
+
+            case('T'): //en: _th_in
+            case('D'): //en: _th_is
+                //as we dont have a tongue, only open the mouth slighly
+                override[CENTER] = true;
+                opening[CENTER] = 4.0;
+                break;
+
+            case('u'): //en: l_o_se
+                 override[CENTER] = true;
+                 opening[CENTER]  = 13.0;
+
+            case('e'): //en: r_ai_se
+                 override[CENTER] = true;
+                 opening[CENTER]  = 5.0;
+                    break;
+
+            case('V'): //en: c_u_t
+                 override[CENTER] = true;
+                 opening[CENTER]  = 3.0;
+                 break;
+
+            case('{'): //en: p_a_t
+                 //open mouth
+                 override[CENTER] = true;
+                 opening[CENTER]  = 12.0;
+                 break;
+
+            case('w'): //en: _w_asp
+                //mouth nearly closed:
+                override[CENTER] = true;
+                opening[CENTER] = 4.0;
+                break;
+
+            case('p'): //Pein + en: _p_in
+            case('b'): //Bein
+                //close mouth at the center:
+                override[CENTER] = true;
+                break;
+
+            case('t'): //Teich
+            case('d'): //Deich
+            case('k'): //Kunst
+            case('g'): //Gunst
+                //open mouth at the center
+                override[CENTER] = true;
+                opening[CENTER]  = 11.0;
+                break;
+
+            case('?'): //global stop?! ignore
+                break;
+
+            case('f'): //fast
+            case('v'): //was
+            case('@'): // unstressed "schwa" vowel is
+                override[CENTER] = true;
+                opening[CENTER] = 4.0;
+                break;
+
+            case('z'): //Tasse
+            case('s'): //Tasse
+            case('Z'): //Genie
+            case('C'): //Ich
+            case('j'): //Jahr
+            case('x'): //Buch
+            case('h'): //Hand
+                override[CENTER] = true;
+                opening[CENTER] = 7.0;
+                break;
+
+            case('S'): //waschen
+            case('O'): //Trotz
+            case('9'): //plötzlich
+                override[CENTER] = true;
+                opening[CENTER] = 11.0;
+                break;
+
+            case('m'): //mein
+                override[CENTER] = true;
+                break;
+
+            case('n'): //nein
+            case('N'): //Ding
+            case('l'): //leim
+            case('R'): //Reim
+            case('r'): //en: wrong
+            case('I'): //Sitz
+            case('i'): //en: _ea_se
+            case('E'): //gesetz
+            case('a'): //Satz
+            case('U'): //Schutz
+            case('Y'): //hübsch
+                override[CENTER] = true;
+                opening[CENTER] = 7.0;
+                break;
+
+            case('o'): //en: n_o_se
+            case('Q'): //gb: p_o_t
+            case('A'): //english o
+                override[CENTER] = true;
+                opening[CENTER]  = 13.0;
+                break;
+            //r:
+            case('6'): //besser
+                override[CENTER] = true;
+                opening[CENTER] = 3.0;
+                break;
+
+        }
+    }else if (symbol.length() == 2){
+        if (symbol == "pf"){ //Pfahl
+            override[CENTER] = true;
+        }else if(symbol == "ts"){ //Zahl
+            override[CENTER] = true;
+            opening[CENTER]  = 11.0;
+        }else if(symbol == "tS"){ //deutsch
+            override[CENTER] = true;
+            opening[CENTER]  = 10.5;
+        }else if(symbol == "dZ"){ //Dschungel
+            override[CENTER] = true;
+            opening[CENTER]  = 11.0;
+        }else if (
+                (symbol == "OI") || //en: n_oi_se
+                (symbol == "@`") || //en: c_o_rner
+                (symbol == "@U") || //gb: n_o_se
+                (symbol == "o:") || //rot
+                (symbol == "O:") || //gb: c_au_se
+                (symbol == "U@") || //gb: c_u_res
+                (symbol == "u:") || //Blut
+                (symbol == "y:") || //süß
+                (symbol == "2:") || //blöd
+                (symbol == "aU")    //Haus
+                  ){
+            override[CENTER] = true;
+            opening[CENTER]  = 13.0;
+        }else if (
+                (symbol == "i:") || //Lied
+                (symbol == "I@") || //gb: f_ea_rs
+                (symbol == "e:") || //Beet
+                (symbol == "E:") || //spät
+                (symbol == "a:") || //Tat
+                (symbol == "A:")    //gb: st_a_rs
+                  ){
+            override[CENTER] = true;
+            opening[CENTER]  = 9.0;
+        }else if (
+                  (symbol == "aI")|| //Eis
+                  (symbol == "eI")   //gb: r_ai_se
+                  ){
+            override[CENTER] = true;
+            opening[CENTER]  = 5.0;
+        }else if(
+                 (symbol == "OY") || //Kreuz
+                 (symbol == "3:") || //gb: f_ur_s
+                 (symbol == "3`")    //en: f_ur_s
+                 ){
+            override[CENTER] = true;
+            opening[CENTER]  = 5.0;
+        }else if (
+                  (symbol == "I6") || //Wirt
+                  (symbol == "Y6") || //Türke
+                  (symbol == "E6") || //Berg
+                  (symbol == "96") || //Wörter
+                  (symbol == "a6") || //hart
+                  (symbol == "U6") || //kurz
+                  (symbol == "e@") || //gb: st_ai_rs
+                  (symbol == "O6") //dort
+                  ){
+            override[CENTER] = true;
+            opening[CENTER]  = 5.0;
+        }
+    }else if (symbol.length() == 3){
+        if(
+                (symbol == "i:6") || //Tier
+                (symbol == "y:6") || //Tür
+                (symbol == "e:6") || //schwer
+                (symbol == "E:6") || //Bär
+                (symbol == "2:6") || //Föhr
+                (symbol == "a:6") || //Haar
+                (symbol == "u:6") || //Kur
+                (symbol == "o:6")    //Ohr
+                ){
+            override[CENTER] = true;
+            opening[CENTER]  = 5.0;
+        }else{
+            printf("> invalid phoneme '%s' unhandled\n",symbol.c_str());
+        }
+    }else{
+        printf("> invalid phoneme length, phoneme '%s' unhandled\n",symbol.c_str());
+    }
+
+
+}
+
+
+void MouthConfig::apply_on_mouth_state(humotion::MouthState *m){
+    if (override[LEFT]){
+        m->opening_left = opening[LEFT];
+    }else{
+        m->opening_left += opening[LEFT];
+    }
+
+    if (override[CENTER]){
+        m->opening_center = opening[CENTER];
+    }else{
+        m->opening_center += opening[CENTER];
+    }
+
+    if (override[RIGHT]){
+        m->opening_right = opening[RIGHT];
+    }else{
+        m->opening_right += opening[RIGHT];
+    }
+}
diff --git a/server/src/Utterance.cpp b/server/src/Utterance.cpp
new file mode 100644
index 0000000..2dd5619
--- /dev/null
+++ b/server/src/Utterance.cpp
@@ -0,0 +1,118 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "Utterance.h"
+using namespace std;
+using namespace boost;
+
+#define DEBUG_PRINT_PHONEMES 1
+
+Utterance::Utterance(){
+    playing = false;
+    text = "UNINITIALISED UTTERANCE";
+}
+
+void Utterance::set_phoneme_vector(phonemes_vector_t p){
+    phonemes_vector = p;
+}
+
+void Utterance::set_text(string t){
+    text = t;
+}
+
+void Utterance::set_audio_data(AudioData a){
+    audio_data = a;
+}
+
+Utterance::~Utterance(){
+}
+
+string Utterance::get_text(){
+    return text;
+}
+
+AudioData Utterance::get_audio_data(){
+    return audio_data;
+}
+
+void Utterance::start_playback(){
+    if (phonemes_vector.size() == 0){
+        printf("> we have an empty phoneme vector. not playing.\n");
+        return;
+    }
+
+    //set iterator to start:
+    phonemes_vector_iterator = phonemes_vector.begin();
+
+    //fetch first end time
+    symbol_duration_pair_t symbol_duration_pair = *phonemes_vector_iterator;
+    symbol_end_time = get_system_time() + boost::posix_time::milliseconds(symbol_duration_pair.second);
+
+    printf("> we have %d pairs\n",(int)phonemes_vector.size());
+
+    //go!
+    playing = true;
+}
+
+string Utterance::currently_active_phoneme(){
+    //not active -> return
+    if (!playing) return "";
+
+    //empty phoneme list
+    if (phonemes_vector.size() == 0) return "";
+
+    system_time now = get_system_time();
+
+    while(now > symbol_end_time){
+        //fetch next phoneme:
+        symbol_duration_pair_t symbol_duration_pair = *phonemes_vector_iterator;
+        symbol_end_time = symbol_end_time + boost::posix_time::milliseconds(symbol_duration_pair.second);
+        //printf("time: %d", symbol_duration_pair.second);
+
+        //do we have to increment the iterator or are we done? (NOTE: -1 is necessary here!)
+        if (phonemes_vector_iterator < phonemes_vector.end() - 1){
+            phonemes_vector_iterator++;
+        }else{
+            //reached end, stop playback
+            playing=false;
+            return "";
+            if (DEBUG_PRINT_PHONEMES) printf("\n");
+        }
+    }
+
+    //fetch active symbol:
+    string symbol = ((symbol_duration_pair_t)*phonemes_vector_iterator).first;
+    //printf("> active symbol = %s\n",symbol.c_str());
+    if (DEBUG_PRINT_PHONEMES) printf("%s ",symbol.c_str()); fflush(stdout);
+
+    return symbol;
+}
+
+bool Utterance::is_playing(){
+    return playing;
+}
diff --git a/server/src/main.cpp b/server/src/main.cpp
new file mode 100644
index 0000000..d636cfa
--- /dev/null
+++ b/server/src/main.cpp
@@ -0,0 +1,109 @@
+/*
+* This file is part of hlrc_server
+*
+* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
+* http://opensource.cit-ec.de/projects/hlrc_server
+*
+* This file may be licensed under the terms of the
+* GNU General Public License Version 3 (the ``GPL''),
+* or (at your option) any later version.
+*
+* Software distributed under the License is distributed
+* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+* express or implied. See the GPL for the specific language
+* governing rights and limitations.
+*
+* You should have received a copy of the GPL along with this
+* program. If not, go to http://www.gnu.org/licenses/gpl.html
+* or write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The development of this software was supported by the
+* Excellence Cluster EXC 277 Cognitive Interaction Technology.
+* The Excellence Cluster EXC 277 is a grant of the Deutsche
+* Forschungsgemeinschaft (DFG) in the context of the German
+* Excellence Initiative.
+*
+*/
+
+#include "MiddlewareRSB.h"
+#include "MiddlewareROS.h"
+#include "Arbiter.h"
+
+#include <string>
+#include <iostream>
+#include <stdlib.h>
+#include <math.h>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/algorithm/string.hpp>
+
+Arbiter *arbiter;
+
+using namespace std;
+using namespace boost;
+
+int main(int argc, char *argv[]) {
+    if ((argc != 3) && (argc != 4)){
+        printf("> ERROR: no base scope passed to server!\n\nusage: %s <base scopename> <mw> [<audio output>]  (example: %s /flobi1/ RSB pulse )\n",argv[0],argv[0]);
+        printf("          audio output is optional and can be {pulse,oss,alsa,null,sndio,..}\n\n");
+        exit(EXIT_FAILURE);
+    }
+
+    printf("> hlrc_server starting\n");
+
+    //fetch scope from cmd line
+    std::string scope = argv[1];
+
+    //fetch middleware from cmd line
+    std::string mw = argv[2];
+    to_upper(mw); //convert to uppercase
+
+    //arbiter
+    std::string sound_output = "pulse";
+    if (argc == 4){
+        sound_output = argv[3];
+    }
+    arbiter = new Arbiter(sound_output);
+
+    //mw connection
+    Middleware *middleware;
+    if (mw == "ROS"){
+        middleware = new MiddlewareROS(arbiter, scope);
+    }else{
+        middleware = new MiddlewareRSB(arbiter, scope);
+    }
+
+    //human motion connection:
+    printf("> initializing humotion client\n");
+    humotion::client::Client *client = new humotion::client::Client(scope, "ROS");
+
+    printf("> all done. hlrc server ready\n");
+
+    //send values to human motion server
+    float loop_delay = 1000.0 / 50.0; //run with 50Hz
+    boost::system_time timeout = get_system_time() + posix_time::milliseconds(loop_delay);
+
+    while(client->ok()){
+        middleware->tick();
+
+        //find correct arbitration
+        arbiter->arbitrate();
+
+        //periodically send mouth & gaze target
+        client->update_mouth_target(arbiter->get_mouth_state());
+        client->update_gaze_target(arbiter->get_gaze_state());
+        client->send_all();
+
+        //debug:
+        //arbiter->get_mouth_state().dump();
+
+        thread::sleep(timeout);
+        timeout = get_system_time() + posix_time::milliseconds(loop_delay);
+    }
+
+    return EXIT_SUCCESS;
+
+}
+
diff --git a/server/srv/gazetarget.srv b/server/srv/gazetarget.srv
new file mode 100644
index 0000000..97fc3af
--- /dev/null
+++ b/server/srv/gazetarget.srv
@@ -0,0 +1,16 @@
+#pan  angle (left/right)
+float32 pan  = 1
+
+#tilt angle (up/down)
+float32 tilt = 2 
+
+#roll angle (sideway movement)
+float32 roll = 3 
+
+#vergence angle (angle difference from straight view, defaults to 0.0 for straight)
+float32 vergence = 4 
+
+---
+#response
+uint32 result
+
diff --git a/server/tools/hlrc_test_gui.py b/server/tools/hlrc_test_gui.py
new file mode 100755
index 0000000..06e7933
--- /dev/null
+++ b/server/tools/hlrc_test_gui.py
@@ -0,0 +1,248 @@
+#!/usr/bin/python
+import sys
+import os.path
+from PyQt4 import QtGui, QtCore
+from PyQt4.QtCore import SIGNAL
+from hlrc_speak_utterance import hlrc_utterance
+from hlrc_play_animation import hlrc_animation
+from hlrc_set_emotion import hlrc_emotion
+
+class Example(QtGui.QWidget):
+    
+    def __init__(self, _scope):
+        super(Example, self).__init__()
+        self.scope = _scope
+        self.initUI()
+	scope = self.scope_lineedit.text()
+        self.hlrc_utterance = hlrc_utterance(scope)
+        self.hlrc_animation = hlrc_animation(scope)
+        self.hlrc_emotion   = hlrc_emotion(scope)
+
+    def scopeChanged(self):
+	self.scope = self.scope_lineedit.text()
+        print "> changed scope to %s" % self.scope
+        self.hlrc_utterance.set_scope(self.scope)
+        self.hlrc_animation.set_scope(self.scope)
+        self.hlrc_emotion.set_scope(self.scope)
+
+    def initUtteranceUI(self):
+        groupBox = QtGui.QGroupBox("utterances")
+
+        hello = QtGui.QPushButton("hello...")
+        hello.clicked.connect(self.utterance_button_clicked)
+
+        count = QtGui.QPushButton("12345...")
+        count.clicked.connect(self.utterance_button_clicked)
+
+
+        vbox = QtGui.QVBoxLayout()
+        vbox.addWidget(hello)
+        vbox.addWidget(count)
+        vbox.addStretch(1)
+        groupBox.setLayout(vbox)
+
+        return groupBox
+
+    def initSpinbox(self, _min, _max, _init, double):
+        if (double): 
+            s = QtGui.QDoubleSpinBox()
+        else:
+            s = QtGui.QSpinBox()
+
+        s.setMinimum(_min)
+        s.setMaximum(_max)
+        s.setValue(_init)
+        return s
+
+    def initEmotionUI(self):
+        groupBox = QtGui.QGroupBox("emotion")
+        neutral   = QtGui.QPushButton("neutral")
+        neutral.clicked.connect(self.emotion_button_clicked)
+        surprised = QtGui.QPushButton("surprise")
+        surprised.clicked.connect(self.emotion_button_clicked)
+        angry     = QtGui.QPushButton("angry")
+        angry.clicked.connect(self.emotion_button_clicked)
+        happy     = QtGui.QPushButton("happy")
+        happy.clicked.connect(self.emotion_button_clicked)
+        sad     = QtGui.QPushButton("sad")
+        sad.clicked.connect(self.emotion_button_clicked)
+        fear      = QtGui.QPushButton("fear")
+        fear.clicked.connect(self.emotion_button_clicked)
+
+        self.duration_spinbox = self.initSpinbox(100, 10000, 1000, 0)
+
+        vbox = QtGui.QVBoxLayout()
+        vbox.addWidget(self.duration_spinbox)
+        vbox.addWidget(neutral)
+        vbox.addWidget(surprised)
+        vbox.addWidget(angry)
+        vbox.addWidget(happy)
+        vbox.addWidget(sad)
+        vbox.addWidget(fear)
+        vbox.addStretch(1)
+        groupBox.setLayout(vbox)
+        return groupBox
+
+
+    def initAnimationButton(self, name):
+        b = QtGui.QPushButton(name)
+        b.clicked.connect(self.animation_button_clicked)
+        return b
+
+    def initAnimUI(self):
+        groupBox = QtGui.QGroupBox("animations")
+  
+        #options
+        options = QtGui.QHBoxLayout()
+        vbox_r = QtGui.QVBoxLayout()
+        vbox_r.addWidget(QtGui.QLabel("repetitions"))
+        self.repetitions_spinbox = self.initSpinbox(1,10,1,0)
+        vbox_r.addWidget(self.repetitions_spinbox)
+
+        vbox_d = QtGui.QVBoxLayout()
+        vbox_d.addWidget(QtGui.QLabel("duration/ms (each)"))
+        self.duration_each_spinbox = self.initSpinbox(100,10000,1000,0)
+        vbox_d.addWidget(self.duration_each_spinbox)
+
+        vbox_s = QtGui.QVBoxLayout()
+        vbox_s.addWidget(QtGui.QLabel("scale"))
+        self.scale_spinbox = self.initSpinbox(0.1, 5.0, 1.0, 1)
+        vbox_s.addWidget(self.scale_spinbox)
+
+
+        options.addLayout(vbox_r)
+        options.addLayout(vbox_d)        
+        options.addLayout(vbox_s)
+
+        #buttons
+        vbox = QtGui.QVBoxLayout()
+        vbox.addLayout(options)
+        vbox.addWidget(self.initAnimationButton("head shake"))
+        vbox.addWidget(self.initAnimationButton("head nod"))
+        vbox.addWidget(self.initAnimationButton("eyeblink left"))
+        vbox.addWidget(self.initAnimationButton("eyeblink right"))
+        vbox.addWidget(self.initAnimationButton("eyeblink both"))
+	vbox.addWidget(self.initAnimationButton("eyebrows raise"))
+	vbox.addWidget(self.initAnimationButton("eyebrows lower"))
+        vbox.addStretch(1)
+        groupBox.setLayout(vbox)
+
+        return groupBox
+
+    def initUI(self):        
+
+        self.scope_lineedit = QtGui.QLineEdit(self.scope);
+        self.connect(self.scope_lineedit, SIGNAL("editingFinished()"),self.scopeChanged)
+
+	vbox = QtGui.QVBoxLayout();
+	
+	hboxl = QtGui.QHBoxLayout();
+	hboxl.addWidget(QtGui.QLabel("base scope: "));
+	hboxl.addWidget(self.scope_lineedit);
+	vbox.addLayout(hboxl);
+
+        hbox = QtGui.QHBoxLayout()
+	vbox.addLayout(hbox);
+	
+        #emotion
+        hbox.addWidget(self.initEmotionUI())
+
+        #utterance:
+        hbox.addWidget(self.initUtteranceUI())
+
+        #animations:
+        hbox.addWidget(self.initAnimUI())
+
+        self.setLayout(vbox)
+        #sld.valueChanged.connect(lcd.display)
+        
+        self.setGeometry(400, 100, 250, 150)
+        self.setWindowTitle("HLC Server test GUI")
+        self.show()
+
+    def utterance_button_clicked(self):
+        button = self.sender().text()
+        
+        fn_praat = "b.praat"
+        fn_wav   = "b.wav"
+
+        if (button == "12345..."):
+            print("123")
+            fn_praat = "1234.praat"
+            fn_wav   = "1234.wav"
+
+        elif (button == "hello..."):
+            print "hello"
+            fn_praat = "hello_my_name.praat"
+            fn_wav   = "hello_my_name.wav"
+
+        else:
+            print "invalid button '%s'" % (button)
+            return
+
+        #try to find the wav/praat files:
+        path = os.path.dirname(os.path.realpath(__file__)) + "/../share/hlrc_server/examples/"
+        if (not os.path.isfile(path + fn_wav)):
+            #try fallback solution for running from current folder:
+            path = "examples/"
+
+        self.hlrc_utterance.trigger_utterance(path + fn_praat, path + fn_wav, 0)
+
+    def emotion_button_clicked(self):
+        button = self.sender().text()
+        duration = self.duration_spinbox.value()
+
+
+        if (button == "angry"):
+            self.hlrc_emotion.set_emotion(3, duration, 0)
+        elif (button == "neutral"):
+            self.hlrc_emotion.set_emotion(0, duration, 0)
+        elif (button == "happy"):
+            self.hlrc_emotion.set_emotion(1, duration, 0)
+        elif (button == "sad"):
+            self.hlrc_emotion.set_emotion(2, duration, 0)
+        elif (button == "surprise"):
+            self.hlrc_emotion.set_emotion(4, duration, 0)
+        elif (button == "fear"):
+            self.hlrc_emotion.set_emotion(5, duration, 0)
+        else:
+            print "invalid emotion id '%s'" % (button)
+            return
+
+    def animation_button_clicked(self):
+        button = self.sender().text()
+
+        repetitions = self.repetitions_spinbox.value()
+        duration_each = self.duration_each_spinbox.value()
+        scale = self.scale_spinbox.value()
+
+        if (button == "head nod"):
+            self.hlrc_animation.trigger_animation(1, repetitions, duration_each, scale, 0)
+        elif (button == "head shake"):
+            self.hlrc_animation.trigger_animation(2, repetitions, duration_each, scale, 0)
+        elif (button == "eyeblink left"):
+            self.hlrc_animation.trigger_animation(3, repetitions, duration_each, scale, 0)
+        elif (button == "eyeblink right"):
+            self.hlrc_animation.trigger_animation(4, repetitions, duration_each, scale, 0)
+        elif (button == "eyeblink both"):
+            self.hlrc_animation.trigger_animation(5, repetitions, duration_each, scale, 0)
+        elif (button == "eyebrows raise"):
+            self.hlrc_animation.trigger_animation(6, repetitions, duration_each, scale, 0)
+        elif (button == "eyebrows lower"):
+            self.hlrc_animation.trigger_animation(7, repetitions, duration_each, scale, 0)
+        else:
+            print "invalid button '%s'" % (button)
+            return
+
+def main():
+    scope = "/home/wardrobe/flobi"
+    if (len(sys.argv) == 2):
+	scope = sys.argv[1]
+
+    app = QtGui.QApplication(sys.argv)
+    ex = Example(scope)
+    sys.exit(app.exec_())
+
+
+if __name__ == '__main__':
+    main()
