diff --git a/silecs-codegen/.project b/silecs-codegen/.project
new file mode 100644
index 0000000000000000000000000000000000000000..d8a27b477aebaf971619fa0ff83654a04205ffc4
--- /dev/null
+++ b/silecs-codegen/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>silecs-codegen</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
diff --git a/silecs-codegen/LICENSE b/silecs-codegen/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..20d40b6bceca3a6c0237d7455ebf1820aeff3680
--- /dev/null
+++ b/silecs-codegen/LICENSE
@@ -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>.
\ No newline at end of file
diff --git a/silecs-codegen/README.md b/silecs-codegen/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..a5e382f8130b53a8742069d0e76622107f890ba1
--- /dev/null
+++ b/silecs-codegen/README.md
@@ -0,0 +1,19 @@
+# silecs-codegen
+
+This component of the SILECS PLC-framework generates FESA and stand-alone C++ code from an existing silecs-project in order to ease the usage of the package silecs-communication-cpp
+
+## Getting Started
+
+Please check the lab-specific SILECS-Wikis for more information:
+
+[CERN SILECS Wiki Page][CERN_Wiki]
+
+[GSI SILECS Wiki Page][GSI_Wiki]
+
+## License
+
+Licensed under the GNU GENERAL PUBLIC LICENSE Version 3. See the [LICENSE file][license] for details.
+
+[license]: LICENSE
+[CERN_Wiki]: https://wikis.cern.ch/display/SIL/SILECs+Home
+[GSI_Wiki]: https://www-acc.gsi.de/wiki/Frontend/SILECS
\ No newline at end of file
diff --git a/silecs-codegen/install.sh b/silecs-codegen/install.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e8e33e9f6cfb3f50b7dc6357fdb42e4d7803ef7a
--- /dev/null
+++ b/silecs-codegen/install.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+set -e
+
+INSTALL_DIR=$1
+
+SCRIPT=$(readlink -f "$0")
+SCRIPTPATH=$(dirname "$SCRIPT")     # path where this script is located in
+
+mkdir -p ${INSTALL_DIR}
+cp -r ${SCRIPTPATH}/src/xml ${INSTALL_DIR}
\ No newline at end of file
diff --git a/silecs-model/dummy b/silecs-codegen/src/xml/__init__.py
similarity index 100%
rename from silecs-model/dummy
rename to silecs-codegen/src/xml/__init__.py
diff --git a/test b/silecs-codegen/src/xml/fesa/__init__.py
similarity index 100%
rename from test
rename to silecs-codegen/src/xml/fesa/__init__.py
diff --git a/silecs-codegen/src/xml/fesa/__init__.pyc b/silecs-codegen/src/xml/fesa/__init__.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e9a909548eefa46b401ca6b0d4ceee202ccdedd3
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/__init__.pyc differ
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/__init__.py b/silecs-codegen/src/xml/fesa/fesa_3_0_0/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/__init__.pyc b/silecs-codegen/src/xml/fesa/fesa_3_0_0/__init__.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e033898af1d4fd1d4863d78285b0c8806034345b
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fesa_3_0_0/__init__.pyc differ
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/fesaTemplates$py.class b/silecs-codegen/src/xml/fesa/fesa_3_0_0/fesaTemplates$py.class
new file mode 100644
index 0000000000000000000000000000000000000000..1b65a8fcbd59c7ab6627091fb203ce597f934a2d
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fesa_3_0_0/fesaTemplates$py.class differ
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/fesaTemplates.py b/silecs-codegen/src/xml/fesa/fesa_3_0_0/fesaTemplates.py
new file mode 100644
index 0000000000000000000000000000000000000000..2406e29d2155bf31e4e36709aaae9d8f52085ff0
--- /dev/null
+++ b/silecs-codegen/src/xml/fesa/fesa_3_0_0/fesaTemplates.py
@@ -0,0 +1,840 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import iecommon
+import time
+
+#=========================================================================
+# FESA .cproject file
+#=========================================================================
+
+cproject = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="cern.fesa.plugin.build.configuration.537108490">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cern.fesa.plugin.build.configuration.537108490" moduleId="org.eclipse.cdt.core.settings" name="FESA Make Build">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration buildProperties="" description="" id="cern.fesa.plugin.build.configuration.537108490" name="FESA Make Build" parent="cern.fesa.plugin.build.configuration">
+					<folderInfo id="cern.fesa.plugin.build.configuration.537108490." name="/" resourcePath="">
+						<toolChain id="cern.fesa.plugin.build.toolchain.1156032800" name="FESA Toolchain" superClass="cern.fesa.plugin.build.toolchain">
+							<targetPlatform id="cern.fesa.plugin.build.targetplatform.67227612" isAbstract="false" superClass="cern.fesa.plugin.build.targetplatform"/>
+							<builder id="cern.fesa.plugin.build.builder.1302129891" name="Gnu Make Builder.FESA Make Build" superClass="cern.fesa.plugin.build.builder"/>
+							<tool id="cern.fesa.plugin.build.archiver.1068962328" name="GCC Archiver" superClass="cern.fesa.plugin.build.archiver"/>
+							<tool id="cern.fesa.plugin.build.compiler.648804671" name="GCC C++ Compiler" superClass="cern.fesa.plugin.build.compiler">
+								<option id="gnu.cpp.compiler.option.include.paths.12841593" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
+								</option>
+								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.2129597065" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.662860517" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
+								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1388561052" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.c.linker.base.365658250" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
+							<tool id="cern.fesa.plugin.build.linker.884627432" name="GCC C++ Linker" superClass="cern.fesa.plugin.build.linker">
+								<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.2024588043" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="cern.fesa.plugin.build.assembler.838409637" name="GCC Assembler" superClass="cern.fesa.plugin.build.assembler">
+								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1405521367" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+							</tool>
+						</toolChain>
+					</folderInfo>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="" name=""/>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
+		<buildTargets>
+			<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+				<buildCommand>make</buildCommand>
+				<buildArguments/>
+				<buildTarget>clean</buildTarget>
+				<stopOnError>true</stopOnError>
+				<useDefaultCommand>true</useDefaultCommand>
+				<runAllBuilders>true</runAllBuilders>
+			</target>
+			<target name="all x86_64" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+				<buildCommand>make</buildCommand>
+				<buildArguments/>
+				<buildTarget>-j16 CPU=x86_64 </buildTarget>
+				<stopOnError>true</stopOnError>
+				<useDefaultCommand>true</useDefaultCommand>
+				<runAllBuilders>true</runAllBuilders>
+			</target>
+		</buildTargets>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration"/>
+</cproject>
+"""
+
+#=========================================================================
+# H Source template (.h file)
+#=========================================================================
+hTop = """/*
+ * %s.h
+ *
+ * Generated by SILECS framework tools 
+ */
+
+#ifndef %s_%s_H_
+#define %s_%s_H_
+
+#include <SilecsService.h>
+#include <fesa-core/Synchronization/MultiplexingContext.h>
+#include <%s/GeneratedCode/ServiceLocator.h>
+    """
+
+hTopBlock = """#include <%s/Server/%s.h>
+    """
+
+hTop2 = """
+namespace %s
+{
+
+    /*---------------------------------------------------------------------------------------------------------
+     * SETUP
+     *---------------------------------------------------------------------------------------------------------
+     *  Setup the SILECS service by calling the setup() method from the RTDeviceClass::specificInit()
+     *  Stop and cleanup the SILECS service by calling the cleanup() method if needed (eg.: from ~RTDeviceClass())
+     *
+     *  In order to make use of the different blocks, defined in the silecsdesign, please make use of the static, block related variables of the class, defined on the bottom of this file !
+     * --------------------------------------------------------------------------------------------------------
+     */
+
+    /*---------------------------------------------------------------------------------------------------------
+     * COMMUNICATION
+     *---------------------------------------------------------------------------------------------------------
+     * General methods to synchronize the FESA fields and related PLC registers of the FESA server with or without
+     * PLC side synchronization (send/recv) if requested. Each action is done for one particular block.
+     * In case of BLOCK_MODE configuration (see SILECS doc.), the transaction is optimal with the following
+     * 'AllDevices' and 'PLCDevices' methods.
+     * Each method can be called in the appropriate server-action (set) and rt-action (get)
+     *
+     * getAllDevices  : [receive all devices of all connected PLCs +] update FESA fields with related SILECS registers
+     * setAllDevices  : update SILECS registers with related FESA fields [+ send block to all connected PLCs]
+     * getPLCDevices  : [receive all devices of one PLC +] update FESA fields with related SILECS registers
+     * setPLCDevices  : update SILECS registers with related FESA fields [+ send block to the PLC]
+     * getSomeDevices : [receive each device of the device-collection +] update FESA fields with related SILECS registers
+     * setSomeDevices : update SILECS registers with related FESA fields [+ send block to each device of the device-collection]
+     * getOneDevice   : [receive block of one PLC device +] update FESA fields with related SILECS registers
+     * setOneDevice   : update SILECS registers with related FESA fields [+ send block to the PLC device]
+     *
+     * --------------------------------------------------------------------------------------------------------
+     */
+
+    class Abstract%s
+    {
+        public:
+            static inline Silecs::Service* theService()  { return pService_; }
+            static inline Silecs::Cluster* theCluster()  { return pCluster_; }
+            inline std::string& getBlockName()          { return blockName_; }
+
+            static void setup(const ServiceLocator* serviceLocator);
+            static void cleanup();
+            static void setPLCSlaveRegisters(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator);
+            static void getPLCMasterRegisters(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator);
+
+            Abstract%s(std::string blockName);
+            virtual ~Abstract%s();
+
+            void getAllDevices(const ServiceLocator* serviceLocator, const bool recvNow, MultiplexingContext* pContext);
+            void getPLCDevices(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator, const bool recvNow, MultiplexingContext* pContext);
+            void getSomeDevices(std::vector<Device*> deviceCol, const bool recvNow, MultiplexingContext* pContext);
+            virtual void getOneDevice(Device* pDevice, const bool recvNow, MultiplexingContext* pContext);
+
+            void setAllDevices(const ServiceLocator* serviceLocator, const bool sendNow, MultiplexingContext* pContext);
+            void setPLCDevices(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator, const bool sendNow, MultiplexingContext* pContext);
+            void setSomeDevices(std::vector<Device*> deviceCol, const bool sendNow, MultiplexingContext* pContext);
+            virtual void setOneDevice(Device* pDevice, const bool sendNow, MultiplexingContext* pContext);
+
+        protected:
+
+            static Silecs::Service* pService_;
+            static Silecs::Cluster* pCluster_;
+            static bool isInitialized_;
+
+            // Name of the silecs-block which is addressed
+            std::string blockName_;
+
+            // not copyable object
+            Abstract%s(const Abstract%s&);
+            Abstract%s& operator=(const Abstract%s&);
+    };
+
+    // -------------------------------------------------------------------------------------------------
+    #define BLOCK_RO( name )\t\\
+    class name##_Type : public Abstract%s\t\\
+    {\t\\
+        public:\t\\
+            name##_Type(std::string name);\t\\
+            ~name##_Type();\t\\
+            void getOneDevice(Device* pDevice, const bool transmitNow, MultiplexingContext* pContext);\t\\
+    }
+
+
+    #define BLOCK_WO( name )\t\\
+    class name##_Type : public Abstract%s\t\\
+    {\t\\
+        public:\t\\
+            name##_Type(std::string name);\t\\
+            ~name##_Type();\t\\
+        void setOneDevice(Device* pDevice, const bool transmitNow, MultiplexingContext* pContext);\t\\
+        void setOneDevice(Device* pDevice, name##PropertyData& data, const bool transmitNow, MultiplexingContext* pContext);\t\\
+    }
+
+    #define BLOCK_RW( name )\t\\
+    class name##_Type : public Abstract%s\t\\
+    {\t\\
+        public:\t\\
+            name##_Type(std::string name);\t\\
+            ~name##_Type();\t\\
+            void getOneDevice(Device* pDevice, const bool transmitNow, MultiplexingContext* pContext);\t\\
+            void setOneDevice(Device* pDevice, const bool transmitNow, MultiplexingContext* pContext);\t\\
+            void setOneDevice(Device* pDevice, name##PropertyData& data, const bool transmitNow, MultiplexingContext* pContext);\t\\
+    }
+    
+    """
+
+hBlock = """BLOCK_%s( %s );
+    """
+
+hBottom = """
+    /*---------------------------------------------------------------------------------------------------------
+     * INTERFACE
+     *---------------------------------------------------------------------------------------------------------
+     * This is the public interface used from the FESA code to access the PLC service.
+     */
+    class %s
+    {
+        public:
+            static inline Silecs::Service* theService()  { return Abstract%s::theService(); }
+            static inline Silecs::Cluster* theCluster()  { return Abstract%s::theCluster(); }
+            static void setup(const ServiceLocator* serviceLocator) { Abstract%s::setup(serviceLocator); }
+            static void cleanup() { Abstract%s::cleanup(); }
+
+    """
+
+hDeclBlocks = """            static %s_Type %s;
+    """
+
+hClosing = """           
+        };
+    }
+
+    #endif /* %s_%s_H_ */
+    """
+
+#=========================================================================
+# C++ Source template (.cpp file)
+#=========================================================================
+cTop = """/*
+ * %s.cpp
+ *
+ * Generated by SILECS framework tools 
+ */
+ 
+#include <%s/Common/%s.h>
+#include <fesa-core/Synchronization/NoneContext.h>
+#include <fesa-core/Synchronization/MultiplexingContext.h>
+ 
+namespace %s
+{
+    //Global objects of the SILECS class
+    Silecs::Service* Abstract%s::pService_ = NULL;
+    Silecs::Cluster* Abstract%s::pCluster_ = NULL;
+    bool Abstract%s::isInitialized_ = false;
+
+    """
+
+cGlobal = """%s_Type\t%s::%s("%s");
+    """
+cPart1 = """
+    //-------------------------------------------------------------------------------------------------------------
+    // Constructor & Destructor methods
+    
+    Abstract%s::Abstract%s(std::string blockName): blockName_(blockName) {}
+    Abstract%s::~Abstract%s() {}
+    """
+
+cBlockConstr = """
+    %s_Type::%s_Type(std::string name): Abstract%s(name) {}
+    %s_Type::~%s_Type() {}
+    """
+
+cPart2 = """
+    //---------------------------------------------------------------------------------------------------------
+    // Set-up the SILECS components for the Abstract%s class (service & cluster)
+
+    void Abstract%s::setup(const ServiceLocator* serviceLocator)
+    {
+        try
+        {
+            // Instantiate the singleton of the SILECS Service
+            pService_ = Silecs::Service::getInstance();
+
+            // Enable the SILECS diagnostic with user topics if any
+            pService_->setArguments(serviceLocator->getUsrCmdArgs());
+
+            // Instantiate the SILECS Cluster object for the given Class/Version
+            GlobalDevice* pGlobalDevice = serviceLocator->getGlobalDevice();
+            pCluster_ = pService_->getCluster( "%s", pGlobalDevice->plcClassVersion.get());
+            isInitialized_ = true;
+
+            // Connect each PLC of the Cluster that is referred from the FESA instance
+            std::vector<Device*> pDeviceCol = serviceLocator->getDeviceCollection();
+            for(std::vector<Device*>::iterator pDeviceIter=pDeviceCol.begin(); pDeviceIter!= pDeviceCol.end(); pDeviceIter++)
+            {
+                Device* pDevice = *pDeviceIter;
+
+                // Retrieve the PLC related to the current FESA device
+                // (from 'plcHostName' FESA field defined on that purpose).
+                Silecs::PLC* pPLC = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+
+                // Update the PLC Slave registers from related FESA fields just before synchronising done at connection time
+                setPLCSlaveRegisters(pPLC, serviceLocator);
+
+                // Connect the PLC if not already connected
+                if (!pPLC->isEnabled())
+                {   pPLC->connect(/*synchroMode=*/Silecs::FULL_SYNCHRO, /*connectNow=*/true);
+                    if (pPLC->isConnected())
+                    {   // Update FESA fields from related PLC Master registers just after synchronising done at connection time
+                        getPLCMasterRegisters(pPLC, serviceLocator);
+                    }
+                }
+            }
+        }
+        catch (const Silecs::SilecsException& ex)
+        {
+            throw fesa::FesaException(__FILE__, __LINE__, ex.getMessage());
+        }
+    }
+
+    //---------------------------------------------------------------------------------------------------------
+    // Release all the SILECS resources
+    void Abstract%s::cleanup()
+    {
+        // Attention! This method is responsible to stop all the PLC connections
+        // and to remove all the SILECS resources (Clusters and related components: PLCs, Devices, Registers, ..)
+        // Calling method must ensure that no process is currently accessing these resources before cleaning.
+        //
+        Silecs::Service::deleteInstance();
+    }
+
+    //---------------------------------------------------------------------------------------------------------
+    // Synchronise PLC SLAVE/MASTER registers and related FESA fields (automatically called by the setup method @connection time)
+    void Abstract%s::setPLCSlaveRegisters(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator)
+    {
+        fesa::NoneContext noneContext;
+    """
+
+cSetPLC = """
+        %s::%s.setPLCDevices(pPLC, serviceLocator, false, &noneContext);"""
+
+cPart3 = """
+    }
+
+    void Abstract%s::getPLCMasterRegisters(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator)
+    {
+        fesa::NoneContext noneContext;    //MASTER acquisition fields are not consistent, can be set with none-context
+    """
+
+cGetPLC = """
+        %s::%s.getPLCDevices(pPLC, serviceLocator, false, &noneContext);"""
+
+cPart4 = """
+    }
+    
+    //---------------------------------------------------------------------------------------------------------
+    // General methods to synchronize the FESA fields and related PLC registers of the FESA server
+    // with or without PLC side access (send/recv) if requested.
+    // get_ : [receive block from PLC +] update FESA fields with related PLC registers
+    // set_ : update PLC registers with related FESA fields [+ send block to PLC]
+
+    //---------------------------------------------------------------------------------------------------------
+
+    void Abstract%s::getAllDevices(const ServiceLocator* serviceLocator, const bool recvNow, MultiplexingContext* pContext)
+    {
+        if (recvNow) theCluster()->recv(blockName_);
+
+        std::vector<Device*> deviceCol = serviceLocator->getDeviceCollection();
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {  getOneDevice(*pDeviceIter, false, pContext);
+        }
+    }
+
+    void Abstract%s::getPLCDevices(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator, const bool recvNow, MultiplexingContext* pContext)
+    {
+        if (recvNow) pPLC->recv(blockName_);
+
+        std::vector<Device*> deviceCol = serviceLocator->getDeviceCollection();
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {   if ((*pDeviceIter)->plcHostName.get() == pPLC->getName())
+            {  getOneDevice(*pDeviceIter, false, pContext);
+            }
+        }
+    }
+
+    void Abstract%s::getSomeDevices(std::vector<Device*> deviceCol, const bool sendNow, MultiplexingContext* pContext)
+    {
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {    getOneDevice(*pDeviceIter, sendNow, pContext);
+        }
+    }
+
+    void Abstract%s::getOneDevice(Device* pDevice, const bool recvNow, MultiplexingContext* pContext) {};
+
+    //---------------------------------------------------------------------------------------------------------
+
+    void Abstract%s::setAllDevices(const ServiceLocator* serviceLocator, bool sendNow, MultiplexingContext* pContext)
+    {
+        std::vector<Device*> deviceCol = serviceLocator->getDeviceCollection();
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {  setOneDevice(*pDeviceIter, false, pContext);
+        }
+
+        if (sendNow) theCluster()->send(blockName_);
+    }
+
+    void Abstract%s::setPLCDevices(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator, bool sendNow, MultiplexingContext* pContext)
+    {
+        std::vector<Device*> deviceCol = serviceLocator->getDeviceCollection();
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {   if ((*pDeviceIter)->plcHostName.get() == pPLC->getName())
+            {  setOneDevice(*pDeviceIter, false, pContext);
+            }
+        }
+
+        if (sendNow) pPLC->send(blockName_);
+    }
+
+    void Abstract%s::setSomeDevices(std::vector<Device*> deviceCol, bool sendNow, MultiplexingContext* pContext)
+    {
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {    setOneDevice(*pDeviceIter, sendNow, pContext);
+        }
+    }
+
+    void Abstract%s::setOneDevice(Device* pDevice, const bool sendNow, MultiplexingContext* pContext) {};
+    
+    //---------------------------------------------------------------------------------------------------------
+    """
+
+cCommonGet = """
+    void %s_Type::getOneDevice(Device* pDevice, const bool recvNow, MultiplexingContext* pContext)
+    {
+    	if( !isInitialized_ )
+    	{
+    		throw fesa::FesaException(__FILE__, __LINE__, "SILECS-Service not initialized yet - %s::setup needs to be called before any plc-interaction can be done");
+    	}
+        Silecs::PLC* pPLC  = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+        Silecs::Device* pPLCDevice = pPLC->getDevice(pDevice->plcDeviceLabel.get());
+"""
+
+cRegVar = """        Silecs::Register*  pRegister = NULL;
+"""
+
+cGetArrayVar = """        uint32_t dim1 = 1;
+"""
+cGetArray2DVar = """        uint32_t dim2 = 1;
+"""
+cSetArrayVar = """        uint32_t dim1 = 1;
+        uint32_t fesaDim1;
+"""
+cSetArray2DVar = """        uint32_t dim2 = 1;
+        uint32_t fesaDim2;
+"""
+
+cRecv = """        if (recvNow) pPLCDevice -> recv(blockName_);        
+    """
+
+cGetStringReg = """
+        pRegister = pPLCDevice->getRegister("%s");
+        pDevice->%s.set(pRegister->getValString().c_str(), pContext);
+"""
+
+cGetStringArrayReg = """
+        {
+        pRegister = pPLCDevice->getRegister("%s");
+        dim1 = pRegister->getDimension1();
+        const std::string** stdStringArray = pRegister->getRefStringArray(dim1);
+        for (unsigned int i=0; i<dim1; i++)
+        {   pDevice->%s.setString(stdStringArray[i]->c_str(), i, pContext);
+        }
+        }
+"""
+
+cGetScalarReg = """
+        pDevice->%s.set( pPLCDevice->getRegister("%s")->getVal%s(), pContext);"""
+
+cGetArrayReg = """
+        pRegister = pPLCDevice->getRegister("%s");
+            dim1 = pRegister->getDimension1();
+            pDevice->%s.set(pRegister->getRef%sArray(dim1), dim1, pContext);
+        """
+cGetArray2DReg = """
+        pRegister = pPLCDevice->getRegister("%s");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->%s.set(pRegister->getRef%sArray2D(dim1, dim2), dim1, dim2, pContext);
+"""
+cGetUnsignedArrayReg = """
+        pRegister = pPLCDevice->getRegister("%s");
+            dim1 = pRegister->getDimension1();
+            %s* %s = (%s*)calloc(dim1, sizeof(%s));
+            pRegister->getVal%sArray(%s, dim1);\t//use automatic conversion for JAVA non-supported type
+            pDevice->%s.set(%s, dim1, pContext);
+            free(%s);
+    """
+
+cGetUnsignedArray2DReg = """
+        pRegister = pPLCDevice->getRegister("%s");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        %s* %s = (%s*)calloc(dim1*dim2, sizeof(%s));
+        pRegister->getVal%sArray2D(%s, dim1, dim2);\t//use automatic conversion for JAVA non-supported type
+        pDevice->%s.set(%s, dim1, dim2, pContext);
+    free(%s);
+"""
+
+cCommonSet = """    
+    void %s_Type::setOneDevice(Device* pDevice, const bool sendNow, MultiplexingContext* pContext)
+    {
+    	if( !isInitialized_ )
+    	{
+    		throw fesa::FesaException(__FILE__, __LINE__, "SILECS-Service not initialized yet - %s::setup needs to be called before any plc-interaction can be done");
+    	}
+        Silecs::PLC* pPLC  = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+        Silecs::Device* pPLCDevice = pPLC->getDevice(pDevice->plcDeviceLabel.get());
+"""
+
+cSend = """
+        if (sendNow) pPLCDevice->send(blockName_);
+"""
+
+cDatatypeSet = """
+    void %s_Type::setOneDevice(Device* pDevice, %sPropertyData& data, bool sendNow, MultiplexingContext* pContext)
+    {
+    	if( !isInitialized_ )
+    	{
+    		throw fesa::FesaException(__FILE__, __LINE__, "SILECS-Service not initialized yet - %s::setup needs to be called before any plc-interaction can be done");
+    	}
+        Silecs::PLC* pPLC = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+        Silecs::Device* pPLCDevice = pPLC->getDevice(pDevice->plcDeviceLabel.get());
+"""
+
+cSetStringReg = """
+        pPLCDevice->getRegister("%s")->setValString(pDevice->%s.get(pContext));
+"""
+
+cSetStringArrayReg = """
+        {
+        pRegister = pPLCDevice->getRegister("%s");
+        dim1 = pRegister->getDimension1();
+        std::string stdStringArray[dim1];
+        const char** cStringArray = pDevice->%s.get(fesaDim1, pContext);
+        for (unsigned int i=0; i<dim1; i++) stdStringArray[i] = (const char*)cStringArray[i];
+        pRegister->setValStringArray(stdStringArray, dim1);
+        }
+"""
+
+cSetScalarReg = """
+        pPLCDevice->getRegister("%s")->setVal%s( pDevice->%s.get(pContext));"""
+            
+cSetScalarUReg = """
+        pPLCDevice->getRegister("%s")->setVal%s( (%s)pDevice->%s.get(pContext));"""
+
+cSetArrayReg = """
+        pRegister = pPLCDevice->getRegister("%s");
+            dim1 = pRegister->getDimension1();
+            pRegister->setVal%sArray(pDevice->%s.get(fesaDim1, pContext), dim1);
+    """
+
+cSetArray2DReg = """
+    pRegister = pPLCDevice->getRegister("%s");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setVal%sArray2D(pDevice->%s.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+"""
+
+cSetUnsignedArrayReg = """
+        pRegister = pPLCDevice->getRegister("%s");
+        dim1 = pRegister->getDimension1();
+        pRegister->setVal%sArray(pDevice->%s.get(fesaDim1, pContext), dim1);\t//use automatic conversion for JAVA non-supported type
+"""
+
+cSetUnsignedArray2DReg = """
+        pRegister = pPLCDevice->getRegister("%s");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setVal%sArray2D( pDevice->%s.get(fesaDim1, fesaDim2, pContext), dim1, dim2);\t//use automatic conversion for JAVA non-supported type
+"""
+
+cSetStringRegData = """
+        (data.is%sAvailable()) ? pPLCDevice->getRegister("%s")->setValString(data.%s.get()) :
+                                     pPLCDevice->getRegister("%s")->setValString(pDevice->%s.get(pContext));"""
+                                    
+cSetStringArrayRegData = """
+        {
+        pRegister = pPLCDevice->getRegister("%s");
+        dim1 = pRegister->getDimension1();
+        std::string stdStringArray[dim1];
+        const char** cStringArray = (data.is%sAvailable() ? data.%s.get(fesaDim1) : pDevice->%s.get(fesaDim1, pContext));
+        for (unsigned int i=0; i<dim1; i++) stdStringArray[i] = (const char*)cStringArray[i];
+        pRegister->setValStringArray(stdStringArray, dim1);
+        }
+"""
+cSetScalarRegData = """
+        (data.is%sAvailable()) ? pPLCDevice->getRegister("%s")->setVal%s( data.%s.get()) :
+                                          pPLCDevice->getRegister("%s")->setVal%s( pDevice->%s.get(pContext));"""
+
+cSetScalarURegData = """
+        (data.is%sAvailable()) ? pPLCDevice->getRegister("%s")->setVal%s( (%s)data.%s.get()) :
+                                          pPLCDevice->getRegister("%s")->setVal%s( (%s)pDevice->%s.get(pContext));"""
+
+cSetArrayRegData = """
+        pRegister = pPLCDevice->getRegister("%s");
+            dim1 = pRegister->getDimension1();
+            (data.is%sAvailable()) ? pRegister->setVal%sArray( data.%s.get(fesaDim1), dim1) :
+                                         pRegister->setVal%sArray( pDevice->%s.get(fesaDim1, pContext), dim1);
+    """
+
+cSetUnsignedArrayRegData = """
+        pRegister = pPLCDevice->getRegister("%s");
+            dim1 = pRegister->getDimension1();
+            (data.is%sAvailable()) ? pRegister->setVal%sArray( data.%s.get(fesaDim1), dim1) :
+                                         pRegister->setVal%sArray( pDevice->%s.get(fesaDim1, pContext), dim1);
+    """
+
+cSetArray2DRegData = """
+        pRegister = pPLCDevice->getRegister("%s");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.is%sAvailable()) ? pRegister->setVal%sArray2D(data.%s.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setVal%sArray2D(pDevice->%s.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+"""
+
+cSetUnsignedArray2DRegData = """
+        pRegister = pPLCDevice->getRegister("%s");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.is%sAvailable()) ? pRegister->setVal%sArray2D(data.%s.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setVal%sArray2D(pDevice->%s.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+"""
+
+makeDesign = """# Include SILECS library path
+SILECS_PATH ?= %s
+
+# Additional compiler warning flags
+override WARNFLAGS += 
+
+# Additional compiler flags
+COMPILER_FLAGS += -I$(SILECS_PATH)/include -I$(SILECS_PATH)/include/silecs-communication/interface/core
+COMPILER_FLAGS +=
+LINKER_FLAGS +=
+
+# Additional headers (Custom.h Specific.h ...) which need to be installed
+EXTRA_HEADERS += 
+
+    """
+
+makeDeploy = """# Include SILECS library path
+SILECS_PATH ?= %s
+
+SNAP7_BASE = %s
+
+# Additional compiler warning flags
+override WARNFLAGS += 
+
+# Additional libs and flags which are common to the Realtime and Server part
+COMPILER_FLAGS +=
+LINKER_FLAGS += -L$(SILECS_PATH)/lib/$(CPU) -lsilecs-comm
+LINKER_FLAGS += -L$(SNAP7_BASE)/bin/$(CPU)-linux -lsnap7
+#add default search path for dynamic snap7 library
+LINKER_FLAGS += -Wl,-rpath,$(SNAP7_BASE)/bin/$(CPU)-linux,-rpath,/usr/lib
+LINKER_FLAGS +=
+
+# Additional libs and flags which are specific to the Realtime part
+COMPILER_RT_FLAGS += 
+LINKER_RT_FLAGS += 
+
+# Additional libs and flags which are specific to the Server part
+COMPILER_SERVER_FLAGS += 
+LINKER_SERVER_FLAGS += 
+
+# Additional headers (Custom.h Specific.h ...) which need to be released
+EXTRA_HEADERS += 
+
+    """
+
+#=========================================================================
+# FESA .cproject file
+#=========================================================================
+
+def genCProject():
+    return cproject
+
+#=========================================================================
+# Header file (.h) code generation sub-functions
+#=========================================================================
+def genHTop(className):
+    return hTop %(className, className, className, className, className, className)
+
+def genHTopBlock(className, blockName):
+    return hTopBlock %(className, blockName)
+
+def genHTop2(className):
+    return hTop2 %(className, className, className, className, className, className, className, className, className, className, className)
+
+def genHBlock(mode, blockName):
+    return hBlock %(mode, blockName)
+
+def genHBottom(className):
+    return hBottom %(className, className, className, className, className)
+
+def genHDeclBlocks(className): 
+    return hDeclBlocks %(className, className)
+
+def genHClosing(className):
+    return hClosing %(className, className)
+
+#=========================================================================
+# C++ file (.cpp) code generation sub-functions
+#=========================================================================
+def genCTop(className):
+    return cTop %(className, className, className, className, className, className, className)
+
+def genCGlobal(className, blockName):
+    return cGlobal %(blockName, className, blockName, blockName)
+
+def genCPart1(className):
+    return cPart1 %(className, className, className, className)
+
+def genCBlockConstr(blockName, className):
+    return cBlockConstr %(blockName, blockName, className, blockName, blockName)
+
+def genCPart2(className):
+    return cPart2 %(className, className, className, className, className)
+
+def genCSetPLC(className, blockName):
+    return cSetPLC %(className, blockName)
+
+def genCCommonGet(blockName,className):
+    return cCommonGet %(blockName,className)
+
+def genCPart3(className):
+    return cPart3 %(className)
+
+def genCGetPLC(className, blockName):
+    return cGetPLC %(className, blockName)
+
+def genCPart4(className):
+    return cPart4 %(className, className, className, className, className, className, className, className)
+
+def genCGetStringReg(regName):
+    return cGetStringReg %(regName, regName)
+
+def genCGetStringArrayReg(regName):
+    return cGetStringArrayReg %(regName, regName)
+
+def genCGetScalarReg(regName, regType):
+    return cGetScalarReg %(regName, regName, regType)
+
+def genCGetArrayReg(regName, regType):    
+    return cGetArrayReg %(regName, regName, regType)
+
+def genCGetArray2DReg(regName, regType):
+    return cGetArray2DReg %(regName, regName, regType)
+
+def genCGetUnsignedArrayReg(regName, fesaType, regType):
+    return cGetUnsignedArrayReg %(regName, fesaType, regName, fesaType, fesaType, regType, regName, regName, regName, regName)
+
+def genCGetUnsignedArray2DReg(regName, fesaType, regType):
+    return cGetUnsignedArray2DReg %(regName, fesaType, regName, fesaType, fesaType, regType, regName, regName, regName, regName)
+
+def genCCommonSet(blockName,className):
+    return cCommonSet %(blockName,className)
+
+def genCDatatypeSet(blockName,className):
+    return cDatatypeSet %(blockName, blockName,className)
+
+def genCSetStringReg(regName):
+    return cSetStringReg %(regName, regName)
+
+def genCSetStringArrayReg(regName):
+    return cSetStringArrayReg %(regName, regName)
+
+def genCSetScalarReg(regName, regType):
+    return cSetScalarReg %(regName, regType, regName) 
+
+def genCSetScalarUReg(regName, regType, lowerType):
+    return cSetScalarUReg %(regName, regType, lowerType, regName)
+
+def genCSetArrayReg(regName, regType):
+    return cSetArrayReg %(regName, regType, regName)
+
+def genCSetUnsignedArrayReg(regName, regType):    
+    return cSetUnsignedArrayReg %(regName, regType, regName)
+
+def genCSetArray2DReg(regName, regType):
+    return cSetArray2DReg %(regName, regType, regName)
+
+def genCSetUnsignedArray2DReg(regName, regType):
+    return cSetUnsignedArray2DReg %(regName, regType, regName)
+
+def genCSetStringRegData(regName):
+    return cSetStringRegData %(iecommon.capitalizeString(regName), regName, regName, regName, regName)
+
+def genCSetStringArrayRegData(regName):
+    return cSetStringArrayRegData %(regName, iecommon.capitalizeString(regName), regName, regName)
+
+def genCSetScalarRegData(regName, regType):
+    return cSetScalarRegData %(iecommon.capitalizeString(regName), regName, regType, regName, regName, regType, regName)
+
+def genCSetScalarURegData(regName, regType, lowerType):
+    return cSetScalarURegData %(iecommon.capitalizeString(regName), regName, regType, lowerType, regName, regName, regType, lowerType, regName)
+
+def genCSetUnsignedArrayRegData(regName, regType):
+    return cSetUnsignedArrayRegData %(regName, iecommon.capitalizeString(regName), regType, regName, regType, regName) 
+
+def genCSetUnsignedArray2DRegData(regName, fesaType, regType):
+    return cSetUnsignedArray2DRegData %(regName, iecommon.capitalizeString(regName), regType, regName, regType, regName)  
+
+def genCSetArrayRegData(regName, regType):
+    return cSetArrayRegData %(regName, iecommon.capitalizeString(regName), regType, regName, regType, regName)
+
+def genCSetArray2DRegData(regName, fesaType, regType):
+    return cSetArray2DRegData %(regName, iecommon.capitalizeString(regName), regType, regName, regType, regName)
+
+def genMakeDesign(CentralMakefilePath):
+    return makeDesign %(CentralMakefilePath)
+
+def genMakeDeploy(silecsBasePath,snap7BasePath):
+    return makeDeploy %(silecsBasePath,snap7BasePath)
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/fesaTemplates.pyc b/silecs-codegen/src/xml/fesa/fesa_3_0_0/fesaTemplates.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..191a8f90d757ffd27d3abd43a113e417c614ff1e
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fesa_3_0_0/fesaTemplates.pyc differ
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/fillFESADeployUnit.py b/silecs-codegen/src/xml/fesa/fesa_3_0_0/fillFESADeployUnit.py
new file mode 100644
index 0000000000000000000000000000000000000000..5e900bc18a2bf68dba65788bcd8b2e6d5629c0d9
--- /dev/null
+++ b/silecs-codegen/src/xml/fesa/fesa_3_0_0/fillFESADeployUnit.py
@@ -0,0 +1,75 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import libxml2
+import iecommon
+
+import fesa.fillFesaDeployUnitBase
+
+class FESADeployUnitGenerator3_0_0(object):
+
+    def fillXML(self,fesaDeployParsed,silecsDeployParsed,deployName, deployUnitSchemaPath, fesaVersion,logTopics={'errorlog': True} ):
+
+        fesaRoot = fesaDeployParsed.xpathEval("/*")[0]
+        fesaRoot.setProp("xsi:noNamespaceSchemaLocation",deployUnitSchemaPath)
+
+        fesaVersionNode = fesaDeployParsed.xpathEval("/deploy-unit/information/fesa-version")[0]
+        fesaVersionNode.setContent(fesaVersion)
+
+        fesaDUNameNode = fesaDeployParsed.xpathEval("/deploy-unit/information/deploy-unit-name")[0]
+        fesaDUNameNode.setContent(deployName)
+
+        fesaOwnershipNode = fesaDeployParsed.xpathEval("/deploy-unit/ownership")[0]
+
+        defaultClassTemplate = fesaDeployParsed.xpathEval('/deploy-unit/class[class-name/text()="class-name"]')
+        if len(defaultClassTemplate) > 0:
+            defaultClassTemplate[0].unlinkNode()
+
+        silecsClasses = silecsDeployParsed.xpathEval("/SILECS-Deploy/Controller/SilecsDesign")
+        for silecsClass in silecsClasses:
+
+            existingClassEntry = fesaDeployParsed.xpathEval('/deploy-unit/class/class-name[text()="' + silecsClass.prop('silecs-design-name') + '"]')
+            if len(existingClassEntry) > 0:
+                continue # dont overwrite existing entrys
+
+            iecommon.logDebug("Adding class '" + silecsClass.prop('silecs-design-name') + "' to DeployUnit document", {'debuglog': True})
+            fesaClassNode = libxml2.newNode("class")
+
+            fesaClassName = libxml2.newNode("class-name")
+            fesaClassName.setContent(silecsClass.prop('silecs-design-name'))
+            fesaClassNode.addChild(fesaClassName)
+
+            fesaClassMajorVersion = libxml2.newNode("class-major-version")
+            fesaClassMajorVersion.setContent('0')
+            fesaClassNode.addChild(fesaClassMajorVersion)
+
+            fesaClassMinorVersion = libxml2.newNode("class-minor-version")
+            fesaClassMinorVersion.setContent('1')
+            fesaClassNode.addChild(fesaClassMinorVersion)
+
+            fesaClassTinyVersion = libxml2.newNode("class-tiny-version")
+            fesaClassTinyVersion.setContent('0')
+            fesaClassNode.addChild(fesaClassTinyVersion)
+
+            fesaClassDeviceInstance = libxml2.newNode("device-instance")
+            fesaClassDeviceInstance.setContent('required')
+            fesaClassNode.addChild(fesaClassDeviceInstance)
+
+            fesaOwnershipNode.addNextSibling(fesaClassNode)
+
+def fillDeployUnit(fesaVersion, className, workspacePath,fesaDesignXSDPath,logTopics={'errorlog': True}):
+    generator = FESADeployUnitGenerator3_0_0()
+    fesa.fillFesaDeployUnitBase.fillFesaDeployUnitBase(generator,fesaVersion, className, workspacePath,fesaDesignXSDPath,logTopics)
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/fillFESADeployUnit.pyc b/silecs-codegen/src/xml/fesa/fesa_3_0_0/fillFESADeployUnit.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..cd840c04a96109d04746c91f2801fb261daf56c9
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fesa_3_0_0/fillFESADeployUnit.pyc differ
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateBuildEnvironment$py.class b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateBuildEnvironment$py.class
new file mode 100644
index 0000000000000000000000000000000000000000..5c789754d31f9ea7d501313f62f7a65befd945d6
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateBuildEnvironment$py.class differ
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateBuildEnvironment.py b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateBuildEnvironment.py
new file mode 100644
index 0000000000000000000000000000000000000000..b6e6ed56fc78fa0e828e4f36a31d5a551c1274a9
--- /dev/null
+++ b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateBuildEnvironment.py
@@ -0,0 +1,70 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import os
+import sys
+import time
+import zlib
+import glob
+import re
+import datetime
+import socket
+
+import iecommon
+import fesaTemplates
+import iefiles
+
+from iecommon import *
+
+#-------------------------------------------------------------------------    
+# Generates two Makefile.specific, one for the class design
+# and another for the deploy unit
+#-------------------------------------------------------------------------    
+def genMakefileClass(projectPath, centralMakefilePath, logTopics={'errorlog': True} ):
+    # Generate makefile for class design
+    source = fesaTemplates.genMakeDesign(centralMakefilePath)
+    makefile = projectPath + "/" + "Makefile.specific"
+    if os.path.isfile(makefile): #dont overwrite
+        return
+    fdesc = open(makefile, "w")
+    iecommon.logInfo("Generate makefile.specific for class design:  " + makefile, logTopics)
+    fdesc.write(source)      
+    fdesc.close()
+
+def genMakefileDU(projectPath, silecsBasePath, snap7BasePath, logTopics={'errorlog': True}):
+    # Generate makefile for class design
+    source = fesaTemplates.genMakeDeploy(silecsBasePath,snap7BasePath)
+    # Write file and save
+    makefile = projectPath + "/" + "Makefile.specific"
+    if os.path.isfile(makefile): #dont overwrite
+        return
+    fdesc = open(makefile, "w")
+    iecommon.logInfo("Generate makefile.specific for deploy unit:  " + makefile, logTopics)
+    fdesc.write(source)      
+    fdesc.close()
+
+def genCProjectFile(projectPath, logTopics={'errorlog': True}):
+    # Generate makefile for class design
+    source = fesaTemplates.genCProject()
+    
+    # Write file and save
+    newFile = projectPath + "/" + ".cproject"
+    if os.path.isfile(newFile): #dont overwrite
+        return
+    fdesc = open(newFile, "w")
+    iecommon.logInfo("Generate .cproject", logTopics)
+    fdesc.write(source)      
+    fdesc.close()
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateBuildEnvironment.pyc b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateBuildEnvironment.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1c0a1031d4378963a6696790366150a8eadd39d5
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateBuildEnvironment.pyc differ
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateFesaDesign$py.class b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateFesaDesign$py.class
new file mode 100644
index 0000000000000000000000000000000000000000..3a5ea7798548189be5e399cb855e51d69cd9bfda
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateFesaDesign$py.class differ
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateFesaDesign.py b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateFesaDesign.py
new file mode 100644
index 0000000000000000000000000000000000000000..9aa76a346333523b0aa827eae5a55cf99268382c
--- /dev/null
+++ b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateFesaDesign.py
@@ -0,0 +1,523 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import fesa.fillFesaDesignBase
+
+import os
+import sys
+import time
+import zlib
+import glob
+import re
+import datetime
+import socket
+
+import iecommon
+import fesaTemplates
+import iefiles
+
+from iecommon import *
+
+import libxml2
+
+
+class FESADesignGenerator3_0_0(object):
+
+    #=========================================================================
+    # Sub-functions
+    #=========================================================================
+
+    def isGSITemplate(self,parent):
+        if isChildElement(parent,"GSI-Status-Property"):
+            return True
+        if isChildElement(parent,"GSI-Init-Property"):
+            return True
+        return False
+
+
+    def getSilecsStringLength(self,register):
+        strlen = '64'# check if custom length exists for string, otherwise use default length (64)
+        if(register.hasProp('string-len')):
+            strlen = str(register.prop('string-len'))
+        return strlen
+
+    def getOrCreateStringArrayType(self,fieldNode,register):
+        array2DNode = getOrCreateChildElement(fieldNode,'array2D')
+        fillAttributes(array2DNode, {'type': iecommon.getFesaDataType(register.prop('format'))})
+        dim1Node = getOrCreateChildElement(array2DNode,'dim1')
+        dim2Node = getOrCreateChildElement(array2DNode,'dim2')
+        dim1Node.setContent(register.prop('array-dim1')) # first dimension is the dimension of the array
+        dim2Node.setContent(self.getSilecsStringLength(register)) # first dimension is the dimension of the array
+        return array2DNode
+
+    def getOrCreateStringType(self,fieldNode,register):
+        stringNode = getOrCreateChildElement(fieldNode,'array')
+        fillAttributes(stringNode, {'type': iecommon.getFesaDataType(register.prop('format'))})
+        dimNode = getOrCreateChildElement(stringNode,'dim')
+        dimNode.setContent(self.getSilecsStringLength(register)) # first dimension is the dimension of the array
+        return stringNode
+
+    def getOrCreate2DArrayType(self,fieldNode,register):
+        array2DNode = getOrCreateChildElement(fieldNode,'array2D')
+        fillAttributes(array2DNode, {'type': iecommon.getFesaDataType(register.prop('format'))})
+        dim1Node = getOrCreateChildElement(array2DNode,'dim1')
+        dim2Node = getOrCreateChildElement(array2DNode,'dim2')
+        dim1Node.setContent(register.prop('array-dim1'))
+        dim2Node.setContent(register.prop('array-dim2'))
+        return array2DNode
+
+    def getOrCreateArrayType(self,fieldNode,register):
+        arrayNode = getOrCreateChildElement(fieldNode,'array')
+        fillAttributes(arrayNode, {'type': iecommon.getFesaDataType(register.prop('format'))})
+        dimNode = getOrCreateChildElement(arrayNode,'dim')
+        dimNode.setContent(register.prop('array-dim1'))
+        return arrayNode
+
+    def getOrCreateScalarType(self,fieldNode,scalarType):
+        scalarNode = getOrCreateChildElement(fieldNode,'scalar')
+        fillAttributes(scalarNode, {'type': iecommon.getFesaDataType(scalarType)})
+        return scalarNode
+
+    def getOrCreateStringTypeBase(self,fieldNode,register):
+        if(register.prop('array-dim2')) and int(register.prop('array-dim2')) > 1:
+            iecommon.logError('ERROR: In register '+register.prop('name')+' - 2D array of strings not supported in FESA.', True, {'errorlog': True})
+            return null
+        elif (register.prop('array-dim1')) and int(register.prop('array-dim1')) > 1:
+            return self.getOrCreateStringArrayType(fieldNode,register)
+        else:
+            return self.getOrCreateStringType(fieldNode,register)
+
+    def getOrCreateBaseType(self,fieldNode,register):
+        if (register.prop('array-dim2')) and int(register.prop('array-dim2')) > 1:
+            return self.getOrCreate2DArrayType(fieldNode,register)
+        elif (register.prop('array-dim1')) and int(register.prop('array-dim1')) > 1:
+            return self.getOrCreateArrayType(fieldNode,register)
+        else:
+            return self.getOrCreateScalarType(fieldNode,register.prop('format'))
+
+    def getOrCreateType(self,fieldNode,register):
+        if(register.prop('format') == 'string'):
+            return self.getOrCreateStringTypeBase(fieldNode,register)
+        else:
+            return self.getOrCreateBaseType(fieldNode,register)
+
+    def getOrCreateFieldRef(self,valueItemNode,FieldNameRef):
+        fieldRefNode = getOrCreateNamedChildElement(valueItemNode,'data-field-ref',FieldNameRef,'field-name-ref')
+        return fieldRefNode
+        
+    def getOrCreateAcqStampItem(self,fieldNode):
+        item = getOrCreateChildElement(fieldNode,'acq-stamp-item')
+        fillAttributes(item, {'direction': 'OUT', 'name': 'acqStamp'})
+        scalar = getOrCreateChildElement(item,'scalar')
+        fillAttributes(scalar, {'type': 'int64_t'})
+        return item
+
+    def getOrCreateUpdateFlagItem(self,fieldNode):
+        item = getOrCreateChildElement(fieldNode,'update-flag-item')
+        fillAttributes(item, {'direction': 'OUT', 'name': 'updateFlags', 'optional': 'true'})
+        scalar = getOrCreateChildElement(item,'builtin-type-scalar')
+        fillAttributes(scalar, {'data-type-name-ref': 'NOTIFICATION_UPDATE'})
+        return item
+
+    def getOrCreateCyleNameItem(self,fieldNode):
+        item = getOrCreateChildElement(fieldNode,'cycle-name-item')
+        fillAttributes(item, {'direction': 'OUT', 'name': 'cycleName', 'optional': 'true'})
+        array = getOrCreateChildElement(item,'array')
+        fillAttributes(array, {'type': 'char'})
+        dim = getOrCreateChildElement(array,'dim')
+        dim.setContent('32')
+        return item
+
+    def getOrCreateCyleStampItem(self,fieldNode):
+        item = getOrCreateChildElement(fieldNode,'cycle-stamp-item')
+        fillAttributes(item, {'direction': 'OUT', 'name': 'cycleStamp', 'optional': 'true'})
+        scalar = getOrCreateChildElement(item,'scalar')
+        fillAttributes(scalar, {'type': 'int64_t'})
+        return item
+
+    def getOrCreateAcquisitionContextItem(self,propertyNode):
+        item = propertyNode.xpathEval('acquisition-context-item')
+        if item != None:
+            return item
+            
+        item = getOrCreateChildElement(propertyNode,'acquisition-context-item')
+        item.setProp("direction","OUT")
+        acqStamp = getOrCreateChildElement(item,'acqStamp')
+        acqStamp.setProp("direction","OUT")
+        acqStamp.setProp("name","acqStampGSI")
+        acqStampScalar = getOrCreateChildElement(acqStamp,'scalar')
+        acqStampScalar.setProp('type','int64_t')
+        
+        cycleStamp = getOrCreateChildElement(item,'cycleStamp')
+        cycleStamp.setProp("direction","OUT")
+        cycleStamp.setProp("name","cycleStampGSI")
+        cycleStampScalar = getOrCreateChildElement(cycleStamp,'scalar')
+        cycleStampScalar.setProp('type','int64_t')
+        
+        cycleName = getOrCreateChildElement(item,'cycleName')
+        cycleName.setProp("direction","OUT")
+        cycleName.setProp("name","cycleNameGSI")
+        cycleNameArray = getOrCreateChildElement(cycleName,'array')
+        cycleNameArray.setProp('type','char')
+        cycleNameDim = getOrCreateChildElement(cycleNameArray,'custom-constant-dim')
+        cycleNameDim.setProp('constant-name-ref', 'MAX_CYCLE_NAME_LENGTH')
+        
+        beamProcessID = getOrCreateChildElement(item,'beamProcessID')
+        beamProcessID.setProp("direction","OUT")
+        beamProcessID.setProp("name","beamProcessID")
+        beamProcessIDScalar = getOrCreateChildElement(beamProcessID,'scalar')
+        beamProcessIDScalar.setProp('type','int32_t')
+        
+        sequenceID = getOrCreateChildElement(item,'sequenceID')
+        sequenceID.setProp("direction","OUT")
+        sequenceID.setProp("name","sequenceID")
+        sequenceIDScalar = getOrCreateChildElement(sequenceID,'scalar')
+        sequenceIDScalar.setProp('type','int32_t')
+        
+        fieldRef = getOrCreateChildElement(item,'acquisition-context-field-ref')
+        fieldRef.setProp("field-name-ref","acquisitionContext")
+                        
+    def getOrCreateAction(self,propNode,name,type,actionsNode,implementation):
+        iecommon.logDebug('Generating Server-Action: ' + name, {'debuglog': True})
+        action = getOrCreateChildElement(propNode,type +'-action')
+        if not isChildElement(action,'server-action-ref'):
+            actionSub = getOrCreateChildElement(action,'server-action-ref')
+            fillAttributes(actionSub, {'server-action-name-ref': name})
+        finalName = action.xpathEval("server-action-ref")[0].prop('server-action-name-ref') # could be different from name if already exists
+        getActionNode = getOrCreateNamedChildElement(actionsNode,type + '-server-action',finalName)
+        fillAttributes(getActionNode, {'implementation': implementation})
+
+    def getOrCreateFieldNode(self,parent,register): #in order to place them before any GSI-specifc fields (order matters!)
+        iecommon.logDebug('Generating Data-Field for register: ' + register.prop('name'), {'debuglog': True})
+        if( hasChildren(parent) ):
+            return getOrCreateNamedPreviousSiblingElement(parent,getFirstChild(parent),'field',register.prop('name'))
+        else:
+            return getOrCreateNamedChildElement(parent,'field',register.prop('name'))
+
+    def getOrCreatePLCHostNameField(self,configurationNode):
+        fieldNode = getOrCreateNamedFirstChild(configurationNode,'field','plcHostName')
+        descriptionNode = getOrCreateChildElement(fieldNode,'description')
+        descriptionNode.setContent('Hostname of the PLC that contains the related SILECS class device')
+        array = getOrCreateChildElement(fieldNode,'array')
+        fillAttributes(array, {'type': 'char'})
+        dim = getOrCreateChildElement(array,'dim')
+        dim.setContent('128')
+        return fieldNode
+
+    def getOrCreatePLCDeviceLabelField(self,configurationNode):
+        fieldNode = getOrCreateNamedFirstChild(configurationNode,'field','plcDeviceLabel')
+        descriptionNode = getOrCreateChildElement(fieldNode,'description')
+        descriptionNode.setContent('Name of the related SILECS instance within the PLC mapping')
+        array = getOrCreateChildElement(fieldNode,'array')
+        fillAttributes(array, {'type': 'char'})
+        dim = getOrCreateChildElement(array,'dim')
+        dim.setContent('128')
+        return fieldNode
+        
+    def getOrCreateParameterFileField(self,configurationNode):
+        fieldNode = getOrCreateNamedFirstChild(configurationNode,'field','parameterFile')
+        descriptionNode = getOrCreateChildElement(fieldNode,'description')
+        descriptionNode.setContent('ParameterFile of the PLC (*.silecsparam)')
+        array = getOrCreateChildElement(fieldNode,'array')
+        fillAttributes(array, {'type': 'char'})
+        dim = getOrCreateChildElement(array,'dim')
+        defaultNode = getOrCreateChildElement(fieldNode,'default')
+        defaultNode.setContent('../../../generated/client/MyControllerName.silecsparam')
+        dim.setContent('512')
+        return fieldNode
+
+    def getOrCreatePLCClassVersionField(self,configurationNode,plcClassVersion):
+        fieldNode = getOrCreateNamedFirstChild(configurationNode,'field','plcClassVersion')
+        descriptionNode = getOrCreateChildElement(fieldNode,'description')
+        descriptionNode.setContent('Version of the SILECS class that needs to be deployed in the controller')
+        array = getOrCreateChildElement(fieldNode,'array')
+        fillAttributes(array, {'type': 'char'})
+        dim = getOrCreateChildElement(array,'dim')
+        defaultNode = getOrCreateChildElement(fieldNode,'default')
+        defaultNode.setContent(plcClassVersion)
+        dim.setContent(str(len(defaultNode.getContent())))
+        return fieldNode
+                
+    def getOrCreateRegisterValueItems(self,prop,block,isSetting):
+        for register in block.xpathEval('Register'):
+            if register.prop('generateFesaValueItem') == 'true':
+                self.getOrCreateValueItem(prop,register,isSetting)
+
+    def getOrCreateSettingProperty(self,parent,block):
+        iecommon.logDebug('Generating SettingProperty for Block: ' + block.prop('name'), {'debuglog': True})
+        if( hasChildren(parent)):
+            propsAfterCommand = parent.xpathEval("*[not(name()='command-property')]")
+            prop = getOrCreateNamedPreviousSiblingElement(parent,propsAfterCommand[0], 'setting-property',block.prop('name'))
+        else:
+            prop = getOrCreateNamedChildElement(parent,'setting-property',block.prop('name'))
+        self.getOrCreateRegisterValueItems(prop,block,True)
+        self.getOrCreateUpdateFlagItem(prop)
+        self.getOrCreateCyleNameItem(prop)
+        return prop
+            
+    def getOrCreateAcquisitionProperty(self,parent,actionsNode,block):
+        iecommon.logDebug('Generating AcquisitionProperty for Block: ' + block.prop('name'), {'debuglog': True})
+        prop = ""
+        if( hasChildren(parent)):
+            prop = getOrCreateNamedPreviousSiblingElement(parent,getFirstChild(parent), 'acquisition-property',block.prop('name'))
+        else:
+            prop = getOrCreateNamedChildElement(parent,'acquisition-property',block.prop('name'))
+        fillAttributes(prop, {'visibility': 'development', 'subscribable': 'true', 'multiplexed': 'false', 'on-change': 'true'})
+        self.getOrCreateRegisterValueItems(prop,block,False)
+        self.getOrCreateAcqStampItem(prop)
+        self.getOrCreateUpdateFlagItem(prop)
+        self.getOrCreateCyleNameItem(prop)
+        self.getOrCreateCyleStampItem(prop)
+        self.getOrCreateAction(prop,'Get'+block.prop('name'),'get',actionsNode,'default')
+        return prop
+                
+            
+    def getOrCreateGSISettingProperty(self,parent,block):
+        iecommon.logDebug('Generating GSISettingProperty for Block: ' + block.prop('name'), {'debuglog': True})
+        powerProp = parent.xpathEval('GSI-Power-Property')[0] # template is used --> there has to be a power prop
+        prop =  getOrCreateNamedPreviousSiblingElement(parent,powerProp, 'GSI-Setting-Property',block.prop('name'))
+        self.getOrCreateRegisterValueItems(prop,block,True)
+        self.getOrCreateUpdateFlagItem(prop)
+        self.getOrCreateCyleNameItem(prop)
+        return prop
+            
+    def getOrCreateGSIAcquisitionProperty(self,parent,actionsNode,block):
+        iecommon.logDebug('Generating GSIAcquisitionProperty for Block: ' + block.prop('name'), {'debuglog': True})
+        versionProp = parent.xpathEval('GSI-Version-Property')[0] # template is used --> there has to be a version prop
+        prop =  getOrCreateNamedPreviousSiblingElement(parent,versionProp, 'GSI-Acquisition-Property',block.prop('name'))
+        fillAttributes(prop, {'visibility': 'development', 'subscribable': 'true', 'multiplexed': 'false', 'on-change': 'true'})
+        self.getOrCreateRegisterValueItems(prop,block,False)
+        self.getOrCreateAcqStampItem(prop)
+        self.getOrCreateUpdateFlagItem(prop)
+        self.getOrCreateCyleNameItem(prop)
+        self.getOrCreateCyleStampItem(prop)
+        self.getOrCreateAction(prop,'Get'+block.prop('name'),'get',actionsNode,'default')
+        self.getOrCreateAcquisitionContextItem(prop)
+        return prop
+
+    # propertyType only used during creation ! If named property already exists, it is just returned, no matter which type
+    def getOrCreateFESAProperty(self,parent,actionsNode,block):
+        properties = parent.xpathEval("*")
+        if self.isGSITemplate(parent):
+            if parent.get_name() == 'setting':
+                return self.getOrCreateGSISettingProperty(parent,block)
+            else:
+                return self.getOrCreateGSIAcquisitionProperty(parent,actionsNode,block)
+        else:
+            if parent.get_name() == 'setting':
+                return self.getOrCreateSettingProperty(parent,block)
+            else:
+                return self.getOrCreateAcquisitionProperty(parent,actionsNode,block)
+
+    def getOrCreateValueItem(self,propertyNode,register,isSetting):
+        iecommon.logDebug('Generating ValueItem for Register: ' + register.prop('name'), {'debuglog': True})
+        result = propertyNode.xpathEval("value-item[@name='" + register.prop('name') + "']")
+        if len(result):
+            return result[0]
+        if( hasChildren(propertyNode)):
+            result = propertyNode.xpathEval("*[not(name()='description') and not(name()='export') and not(name()='filter-item')]") # skip possible first elements to get right position
+            valueItemNode =  getOrCreateNamedPreviousSiblingElement(propertyNode,result[0],'value-item',register.prop('name'))
+        else:
+            valueItemNode = getOrCreateNamedChildElement(propertyNode,'value-item',register.prop('name'))
+        if isSetting:
+            fillAttributes(valueItemNode, {'direction': 'INOUT'})
+        else:
+            fillAttributes(valueItemNode, {'direction': 'OUT'})
+        self.getOrCreateType(valueItemNode,register)
+        self.getOrCreateFieldRef(valueItemNode,register.prop('name'))
+
+    #-------------------------------------------------------------------------
+    # Generates the data node of the FESA design document
+    # parsing the SILECS class document
+    #-------------------------------------------------------------------------
+    def genData(self,silecsRoot, doc,logTopics):
+        iecommon.logDebug("Creating data fields", logTopics)
+        
+        dataNode = doc.xpathEval('/equipment-model/data')[0]
+        iecommon.logError("len(dataNode)" + dataNode.get_name(), logTopics)
+        deviceDataNode = getOrCreateChildElement(dataNode,'device-data')
+        configurationNode = getOrCreateChildElement(deviceDataNode,'configuration')
+        settingNode = getOrCreateChildElement(deviceDataNode,'setting')
+        acquisitionNode = getOrCreateChildElement(deviceDataNode,'acquisition')
+        self.getOrCreatePLCHostNameField(configurationNode)
+        self.getOrCreatePLCDeviceLabelField(configurationNode)
+        classNode = silecsRoot.xpathEval('//SILECS-Class')[0]
+        self.getOrCreateParameterFileField(configurationNode)
+        # parse the SILECS design document to find the blocks 
+        for block in silecsRoot.xpathEval("//Block"):   # loop over the blocks
+            iecommon.logDebug('Analysing block '+block.prop('name'), logTopics)
+            # Check that every register in the block has the same value for synchro
+            regList = block.xpathEval("Register")
+            for r in range (0, len(regList)-1):
+                if regList[r].prop('synchro') != regList[r+1].prop('synchro'):
+                    # Return error and exit
+                     iecommon.logError('ERROR: In block '+block.prop('name')+' registers have different synchronisation values.', True, logTopics)        
+            
+            if block.prop('mode') == 'READ-ONLY':
+                for reg in regList:
+                    fieldNode = self.getOrCreateFieldNode(acquisitionNode,reg)
+                    if reg.prop('synchro') == 'MASTER': # the value of a master register never change, consistency is not required
+                        fillAttributes(fieldNode, {'multiplexed': 'false', 'persistent': 'false'})
+                    elif reg.prop('synchro') == 'NONE':
+                        fillAttributes(fieldNode, {'multiplexed': 'false', 'persistent': 'false'})
+                    self.getOrCreateType(fieldNode,reg)
+            
+            elif block.prop('mode') == 'WRITE-ONLY':
+                for reg in regList:
+                    fieldNode = self.getOrCreateFieldNode(settingNode,reg)
+                    if reg.prop('synchro') == 'SLAVE':
+                        fillAttributes(fieldNode, {'multiplexed': 'false', 'persistent': 'true', 'shared': 'true'})
+                    elif reg.prop('synchro') == 'NONE':
+                        fillAttributes(fieldNode, {'multiplexed': 'false', 'persistent': 'false', 'shared': 'true'})
+                    self.getOrCreateType(fieldNode,reg)
+             
+            else:       # READ-WRITE block
+                for reg in regList:
+                    fieldNode = self.getOrCreateFieldNode(settingNode,reg)
+                    if reg.prop('synchro') == 'NONE':
+                        fillAttributes(fieldNode, {'multiplexed': 'false', 'persistent': 'false'})
+                    else:   #synchro SLAVE and MASTER
+                        fillAttributes(fieldNode, {'multiplexed': 'false', 'persistent': 'true'})
+                    self.getOrCreateType(fieldNode,reg)
+
+        globalDataNode = getOrCreateChildElement(dataNode,'global-data')
+        globalConfigurationNode = ""
+        if len(globalDataNode.xpathEval("configuration")) == 0:
+            if len( globalDataNode.xpathEval("*")) == 0:
+                globalConfigurationNode = getOrCreateChildElement(globalDataNode,'configuration')
+            else:
+                globalConfigurationNode = getOrCreatePreviousSiblingElement(getFirstChild(globalDataNode),'configuration')
+        else:
+            globalConfigurationNode = globalDataNode.xpathEval("configuration")[0]
+        self.getOrCreatePLCClassVersionField(globalConfigurationNode,classNode.prop('version'))
+
+    #-------------------------------------------------------------------------
+    # Generates the interface/device-interface node of the 
+    # FESA design document parsing the SILECS class document
+    #-------------------------------------------------------------------------
+    def genDeviceInterface(self,silecsRoot, doc,logTopics):
+        # parse the FESA design document to find the device-interface node and create children
+        interfaceNode = doc.xpathEval('/equipment-model/interface')[0]
+        globalInterfaceNode = getOrCreateChildElement(interfaceNode,'global-interface')
+        deviceInterfaceNode = getOrCreatePreviousSiblingElement(globalInterfaceNode,'device-interface')
+        settingNode = getOrCreateChildElement(deviceInterfaceNode,'setting')
+        acquisitionNode = getOrCreateChildElement(deviceInterfaceNode,'acquisition')
+        actionsNode = doc.xpathEval('/equipment-model/actions')[0]
+        for block in silecsRoot.xpathEval("//Block"):
+
+            if block.prop('generateFesaProperty') == 'false':
+                continue #skip this block
+
+            if block.prop('mode') in ('READ-ONLY'):
+                self.getOrCreateFESAProperty(acquisitionNode,actionsNode,block)
+                rtAction = getOrCreateNamedChildElement(actionsNode,'rt-action','Recv'+block.prop('name'))
+                notifiedProperty = getOrCreateNamedChildElement(rtAction,'notified-property',block.prop('name'),'property-name-ref')
+                fillAttributes(notifiedProperty, {'automatic': 'true'})
+                self.genEvent(block,doc,logTopics)
+                self.genSchedulingUnit(block,doc,logTopics)
+            else:   # setting property for both WO and RW blocks, w/get+set server action
+                settingPropertyNode = self.getOrCreateFESAProperty(settingNode, actionsNode, block)
+                fillAttributes(settingPropertyNode, {'visibility': 'development', 'multiplexed': 'false'})
+                self.getOrCreateAction(settingPropertyNode,'Send'+block.prop('name'),'set',actionsNode,'custom')
+                if block.prop('mode') == 'READ-WRITE':
+                    self.getOrCreateAction(settingPropertyNode,'Recv'+block.prop('name'),'get',actionsNode,'custom')
+                else:   # WRITE-ONLY
+                    self.getOrCreateAction(settingPropertyNode,'Get'+block.prop('name'),'get',actionsNode,'default')
+
+    #-------------------------------------------------------------------------
+    # Generates the logical-events node of the FESA design
+    # document parsing the SILECS class document
+    #-------------------------------------------------------------------------       
+    def genEvent(self,block, fesaRoot,logTopics):
+        iecommon.logDebug('Generating event', logTopics)
+        eqpModelNode = fesaRoot.xpathEval("/equipment-model")[0]
+        eventsNode = getOrCreateChildElement(eqpModelNode,'events')
+        sourcesNode = getOrCreateChildElement(eventsNode,'sources')
+        timingSourceNode = getOrCreateNamedChildElement(sourcesNode,'timing-event-source','Timing')
+        timerSourceNode = getOrCreateNamedChildElement(sourcesNode,'timer-event-source','Timer')
+        logicalEventsNode = getOrCreateChildElement(eventsNode,'logical-events')
+        logicalEventNode = getOrCreateNamedChildElement(logicalEventsNode,'logical-event','Recv'+block.prop('name')+'Event')
+        fillAttributes(logicalEventNode, {'type': 'timer', 'use': 'required'})
+            
+    #-------------------------------------------------------------------------
+    # Generates the scheduling-units node of the FESA design
+    # document parsing the SILECS class document
+    #-------------------------------------------------------------------------
+    def genSchedulingUnit(self,block, fesaRoot,logTopics):
+        iecommon.logDebug('Generating scheduling unit', logTopics)
+        eqpModelNode = fesaRoot.xpathEval("/equipment-model")[0]
+        schedulingUnitsNode = getOrCreateChildElement(eqpModelNode,'scheduling-units')
+        schedulingUnitNode = getOrCreateNamedChildElement(schedulingUnitsNode,'scheduling-unit','Recv'+block.prop('name')+'Unit')
+        rtActionRefNode = getOrCreateChildElement(schedulingUnitNode,'rt-action-ref')
+        fillAttributes(rtActionRefNode, {'rt-action-name-ref': 'Recv'+block.prop('name')})
+        logicalEventRefNode = getOrCreateChildElement(schedulingUnitNode,'logical-event-ref')
+        fillAttributes(logicalEventRefNode, {'logical-event-name-ref': 'Recv'+block.prop('name')+'Event'})
+
+    #-------------------------------------------------------------------------
+    # Generates the scheduling-units node of the FESA design
+    # document parsing the SILECS class document
+    #-------------------------------------------------------------------------
+    def addDesignFileId(self,fesaDesignFile,logTopics):
+        nodeRequiringId = ['setting-property','acquisition-property','diagnostic-property',
+                           'value-item','update-flag-item','cycle-name-item', 'acq-stamp-item',
+                           'cycle-stamp-item','mode-item','host-item','port-item','config-item',
+                           'state-item','fwk-topic-item','custom-topic-item','device-trace-item',
+                           'bypass-action-item','diag-custom-topic','field','timing-event-source',
+                           'timer-event-source','logical-event']
+        counter = 0
+        now = datetime.datetime.today()
+        id = '_' + now.strftime('%y%m%d%H%M%S') + '_%s'
+        for nodeName in nodeRequiringId:
+            for node in fesaDesignFile.xpathEval("//" + nodeName):
+                if node.hasProp("id"):
+                    node.setProp("id", id%counter)
+                    counter = counter +1
+        
+            
+    def fillXML(self,fesaVersion, className, fesaRoot, silecsRoot,logTopics={'errorlog': True}):
+
+        #print etree.tostring(silecsRoot, pretty_print=True)
+        #-------------------------------------------------------------------------
+        # Fill section <information>
+        #-------------------------------------------------------------------------
+        informationNode = fesaRoot.xpathEval("/equipment-model/information")[0]
+        informationNode.xpathEval("class-name")[0].setContent(className)
+        informationNode.xpathEval("fesa-version")[0].setContent(fesaVersion)
+
+        #-------------------------------------------------------------------------
+        # Fill section <ownership>
+        #-------------------------------------------------------------------------
+        creatorNode = fesaRoot.xpathEval("//ownership/creator")[0]
+        owner = silecsRoot.xpathEval('//Information/Owner')[0]
+
+        creatorNode.setProp('login', owner.prop('user-login'))    # == Owner in SILECS design document
+       
+        # Generate data fields
+        self.genData(silecsRoot, fesaRoot,logTopics)
+
+        # Generate properties, Actions, Events, Scheduling Units
+        self.genDeviceInterface(silecsRoot, fesaRoot,logTopics)
+
+        self.addDesignFileId(fesaRoot,logTopics)
+        return fesaRoot
+
+#-------------------------------------------------------------------------
+# Fill the FESA design document - entry point of the plugin
+#-------------------------------------------------------------------------
+def fillDesignFile(fesaVersion, className, workspacePath,fesaDesignXSDPath,logTopics={'errorlog': True}):
+    generator = FESADesignGenerator3_0_0()
+    fesa.fillFesaDesignBase.fillDesignFileBase(generator,fesaVersion, className, workspacePath,fesaDesignXSDPath,logTopics)
+
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateFesaDesign.pyc b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateFesaDesign.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c272814d893e20e5e63cef311e1ec38afc8153a3
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateFesaDesign.pyc differ
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode$py.class b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode$py.class
new file mode 100644
index 0000000000000000000000000000000000000000..8770643814912b44ab3d8ba0d73eba6c05f8f7e1
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode$py.class differ
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode.py b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode.py
new file mode 100644
index 0000000000000000000000000000000000000000..2b520a933ce43726168a3e529d2713b38a7956be
--- /dev/null
+++ b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode.py
@@ -0,0 +1,356 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import os
+import sys
+import time
+import zlib
+import glob
+import re
+import datetime
+import socket
+
+import iecommon
+import fesaTemplates
+import iefiles
+
+from iecommon import *
+import libxml2
+
+def findBlockServerSetActionName(fesaRoot, blockName):
+    properties = fesaRoot.xpathEval("/equipment-model/interface/device-interface/*/*[@name='" + blockName + "']")
+    for property in properties:
+        return property.xpathEval("set-action/server-action-ref")[0].prop("server-action-name-ref")
+    raise Exception("Error: Server Action for Block '" + blockName + "' not found")
+
+#-------------------------------------------------------------------------  
+# Generates the H source file containing general methods
+# to synchronise the FESA fields and related PLC registers
+# of the FESA server
+#-------------------------------------------------------------------------  
+def genHSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
+    source =  fesaTemplates.genHTop(className)
+    
+    for block in silecsRoot.xpathEval('//Block'):
+        if block.prop('mode') == 'WRITE-ONLY' or block.prop('mode') == 'READ-WRITE':
+            serverActionName = findBlockServerSetActionName(fesaRoot,block.prop('name'))
+            source += fesaTemplates.genHTopBlock(className, serverActionName)
+        
+    source += fesaTemplates.genHTop2(className)
+        
+    for block in silecsRoot.xpathEval('//Block'):
+        if block.prop('mode') == 'READ-ONLY':
+            source += fesaTemplates.genHBlock('RO', block.prop('name'))
+        elif block.prop('mode') == 'WRITE-ONLY':
+            source += fesaTemplates.genHBlock('WO', block.prop('name'))
+        else:   # READ-WRITE
+            source += fesaTemplates.genHBlock('RW', block.prop('name'))
+    
+    source += fesaTemplates.genHBottom(className)
+
+    for block in silecsRoot.xpathEval('//Block'):
+        source += fesaTemplates.genHDeclBlocks(block.prop('name'))
+    
+    source += fesaTemplates.genHClosing(className)
+    
+    # Create output directory if necessary
+    if not os.path.exists(sourcePath):
+        os.makedirs(sourcePath)
+    iecommon.logDebug("Create directory %s" %sourcePath, logTopics)
+    
+    # Write to file and save
+    sourceFile = sourcePath + "/"+ className + ".h"
+    iecommon.logInfo("Generate header file: " + sourceFile, logTopics)
+    fdesc = open(sourceFile, "w")
+    fdesc.write(source)
+    fdesc.close()  
+ 
+    iecommon.logInfo('Header file for '+className+' generated successfully', logTopics)
+    
+#-------------------------------------------------------------------------  
+# Generates the C++ source file containing general 
+# methods to synchronise the FESA fields and related PLC 
+# registers of the FESA server
+#-------------------------------------------------------------------------    
+def genCppSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
+    finalSource =  fesaTemplates.genCTop(className)
+    blockList = silecsRoot.xpathEval('//Block')
+    for block in blockList:
+        finalSource +=  fesaTemplates.genCGlobal(className, block.prop('name'))
+    
+    finalSource += fesaTemplates.genCPart1(className)
+    
+    for block in blockList:
+        finalSource += fesaTemplates.genCBlockConstr(block.prop('name'), className)
+        
+    finalSource += fesaTemplates.genCPart2(className)
+    
+    for block in blockList:
+        regList = block.xpathEval('Register')
+        if (block.prop('mode') == 'WRITE-ONLY' or block.prop('mode') == 'READ-WRITE') and regList[0].prop('synchro') == 'SLAVE':
+            # just set the fields if block is WO or RW and register synchronisation is SLAVE
+            # WARNING: In order to have multiplexed FESA fields, the corresponding SILECS registers' synchro mode must be 'NONE' 
+            finalSource += fesaTemplates.genCSetPLC(className, block.prop('name'))
+        
+    finalSource += fesaTemplates.genCPart3(className)
+    
+    for block in blockList:
+        regList = block.xpathEval('Register')
+        if (block.prop('mode') == 'READ-ONLY' or block.prop('mode') == 'READ-WRITE') and regList[0].prop('synchro') == 'MASTER':
+            # just get the fields if block is RO or RW and register synchronisation is MASTER
+            # WARNING: In order to have multiplexed FESA fields, the corresponding SILECS registers' synchro mode must be 'NONE'
+            finalSource += fesaTemplates.genCGetPLC(className, block.prop('name'))
+    
+    finalSource += fesaTemplates.genCPart4(className)
+    
+    for block in blockList:
+        
+        source = ''     #compute one source at a time
+        flagReg = False
+        flagDim1 = False
+        flagDim2 = False
+        
+        if block.prop('mode') != 'WRITE-ONLY':
+            finalSource += fesaTemplates.genCCommonGet(block.prop('name'),className)
+
+            regList = block.xpathEval('Register')
+            source += fesaTemplates.cRecv
+            
+            for reg in regList:
+                type = reg.prop('format')
+                if type == 'string':    # string register
+                    flagReg = True                    
+                    if (reg.prop('array-dim1')) and int(reg.prop('array-dim1')) > 1:   # string array
+                        flagDim1 = True                    
+                        source += fesaTemplates.genCGetStringArrayReg(reg.prop('name'))
+                    else:   # simple string
+                        source += fesaTemplates.genCGetStringReg(reg.prop('name'))
+
+                else:   # not string register
+                    # uppercasing of type
+                    fesaType = iecommon.getFesaDataType(type)
+                    type = iecommon.getSilecsDataType(type)
+                    if type[0] == 'u':
+                        type = type[:2].upper() + type[2:]  # first two characters if unsigned
+                        
+                        if reg.prop('array-dim2') and int(reg.prop('array-dim2')) > 1:    # 2D array
+                            flagReg = True                    
+                            flagDim2 = True                    
+                            flagDim1 = True                    
+                            source += fesaTemplates.genCGetUnsignedArray2DReg(reg.prop('name'), fesaType, type)
+                        elif (reg.prop('array-dim1')) and int(reg.prop('array-dim1')) > 1:   # array
+                            flagReg = True                    
+                            flagDim1 = True                    
+                            source += fesaTemplates.genCGetUnsignedArrayReg(reg.prop('name'), fesaType, type)
+                        else:    # scalar
+                            source += fesaTemplates.genCGetScalarReg(reg.prop('name'), type) 
+                            
+                    elif type[0] == 'd':    # date type
+                        if reg.prop('array-dim2') and int(reg.prop('array-dim2')) > 1:
+                            flagReg = True                    
+                            flagDim2 = True                    
+                            flagDim1 = True                    
+                            source += fesaTemplates.genCGetArray2DReg(reg.prop('name'), 'Date')
+                        elif (reg.prop('array-dim1')) and int(reg.prop('array-dim1')) > 1:   # array
+                            flagReg = True                    
+                            flagDim1 = True                    
+                            source += fesaTemplates.genCGetArrayReg(reg.prop('name'), 'Date')
+                        else:    # scalar
+                            source += fesaTemplates.genCGetScalarReg(reg.prop('name'), 'Date')
+                        
+                    else:
+                        type = type[:1].upper() + type[1:]  # only first character if not unsigned
+                        if reg.prop('array-dim2') and int(reg.prop('array-dim2')) > 1:    # 2D array
+                            flagReg = True                    
+                            flagDim2 = True                    
+                            flagDim1 = True                    
+                            source += fesaTemplates.genCGetArray2DReg(reg.prop('name'), type)
+                        elif (reg.prop('array-dim1')) and int(reg.prop('array-dim1')) > 1:   # array
+                            flagReg = True                    
+                            flagDim1 = True                    
+                            source += fesaTemplates.genCGetArrayReg(reg.prop('name'), type)
+                        else:    # scalar
+                            source += fesaTemplates.genCGetScalarReg(reg.prop('name'), type)
+            
+            source += '\n\t}'   # closing bracket for block
+
+        #Add data declatation on top if needed and append the final source
+        if flagReg == True:
+            finalSource += fesaTemplates.cRegVar
+        if flagDim1 == True:
+            finalSource += fesaTemplates.cGetArrayVar
+        if flagDim2 == True:
+            finalSource += fesaTemplates.cGetArray2DVar
+            
+        finalSource += '\n' + source    
+                                   
+        source = ''     #compute one source at a time
+        flagReg = False
+        flagDim1 = False
+        flagDim2 = False
+
+        if block.prop('mode') != 'READ-ONLY':
+            finalSource += fesaTemplates.genCCommonSet(block.prop('name'),className)
+            
+            regList = block.xpathEval('Register')
+            
+            for reg in regList:
+                type = reg.prop('format')
+                if type == 'string':
+                    flagReg = True                    
+                    if (reg.prop('array-dim1')) and int(reg.prop('array-dim1')) > 1:   # string array
+                        flagDim1 = True                    
+                        source += fesaTemplates.genCSetStringArrayReg(reg.prop('name'))
+                    else:   # simple string
+                        source += fesaTemplates.genCSetStringReg(reg.prop('name'))
+                
+                else:   # not string register              
+                    # uppercasing of type
+                    type = iecommon.getSilecsDataType(type)
+                    lowerType = type+'_t'   # store lowercase type for unsigned registers (fesa type)
+                    if type[0] == 'u':  # unsigned type
+                        type = type[:2].upper() + type[2:]  # first two characters if unsigned
+
+                        if reg.prop('array-dim2') and int(reg.prop('array-dim2')) > 1:    # 2D array
+                            flagReg = True                    
+                            flagDim2 = True                    
+                            flagDim1 = True                    
+                            source += fesaTemplates.genCSetUnsignedArray2DReg(reg.prop('name'), type)
+                        elif (reg.prop('array-dim1')) and int(reg.prop('array-dim1')) > 1:   # array
+                            flagReg = True                    
+                            flagDim1 = True                    
+                            source += fesaTemplates.genCSetUnsignedArrayReg(reg.prop('name'), type)
+                        else:    # scalar
+                            source += fesaTemplates.genCSetScalarUReg(reg.prop('name'), type, lowerType)
+    
+                    else:   # signed type
+                        type = type[:1].upper() + type[1:]  # only first character if not unsigned
+                        if reg.prop('array-dim2') and int(reg.prop('array-dim2')) > 1:    # 2D array
+                            flagReg = True                    
+                            flagDim2 = True                    
+                            flagDim1 = True                    
+                            source += fesaTemplates.genCSetArray2DReg(reg.prop('name'), type)
+                        elif (reg.prop('array-dim1')) and int(reg.prop('array-dim1')) > 1:   # array
+                            flagReg = True                    
+                            flagDim1 = True                    
+                            source += fesaTemplates.genCSetArrayReg(reg.prop('name'), type)
+                        else:    # scalar
+                            source += fesaTemplates.genCSetScalarReg(reg.prop('name'), type)
+
+            source += fesaTemplates.cSend
+            source += '\n\t}'   # closing bracket for block
+        
+            #Add data declatation on top if needed and append the final source
+            if flagReg == True:
+                finalSource += fesaTemplates.cRegVar
+            if flagDim1 == True:
+                finalSource += fesaTemplates.cSetArrayVar
+            if flagDim2 == True:
+                finalSource += fesaTemplates.cSetArray2DVar
+            
+            finalSource += '\n' + source    
+                      
+            source = ''     #compute one source at a time
+            flagReg = False
+            flagDim1 = False
+            flagDim2 = False
+    
+            finalSource += fesaTemplates.genCDatatypeSet(block.prop('name'),className)
+            
+            regList = block.xpathEval('Register')
+            
+            for reg in regList:
+                type = reg.prop('format')
+                if type == 'string':
+                    flagReg = True                    
+                    if (reg.prop('array-dim1')) and int(reg.prop('array-dim1')) > 1:   # string array
+                        flagDim1 = True                    
+                        source += fesaTemplates.genCSetStringArrayRegData(reg.prop('name'))
+                    else:   # simple string
+                        source += fesaTemplates.genCSetStringRegData(reg.prop('name'))
+                
+                else:   # not string register
+                    # uppercasing of type
+                    fesaType = iecommon.getFesaDataType(type)
+                    type = iecommon.getSilecsDataType(type)
+                    lowerType = type+'_t'   # store lowercase type for unsigned registers (fesa type)
+                    if type[0] == 'u':  # unsigned type
+                        type = type[:2].upper() + type[2:]  # first two characters if unsigned
+                        if reg.prop('array-dim2') and int(reg.prop('array-dim2')) > 1:    # 2D array
+                            flagReg = True                    
+                            flagDim2 = True                    
+                            flagDim1 = True                    
+                            source += fesaTemplates.genCSetUnsignedArray2DRegData(reg.prop('name'), fesaType, type)
+                        elif (reg.prop('array-dim1')) and int(reg.prop('array-dim1')) > 1:   # array
+                            flagReg = True                    
+                            flagDim1 = True                    
+                            source += fesaTemplates.genCSetUnsignedArrayRegData(reg.prop('name'), type)
+                        else:    # scalar
+                            source += fesaTemplates.genCSetScalarURegData(reg.prop('name'), type, lowerType)
+                            
+                    else:   # signed type
+                        type = type[:1].upper() + type[1:]  # only first character if not unsigned
+                        if reg.prop('array-dim2') and int(reg.prop('array-dim2')) > 1:    # 2D array
+                            flagReg = True                    
+                            flagDim2 = True                    
+                            flagDim1 = True                    
+                            source += fesaTemplates.genCSetArray2DRegData(reg.prop('name'), fesaType, type)
+                        elif (reg.prop('array-dim1')) and int(reg.prop('array-dim1')) > 1:   # array
+                            flagReg = True                    
+                            flagDim1 = True                    
+                            source += fesaTemplates.genCSetArrayRegData(reg.prop('name'), type)
+                        else:    # scalar
+                            source += fesaTemplates.genCSetScalarRegData(reg.prop('name'), type)
+             
+            source += fesaTemplates.cSend
+            source += '\n\t}'   # closing bracket for block
+
+            #Add data declatation on top if needed and append the final source
+            if flagReg == True:
+                finalSource += fesaTemplates.cRegVar
+            if flagDim1 == True:
+                finalSource += fesaTemplates.cSetArrayVar
+            if flagDim2 == True:
+                finalSource += fesaTemplates.cSetArray2DVar
+            
+            finalSource += '\n' + source    
+
+    finalSource += '\n}\n'   # closing bracket for class
+
+    # Write to file and save
+    sourceFile = sourcePath + "/" + className + ".cpp"
+    iecommon.logInfo("Generate source file: " + sourceFile, logTopics)
+    fdesc = open(sourceFile, "w")
+    fdesc.write(finalSource)
+    fdesc.close()
+
+    iecommon.logInfo('Source file for '+className+' generated successfully', logTopics)
+
+def genCppFiles(className, workspacePath, silecsDesignFilePath,logTopics={'errorlog': True}):
+    fesaCommonDirectory = iefiles.getFesa3CommonDirectory(workspacePath,className)
+    iecommon.logInfo("fesaCommonDirectory:" + fesaCommonDirectory,logTopics)
+
+    if not os.path.exists(fesaCommonDirectory ):
+        os.makedirs(fesaCommonDirectory)
+
+    silecsDesignFilePath = iefiles.getSilecsDesignFilePath(workspacePath,className)
+    fesaDesignFilePath = workspacePath + "/" + className + "/src/" + className + ".design"
+    silecsRoot = libxml2.parseFile(silecsDesignFilePath)
+    fesaRoot = libxml2.parseFile(fesaDesignFilePath)
+
+    genHSource(className, silecsRoot, fesaRoot, fesaCommonDirectory,logTopics)
+    genCppSource(className, silecsRoot, fesaRoot, fesaCommonDirectory,logTopics)
+
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode.pyc b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..72312939377bf0c7ddf22596a94ccba4eda959ba
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode.pyc differ
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_1_0/__init__.py b/silecs-codegen/src/xml/fesa/fesa_3_1_0/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_1_0/__init__.pyc b/silecs-codegen/src/xml/fesa/fesa_3_1_0/__init__.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c41cdca279065f08f99af77fa3a90e539f978239
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fesa_3_1_0/__init__.pyc differ
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_1_0/fillFESADeployUnit.py b/silecs-codegen/src/xml/fesa/fesa_3_1_0/fillFESADeployUnit.py
new file mode 100644
index 0000000000000000000000000000000000000000..b7282c5cfba8ab2a3edf1f5a2f258b8067763230
--- /dev/null
+++ b/silecs-codegen/src/xml/fesa/fesa_3_1_0/fillFESADeployUnit.py
@@ -0,0 +1,23 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import fesa.fillFesaDeployUnitBase
+import fesa.fesa_3_0_0.fillFESADeployUnit
+
+def fillDeployUnit(fesaVersion, className, workspacePath,fesaDesignXSDPath,logTopics={'errorlog': True}):
+    generator = fesa.fesa_3_0_0.fillFESADeployUnit.FESADeployUnitGenerator3_0_0() # identical with FESA 3.0.0
+    fesa.fillFesaDeployUnitBase.fillFesaDeployUnitBase(generator,fesaVersion, className, workspacePath,fesaDesignXSDPath,logTopics)
+
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_1_0/fillFESADeployUnit.pyc b/silecs-codegen/src/xml/fesa/fesa_3_1_0/fillFESADeployUnit.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..530c9b58ca9f47424022f8dd69bcdb8da4b6fb3e
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fesa_3_1_0/fillFESADeployUnit.pyc differ
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateBuildEnvironment.py b/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateBuildEnvironment.py
new file mode 100644
index 0000000000000000000000000000000000000000..b218687508da8c94669f8394caa208205405dc17
--- /dev/null
+++ b/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateBuildEnvironment.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import fesa.fesa_3_0_0.generateBuildEnvironment
+
+def genMakefileClass(projectPath, centralMakefilePath, logTopics={'errorlog': True} ):
+    return fesa.fesa_3_0_0.generateBuildEnvironment.genMakefileClass(projectPath, centralMakefilePath, logTopics )
+
+def genMakefileDU(projectPath, silecsBasePath, snap7BasePath, logTopics={'errorlog': True}):
+    return fesa.fesa_3_0_0.generateBuildEnvironment.genMakefileDU(projectPath, silecsBasePath, snap7BasePath, logTopics )
+
+def genCProjectFile(projectPath, logTopics={'errorlog': True}):
+    return fesa.fesa_3_0_0.generateBuildEnvironment.genCProjectFile(projectPath, logTopics )
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateBuildEnvironment.pyc b/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateBuildEnvironment.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c4c494f04d2525beb82cbe58647bfc3b5808f19d
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateBuildEnvironment.pyc differ
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateFesaDesign.py b/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateFesaDesign.py
new file mode 100644
index 0000000000000000000000000000000000000000..0d778a58d88209d111f54cfe7b27130696af0cfb
--- /dev/null
+++ b/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateFesaDesign.py
@@ -0,0 +1,99 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import fesa.fillFesaDesignBase
+import fesa.fesa_3_0_0.generateFesaDesign
+
+from iecommon import *
+
+def fillDesignFile(fesaVersion, className, workspacePath,fesaDesignXSDPath,logTopics={'errorlog': True}):
+    generator = FESADesignGenerator3_1_0()
+    fesa.fillFesaDesignBase.fillDesignFileBase(generator,fesaVersion, className, workspacePath,fesaDesignXSDPath,logTopics)
+
+class FESADesignGenerator3_1_0(fesa.fesa_3_0_0.generateFesaDesign.FESADesignGenerator3_0_0):
+
+    #overwrite 3_0_0 version
+    def getOrCreateAcquisitionContextItem(self,propertyNode):
+        items = propertyNode.xpathEval('acquisition-context-item')
+        if items:
+            return items[0]
+            
+        item = getOrCreateChildElement(propertyNode,'acquisition-context-item')
+        item.setProp("direction","OUT")
+
+        processIndex = getOrCreateChildElement(item,'processIndex')
+        processIndex.setProp("direction","OUT")
+        processIndex.setProp("name","processIndex")
+        processIndex = getOrCreateChildElement(processIndex,'scalar')
+        processIndex.setProp('type','int32_t')
+
+        sequenceIndex = getOrCreateChildElement(item,'sequenceIndex')
+        sequenceIndex.setProp("direction","OUT")
+        sequenceIndex.setProp("name","sequenceIndex")
+        sequenceIndex = getOrCreateChildElement(sequenceIndex,'scalar')
+        sequenceIndex.setProp('type','int32_t')
+
+        chainIndex = getOrCreateChildElement(item,'chainIndex')
+        chainIndex.setProp("direction","OUT")
+        chainIndex.setProp("name","chainIndex")
+        chainIndex = getOrCreateChildElement(chainIndex,'scalar')
+        chainIndex.setProp('type','int32_t')
+
+        eventNumber = getOrCreateChildElement(item,'eventNumber')
+        eventNumber.setProp("direction","OUT")
+        eventNumber.setProp("name","eventNumber")
+        eventNumber = getOrCreateChildElement(eventNumber,'scalar')
+        eventNumber.setProp('type','int32_t')
+
+        timingGroupID = getOrCreateChildElement(item,'timingGroupID')
+        timingGroupID.setProp("direction","OUT")
+        timingGroupID.setProp("name","timingGroupID")
+        timingGroupID = getOrCreateChildElement(timingGroupID,'scalar')
+        timingGroupID.setProp('type','int32_t')
+
+        acquisitionStamp = getOrCreateChildElement(item,'acquisitionStamp')
+        acquisitionStamp.setProp("direction","OUT")
+        acquisitionStamp.setProp("name","acquisitionStamp")
+        acquisitionStamp = getOrCreateChildElement(acquisitionStamp,'scalar')
+        acquisitionStamp.setProp('type','int64_t')
+
+        eventStamp = getOrCreateChildElement(item,'eventStamp')
+        eventStamp.setProp("direction","OUT")
+        eventStamp.setProp("name","eventStamp")
+        eventStamp = getOrCreateChildElement(eventStamp,'scalar')
+        eventStamp.setProp('type','int64_t')
+
+        processStartStamp = getOrCreateChildElement(item,'processStartStamp')
+        processStartStamp.setProp("direction","OUT")
+        processStartStamp.setProp("name","processStartStamp")
+        processStartStamp = getOrCreateChildElement(processStartStamp,'scalar')
+        processStartStamp.setProp('type','int64_t')
+
+        sequenceStartStamp = getOrCreateChildElement(item,'sequenceStartStamp')
+        sequenceStartStamp.setProp("direction","OUT")
+        sequenceStartStamp.setProp("name","sequenceStartStamp")
+        sequenceStartStamp = getOrCreateChildElement(sequenceStartStamp,'scalar')
+        sequenceStartStamp.setProp('type','int64_t')
+
+        chainStartStamp = getOrCreateChildElement(item,'chainStartStamp')
+        chainStartStamp.setProp("direction","OUT")
+        chainStartStamp.setProp("name","chainStartStamp")
+        chainStartStamp = getOrCreateChildElement(chainStartStamp,'scalar')
+        chainStartStamp.setProp('type','int64_t')
+
+        fieldRef = getOrCreateChildElement(item,'acquisition-context-field-ref')
+        fieldRef.setProp("field-name-ref","acquisitionContext")
+
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateFesaDesign.pyc b/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateFesaDesign.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7d001a3edfe56845c61b913a78345a261be6cbe5
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateFesaDesign.pyc differ
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateSourceCode.py b/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateSourceCode.py
new file mode 100644
index 0000000000000000000000000000000000000000..973222d52874243cce288f915fab47b9926e9fff
--- /dev/null
+++ b/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateSourceCode.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import fesa.fesa_3_0_0.generateSourceCode
+
+def genHSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
+    return fesa.fesa_3_0_0.generateSourceCode.genHSource(className, silecsRoot, fesaRoot, sourcePath,logTopics)
+
+def genCppSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
+    return fesa.fesa_3_0_0.generateSourceCode.genCppSource(className, silecsRoot, fesaRoot, sourcePath,logTopics)
+
+def genCppFiles(className, workspacePath, silecsDesignFilePath,logTopics={'errorlog': True}):
+    return fesa.fesa_3_0_0.generateSourceCode.genCppFiles(className, workspacePath, silecsDesignFilePath,logTopics)
diff --git a/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateSourceCode.pyc b/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateSourceCode.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..be18ac5b144058ae10d08bb59f4f9b49c2d3fbd5
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fesa_3_1_0/generateSourceCode.pyc differ
diff --git a/silecs-codegen/src/xml/fesa/fillDesignFileBase.pyc b/silecs-codegen/src/xml/fesa/fillDesignFileBase.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c9cc01785e13bc088ade97fe807d1d1772beb942
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fillDesignFileBase.pyc differ
diff --git a/silecs-codegen/src/xml/fesa/fillFesaDeployUnitBase.py b/silecs-codegen/src/xml/fesa/fillFesaDeployUnitBase.py
new file mode 100644
index 0000000000000000000000000000000000000000..670bbe2ade540ef0de44d506486137d768fbc56c
--- /dev/null
+++ b/silecs-codegen/src/xml/fesa/fillFesaDeployUnitBase.py
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import libxml2
+import os
+
+import iefiles
+import iecommon
+
+def fillFesaDeployUnitBase(generator,workspacePath,deployName, deployUnitSchemaPath, fesaVersion, logTopics):
+    iecommon.logDebug("deployUnitSchemaPath: " + deployUnitSchemaPath, {'debuglog': True})
+    iecommon.logDebug("fesaVersion: " + fesaVersion, {'debuglog': True})
+    fesaDeployFile = iefiles.getFesaDeployFilePath(workspacePath,deployName)
+    silecsDeployFile = iefiles.getSilecsDeployFilePath(workspacePath,deployName)
+    if (not os.path.isfile(fesaDeployFile)):
+        raise Exception( "FESA DeployUnit Missing: " + fesaDeployFile )
+    if (not os.path.isfile(silecsDeployFile)):
+        raise Exception( "SILECS Deploy File Missing: " + silecsDeployFile )
+    fesaDeployParsed = libxml2.parseFile(fesaDeployFile)
+    silecsDeployParsed = libxml2.parseFile(silecsDeployFile)
+    generator.fillXML(fesaDeployParsed,silecsDeployParsed,deployName, deployUnitSchemaPath, fesaVersion, logTopics)
+    iefiles.saveXMLToFile(fesaDeployFile,fesaDeployParsed)
diff --git a/silecs-codegen/src/xml/fesa/fillFesaDeployUnitBase.pyc b/silecs-codegen/src/xml/fesa/fillFesaDeployUnitBase.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..163e6d9a446a2fe47fb2b5aecb63317674631103
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fillFesaDeployUnitBase.pyc differ
diff --git a/silecs-codegen/src/xml/fesa/fillFesaDesignBase.py b/silecs-codegen/src/xml/fesa/fillFesaDesignBase.py
new file mode 100644
index 0000000000000000000000000000000000000000..a7362e2eb36bcb0c41e9d2f2d4085a512859f5b0
--- /dev/null
+++ b/silecs-codegen/src/xml/fesa/fillFesaDesignBase.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import iecommon
+import iefiles
+import libxml2
+
+def fillDesignFileBase(generator, fesaVersion, className, workspacePath,fesaDesignXSDPath,logTopics={'errorlog': True}): 
+    iecommon.logInfo("Filling information and ownership-attribute FESA design for FESA version %s " %fesaVersion, logTopics)
+
+    silecsDesignFilePath = iefiles.getSilecsDesignFilePath(workspacePath,className)
+    fesaDesignFilePath = workspacePath + "/" + className + "/src/" + className + ".design"
+    iecommon.logInfo("silecsDesignFilePath:" + silecsDesignFilePath, logTopics)
+    iecommon.logInfo("fesaDesignFilePath:" + fesaDesignFilePath, logTopics)
+    
+    silecsDesignParsed = libxml2.parseFile(silecsDesignFilePath)
+    fesaDesignParsed = libxml2.parseFile(fesaDesignFilePath)
+
+    fesaDesignParsed = generator.fillXML(fesaVersion, className, fesaDesignParsed, silecsDesignParsed)
+    
+    iecommon.logInfo("Filling design document: " + fesaDesignFilePath, logTopics)
+    iefiles.saveXMLToFile(fesaDesignFilePath,fesaDesignParsed)
+
+    #fesaDesignFile.write(sys.stdout)
+    iecommon.logInfo('FESA design document for class '+ className +' filled successfully', logTopics)
diff --git a/silecs-codegen/src/xml/fesa/fillFesaDesignBase.pyc b/silecs-codegen/src/xml/fesa/fillFesaDesignBase.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b1cea04fffaf5bc477d302baeb32f9ad40347763
Binary files /dev/null and b/silecs-codegen/src/xml/fesa/fillFesaDesignBase.pyc differ
diff --git a/silecs-codegen/src/xml/genduwrapper$py.class b/silecs-codegen/src/xml/genduwrapper$py.class
new file mode 100644
index 0000000000000000000000000000000000000000..3688309a9ae1caa7040815610c39c07f7c6ab4dc
Binary files /dev/null and b/silecs-codegen/src/xml/genduwrapper$py.class differ
diff --git a/silecs-codegen/src/xml/genduwrapper.py b/silecs-codegen/src/xml/genduwrapper.py
new file mode 100644
index 0000000000000000000000000000000000000000..c42a32a7e054fd75903f80c4a7985849831f80e7
--- /dev/null
+++ b/silecs-codegen/src/xml/genduwrapper.py
@@ -0,0 +1,144 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import os
+import sys
+import libxml2
+from collections import namedtuple
+
+import iecommon
+import iefiles
+import genduwrappertemplate
+
+from iecommon import *
+
+#=========================================================================
+# Sub-functions
+#=========================================================================
+    
+def extractBlockList(designDOM):
+    blockList = []
+    for blockNode in designDOM.xpathEval("//Block"):
+        blockList.append([blockNode.prop("name"), blockNode.prop("mode")])
+    return blockList
+
+def getRegisterList(designFile,blockName):
+    '''Return the list of register included in a given block.
+    for each register a the following tuple is returned: [name,format,dim1,dim2]
+    '''
+    registerList = []
+    dom = libxml2.parseFile(designFile)
+    blockNodeList = dom.xpathEval("//Block")
+    for blockNode in blockNodeList:
+        if blockNode.prop("name")==blockName:
+            break #after the loop blockNode will point to the good node
+        
+    registerNodeList=blockNode.xpathEval("Register")
+    for registerNode in registerNodeList:
+        name = registerNode.prop("name")
+        format = registerNode.prop("format")
+        dim1 = 1
+        dim2 = 1
+        try:
+            dim1 = int(registerNode.prop("array-dim1"))
+        except:
+            pass #use 1 as default dimention 
+        try:
+            dim2 = int(registerNode.prop("array-dim2"))
+        except:
+            pass #use 1 as default dimention
+        registerList.append([name,format,dim1,dim2])
+    return registerList
+            
+def genClassHeader(workspacePath, deployName, classNode, funcGetSilecsDesignFilePath, funcGetDuDesignWrapperFile, logTopics):
+    designName = classNode.prop("silecs-design-name")
+    designVersion = classNode.prop("silecs-design-version") 
+    designFile = funcGetSilecsDesignFilePath(workspacePath, designName)
+    designDOM = libxml2.parseFile(designFile)
+    if(not os.path.isfile(designFile)):
+        raise Exception("File not found: " + designFile)
+    blockList = extractBlockList(designDOM)
+    classDeclarations = ""
+    
+    #construct Block class
+    for [blockName,blockMode] in blockList:
+        registerList = getRegisterList(designFile,blockName)
+        registerInitializerList = genduwrappertemplate.getBlockInitializerList(registerList)
+        registerGetterSetter = genduwrappertemplate.getRegisterGetterSetter(blockName,blockMode,registerList)
+        registersDimentionsDeclaration = genduwrappertemplate.getRegistersDimetionsDeclaration(registerList)
+        registersDeclaration = genduwrappertemplate.getRegistersDeclaration(registerList)
+        classDeclarations += genduwrappertemplate.getBlockClass(blockName,registerInitializerList,registerGetterSetter,registersDimentionsDeclaration,registersDeclaration)
+    
+    blockGetters = ""
+    sendRecvBlocks = genduwrappertemplate.getDeviceSendRecvBlocks(blockList)
+    for [blockName,mode] in blockList:
+        registerList = getRegisterList(designFile,blockName)
+        blockGetters += genduwrappertemplate.getDeviceBlockGetterSetter(blockName, mode, registerList)
+
+    classDeclarations += genduwrappertemplate.getDeviceClass(blockGetters,sendRecvBlocks)
+
+    sendRecvBlocks = genduwrappertemplate.getControllerSendRecvBlocks(blockList)
+    classDeclarations = genduwrappertemplate.getDesignClass(designName, designVersion)
+    designWrapper = genduwrappertemplate.designFileTemplate.substitute({'designNameCapitalized' :  iecommon.capitalizeString(designName),'designNameUpper' :  designName.upper(),'classDeclarations' : classDeclarations})
+
+    designWrapperFile = funcGetDuDesignWrapperFile(workspacePath, deployName, designName)
+    fdesc = open(designWrapperFile, "w")
+    fdesc.write(designWrapper)
+    iecommon.logInfo('Generated Wrapper for Design %s'%(designName), logTopics)
+    fdesc.close()
+
+def genDuWrapperBase(deployFile,funcGetDuWrapperFile,workspacePath,funcGetSilecsDesignFilePath, funcGetDuDesignWrapperFile,deployName,deployVersion,logTopics={'errorlog': True}):
+    deployDOM = libxml2.parseFile(deployFile)
+    
+    for controllerNode in deployDOM.xpathEval("/SILECS-Deploy/Controller"):
+        controllerName = controllerNode.prop("host-name")
+        controllerDomain = "" # GSI-Hack - No Support for domains at GSI
+        deployCustomInclude = constructorBody = destructorBody = designGetters = designMemberDeclarations = ""
+        for classNode in controllerNode.xpathEval("SilecsDesign"):
+            designName = classNode.prop("silecs-design-name")
+            designNameCapitalized = iecommon.capitalizeString(designName)
+            genClassHeader(workspacePath, deployName, classNode, funcGetSilecsDesignFilePath, funcGetDuDesignWrapperFile, logTopics)
+            deployCustomInclude += genduwrappertemplate.deployIncludeTemplate.substitute({'designNameCapitalized' : designNameCapitalized})
+            constructorBody += genduwrappertemplate.designAllocation.substitute({'designName' : designName,'designNameCapitalized' : designNameCapitalized})
+            destructorBody += genduwrappertemplate.designDeallocation.substitute({'designName' : designName})
+            designGetters += genduwrappertemplate.designGetterTemplate.substitute({'designName' : designName,'designNameCapitalized' : designNameCapitalized})
+            designMemberDeclarations += genduwrappertemplate.deployUnitMembersDeclaration.substitute({'designName' : designName,'designNameCapitalized' : designNameCapitalized})
+
+        controllerCtor = deviceGetter = ''
+        for deviceNode in controllerNode.xpathEval("*/Device"):
+            deviceName = deviceNode.prop("device-name")
+            controllerCtor +=  genduwrappertemplate.controllerDeviceInit.substitute({'deviceName' : deviceName})
+            deviceGetter += genduwrappertemplate.deviceGetterTemplate.substitute({'deviceName' : deviceName, 'deviceNameCapitalizedNoUndercore' : iecommon.capitalizeString(deviceName.replace("-","_"))})
+        controllerClass = genduwrappertemplate.getControllerClass(controllerCtor,deviceGetter,controllerName, controllerDomain)
+        code = genduwrappertemplate.generateControllerFile(deployName,deployVersion,deployCustomInclude,constructorBody,destructorBody,designGetters,designMemberDeclarations,controllerClass)
+    
+        fdesc = open(funcGetDuWrapperFile(workspacePath, deployName, controllerNode.prop("host-name")) , "w")
+        fdesc.write(code)
+        iecommon.logInfo('Generated Wrapper for Controller %s'%(controllerNode.prop("host-name")), logTopics)
+        fdesc.close()
+
+def genDuWrapper(workspacePath,deployName,deployVersion,logTopics={'errorlog': True}):
+    deployFile = iefiles.getSilecsDeployFilePath(workspacePath, deployName)
+    funcGetDuWrapperFile = iefiles.getDuWrapperFile
+    
+    # Create output directory if necessary
+    sourcePath = iefiles.getDuWrapperSourceDirectory(workspacePath, deployName)
+    if not os.path.exists(sourcePath):
+        os.makedirs(sourcePath)
+        
+    genDuWrapperBase(deployFile,funcGetDuWrapperFile,workspacePath,iefiles.getSilecsDesignFilePath, iefiles.getDuDesignWrapperFile,deployName,deployVersion,logTopics)
+    
+    
diff --git a/silecs-codegen/src/xml/genduwrapper.pyc b/silecs-codegen/src/xml/genduwrapper.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..83bc1fef2f702755849f066f3d1011abce281399
Binary files /dev/null and b/silecs-codegen/src/xml/genduwrapper.pyc differ
diff --git a/silecs-codegen/src/xml/genduwrappertemplate$py.class b/silecs-codegen/src/xml/genduwrappertemplate$py.class
new file mode 100644
index 0000000000000000000000000000000000000000..f1f4e6e13353ad97f875afa4d3532672694f86e5
Binary files /dev/null and b/silecs-codegen/src/xml/genduwrappertemplate$py.class differ
diff --git a/silecs-codegen/src/xml/genduwrappertemplate.py b/silecs-codegen/src/xml/genduwrappertemplate.py
new file mode 100644
index 0000000000000000000000000000000000000000..8f5814902a33717a3e4fa572ce11afe9c13bfb57
--- /dev/null
+++ b/silecs-codegen/src/xml/genduwrappertemplate.py
@@ -0,0 +1,740 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import string
+import iecommon
+
+#=================================================================
+# Deploy Unit Class
+#=================================================================
+deployUnitFileTemplate = string.Template("""/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ${deployNameUpper}_H_
+#define ${deployNameUpper}_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+${deployCustomInclude}
+namespace ${deployNameCapitalized}
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \\brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \\brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+${designGetters}\
+private:
+
+${designMemberDeclarations}\
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("${deployNameCapitalized}", "${deployVersion}", logTopics, globalConfig)
+    {
+${constructorBody}\
+    }
+    
+    ~DeployUnit()
+    {
+${destructorBody}\
+    }
+};
+
+${controllerClass}
+
+} /* namespace ${deployNameCapitalized} */
+
+#endif /* ${deployNameUpper}_H_ */
+""")
+
+deployIncludeTemplate = string.Template("""\
+#include "${designNameCapitalized}.h"
+""")
+
+designGetterTemplate = string.Template("""\
+    /*!
+     * \\brief Return pointer to the deployed design ${designName}.
+     */
+    ${designNameCapitalized}::Design* get${designNameCapitalized}()
+    {
+        return _${designName};
+    }
+
+""")
+
+designAllocation = string.Template("""\
+        // Construct Design ${designNameCapitalized}
+        _${designName} = new ${designNameCapitalized}::Design((SilecsWrapper::DeployUnit*) this);
+        
+""")
+
+designDeallocation = string.Template("""\
+        delete _${designName};
+""")
+
+deployUnitMembersDeclaration = string.Template("""\
+    ${designNameCapitalized}::Design* _${designName};
+""")
+        
+def generateControllerFile(deployName, deployVersion, deployCustomInclude, constructorBody, destructorBody, designGetters, designMemberDeclarations, controllerClass):
+    deployMapping = {'deployVersion' : deployVersion,
+                     'deployNameCapitalized' :  iecommon.capitalizeString(deployName),
+                     'deployNameUpper' :  deployName.upper(),
+                     'deployCustomInclude' : deployCustomInclude,
+                     'constructorBody' : constructorBody,
+                     'destructorBody' : destructorBody,
+                     'designGetters' : designGetters,
+                     'designMemberDeclarations' : designMemberDeclarations,
+                     'controllerClass' : controllerClass
+                   }
+    return deployUnitFileTemplate.substitute(deployMapping)
+
+#=================================================================
+# Design Class
+#=================================================================
+
+designFileTemplate = string.Template("""/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ${designNameUpper}_H_
+#define ${designNameUpper}_H_
+
+#include <silecs-communication/wrapper/Block.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+#include <silecs-communication/wrapper/Device.h>
+
+namespace ${designNameCapitalized}
+{
+
+${classDeclarations}
+} /* namespace ${designNameCapitalized} */
+
+#endif /* ${designNameUpper}_H_ */
+""")
+
+designClassTemplate = string.Template("""
+class Design : public SilecsWrapper::Design
+{
+public:
+
+    Design(SilecsWrapper::DeployUnit *deployUnit) :
+                    SilecsWrapper::Design("${designNameCapitalized}", "${designVersion}", deployUnit)
+    {
+    }
+
+    ~Design()
+    {
+    }
+};
+""")
+
+def getDesignClass(designName,designVersion):
+    text = ""
+    designClassmap = {'designName' : designName,
+                      'designNameCapitalized' : iecommon.capitalizeString(designName),
+                      'designVersion' : designVersion}
+    return designClassTemplate.substitute(designClassmap)
+
+designControllerInit = string.Template("""
+            _controllerMap.insert(
+                std::pair<std::string, Controller*>("${controllerName}",
+                        new Controller("${controllerName}", "${controllerDomain}", this)));
+""")
+
+designReceiveTemplate = string.Template("""\
+    /*!
+     * \\brief Receive ${blockName} blocks from all connected controllers.
+     */
+    void receive${blockNameCapitalized}AllControllers()
+    {
+        _silecsCluster->recv("${blockName}");
+    }
+    
+""")
+
+designSendTemplate = string.Template("""\
+    /*!
+     * \\brief Send ${blockName} blocks to all connected controllers.
+     */
+    void send${blockNameCapitalized}AllControllers()
+    {
+        _silecsCluster->send("${blockName}");
+    }
+    
+""")
+
+def getDesignSendRecvBlocks(blockList):
+    text = ""
+    for [blockName,mode] in blockList:
+        map = {'blockName' : blockName,
+               'blockNameCapitalized' : iecommon.capitalizeString(blockName)}
+        if mode == 'READ-ONLY' or mode == 'READ-WRITE':
+            text += designReceiveTemplate.substitute(map)
+        if mode == 'WRITE-ONLY' or mode == 'READ-WRITE':
+            text += designSendTemplate.substitute(map)
+    return text
+
+#=================================================================
+# Controller Class
+#=================================================================
+
+controllerClassTemplate = string.Template("""
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("${controllerName}", "${controllerDomain}", design, parameterFile)
+    {
+${constructorBody}\
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \\brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+${deviceGetter}\
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+""")
+
+def getControllerClass(constructorBody,deviceGetter,controllerName,controllerDomain):
+    text = ""
+    designClassmap = {'constructorBody' : constructorBody,
+                      'deviceGetter' : deviceGetter,
+                        'controllerName' : controllerName,
+                        'controllerDomain' : controllerDomain}
+    return controllerClassTemplate.substitute(designClassmap)
+
+controllerDeviceInit = string.Template("""\
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("${deviceName}", new SilecsWrapper::Device("${deviceName}", this)));
+""")
+
+deviceGetterTemplate = string.Template("""\
+    /*!
+     * \\brief Get pointer to device ${deviceName}.
+     */
+    SilecsWrapper::Device* get${deviceNameCapitalizedNoUndercore}()
+    {
+        return _deviceMap["${deviceName}"];
+    }
+    
+""")
+
+controllerReceiveTemplate = string.Template("""\
+    /*!
+     * \\brief Receive ${blockName} blocks from all devices of current controller.
+     */
+    void receive${blockNameCapitalized}AllDevices()
+    {
+        _silecsPLC->recv("${blockName}");
+    }
+    
+""")
+
+controllerSendTemplate = string.Template("""\
+    /*!
+     * \\brief Send ${blockName} blocks to all devices of current controller.
+     */
+    void send${blockNameCapitalized}AllDevices()
+    {
+        _silecsPLC->send("${blockName}");
+    }
+    
+""")
+
+def getControllerSendRecvBlocks(blockList):
+    text = ""
+    for [blockName,mode] in blockList:
+        map = {'blockName' : blockName,
+               'blockNameCapitalized' : iecommon.capitalizeString(blockName)}
+        if mode == 'READ-ONLY' or mode == 'READ-WRITE':
+            text += controllerReceiveTemplate.substitute(map)
+        if mode == 'WRITE-ONLY' or mode == 'READ-WRITE':
+            text += controllerSendTemplate.substitute(map)
+    return text
+
+#=================================================================
+# Device Class
+#=================================================================
+
+deviceClassTemplate = string.Template("""\
+class Device : public SilecsWrapper::Device
+{
+public:
+    Device(const std::string& label, SilecsWrapper::Controller *controller) :
+                    SilecsWrapper::Device(label, controller)
+    {
+    }
+
+    ~Device()
+    {
+    }
+    
+${blockGetter}
+${sendRecvBlocks}
+};
+""")
+
+def getDeviceClass(blockGetter,sendRecvBlocks):
+    text = ""
+    designClassmap = {'blockGetter' : blockGetter,
+                      'sendRecvBlocks' : sendRecvBlocks}
+    return deviceClassTemplate.substitute(designClassmap)
+
+
+blockGetterTemplate = string.Template("""\
+    /*!
+     * \\brief Get ${blockName} block. 
+     * \param block ${blockNameCapitalized} reference where to store returned value.
+     */
+    void get${blockNameCapitalized}(${blockNameCapitalized} &block)
+    {
+${blockInitialization}\
+    }
+    
+""")
+
+blockSetterTemplate = string.Template("""\
+    /*!
+     * \\brief Set ${blockName} block. 
+     * \param block ${blockNameCapitalized} reference from where value are copied.
+     */
+    void set${blockNameCapitalized}(${blockNameCapitalized} &block)
+    {
+${blockInitialization}\
+    }
+    
+""")
+
+matrixRegisterAssignementGetter = string.Template("""\
+        // Copy register ${regName}
+        ${cType} *__${regName} = new ${cType}[block.${regName}Dim1 * block.${regName}Dim2];
+        getSilecsDevice()->getRegister("${regName}")->getVal${silecsTypeCapitalized}Array2D(__${regName}, block.${regName}Dim1, block.${regName}Dim2);
+        block.set${regNameCapitalized}(__${regName});
+        delete[] __${regName};
+""")
+arrayRegisterAssignementGetter = string.Template("""\
+        // Copy register ${regName}
+        ${cType} *__${regName} = new ${cType}[block.${regName}Dim1];
+        getSilecsDevice()->getRegister("${regName}")->getVal${silecsTypeCapitalized}Array(__${regName}, block.${regName}Dim1);
+        block.set${regNameCapitalized}(__${regName});
+        delete[] __${regName};
+""")
+scalarRegisterAssignementGetter = string.Template("""\
+        // Copy register ${regName}
+        block.set${regNameCapitalized}(getSilecsDevice()->getRegister("${regName}")->getVal${silecsTypeCapitalized}());
+""")
+
+matrixRegisterAssignementSetter = string.Template("""\
+        // Copy register ${regName}
+        ${cType} *__${regName} = new ${cType}[block.${regName}Dim1 * block.${regName}Dim2];
+        block.get${regNameCapitalized}(__${regName});
+        getSilecsDevice()->getRegister("${regName}")->setVal${silecsTypeCapitalized}Array2D(__${regName}, block.${regName}Dim1, block.${regName}Dim2);
+        delete[] __${regName};
+""")
+arrayRegisterAssignementSetter = string.Template("""\
+        // Copy register ${regName}
+        ${cType} *__${regName} = new ${cType}[block.${regName}Dim1];
+        block.get${regNameCapitalized}(__${regName});
+        getSilecsDevice()->getRegister("${regName}")->setVal${silecsTypeCapitalized}Array(__${regName}, block.${regName}Dim1);
+        delete[] __${regName};
+""")
+scalarRegisterAssignementSetter = string.Template("""\
+        // Copy register ${regName}
+        getSilecsDevice()->getRegister("${regName}")->setVal${silecsTypeCapitalized}(block.get${regNameCapitalized}());
+""")
+
+def getDeviceBlockGetterSetter(blockName, blockMode, registerList):
+    text = ""
+    if blockMode == 'READ-ONLY' or blockMode == 'READ-WRITE':
+        blockInitialization = ""
+        for [name,format,dim1,dim2] in registerList:
+            silecsType = iecommon.getSilecsDataType(format)
+            if silecsType[0] == 'u':
+                silecsTypeCapitalized = silecsType[:2].upper() + silecsType[2:]
+            else:
+                silecsTypeCapitalized = iecommon.capitalizeString(silecsType)
+            
+            map = {'regName' : name,
+                   'regNameCapitalized' : iecommon.capitalizeString(name),
+                   'silecsTypeCapitalized' : silecsTypeCapitalized,
+                   'cType' : iecommon.getCDataType(format)}
+            if dim2 > 1:
+                #matrix
+                blockInitialization += matrixRegisterAssignementGetter.substitute(map)
+            elif dim1 > 1:
+                #array
+                blockInitialization += arrayRegisterAssignementGetter.substitute(map)
+            else:
+                #scalar
+                blockInitialization += scalarRegisterAssignementGetter.substitute(map)
+        
+        blockMap = {'blockName' : blockName, 
+                    'blockInitialization' : blockInitialization,
+                    'blockNameCapitalized' : iecommon.capitalizeString(blockName)}
+        text +=  blockGetterTemplate.substitute(blockMap)
+    if blockMode == 'WRITE-ONLY' or blockMode == 'READ-WRITE':
+        blockInitialization = ""
+        for [name,format,dim1,dim2] in registerList:
+            silecsType = iecommon.getSilecsDataType(format)
+            if silecsType[0] == 'u':
+                silecsTypeCapitalized = silecsType[:2].upper() + silecsType[2:]
+            else:
+                silecsTypeCapitalized = iecommon.capitalizeString(silecsType)
+            
+            map = {'regName' : name,
+                   'regNameCapitalized' : iecommon.capitalizeString(name),
+                   'silecsTypeCapitalized' : silecsTypeCapitalized,
+                   'cType' : iecommon.getCDataType(format)}
+            if dim2 > 1:
+                #matrix
+                blockInitialization += matrixRegisterAssignementSetter.substitute(map)
+            elif dim1 > 1:
+                #array
+                blockInitialization += arrayRegisterAssignementSetter.substitute(map)
+            else:
+                #scalar
+                blockInitialization += scalarRegisterAssignementSetter.substitute(map)
+        
+        blockMap = {'blockName' : blockName, 
+                    'blockInitialization' : blockInitialization,
+                    'blockNameCapitalized' : iecommon.capitalizeString(blockName)}
+        text +=  blockSetterTemplate.substitute(blockMap)
+    return text
+
+deviceReceiveTemplate = string.Template("""\
+    /*!
+     * \\brief Receive ${blockName} block for current device.
+     */
+    void receive${blockNameCapitalized}()
+    {
+        _silecsDevice->recv("${blockName}");
+    }
+    
+""")
+
+deviceSendTemplate = string.Template("""\
+    /*!
+     * \\brief Send ${blockName} blocks to current device.
+     */
+    void send${blockNameCapitalized}()
+    {
+        _silecsDevice->send("${blockName}");
+    }
+    
+""")
+
+def getDeviceSendRecvBlocks(blockList):
+    text = ""
+    for [blockName,mode] in blockList:
+        map = {'blockName' : blockName,
+               'blockNameCapitalized' : iecommon.capitalizeString(blockName)}
+        if mode == 'READ-ONLY' or mode == 'READ-WRITE':
+            text += deviceReceiveTemplate.substitute(map)
+        if mode == 'WRITE-ONLY' or mode == 'READ-WRITE':
+            text += deviceSendTemplate.substitute(map)
+    return text
+
+#=================================================================
+# Block Class
+#=================================================================
+
+blockClassTemplate = string.Template("""
+class ${blockNameCapitalized} : public SilecsWrapper::Block
+{
+public:
+    /*!
+     * \\brief ${blockName} constructor. It creates an empty block.
+     */
+    ${blockNameCapitalized}() :
+                    SilecsWrapper::Block("${blockName}")${registerInitializerList}
+    {
+    }
+
+    ~${blockNameCapitalized}()
+    {
+    }
+${registerGetterSetter}\
+${registersDimentionsDeclaration}\
+private:
+${registersDeclaration}
+};
+""")
+
+def getBlockClass(blockName,registerInitializerList,registerGetterSetter,registersDimentionsDeclaration,registersDeclaration):
+    map = {'blockName' : blockName,
+           'registerInitializerList' : registerInitializerList,
+           'blockNameCapitalized' : iecommon.capitalizeString(blockName),
+           'registerGetterSetter' : registerGetterSetter,
+           'registersDimentionsDeclaration' : registersDimentionsDeclaration,
+           'registersDeclaration' : registersDeclaration}
+    return blockClassTemplate.substitute(map)
+
+registerInitializerListTemplate = string.Template("""\
+,
+                    ${registerName}(0)""")
+
+def getBlockInitializerList(regList):
+    text = ""
+    for [name,format,dim1,dim2] in regList:
+        if format != 'string' and dim1 == 1 and dim2 == 1:
+            text += registerInitializerListTemplate.substitute({'registerName' : name})
+    return text
+    
+
+matrixRegisterGetterTemplate = string.Template("""
+    /*!
+     * \\brief Get 2D array ${registerName} register.
+     * \param value buffer where the value will be stored.
+     */
+    void get${registerNameCapitalized}(${cType}* value) const
+    {
+        memcpy(value, static_cast<const void *>(${registerName}), ${registerName}Dim1 * ${registerName}Dim2);
+    }
+""")
+
+matrixRegisterSetterTemplate = string.Template("""
+    /*!
+     * \\brief Get array ${registerName} register.
+     * \param value buffer where the value will be stored.
+     */
+    void set${registerNameCapitalized}(${cType}* value) const
+    {
+        memcpy((void *) ${registerName}, value, ${registerName}Dim1 * ${registerName}Dim2);
+    }
+""")
+
+stringArrayRegisterGetterTemplate = string.Template("""
+    /*!
+     * \\brief Get std::string ${registerName} register.
+     * \param value buffer where the value will be stored.
+     */
+    void get${registerNameCapitalized}(std::string* value) const
+    {
+        for (std::size_t i = 0; i <  ${registerName}Dim1; i++)
+        {
+            value[i] =  ${registerName}[i];
+        }
+    }
+""")
+
+stringArrayRegisterSetterTemplate = string.Template("""
+    /*!
+     * \\brief Set std::string ${registerName} register.
+     * \param value to be set.
+     */
+    void set${registerNameCapitalized}(const std::string* value)
+    {
+        for (std::size_t i = 0; i < ${registerName}Dim1; i++)
+        {
+            ${registerName}[i] = value[i];
+        }
+    }
+""")
+
+arrayRegisterGetterTemplate = string.Template("""
+    /*!
+     * \\brief Set array ${registerName} register.
+     * \param value to be set.
+     */
+    void get${registerNameCapitalized}(${cType}* value) const
+    {
+        memcpy(value, (void *) ${registerName}, ${registerName}Dim1);
+    }
+""")
+
+arrayRegisterSetterTemplate = string.Template("""
+    /*!
+     * \\brief Set 2D array ${registerName} register.
+     * \param value to be set.
+     */
+    void set${registerNameCapitalized}(${cType}* value) const
+    {
+        memcpy((void *) ${registerName}, value, ${registerName}Dim1);
+    }
+""")
+
+scalarRegisterGetterTemplate = string.Template("""
+    /*!
+     * \\brief Get ${registerName} register.
+     * \\return value.
+     */
+    ${cType} get${registerNameCapitalized}() const
+    {
+        return ${registerName};
+    }
+""")
+
+scalarRegisterSetterTemplate = string.Template("""
+    /*!
+     * \\brief Set ${registerName} register.
+     * \param value to be set.
+     */
+    void set${registerNameCapitalized}(${cType} value)
+    {
+        ${registerName} = value;
+    }
+""")
+
+def getRegisterGetterSetter(blockName,blockMode,regList):
+    text = ""
+    for [name,format,dim1,dim2] in regList:
+        cType = iecommon.getCDataType(format)
+        map = {'registerName' : name,
+               'registerNameCapitalized' : iecommon.capitalizeString(name),
+               'cType' : iecommon.getCDataType(format)}
+        
+        if dim2 > 1:
+            text += matrixRegisterGetterTemplate.substitute(map)
+            text += matrixRegisterSetterTemplate.substitute(map)
+        elif dim1 > 1:
+            if format == 'string':
+                text += stringArrayRegisterGetterTemplate.substitute(map)
+                text += stringArrayRegisterSetterTemplate.substitute(map)
+            else:
+                text += arrayRegisterGetterTemplate.substitute(map)
+                text += arrayRegisterSetterTemplate.substitute(map)
+        else:
+            if format == 'string':
+                map['cType'] = "const std::string&"
+            text += scalarRegisterGetterTemplate.substitute(map)
+            text += scalarRegisterSetterTemplate.substitute(map)
+    return text
+
+registersDimetionsDeclarationTemplate = string.Template("""\
+    static const std::size_t ${registerName}Dim${index} = ${dimention};
+""")
+
+def getRegistersDimetionsDeclaration(regList):
+    text = ""
+    for [name,format,dim1,dim2] in regList:
+        map = {'registerName' : name}
+        if dim2 > 1:
+            map['index'] = "2"
+            map['dimention'] = dim2
+            text += registersDimetionsDeclarationTemplate.substitute(map)
+            map['index'] = "1"
+            map['dimention'] = dim1
+            text += registersDimetionsDeclarationTemplate.substitute(map)
+        elif dim1 > 1:
+            map['index'] = "1"
+            map['dimention'] = dim1
+            text += registersDimetionsDeclarationTemplate.substitute(map)
+    return text
+
+matrixRegistersDeclarationTemplate = string.Template("""\
+    ${cType} ${registerName}[${registerName}Dim1][${registerName}Dim2];
+""")
+
+arrayRegistersDeclarationTemplate = string.Template("""\
+    ${cType} ${registerName}[${registerName}Dim1];
+""")
+
+scalarRegistersDeclarationTemplate = string.Template("""\
+    ${cType} ${registerName};
+""")
+
+def getRegistersDeclaration(regList):
+    text = ""
+    for [name,format,dim1,dim2] in regList:
+        map = {'registerName' : name,
+               'cType' : iecommon.getCDataType(format)}
+        if dim2 > 1:
+            text += matrixRegistersDeclarationTemplate.substitute(map)
+        elif dim1 > 1:
+            text += arrayRegistersDeclarationTemplate.substitute(map)
+        else:
+            text += scalarRegistersDeclarationTemplate.substitute(map)
+    return text
diff --git a/silecs-codegen/src/xml/genduwrappertemplate.pyc b/silecs-codegen/src/xml/genduwrappertemplate.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a5d8778482c22d55002484d44f47696c68ac4c56
Binary files /dev/null and b/silecs-codegen/src/xml/genduwrappertemplate.pyc differ
diff --git a/silecs-codegen/src/xml/genparam$py.class b/silecs-codegen/src/xml/genparam$py.class
new file mode 100644
index 0000000000000000000000000000000000000000..192483cd4de2b7e09739209efbad6a48b30f5478
Binary files /dev/null and b/silecs-codegen/src/xml/genparam$py.class differ
diff --git a/silecs-codegen/src/xml/genparam.py b/silecs-codegen/src/xml/genparam.py
new file mode 100644
index 0000000000000000000000000000000000000000..c7cf9068e1618159430d6b95e47bf2a3a260a0b6
--- /dev/null
+++ b/silecs-codegen/src/xml/genparam.py
@@ -0,0 +1,980 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import os
+import sys
+import time
+import zlib
+import glob
+import datetime
+import shutil
+import libxml2
+
+import iecommon
+import xmltemplate
+import iefiles
+
+from iecommon import *
+
+#-------------------------------------------------------------------------
+# Global definitions
+#-------------------------------------------------------------------------
+msize                   = 0 # my regMemSize in the former PERL script
+blkMemSize              = 0 # my $blockMemSize = 0; in the former PERL script
+blkAddr                 = 0 # my $blockAddress = 0; in the former PERL script
+deviceMemSize           = 0 # global memory-size of one class instance (sum of block-memory size)
+nbBlock                 = 0 # number of block of the class
+plcSize                 = 0
+plcLast                 = 0
+classMem                = 0
+instAddr                = 0 
+
+blockCounter            = 0 # used for NI block address generation
+regCounter              = 0 # used for NI register address generation
+
+
+#=========================================================================
+# Sub-function
+#=========================================================================
+
+#-------------------------------------------------------------------------
+# Decode HTML mapping < , > , " , ' in the appropiate coding
+def decode(html):
+    html = html.replace("<","&lt;")
+    html = html.replace(">","&gt;")
+    html = html.replace('"',"&quot;")
+    html = html.replace("'","&#39;")
+    return html
+
+#-------------------------------------------------------------------------
+# Trimming: remove new-line, tabulation and spaces of the string
+# Used to compute CRC32 on significant data only
+def trim (str):
+    str = str.replace(' ', '')
+    str = str.replace('\s', '')
+    str = str.replace('\t', '')
+    str = str.replace('\r', '')
+    str = str.replace('\n', '')
+    return str
+
+#-------------------------------------------------------------------------
+# Return the highest bit-alignment of the given address
+def whichDataAlignment(value):
+    if (value % 2 != 0): return 8
+    if (value % 4 != 0): return 16
+    if (value % 8 != 0): return 32
+    return 64
+
+
+#-------------------------------------------------------------------------
+# DATA ALIGNMENT depends on different conditions: PLC brand, model and also
+# depends on type of data structure (scalar or array)
+# These methods are used to compute the correct address of each register respecting
+# this conditions.
+# Attention!! $addr is the relative address of the register within the block including
+# this alignment while $msize is still the useful memory of the data which does not include
+# memory spaces because of alignment shifts of the following variables if any.
+# This remark is not true for the block mem-size which naturally includes the alignment spaces.
+#
+
+# Adjust the register address relying on the SCHNEIDER Premium/Quantum alignment constraints
+# Unity Premium/Quantum is 16bits processor and base-address is interpreted as 16bit address
+# Byte elements of array (including STRING) use 8bit alignment.
+def alignPremiumRegAddress(addr, format, size, dim, dim2, strLen):
+    global msize
+
+    # internal string/unicode to integer cast
+    size = int(size)
+    addr = int(addr)
+    dim = int(dim)
+    dim2 = int(dim2)
+    strLen = int(strLen)
+    
+    algnt  = 16
+    while(whichDataAlignment(addr) < algnt):
+        addr+=1
+    msize = dim * dim2 * strLen * size    #compute memory data size
+    if (format in ['int8', 'char']):   #8bit signed type use word alignment (16bit)
+        msize = msize * 2            # while string and uint8-array use 8bit alignment
+    return addr
+    
+# Adjust the register address relying on the SCHNEIDER M340 alignment constraints
+# Unity M340 is 32bits processor but base-address is interpreted as 16bit address (required even address in the mapping)
+# 32bits alignment except for 8/16bits (16bits alignment)
+# Byte elements of array (including STRING) use 8bit alignment.
+def alignM340RegAddress(addr, format, size, dim, dim2, strLen):
+    global msize
+    
+    # internal string/unicode to integer cast
+    size = int(size)
+    addr = int(addr)
+    dim = int(dim)
+    dim2 = int(dim2)
+    strLen = int(strLen)
+    
+    algnt  = 16
+    if (size > 2):
+        algnt = 32
+    while(whichDataAlignment(addr) < algnt):
+        addr+=1
+    msize = dim * dim2 * strLen * size    #compute memory data size
+    if (format in ['int8', 'char']):   #8bit signed type use word alignment (16bit)
+        msize = msize * 2            # while string and uint8-array use 8bit alignment
+    return addr
+    
+# Adjust the register address relying on the DIGI-Rabbit RCMx alignment constraints
+# Use  16bits processor and base-address is interpreted as 16bit address
+def alignDIGIRegAddress(addr, format, size, dim, dim2, strLen):
+    global msize
+
+    # internal string/unicode to integer cast
+    size = int(size)
+    addr = int(addr)
+    dim = int(dim)
+    dim2 = int(dim2)
+    strLen = int(strLen)
+    
+    algnt  = 16
+    while(whichDataAlignment(addr) < algnt):
+        addr+=1
+    msize = dim * dim2 * strLen * size    #compute memory data size
+    if (format != 'string'):                       
+        if (size == 1):                   #but it's a 8bit type
+            msize = msize * 2        #so, it's a word alignment (only string use byte alignment)
+    return addr
+
+def alignCNVRegAddress(addr, format, size, dim, dim2, strLen):
+    global regCounter
+    return regCounter
+
+# Adjust the register relying on the SIEMENS Simatic alignment constraints
+# 8bits alignment except for array and >8bits data (16bits alignment)
+# In case of string, its length has to be +2 to hold info on string
+def alignSimaticRegAddress(addr, format, size, dim, dim2, strLen):
+    global msize
+    
+    # internal string/unicode to integer cast
+    size = int(size)
+    addr = int(addr)
+    dim = int(dim)
+    dim2 = int(dim2)
+    strLen = int(strLen)
+        
+    algnt  = 8
+    if ((size > 1) | (dim > 1) | (dim2 > 1) | (strLen > 1)):
+        algnt = 16
+    while(whichDataAlignment(addr) < algnt):
+        addr+=1
+    if strLen > 1:                          # register is a string, 
+        if ((strLen % 2) != 0): strLen+=1   #adjusts the global size for byte type (word alignment)
+        strLen+=2   #add increment to strLen first two bytes for info on string (len, maxlen)
+          
+    msize = dim * dim2 * strLen * size      #compute memory data size
+    return addr
+
+# Adjust the register address relying on the BECKHOFF Twincat BC9020 alignment constraints.
+# TwinCAT BCxx PLCs are 16bits processor and base-address is interpreted as 16bit address
+# 8bits alignment between elements of 8bit-data array (including strings).
+# In case of string, its length has to be +1 to hold end-terminator.
+def alignBCxxRegAddress(addr, format, size, dim, dim2, strLen):
+    global msize
+
+    # internal string/unicode to integer cast
+    size = int(size)
+    addr = int(addr)
+    dim = int(dim)
+    dim2 = int(dim2)
+    strLen = int(strLen)
+    
+    algnt  = 16
+    while(whichDataAlignment(addr) < algnt):
+        addr+=1
+        
+    if strLen > 1:          # register is a string, 
+        strLen += 1       #TwinCAT  requires  '\0' string terminator.                             
+    
+    msize = dim * dim2 * strLen * size    #compute memory data size
+    return addr
+
+# Adjust the register address relying on the BECKHOFF Twincat CX9020 alignment constraints.
+# TwinCAT CXxx PLCs are 32bits processor but base-address is interpreted as 16bit address (required even address in the mapping)
+# 32bits alignment except for 8/16bits (16bits alignment).
+# 8bits alignment between elements of 8bit-data array (including strings).
+# In case of string, its length has to be +1 to hold end-terminator.
+def alignCXxxRegAddress(addr, format, size, dim, dim2, strLen):
+    global msize
+    
+    # internal string/unicode to integer cast
+    size = int(size)
+    addr = int(addr)
+    dim = int(dim)
+    dim2 = int(dim2)
+    strLen = int(strLen)
+    
+    algnt  = 16
+    if (size > 2):
+        algnt = 32
+    while(whichDataAlignment(addr) < algnt):
+        addr+=1
+        
+    if strLen > 1:          # register is a string, 
+        strLen += 1       #TwinCAT  requires  '\0' string terminator.
+                                     
+    msize = dim * dim2 * strLen * size    #compute memory data size
+    return addr
+    
+#block-address = block DB-Number
+def computeSiemensBlockBlkAddress(regAddr, classAddr, nbDev):
+    #Compute block mem-size at first: each block has a dedicated DB-number which contains an array of devices
+    #each element of the array is a structure which must be 16bits aligned!
+    global blkMemSize
+    global plcModel
+    global blkAddr
+    
+    # internal string/unicode to integer cast
+    regAddr = int(regAddr)
+    classAddr = int(classAddr)
+    nbDev = int(nbDev)
+    
+    nextBlockAddr = regAddr
+    algnt = whichBaseAlignment[plcModel]    #get the base struct-alignment of that PLC (16bit here)
+    # then adjust the next block-address by respecting this base-alignment.
+    while(int(whichDataAlignment(nextBlockAddr)) < int(algnt)):
+        nextBlockAddr+=1
+    blkMemSize = nextBlockAddr
+    # then compute the next block DB-number and return the current one
+    tmpblkAddr = blkAddr    
+    blkAddr = blkAddr + 1
+
+    return tmpblkAddr + classAddr
+
+#block-address = offset in the device memory
+def computeSiemensDeviceBlkAddress(regAddr, classAddr, nbDev):
+    #Compute block mem-size at first: each device has a dedicated DB-number which contains a sequence of blocks
+    #each block is a structure which must be 16bits aligned!
+    global blkMemSize
+    global plcModel
+    global blkAddr
+    
+    # internal string/unicode to integer cast
+    regAddr = int(regAddr)
+    classAddr = int(classAddr)
+    nbDev = int(nbDev)
+
+    nextBlockAddr = regAddr
+    algnt  = whichBaseAlignment[plcModel]   #get the base struct-alignment of that PLC (16bit here)
+    #then adjust the next block-address by respecting this base-alignment.                          
+    while(int(whichDataAlignment(nextBlockAddr)) < int(algnt)):
+        nextBlockAddr+=1
+    blkMemSize = nextBlockAddr
+    #then compute the next block DB-number and return the current one
+    tmpblkAddr = blkAddr
+    blkAddr = blkAddr + blkMemSize
+    return tmpblkAddr
+    
+    
+# Block-address = absolute address in the PLC memory
+def computeSchneiderBlockBlkAddress(regAddr, classAddr, nbDev):
+    global blkMemSize
+    global plcModel
+    global blkAddr
+
+    # Internal string/unicode to integer cast
+    regAddr = int(regAddr)
+    classAddr = int(classAddr)
+    nbDev = int(nbDev)
+
+    # Compute block mem-size at first:
+    # It corresponds to the next potential address that is 16bits or 32bits with SCHNEIDER.
+    nextBlockAddr = regAddr
+    
+    # Each data-block for each class and device will be aligned on the worst-case alignment
+    # of the given PLC. This logic allows having a unique address computing whatever the mode (DEVICE/BLOCK)
+    # and the PLC model (16bits or 32bits).
+    algnt  = whichBaseAlignment[plcModel] # get the "worst-case" base-alignment of that PLC
+    #then adjust the next block-address by respecting this base-alignment.                          
+    while(whichDataAlignment(nextBlockAddr) < int(algnt)):
+        nextBlockAddr+=1
+    blkMemSize = nextBlockAddr  
+    # then compute the next block DB-number and return the current one
+    tmpblkAddr = blkAddr   
+    # next absolute address: relies on the global class-address
+    blkAddr = blkAddr + (nbDev * blkMemSize)
+    return classAddr + tmpblkAddr
+    
+    
+# Block-address = offset in the device memory
+def computeSchneiderDeviceBlkAddress(regAddr, classAddr, nbDev):
+    global blkMemSize
+    global plcModel
+    global blkAddr
+        
+    # internal string/unicode to integer cast
+    regAddr = int(regAddr)
+    classAddr = int(classAddr)
+    nbDev = int(nbDev)
+    
+    #Compute block mem-size at first:
+    #it corresponds to the next potential address that is 16bits or 32bits with SCHNEIDER.
+    nextBlockAddr = regAddr
+    #Each data-block for each class and device will be aligned on the worst-case alignment
+    #of the given PLC. This logic allows having a unique adress computing whatever the mode (DEVICE/BLOCK)
+    #and the PLC model (16bits or 32bits).
+    algnt  = whichBaseAlignment[plcModel] #get the "worst-case" base-alignment of that PLC
+    #then adjust the next block-address by respecting this base-alignment.          
+    while(whichDataAlignment(nextBlockAddr) < int(algnt)):
+        nextBlockAddr+=1
+    blkMemSize = nextBlockAddr
+    #then compute the next block DB-number and return the current one
+    tmpblkAddr = blkAddr   
+    #next relative address: independent from the global class-address
+    blkAddr = blkAddr + blkMemSize
+    return tmpblkAddr
+    
+def computeNiDeviceBlkAddress(regAddr, classAddr, nbDev):
+    global blockCounter
+    blockCounter = blockCounter + 1
+    return blockCounter
+
+#-------------------------------------------------------------------------
+# Compute the next register address relying on the data start-address and size.
+def computeAnyNextRegAddress(brand, addr, dim, dim2=1):
+    global msize
+    
+    # internal string/unicode to integer cast
+    addr = int(addr)
+    dim = int (dim)
+    dim2 = int(dim2)
+    
+    addr = addr + msize;    #compute the next address for any case
+    if (brand == 'SIEMENS'):
+        # SIEMENS requires specific treatment in case of array.
+        if ((dim > 1) | (dim2 > 1)):
+            #SIEMENS array is always followed by 16bits adressing
+            algnt = 16
+            while(whichDataAlignment(addr) < algnt):
+                addr+=1
+    elif (brand == 'NI'):
+        msize = 0
+    return addr
+
+
+#-------------------------------------------------------------------------
+def computeAnyBlockInstAddress(classAddr, devSize):
+    global instAddr
+    tmpInstAddr = instAddr
+    instAddr = instAddr + 1     #device-index
+    return tmpInstAddr
+
+def computeSiemensDeviceInstAddress(classAddr, devSize):
+    global instAddr 
+    tmpInstAddr = instAddr
+    instAddr = instAddr + 1     #device DB-number
+    return tmpInstAddr + classAddr
+
+def computeSchneiderDeviceInstAddress(classAddr, devSize):
+    global instAddr
+    tmpInstAddr = instAddr
+    instAddr = instAddr + devSize #absolute address
+    return tmpInstAddr + classAddr
+
+def computeNiDeviceInstAddress(classAddr, devSize):
+    return 0
+#-------------------------------------------------------------------------
+# Compute the base DB-number of the next class in the SIEMENS PLC memory
+# BLOCK mode requires 1 DB per class block
+def computeSiemensBlockNextBaseAddress(classAddr, nbBlk, nbDev, devSize):
+    global classMem
+    global plcLast
+    global plcSize
+
+    # internal string/unicode to integer cast
+    classAddr   = int(classAddr)
+    nbBlk       = int(nbBlk)
+    nbDev       = int(nbDev)
+    devSize     = int(devSize)
+    
+    byteSize = nbDev * devSize
+    plcSize = int(plcSize) + int(byteSize)  #global size of the plc configuration
+    startDB = classAddr                     #first DB used for this class
+    plcLast = classAddr + nbBlk - 1         #last DB used
+    classMem = "DB%d..DB%d / %d bytes"%(startDB,plcLast,byteSize)
+    return plcLast + 1                      #next DB number
+
+# Compute the base DB-number of the next instance in the SIEMENS PLC memory
+# DEVICE mode requires 1 DB per class instance
+def computeSiemensDeviceNextBaseAddress(classAddr, nbBlk, nbDev, devSize):
+    global classMem
+    global plcLast
+    global plcSize
+    classAddr   = int(classAddr)
+    nbBlk       = int(nbBlk)
+    nbDev       = int(nbDev)
+    devSize     = int(devSize)
+    
+    byteSize = nbDev * devSize
+    plcSize = plcSize + byteSize            #global size of the plc configuration
+    startDB = classAddr                     #first DB used for this class
+    plcLast = classAddr + nbDev - 1         #last DB used
+    classMem = "DB%d..DB%d / %d bytes"%(startDB,plcLast,byteSize)
+    return plcLast + 1                      #next DB number
+
+# Compute the base-address of the next class in the SCHNEIDER PLC memory
+# DEVICE or BLOCK mode use the same memory size: next base address should be the same
+# 'used-mem' info is expressed in words (/2) but address is computed in bytes
+def computeSchneiderAnyNextBaseAddress(classAddr, nbBlk, nbDev, devSize):
+    global classMem
+    global plcLast
+    global plcSize
+    classAddr   = int(classAddr)
+    nbBlk       = int(nbBlk)
+    nbDev       = int(nbDev)
+    devSize     = int(devSize)
+    
+    wordSize = (nbDev * devSize) / 2
+    plcSize = plcSize + wordSize            #global size of the plc configuration
+    startAddr = classAddr / 2               #first word address used for this class
+    plcLast = startAddr + wordSize - 1      #LAST word address used for this class
+    classMem = "MW%d..MW%d / %d words"%(startAddr,plcLast,wordSize);
+    return (classAddr + (wordSize * 2))     #next word address expressed in bytes
+
+def computeNiAnyNextBaseAddress(classAddr, nbBlk, nbDev, devSize):
+    return 0
+
+#-------------------------------------------------------------------------
+# computeChecksumController
+# checksum procedure:
+#     CRC = Major-number + PLC-base-address
+#     For each PLC-Class (cluster) of the controller mapping:
+#         CRC += class-name + class-version + class-access //DEVICE/BLOCK
+#         For each Block
+#             CRC += block-name + block-mode //R/W
+#             For each Register
+#                 CRC += reg-name + reg-format + array-dim1 + array-dim2 + (string-length) optional
+#         CRC += nb-instance
+#
+def computeChecksumController( workspacePath, controllerNode, silecsVersion, PLCbaseAddress, funcGetSilecsDesignFilePath,  logTopics={'errorlog': True}):
+    majorSilecsVersion = iecommon.getMajorSilecsVersion(silecsVersion)
+    CRC32 = zlib.crc32(trim(str(majorSilecsVersion)),0)& 0xffffffff
+    CRC32 = zlib.crc32(trim(str(PLCbaseAddress)),CRC32)& 0xffffffff
+    for silecsDesign in controllerNode.xpathEval("SilecsDesign"):
+        CRC32       = zlib.crc32(trim(silecsDesign.prop("silecs-design-name")),CRC32)& 0xffffffff
+        CRC32       = zlib.crc32(trim(silecsDesign.prop("silecs-design-version")),CRC32)& 0xffffffff
+        designDOM = loadSilecsDesignDOM(workspacePath, silecsDesign, silecsVersion, funcGetSilecsDesignFilePath)
+        CRC32 = computeChecksumClass(designDOM,CRC32,logTopics)
+        for device in silecsDesign.xpathEval("Device"):
+            CRC32     = zlib.crc32(trim(device.prop("device-name")),CRC32)& 0xffffffff
+    iecommon.logInfo("CRC32: %s" % str(CRC32),logTopics)
+    return CRC32
+    
+def computeChecksumClass(designDOM, CRC32, logTopics={'errorlog': True}):
+    blockList = designDOM.xpathEval("Block")
+    for blockNode in blockList:
+        blockName = blockNode.prop('name')
+        blockMode = blockNode.prop('mode')
+        registerList = blockNode.xpathEval("Register")
+        for register in registerList:
+            regName   = register.prop("name")
+            CRC32     = zlib.crc32(trim(regName),CRC32)& 0xffffffff
+
+            regFormat = register.prop("format")
+            CRC32     = zlib.crc32(trim(regFormat),CRC32)& 0xffffffff
+
+            try:
+                # array-dim1 is an optional attribute!!!
+                regDim1   = register.prop("array-dim1")
+            except:
+                regDim1   = "1"
+            CRC32     = zlib.crc32(trim(regDim1),CRC32)& 0xffffffff
+
+            try:
+                # array-dim2 is an optional attribute!!!
+                regDim2   = register.prop("array-dim2")
+            except:
+                regDim2   = "1"
+            CRC32     = zlib.crc32(trim(regDim2),CRC32)& 0xffffffff
+
+            try:
+                # string-len is an optional attribute!!!
+                stringLength = register.prop("string-len")
+                CRC32     = zlib.crc32(trim(stringLength),CRC32)& 0xffffffff
+            except:
+                pass
+    return CRC32
+    
+#-------------------------------------------------------------------------
+# Hash table
+#-------------------------------------------------------------------------
+
+whichPLCBrand = {
+    'SIMATIC_S7-300'    : 'SIEMENS',
+    'SIMATIC_S7-400'    : 'SIEMENS',
+    'SIMATIC_S7-1200'   : 'SIEMENS',
+    'SIMATIC_S7-1500'   : 'SIEMENS',
+    'SIMATIC_ET-200S'   : 'SIEMENS',
+    'SIMATIC_S7-VIRTUAL': 'SIEMENS',
+    'Premium'           : 'SCHNEIDER',
+    'Quantum'           : 'SCHNEIDER',
+    'M340'              : 'SCHNEIDER',
+    'Compact_RIO'       : 'NI',
+    'PXI_RT'            : 'NI',
+    'PXI_Windows'       : 'NI',
+    'PC_Windows'        : 'NI',
+    'Other_Support_CNV' : 'NI',
+    'Rabbit_RCM_4010'   : 'DIGI',
+    'Rabbit_RCM_2000'   : 'DIGI',
+    'BC9020'            : 'BECKHOFF',
+    'CX9020'            : 'BECKHOFF'
+}
+
+# The following constant are used to align the address of a device block {set of registers}.
+# With SCHNEIDER PLC, block is aligned depending on his 'worst-case' alignement {16bits or 32bits}.
+# This logic allows having a unique adress computing whatever the mode {DEVICE/BLOCK} and the PLC model.
+# Concerning SIEMENS PLC, block alignment should respect the 16bits alignement constraint for Struct&Array.
+whichBaseAlignment = {
+    'SIMATIC_S7-300'    : '16',
+    'SIMATIC_S7-400'    : '16',
+    'SIMATIC_S7-1200'   : '16',
+    'SIMATIC_S7-1500'   : '16',
+    'SIMATIC_ET-200S'   : '16',
+    'SIMATIC_S7-VIRTUAL': '16',
+    'Premium'           : '16',
+    'Quantum'           : '16',
+    'M340'              : '32',     # any data-block of M340 model will start on 32bits address
+                                  # even if the first register of the block is a 16bit data.
+    'Rabbit_RCM_4010' : '16',
+    'Rabbit_RCM_2000' : '16',
+    'BC9020'          : '16',
+    'CX9020'          : '32'                          
+}
+
+whichDataSize = {
+    'uint8'        : '1',
+    'int8'          : '1',
+    'uint16'      : '2',
+    'int16'        : '2',
+    'uint32'      : '4',
+    'int32'        : '4',
+    'float32'     : '4',
+    'uint64'      : '8',
+    'int64'        : '8',
+    'float64'     : '8',
+    'string'       : '1',
+    'date'         : '8',
+    # deprecated formats
+    'char'         : '1',
+    'byte'         : '1',
+    'word'        : '2',
+    'dword'      : '4',
+    'int'            : '2',
+    'dint'          : '4',
+    'real'          : '4',
+    'dt'             : '8'
+}
+
+whichRegAddressFunction = {
+    'SIMATIC_S7-300'          : alignSimaticRegAddress,
+    'SIMATIC_S7-400'          : alignSimaticRegAddress,
+    'SIMATIC_S7-1200'         : alignSimaticRegAddress,
+    'SIMATIC_S7-1500'         : alignSimaticRegAddress,
+    'SIMATIC_ET-200S'         : alignSimaticRegAddress,
+    'SIMATIC_S7-VIRTUAL'      : alignSimaticRegAddress,
+    'Premium'                 : alignPremiumRegAddress,
+    'Quantum'                 : alignPremiumRegAddress,
+    'M340'                    : alignM340RegAddress,
+    'Compact_RIO'             : alignCNVRegAddress,
+    'PXI_RT'                  : alignCNVRegAddress,
+    'PXI_Windows'             : alignCNVRegAddress,
+    'PC_Windows'              : alignCNVRegAddress,
+    'Other_Support_CNV'       : alignCNVRegAddress,
+    'Rabbit_RCM_4010'         : alignDIGIRegAddress,
+    'Rabbit_RCM_2000'         : alignDIGIRegAddress,
+    'BC9020'                  : alignBCxxRegAddress,
+    'CX9020'                  : alignCXxxRegAddress
+}
+
+whichBlkAddressFunction = {
+    'SIEMENS'+'BLOCK_MODE'        : computeSiemensBlockBlkAddress,
+    'SIEMENS'+'DEVICE_MODE'       : computeSiemensDeviceBlkAddress,
+    'SCHNEIDER'+'BLOCK_MODE'    : computeSchneiderBlockBlkAddress,
+    'SCHNEIDER'+'DEVICE_MODE'   : computeSchneiderDeviceBlkAddress,
+    'NI'+'DEVICE_MODE'                  : computeNiDeviceBlkAddress,
+    'DIGI'+'BLOCK_MODE'           : computeSchneiderBlockBlkAddress,
+    'DIGI'+'DEVICE_MODE'          : computeSchneiderDeviceBlkAddress,
+    'BECKHOFF'+'BLOCK_MODE'      : computeSchneiderBlockBlkAddress
+}
+
+whichInstAddressFunction = {
+    'SIEMENS'+'BLOCK_MODE'         : computeAnyBlockInstAddress,
+    'SIEMENS'+'DEVICE_MODE'        : computeSiemensDeviceInstAddress,
+    'SCHNEIDER'+'BLOCK_MODE'    : computeAnyBlockInstAddress,
+    'SCHNEIDER'+'DEVICE_MODE'   : computeSchneiderDeviceInstAddress,
+    'NI'+'DEVICE_MODE'                  : computeNiDeviceInstAddress,
+    'DIGI'+'BLOCK_MODE'           : computeAnyBlockInstAddress,
+    'DIGI'+'DEVICE_MODE'          : computeSchneiderDeviceInstAddress,
+    'BECKHOFF'+'BLOCK_MODE'      : computeAnyBlockInstAddress
+}
+
+whichBaseAddressFunction = {
+    'SIEMENS'+'BLOCK_MODE'         : computeSiemensBlockNextBaseAddress,
+    'SIEMENS'+'DEVICE_MODE'        : computeSiemensDeviceNextBaseAddress,
+    'SCHNEIDER'+'BLOCK_MODE'     : computeSchneiderAnyNextBaseAddress,
+    'SCHNEIDER'+'DEVICE_MODE'    : computeSchneiderAnyNextBaseAddress,
+    'NI'+'DEVICE_MODE'                   : computeNiAnyNextBaseAddress,
+    'DIGI'+'BLOCK_MODE'            : computeSchneiderAnyNextBaseAddress,
+    'DIGI'+'DEVICE_MODE'           : computeSchneiderAnyNextBaseAddress,
+    'BECKHOFF'+'BLOCK_MODE'       : computeSchneiderAnyNextBaseAddress
+}
+
+#Base address provided by the user in the Deployment relies on the PLC model:
+#Unity Premium/Quantum is interpreted as 16bit address
+#Unity M340 is interpreted as 32bit address
+#Factor is used to convert the base-address to byte-addressing for computation.
+whichAddressFactor = {      
+    'SIMATIC_S7-300'    : 1,  # Simatic does not use absolute addressing {DB-number}
+    'SIMATIC_S7-400'    : 1,
+    'SIMATIC_S7-1200'   : 1,
+    'SIMATIC_S7-1500'   : 1,
+    'SIMATIC_ET-200S'   : 1,
+    'SIMATIC_S7-VIRTUAL': 1,
+    'Premium'           : 2,  # Premium/Quantum uses 16bit adressing for 32bit values
+    'Quantum'           : 2,
+    'M340'              : 2,
+    'Compact_RIO'       : 0,
+    'PXI_RT'            : 0,
+    'PXI_Windows'       : 0,
+    'PC_Windows'        : 0,
+    'Other_Support_CNV' : 0,
+    'Rabbit_RCM_4010'   : 2,
+    'Rabbit_RCM_2000'   : 2,
+    'BC9020'            : 2,    # BC90xx use 16 bit addressing
+    'CX9020'            : 1
+} 
+
+def loadSilecsDesignDOM(workspacePath, classNode, silecsVersion, funcGetSilecsDesignFilePath):
+    if classNode.prop("silecs-design-name") == "SilecsHeader":
+        silecsHeader = xmltemplate.getSilecsHeader(silecsVersion)
+        return libxml2.parseDoc(silecsHeader)
+    else:
+        designPath = funcGetSilecsDesignFilePath(workspacePath, classNode.prop("silecs-design-name"))
+        return libxml2.parseFile(designPath)
+
+# Needed to encapsulate "genParam" in order to allow unit-testing (fake all file interactions)
+def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSilecsDeployFilePath,  funcGetParameterFileDirectory, workspacePath, deployName, deployVersion, silecsVersion, logTopics={'errorlog': True}):
+    # Global variable links
+    global plcModel, plcBrand, plcSystem, plcProtocol, plcSize, plcLast
+    global PLCbaseAddress, checksumRef, owner, deviceMemSize, blkAddr, nbBlock, msize
+    global blkMemSize
+    global instAddr, classAddr
+    global classMem
+    
+    global blockCounter     # used for NI block address generation
+    global regCounter   # used for NI register address generation
+
+    # Check the Deployment document exist for that PLC
+    deployPath = funcGetSilecsDeployFilePath(workspacePath, deployName)
+    if(not os.path.isfile(deployPath)):
+        iecommon.logError(deployName + "deployment file cannot be found in provided workspace",logTopics)
+    
+    # Create the Deployment DOM object
+    deployDOM = libxml2.parseFile(deployPath)
+    
+    # Check that Deployment data are consistent
+    deployUnitNode = deployDOM.xpathEval("/SILECS-Deploy/Deploy-Unit")[0] # only one Deploy-Unit
+    
+    if (deployUnitNode.prop('name') != deployName):
+        iecommon.logError("Deployment name is not consistent", True,logTopics)
+
+    #-------------------------------------------------------------------------
+    # Extract information from the XML
+    #-------------------------------------------------------------------------
+    
+    # Extract Deployment owner from the Information node
+    owner = deployDOM.xpathEval("/SILECS-Deploy/Information/Owner")[0].prop('user-login')
+
+    #-------------------------------------------------------------------------
+    # SECOND pass on each Design documents: Generate parameters
+    # For each class generate XML-ouput document relying on Design & Deployment
+    #-------------------------------------------------------------------------
+    iecommon.logDebug("------Processing for output file generation------",logTopics)
+    paramPath = funcGetParameterFileDirectory(workspacePath, deployName)
+
+    #create output directory if necessary
+    if not os.path.exists(paramPath):
+        os.makedirs(paramPath)
+        iecommon.logDebug("create directory %s" %paramPath,logTopics)
+    
+    iecommon.addSilecsHeaderToClasses(deployDOM)
+    controllerNodes = deployDOM.xpathEval("/SILECS-Deploy/Controller")
+    for controllerNode in controllerNodes:
+        plcNode  = controllerNode.xpathEval("*[@system]")[0]
+        # Extract PLC global information
+        plcSystem     = plcNode.prop('system')
+        plcModel        = plcNode.prop('model')
+        plcBrand        = whichPLCBrand[plcModel]
+        plcProtocol     = plcNode.prop('protocol')
+        addressFactor   = whichAddressFactor[plcModel]
+
+        if plcBrand == 'SIEMENS':
+            PLCbaseAddress = long(plcNode.prop('base-DB-number'))
+            
+        elif plcBrand == 'SCHNEIDER':
+            PLCbaseAddress = long(plcNode.prop('base-address'))
+            PLCbaseAddress = PLCbaseAddress * addressFactor
+            
+        elif plcBrand == 'BECKHOFF':
+            PLCbaseAddress = long(plcNode.prop('base-address'))
+            # Use plcModel to set appropriate initial offset
+            if plcModel == 'BC9020':
+                offset = 32768
+            elif plcModel == 'CX9020':
+                offset = 24576
+            PLCbaseAddress = (PLCbaseAddress * addressFactor) + offset
+                
+        elif plcBrand == 'DIGI':
+            PLCbaseAddress = long(plcNode.prop('base-address'))
+            PLCbaseAddress = PLCbaseAddress * addressFactor
+            
+        else: # plcBrand == 'NI'
+            PLCbaseAddress = 0
+
+        classBaseAddress = PLCbaseAddress
+
+        # Messagges for debugging purpose
+        iecommon.logDebug("------ XML extracted informations ------",logTopics)
+        iecommon.logDebug("owner = "+owner,logTopics)
+        iecommon.logDebug("plcSystem = "+plcSystem,logTopics)
+        iecommon.logDebug("plcModel = "+plcModel,logTopics)
+        iecommon.logDebug("plcBrand = "+plcBrand,logTopics)
+        iecommon.logDebug("plcProtocol = "+plcProtocol,logTopics)
+        iecommon.logDebug("addressFactor = %d" %addressFactor,logTopics)
+        iecommon.logDebug("PLCbaseAddress = %d" %PLCbaseAddress,logTopics)
+
+        paramFile = funcGetParameterFile(workspacePath, deployName, controllerNode.prop('host-name'))
+        iecommon.logInfo("Generate xml for parameters file: "+paramFile,logTopics)
+
+        # Create the parameter DOM for the output file
+        paramDOM  = libxml2.newDoc(version='1.0')
+        outputRoot  = libxml2.newNode('SILECS-Param')
+        outputRoot.setProp("silecs-version", silecsVersion)
+        paramDOM.addChild(outputRoot)
+
+        #-------------------------------------------------------------------------
+        # Generate section <Mapping-Info></Mapping-Infon>
+        #-------------------------------------------------------------------------
+        paramMappingInfoNode = libxml2.newNode("Mapping-Info")
+        outputRoot.addChild(paramMappingInfoNode)
+
+        # Add Owner
+        paramOwnerNode = libxml2.newNode('Owner')
+        paramOwnerNode.setProp("user-login", owner)
+        paramMappingInfoNode.addChild(paramOwnerNode)
+        
+        # Add Generation
+        element2 = libxml2.newNode('Generation')
+        currentDate = str(datetime.datetime.now())
+        element2.setProp("date",currentDate)
+        paramMappingInfoNode.addChild(element2)
+        
+        # Add Deployment
+        element2 = libxml2.newNode('Deployment')
+        CRC32 = computeChecksumController(workspacePath, controllerNode, silecsVersion, PLCbaseAddress, funcGetSilecsDesignFilePath, logTopics)
+        element2.setProp("checksum", str(CRC32))
+        paramMappingInfoNode.addChild(element2)
+
+        #-------------------------------------------------------------------------
+        # Generate section <SILECS-Mapping></SILECS-Mapping>
+        #-------------------------------------------------------------------------
+        paramSilecsMappingNode = libxml2.newNode("SILECS-Mapping")
+        paramSilecsMappingNode.setProp("plc-name", controllerNode.prop('host-name'))
+        paramSilecsMappingNode.setProp("plc-brand", plcBrand)
+        paramSilecsMappingNode.setProp("plc-system", plcSystem)
+        paramSilecsMappingNode.setProp("plc-model", plcModel)
+        paramSilecsMappingNode.setProp("protocol", plcProtocol)
+        paramSilecsMappingNode.setProp("address", str(PLCbaseAddress))
+        paramSilecsMappingNode.setProp("domain", "NotUsed")
+        paramSilecsMappingNode.setProp("used-mem", "TODO")
+        outputRoot.addChild(paramSilecsMappingNode)
+
+        classNodes = controllerNode.xpathEval('SilecsDesign')
+        for classNode in classNodes:
+            iecommon.logDebug("-----------------------------------------",logTopics)
+            iecommon.logDebug("------  Analysing Class %s   ------"%classNode.prop("silecs-design-name"),logTopics)
+            iecommon.logDebug("-----------------------------------------",logTopics)
+            
+            designDOM = loadSilecsDesignDOM(workspacePath, classNode, silecsVersion, funcGetSilecsDesignFilePath)
+
+            # Extract the number of devices ------------------------------------------
+
+            deviceLabelList=classNode.xpathEval('Device')
+            nbDevice = len(deviceLabelList)
+            iecommon.logDebug("Class %s uses device-list and has %s devices" %(classNode,nbDevice),logTopics)
+            
+            paramClassNode = libxml2.newNode("SILECS-Class")
+            paramSilecsMappingNode.addChild(paramClassNode)
+            paramClassNode.setProp("name", classNode.prop("silecs-design-name"))
+            paramClassNode.setProp("version", classNode.prop("silecs-design-version"))
+            
+            #-------------------------------------------------------------------------
+            # Generate section <Block></Block>
+            #-------------------------------------------------------------------------
+            blockCounter = 0
+            
+            deviceMemSize = 0   # global memory-size of one class instance (sum of block-memory size)
+            blkAddr = 0                 # memory address of the block (using byte addressing)
+            nbBlock = 0             # number of block of the class
+
+            computeBlkAddress = whichBlkAddressFunction[plcBrand + plcProtocol]
+            
+            # INNER LOOP TO ACCESS AT BLOCK LEVEL (LOOP-2)
+            for block in designDOM.xpathEval("//Block"):    #LOOP-2
+                element3 = libxml2.newNode("Block")
+                element3.setProp("name", block.prop("name"))
+                element3.setProp("mode", block.prop("mode"))
+                iecommon.logDebug("----- Processing Block "+block.prop('name')+" from design -----",logTopics)
+                # Initialization for inner loop local variables 
+                regAddress = 0      # memory address of the register (using byte addressing)
+                blockSize = 0           # block size (sum of the register size)
+                blockMemSize = 0    # block size (sum of the regist)
+                instAddr = 0                # initial class address BUG FIXED
+                regCounter = 0      # used for NI register address generation
+                alignRegAddress     = whichRegAddressFunction [plcModel]
+        
+                #-------------------------------------------------------------------------
+                # Generate section <Register></Register>
+                #-------------------------------------------------------------------------
+                # INNER LOOP TO ACCESS AT REGISTER LEVEL (LOOP-3)
+                for register in block.xpathEval("Register"):
+                    iecommon.logDebug("------ Processing Register "+register.prop('name')+" ------")
+                    element4 = libxml2.newNode("Register")     
+                    # Set register name
+                    element4.setProp("name", register.prop("name"))
+                    # Set register format
+                    regFormat = register.prop("format")
+                    element4.setProp("format", regFormat)
+                    
+                    # Just get the register dimensions for next computation
+                    regDimension1 = '1' #by default
+                    if register.prop('array-dim1'): #possibly single array
+                        regDimension1 = register.prop("array-dim1")
+                    regDimension2 = '1' #by default
+                    if register.prop('array-dim2'): #possibly double array
+                        regDimension2 = register.prop('array-dim2')
+
+                    # Set length attribute only for string registers
+                    strLen = '1' #not a string by default (no impact on data total-size)
+                    if regFormat == 'string':
+                        strLen = register.prop('string-len')
+                        if strLen: #is string length defined?
+                            if plcBrand == 'RABBIT':
+                                # RABBIT has 8bit memory alignment but uses 16bit word communication protocol (MODBUS).
+                                # String buffer (8bit elements) must have even number of bytes.
+                                if ((int(regDimension1)*int(regDimension2)*int(strLen)) % 2 == 1): #XML CliX cannot check that constraint!   
+                                    iecommon.logError("String length of %s register must be an even value." %register.prop("name"), False,logTopics)
+                                    sys.exit(2)
+                        else:   # if length not given, set default length for string (=64)
+                            strLen = '64'
+                        element4.setProp('string-len', strLen)
+                    
+                    # Set register dimensions
+                    element4.setProp("array-dim1", regDimension1)
+                    element4.setProp("array-dim2", regDimension2)
+                    # Set register size
+                    regSize = whichDataSize[regFormat]
+                    element4.setProp("size", regSize)
+                    # Set register address
+                    regAddress = alignRegAddress(regAddress, regFormat, regSize, regDimension1, regDimension2, strLen)
+                    element4.setProp("address", str(regAddress))
+                    regCounter = regCounter + 1 # used for NI register address generation
+                    # Set register mem-size
+                    element4.setProp("mem-size", str(msize))  
+                    # Compute address for the next register
+                    regAddress = computeAnyNextRegAddress(plcBrand, regAddress, regDimension1, regDimension2)
+                    # Set register synchro
+                    element4.setProp("synchro", register.prop("synchro"))
+                    # Append register
+                    element3.addChild(element4)
+                    #iterativelly compute the block size (accumulator initialized outside the loop)
+                    blockSize = blockSize + (int(regSize) * int(regDimension1) * int(regDimension2))
+                # END OF INNER LOOP TO ACCESS AT REGISTER LEVEL (LOOP-3)
+
+                # Set block size
+                element3.setProp("size", str(blockSize))
+                # Set block address
+                element3.setProp("address",str(computeBlkAddress(regAddress, int(classBaseAddress) , nbDevice)))
+                # Set block mem-size
+                element3.setProp("mem-size", str(blkMemSize))
+                # Append block
+                paramClassNode.addChild(element3)
+                # Count the number of devices
+                nbBlock = nbBlock+1
+                # Accumulate blkMemSize to compute the total deviceMemSize
+                deviceMemSize = deviceMemSize + blkMemSize
+
+            # END OF INNER LOOP TO ACCESS AT BLOCK LEVEL (LOOP-2)
+            # Set block Address
+            paramClassNode.setProp("address", str(classBaseAddress))
+            
+            #-------------------------------------------------------------------------
+            # Devices
+            #-------------------------------------------------------------------------
+            computeInstAddress = whichInstAddressFunction[ plcBrand + plcProtocol ]
+
+            for device in deviceLabelList:
+                element3 = libxml2.newNode("Instance")     
+                element3.setProp("label", device.prop("device-name"))
+                element3.setProp("address", str(computeInstAddress(classBaseAddress, deviceMemSize)))
+                paramClassNode.addChild(element3)
+
+            # Compute the memory address for the next class
+            computeBaseAddress = whichBaseAddressFunction [plcBrand+plcProtocol]
+            classBaseAddress = computeBaseAddress(classBaseAddress, nbBlock, nbDevice, deviceMemSize);
+            
+            # Set class used-memory
+            paramClassNode.setProp("used-mem", str(classMem))
+            iecommon.logInfo("Used-memory for Class "+classNode.prop("silecs-design-version")+": "+str(classMem),logTopics)
+
+        #------------------------------------------------------
+        # Generate output XML
+        #------------------------------------------------------
+        iefiles.saveXMLToFile(paramFile,paramDOM)
+        
+        iecommon.logDebug("---------------------------------------------------------",logTopics)
+        iecommon.logDebug("------GENERATED FILE: %s "%paramFile,logTopics)
+        iecommon.logDebug("---------------------------------------------------------",logTopics)
+     
+    # GSI-Fix there are more then two types now ... better say nothing than something which could be wrong for the else-case
+    #Display details about the PLC memory using for the global configuration
+    #if (plcBrand == 'SIEMENS'):
+    #    # SIEMENS works with data-block addressing
+    #    plcUsedMem = "DB"+str(PLCbaseAddress)+"..DB"+str(plcLast)+" / "+str(plcSize)+" bytes"
+    #else:
+    #    # SCHNEIDER works with absolute addressing
+    #    startAddr   = PLCbaseAddress /2         #Memory info uses word-addressing
+    #    lastAddr    = plcLast               #Already computed as byte-address
+    #    plcUsedMem  = "MW"+str(startAddr)+"..MW"+str(lastAddr)+" / "+str(plcSize)+" words"
+    
+    # print plc used memory
+    # iecommon.logInfo("Used-memory for PLC "+deployName+": "+str(plcUsedMem),logTopics)
+
+
+#=========================================================================
+# Entry point
+#=========================================================================
+def genParam(workspacePath, deployName, deployVersion, silecsVersion, logTopics={'errorlog': True}):
+    genParamBase( iefiles.getSilecsDesignFilePath, iefiles.getParameterFile, iefiles.getSilecsDeployFilePath,  iefiles.getParameterFileDirectory, workspacePath, deployName, deployVersion, silecsVersion, logTopics)
+
+
diff --git a/silecs-codegen/src/xml/genparam.pyc b/silecs-codegen/src/xml/genparam.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9b261e4b82432c86678ae23805fb1f26038001e7
Binary files /dev/null and b/silecs-codegen/src/xml/genparam.pyc differ
diff --git a/silecs-codegen/src/xml/genplcsrc$py.class b/silecs-codegen/src/xml/genplcsrc$py.class
new file mode 100644
index 0000000000000000000000000000000000000000..62f0355bd8a0b7b9373c3a56a58ffffc3b8e91c6
Binary files /dev/null and b/silecs-codegen/src/xml/genplcsrc$py.class differ
diff --git a/silecs-codegen/src/xml/genplcsrc.py b/silecs-codegen/src/xml/genplcsrc.py
new file mode 100644
index 0000000000000000000000000000000000000000..0c86eb8b64391200656d6840bb741500721dc050
--- /dev/null
+++ b/silecs-codegen/src/xml/genplcsrc.py
@@ -0,0 +1,723 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import os
+import sys
+import time
+import zlib
+import libxml2
+
+import iecommon
+import iefiles
+import xmltemplate
+import s7template
+import virtualS7Template
+import rabbitTemplate
+
+from iecommon import *
+#=========================================================================
+# General remarks
+#=========================================================================
+
+#XML input documents well-formed is not checked! 
+#This Python-script generates PLC sources document from XML Parameter documents
+#which are supposed to be well-formed (generated with the 'genparam' script).
+
+
+# Deploy global information
+class Deploy(object):
+    plcModel        = None  # S7-300, .., Premium, ..
+    plcSystem       = None  # UNITY, STEP-7, TIA-PORTAL, ...
+    plcProtocol     = None  # DEVICE_MODE or BLOCK_MODE
+    address         = None
+    checksum     = None  # checksum of the related parameter file
+    owner           = None  # onwer of the Deployment document
+    silecsVersion   = None
+
+whichUnityFormat = {
+    'uint8'      : 'BYTE',
+    'int8'        : 'WORD',
+    'uint16'    : 'WORD',
+    'int16'      : 'INT',
+    'uint32'    : 'DWORD',
+    'int32'      : 'DINT',
+    'float32'   : 'REAL',
+    'string'     : 'STRING',
+#    'uint64'      : '8',    not supported with PLC
+#    'int64'        : '8',    not supported with PLC
+#    'float64'     : '8',    not supported with PLC
+    'date'       : 'DT',
+    'char'       : 'WORD',
+    'byte'       : 'BYTE',
+    'word'      : 'WORD',
+    'dword'    : 'DWORD',
+    'int'          : 'INT',
+    'dint'        : 'DINT',
+    'real'        : 'REAL',
+    'dt'           : 'DT'
+}
+
+whichTwincatFormat = {
+    'uint8'      : 'BYTE',
+    'int8'        : 'SINT',
+    'uint16'    : 'WORD',
+    'int16'      : 'INT',
+    'uint32'    : 'DWORD',
+    'int32'      : 'DINT',
+    'float32'   : 'REAL',
+    'string'     : 'STRING',
+#    'uint64' not supported by PLCs
+#    'int64' not supported by PLCs
+#    'float64' not supported by PLCs
+    'date'       : 'DT',
+    'char'       : 'SINT',
+    'byte'       : 'BYTE',
+    'word'      : 'WORD',
+    'dword'    : 'DWORD',
+    'int'          : 'INT',
+    'dint'        : 'DINT',
+    'real'        : 'REAL',
+    'dt'           : 'DT',
+    'string'     : 'STRING'
+}
+
+schneiderRegArray  = """ARRAY[0..%d] OF %s"""
+schneiderRegArray2d  = """ARRAY[0..%d, 0..%d] OF %s"""
+
+# Beckhoff templates (using newlines \r\n because TwinCAT compiler complains with line feed character)
+beckhoffReg = """    %s_%04x_%s AT %%MW%s: %s;\r\n\r\n"""
+beckhoffRegArray = """    %s_%04x_%s AT %%MW%s: ARRAY [0..%d] OF %s;\r\n\r\n"""
+beckhoffRegArray2d = """    %s_%04x_%s AT %%MW%s: ARRAY [0..%d, 0..%d] OF %s;\r\n\r\n"""
+beckhoffRegInit = """    %s_%04x_%s AT %%MW%s: %s:= %s;\r\n\r\n"""
+
+#=========================================================================
+# Sub-function
+#=========================================================================
+
+#-------------------------------------------------------------------------
+# Schneider registers
+#-------------------------------------------------------------------------
+
+def xsyRegister(regFormat, regDim, regDim2, regLen=1):
+    if regLen > 1:  # register is a string or an array of strings
+        strLen= whichUnityFormat[regFormat]+'['+str(regLen)+']'
+        if  regDim == 1 and regDim2 ==1:    # string
+            return strLen
+        elif regDim > 1 and regDim2 == 1:   # string array
+            return schneiderRegArray %(regDim-1, strLen)
+        else: # dim1>=1 and for whatever dim2, use double array syntax
+            return schneiderRegArray2d %(regDim-1, regDim2-1, strLen)
+    else:
+        if  regDim == 1 and regDim2 ==1:    # scalar
+            return whichUnityFormat[regFormat]
+        elif regDim > 1 and regDim2 == 1:   # array
+            return schneiderRegArray %(regDim-1, whichUnityFormat[regFormat])
+        else: # dim1>=1 and for whatever dim2, use double array syntax
+            return schneiderRegArray2d %(regDim-1, regDim2-1, whichUnityFormat[regFormat])
+    
+def getDateTime():
+    dt = time.localtime(time.time())
+    return "DT#%s-%s-%s-%s:%s:%s" %(dt[0],dt[1],dt[2],dt[3],dt[4],dt[5])
+
+#-------------------------------------------------------------------------
+# SIEMENS PLC code generation
+#-------------------------------------------------------------------------
+def generateSiemensSources(paramDOM, sourceFolderPath ,logTopics):
+    stlString = ''
+    symString = ''  # for .sdf Symbol file
+
+    deploy = getDeploymentInformation(paramDOM)
+
+    # Prepare the Simatic Symbols (<.sdf> file)
+    DBnumber    = long(deploy.address)       #first data-block (SilecsHeader) starts from the base-address
+    UDTnumber   = long(deploy.address)       #use base data-block address for UDT number as well (to be reserved by the developer)
+
+    # Generate sources for each class that is deployed in the PLC
+    classNodes = paramDOM.xpathEval("/SILECS-Param/SILECS-Mapping/SILECS-Class")
+    for classNode in classNodes:
+        blockDOMList  = classNode.xpathEval("Block") # get Blocks elements of that class
+        deviceDOMList = classNode.xpathEval("Instance") # get Device instances of that class
+        
+        className       = classNode.prop('name')
+        classVersion    = classNode.prop('version')
+
+        deviceNumber = len(deviceDOMList)
+
+        # Generate the Blocks definition
+        for blockIndex, blockDOM in enumerate(blockDOMList):
+            registerList = ''
+            blockName = blockDOM.prop('name')
+            registerDOMList = blockDOM.xpathEval("Register") # get registers of the current block
+            for registerIndex, registerDOM in enumerate(registerDOMList):
+                registerName = registerDOM.prop('name')
+                registerFormat = registerDOM.prop('format')
+                
+                # If PLC does not supports this register format abort this generation and log the error
+                if(registerFormat in ['uint64','int64','float64']):
+                    iecommon.logError('ERROR: In design %s_%s register %s, %s format not supported for current controller model.'
+                                      %(className, classVersion, registerName, registerFormat)
+                                      , True,logTopics)
+                
+                #create register value if required (diagnostic registers assignment in particular)
+                registerValue = s7template.stlRegisterValue(registerName, deploy.owner, getDateTime(), deploy.checksum,deploy.silecsVersion)
+                
+                # Read register dimensions
+                registerDimension1 = long(registerDOM.prop('array-dim1'))
+                registerDimension2 = long(registerDOM.prop('array-dim2'))
+                
+                if registerFormat == 'string':
+                    registerList += s7template.stlRegister(registerName, registerFormat, registerDimension1, registerDimension2, registerValue, long(registerDOM.prop('string-len')))
+                else:                    
+                    registerList += s7template.stlRegister(registerName, registerFormat, registerDimension1, registerDimension2, registerValue)
+
+            stlString += s7template.stlBlockUDT(deploy.owner, className, classVersion, blockName, registerList, (blockIndex == 0))
+            symString += s7template.symBlockUDT(className, classVersion, blockName, UDTnumber, (blockIndex == 0))
+            UDTnumber += 1
+   
+        if deploy.plcProtocol == 'DEVICE_MODE':
+        # Generate the Data-Blocks: one DB per Device instance
+            for deviceIndex, deviceDOM in enumerate(deviceDOMList):
+                blockList = ''
+                for blockDOM in blockDOMList:
+                    blockName = blockDOM.prop('name')
+                    blockList += s7template.stlBlock(className, blockName)
+                deviceLabel = deviceDOM.prop('label')
+                stlString += s7template.generateBlock(deploy.owner, className, classVersion, deploy.plcSystem, DBnumber, deviceLabel, blockList, (deviceIndex == 0),deploy.plcProtocol)
+                symString += s7template.symDeviceDB(className, classVersion, deviceLabel, DBnumber, (deviceIndex == 0))
+                DBnumber += 1
+
+        else:             # BLOCK_MODE
+        # Generate the Data-Blocks: one DB per Block of registers
+            for blockIndex, blockDOM in enumerate(blockDOMList):
+                blockName = blockDOM.prop('name')
+
+                deviceList = ''
+                for deviceDOM in deviceDOMList:
+                    deviceLabel = deviceDOM.prop('label')
+                    deviceList += s7template.stlDevice(deviceLabel, className, blockName)
+
+                stlString += s7template.generateBlock(deploy.owner, className, classVersion, deploy.plcSystem, DBnumber, blockName, deviceList, (blockIndex == 0),deploy.plcProtocol)
+                symString += s7template.symBlockDB(className, classVersion, blockName, DBnumber, (blockIndex == 0))
+                DBnumber += 1
+
+    # write the String PLC generated code
+    generateControllerFiles(sourceFolderPath,deploy,".scl",stlString,logTopics);
+        
+    # Write the String PLC generated symbols into the <.sdf> symbols file
+    generateControllerFiles(sourceFolderPath,deploy,".sdf",symString,logTopics);
+
+#-------------------------------------------------------------------------
+# SCHNEIDER PLC code generation
+#-------------------------------------------------------------------------
+
+# ----------------------------------------------------
+def generateSchneiderRegisters(xsydoc, classDOM, deviceDOM, blockDOM, deviceIndex, modeDevice, deploy, logTopics):
+    
+    className    = classDOM.prop('name')
+    deviceLabel = deviceDOM.prop('label')
+    blockName    = blockDOM.prop('name')
+    
+    #Device and Block adresses come from the generated Paramerers file. Depends on the protocol mode:
+    #DEVICE_MODE: relative address of the element within it parent node
+    #BLOCK_MODE : absolute address in the entire PLC memory
+    deviceAddress = long(deviceDOM.prop('address'))
+    blockAddress  = long(blockDOM.prop('address'))
+    blockMemSize  = long(blockDOM.prop('mem-size'))
+    registerDOMList = blockDOM.xpathEval("Register") # get Registers of the current block
+    for registerIndex,registerDOM in enumerate(registerDOMList):
+        registerName = registerDOM.prop('name')
+        registerFormat = registerDOM.prop('format')
+        registerDimension1 = long(registerDOM.prop('array-dim1'))
+        registerDimension2 = long(registerDOM.prop('array-dim2'))
+
+        # If PLC does not supports this register format abort this generation and log the error
+        if(registerFormat in ['uint64','int64','float64']):
+            iecommon.logError('ERROR: In register '+registerName+', '+registerFormat+' format not supported for current controller model.', True,logTopics)
+        
+        #register has relative address irrespective of the protocol mode.
+        registerOffset = long(registerDOM.prop('address'))
+        
+        # Compute the Register address relying on the Class Parameters file data
+        # Attention! Schneider uses WORD addressing while Parameters data are expressed in bytes to be PLC independent
+        if modeDevice:
+            registerAddress = (deviceAddress + blockAddress + registerOffset)/2
+        else:
+            registerAddress = (blockAddress + (deviceIndex * blockMemSize) + registerOffset)/2
+              
+        # then insert the corresponding DOM element
+        dataElt = xsydoc.xpathEval("//dataBlock")[0] #only one dataBlock node has been inserted so far
+        regElt  = libxml2.newNode('variables')
+        # Compute the base checksum of the class name
+        classNameCRC = zlib.crc32(className,0) & 0xffff
+        # Create register name = regname_crc32(classname)_deviceid
+        # 24 char (register name) + 1 (underscore) + 4 char (CRC classname) + 1 (underscore) + n (device id) = 30 + n (device id) 
+        # possible problem when device id (n)> 99 --> string > 32 not compatible with Schneider PLCs
+        regElt.setProp("name", "%s_%04x_%s" %(registerName, classNameCRC, deviceLabel))
+        
+        if registerFormat == 'string':
+            regElt.setProp("typeName", "%s" %xsyRegister(registerFormat, registerDimension1, registerDimension2, registerDOM.prop('string-len')))
+        else:
+            regElt.setProp("typeName", "%s" %xsyRegister(registerFormat, registerDimension1, registerDimension2))
+        
+            
+        regElt.setProp("topologicalAddress", "%%MW%ld" %registerAddress)
+        if blockName == 'hdrBlk':
+            initElt = libxml2.newNode('variableInit')
+            if registerName == '_version': initElt.setProp("value", deploy.silecsVersion )
+            if registerName == '_user'   : initElt.setProp("value", deploy.owner)
+            if registerName == '_checksum': initElt.setProp("value", "%s" %deploy.checksum)
+            if registerName == '_date'  : initElt.setProp("value", getDateTime())
+            regElt.addChild(initElt)
+        commElt    = libxml2.newNode('comment')
+        commElt.setContent(className+"/"+deviceLabel+"/"+blockName)
+        regElt.addChild(commElt)
+        dataElt.addChild(regElt)
+        
+# ----------------------------------------------------
+def generateSchneiderSources(paramDOM,sourceFolderPath,logTopics):
+    #Base address provided by the user in the Deployment relies on the PLC model:  
+    #Quantum, Premium and M340 Schneider PLCs are all interpreted as using 16-bit addressing, 
+    #even though M340 addresses are later properly considered as 32-bit addresses
+    
+    deploy = getDeploymentInformation(paramDOM)
+
+    # Create the Schneider DOM source (Unity <.XSY> XML document)
+    xsyDoc  = libxml2.newDoc(version='1.0')
+    rootElt = libxml2.newNode('VariablesExchangeFile')
+    xsyDoc.addChild(rootElt)
+    dataElt = libxml2.newNode('dataBlock')
+    rootElt.addChild(dataElt)
+   
+    classNodes = paramDOM.xpathEval("/SILECS-Param/SILECS-Mapping/SILECS-Class")
+    for classNode in classNodes:
+        address     = int(classNode.prop('address')) #address of the first register of the configuration
+        blockDOMList  = classNode.xpathEval("Block") # get Blocks elements of that class
+        deviceDOMList = classNode.xpathEval("Instance") # get Device instances of that class
+        
+        for blockDOM in blockDOMList:
+            for deviceIndex,deviceDOM in enumerate(deviceDOMList):
+                if deploy.plcProtocol == 'DEVICE_MODE': #-------------------
+                    generateSchneiderRegisters(xsyDoc, classNode, deviceDOM, blockDOM, deviceIndex, True, deploy, logTopics)
+                else:            
+                    generateSchneiderRegisters(xsyDoc, classNode, deviceDOM, blockDOM, deviceIndex, False, deploy, logTopics)
+    
+    # Finally, write the DOM object (PLC generated code) into the XSY source file
+    generateControllerFiles(sourceFolderPath,deploy,".xsy",rootElt.serialize(format = True),logTopics);
+
+    xsyDoc.freeDoc()      
+    
+# ----------------------------------------------------
+def generateRabbitSources(paramDOM,sourceFolderPath,logTopics):   
+    deviceLabel = ''
+
+    deploy = getDeploymentInformation(paramDOM)
+
+    # Prepare the source (<.h> file) with its diagnostic data-block header
+    cCodeString =  rabbitTemplate.cHeader(deploy.address,deploy.silecsVersion)
+    cTypeDefinitions = ''
+    cDataAllocation  = rabbitTemplate.cAllocationComment(deploy.plcProtocol)
+    
+    blockList = ''
+    classList = ''
+    NBdeviceDefinitionList = ''
+
+    classNodes = paramDOM.xpathEval("/SILECS-Param/SILECS-Mapping/SILECS-Class")
+    for classNode in classNodes:
+        blockDOMList  = classNode.xpathEval("Block")    # get Blocks elements of that class
+        deviceDOMList = classNode.xpathEval("Instance") # get Device instances of that class
+        
+        className        = classNode.prop('name')
+        classVersion    = classNode.prop('version')
+
+        deviceNumber = len(deviceDOMList)
+
+        #==== Generate the Blocks definition ====
+        for blockIndex, blockDOM in enumerate(blockDOMList):
+            registerList = ''
+            blockName = blockDOM.prop('name')
+            registerDOMList = blockDOM.xpathEval("Register") # get Registers of the current block
+            for registerIndex, registerDOM in enumerate(registerDOMList):
+                registerName = registerDOM.prop('name')
+                registerFormat = registerDOM.prop('format')
+                registerDimension1 = long(registerDOM.prop('array-dim1'))
+                registerDimension2 = long(registerDOM.prop('array-dim2'))
+                
+                # If PLC does not supports this register format abort this generation and log the error
+                if(registerFormat in ['float64']):
+                    iecommon.logError('ERROR: In register '+registerName+', '+registerFormat+' format not supported for current controller model.', True,logTopics)
+                
+                if(registerFormat == 'string'):
+                    registerList += rabbitTemplate.cRegister(registerName, registerFormat, registerDimension1, registerDimension2, long(registerDOM.prop('string-len')))
+                else:
+                    registerList += rabbitTemplate.cRegister(registerName, registerFormat, registerDimension1, registerDimension2)    
+
+            cTypeDefinitions += rabbitTemplate.cBlockUDT(className, classVersion, blockName, registerList, (blockIndex == 0))
+            
+        #==== Memory allocation ====
+        if deploy.plcProtocol == 'DEVICE_MODE':
+            # Generate the List of block in the class
+            blockList =''
+            for blockIndex, blockDOM in enumerate(blockDOMList):
+                blockName = blockDOM.prop('name')
+                blockList += rabbitTemplate.cDeviceModeBlockInstantiation(className, blockName)
+
+            deviceList = ''
+            for deviceDOM in deviceDOMList:
+                deviceLabel = className + "_" + deviceDOM.prop('label')
+                deviceList += deviceLabel + ', ';
+            deviceList = deviceList[:-2]  # remove last comma space
+            classList += rabbitTemplate.cDeviceModeClass_deviceList(blockList, deviceList)
+
+
+        else:  # BLOCK_MODE
+            # Generate the List of block in the class
+            for blockIndex, blockDOM in enumerate(blockDOMList):
+                # create instantation for current block
+                blockName = blockDOM.prop('name')
+
+                deviceList = ''
+                for deviceDOM in deviceDOMList:
+                    deviceLabel = deviceDOM.prop('label')
+                    deviceList +=rabbitTemplate.cBlockModeDeviceInstantiation_deviceList(className, blockName, deviceLabel)
+
+                blockList += rabbitTemplate.cBlockModeBlockInstantiation(deviceList, className, blockName)
+
+    # Predefine number of devices constant
+    cDataAllocation += NBdeviceDefinitionList                
+
+    if deploy.plcProtocol == 'DEVICE_MODE':
+        cDataAllocation += rabbitTemplate.cDeviceModeDataInstantiation(classList)
+        cInitFunction    = rabbitTemplate.cInitDeviceMode(deploy.silecsVersion,deploy.checksum,deploy.owner)
+    else:
+        cDataAllocation += rabbitTemplate.cBlockModeDataInstantiation(blockList)
+        cInitFunction    = rabbitTemplate.cInitBlockMode(deploy.silecsVersion,deploy.checksum,deploy.owner)
+    
+            
+    # Append data definitions
+    cCodeString += cTypeDefinitions
+    
+    # Append data allocation
+    cCodeString += cDataAllocation
+    
+    # Append initialization function
+    cCodeString += cInitFunction
+    
+    # Generate and append sample example
+    cCodeString += rabbitTemplate.cExample(deploy.plcProtocol,True,className, blockName, registerName, deviceLabel)
+    
+    # Finally, write the String C generated code into the temporal output file
+    generateControllerFiles(sourceFolderPath,deploy,".h",cCodeString,logTopics);
+
+
+# ----------------------------------------------------
+def generateVirtualS7Sources(paramDOM,sourceFolderPath,logTopics):   
+    deploy = getDeploymentInformation(paramDOM)
+    includeDesign  = ''
+    allocDesign  = ''
+    deleteDesign = ''
+    getDesign = ''
+
+    protocolMode = 'BlockMode'; 
+    if deploy.plcProtocol == 'DEVICE_MODE':
+        protocolMode = 'DeviceMode';
+    duConstructor = virtualS7Template.vs7DuConstructor(deploy.plcName, protocolMode, deploy.address)
+    
+    classNodes = paramDOM.xpathEval("/SILECS-Param/SILECS-Mapping/SILECS-Class")
+    
+    # Generate sources for each class that is deployed in the PLC
+    for classNode in classNodes:
+    
+        blocksCodeString = ''
+         
+        createBlockCodeString = '' 
+        deleteBlockCodeString = '' 
+        deviceCodeString = ''
+         
+        createDeviceCodeString = '' 
+        deleteDeviceCodeString = '' 
+        designCodeString = ''
+         
+        blockDOMList  = classNode.xpathEval("Block")    # get Blocks elements of that class
+        deviceDOMList = classNode.xpathEval("Instance") # get Device instances of that class
+        
+        className = classNode.prop('name')
+        classVersion = classNode.prop('version')
+    
+        #DEPLOY-UNIT code generation ============================
+        includeDesign += virtualS7Template.vs7DuDesignInclude(className, classVersion)   
+        allocDesign += virtualS7Template.vs7DuDesignAlloc(className, classVersion)   
+        deleteDesign += virtualS7Template.vs7DuDesignDelete(className)
+        getDesign += virtualS7Template.vs7DuDesignGet(className, classVersion)
+
+        #CLASSES code generation ================================
+        for blockIndex, blockDOM in enumerate(blockDOMList):
+            getSetCodeString = ''
+            dimsCodeString   = ''
+            dataCodeString   = ''
+            
+            currentRegisterAddress = 0  #used to compute even/odd adress and insert align data by adding dummy registers
+            previousRegisterMemSize = 0 #...
+            dummyIndex = 0;
+             
+            blockName = blockDOM.prop('name')
+            blockOffset = blockDOM.prop('address')
+            registerDOMList = blockDOM.xpathEval("Register") # get Registers of the current block
+            
+            createBlockCodeString += virtualS7Template.vs7ClassCreateBlock(className, blockName)
+            deleteBlockCodeString += virtualS7Template.vs7ClassDeleteBlock(className, blockName)
+            
+            for registerIndex, registerDOM in enumerate(registerDOMList):
+                registerName = registerDOM.prop('name')
+                registerFormat = registerDOM.prop('format')
+                registerDimension1 = long(registerDOM.prop('array-dim1'))
+                registerDimension2 = long(registerDOM.prop('array-dim2'))
+                registerMemSize = long(registerDOM.prop('mem-size')) #store the reigster mem-size for next iteration
+                
+                registerLength = 1  #in case string 
+                if(registerFormat == 'string'):
+                    registerLength = long(registerDOM.prop('string-len'))
+            
+                getSetCodeString += virtualS7Template.vs7ClassGetSet(registerName, registerFormat, registerDimension1, registerDimension2,registerLength)
+                dimsCodeString += virtualS7Template.vs7ClassDimension(registerName, registerFormat, registerDimension1, registerDimension2,registerLength)
+
+                #Specific code to force 16bit alignment if not scalar 8bit register (==> insert dummy register if needed)
+                dummyCodeString = virtualS7Template.vs7ClassDummyRegister(currentRegisterAddress, previousRegisterMemSize, registerMemSize, dummyIndex)
+                dataCodeString += dummyCodeString
+                currentRegisterAddress += registerMemSize 
+                if dummyCodeString != "":
+                    dummyIndex += 1
+                    currentRegisterAddress += 1     
+                #and now insert the normal data register     
+                dataCodeString += virtualS7Template.vs7ClassDataRegister(registerName, registerFormat, registerDimension1, registerDimension2, registerLength)
+                previousRegisterMemSize = registerMemSize 
+                
+            blocksCodeString += virtualS7Template.vs7ClassBlock(deploy.silecsVersion, deploy.owner, deploy.checksum, className, blockName, getSetCodeString, blockOffset, dimsCodeString, dataCodeString)
+
+        for deviceIndex, deviceDOM in enumerate(deviceDOMList):
+            deviceLabel = deviceDOM.prop('label')
+            createDeviceCodeString += virtualS7Template.vs7ClassCreateDevice(className, deviceLabel, deviceIndex)
+            deleteDeviceCodeString += virtualS7Template.vs7ClassDeleteDevice(className, deviceLabel)
+        
+        deviceCodeString = virtualS7Template.vs7ClassDevice(createBlockCodeString, deleteBlockCodeString)
+        designCodeString = virtualS7Template.vs7ClassDesign(className, classVersion, createDeviceCodeString, deleteDeviceCodeString)
+        
+        classCodeString = virtualS7Template.vs7ClassHeader(className, classVersion, blocksCodeString, deviceCodeString, designCodeString)
+            
+        # write the CLASS generated code into the temporal output file
+        generateControllerFiles(sourceFolderPath,deploy, "." + className + ".h",classCodeString,logTopics);
+    
+    # Prepare the source (<.h> file) with its diagnostic data-block header
+    duCodeString = virtualS7Template.vs7DuHeader(deploy.plcName, duConstructor, includeDesign, allocDesign, deleteDesign, getDesign)    
+             
+    # Write the DEPLOY-UNIT generated code into the temporal output file
+    generateControllerFiles(sourceFolderPath,deploy,".h",duCodeString,logTopics);
+             
+    # Prepare the source (<.h> file) with its diagnostic data-block header
+    mainCodeString = virtualS7Template.vs7MainCode(deploy.plcName)
+        
+    # write the DEPLOY-UNIT generated code into the temporal output file
+    generateControllerFiles(sourceFolderPath,deploy,".cpp",mainCodeString,logTopics);
+    
+# ----------------------------------------------------
+def generateBeckhoffRegisters(classDOM, deviceDOM, blockDOM, deviceIndex, deploy, logTopics):
+    source = ''    
+    className    = classDOM.prop('name')
+    deviceLabel = deviceDOM.prop('label')
+    blockName    = blockDOM.prop('name')
+    
+    #Device and Block adresses come from the generated Paramerers file. Depends on the protocol mode:
+    #DEVICE_MODE: relative address of the element within it parent node
+    #BLOCK_MODE : absolute address in the entire PLC memory
+    deviceAddress = long(deviceDOM.prop('address'))
+    blockAddress  = long(blockDOM.prop('address'))
+    blockMemSize  = long(blockDOM.prop('mem-size'))
+
+    registerDOMList = blockDOM.xpathEval("Register") # get registers of the current block
+    
+    for registerIndex, registerDOM in enumerate(registerDOMList):
+        registerName = registerDOM.prop('name')
+        registerFormat = registerDOM.prop('format')
+        registerDimension1 = long(registerDOM.prop('array-dim1'))
+        registerDimension2 = long(registerDOM.prop('array-dim2'))
+        
+        if registerDOM.prop('string-len'):  # only appears for string registers
+            registerLength = long(registerDOM.prop('string-len'))
+        
+        if blockName == 'hdrBlk':
+            if registerName == 'ieVersion' or registerName == 'ieUser':
+                registerFormat = 'string'
+                registerDimension1 = 1
+    
+        # If PLC does not supports this register format abort this generation and log the error
+        if(registerFormat in ['uint64','int64','float64']):
+            iecommon.logError('ERROR: In register '+registerName+', '+registerFormat+' format not supported for current controller model.', True)
+            return
+    
+        #register has relative address irrespective of the protocol mode.
+        registerOffset = long(registerDOM.prop('address'))
+        iecommon.logDebug("Processing: %s %s %s %s" %(className, deviceLabel, blockName, registerName))
+
+        # Compute the register address relying on the Class Parameters file data
+        # Attention! Beckhoff uses WORD addressing while Parameters data are expressed in bytes to be PLC independent
+        if deploy.plcModel == 'BC9020':
+            registerAddress = (blockAddress - long(deploy.address) + (deviceIndex * blockMemSize) + registerOffset)/2
+        elif deploy.plcModel == 'CX9020':
+            registerAddress = (blockAddress - long(deploy.address) + (deviceIndex * blockMemSize) + registerOffset)
+        else:
+            raise "PLC model not supported: " + deploy.plcModel
+
+        # add comment to source to identify block
+        source += '    (*'+className+'/'+deviceLabel+'/'+blockName+' *)\r\n'
+        
+        # Compute the base checksum of the class name
+        classNameCRC = zlib.crc32(className,0) & 0xffff
+        
+        if blockName == 'hdrBlk':
+            if registerName == '_version':
+                source+=beckhoffRegInit %(registerName, classNameCRC, deviceLabel, registerAddress, whichTwincatFormat[registerFormat]+"(16)", deploy.silecsVersion )
+            if registerName == '_user':
+                source+=beckhoffRegInit %(registerName, classNameCRC, deviceLabel, registerAddress, whichTwincatFormat[registerFormat]+"(16)", "'"+deploy.owner+"'") 
+            if registerName == '_checksum':
+                source+=beckhoffRegInit %(registerName, classNameCRC, deviceLabel, registerAddress, whichTwincatFormat[registerFormat], deploy.checksum)
+            if registerName == '_date':
+                source+=beckhoffRegInit %(registerName, classNameCRC, deviceLabel, registerAddress, whichTwincatFormat[registerFormat], getDateTime())
+        
+        else:   # not header block
+             # set data type - for string with fixed value registerLength
+            if registerFormat == 'string':
+                format = whichTwincatFormat[registerFormat]+'('+str(registerLength)+')'
+            else:
+                format = whichTwincatFormat[registerFormat]
+                
+            if registerDimension1 == 1 and registerDimension2 == 1:    # scalar
+                source += beckhoffReg %(registerName, classNameCRC, deviceLabel, registerAddress, format)
+            elif registerDimension1 > 1 and registerDimension2 == 1: # array
+                source += beckhoffRegArray %(registerName, classNameCRC, deviceLabel, registerAddress, registerDimension1-1, format)
+            else:   # dim1>=1 and for whatever dim2, use double array syntax
+                source += beckhoffRegArray2d %(registerName, classNameCRC, deviceLabel, registerAddress, registerDimension1-1, registerDimension2-1, format)
+                    
+    return source
+# ----------------------------------------------------
+def generateBeckhoffSources(paramDOM, sourceFolderPath, logTopics):
+    deploy = getDeploymentInformation(paramDOM)
+    
+    # Prepare the global variables source (<.exp> file) with its diagnostic data-block header
+    source ="""(* +-------------------------------------------------------------------\r\n"""
+    source += """* | C.E.R.N Geneva, Switzerland\r\n"""
+    source += """* | SILECS - BE/CO-FE\r\n"""
+    source += """* | April 2015\r\n"""
+    source += """* +-------------------------------------------------------------------\r\n"""
+    source += """*\r\n"""
+    source += """* Release : SILECS_%s\r\n"""%(deploy.silecsVersion)
+    source += """*)"""
+        
+    source += '\r\nVAR_GLOBAL\r\n'
+
+    classNodes = paramDOM.xpathEval("/SILECS-Param/SILECS-Mapping/SILECS-Class")
+    for classNode in classNodes:
+        address = int(classNode.prop('address')) # address of the first register of the configuration
+        blockDOMList = classNode.xpathEval("Block") # get Blocks elements of that class
+        deviceDOMList = classNode.xpathEval("Instance") # get Device instances of that class
+            
+        # Device mode is not supported for Beckhoff PLCs - Only block mode available
+        for blockDOM in blockDOMList:
+            for deviceIndex, deviceDOM in enumerate(deviceDOMList):
+                source += generateBeckhoffRegisters(classNode, deviceDOM, blockDOM, deviceIndex,deploy,logTopics)
+                
+    source += 'END_VAR'
+
+    # Write the source into the EXP source file
+    generateControllerFiles(sourceFolderPath,deploy,".exp",source,logTopics);
+
+#-------------------------------------------------------------------------
+# NI code generation
+#-------------------------------------------------------------------------
+def generateNISources(paramDOM, sourceFolderPath ,logTopics):
+    iecommon.logInfo("PLC source generation not available for National Instruments equipment",logTopics)
+    return
+
+def getDeploymentInformation(paramDOM):
+    deploy = Deploy()
+    mapping = paramDOM.xpathEval("/SILECS-Param/SILECS-Mapping")[0] 
+
+    deploy.plcModel    = mapping.prop('plc-model')
+    deploy.plcSystem    = mapping.prop('plc-system')
+    deploy.plcProtocol = mapping.prop('protocol')
+    deploy.plcName = mapping.prop('plc-name')
+    deploy.address = mapping.prop('address')
+    ownerNode = paramDOM.xpathEval("/SILECS-Param/Mapping-Info/Owner")[0] 
+    deploy.owner = ownerNode.prop('user-login')
+    deploymentNode = paramDOM.xpathEval("/SILECS-Param/Mapping-Info/Deployment")[0] 
+    deploy.checksum = long(deploymentNode.prop('checksum'))
+    rootNode = paramDOM.xpathEval("/SILECS-Param")[0] 
+    deploy.silecsVersion = rootNode.prop("silecs-version")
+    return deploy
+
+def generateControllerFiles(sourceFolderPath,deploy,fileExtention,source,logTopics={'errorlog': True}):
+    fileName = deploy.plcName + fileExtention
+    fullFilePath = os.path.normpath(sourceFolderPath + "/" + fileName )
+
+    iecommon.logInfo("Generate PLC sources: %s" %fullFilePath,logTopics);
+    fdesc = open(fullFilePath, "w")
+    fdesc.write(source)
+    fdesc.close()
+
+# Needed for unit-testing
+def generateControllerCode(controllerNode, paramsFile, sourceFolderPath, logTopics={'errorlog': True}):
+    paramDOM = libxml2.parseFile(paramsFile)
+    plcNode  = controllerNode.xpathEval("*[@system]")[0]
+    if plcNode.get_name() == 'Siemens-PLC':
+        generateSiemensSources(paramDOM,sourceFolderPath,logTopics)
+    elif plcNode.get_name() == 'Virtual-Controller':
+        generateVirtualS7Sources(paramDOM,sourceFolderPath,logTopics)
+    elif plcNode.get_name() == 'Schneider-PLC':
+        generateSchneiderSources(paramDOM,sourceFolderPath,logTopics)
+    elif plcNode.get_name() == 'Rabbit-uC':
+        generateRabbitSources(paramDOM,sourceFolderPath,logTopics)
+    elif plcNode.get_name() == 'Beckhoff-PLC':
+        generateBeckhoffSources(paramDOM,sourceFolderPath,logTopics)
+    elif plcNode.get_name() == 'NI-Controller':
+        generateNISources(paramDOM,sourceFolderPath,logTopics)
+    else:
+        iecommon.logError("The PLC-Type %s is not supported" %plcNode.get_name(), True,logTopics)
+    paramDOM.freeDoc()
+
+#=========================================================================
+# Entry Point
+#=========================================================================
+def genPlcSrc(workspacePath, deployName,silecsVersion,logTopics={'errorlog': True}):
+    deployFilePath = iefiles.getSilecsDeployFilePath(workspacePath,deployName)
+    deployDOM = libxml2.parseFile(deployFilePath)
+    iecommon.logInfo("Load Deployment document: %s" %deployFilePath,logTopics);
+
+    # Create the source folder if needed
+    sourceFolderPath = iefiles.getControllerSourcesDirectory(workspacePath, deployName)
+    if not os.path.exists(sourceFolderPath):
+        os.makedirs(sourceFolderPath)
+
+    # Add xml of the silecs-header
+    iecommon.addSilecsHeaderToClasses(deployDOM)
+
+    controllerNodes = deployDOM.xpathEval("/SILECS-Deploy/Controller")
+    for controllerNode in controllerNodes:
+        paramsFile = iefiles.getParameterFile(workspacePath, deployName,controllerNode.prop("host-name"))
+        generateControllerCode(controllerNode,paramsFile,sourceFolderPath,logTopics)
+
+    # Clean-up the memory before exit
+    deployDOM.freeDoc()
+    
+    return "Genplcsrc succeded!"
+ 
diff --git a/silecs-codegen/src/xml/genplcsrc.pyc b/silecs-codegen/src/xml/genplcsrc.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b464d27d10be63c988e0e82997dbe55df623daa2
Binary files /dev/null and b/silecs-codegen/src/xml/genplcsrc.pyc differ
diff --git a/silecs-codegen/src/xml/iecommon$py.class b/silecs-codegen/src/xml/iecommon$py.class
new file mode 100644
index 0000000000000000000000000000000000000000..73bc5a4470b22842d905bddc5b49d97cb801ed16
Binary files /dev/null and b/silecs-codegen/src/xml/iecommon$py.class differ
diff --git a/silecs-codegen/src/xml/iecommon.py b/silecs-codegen/src/xml/iecommon.py
new file mode 100644
index 0000000000000000000000000000000000000000..ab625ffc1885e965b8166c77a6a86c62c435f51e
--- /dev/null
+++ b/silecs-codegen/src/xml/iecommon.py
@@ -0,0 +1,266 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import time
+import re
+import os
+import sys
+import getpass
+import codecs
+import commands
+
+import iecommon
+import libxml2
+
+#==================================================================
+# LOGGING
+#==================================================================
+def logHeader(level):
+    global project, program
+    _time = time.strftime("%Y/%m/%d-%H:%M:%S")
+    program = sys.argv[0]
+    return "[%s SILECS %s %s] " %(_time, program, level)
+
+def logError(msg, exit,logTopics={}):
+    if 'errorlog' in logTopics:
+        if logTopics['errorlog'] == True:
+            _logMsg = "%s%s" %(logHeader("ERROR"), msg)
+            print _logMsg
+            if exit:
+                raise Exception(_logMsg)
+
+def logInfo(msg,logTopics={}):
+    if 'infolog' in logTopics:
+        if logTopics['infolog'] == True:
+            _logMsg = "%s%s" %(logHeader("INFO"), msg)
+            print _logMsg
+    
+def logDebug(msg,logTopics={}):   
+    if 'debuglog' in logTopics:
+        if logTopics['debuglog'] == True:
+            _logMsg = "%s%s" %(logHeader("DEBUG"), msg)
+            print _logMsg
+            
+# Append message to a text file
+def logToFile(path,msg):
+    with open(path, "a") as logFile:
+        logFile.write(logHeader("CMD") + msg + "\n")           
+#-------------------------------------------------------------------------
+# General XML Parsing
+#-------------------------------------------------------------------------
+def hasChildren(element):
+    children = element.xpathEval("*")
+    if len(children):
+        return True
+    return False
+
+def getFirstChild(element):
+    return element.xpathEval("*")[0]
+
+def isChildElement(node,elementName):
+    if not type(elementName) is str:
+        raise Exception("Error: Wrong Type Parsed")
+    for subnode in node:
+        if subnode.get_name() == elementName:
+            return True
+    return False
+
+def getChildElement(node,elementName):
+    for subnode in node:
+        if subnode.get_name() == elementName:
+            return subnode
+    return null
+
+def getOrCreateChildElement(node,elementName):
+    namedChilds = node.xpathEval(elementName)
+    if len(namedChilds):
+        return namedChilds[0]
+    newElement = libxml2.newNode(elementName)
+    node.addChild(newElement)
+    return newElement
+
+def getOrCreateNamedChildElement(node,elementName, attributeNameValue, attributeName="name"):
+    elements = node.xpathEval(elementName + "[@" + attributeName + "='" + attributeNameValue + "']")
+    if len(elements):
+        return elements[0]
+    newNode = libxml2.newNode(elementName)
+    node.addChild(newNode)
+    newNode.setProp(attributeName, attributeNameValue)
+    return newNode
+
+def getOrCreateNamedPreviousSiblingElement(parent,node,elementName, attributeNameValue):
+    alreadyAvailable = node.get_parent().xpathEval(elementName + "[@name='" + attributeNameValue + "']")
+    if len(alreadyAvailable):
+        return alreadyAvailable[0]
+    newNode = libxml2.newNode(elementName)
+    node.addPrevSibling(newNode)
+    newNode.setProp("name", attributeNameValue)
+    return newNode
+
+def getOrCreatePreviousSiblingElement(node,elementName):
+    alreadyAvailable = node.get_parent().xpathEval(elementName)
+    if len(alreadyAvailable):
+        return alreadyAvailable[0]
+    iecommon.logDebug("Not Found: Name:"+ elementName, {'debuglog': True})
+    newNode = libxml2.newNode(elementName)
+    node.addPrevSibling(newNode)
+    return newNode
+
+def getOrCreateNamedFirstChild(parent,elementName, attributeNameValue):
+    elements = parent.xpathEval(elementName + "[@name='" + attributeNameValue + "']")
+    if len(elements):
+        return elements[0]
+    newNode = libxml2.newNode(elementName)
+    newNode.setProp('name', attributeNameValue)
+    if parent.get_children():
+        firstChild = parent.xpathEval("*")[0]
+        firstChild.addPrevSibling(newNode)
+    else:
+        parent.addChild(newNode)
+    return newNode
+
+def fillAttributes(element, attrs):
+    for name,value in attrs.iteritems():
+        if not type(value) is str:
+            raise Exception("Error: Wrong Type Parsed for attribute: " + name)
+        element.setProp(name, value)
+    return element
+
+#-------------------------------------------------------------------------
+# Given an SILECS data type, returns the corresponding FESA data type
+# For the time being FESA does not support unsigned data types in properties
+# so here unsigned types are considered as signed to allow users to link
+# any field to properties
+#-------------------------------------------------------------------------
+def getFesaDataType(type):
+    return  {
+             'int8'     :'int8_t',
+             'uint8'    :'int16_t',
+             'int16'    :'int16_t',
+             'uint16'   :'int32_t',
+             'int32'    :'int32_t',
+             'uint32'   :'int64_t',
+             'int64'    :'int64_t',
+             'uint64'   :'uint64_t',  # only for PXI, but not supported from Java! Not possible to use it in FESA properties
+             'float32'  :'float',
+             'float64'  :'double',
+             'date'     :'double',
+             'char'     :'int8_t',
+             'byte'     :'int16_t',
+             'word'     :'int32_t',
+             'dword'    :'int64_t',
+             'int'      :'int16_t',
+             'dint'     :'int32_t',
+             'real'     :'float',
+             'dt'       :'double',
+             'string'   :'char'
+    }[type]
+
+def getCDataType(type):
+    return  {
+             'int8'     :'int8_t',
+             'uint8'    :'uint8_t',
+             'int16'    :'int16_t',
+             'uint16'   :'uint16_t',
+             'int32'    :'int32_t',
+             'uint32'   :'uint32_t',
+             'int64'    :'int64_t',
+             'uint64'   :'uint64_t',
+             'float32'  :'float',
+             'float64'  :'double',
+             'date'     :'double',
+             'char'     :'int8_t',
+             'byte'     :'int16_t',
+             'word'     :'int32_t',
+             'dword'    :'int64_t',
+             'int'      :'int16_t',
+             'dint'     :'int32_t',
+             'real'     :'float',
+             'dt'       :'double',
+             'string'   :'std::string'
+    }[type]
+#-------------------------------------------------------------------------
+# Given data type, returns the corresponding
+# SILECS data type
+#-------------------------------------------------------------------------
+def getSilecsDataType(type):
+    return {
+            'byte'          :'uint8',
+            'char'          :'int8',
+            'unsigned char' :'uint8',
+            'short'         :'int16',
+            'unsigned short':'uint16',
+            'long'          :'int32',   # conversion relies on 32-bit platform (FESA 3 does not support long type anymore)
+            'unsigned long' :'uint32',    
+            'double'        :'float64',
+            'float'         :'float32',
+            'word'          :'uint16',
+            'dword'         :'uint32',
+             'int'          :'int16',
+             'dint'         :'int32',
+             'real'         :'float32',
+             'dt'           :'date',
+             'uint8'        :'uint8',
+             'int8'         :'int8',
+             'uint16'       :'uint16',
+             'int16'        :'int16',
+             'uint32'       :'uint32',
+             'int32'        :'int32',
+             'uint64'       :'uint64',
+             'int64'        :'int64',
+             'float32'      :'float32',
+             'float64'      :'float64',
+             'date'         :'date',
+             'string'       : 'string'
+    }[type]
+
+def capitalizeString(text):
+    str = ""
+    if len(text) > 0:
+        str += text[0].upper()
+        str += text[1:]
+    return str
+    
+def addSilecsHeaderToClasses(silecsDeployDOM):
+    controllers = silecsDeployDOM.xpathEval("/SILECS-Deploy/Controller")
+    for controller in controllers:
+        silecsHeaderDesign = libxml2.newNode("SilecsDesign")
+        silecsHeaderDesign.setProp("silecs-design-name","SilecsHeader")
+        silecsHeaderDesign.setProp("silecs-design-version","1.0.0")
+        silecsHeaderDevice = libxml2.newNode("Device")
+        silecsHeaderDevice.setProp("device-name","SilecsHeader")
+        silecsHeaderDesign.addChild(silecsHeaderDevice)
+        silecsDesigns = controller.xpathEval("SilecsDesign")
+        silecsDesigns[0].addPrevSibling(silecsHeaderDesign)
+
+#Major changes: Public API, database and PLC code generation may be impacted
+def getMajorSilecsVersion(silecsVersionString):
+    firstDot = silecsVersionString.find('.')
+    return silecsVersionString[0:firstDot]
+
+#Minor changes: New functionality: backward-compatible
+def getMinorSilecsVersion(silecsVersionString):
+    firstDot = silecsVersionString.find('.')
+    secondDot = silecsVersionString.find('.',firstDot)
+    return silecsVersionString[firstDot:secondDot]
+
+#Patches and bug fixes: backward compatible
+def getPatchSilecsVersion(silecsVersionString):
+    firstDot = silecsVersionString.find('.')
+    secondDot = silecsVersionString.find('.',firstDot)
+    return silecsVersionString[secondDot:]
+
+
diff --git a/silecs-codegen/src/xml/iecommon.pyc b/silecs-codegen/src/xml/iecommon.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..92d8bb839a079022be36fa9469b02be5aa5becaa
Binary files /dev/null and b/silecs-codegen/src/xml/iecommon.pyc differ
diff --git a/silecs-codegen/src/xml/iefiles$py.class b/silecs-codegen/src/xml/iefiles$py.class
new file mode 100644
index 0000000000000000000000000000000000000000..7b345d46fd3c9e971520e54afcae82c16cefcc37
Binary files /dev/null and b/silecs-codegen/src/xml/iefiles$py.class differ
diff --git a/silecs-codegen/src/xml/iefiles.py b/silecs-codegen/src/xml/iefiles.py
new file mode 100644
index 0000000000000000000000000000000000000000..6b52f876f664c0cd2734aa10220359026f0dc5a1
--- /dev/null
+++ b/silecs-codegen/src/xml/iefiles.py
@@ -0,0 +1,140 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import iecommon
+import xmltemplate
+import socket
+
+import os
+import fnmatch
+import shutil
+
+designFormat    = '.silecsdesign'
+deployFormat    = '.silecsdeploy'
+paramFormat     = '.silecsparam'
+
+generatedDir    = 'generated'
+clientDir       = 'client'
+controllerDir   = 'controller'
+wrapperDir      = 'wrapper'
+
+#==================================================================
+# FILE ACCESS 
+#==================================================================
+
+def saveXMLToFile(filePath,xmlDoc):
+    with open(filePath, 'w') as fd:
+        xmlDoc.saveTo(fd,format = True)
+        #xmlDoc.saveTo(fd,"UTF-8",libxml2.XML_SAVE_NO_EMPTY) # it seems like there is a bug in libxml2  XML_SAVE_NO_EMPTY does the job of XML_SAVE_FORMAT
+            
+#--- DESIGN ---
+
+def getSilecsDesignFileDir(workspacePath, projectName):
+	path = workspacePath + "/" + projectName + "/src"
+	return  os.path.normpath(path)
+
+def getSilecsDesignFilePath(workspacePath, projectName):
+	path = getSilecsDesignFileDir(workspacePath, projectName) + "/" + projectName + designFormat;
+	return  os.path.normpath(path)
+
+def newDesignProject(workspacePath, designName, schemaPath, silecsVersion ):
+    designDir = getSilecsDesignFileDir(workspacePath,designName)
+    designFile = getSilecsDesignFilePath(workspacePath,designName)
+    if(os.path.isfile(designFile)):
+        raise Exception("Design %s already exists in current workspace" % designFile)
+    
+    # create src directory
+    os.makedirs(designDir)
+    # create default design file
+    designText = xmltemplate.getDesignTemplate(designName, schemaPath, silecsVersion)
+    fdesc = open(designFile, "w")
+    fdesc.write(designText)
+    fdesc.close()
+  
+#--- DEPLOY ---
+
+def getSilecsDeployFileDir(workspacePath, projectName):
+	path = workspacePath + "/" + projectName + "/src"
+	return  os.path.normpath(path)
+
+def getSilecsDeployFilePath(workspacePath, projectName):
+	path = getSilecsDeployFileDir(workspacePath, projectName) + "/" + projectName + deployFormat;
+	return  os.path.normpath(path)
+
+def newDeployProject(workspacePath, deployName, schemaPath, silecsVersion):
+    deployDir = getSilecsDeployFileDir(workspacePath, deployName)
+    deployFile = getSilecsDeployFilePath(workspacePath, deployName)
+    if(os.path.isfile(deployFile)):
+        raise Exception("Deploy %s already exists in current workspace" % deployFile)
+    
+    # create src directory
+    os.makedirs(deployDir)
+    # create default deploy file
+    deployText = xmltemplate.getDeployTemplate(deployName, schemaPath, silecsVersion)
+    fdesc = open(deployFile, "w")
+    fdesc.write(deployText)
+    fdesc.close()
+
+#--- PARAMETER ---
+def getParameterFileName(controllerName):
+    return controllerName + paramFormat
+    
+def getParameterFileDirectory(workspacePath, deployName):
+    paramPath = workspacePath + '/' + deployName + '/' + generatedDir + '/' + clientDir
+    paramPathNorm = os.path.normpath(paramPath)
+    return paramPathNorm
+
+def getParameterFile(workspacePath, deployName, controllerName):
+    paramPath = getParameterFileDirectory(workspacePath, deployName) + '/' + getParameterFileName(controllerName)
+    paramPathNorm = os.path.normpath(paramPath)
+    return paramPathNorm
+    
+#--- CONTROLLER SOURCES ---
+def getControllerSourcesDirectory(workspacePath, deployName):
+    controllerPath = workspacePath + '/' + deployName + '/' + generatedDir + '/' + controllerDir
+    controllerNorm = os.path.normpath(controllerPath)
+    return controllerNorm
+
+#--- DU WRAPPER ---
+def getDuWrapperFileName( controllerName ):
+    return iecommon.capitalizeString(controllerName) + ".h"
+
+def getDuWrapperSourceDirectory(workspacePath, deployName):
+    wrapperPath = workspacePath + '/' + deployName + '/' + generatedDir + '/' + wrapperDir
+    wrapperPathNorm = os.path.normpath(wrapperPath)
+    return wrapperPathNorm
+    
+def getDuWrapperFile(workspacePath, deployName, controllerName ):
+    return getDuWrapperSourceDirectory(workspacePath, deployName) + "/" + getDuWrapperFileName(controllerName)
+        
+def getDuDesignWrapperFile(workspacePath, deployName, designName):
+    return getDuWrapperSourceDirectory(workspacePath, deployName) + "/" + getDuWrapperFileName(designName)
+        
+#--- FESA ---
+def getFesa3CommonDirectory(workspacePath, designName):
+    fesa3ClassPath = workspacePath + '/' + designName + '/src/' + designName + '/Common'
+    fesa3ClassPathNorm = os.path.normpath(fesa3ClassPath)
+    return fesa3ClassPathNorm
+
+def getProjectDirectory(workspacePath, designName):
+    path = workspacePath + '/' + designName
+    pathNorm = os.path.normpath(path)
+    return pathNorm
+
+def getFesaDeployFilePath(workspacePath, deployName):
+    path = workspacePath + '/' + deployName + '/src/' + deployName + '.deploy'
+    pathNorm = os.path.normpath(path)
+    return pathNorm
diff --git a/silecs-codegen/src/xml/iefiles.pyc b/silecs-codegen/src/xml/iefiles.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a345a8377c86cae2493acf6236c83962c70f5fc5
Binary files /dev/null and b/silecs-codegen/src/xml/iefiles.pyc differ
diff --git a/silecs-codegen/src/xml/migration/0_10_0to1_0_0.py b/silecs-codegen/src/xml/migration/0_10_0to1_0_0.py
new file mode 100644
index 0000000000000000000000000000000000000000..775ffdbf443957562a8e26c881f427774ff5ec45
--- /dev/null
+++ b/silecs-codegen/src/xml/migration/0_10_0to1_0_0.py
@@ -0,0 +1,92 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import os
+import sys
+
+from migrationBase import MigrationBase
+from migration0_10_0to1_0_0.migrators import *
+
+import libxml2
+import sys
+import FileUtils
+import shutil
+
+class Migration(MigrationBase):
+    def __init__(self, arguments):
+        super(Migration, self).__init__()
+
+    def migrateClass(self, context, projectDir ):
+        modified = designGenerateFesaPropValueItemMigrator(context)
+        return modified
+
+    def migrateDeployUnit(self, context, projectDir ):
+        modified = deploySwapStep7TiaMigrator(context)
+        modified = deployRemoveSilecsHeaderMigrator(context)
+        modified = deployReOrderControllerAndClassesMigrator(context) 
+        self.removeGenCode()
+        self.migrateFESAInstanceFile()
+        return modified
+
+    def backupOldFESAMakeSpecific(self):
+        results = self.parser.parse_args()
+        silecsDocument = results.silecsDocument
+        projectDir = FileUtils.getProjectDir(silecsDocument)
+        makeSpecific = projectDir + "/Makefile.specific"
+        if os.path.isfile(makeSpecific):
+            os.rename(makeSpecific, makeSpecific + ".backup")
+            print("Backed up old FESA Make.specific file: " + makeSpecific)
+
+    def removeGenCode(self):
+        results = self.parser.parse_args()
+        silecsDocument = results.silecsDocument
+        projectDir = FileUtils.getProjectDir(silecsDocument)
+        clientFolder = projectDir + "/generated/client"
+        controllerFolder = projectDir + "/generated/controller"
+        wrapperFolder = projectDir + "/generated/wrapper"
+        if os.path.isdir(clientFolder):
+            shutil.rmtree(clientFolder)
+            print("removed generation folder: " + clientFolder)
+        if os.path.isdir(controllerFolder):
+            shutil.rmtree(controllerFolder)
+            print("removed generation folder: " + controllerFolder)
+        if os.path.isdir(wrapperFolder):
+            shutil.rmtree(wrapperFolder)
+            print("removed generation folder: " + wrapperFolder)
+
+    def migrateFESAInstanceFile(self):
+        results = self.parser.parse_args()
+        silecsDocument = results.silecsDocument
+        projectDir = FileUtils.getProjectDir(silecsDocument)
+        testFolder = projectDir + "/src/test"
+        if not os.path.isdir(testFolder):
+            return
+        for f in os.listdir(testFolder):
+            fecFolder = os.path.join(testFolder, f)
+            if os.path.isdir( fecFolder ):
+                for subFile in os.listdir(fecFolder):
+                    filename, file_extension = os.path.splitext(subFile)
+                    if file_extension == ".instance":
+                        instanceFile = os.path.join(fecFolder, subFile)
+                        print("parsing FESA instancee file: " + instanceFile)
+                        context = self._parse(instanceFile)
+                        if fesaInstanceFileMigrator(context):
+                            self._saveAndBackupFile(context,instanceFile)
+
+if __name__ == "__main__":
+    migration = Migration(sys.argv)
+    migration.migrate()
+    migration.backupOldFESAMakeSpecific()
diff --git a/silecs-codegen/src/xml/migration/0_9_0to0_10_0.py b/silecs-codegen/src/xml/migration/0_9_0to0_10_0.py
new file mode 100644
index 0000000000000000000000000000000000000000..65707fc9dca50dc078e52e5c2cf7a28992f559d3
--- /dev/null
+++ b/silecs-codegen/src/xml/migration/0_9_0to0_10_0.py
@@ -0,0 +1,44 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import os
+import sys
+
+from migrationBase import MigrationBase
+from migration_0_9_0to0_10_0.migrateDeployDeviceNumber import DeployDeviceNumberMigrator
+from migration_0_9_0to0_10_0.migrateDeployDomain import DeployDomainMigrator
+
+import libxml2
+import sys
+
+class Migration(MigrationBase):
+    def __init__(self, arguments):
+        super(Migration, self).__init__()
+        self._deployDomainMigrator = DeployDomainMigrator()
+        self._migrateDeployDeviceNumber = DeployDeviceNumberMigrator()
+
+    def migrateClass(self, context, projectDir ):
+        modified = False
+        return modified
+
+    def migrateDeployUnit(self, context, projectDir ):
+        modified = self._deployDomainMigrator.migrate(context)
+        modified = self._migrateDeployDeviceNumber.migrate(context)
+        return modified
+
+if __name__ == "__main__":
+    migration = Migration(sys.argv)
+    migration.migrate()
diff --git a/silecs-codegen/src/xml/migration/FileUtils.py b/silecs-codegen/src/xml/migration/FileUtils.py
new file mode 100644
index 0000000000000000000000000000000000000000..e1f3b78ca44a677bf8a04a394218592ef9e4adb7
--- /dev/null
+++ b/silecs-codegen/src/xml/migration/FileUtils.py
@@ -0,0 +1,39 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import os
+import shutil
+
+def fileExists(fileName):
+    return os.path.isfile(fileName)
+
+def write(string, filePath):
+    with open(filePath, 'w') as f:
+        f.write(string)
+
+def backupFile(fileName):
+    src = fileName
+    dst = fileName + ".backup"
+    print("Original file backed up by adding '.backup'")
+    shutil.copyfile(src, dst)
+    
+def getExtension(fileName):
+    '''Returns the file extension, dot included'''
+    return fileName[fileName.rfind('.'):]
+
+def getProjectDir(fesaDocument):
+    absPath = os.path.abspath(fesaDocument)
+    return os.path.dirname(os.path.dirname(absPath))
diff --git a/silecs-codegen/src/xml/migration/FileUtils.pyc b/silecs-codegen/src/xml/migration/FileUtils.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3944034d5cfcd9781c89f586bd6dd41b7f3928c1
Binary files /dev/null and b/silecs-codegen/src/xml/migration/FileUtils.pyc differ
diff --git a/silecs-codegen/src/xml/migration/__init__.py b/silecs-codegen/src/xml/migration/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/silecs-codegen/src/xml/migration/__init__.pyc b/silecs-codegen/src/xml/migration/__init__.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c5029dcbd4d713167b91936ce5bee0a56e51fbcf
Binary files /dev/null and b/silecs-codegen/src/xml/migration/__init__.pyc differ
diff --git a/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/DeviceData_PneuDriveDU.instance b/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/DeviceData_PneuDriveDU.instance
new file mode 100644
index 0000000000000000000000000000000000000000..884e19551f50009c88a649e28860bde81a00877b
--- /dev/null
+++ b/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/DeviceData_PneuDriveDU.instance
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<instantiation-unit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:noNamespaceSchemaLocation="file:/common/home/sd/apetit/lnx/workspace/PneuDriveDU/generated/xml/asl730-InstantiationSchemaFEC.xsd">
+	<information>
+		<deploy-unit-name>PneuDriveDU</deploy-unit-name>
+		<deploy-unit-version>0.1.0</deploy-unit-version>
+		<fec-name>asl730</fec-name>
+		<server-name>PneuDriveDU.asl730</server-name>
+		<timestamp>22/03/2016 11:13</timestamp>
+		<fesa-version>3.0.0</fesa-version>
+	</information>
+	<prio-management>
+		<classes>
+			<PneuDrive>
+				<client-notification-threads>
+					<thread-default />
+				</client-notification-threads>
+			</PneuDrive>
+		</classes>
+		<deploy-unit></deploy-unit>
+	</prio-management>
+	<classes>
+		<PneuDrive>
+			<rolling-buffer depth="3" />
+			<events-mapping>
+				<RecvAcqEvent idref="">
+					<event-configuration name="RecAcq">
+						<Timer>
+							<timer-event period="1000" />
+						</Timer>
+					</event-configuration>
+					<unused-event-configuration name="NONE" />
+				</RecvAcqEvent>
+			</events-mapping>
+			<device-instance name="YR07DF2" state="development">
+				<configuration>
+					<description value="" />
+					<timingDomain value="NONE" />
+					<accelerator value="NONE" />
+					<acceleratorZone value="NONE" />
+					<mainMuxCriterion value="NONE" />
+					<parameterFile idref="">
+						<value>../../../generated/client/PneuDrive.silecsparam</value>
+					</parameterFile>
+					<plcDeviceLabel idref="">
+						<value>YR07DF2</value>
+					</plcDeviceLabel>
+					<plcHostName idref="">
+						<value>sdaplc003</value>
+					</plcHostName>
+				</configuration>
+				<events-mapping>
+					<RecvAcqEvent idref="">
+						<event-configuration-ref name="RecAcq" />
+					</RecvAcqEvent>
+				</events-mapping>
+			</device-instance>
+			<device-instance name="YR07DC2" state="development">
+				<configuration>
+					<description value="" />
+					<timingDomain value="NONE" />
+					<accelerator value="NONE" />
+					<acceleratorZone value="NONE" />
+					<mainMuxCriterion value="NONE" />
+					<parameterFile idref="">
+						<value>
+            				../../../generated/client/PneuDrive.silecsparam
+            			</value>
+					</parameterFile>
+					<plcDeviceLabel idref="">
+						<value>YR07DC2</value>
+					</plcDeviceLabel>
+					<plcHostName idref="">
+						<value>sdaplc003</value>
+					</plcHostName>
+				</configuration>
+				<events-mapping>
+					<RecvAcqEvent idref="">
+						<event-configuration-ref name="RecAcq" />
+					</RecvAcqEvent>
+				</events-mapping>
+			</device-instance>
+			<device-instance name="YR11DF3" state="development">
+				<configuration>
+					<description value="" />
+					<timingDomain value="NONE" />
+					<accelerator value="NONE" />
+					<acceleratorZone value="NONE" />
+					<mainMuxCriterion value="NONE" />
+					<parameterFile idref="">
+						<value>../../../generated/client/PneuDrive.silecsparam</value>
+					</parameterFile>
+					<plcDeviceLabel idref="">
+						<value>YR11DF3</value>
+					</plcDeviceLabel>
+					<plcHostName idref="">
+						<value>sdaplc003</value>
+					</plcHostName>
+				</configuration>
+				<events-mapping>
+					<RecvAcqEvent idref="">
+						<event-configuration-ref name="RecAcq"></event-configuration-ref>
+					</RecvAcqEvent>
+				</events-mapping>
+			</device-instance>
+			<device-instance name="YR11DC3" state="development">
+				<configuration>
+					<description value="" />
+					<timingDomain value="NONE" />
+					<accelerator value="NONE" />
+					<acceleratorZone value="NONE" />
+					<mainMuxCriterion value="NONE" />
+					<parameterFile idref="">
+						<value>../../../generated/client/PneuDrive.silecsparam</value>
+					</parameterFile>
+					<plcDeviceLabel idref="">
+						<value>YR11DC3</value>
+					</plcDeviceLabel>
+					<plcHostName idref="">
+						<value>sdaplc003</value>
+					</plcHostName>
+				</configuration>
+				<events-mapping>
+					<RecvAcqEvent idref="">
+						<event-configuration-ref name="RecAcq" />
+					</RecvAcqEvent>
+				</events-mapping>
+			</device-instance>
+			<device-instance name="YRE1DF1" state="development">
+				<configuration>
+					<description value="" />
+					<timingDomain value="NONE" />
+					<accelerator value="NONE" />
+					<acceleratorZone value="NONE" />
+					<mainMuxCriterion value="NONE" />
+					<parameterFile idref="">
+						<value>../../../generated/client/PneuDrive.silecsparam</value>
+					</parameterFile>
+					<plcDeviceLabel idref="">
+						<value>YRE1DF1</value>
+					</plcDeviceLabel>
+					<plcHostName idref="">
+						<value>sdaplc003</value>
+					</plcHostName>
+				</configuration>
+				<events-mapping>
+					<RecvAcqEvent idref="">
+						<event-configuration-ref name="RecAcq" />
+					</RecvAcqEvent>
+				</events-mapping>
+			</device-instance>
+			<device-instance name="YRE1DC1" state="development">
+				<configuration>
+					<description value="" />
+					<timingDomain value="NONE" />
+					<accelerator value="NONE" />
+					<acceleratorZone value="NONE" />
+					<mainMuxCriterion value="NONE" />
+					<parameterFile idref="">
+						<value>../../../generated/client/PneuDrive.silecsparam</value>
+					</parameterFile>
+					<plcDeviceLabel idref="">
+						<value>YRE1DC1</value>
+					</plcDeviceLabel>
+					<plcHostName idref="">
+						<value>sdaplc003</value>
+					</plcHostName>
+				</configuration>
+				<events-mapping>
+					<RecvAcqEvent idref="">
+						<event-configuration-ref name="RecAcq" />
+					</RecvAcqEvent>
+				</events-mapping>
+			</device-instance>
+			<global-instance name="PneuDrive_global" state="development">
+				<configuration>
+					<description value="" />
+					<timingDomain value="NONE" />
+					<accelerator value="NONE" />
+					<acceleratorZone value="NONE" />
+					<mainMuxCriterion value="NONE" />
+					<plcClassVersion idref="">
+						<value></value>
+					</plcClassVersion>
+					<plcClassName idref="">
+						<value></value>
+					</plcClassName>
+				</configuration>
+			</global-instance>
+		</PneuDrive>
+	</classes>
+</instantiation-unit>
diff --git a/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/__init__.py b/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/__init__.pyc b/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/__init__.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b750faf20600d8f3cd94237fa58460b906506113
Binary files /dev/null and b/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/__init__.pyc differ
diff --git a/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/migrators.py b/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/migrators.py
new file mode 100644
index 0000000000000000000000000000000000000000..46f5f96334fe2cbd8189ce5671b86b4097c94a22
--- /dev/null
+++ b/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/migrators.py
@@ -0,0 +1,110 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import libxml2
+
+def deployRemoveSilecsHeaderMigrator(context):
+    modified = False
+    results = context.xpathEval('/SILECS-Deploy/Deploy-Classes/Class[name/text()="SilecsHeader"]')
+    if len(results) != 0:
+        silecsHeaderClassNode = results[0]
+        silecsHeaderClassNode.unlinkNode()
+        modified = True
+    return modified
+
+def deployReOrderControllerAndClassesMigrator(context):
+    modified = False
+    root = context.xpathEval("/SILECS-Deploy")[0]
+    deployInstances = root.xpathEval("Deploy-Instances")[0]
+    for controller in deployInstances.xpathEval("Controller"):
+        controller.unlinkNode()
+        root.addChild(controller)
+        modified = True
+    deployInstances.unlinkNode()
+
+    deployUnitNode = root.xpathEval("Deploy-Unit")[0]
+    oldPLCTypeNodes = deployUnitNode.xpathEval("*[@system]")
+    if len(oldPLCTypeNodes) == 1: # Actually it is exactly one for a valid design
+        oldPLCTypeNode = oldPLCTypeNodes[0]
+        oldPLCTypeNode.unlinkNode()
+        for newController in root.xpathEval("Controller"):
+            newController.addChild(oldPLCTypeNode)
+        modified = True
+
+    # In order to get fresh, empty element ( emty content )
+    newDuNode = libxml2.newNode("Deploy-Unit")
+    newDuNode.newProp("name",deployUnitNode.prop("name"))
+    newDuNode.newProp("version",deployUnitNode.prop("version"))
+    deployUnitNode.replaceNode(newDuNode)
+
+    deployClassesNodes = root.xpathEval("Deploy-Classes")
+    if len(deployClassesNodes) != 1:# Actually it is exactly one for a valid design
+        return modified
+    deployClassesNode = deployClassesNodes[0]
+    for oldClassNode in root.xpathEval("Deploy-Classes/Class"):
+        modified = True
+        className = oldClassNode.xpathEval("name")[0].getContent()
+        classVersion = oldClassNode.xpathEval("version")[0].getContent()
+        for newController in root.xpathEval("Controller"):
+            silecsDesign = libxml2.newNode("SilecsDesign")
+            newController.addChild(silecsDesign)
+            silecsDesign.newProp('silecs-design-name', className)
+            silecsDesign.newProp('silecs-design-version', classVersion)
+            for oldDevice in oldClassNode.xpathEval("device-list/Device"):
+                deviceName = oldDevice.prop("label")
+                newDevice = libxml2.newNode("Device")
+                newDevice.newProp('device-name', deviceName)
+                silecsDesign.addChild(newDevice)
+    deployClassesNode.unlinkNode()
+    return modified
+
+def deploySwapStep7TiaMigrator(context):
+    modified = False
+    for tiaEntry in context.xpathEval("/SILECS-Deploy/Deploy-Unit/Siemens-PLC[@system='TIA-PORTAL']"):
+        tiaEntry.setProp("system","STEP-7")
+        modified = True
+    for s7Entry in context.xpathEval("/SILECS-Deploy/Deploy-Unit/Siemens-PLC[@system='STEP-7']"):
+        s7Entry.setProp("system","TIA-PORTAL")
+        modified = True
+    return modified
+
+def designGenerateFesaPropValueItemMigrator(context):
+    modified = False
+    for block in context.xpathEval("//Block"):
+        if not block.hasProp("generateFesaProperty"):
+            block.newProp("generateFesaProperty","true")
+            modified = True
+    for register in context.xpathEval("//Register"):
+        if not register.hasProp("generateFesaValueItem"):
+            register.newProp("generateFesaValueItem","true")
+            modified = True
+    return modified
+
+def fesaInstanceFileMigrator(context):
+    modified = False
+    for classNode in context.xpathEval('/instantiation-unit/classes/*'):
+        className = classNode.get_name()
+        for deviceConfiguration in classNode.xpathEval('device-instance/configuration'):
+            result1 = deviceConfiguration.xpathEval('parameterFile/value')
+            result2 = deviceConfiguration.xpathEval('plcHostName/value')
+            if len(result1) == 1 and len(result2) == 1:
+                parameterFileValueNode = result1[0]
+                controllerValueNode = result2[0]
+                valueString = parameterFileValueNode.getContent()
+                valueString = valueString.replace(className, controllerValueNode.getContent())
+                parameterFileValueNode.setContent(valueString)
+                modified = True
+    return modified
diff --git a/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/migrators.pyc b/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/migrators.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ae4511242e4437685bb96df9542e964e8546f983
Binary files /dev/null and b/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/migrators.pyc differ
diff --git a/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/testMigration.py b/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/testMigration.py
new file mode 100644
index 0000000000000000000000000000000000000000..7192689ce9ca5b2ca083586acb01fcb799ae2de9
--- /dev/null
+++ b/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/testMigration.py
@@ -0,0 +1,148 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+from test.testBase import *
+
+import libxml2
+#from migration.0_10_0to1_0_0 import *
+from migration.migration0_10_0to1_0_0.migrators import *
+import inspect #get caller name
+
+SilecsDesignOld = '''<?xml version="1.0" encoding="UTF-8"?>
+<SILECS-Design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	silecs-version="0.10.0" created="03/21/16" updated="03/21/16"
+	xsi:noNamespaceSchemaLocation="/common/usr/cscofe/silecs/0.10.0/silecs-model/src/xml/DesignSchema.xsd">
+	<Information>
+		<Owner user-login="apetit" />
+		<Editor user-login="apetit" />
+	</Information>
+	<SILECS-Class name="PneuDrive" version="0.1.0" domain="TEST">
+		<Block name="Setting" mode="READ-WRITE">
+			<Register name="ExecuteDrive" synchro="MASTER" format="int8" />
+			<Register name="RequestControl" synchro="MASTER" format="int8" />
+			<Register name="ErrorAck" synchro="MASTER" format="int8" />
+		</Block>
+		<Block name="Acq" mode="READ-ONLY">
+			<Register name="AirPressure" format="int8" synchro="MASTER" ></Register>
+			<Register name="HardwareILk" synchro="MASTER" format="int8" />
+			<Register name="Maintenance" synchro="MASTER" format="int8" />
+			<Register name="MotionTime" synchro="MASTER" format="int32" />
+			<Register name="DriveCounter" synchro="MASTER" format="int32" />
+			<Register name="Position" synchro="MASTER" format="int8" />
+			<Register name="Warnings" synchro="MASTER" format="int8" />
+			<Register name="Errors" synchro="MASTER" format="int8" />
+			<Register name="OperationalMode" synchro="MASTER" format="int8">
+			</Register>
+		</Block>
+	</SILECS-Class>
+</SILECS-Design>'''
+SilecsDesignOldParsed = libxml2.parseDoc(SilecsDesignOld)
+
+SilecsDeployOld = '''<?xml version="1.0" encoding="UTF-8"?>
+<SILECS-Deploy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" silecs-version="0.10.0" created="03/22/16" updated="03/22/16" xsi:noNamespaceSchemaLocation="/common/usr/cscofe/silecs/0.10.0/silecs-model/src/xml/DeploySchema.xsd">
+    <Information>
+        <Owner user-login="apetit"/>
+        <Editor user-login="apetit"/>
+    </Information>
+    <Deploy-Unit name="PneuDriveDU" version="0.1.0">
+        <Siemens-PLC system="STEP-7" model="SIMATIC_S7-300" protocol="DEVICE_MODE" base-DB-number="1"/>
+    </Deploy-Unit>
+    <Deploy-Instances>
+      <Controller host-name="sdaplc003"/>
+      <Controller host-name="ilkio001" />
+    </Deploy-Instances>
+    <Deploy-Classes>
+       <Class>
+            <device-list><Device label="SilecsHeader"/></device-list><name>SilecsHeader</name>
+            <version>1.0.0</version>
+       </Class>
+       <Class>
+       	<device-list>
+       		<Device label="YR07DC2"/><Device label="YR07DF2"/><Device label="YR11DC3"/><Device label="YR11DF3"/><Device label="YRE1DC1"/><Device label="YRE1DF1"/>
+       	</device-list>
+       	
+       	<name>PneuDrive</name>
+       	<version>0.1.0</version>
+       </Class>
+       <Class>
+       	<device-list>
+       		<Device label="dgsdfg"/>
+       	</device-list>
+       	<name>Whatever</name>
+       	<version>0.1.0</version>
+       </Class>
+    </Deploy-Classes>
+</SILECS-Deploy>'''
+SilecsDeployOldParsed = libxml2.parseDoc(SilecsDeployOld)
+
+fesaInstanceOldParsed = libxml2.parseFile("migration/migration0_10_0to1_0_0/DeviceData_PneuDriveDU.instance")
+
+def testdeployRemoveSilecsHeaderMigrator(deployDoc):
+    deployRemoveSilecsHeaderMigrator(deployDoc)
+    silecsHeaders = deployDoc.xpathEval('/SILECS-Deploy/Deploy-Classes/Class/name[text()="SilecsHeader"]')
+    assertEqual(len(silecsHeaders),0)
+
+def testdeployReOrderControllerAndClassesMigrator(deployDoc):
+    deployReOrderControllerAndClassesMigrator(deployDoc)
+    print deployDoc
+    oldClasses = deployDoc.xpathEval('/SILECS-Deploy/Deploy-Classes/Class')
+    assertEqual(len(oldClasses),0)
+    oldDeployInstances = deployDoc.xpathEval('/SILECS-Deploy/Deploy-Instances')
+    assertEqual(len(oldDeployInstances),0)
+    oldPLCNode = deployDoc.xpathEval('/SILECS-Deploy/Deploy-Unit/Siemens-PLC')
+    assertEqual(len(oldPLCNode),0)
+
+    newContollers = deployDoc.xpathEval('/SILECS-Deploy/Controller')
+    assertEqual(len(newContollers),2)
+    for newController in newContollers:
+        assertTrue(newController.hasProp("host-name"))
+        plcNodes = newController.xpathEval('Siemens-PLC')
+        assertEqual(len(plcNodes),1)
+        classNodes = newController.xpathEval('SilecsDesign')
+        assertEqual(len(classNodes),2)
+        pneuDrive = newController.xpathEval("SilecsDesign[@silecs-design-name='PneuDrive']")[0]
+        pneuDriveDevices = pneuDrive.xpathEval('Device')
+        assertEqual(len(pneuDriveDevices),6)
+        whatever = newController.xpathEval('SilecsDesign[@silecs-design-name="Whatever"]')[0]
+        whateverDevices = whatever.xpathEval('Device')
+        assertEqual(len(whateverDevices),1)
+
+def testdeploySwapStep7TiaMigrator(deployDoc):
+    deploySwapStep7TiaMigrator(deployDoc)
+    plcEntries = deployDoc.xpathEval("/SILECS-Deploy/Deploy-Unit/Siemens-PLC[@system='TIA-PORTAL']")
+    assertEqual(len(plcEntries),1)
+
+def testdesignGenerateFesaPropValueItemMigrator(context):
+    designGenerateFesaPropValueItemMigrator(context)
+    updatedBlocks = context.xpathEval("//Block[@generateFesaProperty='true']")
+    updatedRegisters = context.xpathEval("//Register[@generateFesaValueItem='true']")
+    assertEqual(len(updatedBlocks),2)
+    assertEqual(len(updatedRegisters),12)
+
+def testfesaInstanceFileMigrator(context):
+    fesaInstanceFileMigrator(context)
+    newValues = context.xpathEval("//device-instance[@name='YR11DF3']/configuration/parameterFile/value")
+    assertEqual(len(newValues),1)
+    assertEqual(newValues[0].getContent(),"../../../generated/client/sdaplc003.silecsparam")
+
+def runTests():
+    testdeploySwapStep7TiaMigrator(SilecsDeployOldParsed)
+    testdeployRemoveSilecsHeaderMigrator(SilecsDeployOldParsed)
+    testdeployReOrderControllerAndClassesMigrator(SilecsDeployOldParsed)
+    testdesignGenerateFesaPropValueItemMigrator(SilecsDesignOldParsed)
+    testfesaInstanceFileMigrator(fesaInstanceOldParsed)
+
+    # print deployDoc # for debugging
diff --git a/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/testMigration.pyc b/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/testMigration.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e5cf20323c6fa0965e85099be6ba2a524a3453df
Binary files /dev/null and b/silecs-codegen/src/xml/migration/migration0_10_0to1_0_0/testMigration.pyc differ
diff --git a/silecs-codegen/src/xml/migration/migrationBase.py b/silecs-codegen/src/xml/migration/migrationBase.py
new file mode 100644
index 0000000000000000000000000000000000000000..a35e2aa3e48875c2432e1e17d07ac8071faf7461
--- /dev/null
+++ b/silecs-codegen/src/xml/migration/migrationBase.py
@@ -0,0 +1,115 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import fnmatch
+import os
+import sys
+import libxml2
+from argparse import ArgumentParser
+import FileUtils
+
+class MigrationBase(object):
+    def __init__(self):
+        self.parser = ArgumentParser(description='Migration script')
+        self.parser.add_argument("silecsDocument", action="store", help="The SILECS document to migrate")
+        self.parser.add_argument("xmlSchema", action="store", help="Path to the new schema")
+        self.parser.add_argument("versionOld", action="store", help="old silecs version")
+        self.parser.add_argument("versionNew", action="store", help="new silecs version")
+        results = self.parser.parse_args()
+        self.versionOld = results.versionOld
+        self.versionNew = results.versionNew
+        
+    def fixSilecsVersion(self, context):
+        root = context.xpathEval("/*")[0]
+        if root.prop("silecs-version") != self.versionOld:
+            raise IOError("Wrong Silecs Version - migration cancelled")
+        root.setProp("silecs-version",self.versionNew)
+        print("Info: Replaced old silecs-versiong string: " + self.versionOld + " with: " + self.versionNew)
+
+    def fixXMLScheman(self, context,xmlSchema):
+        root = context.xpathEval("/*")[0]
+        root.setProp("xsi:noNamespaceSchemaLocation",xmlSchema)
+        print("Info: Replaced old silecs-xmlSchema")
+
+    def migrate(self):
+        results = self.parser.parse_args()
+        silecsDocument = results.silecsDocument
+        xmlSchema = results.xmlSchema
+        print("INFO: Migration %s --> %s " % (self.versionOld, self.versionNew))
+        
+        #project directory path
+        projectDir = FileUtils.getProjectDir(silecsDocument)
+        
+        # Design
+        extension = FileUtils.getExtension(silecsDocument)
+        modified = False
+        if extension == '.silecsdesign':
+            context = self._parse(silecsDocument)
+            modified = self.migrateClass(context, projectDir)
+
+        # Deploy
+        elif extension == '.silecsdeploy':
+            context = self._parse(silecsDocument)
+            modified = self.migrateDeployUnit(context, projectDir)
+
+        # Unknown
+        else:
+            raise IOError("Document type unknown: %r" % extension)
+
+        # only chaning the version or the schema does not count as modification --> no backup needed
+        self.fixSilecsVersion(context) 
+        self.fixXMLScheman(context,xmlSchema)
+        if modified:
+            self._saveAndBackupFile(context, silecsDocument)
+        else:
+            self._saveFile(context, silecsDocument)
+        
+        print('File %r successfully migrated' % silecsDocument)
+
+    def migrateClass(self, context, projectDir):
+        return False
+
+    def migrateDeployUnit(self, context, projectDir):
+        return False
+    
+    def _parse(self, silecsDocument):
+        if not FileUtils.fileExists(silecsDocument):
+            raise IOError("File not found: %r" % silecsDocument)
+        else:
+            print("Parsing file: %r" % silecsDocument)
+            return libxml2.parseFile(silecsDocument)
+
+    def _saveFile(self, context, silecsDocument):
+        with open(silecsDocument, 'w') as fd:
+            context.saveTo(fd)
+
+    def _saveAndBackupFile(self, context, silecsDocument):
+        FileUtils.backupFile(silecsDocument)
+        with open(silecsDocument, 'w') as fd:
+            context.saveTo(fd)
+
+
+class MigrationAny(MigrationBase):
+    def __init__(self, arguments):
+        super(MigrationAny, self).__init__()
+
+    def dummy(self):
+        #doNothing
+        print "dummy"
+
+if __name__ == "__main__":
+    migration = MigrationAny(sys.argv)
+    migration.migrate()
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/migration/migrationBase.pyc b/silecs-codegen/src/xml/migration/migrationBase.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..da4d513d8d45c7fa577c10fe60254499cb998c4c
Binary files /dev/null and b/silecs-codegen/src/xml/migration/migrationBase.pyc differ
diff --git a/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/__init__.py b/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/__init__.pyc b/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/__init__.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..74e2cf898e15df7f2ef79185cb234abe13b389d8
Binary files /dev/null and b/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/__init__.pyc differ
diff --git a/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/migrateDeployDeviceNumber.py b/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/migrateDeployDeviceNumber.py
new file mode 100644
index 0000000000000000000000000000000000000000..6fc40a93f66155a6ec375c1b282aa416240c58b8
--- /dev/null
+++ b/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/migrateDeployDeviceNumber.py
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import libxml2
+
+class DeployDeviceNumberMigrator(object):
+
+    def migrateDeviceNumbers(self, context):
+        modified = False
+        oldHeader = context.xpathEval('/SILECS-Deploy/Deploy-Classes/Class[name/text()="SilecsHeader"]')
+        if len(oldHeader) == 1:
+            deviceList = libxml2.newNode("device-list")
+            device = libxml2.newNode("Device")
+            device.newProp('label', "SilecsHeader")
+            deviceList.addChild(device)
+            classNameNode = oldHeader[0].xpathEval("name")[0]
+            classNameNode.addPrevSibling(deviceList)
+            print("Info: Device-number replaced by device-list for Class SilecsHeader")
+            modified = True
+            deviceNumber = oldHeader[0].xpathEval("device-number")
+            deviceNumber[0].unlinkNode()
+            
+        silecsClasses = context.xpathEval("/SILECS-Deploy/Deploy-Classes/Class")
+        for silecsClass in silecsClasses:
+            deviceNumber = silecsClass.xpathEval("device-number")
+            if len(deviceNumber) == 1 :  # not possible to have more than one
+                deviceList = libxml2.newNode("device-list")
+                classNameNode = silecsClass.xpathEval("name")[0]
+                classNameNode.addPrevSibling(deviceList)
+                numberOfDevices = deviceNumber[0].getContent()
+                modified = True
+                print("Info: Device-number replaced by device-list for Class: " + classNameNode.getContent())
+                for i in range(0, int(numberOfDevices)):
+                    device = libxml2.newNode("Device")
+                    device.newProp('label', "GenericDevice" + str(i))
+                    deviceList.addChild(device)
+                    print("Info: Added device: '" + device.prop('label') + "' for Class: " + classNameNode.getContent())
+                deviceNumber[0].unlinkNode()
+
+        return modified
+
+    def migrate(self, context):
+        modified = False
+        modified |= self.migrateDeviceNumbers(context)
+        return modified
diff --git a/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/migrateDeployDeviceNumber.pyc b/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/migrateDeployDeviceNumber.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3983bbc8081a2939b5ea3b1e5f4d14192d2ad008
Binary files /dev/null and b/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/migrateDeployDeviceNumber.pyc differ
diff --git a/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/migrateDeployDomain.py b/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/migrateDeployDomain.py
new file mode 100644
index 0000000000000000000000000000000000000000..83616f5dafc64cd530962f1660a8846a0e375cdd
--- /dev/null
+++ b/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/migrateDeployDomain.py
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import libxml2
+
+class DeployDomainMigrator(object):
+
+    def migrateDomains(self, context):
+        modified = False
+        controllers = context.xpathEval("/SILECS-Deploy/Deploy-Instances/Controller")
+        for controller in controllers:
+            if controller.hasProp('domain'):
+                controller.unsetProp('domain')
+                print("Info: Domain node in Controller %r removed" % controller.prop("host-name"))
+                modified = True
+        return modified
+
+    def migrate(self, context):
+        modified = False
+        modified |= self.migrateDomains(context)
+        return modified
diff --git a/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/migrateDeployDomain.pyc b/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/migrateDeployDomain.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..69cf44a3f250194b5f553539eceede5365966473
Binary files /dev/null and b/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/migrateDeployDomain.pyc differ
diff --git a/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/testMigration.py b/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/testMigration.py
new file mode 100644
index 0000000000000000000000000000000000000000..f8abe0c279fa642df5a267ef30eabb3fdcf48005
--- /dev/null
+++ b/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/testMigration.py
@@ -0,0 +1,91 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+from test.testBase import *
+
+import libxml2
+from migration.migration_0_9_0to0_10_0.migrateDeployDomain import *
+from migration.migration_0_9_0to0_10_0.migrateDeployDeviceNumber import *
+
+import inspect #get caller name
+SilecsDeployOld = '''<?xml version="1.0" encoding="UTF-8"?>
+<SILECS-Deploy silecs-version="0.9.0" created="03/04/16" updated="03/04/16" 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="/common/home/bel/schwinn/lnx/workspace-silecs/silecs-model/src/xml/DeploySchema.xsd">
+    <Information>
+        <Owner user-login="schwinn"/>
+        <Editor user-login="schwinn"/>
+    </Information>
+    <Deploy-Unit name="Test123DU" version="0.1.0">
+        <Siemens-PLC system="STEP-7" model="SIMATIC_S7-300" protocol="BLOCK_MODE" base-DB-number="0"/>
+    </Deploy-Unit>
+    <Deploy-Instances>
+      <Controller host-name="asl733" domain="ADE"/>
+      <Controller host-name="asl734" domain="SDFSDAFF"/>
+    </Deploy-Instances>
+    <Deploy-Classes>
+       <Class>
+            <device-number>1</device-number>
+            <name>SilecsHeader</name>
+            <version>1.0.0</version>
+       </Class>
+       <Class>
+           	<device-number>5</device-number>
+           	<name>Test123</name>
+           	<version>0.1.0</version>
+       </Class>
+       <Class>
+       	    <device-list>
+                <Device label="MyDevice1"/>
+                <Device label="MyDevice2"/>
+            </device-list>
+       	<name>Test345</name>
+       	<version>0.1.0</version>
+       </Class>
+    </Deploy-Classes>
+</SILECS-Deploy>
+'''
+
+def testMigrateDeployDeviceNumber(deployDoc):
+    migrator = DeployDeviceNumberMigrator()
+    migrator.migrate(deployDoc)
+    deviceNumbers = deployDoc.xpathEval("/SILECS-Deploy/Deploy-Classes/Class/device-number")
+    assertEqual(len(deviceNumbers),0)
+    deviceLists = deployDoc.xpathEval("/SILECS-Deploy/Deploy-Classes/Class/device-list")
+    assertEqual(len(deviceLists),3)
+    newHeader = deployDoc.xpathEval('/SILECS-Deploy/Deploy-Classes/Class/device-list/Device[@label="SilecsHeader"]')
+    assertEqual(len(newHeader),1)
+    test123 = deployDoc.xpathEval('/SILECS-Deploy/Deploy-Classes/Class/name[text()="Test123"]')
+    assertEqual(len(test123),1)
+
+    deviceListOnFirstPosition = test123[0].xpathEval('../*')[0]
+    assertTrue(deviceListOnFirstPosition.get_name() == 'device-list')
+
+    genericDevices = test123[0].xpathEval('../device-list/Device')
+    assertEqual(len(genericDevices),5)
+
+def testMigrateDeployDomain(deployDoc):
+    migrator = DeployDomainMigrator()
+    migrator.migrate(deployDoc)
+    controllers = deployDoc.xpathEval("/SILECS-Deploy/Deploy-Instances/Controller")
+    for controller in controllers:
+       assertFalse(controller.hasProp('domain'))
+
+def runTests():
+    deployDoc =  libxml2.parseDoc(SilecsDeployOld)
+    testMigrateDeployDomain(deployDoc)
+    testMigrateDeployDeviceNumber(deployDoc)
+    # print deployDoc # for debugging
diff --git a/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/testMigration.pyc b/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/testMigration.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a52db80e075b9beaf1996d49001e4ec8ff4ad9e4
Binary files /dev/null and b/silecs-codegen/src/xml/migration/migration_0_9_0to0_10_0/testMigration.pyc differ
diff --git a/silecs-codegen/src/xml/migration/runTests.py b/silecs-codegen/src/xml/migration/runTests.py
new file mode 100644
index 0000000000000000000000000000000000000000..86c7e163af06cab443ebaf5f0f2ec579fabdb7d7
--- /dev/null
+++ b/silecs-codegen/src/xml/migration/runTests.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+from test.testBase import *
+import migration.migration_0_9_0to0_10_0.testMigration
+import migration.migration0_10_0to1_0_0.testMigration
+
+SilecsDeployOld = '''<?xml version="1.0" encoding="UTF-8"?>
+<SILECS-Deploy silecs-version="oldVersion" created="03/04/16" updated="03/04/16" 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="oldSchemaLocation">
+</SILECS-Deploy>
+'''
+
+# Test does not run in Jenkins, since "argparse" is not installed there
+
+#class BaseTestFake(MigrationBase):
+#    def __init__(self):
+#        super(BaseTestFake, self).__init__("oldVersion", "newVersion")
+
+#def runbaseTests():
+#    baseClass = BaseTestFake()
+#    context = libxml2.parseDoc(SilecsDeployOld)
+#    baseClass.fixSilecsVersion(context)
+#    baseClass.fixXMLScheman(context,"newSchemaLocation")
+#
+#    root = context.xpathEval("/*")[0]
+#
+#    assertEqual( root.prop('silecs-version'),"newVersion" )
+#    assertEqual( root.prop('noNamespaceSchemaLocation'),"newSchemaLocation" )
+
+def runAllTests():
+#    runbaseTests()
+    migration.migration_0_9_0to0_10_0.testMigration.runTests()
+    migration.migration0_10_0to1_0_0.testMigration.runTests()
+    allTestsOk()
diff --git a/silecs-codegen/src/xml/migration/runTests.pyc b/silecs-codegen/src/xml/migration/runTests.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..488ae043b4ec4be2a173c460e964ff865a14024e
Binary files /dev/null and b/silecs-codegen/src/xml/migration/runTests.pyc differ
diff --git a/silecs-codegen/src/xml/rabbitTemplate$py.class b/silecs-codegen/src/xml/rabbitTemplate$py.class
new file mode 100644
index 0000000000000000000000000000000000000000..afe49a637829dc79e4d63c843aa6048c685db634
Binary files /dev/null and b/silecs-codegen/src/xml/rabbitTemplate$py.class differ
diff --git a/silecs-codegen/src/xml/rabbitTemplate.py b/silecs-codegen/src/xml/rabbitTemplate.py
new file mode 100644
index 0000000000000000000000000000000000000000..b02681c958670691f6611ae13adc22f1f691f4b7
--- /dev/null
+++ b/silecs-codegen/src/xml/rabbitTemplate.py
@@ -0,0 +1,410 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import time
+
+#=========================================================================
+# Global definition
+#=========================================================================
+
+#-------------------------------------------------------------------------
+# Hash-Table
+
+whichRabbitFormat = {
+	'uint8'   : 'uint16_t',
+	'int8'    : 'int16_t',
+	'uint16'  : 'uint16_t',
+	'int16'   : 'int16_t',
+	'uint32'  : 'uint32_t',
+	'int32'   : 'int32_t',
+	'float32' : 'float',
+	'uint64'  : '8',
+	'int64'   : '8',
+    'string'  : 'uint8_t',    
+#	'float64' : '8',    not supported by microcontroller
+	'date'    : 'dt',
+   	'char'	:'int16_t',
+    'byte'	:'uint16_t',
+    'word'	:'uint16_t',
+    'dword'	:'uint32_t',
+    'int'	:'int16_t',
+    'dint'	:'int32_t',
+    'real'	:'float',
+    'dt'	:'dt'
}
+
+#=========================================================================
+# Utils
+#=========================================================================
+
+def toWordArray(strg):
+    wordArray = ''
+    for i in range(0, len(strg), 2):
+        lsb = ord(strg[i])
+        try: hsb = ord(strg[i+1]) 
+        except: hsb = 0
+        wordArray += "0x%02x%02x," %(hsb,lsb)
+    return wordArray
+
+#=========================================================================
+# C Source template (.c file)
+#=========================================================================
+
+header = """
+/* +-------------------------------------------------------------------
+ * | Copyright CERN 2015
+ * | SILECS - BE/CO-SRC
+ * | April 2015
+ * +-------------------------------------------------------------------
+ *
+ * Release : SILECS_%s
+ *
+ * The following code has been automatically generated by SILECS.
+ *
+ * N.B: This file relies on the existence of explicit C data type such
+ * as int8_t, uint8_t, int16_t, etc....
+ * If your compiler does not support them natively please implement 
+ * them by including the data type definition provided on the SILECS
+ * web page before including this header file.
+ */
+
+#define MODBUS_START_ADDRESS %s
+
+/*---------------------------------------------------------------------
+ * DT 
+ * data type definition and related utilities
+ *---------------------------------------------------------------------
+ */
+
+typedef struct
+{
+	uint8_t sc_100;     // second cent
+	uint8_t sc;			// second
+	uint8_t mn;         // minute
+	uint8_t hh;         // hour
+	uint8_t dd;         // day
+	uint8_t mm;         // month
+	uint8_t yy1;        // year
+	uint8_t yy2;        // year2
+} dt;
+
+#define _frombcd(a) (int)(((a>>4)*10)+(a&0x0F))
+#define _tobcd(a)   (((unsigned char)((a)/10)<<4)+((a)%%10))
+
+void SILECS_set_dt(int8_t sc_100 ,int8_t sc, int8_t mn,int8_t hh,int8_t dd,int8_t mm,int32_t yy, dt *date)
+{
+	date->sc_100 = sc_100;
+	date->sc     = _tobcd(sc);
+	date->mn     = _tobcd(mn);
+	date->hh     = _tobcd(hh);
+	date->dd     = _tobcd(dd);
+	date->mm     = _tobcd(mm);
+	date->yy2    = _tobcd((int8_t)(yy/100));
+	date->yy1    = _tobcd((int8_t)(yy%%100));
+}
+
+"""
+
+#=========================================================================
+# DATA TYPE DEFINITION
+#=========================================================================
+
+firstBlockUDT = """
+/*---------------------------------------------------------------------
+ * %s / v%s
+ * BLOCK Type definition
+ *---------------------------------------------------------------------
+ */
+"""
+
+blockUDT = """
+typedef struct 
+{
+%s
+} _%s_%s;
+"""
+
+regScalar = """    %s %s;
+"""
+
+regArray  = """    %s %s[%s];
+"""
+
+regArray2d  = """    %s %s[%s][%s];
+"""
+
+stringArray = """    %s %s[%s][%s][%s];
+"""
+
+#=========================================================================
+# INSTANTIATION
+#=========================================================================
+
+allocationComment = """
+/*---------------------------------------------------------------------
+ * MEMORY ALLOCATION
+ * PROTOCOL: %s
+ *---------------------------------------------------------------------
+ */
+"""
+
+NBdeviceDefinition = """#define NB_%s_DEVICE %s
+"""
+
+#======= DEVICE MODE =================
+
+deviceModeBlockInstantiation = """        _%s_%s %s;
+"""
+
+#deviceModeClass_deviceNumber = """
+#    struct {
+#        _%s_%s %s;
+#    } %s_device[%s];
+#"""
+
+deviceModeClass_deviceNumber = """
+    struct {
+%s
+    } %s_device[NB_%s_DEVICE];
+"""
+
+deviceModeClass_deviceList = """
+    struct {
+%s
+    } %s;
+"""
+
+deviceMode_dataInstantiation = """
+typedef struct {
+    %s
+} _SILECS_DATA_SEGMENT;
+
+#define SILECS_DATA_SEGMENT_MODBUS_SIZE (sizeof(_SILECS_DATA_SEGMENT)/2)
+
+union silecsData {
+    _SILECS_DATA_SEGMENT data;
+    uint16_t array[SILECS_DATA_SEGMENT_MODBUS_SIZE];
+} silecsData;
+
+"""
+
+#======= BLOCK MODE =================
+
+blockModeDeviceInstantiation_deviceNumber = """        _%s_%s device[NB_%s_DEVICE];
+"""
+
+blockModeDeviceInstantiation_deviceList = """        _%s_%s %s;
+"""
+
+blockModeBlockInstantiation = """
+    struct {
+%s    } %s_%s;
+"""
+
+blockMode_dataInstantiation = """
+typedef struct {
+    %s
+} _SILECS_DATA_SEGMENT;
+
+#define SILECS_DATA_SEGMENT_MODBUS_SIZE (sizeof(_SILECS_DATA_SEGMENT)/2)
+
+union modbus_data {
+    _SILECS_DATA_SEGMENT data;
+    uint16_t array[SILECS_DATA_SEGMENT_MODBUS_SIZE];
+} silecsData;
+
+"""
+
+#=========================================================================
+# init
+#=========================================================================
+
+globalAllocation = """
+    SILECS_INSTANCE_DATA data;
+    uint16_t modbus_data = & data;
+"""
+
+initFunctionDeviceMode = """
+/* Initialization function */
+int SILECS_init()
+{
+	/* Silecs version initialization */
+	strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._version, "%s");
+	
+	/* Silecs checksum initialization */
+	silecsData.data.SilecsHeader_device[0].hdrBlk._checksum  = %s;
+	
+	/* Silecs user initialization */
+	strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._user, "%s");
+	
+	/* Silecs date initialization */
+	SILECS_set_dt(%s,%s,%s,%s,%s,%s,%s,&silecsData.data.SilecsHeader_device[0].hdrBlk._date);
+}
+
+"""
+
+#initFunctionBlockMode = """
+initFunctionBlockMode = """
+/* Initialization function */
+int SILECS_init()
+{
+	/* Silecs version initialization */
+	strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._version, "%s");
+	
+	/* Silecs checksum initialization */
+	silecsData.data.SilecsHeader_hdrBlk.device[0]._checksum  = %s;
+	
+	/* Silecs user initialization */
+	strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._user, "%s");
+	
+	/* Silecs date initialization */
+	SILECS_set_dt(%s,%s,%s,%s,%s,%s,%s,&silecsData.data.SilecsHeader_hdrBlk.device[0]._date);
+}
+
+"""
+
+#=========================================================================
+# Example generation
+#=========================================================================
+
+instantiationExample = """/*
+ * Automatically generated Addressing example
+ *"""
+
+deviceModeDeviceListExample = """
+ * This example shows how to address the register %s of block %s
+ * of device %s of the class %s
+ * 
+ *  silecsData.%s_%s.%s.%s = ....;
+ */"""
+
+deviceModeDeviceNumberExample = """
+ * This example shows how to address the register %s of block %s
+ * of device 0 of the class %s
+ *
+ *  silecsData.%s_device[0].%s.%s = ....;
+ */"""
+
+blockModeDeviceListExample = """
+ * This example shows how to address the register %s of block %s
+ * of device %s of the class %s
+ *
+ *  silecsData.%s_%s.%s.%s = ....;
+ */"""
+
+blockModeDeviceNumberExample = """
+ * This example shows how to address the register %s of block %s
+ * of device 0 of the class %s
+ *
+ *  silecsData.%s_%s.device[0].%s = ....;
+ */"""
+
+#=========================================================================
+# C code generation Sub-function
+#=========================================================================
+
+# HEADER file ------------------------------------------------------------
+def cHeader(baseAddress,silecsVersion):
+    return header %(silecsVersion, baseAddress)
+
+# REGISTER definition ----------------------------------------------------
+def cRegister(regName, regFormat, regDim, regDim2=1, strLen=1):
+	if strLen > 1: # if it's a string
+		if regDim2 > 1:    # add another pair of brackets to hold the string length in case second dimension of array is set
+			return stringArray %(whichRabbitFormat[regFormat], regName, regDim, regDim2, strLen)
+		elif regDim > 1:    # reuse the array2D syntax
+			return regArray2d %(whichRabbitFormat[regFormat], regName, regDim, strLen)
+		else:        # regular string register
+			return regArray %(whichRabbitFormat[regFormat], regName, strLen)
+	else:
+		if regDim == 1 and regDim2 == 1:    # scalar
+			return regScalar %(whichRabbitFormat[regFormat], regName)
+		elif regDim > 1 and regDim2 == 1:    # array
+			return regArray %(whichRabbitFormat[regFormat], regName, regDim)
+		else:    # dim1>=1 and for whatever dim2, use double array syntax
+			return regArray2d %(whichRabbitFormat[regFormat], regName, regDim, regDim2)
+
+# BLOCK type definition (UDT) --------------------------------------------
+def cBlockUDT(className, classVersion, blockName, regList, isFirst):
+    if isFirst:
+        return firstBlockUDT %(className, classVersion) + blockUDT %(regList, className, blockName)
+    else:
+        return blockUDT %(regList, className, blockName)
+    
+
+#============= DEVICE instantiation ============= 
+   
+# GLOBAL instantiation ----------------------------------------------
+
+def cAllocationComment(plcProtocol):
+	return allocationComment %(plcProtocol)
+
+def cNBdeviceDefinition(className,deviceNumber):
+    return NBdeviceDefinition %(className,deviceNumber)
+     
+# DEVICE MODE instantiation ----------------------------------------------
+
+def cDeviceModeBlockInstantiation(className, blockName):
+    return deviceModeBlockInstantiation %(className, blockName, blockName)
+
+def cDeviceModeClass_deviceNumber(className, blockList):
+    return deviceModeClass_deviceNumber %(blockList, className, className)
+
+def cDeviceModeClass_deviceList(blockList, deviceList):
+    return deviceModeClass_deviceList %(blockList, deviceList)
+
+def cDeviceModeDataInstantiation(classList):
+    return deviceMode_dataInstantiation %(classList)
+
+# BLOCK MODE instantiation ----------------------------------------------
+
+def cBlockModeDeviceInstantiation_deviceNumber(className, blockName):
+    return blockModeDeviceInstantiation_deviceNumber %(className, blockName, className)
+
+def cBlockModeDeviceInstantiation_deviceList(className, blockName, deviceName):
+    return blockModeDeviceInstantiation_deviceList %(className, blockName, deviceName)
+
+def cBlockModeBlockInstantiation(deviceList, className, blockName):
+    return blockModeBlockInstantiation %(deviceList, className, blockName)
+    
+def cBlockModeDataInstantiation(classList):
+	return blockMode_dataInstantiation %(classList)
+
+# Init Function ----------------------------------------------
+def cInitDeviceMode(silecsVersion,ieChecks,ieUser):
+    dt = time.localtime(time.time())
+    return initFunctionDeviceMode %("SILECS_"+silecsVersion,ieChecks,ieUser,dt[6],dt[5],dt[4],dt[3],dt[2],dt[1],dt[0])
+
+def cInitBlockMode(silecsVersion,ieChecks,ieUser):
+    dt = time.localtime(time.time())
+    return initFunctionBlockMode %("SILECS_"+silecsVersion,ieChecks,ieUser,dt[6],dt[5],dt[4],dt[3],dt[2],dt[1],dt[0])
+        
+# Example function  ----------------------------------------------
+def cExample(plcProtocol,withDeviceList,className, blockName, registerName, deviceLabel =''):
+
+    if plcProtocol == 'DEVICE_MODE':
+        if withDeviceList == True:
+            # device mode - device list            
+            return instantiationExample  + deviceModeDeviceListExample %(registerName, blockName, deviceLabel, className, className, deviceLabel, blockName, registerName)
+        else:
+            # device mode - device number
+            return instantiationExample + deviceModeDeviceNumberExample %(registerName, blockName, className, className, blockName, registerName)
+    else:
+        if withDeviceList == True:
+            # block mode - device list
+            return instantiationExample + blockModeDeviceListExample %(registerName, blockName, deviceLabel, className, className, blockName, deviceLabel, registerName)
+        else:
+            # block mode - device number
+            return instantiationExample + blockModeDeviceNumberExample %(registerName, blockName, className, className, blockName, registerName)
diff --git a/silecs-codegen/src/xml/rabbitTemplate.pyc b/silecs-codegen/src/xml/rabbitTemplate.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9675f7bf315d12e2adcdfa6a6a80e2ba72d6cec8
Binary files /dev/null and b/silecs-codegen/src/xml/rabbitTemplate.pyc differ
diff --git a/silecs-codegen/src/xml/runTests.py b/silecs-codegen/src/xml/runTests.py
new file mode 100644
index 0000000000000000000000000000000000000000..bf970b4941cdf31f3a75a0669c53d4a19b24ad7b
--- /dev/null
+++ b/silecs-codegen/src/xml/runTests.py
@@ -0,0 +1,47 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import sys
+
+from test.testBase import *
+
+import test.fesa.fillFESADeployUnitTest
+import test.fesa.generateFesaDesignTest
+import test.fesa.generateSourceCodeTest
+import migration.runTests
+
+import test.general.iecommonTest
+import test.general.genplcsrcTest
+import test.general.genParamTest
+import test.general.genDuWrapperTest
+
+def runTests():
+    test.fesa.fillFESADeployUnitTest.runTests()
+    test.fesa.generateFesaDesignTest.runTests()
+    test.fesa.generateSourceCodeTest.runTests()
+    test.general.iecommonTest.runTests()
+    test.general.genParamTest.runTests()
+    test.general.genplcsrcTest.runTests()
+    test.general.genDuWrapperTest.runTests()
+    migration.runTests.runAllTests()
+
+    print "################################################"
+    print "# Test suite finished - no failures detected ! #"
+    print "################################################"
+
+# ********************** module stand alone code **********************
+if __name__ == "__main__":
+    runTests()
diff --git a/silecs-codegen/src/xml/s7template$py.class b/silecs-codegen/src/xml/s7template$py.class
new file mode 100644
index 0000000000000000000000000000000000000000..81af5a7d8d4a8d34b94e06300c786ab8ff4c24f5
Binary files /dev/null and b/silecs-codegen/src/xml/s7template$py.class differ
diff --git a/silecs-codegen/src/xml/s7template.py b/silecs-codegen/src/xml/s7template.py
new file mode 100644
index 0000000000000000000000000000000000000000..021a0d5b20b00d9e292b36a75880242986fd10f2
--- /dev/null
+++ b/silecs-codegen/src/xml/s7template.py
@@ -0,0 +1,252 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+
+# Description:
+# This module implement the methods to build each components of the sources.
+# A component source consists of one 'parameterizable' text that can
+# be specialized on call to append the string to be stored in the file.
+#
+
+#=========================================================================
+# Global definition
+#=========================================================================
+
+#-------------------------------------------------------------------------
+# Hash-Table
+
+whichSimaticFormat = {
+	'uint8'   : 'BYTE',
+	'int8'    : 'CHAR',
+	'uint16'  : 'WORD',
+	'int16'   : 'INT',
+	'uint32'  : 'DWORD',
+	'int32'   : 'DINT',
+	'float32' : 'REAL',
+    'string'   : 'STRING',
+#	'uint64'  : '8',	not supported with PLC
+#	'int64'   : '8',	not supported with PLC
+#	'float64' : '8',    not supported with PLC
+	'date'    : 'DT',
+	'char'	:'CHAR',
+    'byte'	:'BYTE',
+    'word'	:'WORD',
+    'dword'	:'DWORD',
+    'int'	:'INT',
+    'dint'	:'DINT',
+    'real'	:'REAL',
+    'dt'	:'DT'
}
+
+
+#=========================================================================
+# STL Source template (.scl file)
+#=========================================================================
+
+firstBlockUDT = """//---------------------------------------------------------------------\r
+// %s/ v%s\r
+// BLOCK Type definition\r
+//---------------------------------------------------------------------\r
+"""
+
+blockUDT = """TYPE _%s_%s\r
+AUTHOR:    %s\r
+FAMILY:    SILECS\r
+NAME:      UDTB\r
+    STRUCT\r
+%s
+    END_STRUCT;\r
+END_TYPE\r
+\r
+"""
+
+regScalar = """        %s: %s%s;\r
+"""
+
+regArray  = """        %s: ARRAY[0..%d] OF %s%s;\r
+"""
+
+regArray2d =  """        %s: ARRAY[0..%d, 0..%d] OF %s%s;\r
+"""
+
+regFixedStringLen = """		%s: STRING[16]%s;\r
+"""
+
+firstBlock = """//---------------------------------------------------------------------\r
+// %s/ v%s\r
+// Block instance definition\r
+//---------------------------------------------------------------------\r
+"""
+
+DB_TIAP = """DATA_BLOCK %s_%s\r
+{ S7_Optimized_Access := 'FALSE' }\r
+AUTHOR:    %s\r
+FAMILY:    SILECS\r
+NAME:      %s\r
+STRUCT\r
%s
+END_STRUCT;\r
+BEGIN\r
+END_DATA_BLOCK\r
+\r
+"""
+
+DB_STEP7 = """// %s_%s ...........................................\r
+DATA_BLOCK DB%s\r
+{ S7_Optimized_Access := 'FALSE' }\r
+AUTHOR:    %s\r
+FAMILY:    SILECS\r
+NAME:      %s\r
+STRUCT\r
+%s
+END_STRUCT;\r
+BEGIN\r
+END_DATA_BLOCK\r
+\r
+"""
+
+device = """    %s: _%s_%s;
+"""
+
+#=========================================================================
+# SYMBOLS Source template (.sdf file)
+#=========================================================================
+
+diagSymbol = """"SILECS_HEADER",%s
+"""
+
+UDTSymbol  = """"_%s_%s","UDT %d","UDT %d","%s"
+"""
+
+DBSymbol   = """"%s_%s","DB %d","DB %d","%s"
+"""
+
+#=========================================================================
+# Sub-function
+#=========================================================================
+
+# ------------------------------------------------------------------------
+# Utils 
+# ------------------------------------------------------------------------
+def toCharArray(strg):
+    charArray = ''
+    for c in strg: charArray += "'%c'," %c
+    return charArray
+
+def toByteArray(strg):
+    byteArray = ''
+    for c in strg: byteArray += "16#%02x," %(ord(c))
+    return byteArray
+
+def toWordArray(strg):
+    wordArray = ''
+    for i in range(0, len(strg), 2):
+        lsb = ord(strg[i])
+        try: hsb = ord(strg[i+1]) 
+        except: hsb = 0
+        wordArray += "16#%02x%02x," %(hsb,lsb)
+    return wordArray
+
+# ------------------------------------------------------------------------
+# STL code generation
+# ------------------------------------------------------------------------
+
+# REGISTER definition ----------------------------------------------------
+def stlRegister(regName, regFormat, regDim, regDim2, regVal, regLen=1):
+    if regLen > 1:    # register is a string or an array of strings
+        strLen = whichSimaticFormat[regFormat]+'['+str(regLen)+']'
+        if regDim == 1 and regDim2 == 1:    # scalar register
+            return regScalar %(regName, strLen, regVal)        
+        elif regDim > 1 and regDim2 == 1:    # array register
+            return regArray %(regName, regDim-1, strLen, regVal)
+        else:    # dim1>=1 and for whatever dim2, use double array syntax
+            return regArray2d %(regName, regDim-1, regDim2-1, strLen, regVal)
+    else:
+        if regDim == 1 and regDim2 == 1:
+            return regScalar %(regName, whichSimaticFormat[regFormat], regVal)
+        elif regDim > 1 and regDim2 == 1:
+            return regArray %(regName, regDim-1, whichSimaticFormat[regFormat], regVal)
+        else:    # dim1>=1 and for whatever dim2, use double array syntax
+            return regArray2d %(regName, regDim-1, regDim2-1, whichSimaticFormat[regFormat], regVal)
+
+#This method is used to add default value to the diagnostic registers
+def stlRegisterValue(regName, owner, date, checksum, silecsversion):
+	if regName == '_version': return " := 'SILECS_%s'" %silecsversion
+	if regName == '_checksum' : return " := DW#16#%x" %checksum
+	if regName == '_user'   : return " := '%s'" %owner
+	if regName == '_date'   : return " := %s" %date
+	return ''    #all other registers cannot have default assignment for the time being
+
+# BLOCK type definition (UDT) --------------------------------------------
+def stlBlockUDT(owner, className, classVersion, blockName, regList, isFirst):
+    if isFirst:
+        return firstBlockUDT %(className, classVersion) + blockUDT %(className, blockName, owner, regList)
+    else:
+        return blockUDT %(className, blockName, owner, regList)
+    
+# BLOCK_MODE: data-block instance ----------------------------------------
+def stlDevice(devLabel, className, blockName):
+    return device %(devLabel, className, blockName)
+	    
+# DEVICE_MODE: data-block instance ---------------------------------------
+def stlBlock(className, blockName):
+    return device %(blockName, className, blockName)     
+        
+def generateBlock(owner, className, classVersion, system, DBnumber, blockName, blockList, isFirst, protocol):
+    srcCore = ""
+    mode = ''    
+    if protocol == 'BLOCK_MODE':
+        mode = 'BLK_MODE'
+    elif protocol == 'DEVICE_MODE':
+        mode = 'DEV_MODE'
+    else:
+        raise Exception( "Unknown PLC-protocol defined: " + protocol )
+
+    if (system == 'TIA-PORTAL'):
+        srcCore = DB_TIAP %(className, blockName, owner, mode, blockList)
+    elif (system == 'STEP-7'):
+        srcCore = DB_STEP7 %(className, blockName, DBnumber, owner, mode, blockList)
+    else:
+        raise Exception( "Unknown PLC-system defined: " + system )
+
+    if isFirst:
+        return firstBlock %(className, classVersion) + srcCore
+    else:
+        return srcCore
+	
+# ------------------------------------------------------------------------
+# SYMBOLS code generation
+# ------------------------------------------------------------------------
+
+# HEADER file ------------------------------------------------------------
+def symHeader(baseAddress):
+    return DBSymbol %('SILECS', 'HEADER', baseAddress, baseAddress, "SILECS Diagnostic data-block")
+
+# UDT Type definition ----------------------------------------------------
+def symBlockUDT(className, classVersion, blockName, number, isFirst):
+    comment = ''
+    if isFirst: comment = "[%s/%s] UDT symbol: _<class-name>_<block-name>" %(className, classVersion)
+    return UDTSymbol %(className, blockName, number, number, comment)
+
+# BLOCK_MODE: data-block symbol ----------------------------
+def symBlockDB(className, classVersion, blockName, number, isFirst):
+    comment = ''
+    if isFirst: comment = "[%s/%s] DB symbol: <class-name>_<block-name>" %(className, classVersion)
+    return DBSymbol %(className, blockName, number, number, comment)
+
+# DEVICE_MODE : data-block symbol ----------------------------
+def symDeviceDB(className, classVersion, deviceLabel, number, isFirst):
+    comment = ''
+    if isFirst: comment = "[%s/%s] DB symbol: <class-name>_<device-label | device-id>" %(className, classVersion)
+    return DBSymbol %(className, deviceLabel, number, number, comment)
diff --git a/silecs-codegen/src/xml/s7template.pyc b/silecs-codegen/src/xml/s7template.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3cfa9954b20c5ef13d6722376b5d2097b90264c4
Binary files /dev/null and b/silecs-codegen/src/xml/s7template.pyc differ
diff --git a/silecs-codegen/src/xml/test/AllTypes.silecsdesign b/silecs-codegen/src/xml/test/AllTypes.silecsdesign
new file mode 100644
index 0000000000000000000000000000000000000000..a92fd2ebf58548789bc609f6a72e2d270bc80339
--- /dev/null
+++ b/silecs-codegen/src/xml/test/AllTypes.silecsdesign
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<SILECS-Design silecs-version="0.10.0" created="06/27/16" updated="06/27/16" 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="/common/home/bel/schwinn/lnx/workspace-silecs-mars/silecs-model/src/xml/DesignSchema.xsd">
+    <Information>
+        <Owner user-login="schwinn"/>
+        <Editor user-login="schwinn"/>
+    </Information>
+    <SILECS-Class name="AllTypes" version="0.1.0" domain="OPERATIONAL" >
+        <Block name="MyROBlock" mode="READ-ONLY" generateFesaProperty="true">
+            <Register name="RO_int8" format="int8" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_uint8" format="uint8" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_int16" format="int16" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_uint16" format="uint16" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_int32" format="int32" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_uint32" format="uint32" synchro="MASTER" generateFesaValueItem="true" />
+            <!--<Register name="RO_int64" format="int64" synchro="MASTER" generateFesaValueItem="true" /> not Supported for Beckhoff, Siemens and Schneider-->
+            <!--<Register name="RO_uint64" format="uint64" synchro="MASTER" generateFesaValueItem="true" /> not Supported for Beckhoff, Siemens and Schneider-->
+            <Register name="RO_float32" format="float32" synchro="MASTER" generateFesaValueItem="true" />
+            <!--<Register name="RO_float64" format="float64" synchro="MASTER" generateFesaValueItem="true" /> not Supported for Rabbit, Beckhoff, Siemens and Schneider-->
+            <Register name="RO_string" format="string" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_date" format="date" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_char" format="char" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_byte" format="byte" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_word" format="word" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_dword" format="dword" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_int" format="int" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_dint" format="dint" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_real" format="real" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_dt" format="dt" synchro="MASTER" generateFesaValueItem="true" />
+        </Block>
+        <Block name="MyRWBlock" generateFesaProperty="true" mode="READ-WRITE">
+            <Register name="RW_int8" format="int8" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2" />
+            <Register name="RW_uint8" format="uint8" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_int16" format="int16" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_uint16" format="uint16" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_int32" format="int32" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_uint32" format="uint32" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <!--  <Register name="RW_int64" format="int64" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/> not Supported for Beckhoff, Siemens and Schneider-->
+            <!--<Register name="RW_uint64" format="uint64" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/> not Supported for Beckhoff, Siemens and Schneider-->
+            <Register name="RW_float32" format="float32" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <!--<Register name="RW_float64" format="float64" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/> not Supported for Rabbit, Beckhoff, Siemens and Schneider-->
+            <Register name="RW_string" format="string" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_date" format="date" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_char" format="char" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_byte" format="byte" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_word" format="word" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_dword" format="dword" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_int" format="int" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_dint" format="dint" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_real" format="real" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_dt" format="dt" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+        </Block>
+        <Block name="MyWOBlock" generateFesaProperty="true" mode="WRITE-ONLY">
+            <Register name="WO_int8" format="int8" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_uint8" format="uint8" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_int16" format="int16" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_uint16" format="uint16" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_int32" format="int32" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_uint32" format="uint32" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <!--<Register name="WO_int64" format="int64" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/> not Supported for Beckhoff, Siemens and Schneider-->
+            <!--<Register name="WO_uint64" format="uint64" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/> not Supported for Beckhoff, Siemens and Schneider-->
+            <Register name="WO_float32" format="float32" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <!--<Register name="WO_float64" format="float64" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/> not Supported for Rabbit, Beckhoff, Siemens and Schneider-->
+            <Register name="WO_string" format="string" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_date" format="date" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_char" format="char" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_byte" format="byte" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_word" format="word" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_dword" format="dword" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_int" format="int" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_dint" format="dint" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_real" format="real" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_dt" format="dt" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+        </Block>
+    </SILECS-Class>
+</SILECS-Design>
diff --git a/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy b/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy
new file mode 100644
index 0000000000000000000000000000000000000000..67fe6fc6f201f4cbf09ae9158321ddb6b7eb52ba
--- /dev/null
+++ b/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<SILECS-Deploy silecs-version="0.10.0" created="06/27/16" updated="06/27/16" 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="/common/home/bel/schwinn/lnx/workspace-silecs-mars/silecs-model/src/xml/DeploySchema.xsd">
+    <Information>
+        <Owner user-login="schwinn"/>
+        <Editor user-login="schwinn"/>
+    </Information>
+    <Deploy-Unit name="AllTypesDU" version="0.1.0"/>
+        <Controller host-name="Siemens_TiaDevice">
+        <Siemens-PLC model="SIMATIC_S7-300" system="TIA-PORTAL" base-DB-number="0" protocol="DEVICE_MODE" />
+        <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes">
+            <Device device-name="testDevice1"/>
+            <Device device-name="testDevice2"/>
+        </SilecsDesign>
+    </Controller>
+        <Controller host-name="Siemens_TiaBlock">
+        <Siemens-PLC model="SIMATIC_S7-300" system="TIA-PORTAL" base-DB-number="0" protocol="BLOCK_MODE" />
+        <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes">
+            <Device device-name="testDevice1"/>
+            <Device device-name="testDevice2"/>
+        </SilecsDesign>
+    </Controller>
+        <Controller host-name="Siemens_Step7Block">
+        <Siemens-PLC model="SIMATIC_S7-300" system="STEP-7" base-DB-number="0" protocol="DEVICE_MODE" />
+        <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes">
+            <Device device-name="testDevice1"/>
+            <Device device-name="testDevice2"/>
+        </SilecsDesign>
+    </Controller>
+    <Controller host-name="Siemens_Step7Device">
+        <Siemens-PLC model="SIMATIC_S7-300" system="STEP-7" base-DB-number="0" protocol="BLOCK_MODE" />
+        <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes">
+            <Device device-name="testDevice1"/>
+            <Device device-name="testDevice2"/>
+        </SilecsDesign>
+    </Controller>
+    <Controller host-name="Virtual_SiemensDevice">
+        <Virtual-Controller model="SIMATIC_S7-VIRTUAL"
+            system="SNAP7 linux32" base-DB-number="0" protocol="DEVICE_MODE" />
+        
+        <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes">
+            <Device device-name="testDevice1"/>
+            <Device device-name="testDevice2"/>
+        </SilecsDesign>
+    </Controller>
+    <Controller host-name="Virtual_SiemensBlock">
+        <Virtual-Controller model="SIMATIC_S7-VIRTUAL"
+            system="SNAP7 linux32" base-DB-number="0" protocol="BLOCK_MODE" />
+        
+        <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes">
+            <Device device-name="testDevice1"/>
+            <Device device-name="testDevice2"/>
+        </SilecsDesign>
+    </Controller>
+    <Controller host-name="Beckhoff_BC9020">
+        <Beckhoff-PLC model="BC9020" system="TWINCat" protocol="BLOCK_MODE" base-address="0" />
+        <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes">
+            <Device device-name="testDevice1"/>
+            <Device device-name="testDevice2"/>
+        </SilecsDesign>
+    </Controller>
+    <Controller host-name="Beckhoff_CX9020">
+        <Beckhoff-PLC model="CX9020" system="TWINCat" protocol="BLOCK_MODE" base-address="0" />
+        <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes">
+            <Device device-name="testDevice1"/>
+            <Device device-name="testDevice2"/>
+        </SilecsDesign>
+    </Controller>
+    <Controller host-name="Schneider_PremiumQuantum">
+        <Schneider-PLC model="Premium" system="UNITY Pro" protocol="BLOCK_MODE" base-address="0" />
+        <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes">
+            <Device device-name="testDevice1"/>
+            <Device device-name="testDevice2"/>
+        </SilecsDesign>
+    </Controller>
+    <Controller host-name="Schneider_M340">
+        <Schneider-PLC model="M340" system="UNITY Pro"
+            protocol="BLOCK_MODE" base-address="0" />
+        <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes">
+            <Device device-name="testDevice1"/>
+            <Device device-name="testDevice2"/>
+        </SilecsDesign>
+    </Controller>
+    <Controller host-name="Rabbit_DeviceMode">
+        <Rabbit-uC model="Rabbit_RCM_4010" system="Standard-C"
+            protocol="DEVICE_MODE" base-address="0" />
+        
+        <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes">
+            <Device device-name="testDevice1"/>
+            <Device device-name="testDevice2"/>
+        </SilecsDesign>
+    </Controller>
+    <Controller host-name="Rabbit_BlockMode">
+        <Rabbit-uC model="Rabbit_RCM_4010" system="Standard-C"
+            protocol="BLOCK_MODE" base-address="0" />
+        
+        <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="AllTypes">
+            <Device device-name="testDevice1"/>
+            <Device device-name="testDevice2"/>
+        </SilecsDesign>
+    </Controller>
+</SILECS-Deploy>
diff --git a/silecs-codegen/src/xml/test/AllTypesFESA.silecsdesign b/silecs-codegen/src/xml/test/AllTypesFESA.silecsdesign
new file mode 100644
index 0000000000000000000000000000000000000000..01c9edf3530200b4dbf73506c9c5662845633003
--- /dev/null
+++ b/silecs-codegen/src/xml/test/AllTypesFESA.silecsdesign
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<SILECS-Design silecs-version="0.10.0" created="06/27/16" updated="06/27/16" 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="/common/home/bel/schwinn/lnx/workspace-silecs-mars/silecs-model/src/xml/DesignSchema.xsd">
+    <Information>
+        <Owner user-login="schwinn"/>
+        <Editor user-login="schwinn"/>
+    </Information>
+    <SILECS-Class name="AllTypesFESA" version="0.1.0" domain="OPERATIONAL" >
+        <Block name="MyROBlock" mode="READ-ONLY" generateFesaProperty="true">
+            <Register name="RO_int8" format="int8" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_uint8" format="uint8" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_int16" format="int16" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_uint16" format="uint16" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_int32" format="int32" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_uint32" format="uint32" synchro="MASTER" generateFesaValueItem="true" />
+            <!--<Register name="RO_int64" format="int64" synchro="MASTER" generateFesaValueItem="true" /> not Supported for Beckhoff, Siemens and Schneider-->
+            <!--<Register name="RO_uint64" format="uint64" synchro="MASTER" generateFesaValueItem="true" /> not Supported for Beckhoff, Siemens and Schneider-->
+            <Register name="RO_float32" format="float32" synchro="MASTER" generateFesaValueItem="true" />
+            <!--<Register name="RO_float64" format="float64" synchro="MASTER" generateFesaValueItem="true" /> not Supported for Rabbit, Beckhoff, Siemens and Schneider-->
+            <Register name="RO_string" format="string" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_date" format="date" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_char" format="char" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_byte" format="byte" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_word" format="word" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_dword" format="dword" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_int" format="int" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_dint" format="dint" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_real" format="real" synchro="MASTER" generateFesaValueItem="true" />
+            <Register name="RO_dt" format="dt" synchro="MASTER" generateFesaValueItem="true" />
+        </Block>
+        <Block name="MyRWBlock" generateFesaProperty="true" mode="READ-WRITE">
+            <Register name="RW_int8" format="int8" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2" />
+            <Register name="RW_uint8" format="uint8" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_int16" format="int16" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_uint16" format="uint16" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_int32" format="int32" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_uint32" format="uint32" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <!--  <Register name="RW_int64" format="int64" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/> not Supported for Beckhoff, Siemens and Schneider-->
+            <!--<Register name="RW_uint64" format="uint64" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/> not Supported for Beckhoff, Siemens and Schneider-->
+            <Register name="RW_float32" format="float32" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <!--<Register name="RW_float64" format="float64" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/> not Supported for Rabbit, Beckhoff, Siemens and Schneider-->
+            <!--  <Register name="RW_string" format="string" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/> 2d string arrays not supported in FESA --> 
+            <Register name="RW_date" format="date" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_char" format="char" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_byte" format="byte" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_word" format="word" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_dword" format="dword" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_int" format="int" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_dint" format="dint" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_real" format="real" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+            <Register name="RW_dt" format="dt" synchro="MASTER" generateFesaValueItem="true" array-dim1="2" array-dim2="2"/>
+        </Block>
+        <Block name="MyWOBlock" generateFesaProperty="true" mode="WRITE-ONLY">
+            <Register name="WO_int8" format="int8" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_uint8" format="uint8" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_int16" format="int16" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_uint16" format="uint16" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_int32" format="int32" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_uint32" format="uint32" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <!--<Register name="WO_int64" format="int64" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/> not Supported for Beckhoff, Siemens and Schneider-->
+            <!--<Register name="WO_uint64" format="uint64" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/> not Supported for Beckhoff, Siemens and Schneider-->
+            <Register name="WO_float32" format="float32" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <!--<Register name="WO_float64" format="float64" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/> not Supported for Rabbit, Beckhoff, Siemens and Schneider-->
+            <Register name="WO_string" format="string" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_date" format="date" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_char" format="char" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_byte" format="byte" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_word" format="word" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_dword" format="dword" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_int" format="int" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_dint" format="dint" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_real" format="real" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+            <Register name="WO_dt" format="dt" synchro="SLAVE" generateFesaValueItem="true" array-dim1="10"/>
+        </Block>
+    </SILECS-Class>
+</SILECS-Design>
diff --git a/silecs-codegen/src/xml/test/__init__.py b/silecs-codegen/src/xml/test/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/silecs-codegen/src/xml/test/__init__.pyc b/silecs-codegen/src/xml/test/__init__.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..27028e401eb7955eeda0c476ee5ea6317451d8b0
Binary files /dev/null and b/silecs-codegen/src/xml/test/__init__.pyc differ
diff --git a/silecs-codegen/src/xml/test/fesa/DeploymentUnitTemplateFESA300.xml b/silecs-codegen/src/xml/test/fesa/DeploymentUnitTemplateFESA300.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c36d558c53daa1a70e4fca9fc2f2c75c040af452
--- /dev/null
+++ b/silecs-codegen/src/xml/test/fesa/DeploymentUnitTemplateFESA300.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deploy-unit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="">
+	<information>
+		<deploy-unit-name>Empty Template</deploy-unit-name>
+		<deploy-unit-major-version>0</deploy-unit-major-version>
+		<deploy-unit-minor-version>1</deploy-unit-minor-version>
+		<deploy-unit-tiny-version>0</deploy-unit-tiny-version>
+		<state>development</state>
+		<description>Empty Template description</description>
+		<fesa-version>0.9.1</fesa-version>
+		<repository-path></repository-path>
+		<build-time></build-time>
+	</information>
+	<ownership>
+		<responsible name="Undefined"/>
+		<creator login="Undefined"/>
+	</ownership>
+	<class>
+		<class-name>class-name</class-name>
+		<class-major-version>0</class-major-version>
+		<class-minor-version>1</class-minor-version>
+		<class-tiny-version>0</class-tiny-version>
+		<device-instance>required</device-instance>
+	</class>
+	<executable>
+		<server extension="_S" />
+	</executable>
+</deploy-unit>
diff --git a/silecs-codegen/src/xml/test/fesa/GSIClassTemplateFESA300.xml b/silecs-codegen/src/xml/test/fesa/GSIClassTemplateFESA300.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f84b0aed9a0fb22801d61035eeb0532fcb6c104b
--- /dev/null
+++ b/silecs-codegen/src/xml/test/fesa/GSIClassTemplateFESA300.xml
@@ -0,0 +1,657 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<equipment-model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../design-gsi.xsd">
+	<information>
+	  	<class-name>GSIClassTemplate</class-name>
+		<class-major-version>0</class-major-version>
+		<class-minor-version>1</class-minor-version>
+		<class-tiny-version>0</class-tiny-version>
+		<type>Final</type>
+		<state>development</state>
+		<description>An Empty design with GSI-specific standard properties</description>
+		<fesa-version>3.0.0</fesa-version>
+		<repository-path>undefined</repository-path>
+	</information>
+	<ownership>
+		<responsible name="CSCO"/>
+		<creator login="Undefined"/>
+	</ownership>
+        <interface>
+        <device-interface>
+            <setting>
+                <GSI-Init-Property multiplexed="false" name="Init" visibility="operational">
+                    <set-action partial-setting="true" transaction="true">
+                        <server-action-ref server-action-name-ref="InitSetAction"/>
+                    </set-action>
+                </GSI-Init-Property>
+                <GSI-Reset-Property multiplexed="false" name="Reset" visibility="operational">
+                    <set-action partial-setting="true" transaction="true">
+                        <server-action-ref server-action-name-ref="ResetSetAction"/>
+                    </set-action>
+                </GSI-Reset-Property>
+                <GSI-Setting-Property multiplexed="false" name="Setting" visibility="operational">
+                    <update-flag-item direction="OUT" name="updateFlags" optional="true">
+                       <builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                    </update-flag-item>
+                    <cycle-name-item direction="OUT" name="cycleName" optional="true">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </cycle-name-item>
+                    <set-action partial-setting="true" transaction="true">
+                        <server-action-ref server-action-name-ref="SettingSetAction"/>
+                    </set-action>
+                    <get-action>
+                        <server-action-ref server-action-name-ref="SettingGetAction"/>
+                    </get-action>
+                </GSI-Setting-Property>
+                <GSI-Power-Property multiplexed="false" name="Power" visibility="operational">
+                    <update-flag-item direction="OUT" name="updateFlags" optional="true">
+						<builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                    </update-flag-item>
+                    <cycle-name-item direction="OUT" name="cycleName" optional="true">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </cycle-name-item>
+                    <set-action partial-setting="true" transaction="true">
+                        <server-action-ref server-action-name-ref="PowerSetAction"/>
+                    </set-action>
+                    <get-action>
+                        <server-action-ref server-action-name-ref="PowerGetAction"/>
+                    </get-action>
+                    <power-item direction="INOUT" name="power">
+                        <custom-type-scalar data-type-name-ref="DEVICE_POWER"/>
+                        
+                        <data-field-ref field-name-ref="power"/>
+                    </power-item>
+                </GSI-Power-Property>
+            </setting>
+            <acquisition>
+                <GSI-Status-Property multiplexed="false" name="Status" on-change="true" subscribable="true" visibility="operational">
+                    <acq-stamp-item direction="OUT" name="acqStamp">
+                        <scalar type="int64_t"/>
+                    </acq-stamp-item>
+                    <update-flag-item direction="OUT" name="updateFlags" optional="true">
+                        <builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                    </update-flag-item>
+                    <cycle-name-item direction="OUT" name="cycleName" optional="true">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </cycle-name-item>
+                    <cycle-stamp-item direction="OUT" name="cycleStamp" optional="true">
+                        <scalar type="int64_t"/>
+                    </cycle-stamp-item>
+                    <get-action>
+                        <server-action-ref server-action-name-ref="StatusGetAction"/>
+                    </get-action>
+                    <status-item direction="OUT" name="status">
+                        <custom-type-scalar data-type-name-ref="DEVICE_STATUS"/>
+                        
+                        <data-field-ref field-name-ref="status"/>
+                    </status-item>
+                    <detailed-status-item direction="OUT" name="detailedStatus">
+                        <array type="bool">
+                            <custom-constant-dim constant-name-ref="DETAILED_STATUS_SIZE"/>
+                        </array>
+                        <data-field-ref field-name-ref="detailedStatus"/>
+                    </detailed-status-item>
+                    <detailed-status-labels-item direction="OUT" name="detailedStatus_labels">
+                        <array2D type="char">
+                            <custom-constant-dim1 constant-name-ref="DETAILED_STATUS_SIZE"/>
+                            <custom-constant-dim2 constant-name-ref="MAX_DETAILED_STATUS_LABEL_LENGTH"/>
+                        </array2D>
+                        <data-field-ref field-name-ref="detailedStatus_labels"/>
+                    </detailed-status-labels-item>
+                    <detailed-status-severity-item direction="OUT" name="detailedStatus_severity">
+                        <custom-type-array data-type-name-ref="DETAILED_STATUS_SEVERITY">
+                            <custom-constant-dim constant-name-ref="DETAILED_STATUS_SIZE"/>
+                        </custom-type-array>
+                        <data-field-ref field-name-ref="detailedStatus_severity"/>
+                    </detailed-status-severity-item>
+                    <powerState-item direction="OUT" name="powerState">
+                        <custom-type-scalar data-type-name-ref="DEVICE_POWER_STATE"/>
+                        
+                        <data-field-ref field-name-ref="powerState"/>
+                    </powerState-item>
+                    <control-item direction="OUT" name="control">
+                        <custom-type-scalar data-type-name-ref="DEVICE_CONTROL"/>
+                        
+                        <data-field-ref field-name-ref="control"/>
+                    </control-item>
+                    <interlock-item direction="OUT" name="interlock">
+                        <scalar type="bool"/>
+                        <data-field-ref field-name-ref="interlock"/>
+                    </interlock-item>
+                    <opReady-item direction="OUT" name="opReady">
+                        <scalar type="bool"/>
+                        <data-field-ref field-name-ref="opReady"/>
+                    </opReady-item>
+                    <modulesReady-item direction="OUT" name="modulesReady">
+                        <scalar type="bool"/>
+                        <data-field-ref field-name-ref="modulesReady"/>
+                    </modulesReady-item>
+                    <error_collection-item direction="OUT">
+                        <error_codes direction="OUT" name="error_codes">
+                            <array type="int32_t">
+                                <custom-constant-dim constant-name-ref="MAX_NUMBER_OF_ERROR_MESSAGES"/>
+                            </array>
+                        </error_codes>
+                        <error_messages direction="OUT" name="error_messages">
+                            <array2D type="char">
+                                <custom-constant-dim1 constant-name-ref="MAX_NUMBER_OF_ERROR_MESSAGES"/>
+                                <custom-constant-dim2 constant-name-ref="MAX_ERROR_MESSAGE_LENGTH"/>
+                            </array2D>
+                        </error_messages>
+                        <error_timestamps direction="OUT" name="error_timestamps">
+                            <array type="int64_t">
+                                <custom-constant-dim constant-name-ref="MAX_NUMBER_OF_ERROR_MESSAGES"/>
+                            </array>
+                        </error_timestamps>
+                        <error_cycle_names direction="OUT" name="error_cycle_names">
+                            <array2D type="char">
+                                <custom-constant-dim1 constant-name-ref="MAX_NUMBER_OF_ERROR_MESSAGES"/>
+                                <custom-constant-dim2 constant-name-ref="MAX_ERROR_MESSAGE_LENGTH"/>
+                            </array2D>
+                        </error_cycle_names>
+                        <error_collection-field-ref field-name-ref="error_collection"/>
+                    </error_collection-item>
+                </GSI-Status-Property>
+                <GSI-ModuleStatus-Property visibility="development" subscribable="true" name="ModuleStatus" multiplexed="false">
+                	<acq-stamp-item name="acqStamp" direction="OUT">
+                		<scalar type="int64_t" />
+                	</acq-stamp-item>
+                	<update-flag-item optional="true" name="updateFlags" direction="OUT">
+                		<builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE" />
+                	</update-flag-item>
+                	<cycle-name-item optional="true" name="cycleName" direction="OUT">
+                		<array type="char">
+                			<dim>32</dim>
+                		</array>
+                	</cycle-name-item>
+                	<cycle-stamp-item optional="true" name="cycleStamp" direction="OUT">
+                		<scalar type="int64_t" />
+                	</cycle-stamp-item>
+                	<get-action>
+                		<server-action-ref server-action-name-ref="ModuleStatusGetAction" />
+                	</get-action>
+                	<module-status-item name="moduleStatus" direction="OUT">
+                		<custom-type-array data-type-name-ref="MODULE_STATUS">
+                			<custom-constant-dim constant-name-ref="MODULE_STATUS_SIZE" />
+                			
+                		</custom-type-array>
+                		
+                		<data-field-ref field-name-ref="moduleStatus" />
+                	</module-status-item>
+                	<module-status-labels-item name="moduleStatus_labels" direction="OUT">
+                		<array2D type="char">
+                			<custom-constant-dim1 constant-name-ref="MODULE_STATUS_SIZE" />
+                			<custom-constant-dim2 constant-name-ref="MAX_MODULE_STATUS_LABEL_LENGTH" />
+                			
+                		</array2D>
+                		
+                		<data-field-ref field-name-ref="moduleStatus_labels" />
+                	</module-status-labels-item>
+                </GSI-ModuleStatus-Property>
+                <GSI-Acquisition-Property multiplexed="true" name="Acquisition" on-change="true" subscribable="true" visibility="operational">
+                    <acq-stamp-item direction="OUT" name="acqStamp">
+                        <scalar type="int64_t"/>
+                    </acq-stamp-item>
+                    <update-flag-item direction="OUT" name="updateFlags" optional="true">
+                        <builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                    </update-flag-item>
+                    <cycle-name-item direction="OUT" name="cycleName" optional="true">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </cycle-name-item>
+                    <cycle-stamp-item direction="OUT" name="cycleStamp" optional="true">
+                        <scalar type="int64_t"/>
+                    </cycle-stamp-item>
+                    <get-action>
+                        <server-action-ref server-action-name-ref="AcquisitionGetAction"/>
+                    </get-action>
+                    <acquisition-context-item direction="OUT">
+                        <acqStamp direction="OUT" name="acqStampGSI">
+                            <scalar type="int64_t"/>
+                        </acqStamp>
+                        <cycleStamp direction="OUT" name="cycleStampGSI">
+                            <scalar type="int64_t"/>
+                        </cycleStamp>
+                        <cycleName direction="OUT" name="cycleNameGSI">
+                            <array type="char">
+                                <custom-constant-dim constant-name-ref="MAX_CYCLE_NAME_LENGTH"/>
+                            </array>
+                        </cycleName>
+                        <beamProcessID direction="OUT" name="beamProcessID">
+                            <scalar type="int32_t"/>
+                        </beamProcessID>
+                         <sequenceID direction="OUT" name="sequenceID">
+                            <scalar type="int32_t"/>
+                        </sequenceID>
+                        <acquisition-context-field-ref field-name-ref="acquisitionContext"/>
+                    </acquisition-context-item>
+                </GSI-Acquisition-Property>
+                <GSI-Version-Property multiplexed="false" name="Version" on-change="false" subscribable="false" visibility="operational">
+                    <acq-stamp-item direction="OUT" name="acqStamp">
+                        <scalar type="int64_t"/>
+                    </acq-stamp-item>
+                    <update-flag-item direction="OUT" name="updateFlags" optional="true">
+                        <builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                    </update-flag-item>
+                    <cycle-name-item direction="OUT" name="cycleName" optional="true">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </cycle-name-item>
+                    <cycle-stamp-item direction="OUT" name="cycleStamp" optional="true">
+                        <scalar type="int64_t"/>
+                    </cycle-stamp-item>
+                    <get-action>
+                        <server-action-ref server-action-name-ref="VersionGetAction"/>
+                    </get-action>
+                    <version-item direction="OUT" name="classVersion">
+                        <array type="char">
+                            <custom-constant-dim constant-name-ref="MAX_VERSION_NAME_LENGTH"/>
+                        </array>
+                    </version-item>
+                    <version-item direction="OUT" name="deployUnitVersion">
+                        <array type="char">
+                            <custom-constant-dim constant-name-ref="MAX_VERSION_NAME_LENGTH"/>
+                        </array>
+                    </version-item>
+                    <version-item direction="OUT" name="fesaVersion">
+                        <array type="char">
+                            <custom-constant-dim constant-name-ref="MAX_VERSION_NAME_LENGTH"/>
+                        </array>
+                    </version-item>
+                </GSI-Version-Property>
+         </acquisition>
+      </device-interface>
+        <global-interface>
+            <setting>
+                <diagnostic-property multiplexed="false" name="DiagnosticSetting" visibility="expert">
+                    <description>Generic property which allows to diagnose any FESA classes</description>
+                        <mode-item direction="INOUT" name="enableDiagMode">
+                            <scalar type="bool"/>
+                        </mode-item>
+                        <host-item direction="INOUT" name="hostName">
+                            <array type="char">
+                                <dim>32</dim>
+                            </array>
+                        </host-item>
+                        <port-item direction="INOUT" name="portNumber">
+                            <scalar type="int32_t"/>
+                        </port-item>
+                        <config-item direction="IN" name="requestConfig">
+                            <scalar type="bool"/>
+                        </config-item>
+                        <state-item direction="IN" name="requestState">
+                            <scalar type="bool"/>
+                        </state-item>
+                        <fwk-topic-item direction="INOUT" name="fwkTopic">
+                            <builtin-type-scalar data-type-name-ref="DIAG_FWK_TOPIC"/>
+                        </fwk-topic-item>
+                        <custom-topic-item direction="INOUT" name="customTopic">
+                            <custom-type-scalar data-type-name-ref="DIAG_TOPIC"/>
+                        </custom-topic-item>
+                        <device-trace-item direction="INOUT" name="traceDevices">
+                            <array type="char">
+                                <dim>320</dim>
+                            </array>
+                        </device-trace-item>
+                        <bypass-action-item direction="INOUT" name="bypassActions">
+                            <array type="char">
+                                <dim>320</dim>
+                            </array>
+                        </bypass-action-item>
+                </diagnostic-property>
+            </setting>
+            <acquisition>
+                <GSI-DeviceDescription-Property multiplexed="false" name="DeviceDescription" on-change="false" subscribable="false" visibility="operational">
+                    <timing-info-item direction="OUT" name="deviceNameTimingReceiver">
+                        <array type="char">
+                            <variable-dim/>
+                        </array>
+                        <data-field-ref field-name-ref="deviceNameTimingReceiver"/>
+                    </timing-info-item>
+                    <property-info-item direction="OUT" name="propertyNames">
+                        <array2D type="char">
+                            <variable-dim1/>
+                            <variable-dim2/>
+                        </array2D>
+                    </property-info-item>
+                    <device-info-item direction="OUT" name="deviceNames">
+                        <array2D type="char">
+                            <variable-dim1/>
+                            <variable-dim2/>
+                        </array2D>
+                    </device-info-item>
+                    <global-device-info-item direction="OUT" name="globalDeviceName">
+                        <array type="char">
+                            <variable-dim/>
+                        </array>
+                    </global-device-info-item>
+                    <host-info-item direction="OUT" name="host">
+                        <array type="char">
+                            <variable-dim/>
+                        </array>
+                    </host-info-item>
+                </GSI-DeviceDescription-Property>
+            </acquisition>
+        </global-interface>
+    </interface>
+    <builtin-types>
+		<notification-update-enum name="NOTIFICATION_UPDATE">
+            <IMMEDIATE access="RO" symbol="IMMEDIATE" value="1"/>
+            <SET access="RO" symbol="SET" value="2"/>
+        </notification-update-enum>
+        <diag-fwk-topic name="DIAG_FWK_TOPIC">
+            <b0 name="SRV_GET_ACTION_PROFIING"/>
+            <b1 name="SRV_SET_ACTION_PROFILING"/>
+            <b2 name="RT_ACTION_PROFILING"/>
+            <b3 name="EVENT_PROFILING"/>
+            <b4 name="NOTIFICATION_PROFILING"/>
+            <b5 name="SRV_GET_ACTION_TRACKING"/>
+            <b6 name="SRV_SET_ACTION_TRACKING"/>
+            <b7 name="RT_ACTION_TRACKING"/>
+            <b8 name="EVENT_TRACKING"/>
+            <b9 name="NOTIFICATION_TRACKING"/>
+            <b10 name="PERSISTENCY_TRACKING"/>
+            <b11 name="TRANSACTION_TRACKING"/>
+            <b12 name="SUBSCRIPTION_TRACKING"/>
+            <b13 name="SIGNAL_HANDLER_TRACKING"/>
+            <b14 name="LOCAL_CONNECTION_TRACKING"/>
+        </diag-fwk-topic>
+        <fault-severity name="FaultSeverity">
+        	<description>Enumeration listing the available fault severities used by the fault fields</description>
+        	<INFO access="RO" meaning="NONE" value="0" symbol="INFO" />
+        	<WARNING access="RO" meaning="WARNING" value="1" symbol="WARNING" />
+        	<ERROR access="RO" meaning="ERROR" value="2" symbol="ERROR" />
+        	<CRITICAL access="RO" meaning="ERROR" value="3" symbol="CRITICAL" />
+        </fault-severity>
+
+    </builtin-types>
+    <custom-types>
+        <diag-custom-topic name="DIAG_TOPIC">
+        </diag-custom-topic>
+        <enum name="DEVICE_STATUS">
+        <!--Possible (mutually exclusive) values to describe the device status-->
+            
+            <item access="RW" meaning="NONE" symbol="UNKNOWN" value="0"/>
+            <!--The device status is unknown-->
+            
+            <item access="RW" meaning="NONE" symbol="OK" value="1"/>
+            <!--The device is in fully operational state-->
+            
+            <item access="RW" meaning="NONE" symbol="WARNING" value="2"/>
+            <!--The device is not fully operational; A device in WARNING state can still be used operationally, -->
+            <!--but clients must be informed of a problem that might become worse. Details are explained in the errorMsg field.-->
+            
+            <item access="RW" meaning="NONE" symbol="ERROR" value="3"/>
+            <!--The device is in a fault state. Details are explained in the errorMsg field-->
+        </enum>
+        <enum name="DEVICE_POWER_STATE">
+        <!--Possible (mutually exclusive) values to describe the power-state of the device.-->
+            
+            <item access="RW" meaning="NONE" symbol="UNKNOWN" value="0"/>
+            <!--The device mode is unknown-->
+            
+            <item access="RW" meaning="ON" symbol="ON" value="1"/>
+            <!--The device is in fully operational state-->
+            
+            <item access="RW" meaning="NONE" symbol="OFF" value="2"/>
+            <!--The device is turned off-->
+            
+            <item access="RW" meaning="NONE" symbol="STANDBY" value="3"/>
+            <!--The device is in a stand-by mode. This mode is a sort of “parking mode” in which the device can -->
+            <!--stay for hours or even days. It is defined by the following characteristics:-->
+            <!--It is safe, it does not wear out, it consumes little energy.-->
+            <!--Furthermore, it takes a short time to go from STANDBY to ON mode-->
+            
+            <item access="RW" meaning="NONE" symbol="POWER_DOWN" value="4"/>
+            <!--The device is shutting down. Note that some properties may not be accessible during this time.-->
+            <!--After shutdown the device will be in the mode OFF-->
+            
+            <item access="RW" meaning="NONE" symbol="POWER_UP" value="5"/>
+            <!--The device is starting up. Note that some properties may not be accessible during this time.-->
+            <!--After (re-)starting the device probably will be in the mode ON-->
+            
+        </enum>
+        <enum name="DEVICE_POWER">
+        <!--An enumeration Type used to control the operational mode of the device.-->
+        <!--Its values are a subset of those in the DEVICE_POWER_STATE type-->
+            <item access="RW" meaning="ON" symbol="ON" value="1"/>
+            <!--The device is in fully operational state-->     
+            
+            <item access="RW" meaning="OFF" symbol="OFF" value="2"/>
+            <!--The device is turned off-->
+        </enum>
+        <enum name="DEVICE_CONTROL">
+        <!--Possible values to describe the control mode of a device-->
+        <!--Currently two control modes (LOCAL, REMOTE) are defined-->
+        
+            <item access="RW" meaning="NONE" symbol="REMOTE" value="0"/>
+            <!--The device can be controlled normally through the control system-->
+            
+            <item access="RW" meaning="NONE" symbol="LOCAL" value="1"/>
+            <!--The device can be controlled locally. But it can be accessed in read-only mode via the control system-->
+        </enum>
+        <enum name="TOL_CHECK_MODE">
+        <!--This constant defines possible modes to check whether a control value is inside the tolerance values.-->
+        <!--Used to give information on how the tolerance fields are used to calculate the xxx_status information.-->
+        
+            <item access="RO" symbol="ABS" value="0"/>
+            <!--Use the absolute tolerance _tolAbs-->
+            
+            <item access="RO" symbol="REL" value="1"/>
+            <!--Use the relative tolerance _tolRel-->
+        </enum>
+        <bit-enum-32bits name="AQN_STATUS">
+        <!--Possible values to describe the acquisition status of a field (in the _status suffix)-->
+        <!--If this suffix is missing, it means that no additional status information is provided for the corresponding field-->
+        <!--If all bits are 0, this means that the corresponding field is OK.-->
+        <!--Only the lower 16 bits are standardized, the upper 16 bits can be defined by the equipment specialist.-->
+        <!--The difference between the Status property and the _status suffix is described in the section on the Status property.-->
+            <b0 name="NOT_OK"/>
+            <!--Some problem occurred that is not represented by the other bits. This property is called-->
+            <!-- NOT_OK so that it is not mixed up with ERROR or WARNING in the Status property-->
+            <b1 name="BAD_QUALITY"/>
+            <!--The value was acquired with a degraded quality. This is typically used for measurements.-->
+            <b2 name="DIFFERENT_FROM_SETTING"/>
+            <!--Different from the requested control value (for discrete values)--><!--or out of tolerance (for continuous values).-->
+            <b3 name="OUT_OF_RANGE"/>
+            <!--The value is out of the normal range (e.g. a temperature is too high or too low).-->
+            <b4 name="BUSY"/>
+            <!--The property value is changing in response to receiving a new control value (e.g. moving to a-->
+            <!--new position, charging a capacitor, ...). If the value change does not reach the requested new-->
+            <!--value within the maximum timeout, the BUSY bit should remain=1 and the TIMEOUT bit must be turned on.-->
+            <b5 name="TIMEOUT"/>
+            <!--A timeout occurred, because the property did not reach the reqested new control value within the-->
+            <!--maximum allowable time. A timeout normally indicates a problem to be addressed by the-->
+            <!--equipment specialist. This is typically used for slow changing control values that are BUSY while they change.-->
+            <b6 name="bit6_is_reserved_for_later_usage"/>
+            <b7 name="bit7_is_reserved_for_later_usage"/>
+            <b8 name="bit8_is_reserved_for_later_usage"/>
+            <b9 name="bit9_is_reserved_for_later_usage"/>
+            <b10 name="bit10_is_reserved_for_later_usage"/>
+            <b11 name="bit11_is_reserved_for_later_usage"/>
+            <b12 name="bit12_is_reserved_for_later_usage"/>
+            <b13 name="bit13_is_reserved_for_later_usage"/>
+            <b14 name="bit14_is_reserved_for_later_usage"/>
+            <b15 name="bit15_is_reserved_for_later_usage"/>
+            <!--bit 6 to 15 are reserved ... dont use them!-->
+            
+            <b16 name="bit_16_and_higher_can_be_used_by_the_class_developer"/>
+            <!--into bit 16..32 you can put in anything you want-->
+        </bit-enum-32bits>
+
+        <struct name="GSI_ERROR">
+        <!--This struct-item describes the structure of an GSI-error-->
+            <struct-item name="error_string">
+            <!--This string holds the error-message-->
+                <array type="char">
+                    <custom-constant-dim constant-name-ref="MAX_ERROR_MESSAGE_LENGTH"/>
+                </array>
+            </struct-item>
+            <struct-item name="error_code">
+            <!--The error code according to the defined error-message-->
+                <scalar type="int32_t"/>
+            </struct-item>
+            <!--The timestamp when the error occured-->
+            <struct-item name="error_timestamp">
+                <scalar type="int64_t"/>
+            </struct-item>
+            <!--The cycle for which the error occured-->
+            <struct-item name="error_cycle_name">
+                <array type="char">
+                    <custom-constant-dim constant-name-ref="MAX_CYCLE_NAME_LENGTH"/>
+                </array>
+            </struct-item>
+        </struct>
+        <struct name="GSI_ACQ_CONTEXT">
+        <!--This struct-item describes all AcquisitionContext items which are relevant for GSI-->
+            <struct-item name="acqStamp">
+            <!--The acquisition stamp is used to indicate when a measurement was done -->
+                <scalar type="int64_t"/>
+            </struct-item>
+            <struct-item name="cycleStamp">
+            <!--The cycle stamp is used to indicate when a specific cycle has started-->
+                <scalar type="int64_t"/>
+            </struct-item>
+            <struct-item name="cycleName">
+            <!--The cycle name indicates the cycle which started at time of the cycleStamp -->
+                <array type="char">
+                    <custom-constant-dim constant-name-ref="MAX_CYCLE_NAME_LENGTH"/>    
+                </array>
+            </struct-item>
+            <struct-item name="beamProcessID">
+				<scalar type="int32_t"/>
+            </struct-item>
+            <struct-item name="sequenceID">
+				<scalar type="int32_t"/>
+            </struct-item>
+        </struct>
+        <constant name="MAX_ERROR_MESSAGE_LENGTH" type="uint32_t" value="256"/>
+        <constant name="MAX_NUMBER_OF_ERROR_MESSAGES" type="uint32_t" value="16"/>
+        <constant name="MAX_CYCLE_NAME_LENGTH" type="uint32_t" value="256"/>
+        <constant name="MAX_VERSION_NAME_LENGTH" type="uint32_t" value="256"/>
+        <constant name="MAX_DETAILED_STATUS_LABEL_LENGTH" type="uint32_t" value="30"/>
+        <constant name="DETAILED_STATUS_SIZE" type="uint32_t" value="2"/>
+        <enum name="DETAILED_STATUS_SEVERITY">
+            <item access="RO" symbol="INFO" value="0"/>
+            <item access="RO" symbol="WARNING_ON_FALSE" value="1"/>
+            <item access="RO" symbol="ERROR_ON_FALSE" value="2"/>
+        </enum>
+        <enum name="MODULE_STATUS">
+        <!-- Mutually exclusive values to describe the status of a hardware / software module-->
+        	<item access="RO" value="0" symbol="UNKNOWN" />
+        	<!--The status of the module is not known-->
+        	<item access="RO" value="1" symbol="OK" />
+        	<!--The module is in fully operational state-->
+        	<item access="RO" value="2" symbol="WARNING" />
+        	<!--The module is not fully operational; A module in WARNING state may still be used operationally, -->
+        	<!--but clients must be informed of a problem that might become worse. -->
+        	<item access="RO" value="3" symbol="ERROR" />
+        	<!--The module is in a fault state. The related device is not operational.-->
+        	<item access="RO" value="4" symbol="NOT_AVAILABLE" />
+            <!--The module is missing. The related device is not operational.-->
+        </enum>
+        <constant name="MAX_MODULE_STATUS_LABEL_LENGTH" type="uint32_t" value="30"/>
+        <constant name="MODULE_STATUS_SIZE" type="uint32_t" value="2"/>
+    </custom-types>
+    <data>
+        <device-data>
+            <configuration>
+                <GSI-detailed-status-labels-field name="detailedStatus_labels">
+                    <array2D type="char">
+                        <custom-constant-dim1 constant-name-ref="DETAILED_STATUS_SIZE"/>
+                        <custom-constant-dim2 constant-name-ref="MAX_DETAILED_STATUS_LABEL_LENGTH"/>
+                    </array2D>
+                    <default>{myStatusLabel1,myStatusLabel2}</default>
+                </GSI-detailed-status-labels-field>
+                <GSI-detailed-status-severity-field name="detailedStatus_severity">
+                    <custom-type-array data-type-name-ref="DETAILED_STATUS_SEVERITY">
+                        <custom-constant-dim constant-name-ref="DETAILED_STATUS_SIZE"/>
+                    </custom-type-array>
+                    <default>{INFO,INFO}</default>
+                </GSI-detailed-status-severity-field>
+                <GSI-module-status-labels-field name="moduleStatus_labels">
+                	<array2D type="char">
+                		<custom-constant-dim1 constant-name-ref="MODULE_STATUS_SIZE" />
+                		
+                		<custom-constant-dim2 constant-name-ref="MAX_MODULE_STATUS_LABEL_LENGTH" />
+                	</array2D>
+                	<default>{myModule1,myModule2}</default>
+                </GSI-module-status-labels-field>
+            </configuration>
+            <setting>
+                <GSI-power-field multiplexed="false" name="power" persistent="false">
+                    <custom-type-scalar data-type-name-ref="DEVICE_POWER"/>
+                </GSI-power-field>
+            </setting>
+            <acquisition>
+                <GSI-control-field multiplexed="false" name="control">
+                    <custom-type-scalar data-type-name-ref="DEVICE_CONTROL"/>
+                </GSI-control-field>
+                <GSI-powerState-field multiplexed="false" name="powerState">
+                    <custom-type-scalar data-type-name-ref="DEVICE_POWER_STATE"/>
+                </GSI-powerState-field>
+                <GSI-status-field multiplexed="false" name="status">
+                    <custom-type-scalar data-type-name-ref="DEVICE_STATUS"/>
+                </GSI-status-field>
+                <GSI-interlock-field multiplexed="false" name="interlock">
+                    <scalar type="bool"/>
+                </GSI-interlock-field>
+                <GSI-opReady-field multiplexed="false" name="opReady">
+                    <scalar type="bool"/>
+                </GSI-opReady-field>
+                <GSI-modulesReady-field name="modulesReady" multiplexed="false">
+                	<scalar type="bool" />
+                </GSI-modulesReady-field>
+                <GSI-detailed-status-field multiplexed="false" name="detailedStatus">
+                    <array type="bool">
+                        <custom-constant-dim constant-name-ref="DETAILED_STATUS_SIZE"/>
+                    </array>
+                </GSI-detailed-status-field>
+                <GSI-module-status-field name="moduleStatus" multiplexed="false">
+                	<custom-type-array data-type-name-ref="MODULE_STATUS">
+                		<custom-constant-dim constant-name-ref="MODULE_STATUS_SIZE" />
+                		
+                	</custom-type-array>
+                </GSI-module-status-field>
+                <GSI-acquisition-context-field multiplexed="true" name="acquisitionContext">
+                    <custom-type-scalar data-type-name-ref="GSI_ACQ_CONTEXT"/>
+                </GSI-acquisition-context-field>
+                <GSI-error_collection-field multiplexed="false" name="error_collection">
+                    <custom-type-array data-type-name-ref="GSI_ERROR">
+                        <custom-constant-dim constant-name-ref="MAX_NUMBER_OF_ERROR_MESSAGES"/>
+                    </custom-type-array>
+                </GSI-error_collection-field>
+            </acquisition>
+        </device-data>
+        <global-data>
+            <configuration>
+                <!-- The name of the timing receiver -->
+                <GSI-timing-receiver-name-field name="deviceNameTimingReceiver">
+                    <array type="char">
+                        <!-- The number of the timing receiver -->
+                        <variable-dim/>
+                    </array>
+                </GSI-timing-receiver-name-field>
+                </configuration>
+        </global-data>
+    </data>
+    <actions>
+        <set-server-action implementation="default" name="InitSetAction"/>
+        <set-server-action implementation="default" name="ResetSetAction"/>
+        <set-server-action implementation="default" name="SettingSetAction"/>
+        <set-server-action implementation="default" name="PowerSetAction"/>
+        <get-server-action implementation="default" name="PowerGetAction"/>
+        <get-server-action implementation="default" name="SettingGetAction"/>
+        <get-server-action implementation="default" name="AcquisitionGetAction"/>
+        <get-server-action implementation="default" name="StatusGetAction"/>
+        <get-server-action implementation="default" name="VersionGetAction"/><get-server-action implementation="default" name="ModuleStatusGetAction"></get-server-action>
+    </actions>
+
+</equipment-model>
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/fesa/__init__.py b/silecs-codegen/src/xml/test/fesa/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/silecs-codegen/src/xml/test/fesa/__init__.pyc b/silecs-codegen/src/xml/test/fesa/__init__.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..68e4dc6ffb146fbdf6125762cdd0dfaa2fe05df9
Binary files /dev/null and b/silecs-codegen/src/xml/test/fesa/__init__.pyc differ
diff --git a/silecs-codegen/src/xml/test/fesa/emptyTemplateFESA300.xml b/silecs-codegen/src/xml/test/fesa/emptyTemplateFESA300.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b6c304461d2c6bd079e08a5e177834438890cc92
--- /dev/null
+++ b/silecs-codegen/src/xml/test/fesa/emptyTemplateFESA300.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<equipment-model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../FESA_Metamodel-lab.xsd">
+    <information>
+        <class-name>EmptyTemplate</class-name>
+        <class-major-version>0</class-major-version>
+        <class-minor-version>1</class-minor-version>
+        <class-tiny-version>0</class-tiny-version>
+        <type>Final</type>
+        <state>development</state>
+        <description>An Empty design</description>
+        <fesa-version>0.9.0</fesa-version>
+        <repository-path>undefined</repository-path>
+    </information>
+    <ownership>
+        <responsible name="Undefined" />
+        <creator login="Undefined" />
+    </ownership>
+    <interface>
+        <global-interface>
+            <setting>
+                <diagnostic-property multiplexed="false" name="DiagnosticSetting" visibility="expert">
+                    <description>Generic property which allows to diagnose any FESA classes</description>
+                    <mode-item direction="INOUT" name="enableDiagMode">
+                        <scalar type="bool" />
+                    </mode-item>
+                    <host-item direction="INOUT" name="hostName">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </host-item>
+                    <port-item direction="INOUT" name="portNumber">
+                        <scalar type="int32_t" />
+                    </port-item>
+                    <config-item direction="IN" name="requestConfig">
+                        <scalar type="bool" />
+                    </config-item>
+                    <state-item direction="IN" name="requestState">
+                        <scalar type="bool" />
+                    </state-item>
+                    <fwk-topic-item direction="INOUT" name="fwkTopic">
+                        <builtin-type-scalar data-type-name-ref="DIAG_FWK_TOPIC" />
+                    </fwk-topic-item>
+                    <custom-topic-item direction="INOUT" name="customTopic">
+                        <custom-type-scalar data-type-name-ref="DIAG_TOPIC" />
+                    </custom-topic-item>
+                    <device-trace-item direction="INOUT" name="traceDevices">
+                        <array type="char">
+                            <dim>320</dim>
+                        </array>
+                    </device-trace-item>
+                    <bypass-action-item direction="INOUT" name="bypassActions">
+                        <array type="char">
+                            <dim>320</dim>
+                        </array>
+                    </bypass-action-item>
+                </diagnostic-property>
+            </setting>
+        </global-interface>
+    </interface>
+    <builtin-types>
+        <notification-update-enum name="NOTIFICATION_UPDATE">
+            <IMMEDIATE access="RO" symbol="IMMEDIATE" value="1" />
+            <SET access="RO" symbol="SET" value="2" />
+        </notification-update-enum>
+        <diag-fwk-topic name="DIAG_FWK_TOPIC">
+            <b0 name="SRV_GET_ACTION_PROFIING" />
+            <b1 name="SRV_SET_ACTION_PROFILING" />
+            <b2 name="RT_ACTION_PROFILING" />
+            <b3 name="EVENT_PROFILING" />
+            <b4 name="NOTIFICATION_PROFILING" />
+            <b5 name="SRV_GET_ACTION_TRACKING" />
+            <b6 name="SRV_SET_ACTION_TRACKING" />
+            <b7 name="RT_ACTION_TRACKING" />
+            <b8 name="EVENT_TRACKING" />
+            <b9 name="NOTIFICATION_TRACKING" />
+            <b10 name="PERSISTENCY_TRACKING" />
+            <b11 name="TRANSACTION_TRACKING" />
+            <b12 name="SUBSCRIPTION_TRACKING" />
+            <b13 name="SIGNAL_HANDLER_TRACKING" />
+            <b14 name="LOCAL_CONNECTION_TRACKING" />
+        </diag-fwk-topic>
+        <fault-severity name="FaultSeverity">
+            <description>Enumeration listing the available fault severities used by the fault fields</description>
+            <INFO access="RO" symbol="INFO" value="0" meaning="NONE" />
+            <WARNING access="RO" symbol="WARNING" value="1" meaning="WARNING" />
+            <ERROR access="RO" symbol="ERROR" value="2" meaning="ERROR" />
+            <CRITICAL access="RO" symbol="CRITICAL" value="3" meaning="ERROR" />
+        </fault-severity>
+    </builtin-types>
+    <custom-types>
+        <diag-custom-topic name="DIAG_TOPIC">
+        </diag-custom-topic>
+    </custom-types>
+    <data />
+    <actions />
+</equipment-model>
diff --git a/silecs-codegen/src/xml/test/fesa/fillFESADeployUnitTest.py b/silecs-codegen/src/xml/test/fesa/fillFESADeployUnitTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..b78fa41550a997a14b824508d48e0a9b260bfc28
--- /dev/null
+++ b/silecs-codegen/src/xml/test/fesa/fillFESADeployUnitTest.py
@@ -0,0 +1,68 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import sys
+import libxml2
+
+from test.testBase import *
+import fesa.fesa_3_0_0.fillFESADeployUnit
+
+simpleSilecsDeploy = '''<?xml version="1.0" encoding="UTF-8"?>
+<SILECS-Deploy silecs-version="0.10.0" created="04/05/16" updated="04/05/16" 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="">
+    <Information>
+        <Owner user-login="MaxMustermann"/>
+        <Editor user-login="MaxMustermann"/>
+    </Information>
+    <Deploy-Unit name="MyTestDeploy" version="0.1.0">
+        <Siemens-PLC system="STEP-7" model="SIMATIC_S7-300" protocol="BLOCK_MODE" base-DB-number="0"/>
+    </Deploy-Unit>
+    <Controller host-name="asl1234">
+      <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="MyTestClass1">
+            <Device device-name="myDevice1" />
+      </SilecsDesign>
+      <SilecsDesign silecs-design-version="0.1.0" silecs-design-name="MyTestClass2">
+            <Device device-name="myDevice2" />
+      </SilecsDesign>
+    </Controller>
+</SILECS-Deploy>'''
+
+simpleSilecsDeployParsed = libxml2.parseDoc(simpleSilecsDeploy)
+simpleFesaDeployParsed = libxml2.parseFile("test/fesa/DeploymentUnitTemplateFESA300.xml")
+
+def fillDU_3_0_0(generator):
+    generator.fillXML(simpleFesaDeployParsed,simpleSilecsDeployParsed,"MyTestDeploy", "some/schema.xsd", "1.2.3")
+    
+    # check that default class is removed
+    defaultClassTemplate = simpleFesaDeployParsed.xpathEval('/deploy-unit/class[class-name/text()="class-name"]')
+    assertEqual( len(defaultClassTemplate), 0 )
+
+    # test 2 classes available
+    classes = simpleFesaDeployParsed.xpathEval('/deploy-unit/class')
+    assertEqual( len(classes), 2 )
+
+    # test 2 classes available after overwrite
+    generator.fillXML(simpleFesaDeployParsed,simpleSilecsDeployParsed,"MyTestDeploy", "some/schema.xsd", "1.2.3")
+    classes = simpleFesaDeployParsed.xpathEval('/deploy-unit/class')
+    assertEqual( len(classes), 2 )
+
+def runTests():
+    generator = fesa.fesa_3_0_0.fillFESADeployUnit.FESADeployUnitGenerator3_0_0()
+    fillDU_3_0_0(generator)
+    # No need to test 3.1.0, it uses the same generator than 3.0.0
+    allTestsOk()
+
diff --git a/silecs-codegen/src/xml/test/fesa/fillFESADeployUnitTest.pyc b/silecs-codegen/src/xml/test/fesa/fillFESADeployUnitTest.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4804c5a96ddb0cda5730705483189fe57df3521f
Binary files /dev/null and b/silecs-codegen/src/xml/test/fesa/fillFESADeployUnitTest.pyc differ
diff --git a/silecs-codegen/src/xml/test/fesa/generateFesaDesignTest.py b/silecs-codegen/src/xml/test/fesa/generateFesaDesignTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..1118df7f428f2b5715632c460e1f3964e2fe40b2
--- /dev/null
+++ b/silecs-codegen/src/xml/test/fesa/generateFesaDesignTest.py
@@ -0,0 +1,115 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import sys
+
+from test.testBase import *
+import fesa.fesa_3_0_0.generateFesaDesign
+import fesa.fesa_3_1_0.generateFesaDesign
+
+import libxml2
+
+simpleSilecsDesign = '''<?xml version="1.0" encoding="UTF-8"?>
+<SILECS-Design silecs-version="0.10.0" created="03/02/16" updated="03/02/16" 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="/common/home/bel/schwinn/lnx/workspace-silecs/silecs-model/src/xml/DesignSchema.xsd">
+    <Information>
+        <Owner user-login="schwinn"/>
+        <Editor user-login="schwinn"/>
+    </Information>
+    <SILECS-Class name="Test123" version="0.1.0" domain="OPERATIONAL">
+        <Block name="Setting" mode="READ-WRITE" generateFesaProperty="true">
+            <Register name="mySettingRegister" format="uint8" synchro="MASTER" generateFesaValueItem="true"/>
+        </Block>
+        <Block name="Acquisition" mode="READ-ONLY" generateFesaProperty="true">
+            <Register name="myAcqRegister" format="uint8" synchro="MASTER" generateFesaValueItem="true"/>
+        </Block>
+    </SILECS-Class>
+</SILECS-Design>'''
+simpleSilecsDesignRoot = libxml2.parseDoc(simpleSilecsDesign)
+
+def testFillXML_EmptyTemplate_3_0_0(generator):
+    fesaRoot = libxml2.parseFile("test/fesa/emptyTemplateFESA300.xml")
+    generator.fillXML('3.0.0', 'MyClass', fesaRoot,simpleSilecsDesignRoot,logTopics={'errorlog': True})
+    assertTrue( fesaRoot.xpathEval('/equipment-model/events') != None )
+    assertTrue( fesaRoot.xpathEval('/equipment-model/scheduling-units') != None )
+    #etree.tostring(fesaRoot)
+
+def testFillXML_GSITemplate_3_0_0(generator):
+    fesaRoot = libxml2.parseFile("test/fesa/GSIClassTemplateFESA300.xml")
+    generator.fillXML('3.0.0', 'MyClass', fesaRoot,simpleSilecsDesignRoot,logTopics={'errorlog': True})
+    assertTrue( fesaRoot.xpathEval('/equipment-model/events') != None )
+    assertTrue( fesaRoot.xpathEval('/equipment-model/scheduling-units') != None )
+
+    acquisition = fesaRoot.xpathEval('/equipment-model/interface/device-interface/acquisition')[0]
+    firstGSIAcqProp = acquisition.xpathEval('GSI-Acquisition-Property')[0]
+    assertTrue( acquisition.xpathEval('*')[0].prop('name') != firstGSIAcqProp.prop('name') ) # check if generated at right position
+    assertEqual( firstGSIAcqProp.prop('name'),"Acquisition" )
+    valueItem = firstGSIAcqProp.xpathEval('value-item')[0]
+    assertTrue( valueItem != None )
+
+    setting = fesaRoot.xpathEval('/equipment-model/interface/device-interface/setting')[0]
+    firstGSISettingProp = setting.xpathEval('GSI-Setting-Property')[0]
+    assertTrue( acquisition.xpathEval('*')[0].prop('name') != firstGSISettingProp.prop('name') ) # check if generated at right position
+    #etree.tostring(fesaRoot)
+
+def testFillXML_EmptyTemplate_3_1_0(generator):
+    fesaRoot = libxml2.parseFile("test/fesa/emptyTemplateFESA300.xml")
+    generator.fillXML('3.1.0', 'MyClass', fesaRoot,simpleSilecsDesignRoot,logTopics={'errorlog': True})
+    assertTrue( fesaRoot.xpathEval('/equipment-model/events') != None )
+    assertTrue( fesaRoot.xpathEval('/equipment-model/scheduling-units') != None )
+    #etree.tostring(fesaRoot)
+
+def testFillXML_GSITemplate_3_1_0(generator):
+    fesaRoot = libxml2.parseFile("test/fesa/GSIClassTemplateFESA300.xml")
+    generator.fillXML('3.1.0', 'MyClass', fesaRoot,simpleSilecsDesignRoot,logTopics={'errorlog': True})
+    assertTrue( fesaRoot.xpathEval('/equipment-model/events') != None )
+    assertTrue( fesaRoot.xpathEval('/equipment-model/scheduling-units') != None )
+
+    acquisition = fesaRoot.xpathEval('/equipment-model/interface/device-interface/acquisition')[0]
+    firstGSIAcqProp = acquisition.xpathEval('GSI-Acquisition-Property')[0]
+    
+    assertTrue( acquisition.xpathEval('*')[0].prop('name') != firstGSIAcqProp.prop('name') ) # check if generated at right position
+    assertEqual( firstGSIAcqProp.prop('name'),"Acquisition" )
+    valueItems = firstGSIAcqProp.xpathEval('value-item')
+    assertTrue( valueItems != None )
+
+    setting = fesaRoot.xpathEval('/equipment-model/interface/device-interface/setting')[0]
+    firstGSISettingProp = setting.xpathEval('GSI-Setting-Property')[0]
+    assertTrue( acquisition.xpathEval('*')[0].prop('name') != firstGSISettingProp.prop('name') ) # check if generated at right position
+    #etree.tostring(fesaRoot)
+
+def testFillXML_AllTypes_3_1_0(generator):
+    fesaRoot = libxml2.parseFile("test/fesa/GSIClassTemplateFESA300.xml")
+    silecsRoot = libxml2.parseFile("test/AllTypesFESA.silecsdesign")
+    fesaRoot = generator.fillXML('3.1.0', 'MyClass', fesaRoot,silecsRoot,logTopics={'errorlog': True})
+    fesaNewDocPath = "test/generated_temp/AllTypesFESA.design"
+    fesaCompareDocPath = "test/generated_correct/AllTypesFESA.design"
+    with open(fesaNewDocPath, 'w') as fd:
+        fesaRoot.saveTo(fd,format = True)
+
+    print 'FESA design document saved successfully'
+    assertFileEqual( fesaNewDocPath, fesaCompareDocPath)
+
+def runTests():
+    generator = fesa.fesa_3_0_0.generateFesaDesign.FESADesignGenerator3_0_0();
+    testFillXML_EmptyTemplate_3_0_0(generator)
+    testFillXML_GSITemplate_3_0_0(generator)
+    generator = fesa.fesa_3_1_0.generateFesaDesign.FESADesignGenerator3_1_0();
+    testFillXML_EmptyTemplate_3_1_0(generator)
+    testFillXML_GSITemplate_3_1_0(generator)
+    testFillXML_AllTypes_3_1_0(generator)
+    allTestsOk()
diff --git a/silecs-codegen/src/xml/test/fesa/generateFesaDesignTest.pyc b/silecs-codegen/src/xml/test/fesa/generateFesaDesignTest.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..23d5186041cfed05c147cdf563884d1b54027d24
Binary files /dev/null and b/silecs-codegen/src/xml/test/fesa/generateFesaDesignTest.pyc differ
diff --git a/silecs-codegen/src/xml/test/fesa/generateSourceCodeTest.py b/silecs-codegen/src/xml/test/fesa/generateSourceCodeTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..edc60f85650b569afdf8b4c8f599eba794263018
--- /dev/null
+++ b/silecs-codegen/src/xml/test/fesa/generateSourceCodeTest.py
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import sys
+
+from test.testBase import *
+import fesa.fesa_3_0_0.generateSourceCode
+import fesa.fesa_3_1_0.generateSourceCode
+
+import libxml2
+
+testFolder = "test"
+generationFolder = testFolder + "/generated_temp"
+comparisonFolder = testFolder + "/generated_correct"
+generatedHeaderName = "AllTypes.h"
+generatedCppName = "AllTypes.cpp"
+
+silecsDesignRoot = libxml2.parseFile("test/AllTypesFESA.silecsdesign")
+
+
+
+def testGenHSource():
+    fesaDesignRoot = libxml2.parseFile(generationFolder + "/AllTypesFESA.design" )
+    fesa.fesa_3_1_0.generateSourceCode.genHSource('AllTypes', silecsDesignRoot,fesaDesignRoot,generationFolder,logTopics={'errorlog': True})
+    assertFileEqual( generationFolder + "/" + generatedHeaderName, comparisonFolder + "/" + generatedHeaderName)
+
+def testGenCppSource():
+    fesaDesignRoot = libxml2.parseFile(generationFolder + "/AllTypesFESA.design" )
+    fesa.fesa_3_1_0.generateSourceCode.genCppSource('AllTypes', silecsDesignRoot,fesaDesignRoot,generationFolder,logTopics={'errorlog': True})
+    assertFileEqual( generationFolder + "/" + generatedCppName, comparisonFolder + "/" + generatedCppName)
+
+def runTests():
+    testGenHSource()
+    testGenCppSource()
+    allTestsOk()
diff --git a/silecs-codegen/src/xml/test/fesa/generateSourceCodeTest.pyc b/silecs-codegen/src/xml/test/fesa/generateSourceCodeTest.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d6c7d920cdc956e5010282326b34c1e8d222f554
Binary files /dev/null and b/silecs-codegen/src/xml/test/fesa/generateSourceCodeTest.pyc differ
diff --git a/silecs-codegen/src/xml/test/general/__init__.py b/silecs-codegen/src/xml/test/general/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/silecs-codegen/src/xml/test/general/__init__.pyc b/silecs-codegen/src/xml/test/general/__init__.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..dcd01aa4a2f45a49711959f9eb958f03364b5c75
Binary files /dev/null and b/silecs-codegen/src/xml/test/general/__init__.pyc differ
diff --git a/silecs-codegen/src/xml/test/general/genDuWrapperTest.py b/silecs-codegen/src/xml/test/general/genDuWrapperTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..d0b43d00a83a4343a8b42a62a375630e3cb93c1f
--- /dev/null
+++ b/silecs-codegen/src/xml/test/general/genDuWrapperTest.py
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import sys
+import libxml2
+
+from test.testBase import *
+from genduwrapper import *
+import iecommon
+import iefiles
+
+import libxml2
+
+testFolder = "test"
+generationFolder = testFolder + "/generated_temp/wrapper"
+comparisonFolder = testFolder + "/generated_correct/wrapper"
+deployFilePath = testFolder + "/AllTypesDU.silecsdeploy"
+duControllerWrapperGenerated = generationFolder + "/Siemens_Step7Device.h" # just check one of them, codegen is identical for all 
+duControllerWrapperCorrect = comparisonFolder + "/Siemens_Step7Device.h"
+duDesignWrapperGenerated = generationFolder + "/AllTypes.h"
+duDesignWrapperCorrect = comparisonFolder + "/AllTypes.h"
+
+def fakeGetSilecsDesignFilePath(workspacePath,designName):
+    return testFolder + "/AllTypes.silecsdesign"
+
+def fakeGetDuDesignWrapperFile(workspacePath,deployName,designName):
+    return generationFolder + "/" + designName + ".h"
+
+def fakeGetDuWrapperFile(workspacePath, deployName, controllerName):
+    return generationFolder + "/" + controllerName + ".h"
+
+def CompareGeneratedFiles():
+    assertFileEqual( duDesignWrapperGenerated, duDesignWrapperCorrect)
+    assertFileEqual( duControllerWrapperGenerated, duControllerWrapperCorrect)
+
+def runTests():
+    genDuWrapperBase(deployFilePath,fakeGetDuWrapperFile,"fake",fakeGetSilecsDesignFilePath, fakeGetDuDesignWrapperFile,"AllTypesDU","0.1.0")
+    CompareGeneratedFiles()
+    allTestsOk()
diff --git a/silecs-codegen/src/xml/test/general/genDuWrapperTest.pyc b/silecs-codegen/src/xml/test/general/genDuWrapperTest.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..aa0081a34ddd6b2da0764f53950b6a5fd34874e9
Binary files /dev/null and b/silecs-codegen/src/xml/test/general/genDuWrapperTest.pyc differ
diff --git a/silecs-codegen/src/xml/test/general/genParamTest.py b/silecs-codegen/src/xml/test/general/genParamTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..0d59b80e66005313b0a8100189384ee9fc57205d
--- /dev/null
+++ b/silecs-codegen/src/xml/test/general/genParamTest.py
@@ -0,0 +1,75 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import difflib
+import sys
+import libxml2
+
+from test.testBase import *
+from genparam import *
+import iecommon
+import iefiles
+
+import libxml2
+
+testFolder = "test"
+generationFolder = testFolder + "/generated_temp/client"
+comparisonFolder = testFolder + "/generated_correct/client"
+
+def fakeGetSilecsDesignFilePath(workspacePath,designName):
+    return testFolder + "/AllTypes.silecsdesign"
+
+def fakeGetParameterFile(workspacePath,deployName,controllerName):
+    return generationFolder + "/" + controllerName + ".silecsparam" 
+
+def fakeGetSilecsDeployFilePath(workspacePath,deployName):
+    return testFolder + "/AllTypesDU.silecsdeploy"
+
+def fakeGetParameterFileDirectory(workspacePath,deployName):
+    return generationFolder
+
+def CompareGeneratedFiles(hostName,fileExtension):
+    fileGeneratedPath = generationFolder + "/" + hostName + fileExtension
+    fileCorrectPath = comparisonFolder + "/" + hostName + fileExtension
+    print "comparing: " + fileGeneratedPath + " with: " +  fileCorrectPath
+    assertParameterFileEqual( fileGeneratedPath, fileCorrectPath)
+
+def SiemensSourcesTest():
+    CompareGeneratedFiles("Siemens_TiaDevice",".silecsparam")
+    CompareGeneratedFiles("Siemens_TiaBlock",".silecsparam")
+    CompareGeneratedFiles("Siemens_Step7Device",".silecsparam")
+    CompareGeneratedFiles("Siemens_Step7Block",".silecsparam")
+
+def BeckhoffSourcesTest():
+    CompareGeneratedFiles("Beckhoff_BC9020",".silecsparam")
+    CompareGeneratedFiles("Beckhoff_CX9020",".silecsparam")
+
+def SchneiderSourcesTest():
+    CompareGeneratedFiles("Schneider_M340",".silecsparam")
+    CompareGeneratedFiles("Schneider_PremiumQuantum",".silecsparam")
+
+def RabbitSourcesTest():
+    CompareGeneratedFiles("Rabbit_BlockMode",".silecsparam")
+    CompareGeneratedFiles("Rabbit_DeviceMode",".silecsparam")
+
+def runTests():
+
+    genParamBase( fakeGetSilecsDesignFilePath, fakeGetParameterFile, fakeGetSilecsDeployFilePath, fakeGetParameterFileDirectory, "fake", "AllTypesDU", "fake", "DEV")
+    SiemensSourcesTest()
+    BeckhoffSourcesTest()
+    SchneiderSourcesTest()
+    RabbitSourcesTest()
+    allTestsOk()
diff --git a/silecs-codegen/src/xml/test/general/genParamTest.pyc b/silecs-codegen/src/xml/test/general/genParamTest.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1059aac19f8e8874af9d0446264a8a8380b9e6c0
Binary files /dev/null and b/silecs-codegen/src/xml/test/general/genParamTest.pyc differ
diff --git a/silecs-codegen/src/xml/test/general/genplcsrcTest.py b/silecs-codegen/src/xml/test/general/genplcsrcTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..12e56fad76183ffa945a46d60f93c1d66a9b0b2d
--- /dev/null
+++ b/silecs-codegen/src/xml/test/general/genplcsrcTest.py
@@ -0,0 +1,77 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import difflib
+import sys
+import libxml2
+
+from test.testBase import *
+import genplcsrc
+import iecommon
+import iefiles
+
+import libxml2
+
+testFolder = "test"
+generationFolder = testFolder + "/generated_temp"
+comparisonFolder = testFolder + "/generated_correct"
+generationFoldeController = generationFolder + "/controller"
+comparisonFolderController = comparisonFolder + "/controller"
+def generatePLCSources():
+    deployDOM = libxml2.parseFile(testFolder + "/AllTypesDU.silecsdeploy")
+    controllerNodes = deployDOM.xpathEval("/SILECS-Deploy/Controller")
+    for controllerNode in controllerNodes:
+        paramsFile = generationFolder + "/client/" + controllerNode.prop("host-name") + ".silecsparam"
+        genplcsrc.generateControllerCode(controllerNode, paramsFile, generationFoldeController ,{'errorlog': True})
+    deployDOM.freeDoc()
+
+def CompareGeneratedFiles(hostName,fileExtension):
+    fileGeneratedPath = generationFoldeController + "/" + hostName + fileExtension
+    fileCorrectPath = comparisonFolderController + "/" + hostName + fileExtension
+    print "comparing: " + fileGeneratedPath + " with: " +  fileCorrectPath
+    assertPLCCodeEqual( fileGeneratedPath, fileCorrectPath)
+
+def SiemensSourcesTest():
+    CompareGeneratedFiles("Siemens_TiaDevice",".scl")
+    CompareGeneratedFiles("Siemens_TiaDevice",".sdf")
+    CompareGeneratedFiles("Siemens_TiaBlock",".scl")
+    CompareGeneratedFiles("Siemens_TiaBlock",".sdf")
+    CompareGeneratedFiles("Siemens_Step7Device",".scl")
+    CompareGeneratedFiles("Siemens_Step7Device",".sdf")
+    CompareGeneratedFiles("Siemens_Step7Block",".scl")
+    CompareGeneratedFiles("Siemens_Step7Block",".sdf")
+
+def BeckhoffSourcesTest():
+    CompareGeneratedFiles("Beckhoff_BC9020",".exp")
+    CompareGeneratedFiles("Beckhoff_CX9020",".exp")
+
+def SchneiderSourcesTest():
+    CompareGeneratedFiles("Schneider_M340",".xsy")
+    CompareGeneratedFiles("Schneider_PremiumQuantum",".xsy")
+
+def RabbitSourcesTest():
+    CompareGeneratedFiles("Rabbit_BlockMode",".h")
+    CompareGeneratedFiles("Rabbit_DeviceMode",".h")
+
+def runTests():
+
+    generatePLCSources()
+
+    SiemensSourcesTest()
+    BeckhoffSourcesTest()
+    SchneiderSourcesTest()
+    RabbitSourcesTest()
+    allTestsOk()
diff --git a/silecs-codegen/src/xml/test/general/genplcsrcTest.pyc b/silecs-codegen/src/xml/test/general/genplcsrcTest.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..70de350b2f54a5db12ed8df953535958c47da92e
Binary files /dev/null and b/silecs-codegen/src/xml/test/general/genplcsrcTest.pyc differ
diff --git a/silecs-codegen/src/xml/test/general/iecommonTest.py b/silecs-codegen/src/xml/test/general/iecommonTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..842f277f8c29fc9c9b0b867efc5f7093dcd718d3
--- /dev/null
+++ b/silecs-codegen/src/xml/test/general/iecommonTest.py
@@ -0,0 +1,51 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import sys
+
+from test.testBase import *
+from iecommon import *
+
+import libxml2
+
+def testhasChildren():
+    document = '''<?xml version="1.0"?>
+                 <a>
+                    <b>
+                        <c/>
+                    </b>
+                </a>'''
+    root = libxml2.parseDoc(document)
+    assertTrue(hasChildren(root))
+    assertTrue(hasChildren(root.xpathEval('/a/b')[0]))
+    assertFalse(hasChildren(root.xpathEval('/a/b/c')[0]))
+    
+def testGetFirstChild():
+    document = '''<?xml version="1.0"?>
+                <a>
+                    <b/>
+                    <c/>
+                    <d/>
+                </a>'''
+    root = libxml2.parseDoc(document)
+    a = root.xpathEval('/a')[0]
+    b = getFirstChild(a)
+    assertEqual( root.xpathEval('/a/b')[0], b )
+
+def runTests():
+    testhasChildren()
+    testGetFirstChild()
+    allTestsOk()
diff --git a/silecs-codegen/src/xml/test/general/iecommonTest.pyc b/silecs-codegen/src/xml/test/general/iecommonTest.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ee12f7681fe5eb2fe8033b5023d75a242e31a603
Binary files /dev/null and b/silecs-codegen/src/xml/test/general/iecommonTest.pyc differ
diff --git a/silecs-codegen/src/xml/test/generated_correct/AllTypes.cpp b/silecs-codegen/src/xml/test/generated_correct/AllTypes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..08c4d7fdeb2770c38e2a0a86015a931c653292a8
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/AllTypes.cpp
@@ -0,0 +1,738 @@
+/*
+ * AllTypes.cpp
+ *
+ * Generated by SILECS framework tools 
+ */
+ 
+#include <AllTypes/Common/AllTypes.h>
+#include <fesa-core/Synchronization/NoneContext.h>
+#include <fesa-core/Synchronization/MultiplexingContext.h>
+ 
+namespace AllTypes
+{
+    //Global objects of the SILECS class
+    Silecs::Service* AbstractAllTypes::pService_ = NULL;
+    Silecs::Cluster* AbstractAllTypes::pCluster_ = NULL;
+    bool AbstractAllTypes::isInitialized_ = false;
+
+    MyROBlock_Type	AllTypes::MyROBlock("MyROBlock");
+    MyRWBlock_Type	AllTypes::MyRWBlock("MyRWBlock");
+    MyWOBlock_Type	AllTypes::MyWOBlock("MyWOBlock");
+    
+    //-------------------------------------------------------------------------------------------------------------
+    // Constructor & Destructor methods
+    
+    AbstractAllTypes::AbstractAllTypes(std::string blockName): blockName_(blockName) {}
+    AbstractAllTypes::~AbstractAllTypes() {}
+    
+    MyROBlock_Type::MyROBlock_Type(std::string name): AbstractAllTypes(name) {}
+    MyROBlock_Type::~MyROBlock_Type() {}
+    
+    MyRWBlock_Type::MyRWBlock_Type(std::string name): AbstractAllTypes(name) {}
+    MyRWBlock_Type::~MyRWBlock_Type() {}
+    
+    MyWOBlock_Type::MyWOBlock_Type(std::string name): AbstractAllTypes(name) {}
+    MyWOBlock_Type::~MyWOBlock_Type() {}
+    
+    //---------------------------------------------------------------------------------------------------------
+    // Set-up the SILECS components for the AbstractAllTypes class (service & cluster)
+
+    void AbstractAllTypes::setup(const ServiceLocator* serviceLocator)
+    {
+        try
+        {
+            // Instantiate the singleton of the SILECS Service
+            pService_ = Silecs::Service::getInstance();
+
+            // Enable the SILECS diagnostic with user topics if any
+            pService_->setArguments(serviceLocator->getUsrCmdArgs());
+
+            // Instantiate the SILECS Cluster object for the given Class/Version
+            GlobalDevice* pGlobalDevice = serviceLocator->getGlobalDevice();
+            pCluster_ = pService_->getCluster( "AllTypes", pGlobalDevice->plcClassVersion.get());
+            isInitialized_ = true;
+
+            // Connect each PLC of the Cluster that is referred from the FESA instance
+            std::vector<Device*> pDeviceCol = serviceLocator->getDeviceCollection();
+            for(std::vector<Device*>::iterator pDeviceIter=pDeviceCol.begin(); pDeviceIter!= pDeviceCol.end(); pDeviceIter++)
+            {
+                Device* pDevice = *pDeviceIter;
+
+                // Retrieve the PLC related to the current FESA device
+                // (from 'plcHostName' FESA field defined on that purpose).
+                Silecs::PLC* pPLC = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+
+                // Update the PLC Slave registers from related FESA fields just before synchronising done at connection time
+                setPLCSlaveRegisters(pPLC, serviceLocator);
+
+                // Connect the PLC if not already connected
+                if (!pPLC->isEnabled())
+                {   pPLC->connect(/*synchroMode=*/Silecs::FULL_SYNCHRO, /*connectNow=*/true);
+                    if (pPLC->isConnected())
+                    {   // Update FESA fields from related PLC Master registers just after synchronising done at connection time
+                        getPLCMasterRegisters(pPLC, serviceLocator);
+                    }
+                }
+            }
+        }
+        catch (const Silecs::SilecsException& ex)
+        {
+            throw fesa::FesaException(__FILE__, __LINE__, ex.getMessage());
+        }
+    }
+
+    //---------------------------------------------------------------------------------------------------------
+    // Release all the SILECS resources
+    void AbstractAllTypes::cleanup()
+    {
+        // Attention! This method is responsible to stop all the PLC connections
+        // and to remove all the SILECS resources (Clusters and related components: PLCs, Devices, Registers, ..)
+        // Calling method must ensure that no process is currently accessing these resources before cleaning.
+        //
+        Silecs::Service::deleteInstance();
+    }
+
+    //---------------------------------------------------------------------------------------------------------
+    // Synchronise PLC SLAVE/MASTER registers and related FESA fields (automatically called by the setup method @connection time)
+    void AbstractAllTypes::setPLCSlaveRegisters(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator)
+    {
+        fesa::NoneContext noneContext;
+    
+        AllTypes::MyWOBlock.setPLCDevices(pPLC, serviceLocator, false, &noneContext);
+    }
+
+    void AbstractAllTypes::getPLCMasterRegisters(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator)
+    {
+        fesa::NoneContext noneContext;    //MASTER acquisition fields are not consistent, can be set with none-context
+    
+        AllTypes::MyROBlock.getPLCDevices(pPLC, serviceLocator, false, &noneContext);
+        AllTypes::MyRWBlock.getPLCDevices(pPLC, serviceLocator, false, &noneContext);
+    }
+    
+    //---------------------------------------------------------------------------------------------------------
+    // General methods to synchronize the FESA fields and related PLC registers of the FESA server
+    // with or without PLC side access (send/recv) if requested.
+    // get_ : [receive block from PLC +] update FESA fields with related PLC registers
+    // set_ : update PLC registers with related FESA fields [+ send block to PLC]
+
+    //---------------------------------------------------------------------------------------------------------
+
+    void AbstractAllTypes::getAllDevices(const ServiceLocator* serviceLocator, const bool recvNow, MultiplexingContext* pContext)
+    {
+        if (recvNow) theCluster()->recv(blockName_);
+
+        std::vector<Device*> deviceCol = serviceLocator->getDeviceCollection();
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {  getOneDevice(*pDeviceIter, false, pContext);
+        }
+    }
+
+    void AbstractAllTypes::getPLCDevices(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator, const bool recvNow, MultiplexingContext* pContext)
+    {
+        if (recvNow) pPLC->recv(blockName_);
+
+        std::vector<Device*> deviceCol = serviceLocator->getDeviceCollection();
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {   if ((*pDeviceIter)->plcHostName.get() == pPLC->getName())
+            {  getOneDevice(*pDeviceIter, false, pContext);
+            }
+        }
+    }
+
+    void AbstractAllTypes::getSomeDevices(std::vector<Device*> deviceCol, const bool sendNow, MultiplexingContext* pContext)
+    {
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {    getOneDevice(*pDeviceIter, sendNow, pContext);
+        }
+    }
+
+    void AbstractAllTypes::getOneDevice(Device* pDevice, const bool recvNow, MultiplexingContext* pContext) {};
+
+    //---------------------------------------------------------------------------------------------------------
+
+    void AbstractAllTypes::setAllDevices(const ServiceLocator* serviceLocator, bool sendNow, MultiplexingContext* pContext)
+    {
+        std::vector<Device*> deviceCol = serviceLocator->getDeviceCollection();
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {  setOneDevice(*pDeviceIter, false, pContext);
+        }
+
+        if (sendNow) theCluster()->send(blockName_);
+    }
+
+    void AbstractAllTypes::setPLCDevices(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator, bool sendNow, MultiplexingContext* pContext)
+    {
+        std::vector<Device*> deviceCol = serviceLocator->getDeviceCollection();
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {   if ((*pDeviceIter)->plcHostName.get() == pPLC->getName())
+            {  setOneDevice(*pDeviceIter, false, pContext);
+            }
+        }
+
+        if (sendNow) pPLC->send(blockName_);
+    }
+
+    void AbstractAllTypes::setSomeDevices(std::vector<Device*> deviceCol, bool sendNow, MultiplexingContext* pContext)
+    {
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {    setOneDevice(*pDeviceIter, sendNow, pContext);
+        }
+    }
+
+    void AbstractAllTypes::setOneDevice(Device* pDevice, const bool sendNow, MultiplexingContext* pContext) {};
+    
+    //---------------------------------------------------------------------------------------------------------
+    
+    void MyROBlock_Type::getOneDevice(Device* pDevice, const bool recvNow, MultiplexingContext* pContext)
+    {
+    	if( !isInitialized_ )
+    	{
+    		throw fesa::FesaException(__FILE__, __LINE__, "SILECS-Service not initialized yet - AllTypes::setup needs to be called before any plc-interaction can be done");
+    	}
+        Silecs::PLC* pPLC  = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+        Silecs::Device* pPLCDevice = pPLC->getDevice(pDevice->plcDeviceLabel.get());
+        Silecs::Register*  pRegister = NULL;
+
+        if (recvNow) pPLCDevice -> recv(blockName_);        
+    
+        pDevice->RO_int8.set( pPLCDevice->getRegister("RO_int8")->getValInt8(), pContext);
+        pDevice->RO_uint8.set( pPLCDevice->getRegister("RO_uint8")->getValUInt8(), pContext);
+        pDevice->RO_int16.set( pPLCDevice->getRegister("RO_int16")->getValInt16(), pContext);
+        pDevice->RO_uint16.set( pPLCDevice->getRegister("RO_uint16")->getValUInt16(), pContext);
+        pDevice->RO_int32.set( pPLCDevice->getRegister("RO_int32")->getValInt32(), pContext);
+        pDevice->RO_uint32.set( pPLCDevice->getRegister("RO_uint32")->getValUInt32(), pContext);
+        pDevice->RO_float32.set( pPLCDevice->getRegister("RO_float32")->getValFloat32(), pContext);
+        pRegister = pPLCDevice->getRegister("RO_string");
+        pDevice->RO_string.set(pRegister->getValString().c_str(), pContext);
+
+        pDevice->RO_date.set( pPLCDevice->getRegister("RO_date")->getValDate(), pContext);
+        pDevice->RO_char.set( pPLCDevice->getRegister("RO_char")->getValInt8(), pContext);
+        pDevice->RO_byte.set( pPLCDevice->getRegister("RO_byte")->getValUInt8(), pContext);
+        pDevice->RO_word.set( pPLCDevice->getRegister("RO_word")->getValUInt16(), pContext);
+        pDevice->RO_dword.set( pPLCDevice->getRegister("RO_dword")->getValUInt32(), pContext);
+        pDevice->RO_int.set( pPLCDevice->getRegister("RO_int")->getValInt16(), pContext);
+        pDevice->RO_dint.set( pPLCDevice->getRegister("RO_dint")->getValInt32(), pContext);
+        pDevice->RO_real.set( pPLCDevice->getRegister("RO_real")->getValFloat32(), pContext);
+        pDevice->RO_dt.set( pPLCDevice->getRegister("RO_dt")->getValDate(), pContext);
+	}
+    void MyRWBlock_Type::getOneDevice(Device* pDevice, const bool recvNow, MultiplexingContext* pContext)
+    {
+    	if( !isInitialized_ )
+    	{
+    		throw fesa::FesaException(__FILE__, __LINE__, "SILECS-Service not initialized yet - AllTypes::setup needs to be called before any plc-interaction can be done");
+    	}
+        Silecs::PLC* pPLC  = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+        Silecs::Device* pPLCDevice = pPLC->getDevice(pDevice->plcDeviceLabel.get());
+        Silecs::Register*  pRegister = NULL;
+        uint32_t dim1 = 1;
+        uint32_t dim2 = 1;
+
+        if (recvNow) pPLCDevice -> recv(blockName_);        
+    
+        pRegister = pPLCDevice->getRegister("RW_int8");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_int8.set(pRegister->getRefInt8Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_uint8");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        int16_t* RW_uint8 = (int16_t*)calloc(dim1*dim2, sizeof(int16_t));
+        pRegister->getValUInt8Array2D(RW_uint8, dim1, dim2);	//use automatic conversion for JAVA non-supported type
+        pDevice->RW_uint8.set(RW_uint8, dim1, dim2, pContext);
+    free(RW_uint8);
+
+        pRegister = pPLCDevice->getRegister("RW_int16");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_int16.set(pRegister->getRefInt16Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_uint16");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        int32_t* RW_uint16 = (int32_t*)calloc(dim1*dim2, sizeof(int32_t));
+        pRegister->getValUInt16Array2D(RW_uint16, dim1, dim2);	//use automatic conversion for JAVA non-supported type
+        pDevice->RW_uint16.set(RW_uint16, dim1, dim2, pContext);
+    free(RW_uint16);
+
+        pRegister = pPLCDevice->getRegister("RW_int32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_int32.set(pRegister->getRefInt32Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_uint32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        int64_t* RW_uint32 = (int64_t*)calloc(dim1*dim2, sizeof(int64_t));
+        pRegister->getValUInt32Array2D(RW_uint32, dim1, dim2);	//use automatic conversion for JAVA non-supported type
+        pDevice->RW_uint32.set(RW_uint32, dim1, dim2, pContext);
+    free(RW_uint32);
+
+        pRegister = pPLCDevice->getRegister("RW_float32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_float32.set(pRegister->getRefFloat32Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_date");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_date.set(pRegister->getRefDateArray2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_char");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_char.set(pRegister->getRefInt8Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_byte");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        int16_t* RW_byte = (int16_t*)calloc(dim1*dim2, sizeof(int16_t));
+        pRegister->getValUInt8Array2D(RW_byte, dim1, dim2);	//use automatic conversion for JAVA non-supported type
+        pDevice->RW_byte.set(RW_byte, dim1, dim2, pContext);
+    free(RW_byte);
+
+        pRegister = pPLCDevice->getRegister("RW_word");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        int32_t* RW_word = (int32_t*)calloc(dim1*dim2, sizeof(int32_t));
+        pRegister->getValUInt16Array2D(RW_word, dim1, dim2);	//use automatic conversion for JAVA non-supported type
+        pDevice->RW_word.set(RW_word, dim1, dim2, pContext);
+    free(RW_word);
+
+        pRegister = pPLCDevice->getRegister("RW_dword");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        int64_t* RW_dword = (int64_t*)calloc(dim1*dim2, sizeof(int64_t));
+        pRegister->getValUInt32Array2D(RW_dword, dim1, dim2);	//use automatic conversion for JAVA non-supported type
+        pDevice->RW_dword.set(RW_dword, dim1, dim2, pContext);
+    free(RW_dword);
+
+        pRegister = pPLCDevice->getRegister("RW_int");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_int.set(pRegister->getRefInt16Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_dint");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_dint.set(pRegister->getRefInt32Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_real");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_real.set(pRegister->getRefFloat32Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_dt");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_dt.set(pRegister->getRefDateArray2D(dim1, dim2), dim1, dim2, pContext);
+
+	}    
+    void MyRWBlock_Type::setOneDevice(Device* pDevice, const bool sendNow, MultiplexingContext* pContext)
+    {
+    	if( !isInitialized_ )
+    	{
+    		throw fesa::FesaException(__FILE__, __LINE__, "SILECS-Service not initialized yet - AllTypes::setup needs to be called before any plc-interaction can be done");
+    	}
+        Silecs::PLC* pPLC  = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+        Silecs::Device* pPLCDevice = pPLC->getDevice(pDevice->plcDeviceLabel.get());
+        Silecs::Register*  pRegister = NULL;
+        uint32_t dim1 = 1;
+        uint32_t fesaDim1;
+        uint32_t dim2 = 1;
+        uint32_t fesaDim2;
+
+
+    pRegister = pPLCDevice->getRegister("RW_int8");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValInt8Array2D(pDevice->RW_int8.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_uint8");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValUInt8Array2D( pDevice->RW_uint8.get(fesaDim1, fesaDim2, pContext), dim1, dim2);	//use automatic conversion for JAVA non-supported type
+
+    pRegister = pPLCDevice->getRegister("RW_int16");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValInt16Array2D(pDevice->RW_int16.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_uint16");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValUInt16Array2D( pDevice->RW_uint16.get(fesaDim1, fesaDim2, pContext), dim1, dim2);	//use automatic conversion for JAVA non-supported type
+
+    pRegister = pPLCDevice->getRegister("RW_int32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValInt32Array2D(pDevice->RW_int32.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_uint32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValUInt32Array2D( pDevice->RW_uint32.get(fesaDim1, fesaDim2, pContext), dim1, dim2);	//use automatic conversion for JAVA non-supported type
+
+    pRegister = pPLCDevice->getRegister("RW_float32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValFloat32Array2D(pDevice->RW_float32.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+    pRegister = pPLCDevice->getRegister("RW_date");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValDateArray2D(pDevice->RW_date.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+    pRegister = pPLCDevice->getRegister("RW_char");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValInt8Array2D(pDevice->RW_char.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_byte");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValUInt8Array2D( pDevice->RW_byte.get(fesaDim1, fesaDim2, pContext), dim1, dim2);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("RW_word");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValUInt16Array2D( pDevice->RW_word.get(fesaDim1, fesaDim2, pContext), dim1, dim2);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("RW_dword");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValUInt32Array2D( pDevice->RW_dword.get(fesaDim1, fesaDim2, pContext), dim1, dim2);	//use automatic conversion for JAVA non-supported type
+
+    pRegister = pPLCDevice->getRegister("RW_int");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValInt16Array2D(pDevice->RW_int.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+    pRegister = pPLCDevice->getRegister("RW_dint");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValInt32Array2D(pDevice->RW_dint.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+    pRegister = pPLCDevice->getRegister("RW_real");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValFloat32Array2D(pDevice->RW_real.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+    pRegister = pPLCDevice->getRegister("RW_dt");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValDateArray2D(pDevice->RW_dt.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        if (sendNow) pPLCDevice->send(blockName_);
+
+	}
+    void MyRWBlock_Type::setOneDevice(Device* pDevice, MyRWBlockPropertyData& data, bool sendNow, MultiplexingContext* pContext)
+    {
+    	if( !isInitialized_ )
+    	{
+    		throw fesa::FesaException(__FILE__, __LINE__, "SILECS-Service not initialized yet - AllTypes::setup needs to be called before any plc-interaction can be done");
+    	}
+        Silecs::PLC* pPLC = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+        Silecs::Device* pPLCDevice = pPLC->getDevice(pDevice->plcDeviceLabel.get());
+        Silecs::Register*  pRegister = NULL;
+        uint32_t dim1 = 1;
+        uint32_t fesaDim1;
+        uint32_t dim2 = 1;
+        uint32_t fesaDim2;
+
+
+        pRegister = pPLCDevice->getRegister("RW_int8");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_int8Available()) ? pRegister->setValInt8Array2D(data.RW_int8.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValInt8Array2D(pDevice->RW_int8.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_uint8");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_uint8Available()) ? pRegister->setValUInt8Array2D(data.RW_uint8.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValUInt8Array2D(pDevice->RW_uint8.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_int16");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_int16Available()) ? pRegister->setValInt16Array2D(data.RW_int16.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValInt16Array2D(pDevice->RW_int16.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_uint16");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_uint16Available()) ? pRegister->setValUInt16Array2D(data.RW_uint16.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValUInt16Array2D(pDevice->RW_uint16.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_int32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_int32Available()) ? pRegister->setValInt32Array2D(data.RW_int32.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValInt32Array2D(pDevice->RW_int32.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_uint32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_uint32Available()) ? pRegister->setValUInt32Array2D(data.RW_uint32.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValUInt32Array2D(pDevice->RW_uint32.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_float32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_float32Available()) ? pRegister->setValFloat32Array2D(data.RW_float32.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValFloat32Array2D(pDevice->RW_float32.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_date");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_dateAvailable()) ? pRegister->setValDateArray2D(data.RW_date.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValDateArray2D(pDevice->RW_date.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_char");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_charAvailable()) ? pRegister->setValInt8Array2D(data.RW_char.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValInt8Array2D(pDevice->RW_char.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_byte");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_byteAvailable()) ? pRegister->setValUInt8Array2D(data.RW_byte.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValUInt8Array2D(pDevice->RW_byte.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_word");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_wordAvailable()) ? pRegister->setValUInt16Array2D(data.RW_word.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValUInt16Array2D(pDevice->RW_word.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_dword");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_dwordAvailable()) ? pRegister->setValUInt32Array2D(data.RW_dword.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValUInt32Array2D(pDevice->RW_dword.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_int");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_intAvailable()) ? pRegister->setValInt16Array2D(data.RW_int.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValInt16Array2D(pDevice->RW_int.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_dint");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_dintAvailable()) ? pRegister->setValInt32Array2D(data.RW_dint.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValInt32Array2D(pDevice->RW_dint.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_real");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_realAvailable()) ? pRegister->setValFloat32Array2D(data.RW_real.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValFloat32Array2D(pDevice->RW_real.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_dt");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_dtAvailable()) ? pRegister->setValDateArray2D(data.RW_dt.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValDateArray2D(pDevice->RW_dt.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        if (sendNow) pPLCDevice->send(blockName_);
+
+	}
+    
+    void MyWOBlock_Type::setOneDevice(Device* pDevice, const bool sendNow, MultiplexingContext* pContext)
+    {
+    	if( !isInitialized_ )
+    	{
+    		throw fesa::FesaException(__FILE__, __LINE__, "SILECS-Service not initialized yet - AllTypes::setup needs to be called before any plc-interaction can be done");
+    	}
+        Silecs::PLC* pPLC  = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+        Silecs::Device* pPLCDevice = pPLC->getDevice(pDevice->plcDeviceLabel.get());
+        Silecs::Register*  pRegister = NULL;
+        uint32_t dim1 = 1;
+        uint32_t fesaDim1;
+
+
+        pRegister = pPLCDevice->getRegister("WO_int8");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValInt8Array(pDevice->WO_int8.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_uint8");
+        dim1 = pRegister->getDimension1();
+        pRegister->setValUInt8Array(pDevice->WO_uint8.get(fesaDim1, pContext), dim1);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("WO_int16");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValInt16Array(pDevice->WO_int16.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_uint16");
+        dim1 = pRegister->getDimension1();
+        pRegister->setValUInt16Array(pDevice->WO_uint16.get(fesaDim1, pContext), dim1);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("WO_int32");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValInt32Array(pDevice->WO_int32.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_uint32");
+        dim1 = pRegister->getDimension1();
+        pRegister->setValUInt32Array(pDevice->WO_uint32.get(fesaDim1, pContext), dim1);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("WO_float32");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValFloat32Array(pDevice->WO_float32.get(fesaDim1, pContext), dim1);
+    
+        {
+        pRegister = pPLCDevice->getRegister("WO_string");
+        dim1 = pRegister->getDimension1();
+        std::string stdStringArray[dim1];
+        const char** cStringArray = pDevice->WO_string.get(fesaDim1, pContext);
+        for (unsigned int i=0; i<dim1; i++) stdStringArray[i] = (const char*)cStringArray[i];
+        pRegister->setValStringArray(stdStringArray, dim1);
+        }
+
+        pRegister = pPLCDevice->getRegister("WO_date");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValDateArray(pDevice->WO_date.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_char");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValInt8Array(pDevice->WO_char.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_byte");
+        dim1 = pRegister->getDimension1();
+        pRegister->setValUInt8Array(pDevice->WO_byte.get(fesaDim1, pContext), dim1);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("WO_word");
+        dim1 = pRegister->getDimension1();
+        pRegister->setValUInt16Array(pDevice->WO_word.get(fesaDim1, pContext), dim1);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("WO_dword");
+        dim1 = pRegister->getDimension1();
+        pRegister->setValUInt32Array(pDevice->WO_dword.get(fesaDim1, pContext), dim1);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("WO_int");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValInt16Array(pDevice->WO_int.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_dint");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValInt32Array(pDevice->WO_dint.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_real");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValFloat32Array(pDevice->WO_real.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_dt");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValDateArray(pDevice->WO_dt.get(fesaDim1, pContext), dim1);
+    
+        if (sendNow) pPLCDevice->send(blockName_);
+
+	}
+    void MyWOBlock_Type::setOneDevice(Device* pDevice, MyWOBlockPropertyData& data, bool sendNow, MultiplexingContext* pContext)
+    {
+    	if( !isInitialized_ )
+    	{
+    		throw fesa::FesaException(__FILE__, __LINE__, "SILECS-Service not initialized yet - AllTypes::setup needs to be called before any plc-interaction can be done");
+    	}
+        Silecs::PLC* pPLC = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+        Silecs::Device* pPLCDevice = pPLC->getDevice(pDevice->plcDeviceLabel.get());
+        Silecs::Register*  pRegister = NULL;
+        uint32_t dim1 = 1;
+        uint32_t fesaDim1;
+
+
+        pRegister = pPLCDevice->getRegister("WO_int8");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_int8Available()) ? pRegister->setValInt8Array( data.WO_int8.get(fesaDim1), dim1) :
+                                         pRegister->setValInt8Array( pDevice->WO_int8.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_uint8");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_uint8Available()) ? pRegister->setValUInt8Array( data.WO_uint8.get(fesaDim1), dim1) :
+                                         pRegister->setValUInt8Array( pDevice->WO_uint8.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_int16");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_int16Available()) ? pRegister->setValInt16Array( data.WO_int16.get(fesaDim1), dim1) :
+                                         pRegister->setValInt16Array( pDevice->WO_int16.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_uint16");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_uint16Available()) ? pRegister->setValUInt16Array( data.WO_uint16.get(fesaDim1), dim1) :
+                                         pRegister->setValUInt16Array( pDevice->WO_uint16.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_int32");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_int32Available()) ? pRegister->setValInt32Array( data.WO_int32.get(fesaDim1), dim1) :
+                                         pRegister->setValInt32Array( pDevice->WO_int32.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_uint32");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_uint32Available()) ? pRegister->setValUInt32Array( data.WO_uint32.get(fesaDim1), dim1) :
+                                         pRegister->setValUInt32Array( pDevice->WO_uint32.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_float32");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_float32Available()) ? pRegister->setValFloat32Array( data.WO_float32.get(fesaDim1), dim1) :
+                                         pRegister->setValFloat32Array( pDevice->WO_float32.get(fesaDim1, pContext), dim1);
+    
+        {
+        pRegister = pPLCDevice->getRegister("WO_string");
+        dim1 = pRegister->getDimension1();
+        std::string stdStringArray[dim1];
+        const char** cStringArray = (data.isWO_stringAvailable() ? data.WO_string.get(fesaDim1) : pDevice->WO_string.get(fesaDim1, pContext));
+        for (unsigned int i=0; i<dim1; i++) stdStringArray[i] = (const char*)cStringArray[i];
+        pRegister->setValStringArray(stdStringArray, dim1);
+        }
+
+        pRegister = pPLCDevice->getRegister("WO_date");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_dateAvailable()) ? pRegister->setValDateArray( data.WO_date.get(fesaDim1), dim1) :
+                                         pRegister->setValDateArray( pDevice->WO_date.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_char");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_charAvailable()) ? pRegister->setValInt8Array( data.WO_char.get(fesaDim1), dim1) :
+                                         pRegister->setValInt8Array( pDevice->WO_char.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_byte");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_byteAvailable()) ? pRegister->setValUInt8Array( data.WO_byte.get(fesaDim1), dim1) :
+                                         pRegister->setValUInt8Array( pDevice->WO_byte.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_word");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_wordAvailable()) ? pRegister->setValUInt16Array( data.WO_word.get(fesaDim1), dim1) :
+                                         pRegister->setValUInt16Array( pDevice->WO_word.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_dword");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_dwordAvailable()) ? pRegister->setValUInt32Array( data.WO_dword.get(fesaDim1), dim1) :
+                                         pRegister->setValUInt32Array( pDevice->WO_dword.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_int");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_intAvailable()) ? pRegister->setValInt16Array( data.WO_int.get(fesaDim1), dim1) :
+                                         pRegister->setValInt16Array( pDevice->WO_int.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_dint");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_dintAvailable()) ? pRegister->setValInt32Array( data.WO_dint.get(fesaDim1), dim1) :
+                                         pRegister->setValInt32Array( pDevice->WO_dint.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_real");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_realAvailable()) ? pRegister->setValFloat32Array( data.WO_real.get(fesaDim1), dim1) :
+                                         pRegister->setValFloat32Array( pDevice->WO_real.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_dt");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_dtAvailable()) ? pRegister->setValDateArray( data.WO_dt.get(fesaDim1), dim1) :
+                                         pRegister->setValDateArray( pDevice->WO_dt.get(fesaDim1, pContext), dim1);
+    
+        if (sendNow) pPLCDevice->send(blockName_);
+
+	}
+}
diff --git a/silecs-codegen/src/xml/test/generated_correct/AllTypes.h b/silecs-codegen/src/xml/test/generated_correct/AllTypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..3edca8fa217278bc71c97da47d4625f01426f1c3
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/AllTypes.h
@@ -0,0 +1,146 @@
+/*
+ * AllTypes.h
+ *
+ * Generated by SILECS framework tools 
+ */
+
+#ifndef AllTypes_AllTypes_H_
+#define AllTypes_AllTypes_H_
+
+#include <SilecsService.h>
+#include <fesa-core/Synchronization/MultiplexingContext.h>
+#include <AllTypes/GeneratedCode/ServiceLocator.h>
+    #include <AllTypes/Server/SendMyRWBlock.h>
+    #include <AllTypes/Server/SendMyWOBlock.h>
+    
+namespace AllTypes
+{
+
+    /*---------------------------------------------------------------------------------------------------------
+     * SETUP
+     *---------------------------------------------------------------------------------------------------------
+     *  Setup the SILECS service by calling the setup() method from the RTDeviceClass::specificInit()
+     *  Stop and cleanup the SILECS service by calling the cleanup() method if needed (eg.: from ~RTDeviceClass())
+     *
+     *  In order to make use of the different blocks, defined in the silecsdesign, please make use of the static, block related variables of the class, defined on the bottom of this file !
+     * --------------------------------------------------------------------------------------------------------
+     */
+
+    /*---------------------------------------------------------------------------------------------------------
+     * COMMUNICATION
+     *---------------------------------------------------------------------------------------------------------
+     * General methods to synchronize the FESA fields and related PLC registers of the FESA server with or without
+     * PLC side synchronization (send/recv) if requested. Each action is done for one particular block.
+     * In case of BLOCK_MODE configuration (see SILECS doc.), the transaction is optimal with the following
+     * 'AllDevices' and 'PLCDevices' methods.
+     * Each method can be called in the appropriate server-action (set) and rt-action (get)
+     *
+     * getAllDevices  : [receive all devices of all connected PLCs +] update FESA fields with related SILECS registers
+     * setAllDevices  : update SILECS registers with related FESA fields [+ send block to all connected PLCs]
+     * getPLCDevices  : [receive all devices of one PLC +] update FESA fields with related SILECS registers
+     * setPLCDevices  : update SILECS registers with related FESA fields [+ send block to the PLC]
+     * getSomeDevices : [receive each device of the device-collection +] update FESA fields with related SILECS registers
+     * setSomeDevices : update SILECS registers with related FESA fields [+ send block to each device of the device-collection]
+     * getOneDevice   : [receive block of one PLC device +] update FESA fields with related SILECS registers
+     * setOneDevice   : update SILECS registers with related FESA fields [+ send block to the PLC device]
+     *
+     * --------------------------------------------------------------------------------------------------------
+     */
+
+    class AbstractAllTypes
+    {
+        public:
+            static inline Silecs::Service* theService()  { return pService_; }
+            static inline Silecs::Cluster* theCluster()  { return pCluster_; }
+            inline std::string& getBlockName()          { return blockName_; }
+
+            static void setup(const ServiceLocator* serviceLocator);
+            static void cleanup();
+            static void setPLCSlaveRegisters(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator);
+            static void getPLCMasterRegisters(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator);
+
+            AbstractAllTypes(std::string blockName);
+            virtual ~AbstractAllTypes();
+
+            void getAllDevices(const ServiceLocator* serviceLocator, const bool recvNow, MultiplexingContext* pContext);
+            void getPLCDevices(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator, const bool recvNow, MultiplexingContext* pContext);
+            void getSomeDevices(std::vector<Device*> deviceCol, const bool recvNow, MultiplexingContext* pContext);
+            virtual void getOneDevice(Device* pDevice, const bool recvNow, MultiplexingContext* pContext);
+
+            void setAllDevices(const ServiceLocator* serviceLocator, const bool sendNow, MultiplexingContext* pContext);
+            void setPLCDevices(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator, const bool sendNow, MultiplexingContext* pContext);
+            void setSomeDevices(std::vector<Device*> deviceCol, const bool sendNow, MultiplexingContext* pContext);
+            virtual void setOneDevice(Device* pDevice, const bool sendNow, MultiplexingContext* pContext);
+
+        protected:
+
+            static Silecs::Service* pService_;
+            static Silecs::Cluster* pCluster_;
+            static bool isInitialized_;
+
+            // Name of the silecs-block which is addressed
+            std::string blockName_;
+
+            // not copyable object
+            AbstractAllTypes(const AbstractAllTypes&);
+            AbstractAllTypes& operator=(const AbstractAllTypes&);
+    };
+
+    // -------------------------------------------------------------------------------------------------
+    #define BLOCK_RO( name )	\
+    class name##_Type : public AbstractAllTypes	\
+    {	\
+        public:	\
+            name##_Type(std::string name);	\
+            ~name##_Type();	\
+            void getOneDevice(Device* pDevice, const bool transmitNow, MultiplexingContext* pContext);	\
+    }
+
+
+    #define BLOCK_WO( name )	\
+    class name##_Type : public AbstractAllTypes	\
+    {	\
+        public:	\
+            name##_Type(std::string name);	\
+            ~name##_Type();	\
+        void setOneDevice(Device* pDevice, const bool transmitNow, MultiplexingContext* pContext);	\
+        void setOneDevice(Device* pDevice, name##PropertyData& data, const bool transmitNow, MultiplexingContext* pContext);	\
+    }
+
+    #define BLOCK_RW( name )	\
+    class name##_Type : public AbstractAllTypes	\
+    {	\
+        public:	\
+            name##_Type(std::string name);	\
+            ~name##_Type();	\
+            void getOneDevice(Device* pDevice, const bool transmitNow, MultiplexingContext* pContext);	\
+            void setOneDevice(Device* pDevice, const bool transmitNow, MultiplexingContext* pContext);	\
+            void setOneDevice(Device* pDevice, name##PropertyData& data, const bool transmitNow, MultiplexingContext* pContext);	\
+    }
+    
+    BLOCK_RO( MyROBlock );
+    BLOCK_RW( MyRWBlock );
+    BLOCK_WO( MyWOBlock );
+    
+    /*---------------------------------------------------------------------------------------------------------
+     * INTERFACE
+     *---------------------------------------------------------------------------------------------------------
+     * This is the public interface used from the FESA code to access the PLC service.
+     */
+    class AllTypes
+    {
+        public:
+            static inline Silecs::Service* theService()  { return AbstractAllTypes::theService(); }
+            static inline Silecs::Cluster* theCluster()  { return AbstractAllTypes::theCluster(); }
+            static void setup(const ServiceLocator* serviceLocator) { AbstractAllTypes::setup(serviceLocator); }
+            static void cleanup() { AbstractAllTypes::cleanup(); }
+
+                static MyROBlock_Type MyROBlock;
+                static MyRWBlock_Type MyRWBlock;
+                static MyWOBlock_Type MyWOBlock;
+               
+        };
+    }
+
+    #endif /* AllTypes_AllTypes_H_ */
+    
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/generated_correct/AllTypesFESA.design b/silecs-codegen/src/xml/test/generated_correct/AllTypesFESA.design
new file mode 100644
index 0000000000000000000000000000000000000000..68ba06391b0da0070cd148dffab36d658d29c968
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/AllTypesFESA.design
@@ -0,0 +1,657 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<equipment-model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../design-gsi.xsd">
+	<information>
+	  	<class-name>MyClass</class-name>
+		<class-major-version>0</class-major-version>
+		<class-minor-version>1</class-minor-version>
+		<class-tiny-version>0</class-tiny-version>
+		<type>Final</type>
+		<state>development</state>
+		<description>An Empty design with GSI-specific standard properties</description>
+		<fesa-version>3.1.0</fesa-version>
+		<repository-path>undefined</repository-path>
+	</information>
+	<ownership>
+		<responsible name="CSCO"/>
+		<creator login="schwinn"/>
+	</ownership>
+        <interface>
+        <device-interface>
+            <setting>
+                <GSI-Init-Property multiplexed="false" name="Init" visibility="operational">
+                    <set-action partial-setting="true" transaction="true">
+                        <server-action-ref server-action-name-ref="InitSetAction"/>
+                    </set-action>
+                </GSI-Init-Property>
+                <GSI-Reset-Property multiplexed="false" name="Reset" visibility="operational">
+                    <set-action partial-setting="true" transaction="true">
+                        <server-action-ref server-action-name-ref="ResetSetAction"/>
+                    </set-action>
+                </GSI-Reset-Property>
+                <GSI-Setting-Property multiplexed="false" name="Setting" visibility="operational">
+                    <update-flag-item direction="OUT" name="updateFlags" optional="true">
+                       <builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                    </update-flag-item>
+                    <cycle-name-item direction="OUT" name="cycleName" optional="true">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </cycle-name-item>
+                    <set-action partial-setting="true" transaction="true">
+                        <server-action-ref server-action-name-ref="SettingSetAction"/>
+                    </set-action>
+                    <get-action>
+                        <server-action-ref server-action-name-ref="SettingGetAction"/>
+                    </get-action>
+                </GSI-Setting-Property>
+                <GSI-Setting-Property name="MyRWBlock" multiplexed="false" visibility="development"><value-item name="RW_dt" direction="INOUT"><array2D type="double"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_dt"/></value-item><value-item name="RW_real" direction="INOUT"><array2D type="float"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_real"/></value-item><value-item name="RW_dint" direction="INOUT"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_dint"/></value-item><value-item name="RW_int" direction="INOUT"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_int"/></value-item><value-item name="RW_dword" direction="INOUT"><array2D type="int64_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_dword"/></value-item><value-item name="RW_word" direction="INOUT"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_word"/></value-item><value-item name="RW_byte" direction="INOUT"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_byte"/></value-item><value-item name="RW_char" direction="INOUT"><array2D type="int8_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_char"/></value-item><value-item name="RW_date" direction="INOUT"><array2D type="double"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_date"/></value-item><value-item name="RW_float32" direction="INOUT"><array2D type="float"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_float32"/></value-item><value-item name="RW_uint32" direction="INOUT"><array2D type="int64_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_uint32"/></value-item><value-item name="RW_int32" direction="INOUT"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_int32"/></value-item><value-item name="RW_uint16" direction="INOUT"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_uint16"/></value-item><value-item name="RW_int16" direction="INOUT"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_int16"/></value-item><value-item name="RW_uint8" direction="INOUT"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_uint8"/></value-item><value-item name="RW_int8" direction="INOUT"><array2D type="int8_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_int8"/></value-item><update-flag-item direction="OUT" optional="true" name="updateFlags"><builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/></update-flag-item><cycle-name-item direction="OUT" optional="true" name="cycleName"><array type="char"><dim>32</dim></array></cycle-name-item><set-action><server-action-ref server-action-name-ref="SendMyRWBlock"/></set-action><get-action><server-action-ref server-action-name-ref="RecvMyRWBlock"/></get-action></GSI-Setting-Property><GSI-Setting-Property name="MyWOBlock" multiplexed="false" visibility="development"><value-item name="WO_dt" direction="INOUT"><array type="double"><dim>10</dim></array><data-field-ref field-name-ref="WO_dt"/></value-item><value-item name="WO_real" direction="INOUT"><array type="float"><dim>10</dim></array><data-field-ref field-name-ref="WO_real"/></value-item><value-item name="WO_dint" direction="INOUT"><array type="int32_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_dint"/></value-item><value-item name="WO_int" direction="INOUT"><array type="int16_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_int"/></value-item><value-item name="WO_dword" direction="INOUT"><array type="int64_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_dword"/></value-item><value-item name="WO_word" direction="INOUT"><array type="int32_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_word"/></value-item><value-item name="WO_byte" direction="INOUT"><array type="int16_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_byte"/></value-item><value-item name="WO_char" direction="INOUT"><array type="int8_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_char"/></value-item><value-item name="WO_date" direction="INOUT"><array type="double"><dim>10</dim></array><data-field-ref field-name-ref="WO_date"/></value-item><value-item name="WO_string" direction="INOUT"><array2D type="char"><dim1>10</dim1><dim2>64</dim2></array2D><data-field-ref field-name-ref="WO_string"/></value-item><value-item name="WO_float32" direction="INOUT"><array type="float"><dim>10</dim></array><data-field-ref field-name-ref="WO_float32"/></value-item><value-item name="WO_uint32" direction="INOUT"><array type="int64_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_uint32"/></value-item><value-item name="WO_int32" direction="INOUT"><array type="int32_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_int32"/></value-item><value-item name="WO_uint16" direction="INOUT"><array type="int32_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_uint16"/></value-item><value-item name="WO_int16" direction="INOUT"><array type="int16_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_int16"/></value-item><value-item name="WO_uint8" direction="INOUT"><array type="int16_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_uint8"/></value-item><value-item name="WO_int8" direction="INOUT"><array type="int8_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_int8"/></value-item><update-flag-item direction="OUT" optional="true" name="updateFlags"><builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/></update-flag-item><cycle-name-item direction="OUT" optional="true" name="cycleName"><array type="char"><dim>32</dim></array></cycle-name-item><set-action><server-action-ref server-action-name-ref="SendMyWOBlock"/></set-action><get-action><server-action-ref server-action-name-ref="GetMyWOBlock"/></get-action></GSI-Setting-Property><GSI-Power-Property multiplexed="false" name="Power" visibility="operational">
+                    <update-flag-item direction="OUT" name="updateFlags" optional="true">
+						<builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                    </update-flag-item>
+                    <cycle-name-item direction="OUT" name="cycleName" optional="true">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </cycle-name-item>
+                    <set-action partial-setting="true" transaction="true">
+                        <server-action-ref server-action-name-ref="PowerSetAction"/>
+                    </set-action>
+                    <get-action>
+                        <server-action-ref server-action-name-ref="PowerGetAction"/>
+                    </get-action>
+                    <power-item direction="INOUT" name="power">
+                        <custom-type-scalar data-type-name-ref="DEVICE_POWER"/>
+                        
+                        <data-field-ref field-name-ref="power"/>
+                    </power-item>
+                </GSI-Power-Property>
+            </setting>
+            <acquisition>
+                <GSI-Status-Property multiplexed="false" name="Status" on-change="true" subscribable="true" visibility="operational">
+                    <acq-stamp-item direction="OUT" name="acqStamp">
+                        <scalar type="int64_t"/>
+                    </acq-stamp-item>
+                    <update-flag-item direction="OUT" name="updateFlags" optional="true">
+                        <builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                    </update-flag-item>
+                    <cycle-name-item direction="OUT" name="cycleName" optional="true">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </cycle-name-item>
+                    <cycle-stamp-item direction="OUT" name="cycleStamp" optional="true">
+                        <scalar type="int64_t"/>
+                    </cycle-stamp-item>
+                    <get-action>
+                        <server-action-ref server-action-name-ref="StatusGetAction"/>
+                    </get-action>
+                    <status-item direction="OUT" name="status">
+                        <custom-type-scalar data-type-name-ref="DEVICE_STATUS"/>
+                        
+                        <data-field-ref field-name-ref="status"/>
+                    </status-item>
+                    <detailed-status-item direction="OUT" name="detailedStatus">
+                        <array type="bool">
+                            <custom-constant-dim constant-name-ref="DETAILED_STATUS_SIZE"/>
+                        </array>
+                        <data-field-ref field-name-ref="detailedStatus"/>
+                    </detailed-status-item>
+                    <detailed-status-labels-item direction="OUT" name="detailedStatus_labels">
+                        <array2D type="char">
+                            <custom-constant-dim1 constant-name-ref="DETAILED_STATUS_SIZE"/>
+                            <custom-constant-dim2 constant-name-ref="MAX_DETAILED_STATUS_LABEL_LENGTH"/>
+                        </array2D>
+                        <data-field-ref field-name-ref="detailedStatus_labels"/>
+                    </detailed-status-labels-item>
+                    <detailed-status-severity-item direction="OUT" name="detailedStatus_severity">
+                        <custom-type-array data-type-name-ref="DETAILED_STATUS_SEVERITY">
+                            <custom-constant-dim constant-name-ref="DETAILED_STATUS_SIZE"/>
+                        </custom-type-array>
+                        <data-field-ref field-name-ref="detailedStatus_severity"/>
+                    </detailed-status-severity-item>
+                    <powerState-item direction="OUT" name="powerState">
+                        <custom-type-scalar data-type-name-ref="DEVICE_POWER_STATE"/>
+                        
+                        <data-field-ref field-name-ref="powerState"/>
+                    </powerState-item>
+                    <control-item direction="OUT" name="control">
+                        <custom-type-scalar data-type-name-ref="DEVICE_CONTROL"/>
+                        
+                        <data-field-ref field-name-ref="control"/>
+                    </control-item>
+                    <interlock-item direction="OUT" name="interlock">
+                        <scalar type="bool"/>
+                        <data-field-ref field-name-ref="interlock"/>
+                    </interlock-item>
+                    <opReady-item direction="OUT" name="opReady">
+                        <scalar type="bool"/>
+                        <data-field-ref field-name-ref="opReady"/>
+                    </opReady-item>
+                    <modulesReady-item direction="OUT" name="modulesReady">
+                        <scalar type="bool"/>
+                        <data-field-ref field-name-ref="modulesReady"/>
+                    </modulesReady-item>
+                    <error_collection-item direction="OUT">
+                        <error_codes direction="OUT" name="error_codes">
+                            <array type="int32_t">
+                                <custom-constant-dim constant-name-ref="MAX_NUMBER_OF_ERROR_MESSAGES"/>
+                            </array>
+                        </error_codes>
+                        <error_messages direction="OUT" name="error_messages">
+                            <array2D type="char">
+                                <custom-constant-dim1 constant-name-ref="MAX_NUMBER_OF_ERROR_MESSAGES"/>
+                                <custom-constant-dim2 constant-name-ref="MAX_ERROR_MESSAGE_LENGTH"/>
+                            </array2D>
+                        </error_messages>
+                        <error_timestamps direction="OUT" name="error_timestamps">
+                            <array type="int64_t">
+                                <custom-constant-dim constant-name-ref="MAX_NUMBER_OF_ERROR_MESSAGES"/>
+                            </array>
+                        </error_timestamps>
+                        <error_cycle_names direction="OUT" name="error_cycle_names">
+                            <array2D type="char">
+                                <custom-constant-dim1 constant-name-ref="MAX_NUMBER_OF_ERROR_MESSAGES"/>
+                                <custom-constant-dim2 constant-name-ref="MAX_ERROR_MESSAGE_LENGTH"/>
+                            </array2D>
+                        </error_cycle_names>
+                        <error_collection-field-ref field-name-ref="error_collection"/>
+                    </error_collection-item>
+                </GSI-Status-Property>
+                <GSI-ModuleStatus-Property visibility="development" subscribable="true" name="ModuleStatus" multiplexed="false">
+                	<acq-stamp-item name="acqStamp" direction="OUT">
+                		<scalar type="int64_t"/>
+                	</acq-stamp-item>
+                	<update-flag-item optional="true" name="updateFlags" direction="OUT">
+                		<builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                	</update-flag-item>
+                	<cycle-name-item optional="true" name="cycleName" direction="OUT">
+                		<array type="char">
+                			<dim>32</dim>
+                		</array>
+                	</cycle-name-item>
+                	<cycle-stamp-item optional="true" name="cycleStamp" direction="OUT">
+                		<scalar type="int64_t"/>
+                	</cycle-stamp-item>
+                	<get-action>
+                		<server-action-ref server-action-name-ref="ModuleStatusGetAction"/>
+                	</get-action>
+                	<module-status-item name="moduleStatus" direction="OUT">
+                		<custom-type-array data-type-name-ref="MODULE_STATUS">
+                			<custom-constant-dim constant-name-ref="MODULE_STATUS_SIZE"/>
+                			
+                		</custom-type-array>
+                		
+                		<data-field-ref field-name-ref="moduleStatus"/>
+                	</module-status-item>
+                	<module-status-labels-item name="moduleStatus_labels" direction="OUT">
+                		<array2D type="char">
+                			<custom-constant-dim1 constant-name-ref="MODULE_STATUS_SIZE"/>
+                			<custom-constant-dim2 constant-name-ref="MAX_MODULE_STATUS_LABEL_LENGTH"/>
+                			
+                		</array2D>
+                		
+                		<data-field-ref field-name-ref="moduleStatus_labels"/>
+                	</module-status-labels-item>
+                </GSI-ModuleStatus-Property>
+                <GSI-Acquisition-Property multiplexed="true" name="Acquisition" on-change="true" subscribable="true" visibility="operational">
+                    <acq-stamp-item direction="OUT" name="acqStamp">
+                        <scalar type="int64_t"/>
+                    </acq-stamp-item>
+                    <update-flag-item direction="OUT" name="updateFlags" optional="true">
+                        <builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                    </update-flag-item>
+                    <cycle-name-item direction="OUT" name="cycleName" optional="true">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </cycle-name-item>
+                    <cycle-stamp-item direction="OUT" name="cycleStamp" optional="true">
+                        <scalar type="int64_t"/>
+                    </cycle-stamp-item>
+                    <get-action>
+                        <server-action-ref server-action-name-ref="AcquisitionGetAction"/>
+                    </get-action>
+                    <acquisition-context-item direction="OUT">
+                        <acqStamp direction="OUT" name="acqStampGSI">
+                            <scalar type="int64_t"/>
+                        </acqStamp>
+                        <cycleStamp direction="OUT" name="cycleStampGSI">
+                            <scalar type="int64_t"/>
+                        </cycleStamp>
+                        <cycleName direction="OUT" name="cycleNameGSI">
+                            <array type="char">
+                                <custom-constant-dim constant-name-ref="MAX_CYCLE_NAME_LENGTH"/>
+                            </array>
+                        </cycleName>
+                        <beamProcessID direction="OUT" name="beamProcessID">
+                            <scalar type="int32_t"/>
+                        </beamProcessID>
+                         <sequenceID direction="OUT" name="sequenceID">
+                            <scalar type="int32_t"/>
+                        </sequenceID>
+                        <acquisition-context-field-ref field-name-ref="acquisitionContext"/>
+                    </acquisition-context-item>
+                </GSI-Acquisition-Property>
+                <GSI-Acquisition-Property name="MyROBlock" subscribable="true" multiplexed="false" on-change="true" visibility="development"><value-item name="RO_dt" direction="OUT"><scalar type="double"/><data-field-ref field-name-ref="RO_dt"/></value-item><value-item name="RO_real" direction="OUT"><scalar type="float"/><data-field-ref field-name-ref="RO_real"/></value-item><value-item name="RO_dint" direction="OUT"><scalar type="int32_t"/><data-field-ref field-name-ref="RO_dint"/></value-item><value-item name="RO_int" direction="OUT"><scalar type="int16_t"/><data-field-ref field-name-ref="RO_int"/></value-item><value-item name="RO_dword" direction="OUT"><scalar type="int64_t"/><data-field-ref field-name-ref="RO_dword"/></value-item><value-item name="RO_word" direction="OUT"><scalar type="int32_t"/><data-field-ref field-name-ref="RO_word"/></value-item><value-item name="RO_byte" direction="OUT"><scalar type="int16_t"/><data-field-ref field-name-ref="RO_byte"/></value-item><value-item name="RO_char" direction="OUT"><scalar type="int8_t"/><data-field-ref field-name-ref="RO_char"/></value-item><value-item name="RO_date" direction="OUT"><scalar type="double"/><data-field-ref field-name-ref="RO_date"/></value-item><value-item name="RO_string" direction="OUT"><array type="char"><dim>64</dim></array><data-field-ref field-name-ref="RO_string"/></value-item><value-item name="RO_float32" direction="OUT"><scalar type="float"/><data-field-ref field-name-ref="RO_float32"/></value-item><value-item name="RO_uint32" direction="OUT"><scalar type="int64_t"/><data-field-ref field-name-ref="RO_uint32"/></value-item><value-item name="RO_int32" direction="OUT"><scalar type="int32_t"/><data-field-ref field-name-ref="RO_int32"/></value-item><value-item name="RO_uint16" direction="OUT"><scalar type="int32_t"/><data-field-ref field-name-ref="RO_uint16"/></value-item><value-item name="RO_int16" direction="OUT"><scalar type="int16_t"/><data-field-ref field-name-ref="RO_int16"/></value-item><value-item name="RO_uint8" direction="OUT"><scalar type="int16_t"/><data-field-ref field-name-ref="RO_uint8"/></value-item><value-item name="RO_int8" direction="OUT"><scalar type="int8_t"/><data-field-ref field-name-ref="RO_int8"/></value-item><acq-stamp-item direction="OUT" name="acqStamp"><scalar type="int64_t"/></acq-stamp-item><update-flag-item direction="OUT" optional="true" name="updateFlags"><builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/></update-flag-item><cycle-name-item direction="OUT" optional="true" name="cycleName"><array type="char"><dim>32</dim></array></cycle-name-item><cycle-stamp-item direction="OUT" optional="true" name="cycleStamp"><scalar type="int64_t"/></cycle-stamp-item><get-action><server-action-ref server-action-name-ref="GetMyROBlock"/></get-action><acquisition-context-item direction="OUT"><processIndex direction="OUT" name="processIndex"><scalar type="int32_t"/></processIndex><sequenceIndex direction="OUT" name="sequenceIndex"><scalar type="int32_t"/></sequenceIndex><chainIndex direction="OUT" name="chainIndex"><scalar type="int32_t"/></chainIndex><eventNumber direction="OUT" name="eventNumber"><scalar type="int32_t"/></eventNumber><timingGroupID direction="OUT" name="timingGroupID"><scalar type="int32_t"/></timingGroupID><acquisitionStamp direction="OUT" name="acquisitionStamp"><scalar type="int64_t"/></acquisitionStamp><eventStamp direction="OUT" name="eventStamp"><scalar type="int64_t"/></eventStamp><processStartStamp direction="OUT" name="processStartStamp"><scalar type="int64_t"/></processStartStamp><sequenceStartStamp direction="OUT" name="sequenceStartStamp"><scalar type="int64_t"/></sequenceStartStamp><chainStartStamp direction="OUT" name="chainStartStamp"><scalar type="int64_t"/></chainStartStamp><acquisition-context-field-ref field-name-ref="acquisitionContext"/></acquisition-context-item></GSI-Acquisition-Property><GSI-Version-Property multiplexed="false" name="Version" on-change="false" subscribable="false" visibility="operational">
+                    <acq-stamp-item direction="OUT" name="acqStamp">
+                        <scalar type="int64_t"/>
+                    </acq-stamp-item>
+                    <update-flag-item direction="OUT" name="updateFlags" optional="true">
+                        <builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                    </update-flag-item>
+                    <cycle-name-item direction="OUT" name="cycleName" optional="true">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </cycle-name-item>
+                    <cycle-stamp-item direction="OUT" name="cycleStamp" optional="true">
+                        <scalar type="int64_t"/>
+                    </cycle-stamp-item>
+                    <get-action>
+                        <server-action-ref server-action-name-ref="VersionGetAction"/>
+                    </get-action>
+                    <version-item direction="OUT" name="classVersion">
+                        <array type="char">
+                            <custom-constant-dim constant-name-ref="MAX_VERSION_NAME_LENGTH"/>
+                        </array>
+                    </version-item>
+                    <version-item direction="OUT" name="deployUnitVersion">
+                        <array type="char">
+                            <custom-constant-dim constant-name-ref="MAX_VERSION_NAME_LENGTH"/>
+                        </array>
+                    </version-item>
+                    <version-item direction="OUT" name="fesaVersion">
+                        <array type="char">
+                            <custom-constant-dim constant-name-ref="MAX_VERSION_NAME_LENGTH"/>
+                        </array>
+                    </version-item>
+                </GSI-Version-Property>
+         </acquisition>
+      </device-interface>
+        <global-interface>
+            <setting>
+                <diagnostic-property multiplexed="false" name="DiagnosticSetting" visibility="expert">
+                    <description>Generic property which allows to diagnose any FESA classes</description>
+                        <mode-item direction="INOUT" name="enableDiagMode">
+                            <scalar type="bool"/>
+                        </mode-item>
+                        <host-item direction="INOUT" name="hostName">
+                            <array type="char">
+                                <dim>32</dim>
+                            </array>
+                        </host-item>
+                        <port-item direction="INOUT" name="portNumber">
+                            <scalar type="int32_t"/>
+                        </port-item>
+                        <config-item direction="IN" name="requestConfig">
+                            <scalar type="bool"/>
+                        </config-item>
+                        <state-item direction="IN" name="requestState">
+                            <scalar type="bool"/>
+                        </state-item>
+                        <fwk-topic-item direction="INOUT" name="fwkTopic">
+                            <builtin-type-scalar data-type-name-ref="DIAG_FWK_TOPIC"/>
+                        </fwk-topic-item>
+                        <custom-topic-item direction="INOUT" name="customTopic">
+                            <custom-type-scalar data-type-name-ref="DIAG_TOPIC"/>
+                        </custom-topic-item>
+                        <device-trace-item direction="INOUT" name="traceDevices">
+                            <array type="char">
+                                <dim>320</dim>
+                            </array>
+                        </device-trace-item>
+                        <bypass-action-item direction="INOUT" name="bypassActions">
+                            <array type="char">
+                                <dim>320</dim>
+                            </array>
+                        </bypass-action-item>
+                </diagnostic-property>
+            </setting>
+            <acquisition>
+                <GSI-DeviceDescription-Property multiplexed="false" name="DeviceDescription" on-change="false" subscribable="false" visibility="operational">
+                    <timing-info-item direction="OUT" name="deviceNameTimingReceiver">
+                        <array type="char">
+                            <variable-dim/>
+                        </array>
+                        <data-field-ref field-name-ref="deviceNameTimingReceiver"/>
+                    </timing-info-item>
+                    <property-info-item direction="OUT" name="propertyNames">
+                        <array2D type="char">
+                            <variable-dim1/>
+                            <variable-dim2/>
+                        </array2D>
+                    </property-info-item>
+                    <device-info-item direction="OUT" name="deviceNames">
+                        <array2D type="char">
+                            <variable-dim1/>
+                            <variable-dim2/>
+                        </array2D>
+                    </device-info-item>
+                    <global-device-info-item direction="OUT" name="globalDeviceName">
+                        <array type="char">
+                            <variable-dim/>
+                        </array>
+                    </global-device-info-item>
+                    <host-info-item direction="OUT" name="host">
+                        <array type="char">
+                            <variable-dim/>
+                        </array>
+                    </host-info-item>
+                </GSI-DeviceDescription-Property>
+            </acquisition>
+        </global-interface>
+    </interface>
+    <builtin-types>
+		<notification-update-enum name="NOTIFICATION_UPDATE">
+            <IMMEDIATE access="RO" symbol="IMMEDIATE" value="1"/>
+            <SET access="RO" symbol="SET" value="2"/>
+        </notification-update-enum>
+        <diag-fwk-topic name="DIAG_FWK_TOPIC">
+            <b0 name="SRV_GET_ACTION_PROFIING"/>
+            <b1 name="SRV_SET_ACTION_PROFILING"/>
+            <b2 name="RT_ACTION_PROFILING"/>
+            <b3 name="EVENT_PROFILING"/>
+            <b4 name="NOTIFICATION_PROFILING"/>
+            <b5 name="SRV_GET_ACTION_TRACKING"/>
+            <b6 name="SRV_SET_ACTION_TRACKING"/>
+            <b7 name="RT_ACTION_TRACKING"/>
+            <b8 name="EVENT_TRACKING"/>
+            <b9 name="NOTIFICATION_TRACKING"/>
+            <b10 name="PERSISTENCY_TRACKING"/>
+            <b11 name="TRANSACTION_TRACKING"/>
+            <b12 name="SUBSCRIPTION_TRACKING"/>
+            <b13 name="SIGNAL_HANDLER_TRACKING"/>
+            <b14 name="LOCAL_CONNECTION_TRACKING"/>
+        </diag-fwk-topic>
+        <fault-severity name="FaultSeverity">
+        	<description>Enumeration listing the available fault severities used by the fault fields</description>
+        	<INFO access="RO" meaning="NONE" value="0" symbol="INFO"/>
+        	<WARNING access="RO" meaning="WARNING" value="1" symbol="WARNING"/>
+        	<ERROR access="RO" meaning="ERROR" value="2" symbol="ERROR"/>
+        	<CRITICAL access="RO" meaning="ERROR" value="3" symbol="CRITICAL"/>
+        </fault-severity>
+
+    </builtin-types>
+    <custom-types>
+        <diag-custom-topic name="DIAG_TOPIC">
+        </diag-custom-topic>
+        <enum name="DEVICE_STATUS">
+        <!--Possible (mutually exclusive) values to describe the device status-->
+            
+            <item access="RW" meaning="NONE" symbol="UNKNOWN" value="0"/>
+            <!--The device status is unknown-->
+            
+            <item access="RW" meaning="NONE" symbol="OK" value="1"/>
+            <!--The device is in fully operational state-->
+            
+            <item access="RW" meaning="NONE" symbol="WARNING" value="2"/>
+            <!--The device is not fully operational; A device in WARNING state can still be used operationally, -->
+            <!--but clients must be informed of a problem that might become worse. Details are explained in the errorMsg field.-->
+            
+            <item access="RW" meaning="NONE" symbol="ERROR" value="3"/>
+            <!--The device is in a fault state. Details are explained in the errorMsg field-->
+        </enum>
+        <enum name="DEVICE_POWER_STATE">
+        <!--Possible (mutually exclusive) values to describe the power-state of the device.-->
+            
+            <item access="RW" meaning="NONE" symbol="UNKNOWN" value="0"/>
+            <!--The device mode is unknown-->
+            
+            <item access="RW" meaning="ON" symbol="ON" value="1"/>
+            <!--The device is in fully operational state-->
+            
+            <item access="RW" meaning="NONE" symbol="OFF" value="2"/>
+            <!--The device is turned off-->
+            
+            <item access="RW" meaning="NONE" symbol="STANDBY" value="3"/>
+            <!--The device is in a stand-by mode. This mode is a sort of “parking mode” in which the device can -->
+            <!--stay for hours or even days. It is defined by the following characteristics:-->
+            <!--It is safe, it does not wear out, it consumes little energy.-->
+            <!--Furthermore, it takes a short time to go from STANDBY to ON mode-->
+            
+            <item access="RW" meaning="NONE" symbol="POWER_DOWN" value="4"/>
+            <!--The device is shutting down. Note that some properties may not be accessible during this time.-->
+            <!--After shutdown the device will be in the mode OFF-->
+            
+            <item access="RW" meaning="NONE" symbol="POWER_UP" value="5"/>
+            <!--The device is starting up. Note that some properties may not be accessible during this time.-->
+            <!--After (re-)starting the device probably will be in the mode ON-->
+            
+        </enum>
+        <enum name="DEVICE_POWER">
+        <!--An enumeration Type used to control the operational mode of the device.-->
+        <!--Its values are a subset of those in the DEVICE_POWER_STATE type-->
+            <item access="RW" meaning="ON" symbol="ON" value="1"/>
+            <!--The device is in fully operational state-->     
+            
+            <item access="RW" meaning="OFF" symbol="OFF" value="2"/>
+            <!--The device is turned off-->
+        </enum>
+        <enum name="DEVICE_CONTROL">
+        <!--Possible values to describe the control mode of a device-->
+        <!--Currently two control modes (LOCAL, REMOTE) are defined-->
+        
+            <item access="RW" meaning="NONE" symbol="REMOTE" value="0"/>
+            <!--The device can be controlled normally through the control system-->
+            
+            <item access="RW" meaning="NONE" symbol="LOCAL" value="1"/>
+            <!--The device can be controlled locally. But it can be accessed in read-only mode via the control system-->
+        </enum>
+        <enum name="TOL_CHECK_MODE">
+        <!--This constant defines possible modes to check whether a control value is inside the tolerance values.-->
+        <!--Used to give information on how the tolerance fields are used to calculate the xxx_status information.-->
+        
+            <item access="RO" symbol="ABS" value="0"/>
+            <!--Use the absolute tolerance _tolAbs-->
+            
+            <item access="RO" symbol="REL" value="1"/>
+            <!--Use the relative tolerance _tolRel-->
+        </enum>
+        <bit-enum-32bits name="AQN_STATUS">
+        <!--Possible values to describe the acquisition status of a field (in the _status suffix)-->
+        <!--If this suffix is missing, it means that no additional status information is provided for the corresponding field-->
+        <!--If all bits are 0, this means that the corresponding field is OK.-->
+        <!--Only the lower 16 bits are standardized, the upper 16 bits can be defined by the equipment specialist.-->
+        <!--The difference between the Status property and the _status suffix is described in the section on the Status property.-->
+            <b0 name="NOT_OK"/>
+            <!--Some problem occurred that is not represented by the other bits. This property is called-->
+            <!-- NOT_OK so that it is not mixed up with ERROR or WARNING in the Status property-->
+            <b1 name="BAD_QUALITY"/>
+            <!--The value was acquired with a degraded quality. This is typically used for measurements.-->
+            <b2 name="DIFFERENT_FROM_SETTING"/>
+            <!--Different from the requested control value (for discrete values)--><!--or out of tolerance (for continuous values).-->
+            <b3 name="OUT_OF_RANGE"/>
+            <!--The value is out of the normal range (e.g. a temperature is too high or too low).-->
+            <b4 name="BUSY"/>
+            <!--The property value is changing in response to receiving a new control value (e.g. moving to a-->
+            <!--new position, charging a capacitor, ...). If the value change does not reach the requested new-->
+            <!--value within the maximum timeout, the BUSY bit should remain=1 and the TIMEOUT bit must be turned on.-->
+            <b5 name="TIMEOUT"/>
+            <!--A timeout occurred, because the property did not reach the reqested new control value within the-->
+            <!--maximum allowable time. A timeout normally indicates a problem to be addressed by the-->
+            <!--equipment specialist. This is typically used for slow changing control values that are BUSY while they change.-->
+            <b6 name="bit6_is_reserved_for_later_usage"/>
+            <b7 name="bit7_is_reserved_for_later_usage"/>
+            <b8 name="bit8_is_reserved_for_later_usage"/>
+            <b9 name="bit9_is_reserved_for_later_usage"/>
+            <b10 name="bit10_is_reserved_for_later_usage"/>
+            <b11 name="bit11_is_reserved_for_later_usage"/>
+            <b12 name="bit12_is_reserved_for_later_usage"/>
+            <b13 name="bit13_is_reserved_for_later_usage"/>
+            <b14 name="bit14_is_reserved_for_later_usage"/>
+            <b15 name="bit15_is_reserved_for_later_usage"/>
+            <!--bit 6 to 15 are reserved ... dont use them!-->
+            
+            <b16 name="bit_16_and_higher_can_be_used_by_the_class_developer"/>
+            <!--into bit 16..32 you can put in anything you want-->
+        </bit-enum-32bits>
+
+        <struct name="GSI_ERROR">
+        <!--This struct-item describes the structure of an GSI-error-->
+            <struct-item name="error_string">
+            <!--This string holds the error-message-->
+                <array type="char">
+                    <custom-constant-dim constant-name-ref="MAX_ERROR_MESSAGE_LENGTH"/>
+                </array>
+            </struct-item>
+            <struct-item name="error_code">
+            <!--The error code according to the defined error-message-->
+                <scalar type="int32_t"/>
+            </struct-item>
+            <!--The timestamp when the error occured-->
+            <struct-item name="error_timestamp">
+                <scalar type="int64_t"/>
+            </struct-item>
+            <!--The cycle for which the error occured-->
+            <struct-item name="error_cycle_name">
+                <array type="char">
+                    <custom-constant-dim constant-name-ref="MAX_CYCLE_NAME_LENGTH"/>
+                </array>
+            </struct-item>
+        </struct>
+        <struct name="GSI_ACQ_CONTEXT">
+        <!--This struct-item describes all AcquisitionContext items which are relevant for GSI-->
+            <struct-item name="acqStamp">
+            <!--The acquisition stamp is used to indicate when a measurement was done -->
+                <scalar type="int64_t"/>
+            </struct-item>
+            <struct-item name="cycleStamp">
+            <!--The cycle stamp is used to indicate when a specific cycle has started-->
+                <scalar type="int64_t"/>
+            </struct-item>
+            <struct-item name="cycleName">
+            <!--The cycle name indicates the cycle which started at time of the cycleStamp -->
+                <array type="char">
+                    <custom-constant-dim constant-name-ref="MAX_CYCLE_NAME_LENGTH"/>    
+                </array>
+            </struct-item>
+            <struct-item name="beamProcessID">
+				<scalar type="int32_t"/>
+            </struct-item>
+            <struct-item name="sequenceID">
+				<scalar type="int32_t"/>
+            </struct-item>
+        </struct>
+        <constant name="MAX_ERROR_MESSAGE_LENGTH" type="uint32_t" value="256"/>
+        <constant name="MAX_NUMBER_OF_ERROR_MESSAGES" type="uint32_t" value="16"/>
+        <constant name="MAX_CYCLE_NAME_LENGTH" type="uint32_t" value="256"/>
+        <constant name="MAX_VERSION_NAME_LENGTH" type="uint32_t" value="256"/>
+        <constant name="MAX_DETAILED_STATUS_LABEL_LENGTH" type="uint32_t" value="30"/>
+        <constant name="DETAILED_STATUS_SIZE" type="uint32_t" value="2"/>
+        <enum name="DETAILED_STATUS_SEVERITY">
+            <item access="RO" symbol="INFO" value="0"/>
+            <item access="RO" symbol="WARNING_ON_FALSE" value="1"/>
+            <item access="RO" symbol="ERROR_ON_FALSE" value="2"/>
+        </enum>
+        <enum name="MODULE_STATUS">
+        <!-- Mutually exclusive values to describe the status of a hardware / software module-->
+        	<item access="RO" value="0" symbol="UNKNOWN"/>
+        	<!--The status of the module is not known-->
+        	<item access="RO" value="1" symbol="OK"/>
+        	<!--The module is in fully operational state-->
+        	<item access="RO" value="2" symbol="WARNING"/>
+        	<!--The module is not fully operational; A module in WARNING state may still be used operationally, -->
+        	<!--but clients must be informed of a problem that might become worse. -->
+        	<item access="RO" value="3" symbol="ERROR"/>
+        	<!--The module is in a fault state. The related device is not operational.-->
+        	<item access="RO" value="4" symbol="NOT_AVAILABLE"/>
+            <!--The module is missing. The related device is not operational.-->
+        </enum>
+        <constant name="MAX_MODULE_STATUS_LABEL_LENGTH" type="uint32_t" value="30"/>
+        <constant name="MODULE_STATUS_SIZE" type="uint32_t" value="2"/>
+    </custom-types>
+    <data>
+        <device-data>
+            <configuration>
+                <field name="parameterFile"><description>ParameterFile of the PLC (*.silecsparam)</description><array type="char"><dim>512</dim></array><default>../../../generated/client/MyControllerName.silecsparam</default></field><field name="plcDeviceLabel"><description>Name of the related SILECS instance within the PLC mapping</description><array type="char"><dim>128</dim></array></field><field name="plcHostName"><description>Hostname of the PLC that contains the related SILECS class device</description><array type="char"><dim>128</dim></array></field><GSI-detailed-status-labels-field name="detailedStatus_labels">
+                    <array2D type="char">
+                        <custom-constant-dim1 constant-name-ref="DETAILED_STATUS_SIZE"/>
+                        <custom-constant-dim2 constant-name-ref="MAX_DETAILED_STATUS_LABEL_LENGTH"/>
+                    </array2D>
+                    <default>{myStatusLabel1,myStatusLabel2}</default>
+                </GSI-detailed-status-labels-field>
+                <GSI-detailed-status-severity-field name="detailedStatus_severity">
+                    <custom-type-array data-type-name-ref="DETAILED_STATUS_SEVERITY">
+                        <custom-constant-dim constant-name-ref="DETAILED_STATUS_SIZE"/>
+                    </custom-type-array>
+                    <default>{INFO,INFO}</default>
+                </GSI-detailed-status-severity-field>
+                <GSI-module-status-labels-field name="moduleStatus_labels">
+                	<array2D type="char">
+                		<custom-constant-dim1 constant-name-ref="MODULE_STATUS_SIZE"/>
+                		
+                		<custom-constant-dim2 constant-name-ref="MAX_MODULE_STATUS_LABEL_LENGTH"/>
+                	</array2D>
+                	<default>{myModule1,myModule2}</default>
+                </GSI-module-status-labels-field>
+            </configuration>
+            <setting>
+                <field name="WO_dt" shared="true" multiplexed="false" persistent="true"><array type="double"><dim>10</dim></array></field><field name="WO_real" shared="true" multiplexed="false" persistent="true"><array type="float"><dim>10</dim></array></field><field name="WO_dint" shared="true" multiplexed="false" persistent="true"><array type="int32_t"><dim>10</dim></array></field><field name="WO_int" shared="true" multiplexed="false" persistent="true"><array type="int16_t"><dim>10</dim></array></field><field name="WO_dword" shared="true" multiplexed="false" persistent="true"><array type="int64_t"><dim>10</dim></array></field><field name="WO_word" shared="true" multiplexed="false" persistent="true"><array type="int32_t"><dim>10</dim></array></field><field name="WO_byte" shared="true" multiplexed="false" persistent="true"><array type="int16_t"><dim>10</dim></array></field><field name="WO_char" shared="true" multiplexed="false" persistent="true"><array type="int8_t"><dim>10</dim></array></field><field name="WO_date" shared="true" multiplexed="false" persistent="true"><array type="double"><dim>10</dim></array></field><field name="WO_string" shared="true" multiplexed="false" persistent="true"><array2D type="char"><dim1>10</dim1><dim2>64</dim2></array2D></field><field name="WO_float32" shared="true" multiplexed="false" persistent="true"><array type="float"><dim>10</dim></array></field><field name="WO_uint32" shared="true" multiplexed="false" persistent="true"><array type="int64_t"><dim>10</dim></array></field><field name="WO_int32" shared="true" multiplexed="false" persistent="true"><array type="int32_t"><dim>10</dim></array></field><field name="WO_uint16" shared="true" multiplexed="false" persistent="true"><array type="int32_t"><dim>10</dim></array></field><field name="WO_int16" shared="true" multiplexed="false" persistent="true"><array type="int16_t"><dim>10</dim></array></field><field name="WO_uint8" shared="true" multiplexed="false" persistent="true"><array type="int16_t"><dim>10</dim></array></field><field name="WO_int8" shared="true" multiplexed="false" persistent="true"><array type="int8_t"><dim>10</dim></array></field><field name="RW_dt" multiplexed="false" persistent="true"><array2D type="double"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_real" multiplexed="false" persistent="true"><array2D type="float"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_dint" multiplexed="false" persistent="true"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_int" multiplexed="false" persistent="true"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_dword" multiplexed="false" persistent="true"><array2D type="int64_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_word" multiplexed="false" persistent="true"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_byte" multiplexed="false" persistent="true"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_char" multiplexed="false" persistent="true"><array2D type="int8_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_date" multiplexed="false" persistent="true"><array2D type="double"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_float32" multiplexed="false" persistent="true"><array2D type="float"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_uint32" multiplexed="false" persistent="true"><array2D type="int64_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_int32" multiplexed="false" persistent="true"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_uint16" multiplexed="false" persistent="true"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_int16" multiplexed="false" persistent="true"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_uint8" multiplexed="false" persistent="true"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_int8" multiplexed="false" persistent="true"><array2D type="int8_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><GSI-power-field multiplexed="false" name="power" persistent="false">
+                    <custom-type-scalar data-type-name-ref="DEVICE_POWER"/>
+                </GSI-power-field>
+            </setting>
+            <acquisition>
+                <field name="RO_dt" multiplexed="false" persistent="false"><scalar type="double"/></field><field name="RO_real" multiplexed="false" persistent="false"><scalar type="float"/></field><field name="RO_dint" multiplexed="false" persistent="false"><scalar type="int32_t"/></field><field name="RO_int" multiplexed="false" persistent="false"><scalar type="int16_t"/></field><field name="RO_dword" multiplexed="false" persistent="false"><scalar type="int64_t"/></field><field name="RO_word" multiplexed="false" persistent="false"><scalar type="int32_t"/></field><field name="RO_byte" multiplexed="false" persistent="false"><scalar type="int16_t"/></field><field name="RO_char" multiplexed="false" persistent="false"><scalar type="int8_t"/></field><field name="RO_date" multiplexed="false" persistent="false"><scalar type="double"/></field><field name="RO_string" multiplexed="false" persistent="false"><array type="char"><dim>64</dim></array></field><field name="RO_float32" multiplexed="false" persistent="false"><scalar type="float"/></field><field name="RO_uint32" multiplexed="false" persistent="false"><scalar type="int64_t"/></field><field name="RO_int32" multiplexed="false" persistent="false"><scalar type="int32_t"/></field><field name="RO_uint16" multiplexed="false" persistent="false"><scalar type="int32_t"/></field><field name="RO_int16" multiplexed="false" persistent="false"><scalar type="int16_t"/></field><field name="RO_uint8" multiplexed="false" persistent="false"><scalar type="int16_t"/></field><field name="RO_int8" multiplexed="false" persistent="false"><scalar type="int8_t"/></field><GSI-control-field multiplexed="false" name="control">
+                    <custom-type-scalar data-type-name-ref="DEVICE_CONTROL"/>
+                </GSI-control-field>
+                <GSI-powerState-field multiplexed="false" name="powerState">
+                    <custom-type-scalar data-type-name-ref="DEVICE_POWER_STATE"/>
+                </GSI-powerState-field>
+                <GSI-status-field multiplexed="false" name="status">
+                    <custom-type-scalar data-type-name-ref="DEVICE_STATUS"/>
+                </GSI-status-field>
+                <GSI-interlock-field multiplexed="false" name="interlock">
+                    <scalar type="bool"/>
+                </GSI-interlock-field>
+                <GSI-opReady-field multiplexed="false" name="opReady">
+                    <scalar type="bool"/>
+                </GSI-opReady-field>
+                <GSI-modulesReady-field name="modulesReady" multiplexed="false">
+                	<scalar type="bool"/>
+                </GSI-modulesReady-field>
+                <GSI-detailed-status-field multiplexed="false" name="detailedStatus">
+                    <array type="bool">
+                        <custom-constant-dim constant-name-ref="DETAILED_STATUS_SIZE"/>
+                    </array>
+                </GSI-detailed-status-field>
+                <GSI-module-status-field name="moduleStatus" multiplexed="false">
+                	<custom-type-array data-type-name-ref="MODULE_STATUS">
+                		<custom-constant-dim constant-name-ref="MODULE_STATUS_SIZE"/>
+                		
+                	</custom-type-array>
+                </GSI-module-status-field>
+                <GSI-acquisition-context-field multiplexed="true" name="acquisitionContext">
+                    <custom-type-scalar data-type-name-ref="GSI_ACQ_CONTEXT"/>
+                </GSI-acquisition-context-field>
+                <GSI-error_collection-field multiplexed="false" name="error_collection">
+                    <custom-type-array data-type-name-ref="GSI_ERROR">
+                        <custom-constant-dim constant-name-ref="MAX_NUMBER_OF_ERROR_MESSAGES"/>
+                    </custom-type-array>
+                </GSI-error_collection-field>
+            </acquisition>
+        </device-data>
+        <global-data>
+            <configuration>
+                <!-- The name of the timing receiver -->
+                <field name="plcClassVersion"><description>Version of the SILECS class that needs to be deployed in the controller</description><array type="char"><dim>5</dim></array><default>0.1.0</default></field><GSI-timing-receiver-name-field name="deviceNameTimingReceiver">
+                    <array type="char">
+                        <!-- The number of the timing receiver -->
+                        <variable-dim/>
+                    </array>
+                </GSI-timing-receiver-name-field>
+                </configuration>
+        </global-data>
+    </data>
+    <actions>
+        <set-server-action implementation="default" name="InitSetAction"/>
+        <set-server-action implementation="default" name="ResetSetAction"/>
+        <set-server-action implementation="default" name="SettingSetAction"/>
+        <set-server-action implementation="default" name="PowerSetAction"/>
+        <get-server-action implementation="default" name="PowerGetAction"/>
+        <get-server-action implementation="default" name="SettingGetAction"/>
+        <get-server-action implementation="default" name="AcquisitionGetAction"/>
+        <get-server-action implementation="default" name="StatusGetAction"/>
+        <get-server-action implementation="default" name="VersionGetAction"/><get-server-action implementation="default" name="ModuleStatusGetAction"/>
+    <get-server-action name="GetMyROBlock" implementation="default"/><rt-action name="RecvMyROBlock"><notified-property property-name-ref="MyROBlock" automatic="true"/></rt-action><set-server-action name="SendMyRWBlock" implementation="custom"/><get-server-action name="RecvMyRWBlock" implementation="custom"/><set-server-action name="SendMyWOBlock" implementation="custom"/><get-server-action name="GetMyWOBlock" implementation="default"/></actions>
+
+<events><sources><timing-event-source name="Timing"/><timer-event-source name="Timer"/></sources><logical-events><logical-event name="RecvMyROBlockEvent" use="required" type="timer"/></logical-events></events><scheduling-units><scheduling-unit name="RecvMyROBlockUnit"><rt-action-ref rt-action-name-ref="RecvMyROBlock"/><logical-event-ref logical-event-name-ref="RecvMyROBlockEvent"/></scheduling-unit></scheduling-units></equipment-model>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_BC9020.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_BC9020.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..79e434e40e353291d2ba2ef0a1ed7994c52660d0
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_BC9020.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-14 16:03:39.957252"/>
+    <Deployment checksum="2843029646"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Beckhoff_BC9020" plc-brand="BECKHOFF" plc-system="TWINCat" plc-model="BC9020" protocol="BLOCK_MODE" address="32768" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="32768" used-mem="MW16384..MW16407 / 24 words">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="32768" mem-size="48">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="17" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="18" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="22" mem-size="17" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="40" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="32816" used-mem="MW16408..MW18167 / 1760 words">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="32816" mem-size="122">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="2" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="6" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="12" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="65" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="86" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="94" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="96" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="98" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="100" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="104" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="106" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="110" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="114" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="33060" mem-size="468">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="4" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="24" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="40" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="56" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="72" mem-size="260" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="332" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="364" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="372" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="380" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="396" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="404" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="420" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="436" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="33996" mem-size="1170">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="10" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="60" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="100" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="140" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="180" mem-size="650" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="830" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="910" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="930" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="950" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="990" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1010" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1050" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1090" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="0"/>
+      <Instance label="testDevice2" address="1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..90d7bc27743b68dff869e77e160e6a6b0a11cf82
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-14 16:03:58.791145"/>
+    <Deployment checksum="427563505"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Beckhoff_CX9020" plc-brand="BECKHOFF" plc-system="TWINCat" plc-model="CX9020" protocol="BLOCK_MODE" address="24576" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="24576" used-mem="MW12288..MW12313 / 26 words">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="24576" mem-size="52">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="17" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="20" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="24" mem-size="17" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="44" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="24628" used-mem="MW12314..MW14081 / 1768 words">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="24628" mem-size="128">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="2" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="6" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="12" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="65" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="88" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="96" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="98" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="100" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="104" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="108" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="112" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="116" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="120" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="24884" mem-size="468">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="4" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="24" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="40" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="56" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="72" mem-size="260" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="332" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="364" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="372" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="380" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="396" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="404" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="420" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="436" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="25820" mem-size="1172">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="10" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="60" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="100" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="140" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="180" mem-size="650" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="832" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="912" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="922" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="932" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="952" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="992" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1012" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1052" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1092" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="0"/>
+      <Instance label="testDevice2" address="1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..f213b467592a8037d13ad4d9b9c351ecdf82ab86
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-14 16:04:28.617415"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Rabbit_BlockMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="MW0..MW21 / 22 words">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="44">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="16" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="16" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="36" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" used-mem="MW22..MW1821 / 1800 words">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="44" mem-size="120">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="2" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="6" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="12" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="64" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="94" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="96" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="98" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="102" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="104" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="108" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="112" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="284" mem-size="480">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="24" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="32" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="48" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="64" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="80" mem-size="256" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="336" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="384" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="392" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="408" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="416" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="432" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="448" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="1244" mem-size="1200">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="60" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="80" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="120" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="160" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="200" mem-size="640" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="840" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="960" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="980" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1020" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1040" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1080" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1120" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="0"/>
+      <Instance label="testDevice2" address="1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..73cbd938e5446cdc22fd94a3edf000b06608ebd6
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-14 16:04:38.516577"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Rabbit_DeviceMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="DEVICE_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="MW0..MW21 / 22 words">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="44">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="16" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="16" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="36" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" used-mem="MW22..MW1821 / 1800 words">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="0" mem-size="120">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="2" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="6" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="12" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="64" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="94" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="96" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="98" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="102" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="104" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="108" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="112" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="120" mem-size="480">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="24" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="32" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="48" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="64" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="80" mem-size="256" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="336" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="384" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="392" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="408" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="416" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="432" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="448" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="600" mem-size="1200">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="60" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="80" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="120" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="160" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="200" mem-size="640" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="840" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="960" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="980" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1020" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1040" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1080" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1120" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="44"/>
+      <Instance label="testDevice2" address="1844"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Schneider_M340.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Schneider_M340.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..1ea96e043c8ea9ab9ea8f56c417ae3d4faa0842e
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Schneider_M340.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-14 16:04:09.437778"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Schneider_M340" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="M340" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="MW0..MW21 / 22 words">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="44">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="16" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="16" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="36" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" used-mem="MW22..MW1801 / 1780 words">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="44" mem-size="124">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="2" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="6" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="12" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="64" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="94" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="96" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="100" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="104" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="108" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="112" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="116" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="292" mem-size="472">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="12" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="20" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="28" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="44" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="60" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="76" mem-size="256" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="332" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="364" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="372" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="384" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="400" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="408" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="424" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="440" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="1236" mem-size="1184">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="20" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="30" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="50" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="72" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="112" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="152" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="192" mem-size="640" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="832" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="912" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="932" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="942" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="964" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1004" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1024" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1064" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1104" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="0"/>
+      <Instance label="testDevice2" address="1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Schneider_PremiumQuantum.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Schneider_PremiumQuantum.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..0e904f07e7c59035237e3f7c681c82fcfeacb287
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Schneider_PremiumQuantum.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-14 16:04:19.735644"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Schneider_PremiumQuantum" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="Premium" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="MW0..MW21 / 22 words">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="44">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="16" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="16" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="36" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" used-mem="MW22..MW1793 / 1772 words">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="44" mem-size="120">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="2" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="6" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="12" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="64" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="94" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="96" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="98" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="102" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="104" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="108" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="112" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="284" mem-size="472">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="12" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="20" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="28" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="44" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="60" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="76" mem-size="256" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="332" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="364" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="372" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="384" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="400" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="408" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="424" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="440" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="1228" mem-size="1180">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="20" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="30" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="50" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="70" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="110" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="150" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="190" mem-size="640" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="830" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="910" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="930" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="960" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1000" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1020" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1060" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1100" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="0"/>
+      <Instance label="testDevice2" address="1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Block.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Block.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..8182e9e37eb4180a7a04cc04f42152d391623375
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Block.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-14 16:03:31.706052"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Siemens_Step7Block" plc-brand="SIEMENS" plc-system="STEP-7" plc-model="SIMATIC_S7-300" protocol="DEVICE_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="DB0..DB0 / 48 bytes">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="48">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="18" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="18" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="22" mem-size="18" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="40" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" used-mem="DB1..DB2 / 3540 bytes">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="0" mem-size="118">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="1" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="2" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="6" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="10" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="14" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="18" mem-size="66" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="93" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="94" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="96" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="100" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="102" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="106" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="110" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="118" mem-size="472">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="4" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="24" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="40" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="56" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="72" mem-size="264" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="336" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="372" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="384" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="400" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="408" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="424" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="440" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="590" mem-size="1180">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="10" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="60" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="100" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="140" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="180" mem-size="660" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="840" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="930" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="960" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1000" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1020" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1060" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1100" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="1"/>
+      <Instance label="testDevice2" address="2"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Device.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Device.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..46bf195eae0ebb7cb9f3c0c47b46ecaf9233d8e7
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Device.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-14 16:03:18.892092"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Siemens_Step7Device" plc-brand="SIEMENS" plc-system="STEP-7" plc-model="SIMATIC_S7-300" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="DB0..DB0 / 48 bytes">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="48">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="18" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="18" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="22" mem-size="18" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="40" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" used-mem="DB1..DB3 / 3540 bytes">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="1" mem-size="118">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="1" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="2" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="6" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="10" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="14" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="18" mem-size="66" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="93" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="94" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="96" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="100" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="102" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="106" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="110" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="2" mem-size="472">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="4" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="24" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="40" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="56" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="72" mem-size="264" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="336" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="372" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="384" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="400" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="408" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="424" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="440" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="3" mem-size="1180">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="10" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="60" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="100" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="140" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="180" mem-size="660" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="840" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="930" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="960" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1000" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1020" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1060" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1100" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="0"/>
+      <Instance label="testDevice2" address="1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaBlock.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaBlock.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..7f4c98485504479f0f0f3a85d51a19b9261ae7c0
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaBlock.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-14 16:02:43.799998"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Siemens_TiaBlock" plc-brand="SIEMENS" plc-system="TIA-PORTAL" plc-model="SIMATIC_S7-300" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="DB0..DB0 / 48 bytes">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="48">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="18" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="18" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="22" mem-size="18" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="40" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" used-mem="DB1..DB3 / 3540 bytes">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="1" mem-size="118">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="1" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="2" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="6" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="10" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="14" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="18" mem-size="66" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="93" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="94" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="96" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="100" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="102" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="106" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="110" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="2" mem-size="472">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="4" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="24" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="40" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="56" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="72" mem-size="264" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="336" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="372" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="384" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="400" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="408" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="424" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="440" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="3" mem-size="1180">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="10" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="60" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="100" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="140" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="180" mem-size="660" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="840" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="930" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="960" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1000" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1020" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1060" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1100" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="0"/>
+      <Instance label="testDevice2" address="1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaDevice.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaDevice.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..766dea9a9109655e0cab5141ecd0f7fb9f9a45a1
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaDevice.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-14 15:59:09.165849"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Siemens_TiaDevice" plc-brand="SIEMENS" plc-system="TIA-PORTAL" plc-model="SIMATIC_S7-300" protocol="DEVICE_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="DB0..DB0 / 48 bytes">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="48">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="18" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="18" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="22" mem-size="18" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="40" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" used-mem="DB1..DB2 / 3540 bytes">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="0" mem-size="118">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="1" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="2" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="6" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="10" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="14" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="18" mem-size="66" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="93" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="94" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="96" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="100" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="102" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="106" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="110" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="118" mem-size="472">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="4" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="24" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="40" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="56" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="72" mem-size="264" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="336" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="372" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="384" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="400" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="408" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="424" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="440" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="590" mem-size="1180">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="10" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="60" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="100" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="140" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="180" mem-size="660" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="840" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="930" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="960" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1000" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1020" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1060" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1100" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="1"/>
+      <Instance label="testDevice2" address="2"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_BC9020.exp b/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_BC9020.exp
new file mode 100644
index 0000000000000000000000000000000000000000..db9ec3db27e3da588dda7281f46815659add0885
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_BC9020.exp
@@ -0,0 +1,328 @@
+(* +-------------------------------------------------------------------
+* | C.E.R.N Geneva, Switzerland
+* | SILECS - BE/CO-FE
+* | April 2015
+* +-------------------------------------------------------------------
+*
+* Release : SILECS_DEV
+*)
+VAR_GLOBAL
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _version_a781_SilecsHeader AT %MW0: STRING(16):= DEV;
+
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _checksum_a781_SilecsHeader AT %MW9: DWORD:= 2843029646;
+
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _user_a781_SilecsHeader AT %MW11: STRING(16):= 'schwinn';
+
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _date_a781_SilecsHeader AT %MW20: DT:= DT#2016-7-14-16:7:52;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int8_a583_testDevice1 AT %MW24: SINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_uint8_a583_testDevice1 AT %MW25: BYTE;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int16_a583_testDevice1 AT %MW26: INT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_uint16_a583_testDevice1 AT %MW27: WORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int32_a583_testDevice1 AT %MW28: DINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_uint32_a583_testDevice1 AT %MW30: DWORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_float32_a583_testDevice1 AT %MW32: REAL;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_string_a583_testDevice1 AT %MW34: STRING(64);
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_date_a583_testDevice1 AT %MW67: DT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_char_a583_testDevice1 AT %MW71: SINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_byte_a583_testDevice1 AT %MW72: BYTE;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_word_a583_testDevice1 AT %MW73: WORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_dword_a583_testDevice1 AT %MW74: DWORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int_a583_testDevice1 AT %MW76: INT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_dint_a583_testDevice1 AT %MW77: DINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_real_a583_testDevice1 AT %MW79: REAL;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_dt_a583_testDevice1 AT %MW81: DT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int8_a583_testDevice2 AT %MW85: SINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_uint8_a583_testDevice2 AT %MW86: BYTE;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int16_a583_testDevice2 AT %MW87: INT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_uint16_a583_testDevice2 AT %MW88: WORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int32_a583_testDevice2 AT %MW89: DINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_uint32_a583_testDevice2 AT %MW91: DWORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_float32_a583_testDevice2 AT %MW93: REAL;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_string_a583_testDevice2 AT %MW95: STRING(64);
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_date_a583_testDevice2 AT %MW128: DT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_char_a583_testDevice2 AT %MW132: SINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_byte_a583_testDevice2 AT %MW133: BYTE;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_word_a583_testDevice2 AT %MW134: WORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_dword_a583_testDevice2 AT %MW135: DWORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int_a583_testDevice2 AT %MW137: INT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_dint_a583_testDevice2 AT %MW138: DINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_real_a583_testDevice2 AT %MW140: REAL;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_dt_a583_testDevice2 AT %MW142: DT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int8_a583_testDevice1 AT %MW146: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_uint8_a583_testDevice1 AT %MW148: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int16_a583_testDevice1 AT %MW150: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_uint16_a583_testDevice1 AT %MW154: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int32_a583_testDevice1 AT %MW158: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_uint32_a583_testDevice1 AT %MW166: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_float32_a583_testDevice1 AT %MW174: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_string_a583_testDevice1 AT %MW182: ARRAY [0..1, 0..1] OF STRING(64);
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_date_a583_testDevice1 AT %MW312: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_char_a583_testDevice1 AT %MW328: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_byte_a583_testDevice1 AT %MW330: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_word_a583_testDevice1 AT %MW332: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_dword_a583_testDevice1 AT %MW336: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int_a583_testDevice1 AT %MW344: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_dint_a583_testDevice1 AT %MW348: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_real_a583_testDevice1 AT %MW356: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_dt_a583_testDevice1 AT %MW364: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int8_a583_testDevice2 AT %MW380: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_uint8_a583_testDevice2 AT %MW382: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int16_a583_testDevice2 AT %MW384: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_uint16_a583_testDevice2 AT %MW388: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int32_a583_testDevice2 AT %MW392: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_uint32_a583_testDevice2 AT %MW400: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_float32_a583_testDevice2 AT %MW408: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_string_a583_testDevice2 AT %MW416: ARRAY [0..1, 0..1] OF STRING(64);
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_date_a583_testDevice2 AT %MW546: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_char_a583_testDevice2 AT %MW562: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_byte_a583_testDevice2 AT %MW564: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_word_a583_testDevice2 AT %MW566: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_dword_a583_testDevice2 AT %MW570: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int_a583_testDevice2 AT %MW578: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_dint_a583_testDevice2 AT %MW582: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_real_a583_testDevice2 AT %MW590: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_dt_a583_testDevice2 AT %MW598: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int8_a583_testDevice1 AT %MW614: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_uint8_a583_testDevice1 AT %MW619: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int16_a583_testDevice1 AT %MW624: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_uint16_a583_testDevice1 AT %MW634: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int32_a583_testDevice1 AT %MW644: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_uint32_a583_testDevice1 AT %MW664: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_float32_a583_testDevice1 AT %MW684: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_string_a583_testDevice1 AT %MW704: ARRAY [0..9] OF STRING(64);
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_date_a583_testDevice1 AT %MW1029: ARRAY [0..9] OF DT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_char_a583_testDevice1 AT %MW1069: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_byte_a583_testDevice1 AT %MW1074: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_word_a583_testDevice1 AT %MW1079: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_dword_a583_testDevice1 AT %MW1089: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int_a583_testDevice1 AT %MW1109: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_dint_a583_testDevice1 AT %MW1119: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_real_a583_testDevice1 AT %MW1139: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_dt_a583_testDevice1 AT %MW1159: ARRAY [0..9] OF DT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int8_a583_testDevice2 AT %MW1199: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_uint8_a583_testDevice2 AT %MW1204: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int16_a583_testDevice2 AT %MW1209: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_uint16_a583_testDevice2 AT %MW1219: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int32_a583_testDevice2 AT %MW1229: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_uint32_a583_testDevice2 AT %MW1249: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_float32_a583_testDevice2 AT %MW1269: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_string_a583_testDevice2 AT %MW1289: ARRAY [0..9] OF STRING(64);
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_date_a583_testDevice2 AT %MW1614: ARRAY [0..9] OF DT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_char_a583_testDevice2 AT %MW1654: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_byte_a583_testDevice2 AT %MW1659: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_word_a583_testDevice2 AT %MW1664: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_dword_a583_testDevice2 AT %MW1674: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int_a583_testDevice2 AT %MW1694: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_dint_a583_testDevice2 AT %MW1704: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_real_a583_testDevice2 AT %MW1724: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_dt_a583_testDevice2 AT %MW1744: ARRAY [0..9] OF DT;
+
+END_VAR
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020.exp b/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020.exp
new file mode 100644
index 0000000000000000000000000000000000000000..c05bd13cac550027757c98b4f380c2e74742e07c
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020.exp
@@ -0,0 +1,328 @@
+(* +-------------------------------------------------------------------
+* | C.E.R.N Geneva, Switzerland
+* | SILECS - BE/CO-FE
+* | April 2015
+* +-------------------------------------------------------------------
+*
+* Release : SILECS_DEV
+*)
+VAR_GLOBAL
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _version_a781_SilecsHeader AT %MW0: STRING(16):= DEV;
+
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _checksum_a781_SilecsHeader AT %MW20: DWORD:= 427563505;
+
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _user_a781_SilecsHeader AT %MW24: STRING(16):= 'schwinn';
+
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _date_a781_SilecsHeader AT %MW44: DT:= DT#2016-7-14-16:8:13;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int8_a583_testDevice1 AT %MW52: SINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_uint8_a583_testDevice1 AT %MW54: BYTE;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int16_a583_testDevice1 AT %MW56: INT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_uint16_a583_testDevice1 AT %MW58: WORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int32_a583_testDevice1 AT %MW60: DINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_uint32_a583_testDevice1 AT %MW64: DWORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_float32_a583_testDevice1 AT %MW68: REAL;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_string_a583_testDevice1 AT %MW72: STRING(64);
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_date_a583_testDevice1 AT %MW140: DT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_char_a583_testDevice1 AT %MW148: SINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_byte_a583_testDevice1 AT %MW150: BYTE;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_word_a583_testDevice1 AT %MW152: WORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_dword_a583_testDevice1 AT %MW156: DWORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int_a583_testDevice1 AT %MW160: INT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_dint_a583_testDevice1 AT %MW164: DINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_real_a583_testDevice1 AT %MW168: REAL;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_dt_a583_testDevice1 AT %MW172: DT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int8_a583_testDevice2 AT %MW180: SINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_uint8_a583_testDevice2 AT %MW182: BYTE;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int16_a583_testDevice2 AT %MW184: INT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_uint16_a583_testDevice2 AT %MW186: WORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int32_a583_testDevice2 AT %MW188: DINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_uint32_a583_testDevice2 AT %MW192: DWORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_float32_a583_testDevice2 AT %MW196: REAL;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_string_a583_testDevice2 AT %MW200: STRING(64);
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_date_a583_testDevice2 AT %MW268: DT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_char_a583_testDevice2 AT %MW276: SINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_byte_a583_testDevice2 AT %MW278: BYTE;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_word_a583_testDevice2 AT %MW280: WORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_dword_a583_testDevice2 AT %MW284: DWORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int_a583_testDevice2 AT %MW288: INT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_dint_a583_testDevice2 AT %MW292: DINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_real_a583_testDevice2 AT %MW296: REAL;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_dt_a583_testDevice2 AT %MW300: DT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int8_a583_testDevice1 AT %MW308: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_uint8_a583_testDevice1 AT %MW312: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int16_a583_testDevice1 AT %MW316: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_uint16_a583_testDevice1 AT %MW324: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int32_a583_testDevice1 AT %MW332: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_uint32_a583_testDevice1 AT %MW348: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_float32_a583_testDevice1 AT %MW364: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_string_a583_testDevice1 AT %MW380: ARRAY [0..1, 0..1] OF STRING(64);
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_date_a583_testDevice1 AT %MW640: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_char_a583_testDevice1 AT %MW672: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_byte_a583_testDevice1 AT %MW676: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_word_a583_testDevice1 AT %MW680: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_dword_a583_testDevice1 AT %MW688: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int_a583_testDevice1 AT %MW704: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_dint_a583_testDevice1 AT %MW712: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_real_a583_testDevice1 AT %MW728: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_dt_a583_testDevice1 AT %MW744: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int8_a583_testDevice2 AT %MW776: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_uint8_a583_testDevice2 AT %MW780: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int16_a583_testDevice2 AT %MW784: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_uint16_a583_testDevice2 AT %MW792: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int32_a583_testDevice2 AT %MW800: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_uint32_a583_testDevice2 AT %MW816: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_float32_a583_testDevice2 AT %MW832: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_string_a583_testDevice2 AT %MW848: ARRAY [0..1, 0..1] OF STRING(64);
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_date_a583_testDevice2 AT %MW1108: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_char_a583_testDevice2 AT %MW1140: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_byte_a583_testDevice2 AT %MW1144: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_word_a583_testDevice2 AT %MW1148: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_dword_a583_testDevice2 AT %MW1156: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int_a583_testDevice2 AT %MW1172: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_dint_a583_testDevice2 AT %MW1180: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_real_a583_testDevice2 AT %MW1196: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_dt_a583_testDevice2 AT %MW1212: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int8_a583_testDevice1 AT %MW1244: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_uint8_a583_testDevice1 AT %MW1254: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int16_a583_testDevice1 AT %MW1264: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_uint16_a583_testDevice1 AT %MW1284: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int32_a583_testDevice1 AT %MW1304: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_uint32_a583_testDevice1 AT %MW1344: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_float32_a583_testDevice1 AT %MW1384: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_string_a583_testDevice1 AT %MW1424: ARRAY [0..9] OF STRING(64);
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_date_a583_testDevice1 AT %MW2076: ARRAY [0..9] OF DT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_char_a583_testDevice1 AT %MW2156: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_byte_a583_testDevice1 AT %MW2166: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_word_a583_testDevice1 AT %MW2176: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_dword_a583_testDevice1 AT %MW2196: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int_a583_testDevice1 AT %MW2236: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_dint_a583_testDevice1 AT %MW2256: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_real_a583_testDevice1 AT %MW2296: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_dt_a583_testDevice1 AT %MW2336: ARRAY [0..9] OF DT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int8_a583_testDevice2 AT %MW2416: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_uint8_a583_testDevice2 AT %MW2426: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int16_a583_testDevice2 AT %MW2436: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_uint16_a583_testDevice2 AT %MW2456: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int32_a583_testDevice2 AT %MW2476: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_uint32_a583_testDevice2 AT %MW2516: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_float32_a583_testDevice2 AT %MW2556: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_string_a583_testDevice2 AT %MW2596: ARRAY [0..9] OF STRING(64);
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_date_a583_testDevice2 AT %MW3248: ARRAY [0..9] OF DT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_char_a583_testDevice2 AT %MW3328: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_byte_a583_testDevice2 AT %MW3338: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_word_a583_testDevice2 AT %MW3348: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_dword_a583_testDevice2 AT %MW3368: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int_a583_testDevice2 AT %MW3408: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_dint_a583_testDevice2 AT %MW3428: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_real_a583_testDevice2 AT %MW3468: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_dt_a583_testDevice2 AT %MW3508: ARRAY [0..9] OF DT;
+
+END_VAR
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Rabbit_BlockMode.h b/silecs-codegen/src/xml/test/generated_correct/controller/Rabbit_BlockMode.h
new file mode 100644
index 0000000000000000000000000000000000000000..51ea9947fa4c6188656a5d80ce18f068f59b5f79
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Rabbit_BlockMode.h
@@ -0,0 +1,202 @@
+
+/* +-------------------------------------------------------------------
+ * | Copyright CERN 2015
+ * | SILECS - BE/CO-SRC
+ * | April 2015
+ * +-------------------------------------------------------------------
+ *
+ * Release : SILECS_DEV
+ *
+ * The following code has been automatically generated by SILECS.
+ *
+ * N.B: This file relies on the existence of explicit C data type such
+ * as int8_t, uint8_t, int16_t, etc....
+ * If your compiler does not support them natively please implement 
+ * them by including the data type definition provided on the SILECS
+ * web page before including this header file.
+ */
+
+#define MODBUS_START_ADDRESS 0
+
+/*---------------------------------------------------------------------
+ * DT 
+ * data type definition and related utilities
+ *---------------------------------------------------------------------
+ */
+
+typedef struct
+{
+	uint8_t sc_100;     // second cent
+	uint8_t sc;			// second
+	uint8_t mn;         // minute
+	uint8_t hh;         // hour
+	uint8_t dd;         // day
+	uint8_t mm;         // month
+	uint8_t yy1;        // year
+	uint8_t yy2;        // year2
+} dt;
+
+#define _frombcd(a) (int)(((a>>4)*10)+(a&0x0F))
+#define _tobcd(a)   (((unsigned char)((a)/10)<<4)+((a)%10))
+
+void SILECS_set_dt(int8_t sc_100 ,int8_t sc, int8_t mn,int8_t hh,int8_t dd,int8_t mm,int32_t yy, dt *date)
+{
+	date->sc_100 = sc_100;
+	date->sc     = _tobcd(sc);
+	date->mn     = _tobcd(mn);
+	date->hh     = _tobcd(hh);
+	date->dd     = _tobcd(dd);
+	date->mm     = _tobcd(mm);
+	date->yy2    = _tobcd((int8_t)(yy/100));
+	date->yy1    = _tobcd((int8_t)(yy%100));
+}
+
+
+/*---------------------------------------------------------------------
+ * SilecsHeader / v1.0.0
+ * BLOCK Type definition
+ *---------------------------------------------------------------------
+ */
+
+typedef struct 
+{
+    uint8_t _version[16];
+    uint32_t _checksum;
+    uint8_t _user[16];
+    dt _date;
+
+} _SilecsHeader_hdrBlk;
+
+/*---------------------------------------------------------------------
+ * AllTypes / v0.1.0
+ * BLOCK Type definition
+ *---------------------------------------------------------------------
+ */
+
+typedef struct 
+{
+    int16_t RO_int8;
+    uint16_t RO_uint8;
+    int16_t RO_int16;
+    uint16_t RO_uint16;
+    int32_t RO_int32;
+    uint32_t RO_uint32;
+    float RO_float32;
+    uint8_t RO_string[64];
+    dt RO_date;
+    int16_t RO_char;
+    uint16_t RO_byte;
+    uint16_t RO_word;
+    uint32_t RO_dword;
+    int16_t RO_int;
+    int32_t RO_dint;
+    float RO_real;
+    dt RO_dt;
+
+} _AllTypes_MyROBlock;
+
+typedef struct 
+{
+    int16_t RW_int8[2][2];
+    uint16_t RW_uint8[2][2];
+    int16_t RW_int16[2][2];
+    uint16_t RW_uint16[2][2];
+    int32_t RW_int32[2][2];
+    uint32_t RW_uint32[2][2];
+    float RW_float32[2][2];
+    uint8_t RW_string[2][2][64];
+    dt RW_date[2][2];
+    int16_t RW_char[2][2];
+    uint16_t RW_byte[2][2];
+    uint16_t RW_word[2][2];
+    uint32_t RW_dword[2][2];
+    int16_t RW_int[2][2];
+    int32_t RW_dint[2][2];
+    float RW_real[2][2];
+    dt RW_dt[2][2];
+
+} _AllTypes_MyRWBlock;
+
+typedef struct 
+{
+    int16_t WO_int8[10];
+    uint16_t WO_uint8[10];
+    int16_t WO_int16[10];
+    uint16_t WO_uint16[10];
+    int32_t WO_int32[10];
+    uint32_t WO_uint32[10];
+    float WO_float32[10];
+    uint8_t WO_string[10][64];
+    dt WO_date[10];
+    int16_t WO_char[10];
+    uint16_t WO_byte[10];
+    uint16_t WO_word[10];
+    uint32_t WO_dword[10];
+    int16_t WO_int[10];
+    int32_t WO_dint[10];
+    float WO_real[10];
+    dt WO_dt[10];
+
+} _AllTypes_MyWOBlock;
+
+/*---------------------------------------------------------------------
+ * MEMORY ALLOCATION
+ * PROTOCOL: BLOCK_MODE
+ *---------------------------------------------------------------------
+ */
+
+typedef struct {
+    
+    struct {
+        _SilecsHeader_hdrBlk SilecsHeader;
+    } SilecsHeader_hdrBlk;
+
+    struct {
+        _AllTypes_MyROBlock testDevice1;
+        _AllTypes_MyROBlock testDevice2;
+    } AllTypes_MyROBlock;
+
+    struct {
+        _AllTypes_MyRWBlock testDevice1;
+        _AllTypes_MyRWBlock testDevice2;
+    } AllTypes_MyRWBlock;
+
+    struct {
+        _AllTypes_MyWOBlock testDevice1;
+        _AllTypes_MyWOBlock testDevice2;
+    } AllTypes_MyWOBlock;
+
+} _SILECS_DATA_SEGMENT;
+
+#define SILECS_DATA_SEGMENT_MODBUS_SIZE (sizeof(_SILECS_DATA_SEGMENT)/2)
+
+union modbus_data {
+    _SILECS_DATA_SEGMENT data;
+    uint16_t array[SILECS_DATA_SEGMENT_MODBUS_SIZE];
+} silecsData;
+
+
+/* Initialization function */
+int SILECS_init()
+{
+	/* Silecs version initialization */
+	strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._version, "SILECS_DEV");
+	
+	/* Silecs checksum initialization */
+	silecsData.data.SilecsHeader_hdrBlk.device[0]._checksum  = 3940683809;
+	
+	/* Silecs user initialization */
+	strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._user, "schwinn");
+	
+	/* Silecs date initialization */
+	SILECS_set_dt(3,48,8,16,14,7,2016,&silecsData.data.SilecsHeader_hdrBlk.device[0]._date);
+}
+
+/*
+ * Automatically generated Addressing example
+ *
+ * This example shows how to address the register WO_dt of block MyWOBlock
+ * of device testDevice2 of the class AllTypes
+ *
+ *  silecsData.AllTypes_MyWOBlock.testDevice2.WO_dt = ....;
+ */
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Rabbit_DeviceMode.h b/silecs-codegen/src/xml/test/generated_correct/controller/Rabbit_DeviceMode.h
new file mode 100644
index 0000000000000000000000000000000000000000..d382f9dedbd147e7ceb37aaee84bafcdd6d2a32d
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Rabbit_DeviceMode.h
@@ -0,0 +1,195 @@
+
+/* +-------------------------------------------------------------------
+ * | Copyright CERN 2015
+ * | SILECS - BE/CO-SRC
+ * | April 2015
+ * +-------------------------------------------------------------------
+ *
+ * Release : SILECS_DEV
+ *
+ * The following code has been automatically generated by SILECS.
+ *
+ * N.B: This file relies on the existence of explicit C data type such
+ * as int8_t, uint8_t, int16_t, etc....
+ * If your compiler does not support them natively please implement 
+ * them by including the data type definition provided on the SILECS
+ * web page before including this header file.
+ */
+
+#define MODBUS_START_ADDRESS 0
+
+/*---------------------------------------------------------------------
+ * DT 
+ * data type definition and related utilities
+ *---------------------------------------------------------------------
+ */
+
+typedef struct
+{
+	uint8_t sc_100;     // second cent
+	uint8_t sc;			// second
+	uint8_t mn;         // minute
+	uint8_t hh;         // hour
+	uint8_t dd;         // day
+	uint8_t mm;         // month
+	uint8_t yy1;        // year
+	uint8_t yy2;        // year2
+} dt;
+
+#define _frombcd(a) (int)(((a>>4)*10)+(a&0x0F))
+#define _tobcd(a)   (((unsigned char)((a)/10)<<4)+((a)%10))
+
+void SILECS_set_dt(int8_t sc_100 ,int8_t sc, int8_t mn,int8_t hh,int8_t dd,int8_t mm,int32_t yy, dt *date)
+{
+	date->sc_100 = sc_100;
+	date->sc     = _tobcd(sc);
+	date->mn     = _tobcd(mn);
+	date->hh     = _tobcd(hh);
+	date->dd     = _tobcd(dd);
+	date->mm     = _tobcd(mm);
+	date->yy2    = _tobcd((int8_t)(yy/100));
+	date->yy1    = _tobcd((int8_t)(yy%100));
+}
+
+
+/*---------------------------------------------------------------------
+ * SilecsHeader / v1.0.0
+ * BLOCK Type definition
+ *---------------------------------------------------------------------
+ */
+
+typedef struct 
+{
+    uint8_t _version[16];
+    uint32_t _checksum;
+    uint8_t _user[16];
+    dt _date;
+
+} _SilecsHeader_hdrBlk;
+
+/*---------------------------------------------------------------------
+ * AllTypes / v0.1.0
+ * BLOCK Type definition
+ *---------------------------------------------------------------------
+ */
+
+typedef struct 
+{
+    int16_t RO_int8;
+    uint16_t RO_uint8;
+    int16_t RO_int16;
+    uint16_t RO_uint16;
+    int32_t RO_int32;
+    uint32_t RO_uint32;
+    float RO_float32;
+    uint8_t RO_string[64];
+    dt RO_date;
+    int16_t RO_char;
+    uint16_t RO_byte;
+    uint16_t RO_word;
+    uint32_t RO_dword;
+    int16_t RO_int;
+    int32_t RO_dint;
+    float RO_real;
+    dt RO_dt;
+
+} _AllTypes_MyROBlock;
+
+typedef struct 
+{
+    int16_t RW_int8[2][2];
+    uint16_t RW_uint8[2][2];
+    int16_t RW_int16[2][2];
+    uint16_t RW_uint16[2][2];
+    int32_t RW_int32[2][2];
+    uint32_t RW_uint32[2][2];
+    float RW_float32[2][2];
+    uint8_t RW_string[2][2][64];
+    dt RW_date[2][2];
+    int16_t RW_char[2][2];
+    uint16_t RW_byte[2][2];
+    uint16_t RW_word[2][2];
+    uint32_t RW_dword[2][2];
+    int16_t RW_int[2][2];
+    int32_t RW_dint[2][2];
+    float RW_real[2][2];
+    dt RW_dt[2][2];
+
+} _AllTypes_MyRWBlock;
+
+typedef struct 
+{
+    int16_t WO_int8[10];
+    uint16_t WO_uint8[10];
+    int16_t WO_int16[10];
+    uint16_t WO_uint16[10];
+    int32_t WO_int32[10];
+    uint32_t WO_uint32[10];
+    float WO_float32[10];
+    uint8_t WO_string[10][64];
+    dt WO_date[10];
+    int16_t WO_char[10];
+    uint16_t WO_byte[10];
+    uint16_t WO_word[10];
+    uint32_t WO_dword[10];
+    int16_t WO_int[10];
+    int32_t WO_dint[10];
+    float WO_real[10];
+    dt WO_dt[10];
+
+} _AllTypes_MyWOBlock;
+
+/*---------------------------------------------------------------------
+ * MEMORY ALLOCATION
+ * PROTOCOL: DEVICE_MODE
+ *---------------------------------------------------------------------
+ */
+
+typedef struct {
+    
+    struct {
+        _SilecsHeader_hdrBlk hdrBlk;
+
+    } SilecsHeader_SilecsHeader;
+
+    struct {
+        _AllTypes_MyROBlock MyROBlock;
+        _AllTypes_MyRWBlock MyRWBlock;
+        _AllTypes_MyWOBlock MyWOBlock;
+
+    } AllTypes_testDevice1, AllTypes_testDevice2;
+
+} _SILECS_DATA_SEGMENT;
+
+#define SILECS_DATA_SEGMENT_MODBUS_SIZE (sizeof(_SILECS_DATA_SEGMENT)/2)
+
+union silecsData {
+    _SILECS_DATA_SEGMENT data;
+    uint16_t array[SILECS_DATA_SEGMENT_MODBUS_SIZE];
+} silecsData;
+
+
+/* Initialization function */
+int SILECS_init()
+{
+	/* Silecs version initialization */
+	strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._version, "SILECS_DEV");
+	
+	/* Silecs checksum initialization */
+	silecsData.data.SilecsHeader_device[0].hdrBlk._checksum  = 3940683809;
+	
+	/* Silecs user initialization */
+	strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._user, "schwinn");
+	
+	/* Silecs date initialization */
+	SILECS_set_dt(3,0,9,16,14,7,2016,&silecsData.data.SilecsHeader_device[0].hdrBlk._date);
+}
+
+/*
+ * Automatically generated Addressing example
+ *
+ * This example shows how to address the register WO_dt of block MyWOBlock
+ * of device AllTypes_testDevice2 of the class AllTypes
+ * 
+ *  silecsData.AllTypes_AllTypes_testDevice2.MyWOBlock.WO_dt = ....;
+ */
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Schneider_M340.xsy b/silecs-codegen/src/xml/test/generated_correct/controller/Schneider_M340.xsy
new file mode 100644
index 0000000000000000000000000000000000000000..580607556a28904252eb1297249febefba9f35b4
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Schneider_M340.xsy
@@ -0,0 +1,326 @@
+<VariablesExchangeFile>
+  <dataBlock>
+    <variables name="_version_a781_SilecsHeader" typeName="STRING[16]" topologicalAddress="%MW0">
+      <variableInit value="DEV"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="_checksum_a781_SilecsHeader" typeName="DWORD" topologicalAddress="%MW8">
+      <variableInit value="3940683809"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="_user_a781_SilecsHeader" typeName="STRING[16]" topologicalAddress="%MW10">
+      <variableInit value="schwinn"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="_date_a781_SilecsHeader" typeName="DT" topologicalAddress="%MW18">
+      <variableInit value="DT#2016-7-14-16:8:24"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="RO_int8_a583_testDevice1" typeName="WORD" topologicalAddress="%MW22">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint8_a583_testDevice1" typeName="BYTE" topologicalAddress="%MW23">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int16_a583_testDevice1" typeName="INT" topologicalAddress="%MW24">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint16_a583_testDevice1" typeName="WORD" topologicalAddress="%MW25">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int32_a583_testDevice1" typeName="DINT" topologicalAddress="%MW26">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint32_a583_testDevice1" typeName="DWORD" topologicalAddress="%MW28">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_float32_a583_testDevice1" typeName="REAL" topologicalAddress="%MW30">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_string_a583_testDevice1" typeName="STRING[64]" topologicalAddress="%MW32">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_date_a583_testDevice1" typeName="DT" topologicalAddress="%MW64">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_char_a583_testDevice1" typeName="WORD" topologicalAddress="%MW68">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_byte_a583_testDevice1" typeName="BYTE" topologicalAddress="%MW69">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_word_a583_testDevice1" typeName="WORD" topologicalAddress="%MW70">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dword_a583_testDevice1" typeName="DWORD" topologicalAddress="%MW72">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int_a583_testDevice1" typeName="INT" topologicalAddress="%MW74">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dint_a583_testDevice1" typeName="DINT" topologicalAddress="%MW76">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_real_a583_testDevice1" typeName="REAL" topologicalAddress="%MW78">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dt_a583_testDevice1" typeName="DT" topologicalAddress="%MW80">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int8_a583_testDevice2" typeName="WORD" topologicalAddress="%MW84">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint8_a583_testDevice2" typeName="BYTE" topologicalAddress="%MW85">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int16_a583_testDevice2" typeName="INT" topologicalAddress="%MW86">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint16_a583_testDevice2" typeName="WORD" topologicalAddress="%MW87">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int32_a583_testDevice2" typeName="DINT" topologicalAddress="%MW88">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint32_a583_testDevice2" typeName="DWORD" topologicalAddress="%MW90">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_float32_a583_testDevice2" typeName="REAL" topologicalAddress="%MW92">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_string_a583_testDevice2" typeName="STRING[64]" topologicalAddress="%MW94">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_date_a583_testDevice2" typeName="DT" topologicalAddress="%MW126">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_char_a583_testDevice2" typeName="WORD" topologicalAddress="%MW130">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_byte_a583_testDevice2" typeName="BYTE" topologicalAddress="%MW131">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_word_a583_testDevice2" typeName="WORD" topologicalAddress="%MW132">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dword_a583_testDevice2" typeName="DWORD" topologicalAddress="%MW134">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int_a583_testDevice2" typeName="INT" topologicalAddress="%MW136">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dint_a583_testDevice2" typeName="DINT" topologicalAddress="%MW138">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_real_a583_testDevice2" typeName="REAL" topologicalAddress="%MW140">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dt_a583_testDevice2" typeName="DT" topologicalAddress="%MW142">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RW_int8_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW146">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint8_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW150">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int16_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW152">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint16_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW156">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int32_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW160">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint32_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW168">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_float32_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW176">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_string_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF STRING[64]" topologicalAddress="%MW184">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_date_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW312">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_char_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW328">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_byte_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW332">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_word_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW334">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dword_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW338">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW346">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dint_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW350">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_real_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW358">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dt_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW366">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int8_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW382">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint8_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW386">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int16_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW388">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint16_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW392">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int32_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW396">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint32_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW404">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_float32_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW412">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_string_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF STRING[64]" topologicalAddress="%MW420">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_date_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW548">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_char_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW564">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_byte_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW568">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_word_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW570">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dword_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW574">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW582">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dint_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW586">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_real_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW594">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dt_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW602">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="WO_int8_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW618">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint8_a583_testDevice1" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW628">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int16_a583_testDevice1" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW633">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint16_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW643">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int32_a583_testDevice1" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW654">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint32_a583_testDevice1" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW674">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_float32_a583_testDevice1" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW694">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_string_a583_testDevice1" typeName="ARRAY[0..9] OF STRING[64]" topologicalAddress="%MW714">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_date_a583_testDevice1" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1034">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_char_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1074">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_byte_a583_testDevice1" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW1084">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_word_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1089">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dword_a583_testDevice1" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW1100">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int_a583_testDevice1" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW1120">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dint_a583_testDevice1" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW1130">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_real_a583_testDevice1" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW1150">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dt_a583_testDevice1" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1170">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int8_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1210">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint8_a583_testDevice2" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW1220">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int16_a583_testDevice2" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW1225">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint16_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1235">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int32_a583_testDevice2" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW1246">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint32_a583_testDevice2" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW1266">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_float32_a583_testDevice2" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW1286">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_string_a583_testDevice2" typeName="ARRAY[0..9] OF STRING[64]" topologicalAddress="%MW1306">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_date_a583_testDevice2" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1626">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_char_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1666">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_byte_a583_testDevice2" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW1676">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_word_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1681">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dword_a583_testDevice2" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW1692">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int_a583_testDevice2" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW1712">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dint_a583_testDevice2" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW1722">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_real_a583_testDevice2" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW1742">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dt_a583_testDevice2" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1762">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+  </dataBlock>
+</VariablesExchangeFile>
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Schneider_PremiumQuantum.xsy b/silecs-codegen/src/xml/test/generated_correct/controller/Schneider_PremiumQuantum.xsy
new file mode 100644
index 0000000000000000000000000000000000000000..90041edc6d060edc6fb80aa7dcae9cc36fe24ce4
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Schneider_PremiumQuantum.xsy
@@ -0,0 +1,326 @@
+<VariablesExchangeFile>
+  <dataBlock>
+    <variables name="_version_a781_SilecsHeader" typeName="STRING[16]" topologicalAddress="%MW0">
+      <variableInit value="DEV"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="_checksum_a781_SilecsHeader" typeName="DWORD" topologicalAddress="%MW8">
+      <variableInit value="3940683809"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="_user_a781_SilecsHeader" typeName="STRING[16]" topologicalAddress="%MW10">
+      <variableInit value="schwinn"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="_date_a781_SilecsHeader" typeName="DT" topologicalAddress="%MW18">
+      <variableInit value="DT#2016-7-14-16:8:40"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="RO_int8_a583_testDevice1" typeName="WORD" topologicalAddress="%MW22">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint8_a583_testDevice1" typeName="BYTE" topologicalAddress="%MW23">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int16_a583_testDevice1" typeName="INT" topologicalAddress="%MW24">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint16_a583_testDevice1" typeName="WORD" topologicalAddress="%MW25">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int32_a583_testDevice1" typeName="DINT" topologicalAddress="%MW26">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint32_a583_testDevice1" typeName="DWORD" topologicalAddress="%MW28">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_float32_a583_testDevice1" typeName="REAL" topologicalAddress="%MW30">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_string_a583_testDevice1" typeName="STRING[64]" topologicalAddress="%MW32">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_date_a583_testDevice1" typeName="DT" topologicalAddress="%MW64">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_char_a583_testDevice1" typeName="WORD" topologicalAddress="%MW68">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_byte_a583_testDevice1" typeName="BYTE" topologicalAddress="%MW69">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_word_a583_testDevice1" typeName="WORD" topologicalAddress="%MW70">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dword_a583_testDevice1" typeName="DWORD" topologicalAddress="%MW71">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int_a583_testDevice1" typeName="INT" topologicalAddress="%MW73">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dint_a583_testDevice1" typeName="DINT" topologicalAddress="%MW74">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_real_a583_testDevice1" typeName="REAL" topologicalAddress="%MW76">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dt_a583_testDevice1" typeName="DT" topologicalAddress="%MW78">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int8_a583_testDevice2" typeName="WORD" topologicalAddress="%MW82">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint8_a583_testDevice2" typeName="BYTE" topologicalAddress="%MW83">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int16_a583_testDevice2" typeName="INT" topologicalAddress="%MW84">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint16_a583_testDevice2" typeName="WORD" topologicalAddress="%MW85">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int32_a583_testDevice2" typeName="DINT" topologicalAddress="%MW86">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint32_a583_testDevice2" typeName="DWORD" topologicalAddress="%MW88">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_float32_a583_testDevice2" typeName="REAL" topologicalAddress="%MW90">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_string_a583_testDevice2" typeName="STRING[64]" topologicalAddress="%MW92">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_date_a583_testDevice2" typeName="DT" topologicalAddress="%MW124">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_char_a583_testDevice2" typeName="WORD" topologicalAddress="%MW128">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_byte_a583_testDevice2" typeName="BYTE" topologicalAddress="%MW129">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_word_a583_testDevice2" typeName="WORD" topologicalAddress="%MW130">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dword_a583_testDevice2" typeName="DWORD" topologicalAddress="%MW131">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int_a583_testDevice2" typeName="INT" topologicalAddress="%MW133">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dint_a583_testDevice2" typeName="DINT" topologicalAddress="%MW134">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_real_a583_testDevice2" typeName="REAL" topologicalAddress="%MW136">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dt_a583_testDevice2" typeName="DT" topologicalAddress="%MW138">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RW_int8_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW142">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint8_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW146">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int16_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW148">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint16_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW152">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int32_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW156">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint32_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW164">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_float32_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW172">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_string_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF STRING[64]" topologicalAddress="%MW180">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_date_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW308">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_char_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW324">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_byte_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW328">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_word_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW330">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dword_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW334">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW342">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dint_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW346">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_real_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW354">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dt_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW362">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int8_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW378">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint8_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW382">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int16_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW384">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint16_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW388">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int32_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW392">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint32_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW400">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_float32_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW408">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_string_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF STRING[64]" topologicalAddress="%MW416">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_date_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW544">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_char_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW560">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_byte_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW564">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_word_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW566">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dword_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW570">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW578">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dint_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW582">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_real_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW590">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dt_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW598">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="WO_int8_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW614">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint8_a583_testDevice1" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW624">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int16_a583_testDevice1" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW629">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint16_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW639">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int32_a583_testDevice1" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW649">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint32_a583_testDevice1" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW669">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_float32_a583_testDevice1" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW689">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_string_a583_testDevice1" typeName="ARRAY[0..9] OF STRING[64]" topologicalAddress="%MW709">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_date_a583_testDevice1" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1029">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_char_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1069">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_byte_a583_testDevice1" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW1079">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_word_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1084">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dword_a583_testDevice1" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW1094">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int_a583_testDevice1" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW1114">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dint_a583_testDevice1" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW1124">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_real_a583_testDevice1" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW1144">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dt_a583_testDevice1" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1164">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int8_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1204">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint8_a583_testDevice2" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW1214">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int16_a583_testDevice2" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW1219">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint16_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1229">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int32_a583_testDevice2" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW1239">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint32_a583_testDevice2" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW1259">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_float32_a583_testDevice2" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW1279">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_string_a583_testDevice2" typeName="ARRAY[0..9] OF STRING[64]" topologicalAddress="%MW1299">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_date_a583_testDevice2" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1619">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_char_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1659">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_byte_a583_testDevice2" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW1669">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_word_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1674">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dword_a583_testDevice2" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW1684">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int_a583_testDevice2" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW1704">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dint_a583_testDevice2" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW1714">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_real_a583_testDevice2" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW1734">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dt_a583_testDevice2" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1754">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+  </dataBlock>
+</VariablesExchangeFile>
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_Step7Block.scl b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_Step7Block.scl
new file mode 100644
index 0000000000000000000000000000000000000000..c5cd604ba78e2a8c7f6a3015495d13ab24ffce06
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_Step7Block.scl
@@ -0,0 +1,150 @@
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _SilecsHeader_hdrBlk
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        _version: STRING[16] := 'SILECS_DEV';
+        _checksum: DWORD := DW#16#eae21021;
+        _user: STRING[16] := 'schwinn';
+        _date: DT := DT#2016-7-14-16:7:40;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// Block instance definition
+//---------------------------------------------------------------------
+// SilecsHeader_SilecsHeader ...........................................
+DATA_BLOCK DB0
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      DEV_MODE
+STRUCT
+    hdrBlk: _SilecsHeader_hdrBlk;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _AllTypes_MyROBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RO_int8: CHAR;
+        RO_uint8: BYTE;
+        RO_int16: INT;
+        RO_uint16: WORD;
+        RO_int32: DINT;
+        RO_uint32: DWORD;
+        RO_float32: REAL;
+        RO_string: STRING[64];
+        RO_date: DT;
+        RO_char: CHAR;
+        RO_byte: BYTE;
+        RO_word: WORD;
+        RO_dword: DWORD;
+        RO_int: INT;
+        RO_dint: DINT;
+        RO_real: REAL;
+        RO_dt: DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyRWBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RW_int8: ARRAY[0..1, 0..1] OF CHAR;
+        RW_uint8: ARRAY[0..1, 0..1] OF BYTE;
+        RW_int16: ARRAY[0..1, 0..1] OF INT;
+        RW_uint16: ARRAY[0..1, 0..1] OF WORD;
+        RW_int32: ARRAY[0..1, 0..1] OF DINT;
+        RW_uint32: ARRAY[0..1, 0..1] OF DWORD;
+        RW_float32: ARRAY[0..1, 0..1] OF REAL;
+        RW_string: ARRAY[0..1, 0..1] OF STRING[64];
+        RW_date: ARRAY[0..1, 0..1] OF DT;
+        RW_char: ARRAY[0..1, 0..1] OF CHAR;
+        RW_byte: ARRAY[0..1, 0..1] OF BYTE;
+        RW_word: ARRAY[0..1, 0..1] OF WORD;
+        RW_dword: ARRAY[0..1, 0..1] OF DWORD;
+        RW_int: ARRAY[0..1, 0..1] OF INT;
+        RW_dint: ARRAY[0..1, 0..1] OF DINT;
+        RW_real: ARRAY[0..1, 0..1] OF REAL;
+        RW_dt: ARRAY[0..1, 0..1] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyWOBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        WO_int8: ARRAY[0..9] OF CHAR;
+        WO_uint8: ARRAY[0..9] OF BYTE;
+        WO_int16: ARRAY[0..9] OF INT;
+        WO_uint16: ARRAY[0..9] OF WORD;
+        WO_int32: ARRAY[0..9] OF DINT;
+        WO_uint32: ARRAY[0..9] OF DWORD;
+        WO_float32: ARRAY[0..9] OF REAL;
+        WO_string: ARRAY[0..9] OF STRING[64];
+        WO_date: ARRAY[0..9] OF DT;
+        WO_char: ARRAY[0..9] OF CHAR;
+        WO_byte: ARRAY[0..9] OF BYTE;
+        WO_word: ARRAY[0..9] OF WORD;
+        WO_dword: ARRAY[0..9] OF DWORD;
+        WO_int: ARRAY[0..9] OF INT;
+        WO_dint: ARRAY[0..9] OF DINT;
+        WO_real: ARRAY[0..9] OF REAL;
+        WO_dt: ARRAY[0..9] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// Block instance definition
+//---------------------------------------------------------------------
+// AllTypes_testDevice1 ...........................................
+DATA_BLOCK DB1
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      DEV_MODE
+STRUCT
+    MyROBlock: _AllTypes_MyROBlock;
+    MyRWBlock: _AllTypes_MyRWBlock;
+    MyWOBlock: _AllTypes_MyWOBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+// AllTypes_testDevice2 ...........................................
+DATA_BLOCK DB2
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      DEV_MODE
+STRUCT
+    MyROBlock: _AllTypes_MyROBlock;
+    MyRWBlock: _AllTypes_MyRWBlock;
+    MyWOBlock: _AllTypes_MyWOBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_Step7Block.sdf b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_Step7Block.sdf
new file mode 100644
index 0000000000000000000000000000000000000000..e5d2ddb66c2635a199c7f174cfbfd46beccb8ef8
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_Step7Block.sdf
@@ -0,0 +1,7 @@
+"_SilecsHeader_hdrBlk","UDT 0","UDT 0","[SilecsHeader/1.0.0] UDT symbol: _<class-name>_<block-name>"
+"SilecsHeader_SilecsHeader","DB 0","DB 0","[SilecsHeader/1.0.0] DB symbol: <class-name>_<device-label | device-id>"
+"_AllTypes_MyROBlock","UDT 1","UDT 1","[AllTypes/0.1.0] UDT symbol: _<class-name>_<block-name>"
+"_AllTypes_MyRWBlock","UDT 2","UDT 2",""
+"_AllTypes_MyWOBlock","UDT 3","UDT 3",""
+"AllTypes_testDevice1","DB 1","DB 1","[AllTypes/0.1.0] DB symbol: <class-name>_<device-label | device-id>"
+"AllTypes_testDevice2","DB 2","DB 2",""
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_Step7Device.scl b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_Step7Device.scl
new file mode 100644
index 0000000000000000000000000000000000000000..32b0476df75d8226bf16e2e4e9abc078fe75d716
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_Step7Device.scl
@@ -0,0 +1,162 @@
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _SilecsHeader_hdrBlk
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        _version: STRING[16] := 'SILECS_DEV';
+        _checksum: DWORD := DW#16#eae21021;
+        _user: STRING[16] := 'schwinn';
+        _date: DT := DT#2016-7-14-16:7:24;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// Block instance definition
+//---------------------------------------------------------------------
+// SilecsHeader_hdrBlk ...........................................
+DATA_BLOCK DB0
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    SilecsHeader: _SilecsHeader_hdrBlk;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _AllTypes_MyROBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RO_int8: CHAR;
+        RO_uint8: BYTE;
+        RO_int16: INT;
+        RO_uint16: WORD;
+        RO_int32: DINT;
+        RO_uint32: DWORD;
+        RO_float32: REAL;
+        RO_string: STRING[64];
+        RO_date: DT;
+        RO_char: CHAR;
+        RO_byte: BYTE;
+        RO_word: WORD;
+        RO_dword: DWORD;
+        RO_int: INT;
+        RO_dint: DINT;
+        RO_real: REAL;
+        RO_dt: DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyRWBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RW_int8: ARRAY[0..1, 0..1] OF CHAR;
+        RW_uint8: ARRAY[0..1, 0..1] OF BYTE;
+        RW_int16: ARRAY[0..1, 0..1] OF INT;
+        RW_uint16: ARRAY[0..1, 0..1] OF WORD;
+        RW_int32: ARRAY[0..1, 0..1] OF DINT;
+        RW_uint32: ARRAY[0..1, 0..1] OF DWORD;
+        RW_float32: ARRAY[0..1, 0..1] OF REAL;
+        RW_string: ARRAY[0..1, 0..1] OF STRING[64];
+        RW_date: ARRAY[0..1, 0..1] OF DT;
+        RW_char: ARRAY[0..1, 0..1] OF CHAR;
+        RW_byte: ARRAY[0..1, 0..1] OF BYTE;
+        RW_word: ARRAY[0..1, 0..1] OF WORD;
+        RW_dword: ARRAY[0..1, 0..1] OF DWORD;
+        RW_int: ARRAY[0..1, 0..1] OF INT;
+        RW_dint: ARRAY[0..1, 0..1] OF DINT;
+        RW_real: ARRAY[0..1, 0..1] OF REAL;
+        RW_dt: ARRAY[0..1, 0..1] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyWOBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        WO_int8: ARRAY[0..9] OF CHAR;
+        WO_uint8: ARRAY[0..9] OF BYTE;
+        WO_int16: ARRAY[0..9] OF INT;
+        WO_uint16: ARRAY[0..9] OF WORD;
+        WO_int32: ARRAY[0..9] OF DINT;
+        WO_uint32: ARRAY[0..9] OF DWORD;
+        WO_float32: ARRAY[0..9] OF REAL;
+        WO_string: ARRAY[0..9] OF STRING[64];
+        WO_date: ARRAY[0..9] OF DT;
+        WO_char: ARRAY[0..9] OF CHAR;
+        WO_byte: ARRAY[0..9] OF BYTE;
+        WO_word: ARRAY[0..9] OF WORD;
+        WO_dword: ARRAY[0..9] OF DWORD;
+        WO_int: ARRAY[0..9] OF INT;
+        WO_dint: ARRAY[0..9] OF DINT;
+        WO_real: ARRAY[0..9] OF REAL;
+        WO_dt: ARRAY[0..9] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// Block instance definition
+//---------------------------------------------------------------------
+// AllTypes_MyROBlock ...........................................
+DATA_BLOCK DB1
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    testDevice1: _AllTypes_MyROBlock;
+    testDevice2: _AllTypes_MyROBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+// AllTypes_MyRWBlock ...........................................
+DATA_BLOCK DB2
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    testDevice1: _AllTypes_MyRWBlock;
+    testDevice2: _AllTypes_MyRWBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+// AllTypes_MyWOBlock ...........................................
+DATA_BLOCK DB3
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    testDevice1: _AllTypes_MyWOBlock;
+    testDevice2: _AllTypes_MyWOBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_Step7Device.sdf b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_Step7Device.sdf
new file mode 100644
index 0000000000000000000000000000000000000000..29a5f5851a5e2e6dea4c19a034b129e1333190e5
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_Step7Device.sdf
@@ -0,0 +1,8 @@
+"_SilecsHeader_hdrBlk","UDT 0","UDT 0","[SilecsHeader/1.0.0] UDT symbol: _<class-name>_<block-name>"
+"SilecsHeader_hdrBlk","DB 0","DB 0","[SilecsHeader/1.0.0] DB symbol: <class-name>_<block-name>"
+"_AllTypes_MyROBlock","UDT 1","UDT 1","[AllTypes/0.1.0] UDT symbol: _<class-name>_<block-name>"
+"_AllTypes_MyRWBlock","UDT 2","UDT 2",""
+"_AllTypes_MyWOBlock","UDT 3","UDT 3",""
+"AllTypes_MyROBlock","DB 1","DB 1","[AllTypes/0.1.0] DB symbol: <class-name>_<block-name>"
+"AllTypes_MyRWBlock","DB 2","DB 2",""
+"AllTypes_MyWOBlock","DB 3","DB 3",""
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_TiaBlock.scl b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_TiaBlock.scl
new file mode 100644
index 0000000000000000000000000000000000000000..a12f7bd70ce4d6e013e361af12f490d175aade87
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_TiaBlock.scl
@@ -0,0 +1,158 @@
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _SilecsHeader_hdrBlk
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        _version: STRING[16] := 'SILECS_DEV';
+        _checksum: DWORD := DW#16#eae21021;
+        _user: STRING[16] := 'schwinn';
+        _date: DT := DT#2016-7-14-16:7:12;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// Block instance definition
+//---------------------------------------------------------------------
+DATA_BLOCK SilecsHeader_hdrBlk
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    SilecsHeader: _SilecsHeader_hdrBlk;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _AllTypes_MyROBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RO_int8: CHAR;
+        RO_uint8: BYTE;
+        RO_int16: INT;
+        RO_uint16: WORD;
+        RO_int32: DINT;
+        RO_uint32: DWORD;
+        RO_float32: REAL;
+        RO_string: STRING[64];
+        RO_date: DT;
+        RO_char: CHAR;
+        RO_byte: BYTE;
+        RO_word: WORD;
+        RO_dword: DWORD;
+        RO_int: INT;
+        RO_dint: DINT;
+        RO_real: REAL;
+        RO_dt: DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyRWBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RW_int8: ARRAY[0..1, 0..1] OF CHAR;
+        RW_uint8: ARRAY[0..1, 0..1] OF BYTE;
+        RW_int16: ARRAY[0..1, 0..1] OF INT;
+        RW_uint16: ARRAY[0..1, 0..1] OF WORD;
+        RW_int32: ARRAY[0..1, 0..1] OF DINT;
+        RW_uint32: ARRAY[0..1, 0..1] OF DWORD;
+        RW_float32: ARRAY[0..1, 0..1] OF REAL;
+        RW_string: ARRAY[0..1, 0..1] OF STRING[64];
+        RW_date: ARRAY[0..1, 0..1] OF DT;
+        RW_char: ARRAY[0..1, 0..1] OF CHAR;
+        RW_byte: ARRAY[0..1, 0..1] OF BYTE;
+        RW_word: ARRAY[0..1, 0..1] OF WORD;
+        RW_dword: ARRAY[0..1, 0..1] OF DWORD;
+        RW_int: ARRAY[0..1, 0..1] OF INT;
+        RW_dint: ARRAY[0..1, 0..1] OF DINT;
+        RW_real: ARRAY[0..1, 0..1] OF REAL;
+        RW_dt: ARRAY[0..1, 0..1] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyWOBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        WO_int8: ARRAY[0..9] OF CHAR;
+        WO_uint8: ARRAY[0..9] OF BYTE;
+        WO_int16: ARRAY[0..9] OF INT;
+        WO_uint16: ARRAY[0..9] OF WORD;
+        WO_int32: ARRAY[0..9] OF DINT;
+        WO_uint32: ARRAY[0..9] OF DWORD;
+        WO_float32: ARRAY[0..9] OF REAL;
+        WO_string: ARRAY[0..9] OF STRING[64];
+        WO_date: ARRAY[0..9] OF DT;
+        WO_char: ARRAY[0..9] OF CHAR;
+        WO_byte: ARRAY[0..9] OF BYTE;
+        WO_word: ARRAY[0..9] OF WORD;
+        WO_dword: ARRAY[0..9] OF DWORD;
+        WO_int: ARRAY[0..9] OF INT;
+        WO_dint: ARRAY[0..9] OF DINT;
+        WO_real: ARRAY[0..9] OF REAL;
+        WO_dt: ARRAY[0..9] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// Block instance definition
+//---------------------------------------------------------------------
+DATA_BLOCK AllTypes_MyROBlock
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    testDevice1: _AllTypes_MyROBlock;
+    testDevice2: _AllTypes_MyROBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+DATA_BLOCK AllTypes_MyRWBlock
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    testDevice1: _AllTypes_MyRWBlock;
+    testDevice2: _AllTypes_MyRWBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+DATA_BLOCK AllTypes_MyWOBlock
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    testDevice1: _AllTypes_MyWOBlock;
+    testDevice2: _AllTypes_MyWOBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_TiaBlock.sdf b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_TiaBlock.sdf
new file mode 100644
index 0000000000000000000000000000000000000000..29a5f5851a5e2e6dea4c19a034b129e1333190e5
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_TiaBlock.sdf
@@ -0,0 +1,8 @@
+"_SilecsHeader_hdrBlk","UDT 0","UDT 0","[SilecsHeader/1.0.0] UDT symbol: _<class-name>_<block-name>"
+"SilecsHeader_hdrBlk","DB 0","DB 0","[SilecsHeader/1.0.0] DB symbol: <class-name>_<block-name>"
+"_AllTypes_MyROBlock","UDT 1","UDT 1","[AllTypes/0.1.0] UDT symbol: _<class-name>_<block-name>"
+"_AllTypes_MyRWBlock","UDT 2","UDT 2",""
+"_AllTypes_MyWOBlock","UDT 3","UDT 3",""
+"AllTypes_MyROBlock","DB 1","DB 1","[AllTypes/0.1.0] DB symbol: <class-name>_<block-name>"
+"AllTypes_MyRWBlock","DB 2","DB 2",""
+"AllTypes_MyWOBlock","DB 3","DB 3",""
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_TiaDevice.scl b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_TiaDevice.scl
new file mode 100644
index 0000000000000000000000000000000000000000..3f0ee9dc2884c6ddd4bb049ee7011a08f7a09c75
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_TiaDevice.scl
@@ -0,0 +1,147 @@
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _SilecsHeader_hdrBlk
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        _version: STRING[16] := 'SILECS_DEV';
+        _checksum: DWORD := DW#16#eae21021;
+        _user: STRING[16] := 'schwinn';
+        _date: DT := DT#2016-7-14-16:6:23;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// Block instance definition
+//---------------------------------------------------------------------
+DATA_BLOCK SilecsHeader_SilecsHeader
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      DEV_MODE
+STRUCT
+    hdrBlk: _SilecsHeader_hdrBlk;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _AllTypes_MyROBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RO_int8: CHAR;
+        RO_uint8: BYTE;
+        RO_int16: INT;
+        RO_uint16: WORD;
+        RO_int32: DINT;
+        RO_uint32: DWORD;
+        RO_float32: REAL;
+        RO_string: STRING[64];
+        RO_date: DT;
+        RO_char: CHAR;
+        RO_byte: BYTE;
+        RO_word: WORD;
+        RO_dword: DWORD;
+        RO_int: INT;
+        RO_dint: DINT;
+        RO_real: REAL;
+        RO_dt: DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyRWBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RW_int8: ARRAY[0..1, 0..1] OF CHAR;
+        RW_uint8: ARRAY[0..1, 0..1] OF BYTE;
+        RW_int16: ARRAY[0..1, 0..1] OF INT;
+        RW_uint16: ARRAY[0..1, 0..1] OF WORD;
+        RW_int32: ARRAY[0..1, 0..1] OF DINT;
+        RW_uint32: ARRAY[0..1, 0..1] OF DWORD;
+        RW_float32: ARRAY[0..1, 0..1] OF REAL;
+        RW_string: ARRAY[0..1, 0..1] OF STRING[64];
+        RW_date: ARRAY[0..1, 0..1] OF DT;
+        RW_char: ARRAY[0..1, 0..1] OF CHAR;
+        RW_byte: ARRAY[0..1, 0..1] OF BYTE;
+        RW_word: ARRAY[0..1, 0..1] OF WORD;
+        RW_dword: ARRAY[0..1, 0..1] OF DWORD;
+        RW_int: ARRAY[0..1, 0..1] OF INT;
+        RW_dint: ARRAY[0..1, 0..1] OF DINT;
+        RW_real: ARRAY[0..1, 0..1] OF REAL;
+        RW_dt: ARRAY[0..1, 0..1] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyWOBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        WO_int8: ARRAY[0..9] OF CHAR;
+        WO_uint8: ARRAY[0..9] OF BYTE;
+        WO_int16: ARRAY[0..9] OF INT;
+        WO_uint16: ARRAY[0..9] OF WORD;
+        WO_int32: ARRAY[0..9] OF DINT;
+        WO_uint32: ARRAY[0..9] OF DWORD;
+        WO_float32: ARRAY[0..9] OF REAL;
+        WO_string: ARRAY[0..9] OF STRING[64];
+        WO_date: ARRAY[0..9] OF DT;
+        WO_char: ARRAY[0..9] OF CHAR;
+        WO_byte: ARRAY[0..9] OF BYTE;
+        WO_word: ARRAY[0..9] OF WORD;
+        WO_dword: ARRAY[0..9] OF DWORD;
+        WO_int: ARRAY[0..9] OF INT;
+        WO_dint: ARRAY[0..9] OF DINT;
+        WO_real: ARRAY[0..9] OF REAL;
+        WO_dt: ARRAY[0..9] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// Block instance definition
+//---------------------------------------------------------------------
+DATA_BLOCK AllTypes_testDevice1
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      DEV_MODE
+STRUCT
+    MyROBlock: _AllTypes_MyROBlock;
+    MyRWBlock: _AllTypes_MyRWBlock;
+    MyWOBlock: _AllTypes_MyWOBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+DATA_BLOCK AllTypes_testDevice2
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      DEV_MODE
+STRUCT
+    MyROBlock: _AllTypes_MyROBlock;
+    MyRWBlock: _AllTypes_MyRWBlock;
+    MyWOBlock: _AllTypes_MyWOBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_TiaDevice.sdf b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_TiaDevice.sdf
new file mode 100644
index 0000000000000000000000000000000000000000..e5d2ddb66c2635a199c7f174cfbfd46beccb8ef8
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Siemens_TiaDevice.sdf
@@ -0,0 +1,7 @@
+"_SilecsHeader_hdrBlk","UDT 0","UDT 0","[SilecsHeader/1.0.0] UDT symbol: _<class-name>_<block-name>"
+"SilecsHeader_SilecsHeader","DB 0","DB 0","[SilecsHeader/1.0.0] DB symbol: <class-name>_<device-label | device-id>"
+"_AllTypes_MyROBlock","UDT 1","UDT 1","[AllTypes/0.1.0] UDT symbol: _<class-name>_<block-name>"
+"_AllTypes_MyRWBlock","UDT 2","UDT 2",""
+"_AllTypes_MyWOBlock","UDT 3","UDT 3",""
+"AllTypes_testDevice1","DB 1","DB 1","[AllTypes/0.1.0] DB symbol: <class-name>_<device-label | device-id>"
+"AllTypes_testDevice2","DB 2","DB 2",""
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/AllTypes.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/AllTypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..5900b5b05a12e769dd10eaab1b40f0757b103ce5
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/AllTypes.h
@@ -0,0 +1,38 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPES_H_
+#define ALLTYPES_H_
+
+#include <silecs-communication/wrapper/Block.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+#include <silecs-communication/wrapper/Device.h>
+
+namespace AllTypes
+{
+
+
+class Design : public SilecsWrapper::Design
+{
+public:
+
+    Design(SilecsWrapper::DeployUnit *deployUnit) :
+                    SilecsWrapper::Design("AllTypes", "0.1.0", deployUnit)
+    {
+    }
+
+    ~Design()
+    {
+    }
+};
+
+} /* namespace AllTypes */
+
+#endif /* ALLTYPES_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Beckhoff_BC9020.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Beckhoff_BC9020.h
new file mode 100644
index 0000000000000000000000000000000000000000..0434b104410b92134dbbb0e3e0f81f9b3107225a
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Beckhoff_BC9020.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Beckhoff_BC9020", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Beckhoff_CX9020.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Beckhoff_CX9020.h
new file mode 100644
index 0000000000000000000000000000000000000000..7feef9927fc34162e92a9b9abc6b623f81eda5fc
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Beckhoff_CX9020.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Beckhoff_CX9020", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Makefile b/silecs-codegen/src/xml/test/generated_correct/wrapper/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..3f11b2c51a6c3f984e863c0f6e973dfcc28897ad
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Makefile
@@ -0,0 +1,59 @@
+## Help on how to modify Makefiles you can get e.g. here: http://www.ijon.de/comp/tutorials/makefile.html
+
+#CPU ?= i686
+CPU=x86_64
+
+LIBS += -pthread
+
+SILECS_COMM_VERSION = 1.0.2
+SILECS_COMM_HOME ?= ../../../../../../silecs-communication-cpp/build
+SNAP7_BASE = ../../../../../../snap7/snap7-full
+LIBXML_PATH  	= /usr/include/libxml2/
+
+COMPILER_FLAGS += -I$(SILECS_COMM_HOME)/include
+COMPILER_FLAGS += -I$(LIBXML_PATH)
+ 
+LINKER_FLAGS += -L$(SILECS_COMM_HOME)/lib/$(CPU)
+LINKER_FLAGS += -L$(SNAP7_BASE)/build/bin/$(CPU)-linux -lsnap7
+LINKER_FLAGS += -L/usr/lib64 -lxml2
+LINKER_FLAGS += -lsilecs-comm
+
+
+#Optimisation flag ( 00 till 03 )
+COMPILER_FLAGS += -O2
+
+# Warn all - always use this to make the compiler really picky (and thus more helpful) 
+COMPILER_FLAGS += -Wall
+
+#include debugging symbols - always use this or your debugger doesn't work! 
+COMPILER_FLAGS += -g
+
+# files to work with:
+SOURCES = 	main.cpp
+TARGET =	Test
+
+# .o files have same name as .cpp files
+OBJS = $(SOURCES:%.cpp=%.o)
+
+# Link command to compile + build binary:
+link:		$(OBJS)
+	g++ $(OBJS) $(LINKER_FLAGS) -o $(TARGET) $(LIBS)
+
+# Compilation command:
+# Generic Way to create a .o file for each .cpp file (for many cpp files) $< is the "first dependency"
+%.o: %.cpp 
+	g++ $(INCLUDES) $(COMPILER_FLAGS) -c $<
+
+#support for "make all"
+all: link
+	@echo "-- build of target: '$(TARGET)' finished --"
+
+#support for "make clean"
+clean:
+	rm -f $(OBJS) $(TARGET) $(LIBRARY)
+
+#if you just type "make", the first command in the list of commands is executed
+
+# Simple Compilation command:
+#compile:	$(CPP)
+#	g++ $(INCLUDES) $(COMPILER_FLAGS) -c $(CPP) -o $(OBJS)
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Rabbit_BlockMode.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Rabbit_BlockMode.h
new file mode 100644
index 0000000000000000000000000000000000000000..c5620055cf7af94d6996aae076cc93076ae8fc41
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Rabbit_BlockMode.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Rabbit_BlockMode", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Rabbit_DeviceMode.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Rabbit_DeviceMode.h
new file mode 100644
index 0000000000000000000000000000000000000000..a90d775c078fbd3334d2bbff7aab429f7e46f6a5
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Rabbit_DeviceMode.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Rabbit_DeviceMode", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Schneider_M340.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Schneider_M340.h
new file mode 100644
index 0000000000000000000000000000000000000000..d31fa177a7b23b5b220ff1548ba7ffbea13267ad
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Schneider_M340.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Schneider_M340", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Schneider_PremiumQuantum.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Schneider_PremiumQuantum.h
new file mode 100644
index 0000000000000000000000000000000000000000..58576f6facb5e61e418f31f9350c6aff7a0ea63b
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Schneider_PremiumQuantum.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Schneider_PremiumQuantum", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_Step7Block.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_Step7Block.h
new file mode 100644
index 0000000000000000000000000000000000000000..9e32650f2ac7cd5376ac08e3f6e70ab22ab0942d
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_Step7Block.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Siemens_Step7Block", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_Step7Device.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_Step7Device.h
new file mode 100644
index 0000000000000000000000000000000000000000..be5bd8a0ecafcca89b0fae15e2a2f1f4cc20c8d6
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_Step7Device.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Siemens_Step7Device", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_TiaBlock.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_TiaBlock.h
new file mode 100644
index 0000000000000000000000000000000000000000..63877a39a230d8894c569d4de058e6b2c3273c70
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_TiaBlock.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Siemens_TiaBlock", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_TiaDevice.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_TiaDevice.h
new file mode 100644
index 0000000000000000000000000000000000000000..e6a302939e50d1631e9cd16bc3601015035ef975
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Siemens_TiaDevice.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Siemens_TiaDevice", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Test b/silecs-codegen/src/xml/test/generated_correct/wrapper/Test
new file mode 100755
index 0000000000000000000000000000000000000000..e50a15463ea588b2eb28f158b3e9211f19d4d720
Binary files /dev/null and b/silecs-codegen/src/xml/test/generated_correct/wrapper/Test differ
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Virtual_SiemensBlock.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Virtual_SiemensBlock.h
new file mode 100644
index 0000000000000000000000000000000000000000..1681d8b22ba04770f1b3adf8cbd197212341b0dc
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Virtual_SiemensBlock.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Virtual_SiemensBlock", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/Virtual_SiemensDevice.h b/silecs-codegen/src/xml/test/generated_correct/wrapper/Virtual_SiemensDevice.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b1ef2728a190215f7d3a31e8fba210523c18be4
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/Virtual_SiemensDevice.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Virtual_SiemensDevice", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/main.cpp b/silecs-codegen/src/xml/test/generated_correct/wrapper/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a43e59a85d24468eb601a120817e989b3eaa40c0
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/wrapper/main.cpp
@@ -0,0 +1,14 @@
+#include "AllTypes.h"
+#include "Siemens_Step7Device.h"
+
+int main()
+{
+	std::string logTopic = "ERROR";
+	AllTypesDU::DeployUnit* du = AllTypesDU::DeployUnit::getInstance(logTopic);
+	std::cout << du->getName() << std::endl;
+	AllTypes::Design* allTypesDesign = du->getAllTypes();
+	AllTypesDU::Controller controller(allTypesDesign,"fakeParamFile.silecsparam");
+	controller.connect();
+
+    return 0;
+}
diff --git a/silecs-codegen/src/xml/test/generated_correct/wrapper/main.o b/silecs-codegen/src/xml/test/generated_correct/wrapper/main.o
new file mode 100644
index 0000000000000000000000000000000000000000..9c2bf1ee5a3c6a701d0b411a5ea5eb24d9b64df3
Binary files /dev/null and b/silecs-codegen/src/xml/test/generated_correct/wrapper/main.o differ
diff --git a/silecs-codegen/src/xml/test/generated_temp/AllTypes.cpp b/silecs-codegen/src/xml/test/generated_temp/AllTypes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..08c4d7fdeb2770c38e2a0a86015a931c653292a8
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/AllTypes.cpp
@@ -0,0 +1,738 @@
+/*
+ * AllTypes.cpp
+ *
+ * Generated by SILECS framework tools 
+ */
+ 
+#include <AllTypes/Common/AllTypes.h>
+#include <fesa-core/Synchronization/NoneContext.h>
+#include <fesa-core/Synchronization/MultiplexingContext.h>
+ 
+namespace AllTypes
+{
+    //Global objects of the SILECS class
+    Silecs::Service* AbstractAllTypes::pService_ = NULL;
+    Silecs::Cluster* AbstractAllTypes::pCluster_ = NULL;
+    bool AbstractAllTypes::isInitialized_ = false;
+
+    MyROBlock_Type	AllTypes::MyROBlock("MyROBlock");
+    MyRWBlock_Type	AllTypes::MyRWBlock("MyRWBlock");
+    MyWOBlock_Type	AllTypes::MyWOBlock("MyWOBlock");
+    
+    //-------------------------------------------------------------------------------------------------------------
+    // Constructor & Destructor methods
+    
+    AbstractAllTypes::AbstractAllTypes(std::string blockName): blockName_(blockName) {}
+    AbstractAllTypes::~AbstractAllTypes() {}
+    
+    MyROBlock_Type::MyROBlock_Type(std::string name): AbstractAllTypes(name) {}
+    MyROBlock_Type::~MyROBlock_Type() {}
+    
+    MyRWBlock_Type::MyRWBlock_Type(std::string name): AbstractAllTypes(name) {}
+    MyRWBlock_Type::~MyRWBlock_Type() {}
+    
+    MyWOBlock_Type::MyWOBlock_Type(std::string name): AbstractAllTypes(name) {}
+    MyWOBlock_Type::~MyWOBlock_Type() {}
+    
+    //---------------------------------------------------------------------------------------------------------
+    // Set-up the SILECS components for the AbstractAllTypes class (service & cluster)
+
+    void AbstractAllTypes::setup(const ServiceLocator* serviceLocator)
+    {
+        try
+        {
+            // Instantiate the singleton of the SILECS Service
+            pService_ = Silecs::Service::getInstance();
+
+            // Enable the SILECS diagnostic with user topics if any
+            pService_->setArguments(serviceLocator->getUsrCmdArgs());
+
+            // Instantiate the SILECS Cluster object for the given Class/Version
+            GlobalDevice* pGlobalDevice = serviceLocator->getGlobalDevice();
+            pCluster_ = pService_->getCluster( "AllTypes", pGlobalDevice->plcClassVersion.get());
+            isInitialized_ = true;
+
+            // Connect each PLC of the Cluster that is referred from the FESA instance
+            std::vector<Device*> pDeviceCol = serviceLocator->getDeviceCollection();
+            for(std::vector<Device*>::iterator pDeviceIter=pDeviceCol.begin(); pDeviceIter!= pDeviceCol.end(); pDeviceIter++)
+            {
+                Device* pDevice = *pDeviceIter;
+
+                // Retrieve the PLC related to the current FESA device
+                // (from 'plcHostName' FESA field defined on that purpose).
+                Silecs::PLC* pPLC = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+
+                // Update the PLC Slave registers from related FESA fields just before synchronising done at connection time
+                setPLCSlaveRegisters(pPLC, serviceLocator);
+
+                // Connect the PLC if not already connected
+                if (!pPLC->isEnabled())
+                {   pPLC->connect(/*synchroMode=*/Silecs::FULL_SYNCHRO, /*connectNow=*/true);
+                    if (pPLC->isConnected())
+                    {   // Update FESA fields from related PLC Master registers just after synchronising done at connection time
+                        getPLCMasterRegisters(pPLC, serviceLocator);
+                    }
+                }
+            }
+        }
+        catch (const Silecs::SilecsException& ex)
+        {
+            throw fesa::FesaException(__FILE__, __LINE__, ex.getMessage());
+        }
+    }
+
+    //---------------------------------------------------------------------------------------------------------
+    // Release all the SILECS resources
+    void AbstractAllTypes::cleanup()
+    {
+        // Attention! This method is responsible to stop all the PLC connections
+        // and to remove all the SILECS resources (Clusters and related components: PLCs, Devices, Registers, ..)
+        // Calling method must ensure that no process is currently accessing these resources before cleaning.
+        //
+        Silecs::Service::deleteInstance();
+    }
+
+    //---------------------------------------------------------------------------------------------------------
+    // Synchronise PLC SLAVE/MASTER registers and related FESA fields (automatically called by the setup method @connection time)
+    void AbstractAllTypes::setPLCSlaveRegisters(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator)
+    {
+        fesa::NoneContext noneContext;
+    
+        AllTypes::MyWOBlock.setPLCDevices(pPLC, serviceLocator, false, &noneContext);
+    }
+
+    void AbstractAllTypes::getPLCMasterRegisters(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator)
+    {
+        fesa::NoneContext noneContext;    //MASTER acquisition fields are not consistent, can be set with none-context
+    
+        AllTypes::MyROBlock.getPLCDevices(pPLC, serviceLocator, false, &noneContext);
+        AllTypes::MyRWBlock.getPLCDevices(pPLC, serviceLocator, false, &noneContext);
+    }
+    
+    //---------------------------------------------------------------------------------------------------------
+    // General methods to synchronize the FESA fields and related PLC registers of the FESA server
+    // with or without PLC side access (send/recv) if requested.
+    // get_ : [receive block from PLC +] update FESA fields with related PLC registers
+    // set_ : update PLC registers with related FESA fields [+ send block to PLC]
+
+    //---------------------------------------------------------------------------------------------------------
+
+    void AbstractAllTypes::getAllDevices(const ServiceLocator* serviceLocator, const bool recvNow, MultiplexingContext* pContext)
+    {
+        if (recvNow) theCluster()->recv(blockName_);
+
+        std::vector<Device*> deviceCol = serviceLocator->getDeviceCollection();
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {  getOneDevice(*pDeviceIter, false, pContext);
+        }
+    }
+
+    void AbstractAllTypes::getPLCDevices(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator, const bool recvNow, MultiplexingContext* pContext)
+    {
+        if (recvNow) pPLC->recv(blockName_);
+
+        std::vector<Device*> deviceCol = serviceLocator->getDeviceCollection();
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {   if ((*pDeviceIter)->plcHostName.get() == pPLC->getName())
+            {  getOneDevice(*pDeviceIter, false, pContext);
+            }
+        }
+    }
+
+    void AbstractAllTypes::getSomeDevices(std::vector<Device*> deviceCol, const bool sendNow, MultiplexingContext* pContext)
+    {
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {    getOneDevice(*pDeviceIter, sendNow, pContext);
+        }
+    }
+
+    void AbstractAllTypes::getOneDevice(Device* pDevice, const bool recvNow, MultiplexingContext* pContext) {};
+
+    //---------------------------------------------------------------------------------------------------------
+
+    void AbstractAllTypes::setAllDevices(const ServiceLocator* serviceLocator, bool sendNow, MultiplexingContext* pContext)
+    {
+        std::vector<Device*> deviceCol = serviceLocator->getDeviceCollection();
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {  setOneDevice(*pDeviceIter, false, pContext);
+        }
+
+        if (sendNow) theCluster()->send(blockName_);
+    }
+
+    void AbstractAllTypes::setPLCDevices(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator, bool sendNow, MultiplexingContext* pContext)
+    {
+        std::vector<Device*> deviceCol = serviceLocator->getDeviceCollection();
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {   if ((*pDeviceIter)->plcHostName.get() == pPLC->getName())
+            {  setOneDevice(*pDeviceIter, false, pContext);
+            }
+        }
+
+        if (sendNow) pPLC->send(blockName_);
+    }
+
+    void AbstractAllTypes::setSomeDevices(std::vector<Device*> deviceCol, bool sendNow, MultiplexingContext* pContext)
+    {
+        for(std::vector<Device*>::iterator pDeviceIter=deviceCol.begin(); pDeviceIter!= deviceCol.end(); pDeviceIter++)
+        {    setOneDevice(*pDeviceIter, sendNow, pContext);
+        }
+    }
+
+    void AbstractAllTypes::setOneDevice(Device* pDevice, const bool sendNow, MultiplexingContext* pContext) {};
+    
+    //---------------------------------------------------------------------------------------------------------
+    
+    void MyROBlock_Type::getOneDevice(Device* pDevice, const bool recvNow, MultiplexingContext* pContext)
+    {
+    	if( !isInitialized_ )
+    	{
+    		throw fesa::FesaException(__FILE__, __LINE__, "SILECS-Service not initialized yet - AllTypes::setup needs to be called before any plc-interaction can be done");
+    	}
+        Silecs::PLC* pPLC  = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+        Silecs::Device* pPLCDevice = pPLC->getDevice(pDevice->plcDeviceLabel.get());
+        Silecs::Register*  pRegister = NULL;
+
+        if (recvNow) pPLCDevice -> recv(blockName_);        
+    
+        pDevice->RO_int8.set( pPLCDevice->getRegister("RO_int8")->getValInt8(), pContext);
+        pDevice->RO_uint8.set( pPLCDevice->getRegister("RO_uint8")->getValUInt8(), pContext);
+        pDevice->RO_int16.set( pPLCDevice->getRegister("RO_int16")->getValInt16(), pContext);
+        pDevice->RO_uint16.set( pPLCDevice->getRegister("RO_uint16")->getValUInt16(), pContext);
+        pDevice->RO_int32.set( pPLCDevice->getRegister("RO_int32")->getValInt32(), pContext);
+        pDevice->RO_uint32.set( pPLCDevice->getRegister("RO_uint32")->getValUInt32(), pContext);
+        pDevice->RO_float32.set( pPLCDevice->getRegister("RO_float32")->getValFloat32(), pContext);
+        pRegister = pPLCDevice->getRegister("RO_string");
+        pDevice->RO_string.set(pRegister->getValString().c_str(), pContext);
+
+        pDevice->RO_date.set( pPLCDevice->getRegister("RO_date")->getValDate(), pContext);
+        pDevice->RO_char.set( pPLCDevice->getRegister("RO_char")->getValInt8(), pContext);
+        pDevice->RO_byte.set( pPLCDevice->getRegister("RO_byte")->getValUInt8(), pContext);
+        pDevice->RO_word.set( pPLCDevice->getRegister("RO_word")->getValUInt16(), pContext);
+        pDevice->RO_dword.set( pPLCDevice->getRegister("RO_dword")->getValUInt32(), pContext);
+        pDevice->RO_int.set( pPLCDevice->getRegister("RO_int")->getValInt16(), pContext);
+        pDevice->RO_dint.set( pPLCDevice->getRegister("RO_dint")->getValInt32(), pContext);
+        pDevice->RO_real.set( pPLCDevice->getRegister("RO_real")->getValFloat32(), pContext);
+        pDevice->RO_dt.set( pPLCDevice->getRegister("RO_dt")->getValDate(), pContext);
+	}
+    void MyRWBlock_Type::getOneDevice(Device* pDevice, const bool recvNow, MultiplexingContext* pContext)
+    {
+    	if( !isInitialized_ )
+    	{
+    		throw fesa::FesaException(__FILE__, __LINE__, "SILECS-Service not initialized yet - AllTypes::setup needs to be called before any plc-interaction can be done");
+    	}
+        Silecs::PLC* pPLC  = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+        Silecs::Device* pPLCDevice = pPLC->getDevice(pDevice->plcDeviceLabel.get());
+        Silecs::Register*  pRegister = NULL;
+        uint32_t dim1 = 1;
+        uint32_t dim2 = 1;
+
+        if (recvNow) pPLCDevice -> recv(blockName_);        
+    
+        pRegister = pPLCDevice->getRegister("RW_int8");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_int8.set(pRegister->getRefInt8Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_uint8");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        int16_t* RW_uint8 = (int16_t*)calloc(dim1*dim2, sizeof(int16_t));
+        pRegister->getValUInt8Array2D(RW_uint8, dim1, dim2);	//use automatic conversion for JAVA non-supported type
+        pDevice->RW_uint8.set(RW_uint8, dim1, dim2, pContext);
+    free(RW_uint8);
+
+        pRegister = pPLCDevice->getRegister("RW_int16");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_int16.set(pRegister->getRefInt16Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_uint16");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        int32_t* RW_uint16 = (int32_t*)calloc(dim1*dim2, sizeof(int32_t));
+        pRegister->getValUInt16Array2D(RW_uint16, dim1, dim2);	//use automatic conversion for JAVA non-supported type
+        pDevice->RW_uint16.set(RW_uint16, dim1, dim2, pContext);
+    free(RW_uint16);
+
+        pRegister = pPLCDevice->getRegister("RW_int32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_int32.set(pRegister->getRefInt32Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_uint32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        int64_t* RW_uint32 = (int64_t*)calloc(dim1*dim2, sizeof(int64_t));
+        pRegister->getValUInt32Array2D(RW_uint32, dim1, dim2);	//use automatic conversion for JAVA non-supported type
+        pDevice->RW_uint32.set(RW_uint32, dim1, dim2, pContext);
+    free(RW_uint32);
+
+        pRegister = pPLCDevice->getRegister("RW_float32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_float32.set(pRegister->getRefFloat32Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_date");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_date.set(pRegister->getRefDateArray2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_char");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_char.set(pRegister->getRefInt8Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_byte");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        int16_t* RW_byte = (int16_t*)calloc(dim1*dim2, sizeof(int16_t));
+        pRegister->getValUInt8Array2D(RW_byte, dim1, dim2);	//use automatic conversion for JAVA non-supported type
+        pDevice->RW_byte.set(RW_byte, dim1, dim2, pContext);
+    free(RW_byte);
+
+        pRegister = pPLCDevice->getRegister("RW_word");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        int32_t* RW_word = (int32_t*)calloc(dim1*dim2, sizeof(int32_t));
+        pRegister->getValUInt16Array2D(RW_word, dim1, dim2);	//use automatic conversion for JAVA non-supported type
+        pDevice->RW_word.set(RW_word, dim1, dim2, pContext);
+    free(RW_word);
+
+        pRegister = pPLCDevice->getRegister("RW_dword");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        int64_t* RW_dword = (int64_t*)calloc(dim1*dim2, sizeof(int64_t));
+        pRegister->getValUInt32Array2D(RW_dword, dim1, dim2);	//use automatic conversion for JAVA non-supported type
+        pDevice->RW_dword.set(RW_dword, dim1, dim2, pContext);
+    free(RW_dword);
+
+        pRegister = pPLCDevice->getRegister("RW_int");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_int.set(pRegister->getRefInt16Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_dint");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_dint.set(pRegister->getRefInt32Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_real");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_real.set(pRegister->getRefFloat32Array2D(dim1, dim2), dim1, dim2, pContext);
+
+        pRegister = pPLCDevice->getRegister("RW_dt");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pDevice->RW_dt.set(pRegister->getRefDateArray2D(dim1, dim2), dim1, dim2, pContext);
+
+	}    
+    void MyRWBlock_Type::setOneDevice(Device* pDevice, const bool sendNow, MultiplexingContext* pContext)
+    {
+    	if( !isInitialized_ )
+    	{
+    		throw fesa::FesaException(__FILE__, __LINE__, "SILECS-Service not initialized yet - AllTypes::setup needs to be called before any plc-interaction can be done");
+    	}
+        Silecs::PLC* pPLC  = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+        Silecs::Device* pPLCDevice = pPLC->getDevice(pDevice->plcDeviceLabel.get());
+        Silecs::Register*  pRegister = NULL;
+        uint32_t dim1 = 1;
+        uint32_t fesaDim1;
+        uint32_t dim2 = 1;
+        uint32_t fesaDim2;
+
+
+    pRegister = pPLCDevice->getRegister("RW_int8");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValInt8Array2D(pDevice->RW_int8.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_uint8");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValUInt8Array2D( pDevice->RW_uint8.get(fesaDim1, fesaDim2, pContext), dim1, dim2);	//use automatic conversion for JAVA non-supported type
+
+    pRegister = pPLCDevice->getRegister("RW_int16");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValInt16Array2D(pDevice->RW_int16.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_uint16");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValUInt16Array2D( pDevice->RW_uint16.get(fesaDim1, fesaDim2, pContext), dim1, dim2);	//use automatic conversion for JAVA non-supported type
+
+    pRegister = pPLCDevice->getRegister("RW_int32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValInt32Array2D(pDevice->RW_int32.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_uint32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValUInt32Array2D( pDevice->RW_uint32.get(fesaDim1, fesaDim2, pContext), dim1, dim2);	//use automatic conversion for JAVA non-supported type
+
+    pRegister = pPLCDevice->getRegister("RW_float32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValFloat32Array2D(pDevice->RW_float32.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+    pRegister = pPLCDevice->getRegister("RW_date");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValDateArray2D(pDevice->RW_date.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+    pRegister = pPLCDevice->getRegister("RW_char");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValInt8Array2D(pDevice->RW_char.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_byte");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValUInt8Array2D( pDevice->RW_byte.get(fesaDim1, fesaDim2, pContext), dim1, dim2);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("RW_word");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValUInt16Array2D( pDevice->RW_word.get(fesaDim1, fesaDim2, pContext), dim1, dim2);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("RW_dword");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValUInt32Array2D( pDevice->RW_dword.get(fesaDim1, fesaDim2, pContext), dim1, dim2);	//use automatic conversion for JAVA non-supported type
+
+    pRegister = pPLCDevice->getRegister("RW_int");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValInt16Array2D(pDevice->RW_int.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+    pRegister = pPLCDevice->getRegister("RW_dint");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValInt32Array2D(pDevice->RW_dint.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+    pRegister = pPLCDevice->getRegister("RW_real");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValFloat32Array2D(pDevice->RW_real.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+    pRegister = pPLCDevice->getRegister("RW_dt");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        pRegister->setValDateArray2D(pDevice->RW_dt.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        if (sendNow) pPLCDevice->send(blockName_);
+
+	}
+    void MyRWBlock_Type::setOneDevice(Device* pDevice, MyRWBlockPropertyData& data, bool sendNow, MultiplexingContext* pContext)
+    {
+    	if( !isInitialized_ )
+    	{
+    		throw fesa::FesaException(__FILE__, __LINE__, "SILECS-Service not initialized yet - AllTypes::setup needs to be called before any plc-interaction can be done");
+    	}
+        Silecs::PLC* pPLC = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+        Silecs::Device* pPLCDevice = pPLC->getDevice(pDevice->plcDeviceLabel.get());
+        Silecs::Register*  pRegister = NULL;
+        uint32_t dim1 = 1;
+        uint32_t fesaDim1;
+        uint32_t dim2 = 1;
+        uint32_t fesaDim2;
+
+
+        pRegister = pPLCDevice->getRegister("RW_int8");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_int8Available()) ? pRegister->setValInt8Array2D(data.RW_int8.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValInt8Array2D(pDevice->RW_int8.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_uint8");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_uint8Available()) ? pRegister->setValUInt8Array2D(data.RW_uint8.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValUInt8Array2D(pDevice->RW_uint8.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_int16");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_int16Available()) ? pRegister->setValInt16Array2D(data.RW_int16.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValInt16Array2D(pDevice->RW_int16.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_uint16");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_uint16Available()) ? pRegister->setValUInt16Array2D(data.RW_uint16.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValUInt16Array2D(pDevice->RW_uint16.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_int32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_int32Available()) ? pRegister->setValInt32Array2D(data.RW_int32.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValInt32Array2D(pDevice->RW_int32.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_uint32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_uint32Available()) ? pRegister->setValUInt32Array2D(data.RW_uint32.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValUInt32Array2D(pDevice->RW_uint32.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_float32");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_float32Available()) ? pRegister->setValFloat32Array2D(data.RW_float32.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValFloat32Array2D(pDevice->RW_float32.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_date");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_dateAvailable()) ? pRegister->setValDateArray2D(data.RW_date.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValDateArray2D(pDevice->RW_date.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_char");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_charAvailable()) ? pRegister->setValInt8Array2D(data.RW_char.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValInt8Array2D(pDevice->RW_char.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_byte");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_byteAvailable()) ? pRegister->setValUInt8Array2D(data.RW_byte.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValUInt8Array2D(pDevice->RW_byte.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_word");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_wordAvailable()) ? pRegister->setValUInt16Array2D(data.RW_word.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValUInt16Array2D(pDevice->RW_word.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_dword");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_dwordAvailable()) ? pRegister->setValUInt32Array2D(data.RW_dword.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValUInt32Array2D(pDevice->RW_dword.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_int");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_intAvailable()) ? pRegister->setValInt16Array2D(data.RW_int.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValInt16Array2D(pDevice->RW_int.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_dint");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_dintAvailable()) ? pRegister->setValInt32Array2D(data.RW_dint.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValInt32Array2D(pDevice->RW_dint.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_real");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_realAvailable()) ? pRegister->setValFloat32Array2D(data.RW_real.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValFloat32Array2D(pDevice->RW_real.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        pRegister = pPLCDevice->getRegister("RW_dt");
+        dim1 = pRegister->getDimension1();
+        dim2 = pRegister->getDimension2();
+        (data.isRW_dtAvailable()) ? pRegister->setValDateArray2D(data.RW_dt.get(fesaDim1, fesaDim2), dim1, dim2) :
+                                     pRegister->setValDateArray2D(pDevice->RW_dt.get(fesaDim1, fesaDim2, pContext), dim1, dim2);
+
+        if (sendNow) pPLCDevice->send(blockName_);
+
+	}
+    
+    void MyWOBlock_Type::setOneDevice(Device* pDevice, const bool sendNow, MultiplexingContext* pContext)
+    {
+    	if( !isInitialized_ )
+    	{
+    		throw fesa::FesaException(__FILE__, __LINE__, "SILECS-Service not initialized yet - AllTypes::setup needs to be called before any plc-interaction can be done");
+    	}
+        Silecs::PLC* pPLC  = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+        Silecs::Device* pPLCDevice = pPLC->getDevice(pDevice->plcDeviceLabel.get());
+        Silecs::Register*  pRegister = NULL;
+        uint32_t dim1 = 1;
+        uint32_t fesaDim1;
+
+
+        pRegister = pPLCDevice->getRegister("WO_int8");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValInt8Array(pDevice->WO_int8.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_uint8");
+        dim1 = pRegister->getDimension1();
+        pRegister->setValUInt8Array(pDevice->WO_uint8.get(fesaDim1, pContext), dim1);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("WO_int16");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValInt16Array(pDevice->WO_int16.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_uint16");
+        dim1 = pRegister->getDimension1();
+        pRegister->setValUInt16Array(pDevice->WO_uint16.get(fesaDim1, pContext), dim1);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("WO_int32");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValInt32Array(pDevice->WO_int32.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_uint32");
+        dim1 = pRegister->getDimension1();
+        pRegister->setValUInt32Array(pDevice->WO_uint32.get(fesaDim1, pContext), dim1);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("WO_float32");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValFloat32Array(pDevice->WO_float32.get(fesaDim1, pContext), dim1);
+    
+        {
+        pRegister = pPLCDevice->getRegister("WO_string");
+        dim1 = pRegister->getDimension1();
+        std::string stdStringArray[dim1];
+        const char** cStringArray = pDevice->WO_string.get(fesaDim1, pContext);
+        for (unsigned int i=0; i<dim1; i++) stdStringArray[i] = (const char*)cStringArray[i];
+        pRegister->setValStringArray(stdStringArray, dim1);
+        }
+
+        pRegister = pPLCDevice->getRegister("WO_date");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValDateArray(pDevice->WO_date.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_char");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValInt8Array(pDevice->WO_char.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_byte");
+        dim1 = pRegister->getDimension1();
+        pRegister->setValUInt8Array(pDevice->WO_byte.get(fesaDim1, pContext), dim1);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("WO_word");
+        dim1 = pRegister->getDimension1();
+        pRegister->setValUInt16Array(pDevice->WO_word.get(fesaDim1, pContext), dim1);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("WO_dword");
+        dim1 = pRegister->getDimension1();
+        pRegister->setValUInt32Array(pDevice->WO_dword.get(fesaDim1, pContext), dim1);	//use automatic conversion for JAVA non-supported type
+
+        pRegister = pPLCDevice->getRegister("WO_int");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValInt16Array(pDevice->WO_int.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_dint");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValInt32Array(pDevice->WO_dint.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_real");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValFloat32Array(pDevice->WO_real.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_dt");
+            dim1 = pRegister->getDimension1();
+            pRegister->setValDateArray(pDevice->WO_dt.get(fesaDim1, pContext), dim1);
+    
+        if (sendNow) pPLCDevice->send(blockName_);
+
+	}
+    void MyWOBlock_Type::setOneDevice(Device* pDevice, MyWOBlockPropertyData& data, bool sendNow, MultiplexingContext* pContext)
+    {
+    	if( !isInitialized_ )
+    	{
+    		throw fesa::FesaException(__FILE__, __LINE__, "SILECS-Service not initialized yet - AllTypes::setup needs to be called before any plc-interaction can be done");
+    	}
+        Silecs::PLC* pPLC = pCluster_->getPLC(pDevice->plcHostName.get(),pDevice->parameterFile.get());
+        Silecs::Device* pPLCDevice = pPLC->getDevice(pDevice->plcDeviceLabel.get());
+        Silecs::Register*  pRegister = NULL;
+        uint32_t dim1 = 1;
+        uint32_t fesaDim1;
+
+
+        pRegister = pPLCDevice->getRegister("WO_int8");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_int8Available()) ? pRegister->setValInt8Array( data.WO_int8.get(fesaDim1), dim1) :
+                                         pRegister->setValInt8Array( pDevice->WO_int8.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_uint8");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_uint8Available()) ? pRegister->setValUInt8Array( data.WO_uint8.get(fesaDim1), dim1) :
+                                         pRegister->setValUInt8Array( pDevice->WO_uint8.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_int16");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_int16Available()) ? pRegister->setValInt16Array( data.WO_int16.get(fesaDim1), dim1) :
+                                         pRegister->setValInt16Array( pDevice->WO_int16.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_uint16");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_uint16Available()) ? pRegister->setValUInt16Array( data.WO_uint16.get(fesaDim1), dim1) :
+                                         pRegister->setValUInt16Array( pDevice->WO_uint16.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_int32");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_int32Available()) ? pRegister->setValInt32Array( data.WO_int32.get(fesaDim1), dim1) :
+                                         pRegister->setValInt32Array( pDevice->WO_int32.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_uint32");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_uint32Available()) ? pRegister->setValUInt32Array( data.WO_uint32.get(fesaDim1), dim1) :
+                                         pRegister->setValUInt32Array( pDevice->WO_uint32.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_float32");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_float32Available()) ? pRegister->setValFloat32Array( data.WO_float32.get(fesaDim1), dim1) :
+                                         pRegister->setValFloat32Array( pDevice->WO_float32.get(fesaDim1, pContext), dim1);
+    
+        {
+        pRegister = pPLCDevice->getRegister("WO_string");
+        dim1 = pRegister->getDimension1();
+        std::string stdStringArray[dim1];
+        const char** cStringArray = (data.isWO_stringAvailable() ? data.WO_string.get(fesaDim1) : pDevice->WO_string.get(fesaDim1, pContext));
+        for (unsigned int i=0; i<dim1; i++) stdStringArray[i] = (const char*)cStringArray[i];
+        pRegister->setValStringArray(stdStringArray, dim1);
+        }
+
+        pRegister = pPLCDevice->getRegister("WO_date");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_dateAvailable()) ? pRegister->setValDateArray( data.WO_date.get(fesaDim1), dim1) :
+                                         pRegister->setValDateArray( pDevice->WO_date.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_char");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_charAvailable()) ? pRegister->setValInt8Array( data.WO_char.get(fesaDim1), dim1) :
+                                         pRegister->setValInt8Array( pDevice->WO_char.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_byte");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_byteAvailable()) ? pRegister->setValUInt8Array( data.WO_byte.get(fesaDim1), dim1) :
+                                         pRegister->setValUInt8Array( pDevice->WO_byte.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_word");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_wordAvailable()) ? pRegister->setValUInt16Array( data.WO_word.get(fesaDim1), dim1) :
+                                         pRegister->setValUInt16Array( pDevice->WO_word.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_dword");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_dwordAvailable()) ? pRegister->setValUInt32Array( data.WO_dword.get(fesaDim1), dim1) :
+                                         pRegister->setValUInt32Array( pDevice->WO_dword.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_int");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_intAvailable()) ? pRegister->setValInt16Array( data.WO_int.get(fesaDim1), dim1) :
+                                         pRegister->setValInt16Array( pDevice->WO_int.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_dint");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_dintAvailable()) ? pRegister->setValInt32Array( data.WO_dint.get(fesaDim1), dim1) :
+                                         pRegister->setValInt32Array( pDevice->WO_dint.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_real");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_realAvailable()) ? pRegister->setValFloat32Array( data.WO_real.get(fesaDim1), dim1) :
+                                         pRegister->setValFloat32Array( pDevice->WO_real.get(fesaDim1, pContext), dim1);
+    
+        pRegister = pPLCDevice->getRegister("WO_dt");
+            dim1 = pRegister->getDimension1();
+            (data.isWO_dtAvailable()) ? pRegister->setValDateArray( data.WO_dt.get(fesaDim1), dim1) :
+                                         pRegister->setValDateArray( pDevice->WO_dt.get(fesaDim1, pContext), dim1);
+    
+        if (sendNow) pPLCDevice->send(blockName_);
+
+	}
+}
diff --git a/silecs-codegen/src/xml/test/generated_temp/AllTypes.h b/silecs-codegen/src/xml/test/generated_temp/AllTypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..3edca8fa217278bc71c97da47d4625f01426f1c3
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/AllTypes.h
@@ -0,0 +1,146 @@
+/*
+ * AllTypes.h
+ *
+ * Generated by SILECS framework tools 
+ */
+
+#ifndef AllTypes_AllTypes_H_
+#define AllTypes_AllTypes_H_
+
+#include <SilecsService.h>
+#include <fesa-core/Synchronization/MultiplexingContext.h>
+#include <AllTypes/GeneratedCode/ServiceLocator.h>
+    #include <AllTypes/Server/SendMyRWBlock.h>
+    #include <AllTypes/Server/SendMyWOBlock.h>
+    
+namespace AllTypes
+{
+
+    /*---------------------------------------------------------------------------------------------------------
+     * SETUP
+     *---------------------------------------------------------------------------------------------------------
+     *  Setup the SILECS service by calling the setup() method from the RTDeviceClass::specificInit()
+     *  Stop and cleanup the SILECS service by calling the cleanup() method if needed (eg.: from ~RTDeviceClass())
+     *
+     *  In order to make use of the different blocks, defined in the silecsdesign, please make use of the static, block related variables of the class, defined on the bottom of this file !
+     * --------------------------------------------------------------------------------------------------------
+     */
+
+    /*---------------------------------------------------------------------------------------------------------
+     * COMMUNICATION
+     *---------------------------------------------------------------------------------------------------------
+     * General methods to synchronize the FESA fields and related PLC registers of the FESA server with or without
+     * PLC side synchronization (send/recv) if requested. Each action is done for one particular block.
+     * In case of BLOCK_MODE configuration (see SILECS doc.), the transaction is optimal with the following
+     * 'AllDevices' and 'PLCDevices' methods.
+     * Each method can be called in the appropriate server-action (set) and rt-action (get)
+     *
+     * getAllDevices  : [receive all devices of all connected PLCs +] update FESA fields with related SILECS registers
+     * setAllDevices  : update SILECS registers with related FESA fields [+ send block to all connected PLCs]
+     * getPLCDevices  : [receive all devices of one PLC +] update FESA fields with related SILECS registers
+     * setPLCDevices  : update SILECS registers with related FESA fields [+ send block to the PLC]
+     * getSomeDevices : [receive each device of the device-collection +] update FESA fields with related SILECS registers
+     * setSomeDevices : update SILECS registers with related FESA fields [+ send block to each device of the device-collection]
+     * getOneDevice   : [receive block of one PLC device +] update FESA fields with related SILECS registers
+     * setOneDevice   : update SILECS registers with related FESA fields [+ send block to the PLC device]
+     *
+     * --------------------------------------------------------------------------------------------------------
+     */
+
+    class AbstractAllTypes
+    {
+        public:
+            static inline Silecs::Service* theService()  { return pService_; }
+            static inline Silecs::Cluster* theCluster()  { return pCluster_; }
+            inline std::string& getBlockName()          { return blockName_; }
+
+            static void setup(const ServiceLocator* serviceLocator);
+            static void cleanup();
+            static void setPLCSlaveRegisters(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator);
+            static void getPLCMasterRegisters(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator);
+
+            AbstractAllTypes(std::string blockName);
+            virtual ~AbstractAllTypes();
+
+            void getAllDevices(const ServiceLocator* serviceLocator, const bool recvNow, MultiplexingContext* pContext);
+            void getPLCDevices(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator, const bool recvNow, MultiplexingContext* pContext);
+            void getSomeDevices(std::vector<Device*> deviceCol, const bool recvNow, MultiplexingContext* pContext);
+            virtual void getOneDevice(Device* pDevice, const bool recvNow, MultiplexingContext* pContext);
+
+            void setAllDevices(const ServiceLocator* serviceLocator, const bool sendNow, MultiplexingContext* pContext);
+            void setPLCDevices(Silecs::PLC* pPLC, const ServiceLocator* serviceLocator, const bool sendNow, MultiplexingContext* pContext);
+            void setSomeDevices(std::vector<Device*> deviceCol, const bool sendNow, MultiplexingContext* pContext);
+            virtual void setOneDevice(Device* pDevice, const bool sendNow, MultiplexingContext* pContext);
+
+        protected:
+
+            static Silecs::Service* pService_;
+            static Silecs::Cluster* pCluster_;
+            static bool isInitialized_;
+
+            // Name of the silecs-block which is addressed
+            std::string blockName_;
+
+            // not copyable object
+            AbstractAllTypes(const AbstractAllTypes&);
+            AbstractAllTypes& operator=(const AbstractAllTypes&);
+    };
+
+    // -------------------------------------------------------------------------------------------------
+    #define BLOCK_RO( name )	\
+    class name##_Type : public AbstractAllTypes	\
+    {	\
+        public:	\
+            name##_Type(std::string name);	\
+            ~name##_Type();	\
+            void getOneDevice(Device* pDevice, const bool transmitNow, MultiplexingContext* pContext);	\
+    }
+
+
+    #define BLOCK_WO( name )	\
+    class name##_Type : public AbstractAllTypes	\
+    {	\
+        public:	\
+            name##_Type(std::string name);	\
+            ~name##_Type();	\
+        void setOneDevice(Device* pDevice, const bool transmitNow, MultiplexingContext* pContext);	\
+        void setOneDevice(Device* pDevice, name##PropertyData& data, const bool transmitNow, MultiplexingContext* pContext);	\
+    }
+
+    #define BLOCK_RW( name )	\
+    class name##_Type : public AbstractAllTypes	\
+    {	\
+        public:	\
+            name##_Type(std::string name);	\
+            ~name##_Type();	\
+            void getOneDevice(Device* pDevice, const bool transmitNow, MultiplexingContext* pContext);	\
+            void setOneDevice(Device* pDevice, const bool transmitNow, MultiplexingContext* pContext);	\
+            void setOneDevice(Device* pDevice, name##PropertyData& data, const bool transmitNow, MultiplexingContext* pContext);	\
+    }
+    
+    BLOCK_RO( MyROBlock );
+    BLOCK_RW( MyRWBlock );
+    BLOCK_WO( MyWOBlock );
+    
+    /*---------------------------------------------------------------------------------------------------------
+     * INTERFACE
+     *---------------------------------------------------------------------------------------------------------
+     * This is the public interface used from the FESA code to access the PLC service.
+     */
+    class AllTypes
+    {
+        public:
+            static inline Silecs::Service* theService()  { return AbstractAllTypes::theService(); }
+            static inline Silecs::Cluster* theCluster()  { return AbstractAllTypes::theCluster(); }
+            static void setup(const ServiceLocator* serviceLocator) { AbstractAllTypes::setup(serviceLocator); }
+            static void cleanup() { AbstractAllTypes::cleanup(); }
+
+                static MyROBlock_Type MyROBlock;
+                static MyRWBlock_Type MyRWBlock;
+                static MyWOBlock_Type MyWOBlock;
+               
+        };
+    }
+
+    #endif /* AllTypes_AllTypes_H_ */
+    
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/generated_temp/AllTypesFESA.design b/silecs-codegen/src/xml/test/generated_temp/AllTypesFESA.design
new file mode 100644
index 0000000000000000000000000000000000000000..68ba06391b0da0070cd148dffab36d658d29c968
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/AllTypesFESA.design
@@ -0,0 +1,657 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<equipment-model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../design-gsi.xsd">
+	<information>
+	  	<class-name>MyClass</class-name>
+		<class-major-version>0</class-major-version>
+		<class-minor-version>1</class-minor-version>
+		<class-tiny-version>0</class-tiny-version>
+		<type>Final</type>
+		<state>development</state>
+		<description>An Empty design with GSI-specific standard properties</description>
+		<fesa-version>3.1.0</fesa-version>
+		<repository-path>undefined</repository-path>
+	</information>
+	<ownership>
+		<responsible name="CSCO"/>
+		<creator login="schwinn"/>
+	</ownership>
+        <interface>
+        <device-interface>
+            <setting>
+                <GSI-Init-Property multiplexed="false" name="Init" visibility="operational">
+                    <set-action partial-setting="true" transaction="true">
+                        <server-action-ref server-action-name-ref="InitSetAction"/>
+                    </set-action>
+                </GSI-Init-Property>
+                <GSI-Reset-Property multiplexed="false" name="Reset" visibility="operational">
+                    <set-action partial-setting="true" transaction="true">
+                        <server-action-ref server-action-name-ref="ResetSetAction"/>
+                    </set-action>
+                </GSI-Reset-Property>
+                <GSI-Setting-Property multiplexed="false" name="Setting" visibility="operational">
+                    <update-flag-item direction="OUT" name="updateFlags" optional="true">
+                       <builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                    </update-flag-item>
+                    <cycle-name-item direction="OUT" name="cycleName" optional="true">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </cycle-name-item>
+                    <set-action partial-setting="true" transaction="true">
+                        <server-action-ref server-action-name-ref="SettingSetAction"/>
+                    </set-action>
+                    <get-action>
+                        <server-action-ref server-action-name-ref="SettingGetAction"/>
+                    </get-action>
+                </GSI-Setting-Property>
+                <GSI-Setting-Property name="MyRWBlock" multiplexed="false" visibility="development"><value-item name="RW_dt" direction="INOUT"><array2D type="double"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_dt"/></value-item><value-item name="RW_real" direction="INOUT"><array2D type="float"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_real"/></value-item><value-item name="RW_dint" direction="INOUT"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_dint"/></value-item><value-item name="RW_int" direction="INOUT"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_int"/></value-item><value-item name="RW_dword" direction="INOUT"><array2D type="int64_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_dword"/></value-item><value-item name="RW_word" direction="INOUT"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_word"/></value-item><value-item name="RW_byte" direction="INOUT"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_byte"/></value-item><value-item name="RW_char" direction="INOUT"><array2D type="int8_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_char"/></value-item><value-item name="RW_date" direction="INOUT"><array2D type="double"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_date"/></value-item><value-item name="RW_float32" direction="INOUT"><array2D type="float"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_float32"/></value-item><value-item name="RW_uint32" direction="INOUT"><array2D type="int64_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_uint32"/></value-item><value-item name="RW_int32" direction="INOUT"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_int32"/></value-item><value-item name="RW_uint16" direction="INOUT"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_uint16"/></value-item><value-item name="RW_int16" direction="INOUT"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_int16"/></value-item><value-item name="RW_uint8" direction="INOUT"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_uint8"/></value-item><value-item name="RW_int8" direction="INOUT"><array2D type="int8_t"><dim1>2</dim1><dim2>2</dim2></array2D><data-field-ref field-name-ref="RW_int8"/></value-item><update-flag-item direction="OUT" optional="true" name="updateFlags"><builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/></update-flag-item><cycle-name-item direction="OUT" optional="true" name="cycleName"><array type="char"><dim>32</dim></array></cycle-name-item><set-action><server-action-ref server-action-name-ref="SendMyRWBlock"/></set-action><get-action><server-action-ref server-action-name-ref="RecvMyRWBlock"/></get-action></GSI-Setting-Property><GSI-Setting-Property name="MyWOBlock" multiplexed="false" visibility="development"><value-item name="WO_dt" direction="INOUT"><array type="double"><dim>10</dim></array><data-field-ref field-name-ref="WO_dt"/></value-item><value-item name="WO_real" direction="INOUT"><array type="float"><dim>10</dim></array><data-field-ref field-name-ref="WO_real"/></value-item><value-item name="WO_dint" direction="INOUT"><array type="int32_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_dint"/></value-item><value-item name="WO_int" direction="INOUT"><array type="int16_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_int"/></value-item><value-item name="WO_dword" direction="INOUT"><array type="int64_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_dword"/></value-item><value-item name="WO_word" direction="INOUT"><array type="int32_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_word"/></value-item><value-item name="WO_byte" direction="INOUT"><array type="int16_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_byte"/></value-item><value-item name="WO_char" direction="INOUT"><array type="int8_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_char"/></value-item><value-item name="WO_date" direction="INOUT"><array type="double"><dim>10</dim></array><data-field-ref field-name-ref="WO_date"/></value-item><value-item name="WO_string" direction="INOUT"><array2D type="char"><dim1>10</dim1><dim2>64</dim2></array2D><data-field-ref field-name-ref="WO_string"/></value-item><value-item name="WO_float32" direction="INOUT"><array type="float"><dim>10</dim></array><data-field-ref field-name-ref="WO_float32"/></value-item><value-item name="WO_uint32" direction="INOUT"><array type="int64_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_uint32"/></value-item><value-item name="WO_int32" direction="INOUT"><array type="int32_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_int32"/></value-item><value-item name="WO_uint16" direction="INOUT"><array type="int32_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_uint16"/></value-item><value-item name="WO_int16" direction="INOUT"><array type="int16_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_int16"/></value-item><value-item name="WO_uint8" direction="INOUT"><array type="int16_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_uint8"/></value-item><value-item name="WO_int8" direction="INOUT"><array type="int8_t"><dim>10</dim></array><data-field-ref field-name-ref="WO_int8"/></value-item><update-flag-item direction="OUT" optional="true" name="updateFlags"><builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/></update-flag-item><cycle-name-item direction="OUT" optional="true" name="cycleName"><array type="char"><dim>32</dim></array></cycle-name-item><set-action><server-action-ref server-action-name-ref="SendMyWOBlock"/></set-action><get-action><server-action-ref server-action-name-ref="GetMyWOBlock"/></get-action></GSI-Setting-Property><GSI-Power-Property multiplexed="false" name="Power" visibility="operational">
+                    <update-flag-item direction="OUT" name="updateFlags" optional="true">
+						<builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                    </update-flag-item>
+                    <cycle-name-item direction="OUT" name="cycleName" optional="true">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </cycle-name-item>
+                    <set-action partial-setting="true" transaction="true">
+                        <server-action-ref server-action-name-ref="PowerSetAction"/>
+                    </set-action>
+                    <get-action>
+                        <server-action-ref server-action-name-ref="PowerGetAction"/>
+                    </get-action>
+                    <power-item direction="INOUT" name="power">
+                        <custom-type-scalar data-type-name-ref="DEVICE_POWER"/>
+                        
+                        <data-field-ref field-name-ref="power"/>
+                    </power-item>
+                </GSI-Power-Property>
+            </setting>
+            <acquisition>
+                <GSI-Status-Property multiplexed="false" name="Status" on-change="true" subscribable="true" visibility="operational">
+                    <acq-stamp-item direction="OUT" name="acqStamp">
+                        <scalar type="int64_t"/>
+                    </acq-stamp-item>
+                    <update-flag-item direction="OUT" name="updateFlags" optional="true">
+                        <builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                    </update-flag-item>
+                    <cycle-name-item direction="OUT" name="cycleName" optional="true">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </cycle-name-item>
+                    <cycle-stamp-item direction="OUT" name="cycleStamp" optional="true">
+                        <scalar type="int64_t"/>
+                    </cycle-stamp-item>
+                    <get-action>
+                        <server-action-ref server-action-name-ref="StatusGetAction"/>
+                    </get-action>
+                    <status-item direction="OUT" name="status">
+                        <custom-type-scalar data-type-name-ref="DEVICE_STATUS"/>
+                        
+                        <data-field-ref field-name-ref="status"/>
+                    </status-item>
+                    <detailed-status-item direction="OUT" name="detailedStatus">
+                        <array type="bool">
+                            <custom-constant-dim constant-name-ref="DETAILED_STATUS_SIZE"/>
+                        </array>
+                        <data-field-ref field-name-ref="detailedStatus"/>
+                    </detailed-status-item>
+                    <detailed-status-labels-item direction="OUT" name="detailedStatus_labels">
+                        <array2D type="char">
+                            <custom-constant-dim1 constant-name-ref="DETAILED_STATUS_SIZE"/>
+                            <custom-constant-dim2 constant-name-ref="MAX_DETAILED_STATUS_LABEL_LENGTH"/>
+                        </array2D>
+                        <data-field-ref field-name-ref="detailedStatus_labels"/>
+                    </detailed-status-labels-item>
+                    <detailed-status-severity-item direction="OUT" name="detailedStatus_severity">
+                        <custom-type-array data-type-name-ref="DETAILED_STATUS_SEVERITY">
+                            <custom-constant-dim constant-name-ref="DETAILED_STATUS_SIZE"/>
+                        </custom-type-array>
+                        <data-field-ref field-name-ref="detailedStatus_severity"/>
+                    </detailed-status-severity-item>
+                    <powerState-item direction="OUT" name="powerState">
+                        <custom-type-scalar data-type-name-ref="DEVICE_POWER_STATE"/>
+                        
+                        <data-field-ref field-name-ref="powerState"/>
+                    </powerState-item>
+                    <control-item direction="OUT" name="control">
+                        <custom-type-scalar data-type-name-ref="DEVICE_CONTROL"/>
+                        
+                        <data-field-ref field-name-ref="control"/>
+                    </control-item>
+                    <interlock-item direction="OUT" name="interlock">
+                        <scalar type="bool"/>
+                        <data-field-ref field-name-ref="interlock"/>
+                    </interlock-item>
+                    <opReady-item direction="OUT" name="opReady">
+                        <scalar type="bool"/>
+                        <data-field-ref field-name-ref="opReady"/>
+                    </opReady-item>
+                    <modulesReady-item direction="OUT" name="modulesReady">
+                        <scalar type="bool"/>
+                        <data-field-ref field-name-ref="modulesReady"/>
+                    </modulesReady-item>
+                    <error_collection-item direction="OUT">
+                        <error_codes direction="OUT" name="error_codes">
+                            <array type="int32_t">
+                                <custom-constant-dim constant-name-ref="MAX_NUMBER_OF_ERROR_MESSAGES"/>
+                            </array>
+                        </error_codes>
+                        <error_messages direction="OUT" name="error_messages">
+                            <array2D type="char">
+                                <custom-constant-dim1 constant-name-ref="MAX_NUMBER_OF_ERROR_MESSAGES"/>
+                                <custom-constant-dim2 constant-name-ref="MAX_ERROR_MESSAGE_LENGTH"/>
+                            </array2D>
+                        </error_messages>
+                        <error_timestamps direction="OUT" name="error_timestamps">
+                            <array type="int64_t">
+                                <custom-constant-dim constant-name-ref="MAX_NUMBER_OF_ERROR_MESSAGES"/>
+                            </array>
+                        </error_timestamps>
+                        <error_cycle_names direction="OUT" name="error_cycle_names">
+                            <array2D type="char">
+                                <custom-constant-dim1 constant-name-ref="MAX_NUMBER_OF_ERROR_MESSAGES"/>
+                                <custom-constant-dim2 constant-name-ref="MAX_ERROR_MESSAGE_LENGTH"/>
+                            </array2D>
+                        </error_cycle_names>
+                        <error_collection-field-ref field-name-ref="error_collection"/>
+                    </error_collection-item>
+                </GSI-Status-Property>
+                <GSI-ModuleStatus-Property visibility="development" subscribable="true" name="ModuleStatus" multiplexed="false">
+                	<acq-stamp-item name="acqStamp" direction="OUT">
+                		<scalar type="int64_t"/>
+                	</acq-stamp-item>
+                	<update-flag-item optional="true" name="updateFlags" direction="OUT">
+                		<builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                	</update-flag-item>
+                	<cycle-name-item optional="true" name="cycleName" direction="OUT">
+                		<array type="char">
+                			<dim>32</dim>
+                		</array>
+                	</cycle-name-item>
+                	<cycle-stamp-item optional="true" name="cycleStamp" direction="OUT">
+                		<scalar type="int64_t"/>
+                	</cycle-stamp-item>
+                	<get-action>
+                		<server-action-ref server-action-name-ref="ModuleStatusGetAction"/>
+                	</get-action>
+                	<module-status-item name="moduleStatus" direction="OUT">
+                		<custom-type-array data-type-name-ref="MODULE_STATUS">
+                			<custom-constant-dim constant-name-ref="MODULE_STATUS_SIZE"/>
+                			
+                		</custom-type-array>
+                		
+                		<data-field-ref field-name-ref="moduleStatus"/>
+                	</module-status-item>
+                	<module-status-labels-item name="moduleStatus_labels" direction="OUT">
+                		<array2D type="char">
+                			<custom-constant-dim1 constant-name-ref="MODULE_STATUS_SIZE"/>
+                			<custom-constant-dim2 constant-name-ref="MAX_MODULE_STATUS_LABEL_LENGTH"/>
+                			
+                		</array2D>
+                		
+                		<data-field-ref field-name-ref="moduleStatus_labels"/>
+                	</module-status-labels-item>
+                </GSI-ModuleStatus-Property>
+                <GSI-Acquisition-Property multiplexed="true" name="Acquisition" on-change="true" subscribable="true" visibility="operational">
+                    <acq-stamp-item direction="OUT" name="acqStamp">
+                        <scalar type="int64_t"/>
+                    </acq-stamp-item>
+                    <update-flag-item direction="OUT" name="updateFlags" optional="true">
+                        <builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                    </update-flag-item>
+                    <cycle-name-item direction="OUT" name="cycleName" optional="true">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </cycle-name-item>
+                    <cycle-stamp-item direction="OUT" name="cycleStamp" optional="true">
+                        <scalar type="int64_t"/>
+                    </cycle-stamp-item>
+                    <get-action>
+                        <server-action-ref server-action-name-ref="AcquisitionGetAction"/>
+                    </get-action>
+                    <acquisition-context-item direction="OUT">
+                        <acqStamp direction="OUT" name="acqStampGSI">
+                            <scalar type="int64_t"/>
+                        </acqStamp>
+                        <cycleStamp direction="OUT" name="cycleStampGSI">
+                            <scalar type="int64_t"/>
+                        </cycleStamp>
+                        <cycleName direction="OUT" name="cycleNameGSI">
+                            <array type="char">
+                                <custom-constant-dim constant-name-ref="MAX_CYCLE_NAME_LENGTH"/>
+                            </array>
+                        </cycleName>
+                        <beamProcessID direction="OUT" name="beamProcessID">
+                            <scalar type="int32_t"/>
+                        </beamProcessID>
+                         <sequenceID direction="OUT" name="sequenceID">
+                            <scalar type="int32_t"/>
+                        </sequenceID>
+                        <acquisition-context-field-ref field-name-ref="acquisitionContext"/>
+                    </acquisition-context-item>
+                </GSI-Acquisition-Property>
+                <GSI-Acquisition-Property name="MyROBlock" subscribable="true" multiplexed="false" on-change="true" visibility="development"><value-item name="RO_dt" direction="OUT"><scalar type="double"/><data-field-ref field-name-ref="RO_dt"/></value-item><value-item name="RO_real" direction="OUT"><scalar type="float"/><data-field-ref field-name-ref="RO_real"/></value-item><value-item name="RO_dint" direction="OUT"><scalar type="int32_t"/><data-field-ref field-name-ref="RO_dint"/></value-item><value-item name="RO_int" direction="OUT"><scalar type="int16_t"/><data-field-ref field-name-ref="RO_int"/></value-item><value-item name="RO_dword" direction="OUT"><scalar type="int64_t"/><data-field-ref field-name-ref="RO_dword"/></value-item><value-item name="RO_word" direction="OUT"><scalar type="int32_t"/><data-field-ref field-name-ref="RO_word"/></value-item><value-item name="RO_byte" direction="OUT"><scalar type="int16_t"/><data-field-ref field-name-ref="RO_byte"/></value-item><value-item name="RO_char" direction="OUT"><scalar type="int8_t"/><data-field-ref field-name-ref="RO_char"/></value-item><value-item name="RO_date" direction="OUT"><scalar type="double"/><data-field-ref field-name-ref="RO_date"/></value-item><value-item name="RO_string" direction="OUT"><array type="char"><dim>64</dim></array><data-field-ref field-name-ref="RO_string"/></value-item><value-item name="RO_float32" direction="OUT"><scalar type="float"/><data-field-ref field-name-ref="RO_float32"/></value-item><value-item name="RO_uint32" direction="OUT"><scalar type="int64_t"/><data-field-ref field-name-ref="RO_uint32"/></value-item><value-item name="RO_int32" direction="OUT"><scalar type="int32_t"/><data-field-ref field-name-ref="RO_int32"/></value-item><value-item name="RO_uint16" direction="OUT"><scalar type="int32_t"/><data-field-ref field-name-ref="RO_uint16"/></value-item><value-item name="RO_int16" direction="OUT"><scalar type="int16_t"/><data-field-ref field-name-ref="RO_int16"/></value-item><value-item name="RO_uint8" direction="OUT"><scalar type="int16_t"/><data-field-ref field-name-ref="RO_uint8"/></value-item><value-item name="RO_int8" direction="OUT"><scalar type="int8_t"/><data-field-ref field-name-ref="RO_int8"/></value-item><acq-stamp-item direction="OUT" name="acqStamp"><scalar type="int64_t"/></acq-stamp-item><update-flag-item direction="OUT" optional="true" name="updateFlags"><builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/></update-flag-item><cycle-name-item direction="OUT" optional="true" name="cycleName"><array type="char"><dim>32</dim></array></cycle-name-item><cycle-stamp-item direction="OUT" optional="true" name="cycleStamp"><scalar type="int64_t"/></cycle-stamp-item><get-action><server-action-ref server-action-name-ref="GetMyROBlock"/></get-action><acquisition-context-item direction="OUT"><processIndex direction="OUT" name="processIndex"><scalar type="int32_t"/></processIndex><sequenceIndex direction="OUT" name="sequenceIndex"><scalar type="int32_t"/></sequenceIndex><chainIndex direction="OUT" name="chainIndex"><scalar type="int32_t"/></chainIndex><eventNumber direction="OUT" name="eventNumber"><scalar type="int32_t"/></eventNumber><timingGroupID direction="OUT" name="timingGroupID"><scalar type="int32_t"/></timingGroupID><acquisitionStamp direction="OUT" name="acquisitionStamp"><scalar type="int64_t"/></acquisitionStamp><eventStamp direction="OUT" name="eventStamp"><scalar type="int64_t"/></eventStamp><processStartStamp direction="OUT" name="processStartStamp"><scalar type="int64_t"/></processStartStamp><sequenceStartStamp direction="OUT" name="sequenceStartStamp"><scalar type="int64_t"/></sequenceStartStamp><chainStartStamp direction="OUT" name="chainStartStamp"><scalar type="int64_t"/></chainStartStamp><acquisition-context-field-ref field-name-ref="acquisitionContext"/></acquisition-context-item></GSI-Acquisition-Property><GSI-Version-Property multiplexed="false" name="Version" on-change="false" subscribable="false" visibility="operational">
+                    <acq-stamp-item direction="OUT" name="acqStamp">
+                        <scalar type="int64_t"/>
+                    </acq-stamp-item>
+                    <update-flag-item direction="OUT" name="updateFlags" optional="true">
+                        <builtin-type-scalar data-type-name-ref="NOTIFICATION_UPDATE"/>
+                    </update-flag-item>
+                    <cycle-name-item direction="OUT" name="cycleName" optional="true">
+                        <array type="char">
+                            <dim>32</dim>
+                        </array>
+                    </cycle-name-item>
+                    <cycle-stamp-item direction="OUT" name="cycleStamp" optional="true">
+                        <scalar type="int64_t"/>
+                    </cycle-stamp-item>
+                    <get-action>
+                        <server-action-ref server-action-name-ref="VersionGetAction"/>
+                    </get-action>
+                    <version-item direction="OUT" name="classVersion">
+                        <array type="char">
+                            <custom-constant-dim constant-name-ref="MAX_VERSION_NAME_LENGTH"/>
+                        </array>
+                    </version-item>
+                    <version-item direction="OUT" name="deployUnitVersion">
+                        <array type="char">
+                            <custom-constant-dim constant-name-ref="MAX_VERSION_NAME_LENGTH"/>
+                        </array>
+                    </version-item>
+                    <version-item direction="OUT" name="fesaVersion">
+                        <array type="char">
+                            <custom-constant-dim constant-name-ref="MAX_VERSION_NAME_LENGTH"/>
+                        </array>
+                    </version-item>
+                </GSI-Version-Property>
+         </acquisition>
+      </device-interface>
+        <global-interface>
+            <setting>
+                <diagnostic-property multiplexed="false" name="DiagnosticSetting" visibility="expert">
+                    <description>Generic property which allows to diagnose any FESA classes</description>
+                        <mode-item direction="INOUT" name="enableDiagMode">
+                            <scalar type="bool"/>
+                        </mode-item>
+                        <host-item direction="INOUT" name="hostName">
+                            <array type="char">
+                                <dim>32</dim>
+                            </array>
+                        </host-item>
+                        <port-item direction="INOUT" name="portNumber">
+                            <scalar type="int32_t"/>
+                        </port-item>
+                        <config-item direction="IN" name="requestConfig">
+                            <scalar type="bool"/>
+                        </config-item>
+                        <state-item direction="IN" name="requestState">
+                            <scalar type="bool"/>
+                        </state-item>
+                        <fwk-topic-item direction="INOUT" name="fwkTopic">
+                            <builtin-type-scalar data-type-name-ref="DIAG_FWK_TOPIC"/>
+                        </fwk-topic-item>
+                        <custom-topic-item direction="INOUT" name="customTopic">
+                            <custom-type-scalar data-type-name-ref="DIAG_TOPIC"/>
+                        </custom-topic-item>
+                        <device-trace-item direction="INOUT" name="traceDevices">
+                            <array type="char">
+                                <dim>320</dim>
+                            </array>
+                        </device-trace-item>
+                        <bypass-action-item direction="INOUT" name="bypassActions">
+                            <array type="char">
+                                <dim>320</dim>
+                            </array>
+                        </bypass-action-item>
+                </diagnostic-property>
+            </setting>
+            <acquisition>
+                <GSI-DeviceDescription-Property multiplexed="false" name="DeviceDescription" on-change="false" subscribable="false" visibility="operational">
+                    <timing-info-item direction="OUT" name="deviceNameTimingReceiver">
+                        <array type="char">
+                            <variable-dim/>
+                        </array>
+                        <data-field-ref field-name-ref="deviceNameTimingReceiver"/>
+                    </timing-info-item>
+                    <property-info-item direction="OUT" name="propertyNames">
+                        <array2D type="char">
+                            <variable-dim1/>
+                            <variable-dim2/>
+                        </array2D>
+                    </property-info-item>
+                    <device-info-item direction="OUT" name="deviceNames">
+                        <array2D type="char">
+                            <variable-dim1/>
+                            <variable-dim2/>
+                        </array2D>
+                    </device-info-item>
+                    <global-device-info-item direction="OUT" name="globalDeviceName">
+                        <array type="char">
+                            <variable-dim/>
+                        </array>
+                    </global-device-info-item>
+                    <host-info-item direction="OUT" name="host">
+                        <array type="char">
+                            <variable-dim/>
+                        </array>
+                    </host-info-item>
+                </GSI-DeviceDescription-Property>
+            </acquisition>
+        </global-interface>
+    </interface>
+    <builtin-types>
+		<notification-update-enum name="NOTIFICATION_UPDATE">
+            <IMMEDIATE access="RO" symbol="IMMEDIATE" value="1"/>
+            <SET access="RO" symbol="SET" value="2"/>
+        </notification-update-enum>
+        <diag-fwk-topic name="DIAG_FWK_TOPIC">
+            <b0 name="SRV_GET_ACTION_PROFIING"/>
+            <b1 name="SRV_SET_ACTION_PROFILING"/>
+            <b2 name="RT_ACTION_PROFILING"/>
+            <b3 name="EVENT_PROFILING"/>
+            <b4 name="NOTIFICATION_PROFILING"/>
+            <b5 name="SRV_GET_ACTION_TRACKING"/>
+            <b6 name="SRV_SET_ACTION_TRACKING"/>
+            <b7 name="RT_ACTION_TRACKING"/>
+            <b8 name="EVENT_TRACKING"/>
+            <b9 name="NOTIFICATION_TRACKING"/>
+            <b10 name="PERSISTENCY_TRACKING"/>
+            <b11 name="TRANSACTION_TRACKING"/>
+            <b12 name="SUBSCRIPTION_TRACKING"/>
+            <b13 name="SIGNAL_HANDLER_TRACKING"/>
+            <b14 name="LOCAL_CONNECTION_TRACKING"/>
+        </diag-fwk-topic>
+        <fault-severity name="FaultSeverity">
+        	<description>Enumeration listing the available fault severities used by the fault fields</description>
+        	<INFO access="RO" meaning="NONE" value="0" symbol="INFO"/>
+        	<WARNING access="RO" meaning="WARNING" value="1" symbol="WARNING"/>
+        	<ERROR access="RO" meaning="ERROR" value="2" symbol="ERROR"/>
+        	<CRITICAL access="RO" meaning="ERROR" value="3" symbol="CRITICAL"/>
+        </fault-severity>
+
+    </builtin-types>
+    <custom-types>
+        <diag-custom-topic name="DIAG_TOPIC">
+        </diag-custom-topic>
+        <enum name="DEVICE_STATUS">
+        <!--Possible (mutually exclusive) values to describe the device status-->
+            
+            <item access="RW" meaning="NONE" symbol="UNKNOWN" value="0"/>
+            <!--The device status is unknown-->
+            
+            <item access="RW" meaning="NONE" symbol="OK" value="1"/>
+            <!--The device is in fully operational state-->
+            
+            <item access="RW" meaning="NONE" symbol="WARNING" value="2"/>
+            <!--The device is not fully operational; A device in WARNING state can still be used operationally, -->
+            <!--but clients must be informed of a problem that might become worse. Details are explained in the errorMsg field.-->
+            
+            <item access="RW" meaning="NONE" symbol="ERROR" value="3"/>
+            <!--The device is in a fault state. Details are explained in the errorMsg field-->
+        </enum>
+        <enum name="DEVICE_POWER_STATE">
+        <!--Possible (mutually exclusive) values to describe the power-state of the device.-->
+            
+            <item access="RW" meaning="NONE" symbol="UNKNOWN" value="0"/>
+            <!--The device mode is unknown-->
+            
+            <item access="RW" meaning="ON" symbol="ON" value="1"/>
+            <!--The device is in fully operational state-->
+            
+            <item access="RW" meaning="NONE" symbol="OFF" value="2"/>
+            <!--The device is turned off-->
+            
+            <item access="RW" meaning="NONE" symbol="STANDBY" value="3"/>
+            <!--The device is in a stand-by mode. This mode is a sort of “parking mode” in which the device can -->
+            <!--stay for hours or even days. It is defined by the following characteristics:-->
+            <!--It is safe, it does not wear out, it consumes little energy.-->
+            <!--Furthermore, it takes a short time to go from STANDBY to ON mode-->
+            
+            <item access="RW" meaning="NONE" symbol="POWER_DOWN" value="4"/>
+            <!--The device is shutting down. Note that some properties may not be accessible during this time.-->
+            <!--After shutdown the device will be in the mode OFF-->
+            
+            <item access="RW" meaning="NONE" symbol="POWER_UP" value="5"/>
+            <!--The device is starting up. Note that some properties may not be accessible during this time.-->
+            <!--After (re-)starting the device probably will be in the mode ON-->
+            
+        </enum>
+        <enum name="DEVICE_POWER">
+        <!--An enumeration Type used to control the operational mode of the device.-->
+        <!--Its values are a subset of those in the DEVICE_POWER_STATE type-->
+            <item access="RW" meaning="ON" symbol="ON" value="1"/>
+            <!--The device is in fully operational state-->     
+            
+            <item access="RW" meaning="OFF" symbol="OFF" value="2"/>
+            <!--The device is turned off-->
+        </enum>
+        <enum name="DEVICE_CONTROL">
+        <!--Possible values to describe the control mode of a device-->
+        <!--Currently two control modes (LOCAL, REMOTE) are defined-->
+        
+            <item access="RW" meaning="NONE" symbol="REMOTE" value="0"/>
+            <!--The device can be controlled normally through the control system-->
+            
+            <item access="RW" meaning="NONE" symbol="LOCAL" value="1"/>
+            <!--The device can be controlled locally. But it can be accessed in read-only mode via the control system-->
+        </enum>
+        <enum name="TOL_CHECK_MODE">
+        <!--This constant defines possible modes to check whether a control value is inside the tolerance values.-->
+        <!--Used to give information on how the tolerance fields are used to calculate the xxx_status information.-->
+        
+            <item access="RO" symbol="ABS" value="0"/>
+            <!--Use the absolute tolerance _tolAbs-->
+            
+            <item access="RO" symbol="REL" value="1"/>
+            <!--Use the relative tolerance _tolRel-->
+        </enum>
+        <bit-enum-32bits name="AQN_STATUS">
+        <!--Possible values to describe the acquisition status of a field (in the _status suffix)-->
+        <!--If this suffix is missing, it means that no additional status information is provided for the corresponding field-->
+        <!--If all bits are 0, this means that the corresponding field is OK.-->
+        <!--Only the lower 16 bits are standardized, the upper 16 bits can be defined by the equipment specialist.-->
+        <!--The difference between the Status property and the _status suffix is described in the section on the Status property.-->
+            <b0 name="NOT_OK"/>
+            <!--Some problem occurred that is not represented by the other bits. This property is called-->
+            <!-- NOT_OK so that it is not mixed up with ERROR or WARNING in the Status property-->
+            <b1 name="BAD_QUALITY"/>
+            <!--The value was acquired with a degraded quality. This is typically used for measurements.-->
+            <b2 name="DIFFERENT_FROM_SETTING"/>
+            <!--Different from the requested control value (for discrete values)--><!--or out of tolerance (for continuous values).-->
+            <b3 name="OUT_OF_RANGE"/>
+            <!--The value is out of the normal range (e.g. a temperature is too high or too low).-->
+            <b4 name="BUSY"/>
+            <!--The property value is changing in response to receiving a new control value (e.g. moving to a-->
+            <!--new position, charging a capacitor, ...). If the value change does not reach the requested new-->
+            <!--value within the maximum timeout, the BUSY bit should remain=1 and the TIMEOUT bit must be turned on.-->
+            <b5 name="TIMEOUT"/>
+            <!--A timeout occurred, because the property did not reach the reqested new control value within the-->
+            <!--maximum allowable time. A timeout normally indicates a problem to be addressed by the-->
+            <!--equipment specialist. This is typically used for slow changing control values that are BUSY while they change.-->
+            <b6 name="bit6_is_reserved_for_later_usage"/>
+            <b7 name="bit7_is_reserved_for_later_usage"/>
+            <b8 name="bit8_is_reserved_for_later_usage"/>
+            <b9 name="bit9_is_reserved_for_later_usage"/>
+            <b10 name="bit10_is_reserved_for_later_usage"/>
+            <b11 name="bit11_is_reserved_for_later_usage"/>
+            <b12 name="bit12_is_reserved_for_later_usage"/>
+            <b13 name="bit13_is_reserved_for_later_usage"/>
+            <b14 name="bit14_is_reserved_for_later_usage"/>
+            <b15 name="bit15_is_reserved_for_later_usage"/>
+            <!--bit 6 to 15 are reserved ... dont use them!-->
+            
+            <b16 name="bit_16_and_higher_can_be_used_by_the_class_developer"/>
+            <!--into bit 16..32 you can put in anything you want-->
+        </bit-enum-32bits>
+
+        <struct name="GSI_ERROR">
+        <!--This struct-item describes the structure of an GSI-error-->
+            <struct-item name="error_string">
+            <!--This string holds the error-message-->
+                <array type="char">
+                    <custom-constant-dim constant-name-ref="MAX_ERROR_MESSAGE_LENGTH"/>
+                </array>
+            </struct-item>
+            <struct-item name="error_code">
+            <!--The error code according to the defined error-message-->
+                <scalar type="int32_t"/>
+            </struct-item>
+            <!--The timestamp when the error occured-->
+            <struct-item name="error_timestamp">
+                <scalar type="int64_t"/>
+            </struct-item>
+            <!--The cycle for which the error occured-->
+            <struct-item name="error_cycle_name">
+                <array type="char">
+                    <custom-constant-dim constant-name-ref="MAX_CYCLE_NAME_LENGTH"/>
+                </array>
+            </struct-item>
+        </struct>
+        <struct name="GSI_ACQ_CONTEXT">
+        <!--This struct-item describes all AcquisitionContext items which are relevant for GSI-->
+            <struct-item name="acqStamp">
+            <!--The acquisition stamp is used to indicate when a measurement was done -->
+                <scalar type="int64_t"/>
+            </struct-item>
+            <struct-item name="cycleStamp">
+            <!--The cycle stamp is used to indicate when a specific cycle has started-->
+                <scalar type="int64_t"/>
+            </struct-item>
+            <struct-item name="cycleName">
+            <!--The cycle name indicates the cycle which started at time of the cycleStamp -->
+                <array type="char">
+                    <custom-constant-dim constant-name-ref="MAX_CYCLE_NAME_LENGTH"/>    
+                </array>
+            </struct-item>
+            <struct-item name="beamProcessID">
+				<scalar type="int32_t"/>
+            </struct-item>
+            <struct-item name="sequenceID">
+				<scalar type="int32_t"/>
+            </struct-item>
+        </struct>
+        <constant name="MAX_ERROR_MESSAGE_LENGTH" type="uint32_t" value="256"/>
+        <constant name="MAX_NUMBER_OF_ERROR_MESSAGES" type="uint32_t" value="16"/>
+        <constant name="MAX_CYCLE_NAME_LENGTH" type="uint32_t" value="256"/>
+        <constant name="MAX_VERSION_NAME_LENGTH" type="uint32_t" value="256"/>
+        <constant name="MAX_DETAILED_STATUS_LABEL_LENGTH" type="uint32_t" value="30"/>
+        <constant name="DETAILED_STATUS_SIZE" type="uint32_t" value="2"/>
+        <enum name="DETAILED_STATUS_SEVERITY">
+            <item access="RO" symbol="INFO" value="0"/>
+            <item access="RO" symbol="WARNING_ON_FALSE" value="1"/>
+            <item access="RO" symbol="ERROR_ON_FALSE" value="2"/>
+        </enum>
+        <enum name="MODULE_STATUS">
+        <!-- Mutually exclusive values to describe the status of a hardware / software module-->
+        	<item access="RO" value="0" symbol="UNKNOWN"/>
+        	<!--The status of the module is not known-->
+        	<item access="RO" value="1" symbol="OK"/>
+        	<!--The module is in fully operational state-->
+        	<item access="RO" value="2" symbol="WARNING"/>
+        	<!--The module is not fully operational; A module in WARNING state may still be used operationally, -->
+        	<!--but clients must be informed of a problem that might become worse. -->
+        	<item access="RO" value="3" symbol="ERROR"/>
+        	<!--The module is in a fault state. The related device is not operational.-->
+        	<item access="RO" value="4" symbol="NOT_AVAILABLE"/>
+            <!--The module is missing. The related device is not operational.-->
+        </enum>
+        <constant name="MAX_MODULE_STATUS_LABEL_LENGTH" type="uint32_t" value="30"/>
+        <constant name="MODULE_STATUS_SIZE" type="uint32_t" value="2"/>
+    </custom-types>
+    <data>
+        <device-data>
+            <configuration>
+                <field name="parameterFile"><description>ParameterFile of the PLC (*.silecsparam)</description><array type="char"><dim>512</dim></array><default>../../../generated/client/MyControllerName.silecsparam</default></field><field name="plcDeviceLabel"><description>Name of the related SILECS instance within the PLC mapping</description><array type="char"><dim>128</dim></array></field><field name="plcHostName"><description>Hostname of the PLC that contains the related SILECS class device</description><array type="char"><dim>128</dim></array></field><GSI-detailed-status-labels-field name="detailedStatus_labels">
+                    <array2D type="char">
+                        <custom-constant-dim1 constant-name-ref="DETAILED_STATUS_SIZE"/>
+                        <custom-constant-dim2 constant-name-ref="MAX_DETAILED_STATUS_LABEL_LENGTH"/>
+                    </array2D>
+                    <default>{myStatusLabel1,myStatusLabel2}</default>
+                </GSI-detailed-status-labels-field>
+                <GSI-detailed-status-severity-field name="detailedStatus_severity">
+                    <custom-type-array data-type-name-ref="DETAILED_STATUS_SEVERITY">
+                        <custom-constant-dim constant-name-ref="DETAILED_STATUS_SIZE"/>
+                    </custom-type-array>
+                    <default>{INFO,INFO}</default>
+                </GSI-detailed-status-severity-field>
+                <GSI-module-status-labels-field name="moduleStatus_labels">
+                	<array2D type="char">
+                		<custom-constant-dim1 constant-name-ref="MODULE_STATUS_SIZE"/>
+                		
+                		<custom-constant-dim2 constant-name-ref="MAX_MODULE_STATUS_LABEL_LENGTH"/>
+                	</array2D>
+                	<default>{myModule1,myModule2}</default>
+                </GSI-module-status-labels-field>
+            </configuration>
+            <setting>
+                <field name="WO_dt" shared="true" multiplexed="false" persistent="true"><array type="double"><dim>10</dim></array></field><field name="WO_real" shared="true" multiplexed="false" persistent="true"><array type="float"><dim>10</dim></array></field><field name="WO_dint" shared="true" multiplexed="false" persistent="true"><array type="int32_t"><dim>10</dim></array></field><field name="WO_int" shared="true" multiplexed="false" persistent="true"><array type="int16_t"><dim>10</dim></array></field><field name="WO_dword" shared="true" multiplexed="false" persistent="true"><array type="int64_t"><dim>10</dim></array></field><field name="WO_word" shared="true" multiplexed="false" persistent="true"><array type="int32_t"><dim>10</dim></array></field><field name="WO_byte" shared="true" multiplexed="false" persistent="true"><array type="int16_t"><dim>10</dim></array></field><field name="WO_char" shared="true" multiplexed="false" persistent="true"><array type="int8_t"><dim>10</dim></array></field><field name="WO_date" shared="true" multiplexed="false" persistent="true"><array type="double"><dim>10</dim></array></field><field name="WO_string" shared="true" multiplexed="false" persistent="true"><array2D type="char"><dim1>10</dim1><dim2>64</dim2></array2D></field><field name="WO_float32" shared="true" multiplexed="false" persistent="true"><array type="float"><dim>10</dim></array></field><field name="WO_uint32" shared="true" multiplexed="false" persistent="true"><array type="int64_t"><dim>10</dim></array></field><field name="WO_int32" shared="true" multiplexed="false" persistent="true"><array type="int32_t"><dim>10</dim></array></field><field name="WO_uint16" shared="true" multiplexed="false" persistent="true"><array type="int32_t"><dim>10</dim></array></field><field name="WO_int16" shared="true" multiplexed="false" persistent="true"><array type="int16_t"><dim>10</dim></array></field><field name="WO_uint8" shared="true" multiplexed="false" persistent="true"><array type="int16_t"><dim>10</dim></array></field><field name="WO_int8" shared="true" multiplexed="false" persistent="true"><array type="int8_t"><dim>10</dim></array></field><field name="RW_dt" multiplexed="false" persistent="true"><array2D type="double"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_real" multiplexed="false" persistent="true"><array2D type="float"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_dint" multiplexed="false" persistent="true"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_int" multiplexed="false" persistent="true"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_dword" multiplexed="false" persistent="true"><array2D type="int64_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_word" multiplexed="false" persistent="true"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_byte" multiplexed="false" persistent="true"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_char" multiplexed="false" persistent="true"><array2D type="int8_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_date" multiplexed="false" persistent="true"><array2D type="double"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_float32" multiplexed="false" persistent="true"><array2D type="float"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_uint32" multiplexed="false" persistent="true"><array2D type="int64_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_int32" multiplexed="false" persistent="true"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_uint16" multiplexed="false" persistent="true"><array2D type="int32_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_int16" multiplexed="false" persistent="true"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_uint8" multiplexed="false" persistent="true"><array2D type="int16_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><field name="RW_int8" multiplexed="false" persistent="true"><array2D type="int8_t"><dim1>2</dim1><dim2>2</dim2></array2D></field><GSI-power-field multiplexed="false" name="power" persistent="false">
+                    <custom-type-scalar data-type-name-ref="DEVICE_POWER"/>
+                </GSI-power-field>
+            </setting>
+            <acquisition>
+                <field name="RO_dt" multiplexed="false" persistent="false"><scalar type="double"/></field><field name="RO_real" multiplexed="false" persistent="false"><scalar type="float"/></field><field name="RO_dint" multiplexed="false" persistent="false"><scalar type="int32_t"/></field><field name="RO_int" multiplexed="false" persistent="false"><scalar type="int16_t"/></field><field name="RO_dword" multiplexed="false" persistent="false"><scalar type="int64_t"/></field><field name="RO_word" multiplexed="false" persistent="false"><scalar type="int32_t"/></field><field name="RO_byte" multiplexed="false" persistent="false"><scalar type="int16_t"/></field><field name="RO_char" multiplexed="false" persistent="false"><scalar type="int8_t"/></field><field name="RO_date" multiplexed="false" persistent="false"><scalar type="double"/></field><field name="RO_string" multiplexed="false" persistent="false"><array type="char"><dim>64</dim></array></field><field name="RO_float32" multiplexed="false" persistent="false"><scalar type="float"/></field><field name="RO_uint32" multiplexed="false" persistent="false"><scalar type="int64_t"/></field><field name="RO_int32" multiplexed="false" persistent="false"><scalar type="int32_t"/></field><field name="RO_uint16" multiplexed="false" persistent="false"><scalar type="int32_t"/></field><field name="RO_int16" multiplexed="false" persistent="false"><scalar type="int16_t"/></field><field name="RO_uint8" multiplexed="false" persistent="false"><scalar type="int16_t"/></field><field name="RO_int8" multiplexed="false" persistent="false"><scalar type="int8_t"/></field><GSI-control-field multiplexed="false" name="control">
+                    <custom-type-scalar data-type-name-ref="DEVICE_CONTROL"/>
+                </GSI-control-field>
+                <GSI-powerState-field multiplexed="false" name="powerState">
+                    <custom-type-scalar data-type-name-ref="DEVICE_POWER_STATE"/>
+                </GSI-powerState-field>
+                <GSI-status-field multiplexed="false" name="status">
+                    <custom-type-scalar data-type-name-ref="DEVICE_STATUS"/>
+                </GSI-status-field>
+                <GSI-interlock-field multiplexed="false" name="interlock">
+                    <scalar type="bool"/>
+                </GSI-interlock-field>
+                <GSI-opReady-field multiplexed="false" name="opReady">
+                    <scalar type="bool"/>
+                </GSI-opReady-field>
+                <GSI-modulesReady-field name="modulesReady" multiplexed="false">
+                	<scalar type="bool"/>
+                </GSI-modulesReady-field>
+                <GSI-detailed-status-field multiplexed="false" name="detailedStatus">
+                    <array type="bool">
+                        <custom-constant-dim constant-name-ref="DETAILED_STATUS_SIZE"/>
+                    </array>
+                </GSI-detailed-status-field>
+                <GSI-module-status-field name="moduleStatus" multiplexed="false">
+                	<custom-type-array data-type-name-ref="MODULE_STATUS">
+                		<custom-constant-dim constant-name-ref="MODULE_STATUS_SIZE"/>
+                		
+                	</custom-type-array>
+                </GSI-module-status-field>
+                <GSI-acquisition-context-field multiplexed="true" name="acquisitionContext">
+                    <custom-type-scalar data-type-name-ref="GSI_ACQ_CONTEXT"/>
+                </GSI-acquisition-context-field>
+                <GSI-error_collection-field multiplexed="false" name="error_collection">
+                    <custom-type-array data-type-name-ref="GSI_ERROR">
+                        <custom-constant-dim constant-name-ref="MAX_NUMBER_OF_ERROR_MESSAGES"/>
+                    </custom-type-array>
+                </GSI-error_collection-field>
+            </acquisition>
+        </device-data>
+        <global-data>
+            <configuration>
+                <!-- The name of the timing receiver -->
+                <field name="plcClassVersion"><description>Version of the SILECS class that needs to be deployed in the controller</description><array type="char"><dim>5</dim></array><default>0.1.0</default></field><GSI-timing-receiver-name-field name="deviceNameTimingReceiver">
+                    <array type="char">
+                        <!-- The number of the timing receiver -->
+                        <variable-dim/>
+                    </array>
+                </GSI-timing-receiver-name-field>
+                </configuration>
+        </global-data>
+    </data>
+    <actions>
+        <set-server-action implementation="default" name="InitSetAction"/>
+        <set-server-action implementation="default" name="ResetSetAction"/>
+        <set-server-action implementation="default" name="SettingSetAction"/>
+        <set-server-action implementation="default" name="PowerSetAction"/>
+        <get-server-action implementation="default" name="PowerGetAction"/>
+        <get-server-action implementation="default" name="SettingGetAction"/>
+        <get-server-action implementation="default" name="AcquisitionGetAction"/>
+        <get-server-action implementation="default" name="StatusGetAction"/>
+        <get-server-action implementation="default" name="VersionGetAction"/><get-server-action implementation="default" name="ModuleStatusGetAction"/>
+    <get-server-action name="GetMyROBlock" implementation="default"/><rt-action name="RecvMyROBlock"><notified-property property-name-ref="MyROBlock" automatic="true"/></rt-action><set-server-action name="SendMyRWBlock" implementation="custom"/><get-server-action name="RecvMyRWBlock" implementation="custom"/><set-server-action name="SendMyWOBlock" implementation="custom"/><get-server-action name="GetMyWOBlock" implementation="default"/></actions>
+
+<events><sources><timing-event-source name="Timing"/><timer-event-source name="Timer"/></sources><logical-events><logical-event name="RecvMyROBlockEvent" use="required" type="timer"/></logical-events></events><scheduling-units><scheduling-unit name="RecvMyROBlockUnit"><rt-action-ref rt-action-name-ref="RecvMyROBlock"/><logical-event-ref logical-event-name-ref="RecvMyROBlockEvent"/></scheduling-unit></scheduling-units></equipment-model>
diff --git a/silecs-codegen/src/xml/test/generated_temp/client/Beckhoff_BC9020.silecsparam b/silecs-codegen/src/xml/test/generated_temp/client/Beckhoff_BC9020.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..2d941be3ea443d277feb1128874b622249b44bf6
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/client/Beckhoff_BC9020.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-26 15:37:54.682340"/>
+    <Deployment checksum="2843029646"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Beckhoff_BC9020" plc-brand="BECKHOFF" plc-system="TWINCat" plc-model="BC9020" protocol="BLOCK_MODE" address="32768" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="32768" used-mem="MW16384..MW16407 / 24 words">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="32768" mem-size="48">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="17" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="18" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="22" mem-size="17" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="40" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="32816" used-mem="MW16408..MW18167 / 1760 words">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="32816" mem-size="122">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="2" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="6" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="12" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="65" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="86" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="94" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="96" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="98" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="100" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="104" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="106" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="110" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="114" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="33060" mem-size="468">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="4" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="24" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="40" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="56" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="72" mem-size="260" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="332" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="364" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="372" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="380" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="396" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="404" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="420" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="436" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="33996" mem-size="1170">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="10" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="60" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="100" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="140" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="180" mem-size="650" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="830" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="910" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="930" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="950" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="990" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1010" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1050" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1090" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="0"/>
+      <Instance label="testDevice2" address="1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_temp/client/Beckhoff_CX9020.silecsparam b/silecs-codegen/src/xml/test/generated_temp/client/Beckhoff_CX9020.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..8bfb82c95afa2b63fd3464a61303427ba968d217
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/client/Beckhoff_CX9020.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-26 15:37:54.700573"/>
+    <Deployment checksum="427563505"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Beckhoff_CX9020" plc-brand="BECKHOFF" plc-system="TWINCat" plc-model="CX9020" protocol="BLOCK_MODE" address="24576" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="24576" used-mem="MW12288..MW12313 / 26 words">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="24576" mem-size="52">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="17" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="20" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="24" mem-size="17" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="44" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="24628" used-mem="MW12314..MW14081 / 1768 words">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="24628" mem-size="128">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="2" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="6" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="12" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="65" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="88" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="96" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="98" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="100" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="104" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="108" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="112" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="116" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="120" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="24884" mem-size="468">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="4" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="24" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="40" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="56" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="72" mem-size="260" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="332" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="364" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="372" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="380" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="396" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="404" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="420" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="436" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="25820" mem-size="1172">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="10" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="60" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="100" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="140" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="180" mem-size="650" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="832" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="912" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="922" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="932" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="952" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="992" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1012" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1052" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1092" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="0"/>
+      <Instance label="testDevice2" address="1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_temp/client/Rabbit_BlockMode.silecsparam b/silecs-codegen/src/xml/test/generated_temp/client/Rabbit_BlockMode.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..fb5bbdca3093ba5c5c6787667f94310e527de88b
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/client/Rabbit_BlockMode.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-26 15:37:54.786452"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Rabbit_BlockMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="MW0..MW21 / 22 words">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="44">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="16" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="16" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="36" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" used-mem="MW22..MW1821 / 1800 words">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="44" mem-size="120">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="2" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="6" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="12" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="64" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="94" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="96" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="98" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="102" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="104" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="108" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="112" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="284" mem-size="480">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="24" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="32" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="48" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="64" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="80" mem-size="256" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="336" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="384" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="392" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="408" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="416" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="432" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="448" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="1244" mem-size="1200">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="60" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="80" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="120" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="160" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="200" mem-size="640" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="840" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="960" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="980" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1020" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1040" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1080" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1120" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="0"/>
+      <Instance label="testDevice2" address="1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_temp/client/Rabbit_DeviceMode.silecsparam b/silecs-codegen/src/xml/test/generated_temp/client/Rabbit_DeviceMode.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..0020f58f6b80f236fa915a23b63717b050b83465
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/client/Rabbit_DeviceMode.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-26 15:37:54.769333"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Rabbit_DeviceMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="DEVICE_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="MW0..MW21 / 22 words">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="44">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="16" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="16" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="36" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" used-mem="MW22..MW1821 / 1800 words">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="0" mem-size="120">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="2" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="6" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="12" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="64" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="94" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="96" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="98" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="102" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="104" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="108" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="112" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="120" mem-size="480">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="24" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="32" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="48" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="64" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="80" mem-size="256" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="336" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="384" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="392" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="408" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="416" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="432" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="448" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="600" mem-size="1200">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="60" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="80" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="120" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="160" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="200" mem-size="640" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="840" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="960" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="980" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1020" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1040" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1080" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1120" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="44"/>
+      <Instance label="testDevice2" address="1844"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_temp/client/Schneider_M340.silecsparam b/silecs-codegen/src/xml/test/generated_temp/client/Schneider_M340.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..eb924286b42b7b33b517985a96cb4639eb8455ae
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/client/Schneider_M340.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-26 15:37:54.747831"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Schneider_M340" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="M340" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="MW0..MW21 / 22 words">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="44">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="16" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="16" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="36" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" used-mem="MW22..MW1801 / 1780 words">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="44" mem-size="124">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="2" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="6" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="12" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="64" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="94" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="96" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="100" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="104" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="108" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="112" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="116" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="292" mem-size="472">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="12" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="20" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="28" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="44" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="60" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="76" mem-size="256" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="332" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="364" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="372" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="384" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="400" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="408" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="424" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="440" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="1236" mem-size="1184">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="20" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="30" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="50" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="72" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="112" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="152" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="192" mem-size="640" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="832" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="912" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="932" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="942" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="964" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1004" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1024" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1064" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1104" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="0"/>
+      <Instance label="testDevice2" address="1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_temp/client/Schneider_PremiumQuantum.silecsparam b/silecs-codegen/src/xml/test/generated_temp/client/Schneider_PremiumQuantum.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..6daa7f4d637496c963d8ff8d4f140b8c4f128e68
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/client/Schneider_PremiumQuantum.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-26 15:37:54.727642"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Schneider_PremiumQuantum" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="Premium" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="MW0..MW21 / 22 words">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="44">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="16" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="16" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="36" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" used-mem="MW22..MW1793 / 1772 words">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="44" mem-size="120">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="2" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="6" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="12" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="16" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="20" mem-size="64" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="94" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="96" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="98" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="102" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="104" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="108" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="112" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="284" mem-size="472">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="8" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="12" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="20" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="28" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="44" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="60" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="76" mem-size="256" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="332" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="364" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="372" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="384" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="400" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="408" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="424" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="440" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="1228" mem-size="1180">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="20" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="30" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="50" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="70" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="110" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="150" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="190" mem-size="640" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="830" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="910" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="930" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="960" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1000" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1020" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1060" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1100" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="0"/>
+      <Instance label="testDevice2" address="1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_temp/client/Siemens_Step7Block.silecsparam b/silecs-codegen/src/xml/test/generated_temp/client/Siemens_Step7Block.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..de281574cb2c530805118a33a3f4009894160b93
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/client/Siemens_Step7Block.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-26 15:37:54.623827"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Siemens_Step7Block" plc-brand="SIEMENS" plc-system="STEP-7" plc-model="SIMATIC_S7-300" protocol="DEVICE_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="DB0..DB0 / 48 bytes">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="48">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="18" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="18" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="22" mem-size="18" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="40" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" used-mem="DB1..DB2 / 3540 bytes">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="0" mem-size="118">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="1" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="2" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="6" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="10" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="14" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="18" mem-size="66" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="93" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="94" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="96" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="100" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="102" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="106" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="110" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="118" mem-size="472">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="4" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="24" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="40" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="56" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="72" mem-size="264" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="336" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="372" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="384" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="400" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="408" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="424" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="440" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="590" mem-size="1180">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="10" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="60" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="100" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="140" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="180" mem-size="660" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="840" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="930" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="960" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1000" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1020" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1060" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1100" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="1"/>
+      <Instance label="testDevice2" address="2"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_temp/client/Siemens_Step7Device.silecsparam b/silecs-codegen/src/xml/test/generated_temp/client/Siemens_Step7Device.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..4dd52a13de0dd05978859d11e152041b46b27688
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/client/Siemens_Step7Device.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-26 15:37:54.639689"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Siemens_Step7Device" plc-brand="SIEMENS" plc-system="STEP-7" plc-model="SIMATIC_S7-300" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="DB0..DB0 / 48 bytes">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="48">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="18" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="18" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="22" mem-size="18" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="40" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" used-mem="DB1..DB3 / 3540 bytes">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="1" mem-size="118">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="1" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="2" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="6" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="10" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="14" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="18" mem-size="66" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="93" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="94" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="96" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="100" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="102" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="106" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="110" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="2" mem-size="472">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="4" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="24" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="40" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="56" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="72" mem-size="264" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="336" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="372" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="384" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="400" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="408" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="424" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="440" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="3" mem-size="1180">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="10" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="60" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="100" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="140" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="180" mem-size="660" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="840" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="930" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="960" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1000" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1020" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1060" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1100" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="0"/>
+      <Instance label="testDevice2" address="1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_temp/client/Siemens_TiaBlock.silecsparam b/silecs-codegen/src/xml/test/generated_temp/client/Siemens_TiaBlock.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..2b261f366c3ed00bc0fe4346bac125a405052f6a
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/client/Siemens_TiaBlock.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-26 15:37:54.606556"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Siemens_TiaBlock" plc-brand="SIEMENS" plc-system="TIA-PORTAL" plc-model="SIMATIC_S7-300" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="DB0..DB0 / 48 bytes">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="48">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="18" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="18" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="22" mem-size="18" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="40" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" used-mem="DB1..DB3 / 3540 bytes">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="1" mem-size="118">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="1" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="2" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="6" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="10" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="14" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="18" mem-size="66" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="93" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="94" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="96" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="100" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="102" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="106" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="110" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="2" mem-size="472">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="4" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="24" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="40" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="56" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="72" mem-size="264" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="336" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="372" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="384" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="400" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="408" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="424" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="440" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="3" mem-size="1180">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="10" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="60" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="100" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="140" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="180" mem-size="660" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="840" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="930" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="960" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1000" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1020" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1060" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1100" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="0"/>
+      <Instance label="testDevice2" address="1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_temp/client/Siemens_TiaDevice.silecsparam b/silecs-codegen/src/xml/test/generated_temp/client/Siemens_TiaDevice.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..270a0f16c0a2a7fa439a99bfc4731979dbe84f5f
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/client/Siemens_TiaDevice.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-26 15:37:54.588418"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Siemens_TiaDevice" plc-brand="SIEMENS" plc-system="TIA-PORTAL" plc-model="SIMATIC_S7-300" protocol="DEVICE_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="DB0..DB0 / 48 bytes">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="48">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="18" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="18" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="22" mem-size="18" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="40" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" used-mem="DB1..DB2 / 3540 bytes">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="0" mem-size="118">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="1" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="2" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="6" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="10" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="14" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="18" mem-size="66" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="93" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="94" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="96" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="100" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="102" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="106" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="110" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="118" mem-size="472">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="4" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="24" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="40" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="56" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="72" mem-size="264" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="336" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="372" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="384" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="400" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="408" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="424" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="440" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="590" mem-size="1180">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="10" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="60" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="100" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="140" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="180" mem-size="660" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="840" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="930" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="960" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1000" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1020" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1060" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1100" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="1"/>
+      <Instance label="testDevice2" address="2"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_temp/client/Virtual_SiemensBlock.silecsparam b/silecs-codegen/src/xml/test/generated_temp/client/Virtual_SiemensBlock.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..27fc18410bde753fe1bf3ab4d48b6f67b13a780c
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/client/Virtual_SiemensBlock.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-26 15:37:54.665042"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Virtual_SiemensBlock" plc-brand="SIEMENS" plc-system="SNAP7 linux32" plc-model="SIMATIC_S7-VIRTUAL" protocol="BLOCK_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="DB0..DB0 / 48 bytes">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="48">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="18" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="18" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="22" mem-size="18" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="40" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" used-mem="DB1..DB3 / 3540 bytes">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="1" mem-size="118">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="1" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="2" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="6" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="10" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="14" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="18" mem-size="66" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="93" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="94" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="96" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="100" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="102" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="106" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="110" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="2" mem-size="472">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="4" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="24" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="40" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="56" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="72" mem-size="264" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="336" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="372" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="384" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="400" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="408" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="424" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="440" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="3" mem-size="1180">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="10" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="60" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="100" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="140" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="180" mem-size="660" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="840" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="930" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="960" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1000" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1020" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1060" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1100" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="0"/>
+      <Instance label="testDevice2" address="1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_temp/client/Virtual_SiemensDevice.silecsparam b/silecs-codegen/src/xml/test/generated_temp/client/Virtual_SiemensDevice.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..dcde87d911a7606314e4bf87b2506ed05e28da4f
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/client/Virtual_SiemensDevice.silecsparam
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2016-07-26 15:37:54.650596"/>
+    <Deployment checksum="3940683809"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Virtual_SiemensDevice" plc-brand="SIEMENS" plc-system="SNAP7 linux32" plc-model="SIMATIC_S7-VIRTUAL" protocol="DEVICE_MODE" address="0" domain="NotUsed" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" used-mem="DB0..DB0 / 48 bytes">
+      <Block name="hdrBlk" mode="READ-ONLY" size="14" address="0" mem-size="48">
+        <Register name="_version" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="18" synchro="MASTER"/>
+        <Register name="_checksum" format="uint32" array-dim1="1" array-dim2="1" size="4" address="18" mem-size="4" synchro="MASTER"/>
+        <Register name="_user" format="string" string-len="16" array-dim1="1" array-dim2="1" size="1" address="22" mem-size="18" synchro="MASTER"/>
+        <Register name="_date" format="dt" array-dim1="1" array-dim2="1" size="8" address="40" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" used-mem="DB1..DB2 / 3540 bytes">
+      <Block name="MyROBlock" mode="READ-ONLY" size="53" address="0" mem-size="118">
+        <Register name="RO_int8" format="int8" array-dim1="1" array-dim2="1" size="1" address="0" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_uint8" format="uint8" array-dim1="1" array-dim2="1" size="1" address="1" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_int16" format="int16" array-dim1="1" array-dim2="1" size="2" address="2" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_uint16" format="uint16" array-dim1="1" array-dim2="1" size="2" address="4" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_int32" format="int32" array-dim1="1" array-dim2="1" size="4" address="6" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_uint32" format="uint32" array-dim1="1" array-dim2="1" size="4" address="10" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_float32" format="float32" array-dim1="1" array-dim2="1" size="4" address="14" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_string" format="string" string-len="64" array-dim1="1" array-dim2="1" size="1" address="18" mem-size="66" synchro="MASTER"/>
+        <Register name="RO_date" format="date" array-dim1="1" array-dim2="1" size="8" address="84" mem-size="8" synchro="MASTER"/>
+        <Register name="RO_char" format="char" array-dim1="1" array-dim2="1" size="1" address="92" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_byte" format="byte" array-dim1="1" array-dim2="1" size="1" address="93" mem-size="1" synchro="MASTER"/>
+        <Register name="RO_word" format="word" array-dim1="1" array-dim2="1" size="2" address="94" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dword" format="dword" array-dim1="1" array-dim2="1" size="4" address="96" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_int" format="int" array-dim1="1" array-dim2="1" size="2" address="100" mem-size="2" synchro="MASTER"/>
+        <Register name="RO_dint" format="dint" array-dim1="1" array-dim2="1" size="4" address="102" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_real" format="real" array-dim1="1" array-dim2="1" size="4" address="106" mem-size="4" synchro="MASTER"/>
+        <Register name="RO_dt" format="dt" array-dim1="1" array-dim2="1" size="8" address="110" mem-size="8" synchro="MASTER"/>
+      </Block>
+      <Block name="MyRWBlock" mode="READ-WRITE" size="212" address="118" mem-size="472">
+        <Register name="RW_int8" format="int8" array-dim1="2" array-dim2="2" size="1" address="0" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_uint8" format="uint8" array-dim1="2" array-dim2="2" size="1" address="4" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_int16" format="int16" array-dim1="2" array-dim2="2" size="2" address="8" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_uint16" format="uint16" array-dim1="2" array-dim2="2" size="2" address="16" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_int32" format="int32" array-dim1="2" array-dim2="2" size="4" address="24" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_uint32" format="uint32" array-dim1="2" array-dim2="2" size="4" address="40" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_float32" format="float32" array-dim1="2" array-dim2="2" size="4" address="56" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_string" format="string" string-len="64" array-dim1="2" array-dim2="2" size="1" address="72" mem-size="264" synchro="MASTER"/>
+        <Register name="RW_date" format="date" array-dim1="2" array-dim2="2" size="8" address="336" mem-size="32" synchro="MASTER"/>
+        <Register name="RW_char" format="char" array-dim1="2" array-dim2="2" size="1" address="368" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_byte" format="byte" array-dim1="2" array-dim2="2" size="1" address="372" mem-size="4" synchro="MASTER"/>
+        <Register name="RW_word" format="word" array-dim1="2" array-dim2="2" size="2" address="376" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dword" format="dword" array-dim1="2" array-dim2="2" size="4" address="384" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_int" format="int" array-dim1="2" array-dim2="2" size="2" address="400" mem-size="8" synchro="MASTER"/>
+        <Register name="RW_dint" format="dint" array-dim1="2" array-dim2="2" size="4" address="408" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_real" format="real" array-dim1="2" array-dim2="2" size="4" address="424" mem-size="16" synchro="MASTER"/>
+        <Register name="RW_dt" format="dt" array-dim1="2" array-dim2="2" size="8" address="440" mem-size="32" synchro="MASTER"/>
+      </Block>
+      <Block name="MyWOBlock" mode="WRITE-ONLY" size="530" address="590" mem-size="1180">
+        <Register name="WO_int8" format="int8" array-dim1="10" array-dim2="1" size="1" address="0" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_uint8" format="uint8" array-dim1="10" array-dim2="1" size="1" address="10" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_int16" format="int16" array-dim1="10" array-dim2="1" size="2" address="20" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_uint16" format="uint16" array-dim1="10" array-dim2="1" size="2" address="40" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_int32" format="int32" array-dim1="10" array-dim2="1" size="4" address="60" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_uint32" format="uint32" array-dim1="10" array-dim2="1" size="4" address="100" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_float32" format="float32" array-dim1="10" array-dim2="1" size="4" address="140" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_string" format="string" string-len="64" array-dim1="10" array-dim2="1" size="1" address="180" mem-size="660" synchro="SLAVE"/>
+        <Register name="WO_date" format="date" array-dim1="10" array-dim2="1" size="8" address="840" mem-size="80" synchro="SLAVE"/>
+        <Register name="WO_char" format="char" array-dim1="10" array-dim2="1" size="1" address="920" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_byte" format="byte" array-dim1="10" array-dim2="1" size="1" address="930" mem-size="10" synchro="SLAVE"/>
+        <Register name="WO_word" format="word" array-dim1="10" array-dim2="1" size="2" address="940" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dword" format="dword" array-dim1="10" array-dim2="1" size="4" address="960" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_int" format="int" array-dim1="10" array-dim2="1" size="2" address="1000" mem-size="20" synchro="SLAVE"/>
+        <Register name="WO_dint" format="dint" array-dim1="10" array-dim2="1" size="4" address="1020" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_real" format="real" array-dim1="10" array-dim2="1" size="4" address="1060" mem-size="40" synchro="SLAVE"/>
+        <Register name="WO_dt" format="dt" array-dim1="10" array-dim2="1" size="8" address="1100" mem-size="80" synchro="SLAVE"/>
+      </Block>
+      <Instance label="testDevice1" address="1"/>
+      <Instance label="testDevice2" address="2"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Beckhoff_BC9020.exp b/silecs-codegen/src/xml/test/generated_temp/controller/Beckhoff_BC9020.exp
new file mode 100644
index 0000000000000000000000000000000000000000..e0e9f23991f95fb3db4c5eb00edc1fd07e91746d
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Beckhoff_BC9020.exp
@@ -0,0 +1,328 @@
+(* +-------------------------------------------------------------------
+* | C.E.R.N Geneva, Switzerland
+* | SILECS - BE/CO-FE
+* | April 2015
+* +-------------------------------------------------------------------
+*
+* Release : SILECS_DEV
+*)
+VAR_GLOBAL
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _version_a781_SilecsHeader AT %MW0: STRING(16):= DEV;
+
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _checksum_a781_SilecsHeader AT %MW9: DWORD:= 2843029646;
+
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _user_a781_SilecsHeader AT %MW11: STRING(16):= 'schwinn';
+
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _date_a781_SilecsHeader AT %MW20: DT:= DT#2016-7-26-15:37:54;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int8_a583_testDevice1 AT %MW24: SINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_uint8_a583_testDevice1 AT %MW25: BYTE;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int16_a583_testDevice1 AT %MW26: INT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_uint16_a583_testDevice1 AT %MW27: WORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int32_a583_testDevice1 AT %MW28: DINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_uint32_a583_testDevice1 AT %MW30: DWORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_float32_a583_testDevice1 AT %MW32: REAL;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_string_a583_testDevice1 AT %MW34: STRING(64);
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_date_a583_testDevice1 AT %MW67: DT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_char_a583_testDevice1 AT %MW71: SINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_byte_a583_testDevice1 AT %MW72: BYTE;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_word_a583_testDevice1 AT %MW73: WORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_dword_a583_testDevice1 AT %MW74: DWORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int_a583_testDevice1 AT %MW76: INT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_dint_a583_testDevice1 AT %MW77: DINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_real_a583_testDevice1 AT %MW79: REAL;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_dt_a583_testDevice1 AT %MW81: DT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int8_a583_testDevice2 AT %MW85: SINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_uint8_a583_testDevice2 AT %MW86: BYTE;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int16_a583_testDevice2 AT %MW87: INT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_uint16_a583_testDevice2 AT %MW88: WORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int32_a583_testDevice2 AT %MW89: DINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_uint32_a583_testDevice2 AT %MW91: DWORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_float32_a583_testDevice2 AT %MW93: REAL;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_string_a583_testDevice2 AT %MW95: STRING(64);
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_date_a583_testDevice2 AT %MW128: DT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_char_a583_testDevice2 AT %MW132: SINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_byte_a583_testDevice2 AT %MW133: BYTE;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_word_a583_testDevice2 AT %MW134: WORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_dword_a583_testDevice2 AT %MW135: DWORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int_a583_testDevice2 AT %MW137: INT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_dint_a583_testDevice2 AT %MW138: DINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_real_a583_testDevice2 AT %MW140: REAL;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_dt_a583_testDevice2 AT %MW142: DT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int8_a583_testDevice1 AT %MW146: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_uint8_a583_testDevice1 AT %MW148: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int16_a583_testDevice1 AT %MW150: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_uint16_a583_testDevice1 AT %MW154: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int32_a583_testDevice1 AT %MW158: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_uint32_a583_testDevice1 AT %MW166: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_float32_a583_testDevice1 AT %MW174: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_string_a583_testDevice1 AT %MW182: ARRAY [0..1, 0..1] OF STRING(64);
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_date_a583_testDevice1 AT %MW312: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_char_a583_testDevice1 AT %MW328: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_byte_a583_testDevice1 AT %MW330: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_word_a583_testDevice1 AT %MW332: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_dword_a583_testDevice1 AT %MW336: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int_a583_testDevice1 AT %MW344: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_dint_a583_testDevice1 AT %MW348: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_real_a583_testDevice1 AT %MW356: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_dt_a583_testDevice1 AT %MW364: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int8_a583_testDevice2 AT %MW380: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_uint8_a583_testDevice2 AT %MW382: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int16_a583_testDevice2 AT %MW384: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_uint16_a583_testDevice2 AT %MW388: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int32_a583_testDevice2 AT %MW392: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_uint32_a583_testDevice2 AT %MW400: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_float32_a583_testDevice2 AT %MW408: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_string_a583_testDevice2 AT %MW416: ARRAY [0..1, 0..1] OF STRING(64);
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_date_a583_testDevice2 AT %MW546: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_char_a583_testDevice2 AT %MW562: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_byte_a583_testDevice2 AT %MW564: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_word_a583_testDevice2 AT %MW566: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_dword_a583_testDevice2 AT %MW570: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int_a583_testDevice2 AT %MW578: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_dint_a583_testDevice2 AT %MW582: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_real_a583_testDevice2 AT %MW590: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_dt_a583_testDevice2 AT %MW598: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int8_a583_testDevice1 AT %MW614: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_uint8_a583_testDevice1 AT %MW619: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int16_a583_testDevice1 AT %MW624: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_uint16_a583_testDevice1 AT %MW634: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int32_a583_testDevice1 AT %MW644: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_uint32_a583_testDevice1 AT %MW664: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_float32_a583_testDevice1 AT %MW684: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_string_a583_testDevice1 AT %MW704: ARRAY [0..9] OF STRING(64);
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_date_a583_testDevice1 AT %MW1029: ARRAY [0..9] OF DT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_char_a583_testDevice1 AT %MW1069: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_byte_a583_testDevice1 AT %MW1074: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_word_a583_testDevice1 AT %MW1079: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_dword_a583_testDevice1 AT %MW1089: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int_a583_testDevice1 AT %MW1109: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_dint_a583_testDevice1 AT %MW1119: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_real_a583_testDevice1 AT %MW1139: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_dt_a583_testDevice1 AT %MW1159: ARRAY [0..9] OF DT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int8_a583_testDevice2 AT %MW1199: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_uint8_a583_testDevice2 AT %MW1204: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int16_a583_testDevice2 AT %MW1209: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_uint16_a583_testDevice2 AT %MW1219: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int32_a583_testDevice2 AT %MW1229: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_uint32_a583_testDevice2 AT %MW1249: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_float32_a583_testDevice2 AT %MW1269: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_string_a583_testDevice2 AT %MW1289: ARRAY [0..9] OF STRING(64);
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_date_a583_testDevice2 AT %MW1614: ARRAY [0..9] OF DT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_char_a583_testDevice2 AT %MW1654: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_byte_a583_testDevice2 AT %MW1659: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_word_a583_testDevice2 AT %MW1664: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_dword_a583_testDevice2 AT %MW1674: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int_a583_testDevice2 AT %MW1694: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_dint_a583_testDevice2 AT %MW1704: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_real_a583_testDevice2 AT %MW1724: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_dt_a583_testDevice2 AT %MW1744: ARRAY [0..9] OF DT;
+
+END_VAR
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Beckhoff_CX9020.exp b/silecs-codegen/src/xml/test/generated_temp/controller/Beckhoff_CX9020.exp
new file mode 100644
index 0000000000000000000000000000000000000000..6dcf462f8c97abf947e938cd219a68b2df66a444
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Beckhoff_CX9020.exp
@@ -0,0 +1,328 @@
+(* +-------------------------------------------------------------------
+* | C.E.R.N Geneva, Switzerland
+* | SILECS - BE/CO-FE
+* | April 2015
+* +-------------------------------------------------------------------
+*
+* Release : SILECS_DEV
+*)
+VAR_GLOBAL
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _version_a781_SilecsHeader AT %MW0: STRING(16):= DEV;
+
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _checksum_a781_SilecsHeader AT %MW20: DWORD:= 427563505;
+
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _user_a781_SilecsHeader AT %MW24: STRING(16):= 'schwinn';
+
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _date_a781_SilecsHeader AT %MW44: DT:= DT#2016-7-26-15:37:54;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int8_a583_testDevice1 AT %MW52: SINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_uint8_a583_testDevice1 AT %MW54: BYTE;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int16_a583_testDevice1 AT %MW56: INT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_uint16_a583_testDevice1 AT %MW58: WORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int32_a583_testDevice1 AT %MW60: DINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_uint32_a583_testDevice1 AT %MW64: DWORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_float32_a583_testDevice1 AT %MW68: REAL;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_string_a583_testDevice1 AT %MW72: STRING(64);
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_date_a583_testDevice1 AT %MW140: DT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_char_a583_testDevice1 AT %MW148: SINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_byte_a583_testDevice1 AT %MW150: BYTE;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_word_a583_testDevice1 AT %MW152: WORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_dword_a583_testDevice1 AT %MW156: DWORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int_a583_testDevice1 AT %MW160: INT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_dint_a583_testDevice1 AT %MW164: DINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_real_a583_testDevice1 AT %MW168: REAL;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_dt_a583_testDevice1 AT %MW172: DT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int8_a583_testDevice2 AT %MW180: SINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_uint8_a583_testDevice2 AT %MW182: BYTE;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int16_a583_testDevice2 AT %MW184: INT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_uint16_a583_testDevice2 AT %MW186: WORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int32_a583_testDevice2 AT %MW188: DINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_uint32_a583_testDevice2 AT %MW192: DWORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_float32_a583_testDevice2 AT %MW196: REAL;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_string_a583_testDevice2 AT %MW200: STRING(64);
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_date_a583_testDevice2 AT %MW268: DT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_char_a583_testDevice2 AT %MW276: SINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_byte_a583_testDevice2 AT %MW278: BYTE;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_word_a583_testDevice2 AT %MW280: WORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_dword_a583_testDevice2 AT %MW284: DWORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int_a583_testDevice2 AT %MW288: INT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_dint_a583_testDevice2 AT %MW292: DINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_real_a583_testDevice2 AT %MW296: REAL;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_dt_a583_testDevice2 AT %MW300: DT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int8_a583_testDevice1 AT %MW308: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_uint8_a583_testDevice1 AT %MW312: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int16_a583_testDevice1 AT %MW316: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_uint16_a583_testDevice1 AT %MW324: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int32_a583_testDevice1 AT %MW332: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_uint32_a583_testDevice1 AT %MW348: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_float32_a583_testDevice1 AT %MW364: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_string_a583_testDevice1 AT %MW380: ARRAY [0..1, 0..1] OF STRING(64);
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_date_a583_testDevice1 AT %MW640: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_char_a583_testDevice1 AT %MW672: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_byte_a583_testDevice1 AT %MW676: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_word_a583_testDevice1 AT %MW680: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_dword_a583_testDevice1 AT %MW688: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int_a583_testDevice1 AT %MW704: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_dint_a583_testDevice1 AT %MW712: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_real_a583_testDevice1 AT %MW728: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_dt_a583_testDevice1 AT %MW744: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int8_a583_testDevice2 AT %MW776: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_uint8_a583_testDevice2 AT %MW780: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int16_a583_testDevice2 AT %MW784: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_uint16_a583_testDevice2 AT %MW792: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int32_a583_testDevice2 AT %MW800: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_uint32_a583_testDevice2 AT %MW816: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_float32_a583_testDevice2 AT %MW832: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_string_a583_testDevice2 AT %MW848: ARRAY [0..1, 0..1] OF STRING(64);
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_date_a583_testDevice2 AT %MW1108: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_char_a583_testDevice2 AT %MW1140: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_byte_a583_testDevice2 AT %MW1144: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_word_a583_testDevice2 AT %MW1148: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_dword_a583_testDevice2 AT %MW1156: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int_a583_testDevice2 AT %MW1172: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_dint_a583_testDevice2 AT %MW1180: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_real_a583_testDevice2 AT %MW1196: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_dt_a583_testDevice2 AT %MW1212: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int8_a583_testDevice1 AT %MW1244: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_uint8_a583_testDevice1 AT %MW1254: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int16_a583_testDevice1 AT %MW1264: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_uint16_a583_testDevice1 AT %MW1284: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int32_a583_testDevice1 AT %MW1304: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_uint32_a583_testDevice1 AT %MW1344: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_float32_a583_testDevice1 AT %MW1384: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_string_a583_testDevice1 AT %MW1424: ARRAY [0..9] OF STRING(64);
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_date_a583_testDevice1 AT %MW2076: ARRAY [0..9] OF DT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_char_a583_testDevice1 AT %MW2156: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_byte_a583_testDevice1 AT %MW2166: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_word_a583_testDevice1 AT %MW2176: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_dword_a583_testDevice1 AT %MW2196: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int_a583_testDevice1 AT %MW2236: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_dint_a583_testDevice1 AT %MW2256: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_real_a583_testDevice1 AT %MW2296: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_dt_a583_testDevice1 AT %MW2336: ARRAY [0..9] OF DT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int8_a583_testDevice2 AT %MW2416: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_uint8_a583_testDevice2 AT %MW2426: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int16_a583_testDevice2 AT %MW2436: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_uint16_a583_testDevice2 AT %MW2456: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int32_a583_testDevice2 AT %MW2476: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_uint32_a583_testDevice2 AT %MW2516: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_float32_a583_testDevice2 AT %MW2556: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_string_a583_testDevice2 AT %MW2596: ARRAY [0..9] OF STRING(64);
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_date_a583_testDevice2 AT %MW3248: ARRAY [0..9] OF DT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_char_a583_testDevice2 AT %MW3328: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_byte_a583_testDevice2 AT %MW3338: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_word_a583_testDevice2 AT %MW3348: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_dword_a583_testDevice2 AT %MW3368: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int_a583_testDevice2 AT %MW3408: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_dint_a583_testDevice2 AT %MW3428: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_real_a583_testDevice2 AT %MW3468: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_dt_a583_testDevice2 AT %MW3508: ARRAY [0..9] OF DT;
+
+END_VAR
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Rabbit_BlockMode.h b/silecs-codegen/src/xml/test/generated_temp/controller/Rabbit_BlockMode.h
new file mode 100644
index 0000000000000000000000000000000000000000..f45622af778416dfea9deb7f158869f600c232b5
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Rabbit_BlockMode.h
@@ -0,0 +1,202 @@
+
+/* +-------------------------------------------------------------------
+ * | Copyright CERN 2015
+ * | SILECS - BE/CO-SRC
+ * | April 2015
+ * +-------------------------------------------------------------------
+ *
+ * Release : SILECS_DEV
+ *
+ * The following code has been automatically generated by SILECS.
+ *
+ * N.B: This file relies on the existence of explicit C data type such
+ * as int8_t, uint8_t, int16_t, etc....
+ * If your compiler does not support them natively please implement 
+ * them by including the data type definition provided on the SILECS
+ * web page before including this header file.
+ */
+
+#define MODBUS_START_ADDRESS 0
+
+/*---------------------------------------------------------------------
+ * DT 
+ * data type definition and related utilities
+ *---------------------------------------------------------------------
+ */
+
+typedef struct
+{
+	uint8_t sc_100;     // second cent
+	uint8_t sc;			// second
+	uint8_t mn;         // minute
+	uint8_t hh;         // hour
+	uint8_t dd;         // day
+	uint8_t mm;         // month
+	uint8_t yy1;        // year
+	uint8_t yy2;        // year2
+} dt;
+
+#define _frombcd(a) (int)(((a>>4)*10)+(a&0x0F))
+#define _tobcd(a)   (((unsigned char)((a)/10)<<4)+((a)%10))
+
+void SILECS_set_dt(int8_t sc_100 ,int8_t sc, int8_t mn,int8_t hh,int8_t dd,int8_t mm,int32_t yy, dt *date)
+{
+	date->sc_100 = sc_100;
+	date->sc     = _tobcd(sc);
+	date->mn     = _tobcd(mn);
+	date->hh     = _tobcd(hh);
+	date->dd     = _tobcd(dd);
+	date->mm     = _tobcd(mm);
+	date->yy2    = _tobcd((int8_t)(yy/100));
+	date->yy1    = _tobcd((int8_t)(yy%100));
+}
+
+
+/*---------------------------------------------------------------------
+ * SilecsHeader / v1.0.0
+ * BLOCK Type definition
+ *---------------------------------------------------------------------
+ */
+
+typedef struct 
+{
+    uint8_t _version[16];
+    uint32_t _checksum;
+    uint8_t _user[16];
+    dt _date;
+
+} _SilecsHeader_hdrBlk;
+
+/*---------------------------------------------------------------------
+ * AllTypes / v0.1.0
+ * BLOCK Type definition
+ *---------------------------------------------------------------------
+ */
+
+typedef struct 
+{
+    int16_t RO_int8;
+    uint16_t RO_uint8;
+    int16_t RO_int16;
+    uint16_t RO_uint16;
+    int32_t RO_int32;
+    uint32_t RO_uint32;
+    float RO_float32;
+    uint8_t RO_string[64];
+    dt RO_date;
+    int16_t RO_char;
+    uint16_t RO_byte;
+    uint16_t RO_word;
+    uint32_t RO_dword;
+    int16_t RO_int;
+    int32_t RO_dint;
+    float RO_real;
+    dt RO_dt;
+
+} _AllTypes_MyROBlock;
+
+typedef struct 
+{
+    int16_t RW_int8[2][2];
+    uint16_t RW_uint8[2][2];
+    int16_t RW_int16[2][2];
+    uint16_t RW_uint16[2][2];
+    int32_t RW_int32[2][2];
+    uint32_t RW_uint32[2][2];
+    float RW_float32[2][2];
+    uint8_t RW_string[2][2][64];
+    dt RW_date[2][2];
+    int16_t RW_char[2][2];
+    uint16_t RW_byte[2][2];
+    uint16_t RW_word[2][2];
+    uint32_t RW_dword[2][2];
+    int16_t RW_int[2][2];
+    int32_t RW_dint[2][2];
+    float RW_real[2][2];
+    dt RW_dt[2][2];
+
+} _AllTypes_MyRWBlock;
+
+typedef struct 
+{
+    int16_t WO_int8[10];
+    uint16_t WO_uint8[10];
+    int16_t WO_int16[10];
+    uint16_t WO_uint16[10];
+    int32_t WO_int32[10];
+    uint32_t WO_uint32[10];
+    float WO_float32[10];
+    uint8_t WO_string[10][64];
+    dt WO_date[10];
+    int16_t WO_char[10];
+    uint16_t WO_byte[10];
+    uint16_t WO_word[10];
+    uint32_t WO_dword[10];
+    int16_t WO_int[10];
+    int32_t WO_dint[10];
+    float WO_real[10];
+    dt WO_dt[10];
+
+} _AllTypes_MyWOBlock;
+
+/*---------------------------------------------------------------------
+ * MEMORY ALLOCATION
+ * PROTOCOL: BLOCK_MODE
+ *---------------------------------------------------------------------
+ */
+
+typedef struct {
+    
+    struct {
+        _SilecsHeader_hdrBlk SilecsHeader;
+    } SilecsHeader_hdrBlk;
+
+    struct {
+        _AllTypes_MyROBlock testDevice1;
+        _AllTypes_MyROBlock testDevice2;
+    } AllTypes_MyROBlock;
+
+    struct {
+        _AllTypes_MyRWBlock testDevice1;
+        _AllTypes_MyRWBlock testDevice2;
+    } AllTypes_MyRWBlock;
+
+    struct {
+        _AllTypes_MyWOBlock testDevice1;
+        _AllTypes_MyWOBlock testDevice2;
+    } AllTypes_MyWOBlock;
+
+} _SILECS_DATA_SEGMENT;
+
+#define SILECS_DATA_SEGMENT_MODBUS_SIZE (sizeof(_SILECS_DATA_SEGMENT)/2)
+
+union modbus_data {
+    _SILECS_DATA_SEGMENT data;
+    uint16_t array[SILECS_DATA_SEGMENT_MODBUS_SIZE];
+} silecsData;
+
+
+/* Initialization function */
+int SILECS_init()
+{
+	/* Silecs version initialization */
+	strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._version, "SILECS_DEV");
+	
+	/* Silecs checksum initialization */
+	silecsData.data.SilecsHeader_hdrBlk.device[0]._checksum  = 3940683809;
+	
+	/* Silecs user initialization */
+	strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._user, "schwinn");
+	
+	/* Silecs date initialization */
+	SILECS_set_dt(1,54,37,15,26,7,2016,&silecsData.data.SilecsHeader_hdrBlk.device[0]._date);
+}
+
+/*
+ * Automatically generated Addressing example
+ *
+ * This example shows how to address the register WO_dt of block MyWOBlock
+ * of device testDevice2 of the class AllTypes
+ *
+ *  silecsData.AllTypes_MyWOBlock.testDevice2.WO_dt = ....;
+ */
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Rabbit_DeviceMode.h b/silecs-codegen/src/xml/test/generated_temp/controller/Rabbit_DeviceMode.h
new file mode 100644
index 0000000000000000000000000000000000000000..01e46be42d66c515e0a47928425e68399a41505b
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Rabbit_DeviceMode.h
@@ -0,0 +1,195 @@
+
+/* +-------------------------------------------------------------------
+ * | Copyright CERN 2015
+ * | SILECS - BE/CO-SRC
+ * | April 2015
+ * +-------------------------------------------------------------------
+ *
+ * Release : SILECS_DEV
+ *
+ * The following code has been automatically generated by SILECS.
+ *
+ * N.B: This file relies on the existence of explicit C data type such
+ * as int8_t, uint8_t, int16_t, etc....
+ * If your compiler does not support them natively please implement 
+ * them by including the data type definition provided on the SILECS
+ * web page before including this header file.
+ */
+
+#define MODBUS_START_ADDRESS 0
+
+/*---------------------------------------------------------------------
+ * DT 
+ * data type definition and related utilities
+ *---------------------------------------------------------------------
+ */
+
+typedef struct
+{
+	uint8_t sc_100;     // second cent
+	uint8_t sc;			// second
+	uint8_t mn;         // minute
+	uint8_t hh;         // hour
+	uint8_t dd;         // day
+	uint8_t mm;         // month
+	uint8_t yy1;        // year
+	uint8_t yy2;        // year2
+} dt;
+
+#define _frombcd(a) (int)(((a>>4)*10)+(a&0x0F))
+#define _tobcd(a)   (((unsigned char)((a)/10)<<4)+((a)%10))
+
+void SILECS_set_dt(int8_t sc_100 ,int8_t sc, int8_t mn,int8_t hh,int8_t dd,int8_t mm,int32_t yy, dt *date)
+{
+	date->sc_100 = sc_100;
+	date->sc     = _tobcd(sc);
+	date->mn     = _tobcd(mn);
+	date->hh     = _tobcd(hh);
+	date->dd     = _tobcd(dd);
+	date->mm     = _tobcd(mm);
+	date->yy2    = _tobcd((int8_t)(yy/100));
+	date->yy1    = _tobcd((int8_t)(yy%100));
+}
+
+
+/*---------------------------------------------------------------------
+ * SilecsHeader / v1.0.0
+ * BLOCK Type definition
+ *---------------------------------------------------------------------
+ */
+
+typedef struct 
+{
+    uint8_t _version[16];
+    uint32_t _checksum;
+    uint8_t _user[16];
+    dt _date;
+
+} _SilecsHeader_hdrBlk;
+
+/*---------------------------------------------------------------------
+ * AllTypes / v0.1.0
+ * BLOCK Type definition
+ *---------------------------------------------------------------------
+ */
+
+typedef struct 
+{
+    int16_t RO_int8;
+    uint16_t RO_uint8;
+    int16_t RO_int16;
+    uint16_t RO_uint16;
+    int32_t RO_int32;
+    uint32_t RO_uint32;
+    float RO_float32;
+    uint8_t RO_string[64];
+    dt RO_date;
+    int16_t RO_char;
+    uint16_t RO_byte;
+    uint16_t RO_word;
+    uint32_t RO_dword;
+    int16_t RO_int;
+    int32_t RO_dint;
+    float RO_real;
+    dt RO_dt;
+
+} _AllTypes_MyROBlock;
+
+typedef struct 
+{
+    int16_t RW_int8[2][2];
+    uint16_t RW_uint8[2][2];
+    int16_t RW_int16[2][2];
+    uint16_t RW_uint16[2][2];
+    int32_t RW_int32[2][2];
+    uint32_t RW_uint32[2][2];
+    float RW_float32[2][2];
+    uint8_t RW_string[2][2][64];
+    dt RW_date[2][2];
+    int16_t RW_char[2][2];
+    uint16_t RW_byte[2][2];
+    uint16_t RW_word[2][2];
+    uint32_t RW_dword[2][2];
+    int16_t RW_int[2][2];
+    int32_t RW_dint[2][2];
+    float RW_real[2][2];
+    dt RW_dt[2][2];
+
+} _AllTypes_MyRWBlock;
+
+typedef struct 
+{
+    int16_t WO_int8[10];
+    uint16_t WO_uint8[10];
+    int16_t WO_int16[10];
+    uint16_t WO_uint16[10];
+    int32_t WO_int32[10];
+    uint32_t WO_uint32[10];
+    float WO_float32[10];
+    uint8_t WO_string[10][64];
+    dt WO_date[10];
+    int16_t WO_char[10];
+    uint16_t WO_byte[10];
+    uint16_t WO_word[10];
+    uint32_t WO_dword[10];
+    int16_t WO_int[10];
+    int32_t WO_dint[10];
+    float WO_real[10];
+    dt WO_dt[10];
+
+} _AllTypes_MyWOBlock;
+
+/*---------------------------------------------------------------------
+ * MEMORY ALLOCATION
+ * PROTOCOL: DEVICE_MODE
+ *---------------------------------------------------------------------
+ */
+
+typedef struct {
+    
+    struct {
+        _SilecsHeader_hdrBlk hdrBlk;
+
+    } SilecsHeader_SilecsHeader;
+
+    struct {
+        _AllTypes_MyROBlock MyROBlock;
+        _AllTypes_MyRWBlock MyRWBlock;
+        _AllTypes_MyWOBlock MyWOBlock;
+
+    } AllTypes_testDevice1, AllTypes_testDevice2;
+
+} _SILECS_DATA_SEGMENT;
+
+#define SILECS_DATA_SEGMENT_MODBUS_SIZE (sizeof(_SILECS_DATA_SEGMENT)/2)
+
+union silecsData {
+    _SILECS_DATA_SEGMENT data;
+    uint16_t array[SILECS_DATA_SEGMENT_MODBUS_SIZE];
+} silecsData;
+
+
+/* Initialization function */
+int SILECS_init()
+{
+	/* Silecs version initialization */
+	strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._version, "SILECS_DEV");
+	
+	/* Silecs checksum initialization */
+	silecsData.data.SilecsHeader_device[0].hdrBlk._checksum  = 3940683809;
+	
+	/* Silecs user initialization */
+	strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._user, "schwinn");
+	
+	/* Silecs date initialization */
+	SILECS_set_dt(1,54,37,15,26,7,2016,&silecsData.data.SilecsHeader_device[0].hdrBlk._date);
+}
+
+/*
+ * Automatically generated Addressing example
+ *
+ * This example shows how to address the register WO_dt of block MyWOBlock
+ * of device AllTypes_testDevice2 of the class AllTypes
+ * 
+ *  silecsData.AllTypes_AllTypes_testDevice2.MyWOBlock.WO_dt = ....;
+ */
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Schneider_M340.xsy b/silecs-codegen/src/xml/test/generated_temp/controller/Schneider_M340.xsy
new file mode 100644
index 0000000000000000000000000000000000000000..8bfb3e8ae9a530aa62dfba387a3d1a960b70fca7
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Schneider_M340.xsy
@@ -0,0 +1,326 @@
+<VariablesExchangeFile>
+  <dataBlock>
+    <variables name="_version_a781_SilecsHeader" typeName="STRING[16]" topologicalAddress="%MW0">
+      <variableInit value="DEV"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="_checksum_a781_SilecsHeader" typeName="DWORD" topologicalAddress="%MW8">
+      <variableInit value="3940683809"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="_user_a781_SilecsHeader" typeName="STRING[16]" topologicalAddress="%MW10">
+      <variableInit value="schwinn"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="_date_a781_SilecsHeader" typeName="DT" topologicalAddress="%MW18">
+      <variableInit value="DT#2016-7-26-15:37:54"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="RO_int8_a583_testDevice1" typeName="WORD" topologicalAddress="%MW22">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint8_a583_testDevice1" typeName="BYTE" topologicalAddress="%MW23">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int16_a583_testDevice1" typeName="INT" topologicalAddress="%MW24">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint16_a583_testDevice1" typeName="WORD" topologicalAddress="%MW25">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int32_a583_testDevice1" typeName="DINT" topologicalAddress="%MW26">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint32_a583_testDevice1" typeName="DWORD" topologicalAddress="%MW28">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_float32_a583_testDevice1" typeName="REAL" topologicalAddress="%MW30">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_string_a583_testDevice1" typeName="STRING[64]" topologicalAddress="%MW32">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_date_a583_testDevice1" typeName="DT" topologicalAddress="%MW64">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_char_a583_testDevice1" typeName="WORD" topologicalAddress="%MW68">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_byte_a583_testDevice1" typeName="BYTE" topologicalAddress="%MW69">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_word_a583_testDevice1" typeName="WORD" topologicalAddress="%MW70">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dword_a583_testDevice1" typeName="DWORD" topologicalAddress="%MW72">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int_a583_testDevice1" typeName="INT" topologicalAddress="%MW74">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dint_a583_testDevice1" typeName="DINT" topologicalAddress="%MW76">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_real_a583_testDevice1" typeName="REAL" topologicalAddress="%MW78">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dt_a583_testDevice1" typeName="DT" topologicalAddress="%MW80">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int8_a583_testDevice2" typeName="WORD" topologicalAddress="%MW84">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint8_a583_testDevice2" typeName="BYTE" topologicalAddress="%MW85">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int16_a583_testDevice2" typeName="INT" topologicalAddress="%MW86">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint16_a583_testDevice2" typeName="WORD" topologicalAddress="%MW87">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int32_a583_testDevice2" typeName="DINT" topologicalAddress="%MW88">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint32_a583_testDevice2" typeName="DWORD" topologicalAddress="%MW90">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_float32_a583_testDevice2" typeName="REAL" topologicalAddress="%MW92">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_string_a583_testDevice2" typeName="STRING[64]" topologicalAddress="%MW94">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_date_a583_testDevice2" typeName="DT" topologicalAddress="%MW126">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_char_a583_testDevice2" typeName="WORD" topologicalAddress="%MW130">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_byte_a583_testDevice2" typeName="BYTE" topologicalAddress="%MW131">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_word_a583_testDevice2" typeName="WORD" topologicalAddress="%MW132">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dword_a583_testDevice2" typeName="DWORD" topologicalAddress="%MW134">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int_a583_testDevice2" typeName="INT" topologicalAddress="%MW136">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dint_a583_testDevice2" typeName="DINT" topologicalAddress="%MW138">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_real_a583_testDevice2" typeName="REAL" topologicalAddress="%MW140">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dt_a583_testDevice2" typeName="DT" topologicalAddress="%MW142">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RW_int8_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW146">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint8_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW150">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int16_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW152">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint16_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW156">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int32_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW160">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint32_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW168">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_float32_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW176">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_string_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF STRING[64]" topologicalAddress="%MW184">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_date_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW312">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_char_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW328">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_byte_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW332">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_word_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW334">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dword_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW338">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW346">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dint_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW350">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_real_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW358">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dt_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW366">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int8_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW382">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint8_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW386">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int16_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW388">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint16_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW392">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int32_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW396">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint32_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW404">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_float32_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW412">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_string_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF STRING[64]" topologicalAddress="%MW420">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_date_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW548">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_char_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW564">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_byte_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW568">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_word_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW570">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dword_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW574">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW582">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dint_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW586">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_real_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW594">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dt_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW602">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="WO_int8_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW618">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint8_a583_testDevice1" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW628">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int16_a583_testDevice1" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW633">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint16_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW643">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int32_a583_testDevice1" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW654">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint32_a583_testDevice1" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW674">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_float32_a583_testDevice1" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW694">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_string_a583_testDevice1" typeName="ARRAY[0..9] OF STRING[64]" topologicalAddress="%MW714">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_date_a583_testDevice1" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1034">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_char_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1074">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_byte_a583_testDevice1" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW1084">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_word_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1089">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dword_a583_testDevice1" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW1100">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int_a583_testDevice1" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW1120">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dint_a583_testDevice1" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW1130">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_real_a583_testDevice1" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW1150">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dt_a583_testDevice1" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1170">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int8_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1210">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint8_a583_testDevice2" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW1220">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int16_a583_testDevice2" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW1225">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint16_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1235">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int32_a583_testDevice2" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW1246">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint32_a583_testDevice2" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW1266">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_float32_a583_testDevice2" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW1286">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_string_a583_testDevice2" typeName="ARRAY[0..9] OF STRING[64]" topologicalAddress="%MW1306">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_date_a583_testDevice2" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1626">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_char_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1666">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_byte_a583_testDevice2" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW1676">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_word_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1681">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dword_a583_testDevice2" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW1692">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int_a583_testDevice2" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW1712">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dint_a583_testDevice2" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW1722">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_real_a583_testDevice2" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW1742">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dt_a583_testDevice2" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1762">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+  </dataBlock>
+</VariablesExchangeFile>
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Schneider_PremiumQuantum.xsy b/silecs-codegen/src/xml/test/generated_temp/controller/Schneider_PremiumQuantum.xsy
new file mode 100644
index 0000000000000000000000000000000000000000..fa28512f4050ee676a367a56ef1d3d6b33f0cfc3
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Schneider_PremiumQuantum.xsy
@@ -0,0 +1,326 @@
+<VariablesExchangeFile>
+  <dataBlock>
+    <variables name="_version_a781_SilecsHeader" typeName="STRING[16]" topologicalAddress="%MW0">
+      <variableInit value="DEV"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="_checksum_a781_SilecsHeader" typeName="DWORD" topologicalAddress="%MW8">
+      <variableInit value="3940683809"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="_user_a781_SilecsHeader" typeName="STRING[16]" topologicalAddress="%MW10">
+      <variableInit value="schwinn"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="_date_a781_SilecsHeader" typeName="DT" topologicalAddress="%MW18">
+      <variableInit value="DT#2016-7-26-15:37:54"/>
+      <comment>SilecsHeader/SilecsHeader/hdrBlk</comment>
+    </variables>
+    <variables name="RO_int8_a583_testDevice1" typeName="WORD" topologicalAddress="%MW22">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint8_a583_testDevice1" typeName="BYTE" topologicalAddress="%MW23">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int16_a583_testDevice1" typeName="INT" topologicalAddress="%MW24">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint16_a583_testDevice1" typeName="WORD" topologicalAddress="%MW25">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int32_a583_testDevice1" typeName="DINT" topologicalAddress="%MW26">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint32_a583_testDevice1" typeName="DWORD" topologicalAddress="%MW28">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_float32_a583_testDevice1" typeName="REAL" topologicalAddress="%MW30">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_string_a583_testDevice1" typeName="STRING[64]" topologicalAddress="%MW32">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_date_a583_testDevice1" typeName="DT" topologicalAddress="%MW64">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_char_a583_testDevice1" typeName="WORD" topologicalAddress="%MW68">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_byte_a583_testDevice1" typeName="BYTE" topologicalAddress="%MW69">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_word_a583_testDevice1" typeName="WORD" topologicalAddress="%MW70">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dword_a583_testDevice1" typeName="DWORD" topologicalAddress="%MW71">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int_a583_testDevice1" typeName="INT" topologicalAddress="%MW73">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dint_a583_testDevice1" typeName="DINT" topologicalAddress="%MW74">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_real_a583_testDevice1" typeName="REAL" topologicalAddress="%MW76">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dt_a583_testDevice1" typeName="DT" topologicalAddress="%MW78">
+      <comment>AllTypes/testDevice1/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int8_a583_testDevice2" typeName="WORD" topologicalAddress="%MW82">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint8_a583_testDevice2" typeName="BYTE" topologicalAddress="%MW83">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int16_a583_testDevice2" typeName="INT" topologicalAddress="%MW84">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint16_a583_testDevice2" typeName="WORD" topologicalAddress="%MW85">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int32_a583_testDevice2" typeName="DINT" topologicalAddress="%MW86">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_uint32_a583_testDevice2" typeName="DWORD" topologicalAddress="%MW88">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_float32_a583_testDevice2" typeName="REAL" topologicalAddress="%MW90">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_string_a583_testDevice2" typeName="STRING[64]" topologicalAddress="%MW92">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_date_a583_testDevice2" typeName="DT" topologicalAddress="%MW124">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_char_a583_testDevice2" typeName="WORD" topologicalAddress="%MW128">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_byte_a583_testDevice2" typeName="BYTE" topologicalAddress="%MW129">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_word_a583_testDevice2" typeName="WORD" topologicalAddress="%MW130">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dword_a583_testDevice2" typeName="DWORD" topologicalAddress="%MW131">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_int_a583_testDevice2" typeName="INT" topologicalAddress="%MW133">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dint_a583_testDevice2" typeName="DINT" topologicalAddress="%MW134">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_real_a583_testDevice2" typeName="REAL" topologicalAddress="%MW136">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RO_dt_a583_testDevice2" typeName="DT" topologicalAddress="%MW138">
+      <comment>AllTypes/testDevice2/MyROBlock</comment>
+    </variables>
+    <variables name="RW_int8_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW142">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint8_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW146">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int16_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW148">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint16_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW152">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int32_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW156">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint32_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW164">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_float32_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW172">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_string_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF STRING[64]" topologicalAddress="%MW180">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_date_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW308">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_char_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW324">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_byte_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW328">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_word_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW330">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dword_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW334">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW342">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dint_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW346">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_real_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW354">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dt_a583_testDevice1" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW362">
+      <comment>AllTypes/testDevice1/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int8_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW378">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint8_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW382">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int16_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW384">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint16_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW388">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int32_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW392">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_uint32_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW400">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_float32_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW408">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_string_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF STRING[64]" topologicalAddress="%MW416">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_date_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW544">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_char_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW560">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_byte_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF BYTE" topologicalAddress="%MW564">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_word_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF WORD" topologicalAddress="%MW566">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dword_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DWORD" topologicalAddress="%MW570">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_int_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF INT" topologicalAddress="%MW578">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dint_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DINT" topologicalAddress="%MW582">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_real_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF REAL" topologicalAddress="%MW590">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="RW_dt_a583_testDevice2" typeName="ARRAY[0..1, 0..1] OF DT" topologicalAddress="%MW598">
+      <comment>AllTypes/testDevice2/MyRWBlock</comment>
+    </variables>
+    <variables name="WO_int8_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW614">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint8_a583_testDevice1" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW624">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int16_a583_testDevice1" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW629">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint16_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW639">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int32_a583_testDevice1" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW649">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint32_a583_testDevice1" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW669">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_float32_a583_testDevice1" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW689">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_string_a583_testDevice1" typeName="ARRAY[0..9] OF STRING[64]" topologicalAddress="%MW709">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_date_a583_testDevice1" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1029">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_char_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1069">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_byte_a583_testDevice1" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW1079">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_word_a583_testDevice1" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1084">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dword_a583_testDevice1" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW1094">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int_a583_testDevice1" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW1114">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dint_a583_testDevice1" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW1124">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_real_a583_testDevice1" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW1144">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dt_a583_testDevice1" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1164">
+      <comment>AllTypes/testDevice1/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int8_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1204">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint8_a583_testDevice2" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW1214">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int16_a583_testDevice2" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW1219">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint16_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1229">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int32_a583_testDevice2" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW1239">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_uint32_a583_testDevice2" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW1259">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_float32_a583_testDevice2" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW1279">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_string_a583_testDevice2" typeName="ARRAY[0..9] OF STRING[64]" topologicalAddress="%MW1299">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_date_a583_testDevice2" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1619">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_char_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1659">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_byte_a583_testDevice2" typeName="ARRAY[0..9] OF BYTE" topologicalAddress="%MW1669">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_word_a583_testDevice2" typeName="ARRAY[0..9] OF WORD" topologicalAddress="%MW1674">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dword_a583_testDevice2" typeName="ARRAY[0..9] OF DWORD" topologicalAddress="%MW1684">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_int_a583_testDevice2" typeName="ARRAY[0..9] OF INT" topologicalAddress="%MW1704">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dint_a583_testDevice2" typeName="ARRAY[0..9] OF DINT" topologicalAddress="%MW1714">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_real_a583_testDevice2" typeName="ARRAY[0..9] OF REAL" topologicalAddress="%MW1734">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+    <variables name="WO_dt_a583_testDevice2" typeName="ARRAY[0..9] OF DT" topologicalAddress="%MW1754">
+      <comment>AllTypes/testDevice2/MyWOBlock</comment>
+    </variables>
+  </dataBlock>
+</VariablesExchangeFile>
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_Step7Block.scl b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_Step7Block.scl
new file mode 100644
index 0000000000000000000000000000000000000000..d3f7d1177203eba1f18ec74ef11a25626a747cb5
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_Step7Block.scl
@@ -0,0 +1,150 @@
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _SilecsHeader_hdrBlk
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        _version: STRING[16] := 'SILECS_DEV';
+        _checksum: DWORD := DW#16#eae21021;
+        _user: STRING[16] := 'schwinn';
+        _date: DT := DT#2016-7-26-15:37:54;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// Block instance definition
+//---------------------------------------------------------------------
+// SilecsHeader_SilecsHeader ...........................................
+DATA_BLOCK DB0
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      DEV_MODE
+STRUCT
+    hdrBlk: _SilecsHeader_hdrBlk;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _AllTypes_MyROBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RO_int8: CHAR;
+        RO_uint8: BYTE;
+        RO_int16: INT;
+        RO_uint16: WORD;
+        RO_int32: DINT;
+        RO_uint32: DWORD;
+        RO_float32: REAL;
+        RO_string: STRING[64];
+        RO_date: DT;
+        RO_char: CHAR;
+        RO_byte: BYTE;
+        RO_word: WORD;
+        RO_dword: DWORD;
+        RO_int: INT;
+        RO_dint: DINT;
+        RO_real: REAL;
+        RO_dt: DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyRWBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RW_int8: ARRAY[0..1, 0..1] OF CHAR;
+        RW_uint8: ARRAY[0..1, 0..1] OF BYTE;
+        RW_int16: ARRAY[0..1, 0..1] OF INT;
+        RW_uint16: ARRAY[0..1, 0..1] OF WORD;
+        RW_int32: ARRAY[0..1, 0..1] OF DINT;
+        RW_uint32: ARRAY[0..1, 0..1] OF DWORD;
+        RW_float32: ARRAY[0..1, 0..1] OF REAL;
+        RW_string: ARRAY[0..1, 0..1] OF STRING[64];
+        RW_date: ARRAY[0..1, 0..1] OF DT;
+        RW_char: ARRAY[0..1, 0..1] OF CHAR;
+        RW_byte: ARRAY[0..1, 0..1] OF BYTE;
+        RW_word: ARRAY[0..1, 0..1] OF WORD;
+        RW_dword: ARRAY[0..1, 0..1] OF DWORD;
+        RW_int: ARRAY[0..1, 0..1] OF INT;
+        RW_dint: ARRAY[0..1, 0..1] OF DINT;
+        RW_real: ARRAY[0..1, 0..1] OF REAL;
+        RW_dt: ARRAY[0..1, 0..1] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyWOBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        WO_int8: ARRAY[0..9] OF CHAR;
+        WO_uint8: ARRAY[0..9] OF BYTE;
+        WO_int16: ARRAY[0..9] OF INT;
+        WO_uint16: ARRAY[0..9] OF WORD;
+        WO_int32: ARRAY[0..9] OF DINT;
+        WO_uint32: ARRAY[0..9] OF DWORD;
+        WO_float32: ARRAY[0..9] OF REAL;
+        WO_string: ARRAY[0..9] OF STRING[64];
+        WO_date: ARRAY[0..9] OF DT;
+        WO_char: ARRAY[0..9] OF CHAR;
+        WO_byte: ARRAY[0..9] OF BYTE;
+        WO_word: ARRAY[0..9] OF WORD;
+        WO_dword: ARRAY[0..9] OF DWORD;
+        WO_int: ARRAY[0..9] OF INT;
+        WO_dint: ARRAY[0..9] OF DINT;
+        WO_real: ARRAY[0..9] OF REAL;
+        WO_dt: ARRAY[0..9] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// Block instance definition
+//---------------------------------------------------------------------
+// AllTypes_testDevice1 ...........................................
+DATA_BLOCK DB1
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      DEV_MODE
+STRUCT
+    MyROBlock: _AllTypes_MyROBlock;
+    MyRWBlock: _AllTypes_MyRWBlock;
+    MyWOBlock: _AllTypes_MyWOBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+// AllTypes_testDevice2 ...........................................
+DATA_BLOCK DB2
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      DEV_MODE
+STRUCT
+    MyROBlock: _AllTypes_MyROBlock;
+    MyRWBlock: _AllTypes_MyRWBlock;
+    MyWOBlock: _AllTypes_MyWOBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_Step7Block.sdf b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_Step7Block.sdf
new file mode 100644
index 0000000000000000000000000000000000000000..e5d2ddb66c2635a199c7f174cfbfd46beccb8ef8
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_Step7Block.sdf
@@ -0,0 +1,7 @@
+"_SilecsHeader_hdrBlk","UDT 0","UDT 0","[SilecsHeader/1.0.0] UDT symbol: _<class-name>_<block-name>"
+"SilecsHeader_SilecsHeader","DB 0","DB 0","[SilecsHeader/1.0.0] DB symbol: <class-name>_<device-label | device-id>"
+"_AllTypes_MyROBlock","UDT 1","UDT 1","[AllTypes/0.1.0] UDT symbol: _<class-name>_<block-name>"
+"_AllTypes_MyRWBlock","UDT 2","UDT 2",""
+"_AllTypes_MyWOBlock","UDT 3","UDT 3",""
+"AllTypes_testDevice1","DB 1","DB 1","[AllTypes/0.1.0] DB symbol: <class-name>_<device-label | device-id>"
+"AllTypes_testDevice2","DB 2","DB 2",""
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_Step7Device.scl b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_Step7Device.scl
new file mode 100644
index 0000000000000000000000000000000000000000..2023307de0c80d98bf276666bf8ffe0d304a2fc8
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_Step7Device.scl
@@ -0,0 +1,162 @@
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _SilecsHeader_hdrBlk
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        _version: STRING[16] := 'SILECS_DEV';
+        _checksum: DWORD := DW#16#eae21021;
+        _user: STRING[16] := 'schwinn';
+        _date: DT := DT#2016-7-26-15:37:54;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// Block instance definition
+//---------------------------------------------------------------------
+// SilecsHeader_hdrBlk ...........................................
+DATA_BLOCK DB0
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    SilecsHeader: _SilecsHeader_hdrBlk;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _AllTypes_MyROBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RO_int8: CHAR;
+        RO_uint8: BYTE;
+        RO_int16: INT;
+        RO_uint16: WORD;
+        RO_int32: DINT;
+        RO_uint32: DWORD;
+        RO_float32: REAL;
+        RO_string: STRING[64];
+        RO_date: DT;
+        RO_char: CHAR;
+        RO_byte: BYTE;
+        RO_word: WORD;
+        RO_dword: DWORD;
+        RO_int: INT;
+        RO_dint: DINT;
+        RO_real: REAL;
+        RO_dt: DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyRWBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RW_int8: ARRAY[0..1, 0..1] OF CHAR;
+        RW_uint8: ARRAY[0..1, 0..1] OF BYTE;
+        RW_int16: ARRAY[0..1, 0..1] OF INT;
+        RW_uint16: ARRAY[0..1, 0..1] OF WORD;
+        RW_int32: ARRAY[0..1, 0..1] OF DINT;
+        RW_uint32: ARRAY[0..1, 0..1] OF DWORD;
+        RW_float32: ARRAY[0..1, 0..1] OF REAL;
+        RW_string: ARRAY[0..1, 0..1] OF STRING[64];
+        RW_date: ARRAY[0..1, 0..1] OF DT;
+        RW_char: ARRAY[0..1, 0..1] OF CHAR;
+        RW_byte: ARRAY[0..1, 0..1] OF BYTE;
+        RW_word: ARRAY[0..1, 0..1] OF WORD;
+        RW_dword: ARRAY[0..1, 0..1] OF DWORD;
+        RW_int: ARRAY[0..1, 0..1] OF INT;
+        RW_dint: ARRAY[0..1, 0..1] OF DINT;
+        RW_real: ARRAY[0..1, 0..1] OF REAL;
+        RW_dt: ARRAY[0..1, 0..1] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyWOBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        WO_int8: ARRAY[0..9] OF CHAR;
+        WO_uint8: ARRAY[0..9] OF BYTE;
+        WO_int16: ARRAY[0..9] OF INT;
+        WO_uint16: ARRAY[0..9] OF WORD;
+        WO_int32: ARRAY[0..9] OF DINT;
+        WO_uint32: ARRAY[0..9] OF DWORD;
+        WO_float32: ARRAY[0..9] OF REAL;
+        WO_string: ARRAY[0..9] OF STRING[64];
+        WO_date: ARRAY[0..9] OF DT;
+        WO_char: ARRAY[0..9] OF CHAR;
+        WO_byte: ARRAY[0..9] OF BYTE;
+        WO_word: ARRAY[0..9] OF WORD;
+        WO_dword: ARRAY[0..9] OF DWORD;
+        WO_int: ARRAY[0..9] OF INT;
+        WO_dint: ARRAY[0..9] OF DINT;
+        WO_real: ARRAY[0..9] OF REAL;
+        WO_dt: ARRAY[0..9] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// Block instance definition
+//---------------------------------------------------------------------
+// AllTypes_MyROBlock ...........................................
+DATA_BLOCK DB1
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    testDevice1: _AllTypes_MyROBlock;
+    testDevice2: _AllTypes_MyROBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+// AllTypes_MyRWBlock ...........................................
+DATA_BLOCK DB2
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    testDevice1: _AllTypes_MyRWBlock;
+    testDevice2: _AllTypes_MyRWBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+// AllTypes_MyWOBlock ...........................................
+DATA_BLOCK DB3
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    testDevice1: _AllTypes_MyWOBlock;
+    testDevice2: _AllTypes_MyWOBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_Step7Device.sdf b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_Step7Device.sdf
new file mode 100644
index 0000000000000000000000000000000000000000..29a5f5851a5e2e6dea4c19a034b129e1333190e5
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_Step7Device.sdf
@@ -0,0 +1,8 @@
+"_SilecsHeader_hdrBlk","UDT 0","UDT 0","[SilecsHeader/1.0.0] UDT symbol: _<class-name>_<block-name>"
+"SilecsHeader_hdrBlk","DB 0","DB 0","[SilecsHeader/1.0.0] DB symbol: <class-name>_<block-name>"
+"_AllTypes_MyROBlock","UDT 1","UDT 1","[AllTypes/0.1.0] UDT symbol: _<class-name>_<block-name>"
+"_AllTypes_MyRWBlock","UDT 2","UDT 2",""
+"_AllTypes_MyWOBlock","UDT 3","UDT 3",""
+"AllTypes_MyROBlock","DB 1","DB 1","[AllTypes/0.1.0] DB symbol: <class-name>_<block-name>"
+"AllTypes_MyRWBlock","DB 2","DB 2",""
+"AllTypes_MyWOBlock","DB 3","DB 3",""
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_TiaBlock.scl b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_TiaBlock.scl
new file mode 100644
index 0000000000000000000000000000000000000000..8da2cd777658b103e08a49fc3a305bed22b95771
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_TiaBlock.scl
@@ -0,0 +1,158 @@
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _SilecsHeader_hdrBlk
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        _version: STRING[16] := 'SILECS_DEV';
+        _checksum: DWORD := DW#16#eae21021;
+        _user: STRING[16] := 'schwinn';
+        _date: DT := DT#2016-7-26-15:37:54;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// Block instance definition
+//---------------------------------------------------------------------
+DATA_BLOCK SilecsHeader_hdrBlk
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    SilecsHeader: _SilecsHeader_hdrBlk;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _AllTypes_MyROBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RO_int8: CHAR;
+        RO_uint8: BYTE;
+        RO_int16: INT;
+        RO_uint16: WORD;
+        RO_int32: DINT;
+        RO_uint32: DWORD;
+        RO_float32: REAL;
+        RO_string: STRING[64];
+        RO_date: DT;
+        RO_char: CHAR;
+        RO_byte: BYTE;
+        RO_word: WORD;
+        RO_dword: DWORD;
+        RO_int: INT;
+        RO_dint: DINT;
+        RO_real: REAL;
+        RO_dt: DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyRWBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RW_int8: ARRAY[0..1, 0..1] OF CHAR;
+        RW_uint8: ARRAY[0..1, 0..1] OF BYTE;
+        RW_int16: ARRAY[0..1, 0..1] OF INT;
+        RW_uint16: ARRAY[0..1, 0..1] OF WORD;
+        RW_int32: ARRAY[0..1, 0..1] OF DINT;
+        RW_uint32: ARRAY[0..1, 0..1] OF DWORD;
+        RW_float32: ARRAY[0..1, 0..1] OF REAL;
+        RW_string: ARRAY[0..1, 0..1] OF STRING[64];
+        RW_date: ARRAY[0..1, 0..1] OF DT;
+        RW_char: ARRAY[0..1, 0..1] OF CHAR;
+        RW_byte: ARRAY[0..1, 0..1] OF BYTE;
+        RW_word: ARRAY[0..1, 0..1] OF WORD;
+        RW_dword: ARRAY[0..1, 0..1] OF DWORD;
+        RW_int: ARRAY[0..1, 0..1] OF INT;
+        RW_dint: ARRAY[0..1, 0..1] OF DINT;
+        RW_real: ARRAY[0..1, 0..1] OF REAL;
+        RW_dt: ARRAY[0..1, 0..1] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyWOBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        WO_int8: ARRAY[0..9] OF CHAR;
+        WO_uint8: ARRAY[0..9] OF BYTE;
+        WO_int16: ARRAY[0..9] OF INT;
+        WO_uint16: ARRAY[0..9] OF WORD;
+        WO_int32: ARRAY[0..9] OF DINT;
+        WO_uint32: ARRAY[0..9] OF DWORD;
+        WO_float32: ARRAY[0..9] OF REAL;
+        WO_string: ARRAY[0..9] OF STRING[64];
+        WO_date: ARRAY[0..9] OF DT;
+        WO_char: ARRAY[0..9] OF CHAR;
+        WO_byte: ARRAY[0..9] OF BYTE;
+        WO_word: ARRAY[0..9] OF WORD;
+        WO_dword: ARRAY[0..9] OF DWORD;
+        WO_int: ARRAY[0..9] OF INT;
+        WO_dint: ARRAY[0..9] OF DINT;
+        WO_real: ARRAY[0..9] OF REAL;
+        WO_dt: ARRAY[0..9] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// Block instance definition
+//---------------------------------------------------------------------
+DATA_BLOCK AllTypes_MyROBlock
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    testDevice1: _AllTypes_MyROBlock;
+    testDevice2: _AllTypes_MyROBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+DATA_BLOCK AllTypes_MyRWBlock
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    testDevice1: _AllTypes_MyRWBlock;
+    testDevice2: _AllTypes_MyRWBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+DATA_BLOCK AllTypes_MyWOBlock
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      BLK_MODE
+STRUCT
+    testDevice1: _AllTypes_MyWOBlock;
+    testDevice2: _AllTypes_MyWOBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_TiaBlock.sdf b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_TiaBlock.sdf
new file mode 100644
index 0000000000000000000000000000000000000000..29a5f5851a5e2e6dea4c19a034b129e1333190e5
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_TiaBlock.sdf
@@ -0,0 +1,8 @@
+"_SilecsHeader_hdrBlk","UDT 0","UDT 0","[SilecsHeader/1.0.0] UDT symbol: _<class-name>_<block-name>"
+"SilecsHeader_hdrBlk","DB 0","DB 0","[SilecsHeader/1.0.0] DB symbol: <class-name>_<block-name>"
+"_AllTypes_MyROBlock","UDT 1","UDT 1","[AllTypes/0.1.0] UDT symbol: _<class-name>_<block-name>"
+"_AllTypes_MyRWBlock","UDT 2","UDT 2",""
+"_AllTypes_MyWOBlock","UDT 3","UDT 3",""
+"AllTypes_MyROBlock","DB 1","DB 1","[AllTypes/0.1.0] DB symbol: <class-name>_<block-name>"
+"AllTypes_MyRWBlock","DB 2","DB 2",""
+"AllTypes_MyWOBlock","DB 3","DB 3",""
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_TiaDevice.scl b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_TiaDevice.scl
new file mode 100644
index 0000000000000000000000000000000000000000..567fb31ac7d130f3a775e9b882fc0fca384a169b
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_TiaDevice.scl
@@ -0,0 +1,147 @@
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _SilecsHeader_hdrBlk
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        _version: STRING[16] := 'SILECS_DEV';
+        _checksum: DWORD := DW#16#eae21021;
+        _user: STRING[16] := 'schwinn';
+        _date: DT := DT#2016-7-26-15:37:54;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// SilecsHeader/ v1.0.0
+// Block instance definition
+//---------------------------------------------------------------------
+DATA_BLOCK SilecsHeader_SilecsHeader
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      DEV_MODE
+STRUCT
+    hdrBlk: _SilecsHeader_hdrBlk;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// BLOCK Type definition
+//---------------------------------------------------------------------
+TYPE _AllTypes_MyROBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RO_int8: CHAR;
+        RO_uint8: BYTE;
+        RO_int16: INT;
+        RO_uint16: WORD;
+        RO_int32: DINT;
+        RO_uint32: DWORD;
+        RO_float32: REAL;
+        RO_string: STRING[64];
+        RO_date: DT;
+        RO_char: CHAR;
+        RO_byte: BYTE;
+        RO_word: WORD;
+        RO_dword: DWORD;
+        RO_int: INT;
+        RO_dint: DINT;
+        RO_real: REAL;
+        RO_dt: DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyRWBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        RW_int8: ARRAY[0..1, 0..1] OF CHAR;
+        RW_uint8: ARRAY[0..1, 0..1] OF BYTE;
+        RW_int16: ARRAY[0..1, 0..1] OF INT;
+        RW_uint16: ARRAY[0..1, 0..1] OF WORD;
+        RW_int32: ARRAY[0..1, 0..1] OF DINT;
+        RW_uint32: ARRAY[0..1, 0..1] OF DWORD;
+        RW_float32: ARRAY[0..1, 0..1] OF REAL;
+        RW_string: ARRAY[0..1, 0..1] OF STRING[64];
+        RW_date: ARRAY[0..1, 0..1] OF DT;
+        RW_char: ARRAY[0..1, 0..1] OF CHAR;
+        RW_byte: ARRAY[0..1, 0..1] OF BYTE;
+        RW_word: ARRAY[0..1, 0..1] OF WORD;
+        RW_dword: ARRAY[0..1, 0..1] OF DWORD;
+        RW_int: ARRAY[0..1, 0..1] OF INT;
+        RW_dint: ARRAY[0..1, 0..1] OF DINT;
+        RW_real: ARRAY[0..1, 0..1] OF REAL;
+        RW_dt: ARRAY[0..1, 0..1] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+TYPE _AllTypes_MyWOBlock
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      UDTB
+    STRUCT
+        WO_int8: ARRAY[0..9] OF CHAR;
+        WO_uint8: ARRAY[0..9] OF BYTE;
+        WO_int16: ARRAY[0..9] OF INT;
+        WO_uint16: ARRAY[0..9] OF WORD;
+        WO_int32: ARRAY[0..9] OF DINT;
+        WO_uint32: ARRAY[0..9] OF DWORD;
+        WO_float32: ARRAY[0..9] OF REAL;
+        WO_string: ARRAY[0..9] OF STRING[64];
+        WO_date: ARRAY[0..9] OF DT;
+        WO_char: ARRAY[0..9] OF CHAR;
+        WO_byte: ARRAY[0..9] OF BYTE;
+        WO_word: ARRAY[0..9] OF WORD;
+        WO_dword: ARRAY[0..9] OF DWORD;
+        WO_int: ARRAY[0..9] OF INT;
+        WO_dint: ARRAY[0..9] OF DINT;
+        WO_real: ARRAY[0..9] OF REAL;
+        WO_dt: ARRAY[0..9] OF DT;
+
+    END_STRUCT;
+END_TYPE
+
+//---------------------------------------------------------------------
+// AllTypes/ v0.1.0
+// Block instance definition
+//---------------------------------------------------------------------
+DATA_BLOCK AllTypes_testDevice1
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      DEV_MODE
+STRUCT
+    MyROBlock: _AllTypes_MyROBlock;
+    MyRWBlock: _AllTypes_MyRWBlock;
+    MyWOBlock: _AllTypes_MyWOBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
+DATA_BLOCK AllTypes_testDevice2
+{ S7_Optimized_Access := 'FALSE' }
+AUTHOR:    schwinn
+FAMILY:    SILECS
+NAME:      DEV_MODE
+STRUCT
+    MyROBlock: _AllTypes_MyROBlock;
+    MyRWBlock: _AllTypes_MyRWBlock;
+    MyWOBlock: _AllTypes_MyWOBlock;
+
+END_STRUCT;
+BEGIN
+END_DATA_BLOCK
+
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_TiaDevice.sdf b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_TiaDevice.sdf
new file mode 100644
index 0000000000000000000000000000000000000000..e5d2ddb66c2635a199c7f174cfbfd46beccb8ef8
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Siemens_TiaDevice.sdf
@@ -0,0 +1,7 @@
+"_SilecsHeader_hdrBlk","UDT 0","UDT 0","[SilecsHeader/1.0.0] UDT symbol: _<class-name>_<block-name>"
+"SilecsHeader_SilecsHeader","DB 0","DB 0","[SilecsHeader/1.0.0] DB symbol: <class-name>_<device-label | device-id>"
+"_AllTypes_MyROBlock","UDT 1","UDT 1","[AllTypes/0.1.0] UDT symbol: _<class-name>_<block-name>"
+"_AllTypes_MyRWBlock","UDT 2","UDT 2",""
+"_AllTypes_MyWOBlock","UDT 3","UDT 3",""
+"AllTypes_testDevice1","DB 1","DB 1","[AllTypes/0.1.0] DB symbol: <class-name>_<device-label | device-id>"
+"AllTypes_testDevice2","DB 2","DB 2",""
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensBlock.AllTypes.h b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensBlock.AllTypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..95bdd54ce7657ae4d03075fb2a787a251677a0af
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensBlock.AllTypes.h
@@ -0,0 +1,1272 @@
+
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPES_0_1_0_H_
+#define ALLTYPES_0_1_0_H_
+
+#include <silecs-virtual-controller/interface/Block.h>
+#include <silecs-virtual-controller/interface/DeployUnit.h>
+#include <silecs-virtual-controller/interface/Design.h>
+#include <silecs-virtual-controller/interface/Device.h>
+
+namespace AllTypes_0_1_0
+{
+
+class Design;
+
+class MyROBlock : public SilecsServer::Block
+{
+public:
+    /*!
+     * \brief MyROBlock constructor. It creates an empty block.
+     */
+    MyROBlock() : SilecsServer::Block("AllTypes:MyROBlock")
+    {
+    
+    }
+
+    ~MyROBlock()
+    {
+    }
+    	
+	/*!
+	 * \brief Get RO_int8 register.
+	 * \return value.
+	 */
+	int8_t getRO_int8() const
+	{
+		return structData_.RO_int8;
+	}
+
+	/*!
+	 * \brief Set RO_int8 register.
+	 * \param value to be set.
+	 */
+	void setRO_int8(int8_t value)
+	{
+		structData_.RO_int8 = value;
+	}
+	
+	/*!
+	 * \brief Get RO_uint8 register.
+	 * \return value.
+	 */
+	uint8_t getRO_uint8() const
+	{
+		return structData_.RO_uint8;
+	}
+
+	/*!
+	 * \brief Set RO_uint8 register.
+	 * \param value to be set.
+	 */
+	void setRO_uint8(uint8_t value)
+	{
+		structData_.RO_uint8 = value;
+	}
+	
+	/*!
+	 * \brief Get RO_int16 register.
+	 * \return value.
+	 */
+	int16_t getRO_int16() const
+	{
+		return structData_.RO_int16;
+	}
+
+	/*!
+	 * \brief Set RO_int16 register.
+	 * \param value to be set.
+	 */
+	void setRO_int16(int16_t value)
+	{
+		structData_.RO_int16 = value;
+	}
+	
+	/*!
+	 * \brief Get RO_uint16 register.
+	 * \return value.
+	 */
+	uint16_t getRO_uint16() const
+	{
+		return structData_.RO_uint16;
+	}
+
+	/*!
+	 * \brief Set RO_uint16 register.
+	 * \param value to be set.
+	 */
+	void setRO_uint16(uint16_t value)
+	{
+		structData_.RO_uint16 = value;
+	}
+	
+	/*!
+	 * \brief Get RO_int32 register.
+	 * \return value.
+	 */
+	int32_t getRO_int32() const
+	{
+		return structData_.RO_int32;
+	}
+
+	/*!
+	 * \brief Set RO_int32 register.
+	 * \param value to be set.
+	 */
+	void setRO_int32(int32_t value)
+	{
+		structData_.RO_int32 = value;
+	}
+	
+	/*!
+	 * \brief Get RO_uint32 register.
+	 * \return value.
+	 */
+	uint32_t getRO_uint32() const
+	{
+		return structData_.RO_uint32;
+	}
+
+	/*!
+	 * \brief Set RO_uint32 register.
+	 * \param value to be set.
+	 */
+	void setRO_uint32(uint32_t value)
+	{
+		structData_.RO_uint32 = value;
+	}
+	
+	/*!
+	 * \brief Get RO_float32 register.
+	 * \return value.
+	 */
+	float getRO_float32() const
+	{
+		return structData_.RO_float32;
+	}
+
+	/*!
+	 * \brief Set RO_float32 register.
+	 * \param value to be set.
+	 */
+	void setRO_float32(float value)
+	{
+		structData_.RO_float32 = value;
+	}
+	
+	/*!
+	 * \brief Get RO_string register.
+	 * \return value.
+	 */
+	std::string getRO_string() const
+	{
+		size_t len = (size_t)structData_.RO_string[1];
+		return std::string((char*)&(structData_.RO_string[2]), len);
+	}
+
+	/*!
+	 * \brief Set RO_string register.
+	 * \param value to be set.
+	 */
+	void setRO_string(const std::string &value)
+	{
+		size_t len = (value.length() < RO_stringLen_) ? value.length() : RO_stringLen_;
+		memcpy((char*)&(structData_.RO_string[2]), value.c_str(), len);
+		structData_.RO_string[0] = char(0);
+		structData_.RO_string[1] = char(len);
+	}
+	
+	/*!
+	 * \brief Get RO_date register.
+	 * \return value.
+	 */
+	double getRO_date() const
+	{
+		return structData_.RO_date;
+	}
+
+	/*!
+	 * \brief Set RO_date register.
+	 * \param value to be set.
+	 */
+	void setRO_date(double value)
+	{
+		structData_.RO_date = value;
+	}
+	
+	/*!
+	 * \brief Get RO_char register.
+	 * \return value.
+	 */
+	int8_t getRO_char() const
+	{
+		return structData_.RO_char;
+	}
+
+	/*!
+	 * \brief Set RO_char register.
+	 * \param value to be set.
+	 */
+	void setRO_char(int8_t value)
+	{
+		structData_.RO_char = value;
+	}
+	
+	/*!
+	 * \brief Get RO_byte register.
+	 * \return value.
+	 */
+	uint8_t getRO_byte() const
+	{
+		return structData_.RO_byte;
+	}
+
+	/*!
+	 * \brief Set RO_byte register.
+	 * \param value to be set.
+	 */
+	void setRO_byte(uint8_t value)
+	{
+		structData_.RO_byte = value;
+	}
+	
+	/*!
+	 * \brief Get RO_word register.
+	 * \return value.
+	 */
+	uint16_t getRO_word() const
+	{
+		return structData_.RO_word;
+	}
+
+	/*!
+	 * \brief Set RO_word register.
+	 * \param value to be set.
+	 */
+	void setRO_word(uint16_t value)
+	{
+		structData_.RO_word = value;
+	}
+	
+	/*!
+	 * \brief Get RO_dword register.
+	 * \return value.
+	 */
+	uint32_t getRO_dword() const
+	{
+		return structData_.RO_dword;
+	}
+
+	/*!
+	 * \brief Set RO_dword register.
+	 * \param value to be set.
+	 */
+	void setRO_dword(uint32_t value)
+	{
+		structData_.RO_dword = value;
+	}
+	
+	/*!
+	 * \brief Get RO_int register.
+	 * \return value.
+	 */
+	int16_t getRO_int() const
+	{
+		return structData_.RO_int;
+	}
+
+	/*!
+	 * \brief Set RO_int register.
+	 * \param value to be set.
+	 */
+	void setRO_int(int16_t value)
+	{
+		structData_.RO_int = value;
+	}
+	
+	/*!
+	 * \brief Get RO_dint register.
+	 * \return value.
+	 */
+	int32_t getRO_dint() const
+	{
+		return structData_.RO_dint;
+	}
+
+	/*!
+	 * \brief Set RO_dint register.
+	 * \param value to be set.
+	 */
+	void setRO_dint(int32_t value)
+	{
+		structData_.RO_dint = value;
+	}
+	
+	/*!
+	 * \brief Get RO_real register.
+	 * \return value.
+	 */
+	float getRO_real() const
+	{
+		return structData_.RO_real;
+	}
+
+	/*!
+	 * \brief Set RO_real register.
+	 * \param value to be set.
+	 */
+	void setRO_real(float value)
+	{
+		structData_.RO_real = value;
+	}
+	
+	/*!
+	 * \brief Get RO_dt register.
+	 * \return value.
+	 */
+	double getRO_dt() const
+	{
+		return structData_.RO_dt;
+	}
+
+	/*!
+	 * \brief Set RO_dt register.
+	 * \param value to be set.
+	 */
+	void setRO_dt(double value)
+	{
+		structData_.RO_dt = value;
+	}
+
+	virtual inline size_t getSize() const
+	{
+		return sizeof(structData_);
+	}
+
+	virtual void getData(unsigned char * data) const
+	{
+		memcpy(data, &structData_, this->getSize());
+	}
+
+	virtual void setData(unsigned char * data)
+	{
+		memcpy(&structData_, data, this->getSize());
+	}
+
+	virtual inline size_t getOffset() const { return 1; }
+
+	static const std::size_t RO_stringLen_ = 64;
+
+private:
+
+#pragma pack(push, 1)
+    struct
+    {
+		int8_t RO_int8;
+		uint8_t RO_uint8;
+		int16_t RO_int16;
+		uint16_t RO_uint16;
+		int32_t RO_int32;
+		uint32_t RO_uint32;
+		float RO_float32;
+		char RO_string[RO_stringLen_+2];
+		double RO_date;
+		int8_t RO_char;
+		uint8_t RO_byte;
+		uint16_t RO_word;
+		uint32_t RO_dword;
+		int16_t RO_int;
+		int32_t RO_dint;
+		float RO_real;
+		double RO_dt;
+
+    } structData_;
+#pragma pack(pop)
+	
+};
+
+class MyRWBlock : public SilecsServer::Block
+{
+public:
+    /*!
+     * \brief MyRWBlock constructor. It creates an empty block.
+     */
+    MyRWBlock() : SilecsServer::Block("AllTypes:MyRWBlock")
+    {
+    
+    }
+
+    ~MyRWBlock()
+    {
+    }
+    	
+	/*!
+	 * \brief Get array RW_int8 register.
+	 * \return value.
+	 */
+	void getRW_int8(int8_t* value) const
+	{
+		memcpy(value, &structData_.RW_int8, RW_int8Dim1_ * RW_int8Dim2_ * sizeof(int8_t));
+	}
+
+	/*!
+	 * \brief Set array RW_int8 register.
+	 * \param value to be set.
+	 */
+	void setRW_int8(int8_t* value)
+	{
+		memcpy(&structData_.RW_int8, value, RW_int8Dim1_ * RW_int8Dim2_ * sizeof(int8_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_uint8 register.
+	 * \return value.
+	 */
+	void getRW_uint8(uint8_t* value) const
+	{
+		memcpy(value, &structData_.RW_uint8, RW_uint8Dim1_ * RW_uint8Dim2_ * sizeof(uint8_t));
+	}
+
+	/*!
+	 * \brief Set array RW_uint8 register.
+	 * \param value to be set.
+	 */
+	void setRW_uint8(uint8_t* value)
+	{
+		memcpy(&structData_.RW_uint8, value, RW_uint8Dim1_ * RW_uint8Dim2_ * sizeof(uint8_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_int16 register.
+	 * \return value.
+	 */
+	void getRW_int16(int16_t* value) const
+	{
+		memcpy(value, &structData_.RW_int16, RW_int16Dim1_ * RW_int16Dim2_ * sizeof(int16_t));
+	}
+
+	/*!
+	 * \brief Set array RW_int16 register.
+	 * \param value to be set.
+	 */
+	void setRW_int16(int16_t* value)
+	{
+		memcpy(&structData_.RW_int16, value, RW_int16Dim1_ * RW_int16Dim2_ * sizeof(int16_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_uint16 register.
+	 * \return value.
+	 */
+	void getRW_uint16(uint16_t* value) const
+	{
+		memcpy(value, &structData_.RW_uint16, RW_uint16Dim1_ * RW_uint16Dim2_ * sizeof(uint16_t));
+	}
+
+	/*!
+	 * \brief Set array RW_uint16 register.
+	 * \param value to be set.
+	 */
+	void setRW_uint16(uint16_t* value)
+	{
+		memcpy(&structData_.RW_uint16, value, RW_uint16Dim1_ * RW_uint16Dim2_ * sizeof(uint16_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_int32 register.
+	 * \return value.
+	 */
+	void getRW_int32(int32_t* value) const
+	{
+		memcpy(value, &structData_.RW_int32, RW_int32Dim1_ * RW_int32Dim2_ * sizeof(int32_t));
+	}
+
+	/*!
+	 * \brief Set array RW_int32 register.
+	 * \param value to be set.
+	 */
+	void setRW_int32(int32_t* value)
+	{
+		memcpy(&structData_.RW_int32, value, RW_int32Dim1_ * RW_int32Dim2_ * sizeof(int32_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_uint32 register.
+	 * \return value.
+	 */
+	void getRW_uint32(uint32_t* value) const
+	{
+		memcpy(value, &structData_.RW_uint32, RW_uint32Dim1_ * RW_uint32Dim2_ * sizeof(uint32_t));
+	}
+
+	/*!
+	 * \brief Set array RW_uint32 register.
+	 * \param value to be set.
+	 */
+	void setRW_uint32(uint32_t* value)
+	{
+		memcpy(&structData_.RW_uint32, value, RW_uint32Dim1_ * RW_uint32Dim2_ * sizeof(uint32_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_float32 register.
+	 * \return value.
+	 */
+	void getRW_float32(float* value) const
+	{
+		memcpy(value, &structData_.RW_float32, RW_float32Dim1_ * RW_float32Dim2_ * sizeof(float));
+	}
+
+	/*!
+	 * \brief Set array RW_float32 register.
+	 * \param value to be set.
+	 */
+	void setRW_float32(float* value)
+	{
+		memcpy(&structData_.RW_float32, value, RW_float32Dim1_ * RW_float32Dim2_ * sizeof(float));
+	}
+	
+	/*!
+	 * \brief Get std::string RW_string register.
+	 * \param value buffer where the value will be stored.
+	 */
+	void getRW_string(std::string* value) const
+	{
+		for (std::size_t i = 0; i < RW_stringDim1_; i++)
+		{
+			size_t len = (size_t)structData_.RW_string[i][1];
+			value[i].assign(&(structData_.RW_string[i][2]), len);
+		}
+	}
+
+	/*!
+	 * \brief Set std::string RW_string register.
+	 * \param value to be set.
+	 */
+	void setRW_string(std::string* value)
+	{
+	    for (std::size_t i = 0; i < RW_stringDim1_; i++)
+		{
+		    size_t len = (value[i].length() < RW_stringLen_) ? value[i].length() : RW_stringLen_;
+			memcpy(&(structData_.RW_string[i][2]), value[i].c_str(), len);
+			structData_.RW_string[i][0] = char(0);
+			structData_.RW_string[i][1] = char(len);
+		}
+	}
+	
+	/*!
+	 * \brief Get array RW_date register.
+	 * \return value.
+	 */
+	void getRW_date(double* value) const
+	{
+		memcpy(value, &structData_.RW_date, RW_dateDim1_ * RW_dateDim2_ * sizeof(double));
+	}
+
+	/*!
+	 * \brief Set array RW_date register.
+	 * \param value to be set.
+	 */
+	void setRW_date(double* value)
+	{
+		memcpy(&structData_.RW_date, value, RW_dateDim1_ * RW_dateDim2_ * sizeof(double));
+	}
+	
+	/*!
+	 * \brief Get array RW_char register.
+	 * \return value.
+	 */
+	void getRW_char(int8_t* value) const
+	{
+		memcpy(value, &structData_.RW_char, RW_charDim1_ * RW_charDim2_ * sizeof(int8_t));
+	}
+
+	/*!
+	 * \brief Set array RW_char register.
+	 * \param value to be set.
+	 */
+	void setRW_char(int8_t* value)
+	{
+		memcpy(&structData_.RW_char, value, RW_charDim1_ * RW_charDim2_ * sizeof(int8_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_byte register.
+	 * \return value.
+	 */
+	void getRW_byte(uint8_t* value) const
+	{
+		memcpy(value, &structData_.RW_byte, RW_byteDim1_ * RW_byteDim2_ * sizeof(uint8_t));
+	}
+
+	/*!
+	 * \brief Set array RW_byte register.
+	 * \param value to be set.
+	 */
+	void setRW_byte(uint8_t* value)
+	{
+		memcpy(&structData_.RW_byte, value, RW_byteDim1_ * RW_byteDim2_ * sizeof(uint8_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_word register.
+	 * \return value.
+	 */
+	void getRW_word(uint16_t* value) const
+	{
+		memcpy(value, &structData_.RW_word, RW_wordDim1_ * RW_wordDim2_ * sizeof(uint16_t));
+	}
+
+	/*!
+	 * \brief Set array RW_word register.
+	 * \param value to be set.
+	 */
+	void setRW_word(uint16_t* value)
+	{
+		memcpy(&structData_.RW_word, value, RW_wordDim1_ * RW_wordDim2_ * sizeof(uint16_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_dword register.
+	 * \return value.
+	 */
+	void getRW_dword(uint32_t* value) const
+	{
+		memcpy(value, &structData_.RW_dword, RW_dwordDim1_ * RW_dwordDim2_ * sizeof(uint32_t));
+	}
+
+	/*!
+	 * \brief Set array RW_dword register.
+	 * \param value to be set.
+	 */
+	void setRW_dword(uint32_t* value)
+	{
+		memcpy(&structData_.RW_dword, value, RW_dwordDim1_ * RW_dwordDim2_ * sizeof(uint32_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_int register.
+	 * \return value.
+	 */
+	void getRW_int(int16_t* value) const
+	{
+		memcpy(value, &structData_.RW_int, RW_intDim1_ * RW_intDim2_ * sizeof(int16_t));
+	}
+
+	/*!
+	 * \brief Set array RW_int register.
+	 * \param value to be set.
+	 */
+	void setRW_int(int16_t* value)
+	{
+		memcpy(&structData_.RW_int, value, RW_intDim1_ * RW_intDim2_ * sizeof(int16_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_dint register.
+	 * \return value.
+	 */
+	void getRW_dint(int32_t* value) const
+	{
+		memcpy(value, &structData_.RW_dint, RW_dintDim1_ * RW_dintDim2_ * sizeof(int32_t));
+	}
+
+	/*!
+	 * \brief Set array RW_dint register.
+	 * \param value to be set.
+	 */
+	void setRW_dint(int32_t* value)
+	{
+		memcpy(&structData_.RW_dint, value, RW_dintDim1_ * RW_dintDim2_ * sizeof(int32_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_real register.
+	 * \return value.
+	 */
+	void getRW_real(float* value) const
+	{
+		memcpy(value, &structData_.RW_real, RW_realDim1_ * RW_realDim2_ * sizeof(float));
+	}
+
+	/*!
+	 * \brief Set array RW_real register.
+	 * \param value to be set.
+	 */
+	void setRW_real(float* value)
+	{
+		memcpy(&structData_.RW_real, value, RW_realDim1_ * RW_realDim2_ * sizeof(float));
+	}
+	
+	/*!
+	 * \brief Get array RW_dt register.
+	 * \return value.
+	 */
+	void getRW_dt(double* value) const
+	{
+		memcpy(value, &structData_.RW_dt, RW_dtDim1_ * RW_dtDim2_ * sizeof(double));
+	}
+
+	/*!
+	 * \brief Set array RW_dt register.
+	 * \param value to be set.
+	 */
+	void setRW_dt(double* value)
+	{
+		memcpy(&structData_.RW_dt, value, RW_dtDim1_ * RW_dtDim2_ * sizeof(double));
+	}
+
+	virtual inline size_t getSize() const
+	{
+		return sizeof(structData_);
+	}
+
+	virtual void getData(unsigned char * data) const
+	{
+		memcpy(data, &structData_, this->getSize());
+	}
+
+	virtual void setData(unsigned char * data)
+	{
+		memcpy(&structData_, data, this->getSize());
+	}
+
+	virtual inline size_t getOffset() const { return 2; }
+
+	static const std::size_t RW_int8Dim1_ = 2;
+	static const std::size_t RW_int8Dim2_ = 2;
+	static const std::size_t RW_uint8Dim1_ = 2;
+	static const std::size_t RW_uint8Dim2_ = 2;
+	static const std::size_t RW_int16Dim1_ = 2;
+	static const std::size_t RW_int16Dim2_ = 2;
+	static const std::size_t RW_uint16Dim1_ = 2;
+	static const std::size_t RW_uint16Dim2_ = 2;
+	static const std::size_t RW_int32Dim1_ = 2;
+	static const std::size_t RW_int32Dim2_ = 2;
+	static const std::size_t RW_uint32Dim1_ = 2;
+	static const std::size_t RW_uint32Dim2_ = 2;
+	static const std::size_t RW_float32Dim1_ = 2;
+	static const std::size_t RW_float32Dim2_ = 2;
+	static const std::size_t RW_stringDim1_ = 2;
+	static const std::size_t RW_stringDim2_ = 2;
+	static const std::size_t RW_stringLen_ = 64;
+	static const std::size_t RW_dateDim1_ = 2;
+	static const std::size_t RW_dateDim2_ = 2;
+	static const std::size_t RW_charDim1_ = 2;
+	static const std::size_t RW_charDim2_ = 2;
+	static const std::size_t RW_byteDim1_ = 2;
+	static const std::size_t RW_byteDim2_ = 2;
+	static const std::size_t RW_wordDim1_ = 2;
+	static const std::size_t RW_wordDim2_ = 2;
+	static const std::size_t RW_dwordDim1_ = 2;
+	static const std::size_t RW_dwordDim2_ = 2;
+	static const std::size_t RW_intDim1_ = 2;
+	static const std::size_t RW_intDim2_ = 2;
+	static const std::size_t RW_dintDim1_ = 2;
+	static const std::size_t RW_dintDim2_ = 2;
+	static const std::size_t RW_realDim1_ = 2;
+	static const std::size_t RW_realDim2_ = 2;
+	static const std::size_t RW_dtDim1_ = 2;
+	static const std::size_t RW_dtDim2_ = 2;
+
+private:
+
+#pragma pack(push, 1)
+    struct
+    {
+		int8_t RW_int8[RW_int8Dim1_][RW_int8Dim2_];
+		uint8_t RW_uint8[RW_uint8Dim1_][RW_uint8Dim2_];
+		int16_t RW_int16[RW_int16Dim1_][RW_int16Dim2_];
+		uint16_t RW_uint16[RW_uint16Dim1_][RW_uint16Dim2_];
+		int32_t RW_int32[RW_int32Dim1_][RW_int32Dim2_];
+		uint32_t RW_uint32[RW_uint32Dim1_][RW_uint32Dim2_];
+		float RW_float32[RW_float32Dim1_][RW_float32Dim2_];
+		char RW_string[RW_stringDim1_][RW_stringDim2_][RW_stringLen_+2];
+		double RW_date[RW_dateDim1_][RW_dateDim2_];
+		int8_t RW_char[RW_charDim1_][RW_charDim2_];
+		uint8_t RW_byte[RW_byteDim1_][RW_byteDim2_];
+		uint16_t RW_word[RW_wordDim1_][RW_wordDim2_];
+		uint32_t RW_dword[RW_dwordDim1_][RW_dwordDim2_];
+		int16_t RW_int[RW_intDim1_][RW_intDim2_];
+		int32_t RW_dint[RW_dintDim1_][RW_dintDim2_];
+		float RW_real[RW_realDim1_][RW_realDim2_];
+		double RW_dt[RW_dtDim1_][RW_dtDim2_];
+
+    } structData_;
+#pragma pack(pop)
+	
+};
+
+class MyWOBlock : public SilecsServer::Block
+{
+public:
+    /*!
+     * \brief MyWOBlock constructor. It creates an empty block.
+     */
+    MyWOBlock() : SilecsServer::Block("AllTypes:MyWOBlock")
+    {
+    
+    }
+
+    ~MyWOBlock()
+    {
+    }
+    	
+	/*!
+	 * \brief Get array WO_int8 register.
+	 * \return value.
+	 */
+	void getWO_int8(int8_t* value) const
+	{
+		memcpy(value, &structData_.WO_int8, WO_int8Dim1_ * WO_int8Dim2_ * sizeof(int8_t));
+	}
+
+	/*!
+	 * \brief Set array WO_int8 register.
+	 * \param value to be set.
+	 */
+	void setWO_int8(int8_t* value)
+	{
+		memcpy(&structData_.WO_int8, value, WO_int8Dim1_ * WO_int8Dim2_ * sizeof(int8_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_uint8 register.
+	 * \return value.
+	 */
+	void getWO_uint8(uint8_t* value) const
+	{
+		memcpy(value, &structData_.WO_uint8, WO_uint8Dim1_ * WO_uint8Dim2_ * sizeof(uint8_t));
+	}
+
+	/*!
+	 * \brief Set array WO_uint8 register.
+	 * \param value to be set.
+	 */
+	void setWO_uint8(uint8_t* value)
+	{
+		memcpy(&structData_.WO_uint8, value, WO_uint8Dim1_ * WO_uint8Dim2_ * sizeof(uint8_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_int16 register.
+	 * \return value.
+	 */
+	void getWO_int16(int16_t* value) const
+	{
+		memcpy(value, &structData_.WO_int16, WO_int16Dim1_ * WO_int16Dim2_ * sizeof(int16_t));
+	}
+
+	/*!
+	 * \brief Set array WO_int16 register.
+	 * \param value to be set.
+	 */
+	void setWO_int16(int16_t* value)
+	{
+		memcpy(&structData_.WO_int16, value, WO_int16Dim1_ * WO_int16Dim2_ * sizeof(int16_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_uint16 register.
+	 * \return value.
+	 */
+	void getWO_uint16(uint16_t* value) const
+	{
+		memcpy(value, &structData_.WO_uint16, WO_uint16Dim1_ * WO_uint16Dim2_ * sizeof(uint16_t));
+	}
+
+	/*!
+	 * \brief Set array WO_uint16 register.
+	 * \param value to be set.
+	 */
+	void setWO_uint16(uint16_t* value)
+	{
+		memcpy(&structData_.WO_uint16, value, WO_uint16Dim1_ * WO_uint16Dim2_ * sizeof(uint16_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_int32 register.
+	 * \return value.
+	 */
+	void getWO_int32(int32_t* value) const
+	{
+		memcpy(value, &structData_.WO_int32, WO_int32Dim1_ * WO_int32Dim2_ * sizeof(int32_t));
+	}
+
+	/*!
+	 * \brief Set array WO_int32 register.
+	 * \param value to be set.
+	 */
+	void setWO_int32(int32_t* value)
+	{
+		memcpy(&structData_.WO_int32, value, WO_int32Dim1_ * WO_int32Dim2_ * sizeof(int32_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_uint32 register.
+	 * \return value.
+	 */
+	void getWO_uint32(uint32_t* value) const
+	{
+		memcpy(value, &structData_.WO_uint32, WO_uint32Dim1_ * WO_uint32Dim2_ * sizeof(uint32_t));
+	}
+
+	/*!
+	 * \brief Set array WO_uint32 register.
+	 * \param value to be set.
+	 */
+	void setWO_uint32(uint32_t* value)
+	{
+		memcpy(&structData_.WO_uint32, value, WO_uint32Dim1_ * WO_uint32Dim2_ * sizeof(uint32_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_float32 register.
+	 * \return value.
+	 */
+	void getWO_float32(float* value) const
+	{
+		memcpy(value, &structData_.WO_float32, WO_float32Dim1_ * WO_float32Dim2_ * sizeof(float));
+	}
+
+	/*!
+	 * \brief Set array WO_float32 register.
+	 * \param value to be set.
+	 */
+	void setWO_float32(float* value)
+	{
+		memcpy(&structData_.WO_float32, value, WO_float32Dim1_ * WO_float32Dim2_ * sizeof(float));
+	}
+	
+	/*!
+	 * \brief Get std::string WO_string register.
+	 * \param value buffer where the value will be stored.
+	 */
+	void getWO_string(std::string* value) const
+	{
+		for (std::size_t i = 0; i < WO_stringDim1_; i++)
+		{
+			size_t len = (size_t)structData_.WO_string[i][1];
+			value[i].assign(&(structData_.WO_string[i][2]), len);
+		}
+	}
+
+	/*!
+	 * \brief Set std::string WO_string register.
+	 * \param value to be set.
+	 */
+	void setWO_string(std::string* value)
+	{
+	    for (std::size_t i = 0; i < WO_stringDim1_; i++)
+		{
+		    size_t len = (value[i].length() < WO_stringLen_) ? value[i].length() : WO_stringLen_;
+			memcpy(&(structData_.WO_string[i][2]), value[i].c_str(), len);
+			structData_.WO_string[i][0] = char(0);
+			structData_.WO_string[i][1] = char(len);
+		}
+	}
+	
+	/*!
+	 * \brief Get array WO_date register.
+	 * \return value.
+	 */
+	void getWO_date(double* value) const
+	{
+		memcpy(value, &structData_.WO_date, WO_dateDim1_ * WO_dateDim2_ * sizeof(double));
+	}
+
+	/*!
+	 * \brief Set array WO_date register.
+	 * \param value to be set.
+	 */
+	void setWO_date(double* value)
+	{
+		memcpy(&structData_.WO_date, value, WO_dateDim1_ * WO_dateDim2_ * sizeof(double));
+	}
+	
+	/*!
+	 * \brief Get array WO_char register.
+	 * \return value.
+	 */
+	void getWO_char(int8_t* value) const
+	{
+		memcpy(value, &structData_.WO_char, WO_charDim1_ * WO_charDim2_ * sizeof(int8_t));
+	}
+
+	/*!
+	 * \brief Set array WO_char register.
+	 * \param value to be set.
+	 */
+	void setWO_char(int8_t* value)
+	{
+		memcpy(&structData_.WO_char, value, WO_charDim1_ * WO_charDim2_ * sizeof(int8_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_byte register.
+	 * \return value.
+	 */
+	void getWO_byte(uint8_t* value) const
+	{
+		memcpy(value, &structData_.WO_byte, WO_byteDim1_ * WO_byteDim2_ * sizeof(uint8_t));
+	}
+
+	/*!
+	 * \brief Set array WO_byte register.
+	 * \param value to be set.
+	 */
+	void setWO_byte(uint8_t* value)
+	{
+		memcpy(&structData_.WO_byte, value, WO_byteDim1_ * WO_byteDim2_ * sizeof(uint8_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_word register.
+	 * \return value.
+	 */
+	void getWO_word(uint16_t* value) const
+	{
+		memcpy(value, &structData_.WO_word, WO_wordDim1_ * WO_wordDim2_ * sizeof(uint16_t));
+	}
+
+	/*!
+	 * \brief Set array WO_word register.
+	 * \param value to be set.
+	 */
+	void setWO_word(uint16_t* value)
+	{
+		memcpy(&structData_.WO_word, value, WO_wordDim1_ * WO_wordDim2_ * sizeof(uint16_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_dword register.
+	 * \return value.
+	 */
+	void getWO_dword(uint32_t* value) const
+	{
+		memcpy(value, &structData_.WO_dword, WO_dwordDim1_ * WO_dwordDim2_ * sizeof(uint32_t));
+	}
+
+	/*!
+	 * \brief Set array WO_dword register.
+	 * \param value to be set.
+	 */
+	void setWO_dword(uint32_t* value)
+	{
+		memcpy(&structData_.WO_dword, value, WO_dwordDim1_ * WO_dwordDim2_ * sizeof(uint32_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_int register.
+	 * \return value.
+	 */
+	void getWO_int(int16_t* value) const
+	{
+		memcpy(value, &structData_.WO_int, WO_intDim1_ * WO_intDim2_ * sizeof(int16_t));
+	}
+
+	/*!
+	 * \brief Set array WO_int register.
+	 * \param value to be set.
+	 */
+	void setWO_int(int16_t* value)
+	{
+		memcpy(&structData_.WO_int, value, WO_intDim1_ * WO_intDim2_ * sizeof(int16_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_dint register.
+	 * \return value.
+	 */
+	void getWO_dint(int32_t* value) const
+	{
+		memcpy(value, &structData_.WO_dint, WO_dintDim1_ * WO_dintDim2_ * sizeof(int32_t));
+	}
+
+	/*!
+	 * \brief Set array WO_dint register.
+	 * \param value to be set.
+	 */
+	void setWO_dint(int32_t* value)
+	{
+		memcpy(&structData_.WO_dint, value, WO_dintDim1_ * WO_dintDim2_ * sizeof(int32_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_real register.
+	 * \return value.
+	 */
+	void getWO_real(float* value) const
+	{
+		memcpy(value, &structData_.WO_real, WO_realDim1_ * WO_realDim2_ * sizeof(float));
+	}
+
+	/*!
+	 * \brief Set array WO_real register.
+	 * \param value to be set.
+	 */
+	void setWO_real(float* value)
+	{
+		memcpy(&structData_.WO_real, value, WO_realDim1_ * WO_realDim2_ * sizeof(float));
+	}
+	
+	/*!
+	 * \brief Get array WO_dt register.
+	 * \return value.
+	 */
+	void getWO_dt(double* value) const
+	{
+		memcpy(value, &structData_.WO_dt, WO_dtDim1_ * WO_dtDim2_ * sizeof(double));
+	}
+
+	/*!
+	 * \brief Set array WO_dt register.
+	 * \param value to be set.
+	 */
+	void setWO_dt(double* value)
+	{
+		memcpy(&structData_.WO_dt, value, WO_dtDim1_ * WO_dtDim2_ * sizeof(double));
+	}
+
+	virtual inline size_t getSize() const
+	{
+		return sizeof(structData_);
+	}
+
+	virtual void getData(unsigned char * data) const
+	{
+		memcpy(data, &structData_, this->getSize());
+	}
+
+	virtual void setData(unsigned char * data)
+	{
+		memcpy(&structData_, data, this->getSize());
+	}
+
+	virtual inline size_t getOffset() const { return 3; }
+
+	static const std::size_t WO_int8Dim1_ = 10;
+	static const std::size_t WO_int8Dim2_ = 1;
+	static const std::size_t WO_uint8Dim1_ = 10;
+	static const std::size_t WO_uint8Dim2_ = 1;
+	static const std::size_t WO_int16Dim1_ = 10;
+	static const std::size_t WO_int16Dim2_ = 1;
+	static const std::size_t WO_uint16Dim1_ = 10;
+	static const std::size_t WO_uint16Dim2_ = 1;
+	static const std::size_t WO_int32Dim1_ = 10;
+	static const std::size_t WO_int32Dim2_ = 1;
+	static const std::size_t WO_uint32Dim1_ = 10;
+	static const std::size_t WO_uint32Dim2_ = 1;
+	static const std::size_t WO_float32Dim1_ = 10;
+	static const std::size_t WO_float32Dim2_ = 1;
+	static const std::size_t WO_stringDim1_ = 10;
+	static const std::size_t WO_stringDim2_ = 1;
+	static const std::size_t WO_stringLen_ = 64;
+	static const std::size_t WO_dateDim1_ = 10;
+	static const std::size_t WO_dateDim2_ = 1;
+	static const std::size_t WO_charDim1_ = 10;
+	static const std::size_t WO_charDim2_ = 1;
+	static const std::size_t WO_byteDim1_ = 10;
+	static const std::size_t WO_byteDim2_ = 1;
+	static const std::size_t WO_wordDim1_ = 10;
+	static const std::size_t WO_wordDim2_ = 1;
+	static const std::size_t WO_dwordDim1_ = 10;
+	static const std::size_t WO_dwordDim2_ = 1;
+	static const std::size_t WO_intDim1_ = 10;
+	static const std::size_t WO_intDim2_ = 1;
+	static const std::size_t WO_dintDim1_ = 10;
+	static const std::size_t WO_dintDim2_ = 1;
+	static const std::size_t WO_realDim1_ = 10;
+	static const std::size_t WO_realDim2_ = 1;
+	static const std::size_t WO_dtDim1_ = 10;
+	static const std::size_t WO_dtDim2_ = 1;
+
+private:
+
+#pragma pack(push, 1)
+    struct
+    {
+		int8_t WO_int8[WO_int8Dim1_];
+		uint8_t WO_uint8[WO_uint8Dim1_];
+		int16_t WO_int16[WO_int16Dim1_];
+		uint16_t WO_uint16[WO_uint16Dim1_];
+		int32_t WO_int32[WO_int32Dim1_];
+		uint32_t WO_uint32[WO_uint32Dim1_];
+		float WO_float32[WO_float32Dim1_];
+		char WO_string[WO_stringDim1_][WO_stringLen_+2];
+		double WO_date[WO_dateDim1_];
+		int8_t WO_char[WO_charDim1_];
+		uint8_t WO_byte[WO_byteDim1_];
+		uint16_t WO_word[WO_wordDim1_];
+		uint32_t WO_dword[WO_dwordDim1_];
+		int16_t WO_int[WO_intDim1_];
+		int32_t WO_dint[WO_dintDim1_];
+		float WO_real[WO_realDim1_];
+		double WO_dt[WO_dtDim1_];
+
+    } structData_;
+#pragma pack(pop)
+	
+};
+
+
+
+class Device : public SilecsServer::Device
+{
+public:
+    Device(const std::string& label, size_t number):SilecsServer::Device(label, number)
+    {	
+		blockMap_["AllTypes:MyROBlock"] = new MyROBlock();
+		blockMap_["AllTypes:MyRWBlock"] = new MyRWBlock();
+		blockMap_["AllTypes:MyWOBlock"] = new MyWOBlock();    
+    }
+
+    ~Device()
+    {    
+		delete (blockMap_["AllTypes:MyROBlock"]);
+		delete (blockMap_["AllTypes:MyRWBlock"]);
+		delete (blockMap_["AllTypes:MyWOBlock"]);    
+    }
+};
+
+
+class Design : public SilecsServer::Design
+{
+public:
+
+    Design():SilecsServer::Design("AllTypes", "0.1.0")
+    {    
+		deviceMap_["AllTypes:testDevice1"] = new Device("AllTypes:testDevice1", 0);
+		deviceMap_["AllTypes:testDevice2"] = new Device("AllTypes:testDevice2", 1);    
+    }
+
+    ~Design()
+    {    
+		delete(deviceMap_["AllTypes:testDevice1"]);
+		delete(deviceMap_["AllTypes:testDevice2"]);    
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    AllTypes_0_1_0::Device* getDevice(const std::string& label)
+    {
+        if (deviceMap_.find(label) != deviceMap_.end())
+        {
+            return dynamic_cast<AllTypes_0_1_0::Device*>(deviceMap_[label]);
+        }
+        return NULL;
+    }
+};
+
+} /* namespace */
+#endif
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensBlock.SilecsHeader.h b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensBlock.SilecsHeader.h
new file mode 100644
index 0000000000000000000000000000000000000000..85ecca60a14438414a6e1df5a886a88b03802650
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensBlock.SilecsHeader.h
@@ -0,0 +1,203 @@
+
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef SILECSHEADER_1_0_0_H_
+#define SILECSHEADER_1_0_0_H_
+
+#include <silecs-virtual-controller/interface/Block.h>
+#include <silecs-virtual-controller/interface/DeployUnit.h>
+#include <silecs-virtual-controller/interface/Design.h>
+#include <silecs-virtual-controller/interface/Device.h>
+
+namespace SilecsHeader_1_0_0
+{
+
+class Design;
+
+class HdrBlk : public SilecsServer::Block
+{
+public:
+    /*!
+     * \brief hdrBlk constructor. It creates an empty block.
+     */
+    HdrBlk() : SilecsServer::Block("SilecsHeader:hdrBlk")
+    {
+    	set_version("DEV");
+		set_checksum(0X2110E2EA);
+		set_user("schwinn");
+		set_date(0.0);
+    }
+
+    ~HdrBlk()
+    {
+    }
+    	
+	/*!
+	 * \brief Get _version register.
+	 * \return value.
+	 */
+	std::string get_version() const
+	{
+		size_t len = (size_t)structData_._version[1];
+		return std::string((char*)&(structData_._version[2]), len);
+	}
+
+	/*!
+	 * \brief Set _version register.
+	 * \param value to be set.
+	 */
+	void set_version(const std::string &value)
+	{
+		size_t len = (value.length() < _versionLen_) ? value.length() : _versionLen_;
+		memcpy((char*)&(structData_._version[2]), value.c_str(), len);
+		structData_._version[0] = char(0);
+		structData_._version[1] = char(len);
+	}
+	
+	/*!
+	 * \brief Get _checksum register.
+	 * \return value.
+	 */
+	uint32_t get_checksum() const
+	{
+		return structData_._checksum;
+	}
+
+	/*!
+	 * \brief Set _checksum register.
+	 * \param value to be set.
+	 */
+	void set_checksum(uint32_t value)
+	{
+		structData_._checksum = value;
+	}
+	
+	/*!
+	 * \brief Get _user register.
+	 * \return value.
+	 */
+	std::string get_user() const
+	{
+		size_t len = (size_t)structData_._user[1];
+		return std::string((char*)&(structData_._user[2]), len);
+	}
+
+	/*!
+	 * \brief Set _user register.
+	 * \param value to be set.
+	 */
+	void set_user(const std::string &value)
+	{
+		size_t len = (value.length() < _userLen_) ? value.length() : _userLen_;
+		memcpy((char*)&(structData_._user[2]), value.c_str(), len);
+		structData_._user[0] = char(0);
+		structData_._user[1] = char(len);
+	}
+	
+	/*!
+	 * \brief Get _date register.
+	 * \return value.
+	 */
+	double get_date() const
+	{
+		return structData_._date;
+	}
+
+	/*!
+	 * \brief Set _date register.
+	 * \param value to be set.
+	 */
+	void set_date(double value)
+	{
+		structData_._date = value;
+	}
+
+	virtual inline size_t getSize() const
+	{
+		return sizeof(structData_);
+	}
+
+	virtual void getData(unsigned char * data) const
+	{
+		memcpy(data, &structData_, this->getSize());
+	}
+
+	virtual void setData(unsigned char * data)
+	{
+		memcpy(&structData_, data, this->getSize());
+	}
+
+	virtual inline size_t getOffset() const { return 0; }
+
+	static const std::size_t _versionLen_ = 16;
+	static const std::size_t _userLen_ = 16;
+
+private:
+
+#pragma pack(push, 1)
+    struct
+    {
+		char _version[_versionLen_+2];
+		uint32_t _checksum;
+		char _user[_userLen_+2];
+		double _date;
+
+    } structData_;
+#pragma pack(pop)
+	
+};
+
+
+
+class Device : public SilecsServer::Device
+{
+public:
+    Device(const std::string& label, size_t number):SilecsServer::Device(label, number)
+    {	
+		blockMap_["SilecsHeader:hdrBlk"] = new HdrBlk();    
+    }
+
+    ~Device()
+    {    
+		delete (blockMap_["SilecsHeader:hdrBlk"]);    
+    }
+};
+
+
+class Design : public SilecsServer::Design
+{
+public:
+
+    Design():SilecsServer::Design("SilecsHeader", "1.0.0")
+    {    
+		deviceMap_["SilecsHeader:SilecsHeader"] = new Device("SilecsHeader:SilecsHeader", 0);    
+    }
+
+    ~Design()
+    {    
+		delete(deviceMap_["SilecsHeader:SilecsHeader"]);    
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsHeader_1_0_0::Device* getDevice(const std::string& label)
+    {
+        if (deviceMap_.find(label) != deviceMap_.end())
+        {
+            return dynamic_cast<SilecsHeader_1_0_0::Device*>(deviceMap_[label]);
+        }
+        return NULL;
+    }
+};
+
+} /* namespace */
+#endif
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensBlock.cpp b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensBlock.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d7e2a30372df7923ad5c8667bbdf45c9d043942e
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensBlock.cpp
@@ -0,0 +1,33 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cstring>
+#include <iostream>
+
+#include <silecs-virtual-controller/core/SilecsSnap7Server.h>
+#include "Virtual_SiemensBlock.h"
+
+class UserSnap7Server : public SilecsServer::SilecsSnap7Server
+{
+public:
+    UserSnap7Server(Virtual_SiemensBlock::DeployUnit* du) : SilecsSnap7Server(du, true) {}
+    virtual ~UserSnap7Server() {}
+
+    virtual void userFunction()
+    {
+      // Implement the specific process control here!
+      // Look at SILECS Wikis: 'Create a virtual controller' chapter 
+    }
+};
+
+int main(int argc, char*argv[])
+{
+    Virtual_SiemensBlock::DeployUnit du;
+    UserSnap7Server server(&du);
+    if (server.startServer() < 0)
+    {
+        std::cout << "Failed to start the VC server: " << du.getName() << std::endl;
+        return -1;
+    }
+    return 0;
+}
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensBlock.h b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensBlock.h
new file mode 100644
index 0000000000000000000000000000000000000000..819405bef1b250069e55be5edebff102efa37f28
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensBlock.h
@@ -0,0 +1,53 @@
+
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef VIRTUAL_SIEMENSBLOCK_H_
+#define VIRTUAL_SIEMENSBLOCK_H_
+
+#include <silecs-virtual-controller/interface/DeployUnit.h>
+#include <silecs-virtual-controller/interface/Design.h>
+#include "SilecsHeader_1.0.0.h"
+#include "AllTypes_0.1.0.h"
+
+
+namespace Virtual_SiemensBlock
+{
+
+class DeployUnit : public SilecsServer::DeployUnit
+{
+public:
+
+	DeployUnit() : SilecsServer::DeployUnit("Virtual_SiemensBlock", SilecsServer::S7Protocol, SilecsServer::BlockMode, 0)
+	{
+    	mapDesigns_["SilecsHeader"] = new SilecsHeader_1_0_0::Design();
+	mapDesigns_["AllTypes"] = new AllTypes_0_1_0::Design();
+	}
+
+    ~DeployUnit()
+    {
+    	delete mapDesigns_["SilecsHeader"];
+	delete mapDesigns_["AllTypes"];
+	}
+
+	SilecsHeader_1_0_0::Design* getSilecsHeader()
+	{
+		return dynamic_cast<SilecsHeader_1_0_0::Design*>(mapDesigns_["SilecsHeader"]);
+	}
+	
+	AllTypes_0_1_0::Design* getAllTypes()
+	{
+		return dynamic_cast<AllTypes_0_1_0::Design*>(mapDesigns_["AllTypes"]);
+	}
+	
+};
+
+}
+
+#endif
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensDevice.AllTypes.h b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensDevice.AllTypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..3883554cce81e731ece7cea9a4b17f7aacad908f
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensDevice.AllTypes.h
@@ -0,0 +1,1272 @@
+
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPES_0_1_0_H_
+#define ALLTYPES_0_1_0_H_
+
+#include <silecs-virtual-controller/interface/Block.h>
+#include <silecs-virtual-controller/interface/DeployUnit.h>
+#include <silecs-virtual-controller/interface/Design.h>
+#include <silecs-virtual-controller/interface/Device.h>
+
+namespace AllTypes_0_1_0
+{
+
+class Design;
+
+class MyROBlock : public SilecsServer::Block
+{
+public:
+    /*!
+     * \brief MyROBlock constructor. It creates an empty block.
+     */
+    MyROBlock() : SilecsServer::Block("AllTypes:MyROBlock")
+    {
+    
+    }
+
+    ~MyROBlock()
+    {
+    }
+    	
+	/*!
+	 * \brief Get RO_int8 register.
+	 * \return value.
+	 */
+	int8_t getRO_int8() const
+	{
+		return structData_.RO_int8;
+	}
+
+	/*!
+	 * \brief Set RO_int8 register.
+	 * \param value to be set.
+	 */
+	void setRO_int8(int8_t value)
+	{
+		structData_.RO_int8 = value;
+	}
+	
+	/*!
+	 * \brief Get RO_uint8 register.
+	 * \return value.
+	 */
+	uint8_t getRO_uint8() const
+	{
+		return structData_.RO_uint8;
+	}
+
+	/*!
+	 * \brief Set RO_uint8 register.
+	 * \param value to be set.
+	 */
+	void setRO_uint8(uint8_t value)
+	{
+		structData_.RO_uint8 = value;
+	}
+	
+	/*!
+	 * \brief Get RO_int16 register.
+	 * \return value.
+	 */
+	int16_t getRO_int16() const
+	{
+		return structData_.RO_int16;
+	}
+
+	/*!
+	 * \brief Set RO_int16 register.
+	 * \param value to be set.
+	 */
+	void setRO_int16(int16_t value)
+	{
+		structData_.RO_int16 = value;
+	}
+	
+	/*!
+	 * \brief Get RO_uint16 register.
+	 * \return value.
+	 */
+	uint16_t getRO_uint16() const
+	{
+		return structData_.RO_uint16;
+	}
+
+	/*!
+	 * \brief Set RO_uint16 register.
+	 * \param value to be set.
+	 */
+	void setRO_uint16(uint16_t value)
+	{
+		structData_.RO_uint16 = value;
+	}
+	
+	/*!
+	 * \brief Get RO_int32 register.
+	 * \return value.
+	 */
+	int32_t getRO_int32() const
+	{
+		return structData_.RO_int32;
+	}
+
+	/*!
+	 * \brief Set RO_int32 register.
+	 * \param value to be set.
+	 */
+	void setRO_int32(int32_t value)
+	{
+		structData_.RO_int32 = value;
+	}
+	
+	/*!
+	 * \brief Get RO_uint32 register.
+	 * \return value.
+	 */
+	uint32_t getRO_uint32() const
+	{
+		return structData_.RO_uint32;
+	}
+
+	/*!
+	 * \brief Set RO_uint32 register.
+	 * \param value to be set.
+	 */
+	void setRO_uint32(uint32_t value)
+	{
+		structData_.RO_uint32 = value;
+	}
+	
+	/*!
+	 * \brief Get RO_float32 register.
+	 * \return value.
+	 */
+	float getRO_float32() const
+	{
+		return structData_.RO_float32;
+	}
+
+	/*!
+	 * \brief Set RO_float32 register.
+	 * \param value to be set.
+	 */
+	void setRO_float32(float value)
+	{
+		structData_.RO_float32 = value;
+	}
+	
+	/*!
+	 * \brief Get RO_string register.
+	 * \return value.
+	 */
+	std::string getRO_string() const
+	{
+		size_t len = (size_t)structData_.RO_string[1];
+		return std::string((char*)&(structData_.RO_string[2]), len);
+	}
+
+	/*!
+	 * \brief Set RO_string register.
+	 * \param value to be set.
+	 */
+	void setRO_string(const std::string &value)
+	{
+		size_t len = (value.length() < RO_stringLen_) ? value.length() : RO_stringLen_;
+		memcpy((char*)&(structData_.RO_string[2]), value.c_str(), len);
+		structData_.RO_string[0] = char(0);
+		structData_.RO_string[1] = char(len);
+	}
+	
+	/*!
+	 * \brief Get RO_date register.
+	 * \return value.
+	 */
+	double getRO_date() const
+	{
+		return structData_.RO_date;
+	}
+
+	/*!
+	 * \brief Set RO_date register.
+	 * \param value to be set.
+	 */
+	void setRO_date(double value)
+	{
+		structData_.RO_date = value;
+	}
+	
+	/*!
+	 * \brief Get RO_char register.
+	 * \return value.
+	 */
+	int8_t getRO_char() const
+	{
+		return structData_.RO_char;
+	}
+
+	/*!
+	 * \brief Set RO_char register.
+	 * \param value to be set.
+	 */
+	void setRO_char(int8_t value)
+	{
+		structData_.RO_char = value;
+	}
+	
+	/*!
+	 * \brief Get RO_byte register.
+	 * \return value.
+	 */
+	uint8_t getRO_byte() const
+	{
+		return structData_.RO_byte;
+	}
+
+	/*!
+	 * \brief Set RO_byte register.
+	 * \param value to be set.
+	 */
+	void setRO_byte(uint8_t value)
+	{
+		structData_.RO_byte = value;
+	}
+	
+	/*!
+	 * \brief Get RO_word register.
+	 * \return value.
+	 */
+	uint16_t getRO_word() const
+	{
+		return structData_.RO_word;
+	}
+
+	/*!
+	 * \brief Set RO_word register.
+	 * \param value to be set.
+	 */
+	void setRO_word(uint16_t value)
+	{
+		structData_.RO_word = value;
+	}
+	
+	/*!
+	 * \brief Get RO_dword register.
+	 * \return value.
+	 */
+	uint32_t getRO_dword() const
+	{
+		return structData_.RO_dword;
+	}
+
+	/*!
+	 * \brief Set RO_dword register.
+	 * \param value to be set.
+	 */
+	void setRO_dword(uint32_t value)
+	{
+		structData_.RO_dword = value;
+	}
+	
+	/*!
+	 * \brief Get RO_int register.
+	 * \return value.
+	 */
+	int16_t getRO_int() const
+	{
+		return structData_.RO_int;
+	}
+
+	/*!
+	 * \brief Set RO_int register.
+	 * \param value to be set.
+	 */
+	void setRO_int(int16_t value)
+	{
+		structData_.RO_int = value;
+	}
+	
+	/*!
+	 * \brief Get RO_dint register.
+	 * \return value.
+	 */
+	int32_t getRO_dint() const
+	{
+		return structData_.RO_dint;
+	}
+
+	/*!
+	 * \brief Set RO_dint register.
+	 * \param value to be set.
+	 */
+	void setRO_dint(int32_t value)
+	{
+		structData_.RO_dint = value;
+	}
+	
+	/*!
+	 * \brief Get RO_real register.
+	 * \return value.
+	 */
+	float getRO_real() const
+	{
+		return structData_.RO_real;
+	}
+
+	/*!
+	 * \brief Set RO_real register.
+	 * \param value to be set.
+	 */
+	void setRO_real(float value)
+	{
+		structData_.RO_real = value;
+	}
+	
+	/*!
+	 * \brief Get RO_dt register.
+	 * \return value.
+	 */
+	double getRO_dt() const
+	{
+		return structData_.RO_dt;
+	}
+
+	/*!
+	 * \brief Set RO_dt register.
+	 * \param value to be set.
+	 */
+	void setRO_dt(double value)
+	{
+		structData_.RO_dt = value;
+	}
+
+	virtual inline size_t getSize() const
+	{
+		return sizeof(structData_);
+	}
+
+	virtual void getData(unsigned char * data) const
+	{
+		memcpy(data, &structData_, this->getSize());
+	}
+
+	virtual void setData(unsigned char * data)
+	{
+		memcpy(&structData_, data, this->getSize());
+	}
+
+	virtual inline size_t getOffset() const { return 0; }
+
+	static const std::size_t RO_stringLen_ = 64;
+
+private:
+
+#pragma pack(push, 1)
+    struct
+    {
+		int8_t RO_int8;
+		uint8_t RO_uint8;
+		int16_t RO_int16;
+		uint16_t RO_uint16;
+		int32_t RO_int32;
+		uint32_t RO_uint32;
+		float RO_float32;
+		char RO_string[RO_stringLen_+2];
+		double RO_date;
+		int8_t RO_char;
+		uint8_t RO_byte;
+		uint16_t RO_word;
+		uint32_t RO_dword;
+		int16_t RO_int;
+		int32_t RO_dint;
+		float RO_real;
+		double RO_dt;
+
+    } structData_;
+#pragma pack(pop)
+	
+};
+
+class MyRWBlock : public SilecsServer::Block
+{
+public:
+    /*!
+     * \brief MyRWBlock constructor. It creates an empty block.
+     */
+    MyRWBlock() : SilecsServer::Block("AllTypes:MyRWBlock")
+    {
+    
+    }
+
+    ~MyRWBlock()
+    {
+    }
+    	
+	/*!
+	 * \brief Get array RW_int8 register.
+	 * \return value.
+	 */
+	void getRW_int8(int8_t* value) const
+	{
+		memcpy(value, &structData_.RW_int8, RW_int8Dim1_ * RW_int8Dim2_ * sizeof(int8_t));
+	}
+
+	/*!
+	 * \brief Set array RW_int8 register.
+	 * \param value to be set.
+	 */
+	void setRW_int8(int8_t* value)
+	{
+		memcpy(&structData_.RW_int8, value, RW_int8Dim1_ * RW_int8Dim2_ * sizeof(int8_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_uint8 register.
+	 * \return value.
+	 */
+	void getRW_uint8(uint8_t* value) const
+	{
+		memcpy(value, &structData_.RW_uint8, RW_uint8Dim1_ * RW_uint8Dim2_ * sizeof(uint8_t));
+	}
+
+	/*!
+	 * \brief Set array RW_uint8 register.
+	 * \param value to be set.
+	 */
+	void setRW_uint8(uint8_t* value)
+	{
+		memcpy(&structData_.RW_uint8, value, RW_uint8Dim1_ * RW_uint8Dim2_ * sizeof(uint8_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_int16 register.
+	 * \return value.
+	 */
+	void getRW_int16(int16_t* value) const
+	{
+		memcpy(value, &structData_.RW_int16, RW_int16Dim1_ * RW_int16Dim2_ * sizeof(int16_t));
+	}
+
+	/*!
+	 * \brief Set array RW_int16 register.
+	 * \param value to be set.
+	 */
+	void setRW_int16(int16_t* value)
+	{
+		memcpy(&structData_.RW_int16, value, RW_int16Dim1_ * RW_int16Dim2_ * sizeof(int16_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_uint16 register.
+	 * \return value.
+	 */
+	void getRW_uint16(uint16_t* value) const
+	{
+		memcpy(value, &structData_.RW_uint16, RW_uint16Dim1_ * RW_uint16Dim2_ * sizeof(uint16_t));
+	}
+
+	/*!
+	 * \brief Set array RW_uint16 register.
+	 * \param value to be set.
+	 */
+	void setRW_uint16(uint16_t* value)
+	{
+		memcpy(&structData_.RW_uint16, value, RW_uint16Dim1_ * RW_uint16Dim2_ * sizeof(uint16_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_int32 register.
+	 * \return value.
+	 */
+	void getRW_int32(int32_t* value) const
+	{
+		memcpy(value, &structData_.RW_int32, RW_int32Dim1_ * RW_int32Dim2_ * sizeof(int32_t));
+	}
+
+	/*!
+	 * \brief Set array RW_int32 register.
+	 * \param value to be set.
+	 */
+	void setRW_int32(int32_t* value)
+	{
+		memcpy(&structData_.RW_int32, value, RW_int32Dim1_ * RW_int32Dim2_ * sizeof(int32_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_uint32 register.
+	 * \return value.
+	 */
+	void getRW_uint32(uint32_t* value) const
+	{
+		memcpy(value, &structData_.RW_uint32, RW_uint32Dim1_ * RW_uint32Dim2_ * sizeof(uint32_t));
+	}
+
+	/*!
+	 * \brief Set array RW_uint32 register.
+	 * \param value to be set.
+	 */
+	void setRW_uint32(uint32_t* value)
+	{
+		memcpy(&structData_.RW_uint32, value, RW_uint32Dim1_ * RW_uint32Dim2_ * sizeof(uint32_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_float32 register.
+	 * \return value.
+	 */
+	void getRW_float32(float* value) const
+	{
+		memcpy(value, &structData_.RW_float32, RW_float32Dim1_ * RW_float32Dim2_ * sizeof(float));
+	}
+
+	/*!
+	 * \brief Set array RW_float32 register.
+	 * \param value to be set.
+	 */
+	void setRW_float32(float* value)
+	{
+		memcpy(&structData_.RW_float32, value, RW_float32Dim1_ * RW_float32Dim2_ * sizeof(float));
+	}
+	
+	/*!
+	 * \brief Get std::string RW_string register.
+	 * \param value buffer where the value will be stored.
+	 */
+	void getRW_string(std::string* value) const
+	{
+		for (std::size_t i = 0; i < RW_stringDim1_; i++)
+		{
+			size_t len = (size_t)structData_.RW_string[i][1];
+			value[i].assign(&(structData_.RW_string[i][2]), len);
+		}
+	}
+
+	/*!
+	 * \brief Set std::string RW_string register.
+	 * \param value to be set.
+	 */
+	void setRW_string(std::string* value)
+	{
+	    for (std::size_t i = 0; i < RW_stringDim1_; i++)
+		{
+		    size_t len = (value[i].length() < RW_stringLen_) ? value[i].length() : RW_stringLen_;
+			memcpy(&(structData_.RW_string[i][2]), value[i].c_str(), len);
+			structData_.RW_string[i][0] = char(0);
+			structData_.RW_string[i][1] = char(len);
+		}
+	}
+	
+	/*!
+	 * \brief Get array RW_date register.
+	 * \return value.
+	 */
+	void getRW_date(double* value) const
+	{
+		memcpy(value, &structData_.RW_date, RW_dateDim1_ * RW_dateDim2_ * sizeof(double));
+	}
+
+	/*!
+	 * \brief Set array RW_date register.
+	 * \param value to be set.
+	 */
+	void setRW_date(double* value)
+	{
+		memcpy(&structData_.RW_date, value, RW_dateDim1_ * RW_dateDim2_ * sizeof(double));
+	}
+	
+	/*!
+	 * \brief Get array RW_char register.
+	 * \return value.
+	 */
+	void getRW_char(int8_t* value) const
+	{
+		memcpy(value, &structData_.RW_char, RW_charDim1_ * RW_charDim2_ * sizeof(int8_t));
+	}
+
+	/*!
+	 * \brief Set array RW_char register.
+	 * \param value to be set.
+	 */
+	void setRW_char(int8_t* value)
+	{
+		memcpy(&structData_.RW_char, value, RW_charDim1_ * RW_charDim2_ * sizeof(int8_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_byte register.
+	 * \return value.
+	 */
+	void getRW_byte(uint8_t* value) const
+	{
+		memcpy(value, &structData_.RW_byte, RW_byteDim1_ * RW_byteDim2_ * sizeof(uint8_t));
+	}
+
+	/*!
+	 * \brief Set array RW_byte register.
+	 * \param value to be set.
+	 */
+	void setRW_byte(uint8_t* value)
+	{
+		memcpy(&structData_.RW_byte, value, RW_byteDim1_ * RW_byteDim2_ * sizeof(uint8_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_word register.
+	 * \return value.
+	 */
+	void getRW_word(uint16_t* value) const
+	{
+		memcpy(value, &structData_.RW_word, RW_wordDim1_ * RW_wordDim2_ * sizeof(uint16_t));
+	}
+
+	/*!
+	 * \brief Set array RW_word register.
+	 * \param value to be set.
+	 */
+	void setRW_word(uint16_t* value)
+	{
+		memcpy(&structData_.RW_word, value, RW_wordDim1_ * RW_wordDim2_ * sizeof(uint16_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_dword register.
+	 * \return value.
+	 */
+	void getRW_dword(uint32_t* value) const
+	{
+		memcpy(value, &structData_.RW_dword, RW_dwordDim1_ * RW_dwordDim2_ * sizeof(uint32_t));
+	}
+
+	/*!
+	 * \brief Set array RW_dword register.
+	 * \param value to be set.
+	 */
+	void setRW_dword(uint32_t* value)
+	{
+		memcpy(&structData_.RW_dword, value, RW_dwordDim1_ * RW_dwordDim2_ * sizeof(uint32_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_int register.
+	 * \return value.
+	 */
+	void getRW_int(int16_t* value) const
+	{
+		memcpy(value, &structData_.RW_int, RW_intDim1_ * RW_intDim2_ * sizeof(int16_t));
+	}
+
+	/*!
+	 * \brief Set array RW_int register.
+	 * \param value to be set.
+	 */
+	void setRW_int(int16_t* value)
+	{
+		memcpy(&structData_.RW_int, value, RW_intDim1_ * RW_intDim2_ * sizeof(int16_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_dint register.
+	 * \return value.
+	 */
+	void getRW_dint(int32_t* value) const
+	{
+		memcpy(value, &structData_.RW_dint, RW_dintDim1_ * RW_dintDim2_ * sizeof(int32_t));
+	}
+
+	/*!
+	 * \brief Set array RW_dint register.
+	 * \param value to be set.
+	 */
+	void setRW_dint(int32_t* value)
+	{
+		memcpy(&structData_.RW_dint, value, RW_dintDim1_ * RW_dintDim2_ * sizeof(int32_t));
+	}
+	
+	/*!
+	 * \brief Get array RW_real register.
+	 * \return value.
+	 */
+	void getRW_real(float* value) const
+	{
+		memcpy(value, &structData_.RW_real, RW_realDim1_ * RW_realDim2_ * sizeof(float));
+	}
+
+	/*!
+	 * \brief Set array RW_real register.
+	 * \param value to be set.
+	 */
+	void setRW_real(float* value)
+	{
+		memcpy(&structData_.RW_real, value, RW_realDim1_ * RW_realDim2_ * sizeof(float));
+	}
+	
+	/*!
+	 * \brief Get array RW_dt register.
+	 * \return value.
+	 */
+	void getRW_dt(double* value) const
+	{
+		memcpy(value, &structData_.RW_dt, RW_dtDim1_ * RW_dtDim2_ * sizeof(double));
+	}
+
+	/*!
+	 * \brief Set array RW_dt register.
+	 * \param value to be set.
+	 */
+	void setRW_dt(double* value)
+	{
+		memcpy(&structData_.RW_dt, value, RW_dtDim1_ * RW_dtDim2_ * sizeof(double));
+	}
+
+	virtual inline size_t getSize() const
+	{
+		return sizeof(structData_);
+	}
+
+	virtual void getData(unsigned char * data) const
+	{
+		memcpy(data, &structData_, this->getSize());
+	}
+
+	virtual void setData(unsigned char * data)
+	{
+		memcpy(&structData_, data, this->getSize());
+	}
+
+	virtual inline size_t getOffset() const { return 118; }
+
+	static const std::size_t RW_int8Dim1_ = 2;
+	static const std::size_t RW_int8Dim2_ = 2;
+	static const std::size_t RW_uint8Dim1_ = 2;
+	static const std::size_t RW_uint8Dim2_ = 2;
+	static const std::size_t RW_int16Dim1_ = 2;
+	static const std::size_t RW_int16Dim2_ = 2;
+	static const std::size_t RW_uint16Dim1_ = 2;
+	static const std::size_t RW_uint16Dim2_ = 2;
+	static const std::size_t RW_int32Dim1_ = 2;
+	static const std::size_t RW_int32Dim2_ = 2;
+	static const std::size_t RW_uint32Dim1_ = 2;
+	static const std::size_t RW_uint32Dim2_ = 2;
+	static const std::size_t RW_float32Dim1_ = 2;
+	static const std::size_t RW_float32Dim2_ = 2;
+	static const std::size_t RW_stringDim1_ = 2;
+	static const std::size_t RW_stringDim2_ = 2;
+	static const std::size_t RW_stringLen_ = 64;
+	static const std::size_t RW_dateDim1_ = 2;
+	static const std::size_t RW_dateDim2_ = 2;
+	static const std::size_t RW_charDim1_ = 2;
+	static const std::size_t RW_charDim2_ = 2;
+	static const std::size_t RW_byteDim1_ = 2;
+	static const std::size_t RW_byteDim2_ = 2;
+	static const std::size_t RW_wordDim1_ = 2;
+	static const std::size_t RW_wordDim2_ = 2;
+	static const std::size_t RW_dwordDim1_ = 2;
+	static const std::size_t RW_dwordDim2_ = 2;
+	static const std::size_t RW_intDim1_ = 2;
+	static const std::size_t RW_intDim2_ = 2;
+	static const std::size_t RW_dintDim1_ = 2;
+	static const std::size_t RW_dintDim2_ = 2;
+	static const std::size_t RW_realDim1_ = 2;
+	static const std::size_t RW_realDim2_ = 2;
+	static const std::size_t RW_dtDim1_ = 2;
+	static const std::size_t RW_dtDim2_ = 2;
+
+private:
+
+#pragma pack(push, 1)
+    struct
+    {
+		int8_t RW_int8[RW_int8Dim1_][RW_int8Dim2_];
+		uint8_t RW_uint8[RW_uint8Dim1_][RW_uint8Dim2_];
+		int16_t RW_int16[RW_int16Dim1_][RW_int16Dim2_];
+		uint16_t RW_uint16[RW_uint16Dim1_][RW_uint16Dim2_];
+		int32_t RW_int32[RW_int32Dim1_][RW_int32Dim2_];
+		uint32_t RW_uint32[RW_uint32Dim1_][RW_uint32Dim2_];
+		float RW_float32[RW_float32Dim1_][RW_float32Dim2_];
+		char RW_string[RW_stringDim1_][RW_stringDim2_][RW_stringLen_+2];
+		double RW_date[RW_dateDim1_][RW_dateDim2_];
+		int8_t RW_char[RW_charDim1_][RW_charDim2_];
+		uint8_t RW_byte[RW_byteDim1_][RW_byteDim2_];
+		uint16_t RW_word[RW_wordDim1_][RW_wordDim2_];
+		uint32_t RW_dword[RW_dwordDim1_][RW_dwordDim2_];
+		int16_t RW_int[RW_intDim1_][RW_intDim2_];
+		int32_t RW_dint[RW_dintDim1_][RW_dintDim2_];
+		float RW_real[RW_realDim1_][RW_realDim2_];
+		double RW_dt[RW_dtDim1_][RW_dtDim2_];
+
+    } structData_;
+#pragma pack(pop)
+	
+};
+
+class MyWOBlock : public SilecsServer::Block
+{
+public:
+    /*!
+     * \brief MyWOBlock constructor. It creates an empty block.
+     */
+    MyWOBlock() : SilecsServer::Block("AllTypes:MyWOBlock")
+    {
+    
+    }
+
+    ~MyWOBlock()
+    {
+    }
+    	
+	/*!
+	 * \brief Get array WO_int8 register.
+	 * \return value.
+	 */
+	void getWO_int8(int8_t* value) const
+	{
+		memcpy(value, &structData_.WO_int8, WO_int8Dim1_ * WO_int8Dim2_ * sizeof(int8_t));
+	}
+
+	/*!
+	 * \brief Set array WO_int8 register.
+	 * \param value to be set.
+	 */
+	void setWO_int8(int8_t* value)
+	{
+		memcpy(&structData_.WO_int8, value, WO_int8Dim1_ * WO_int8Dim2_ * sizeof(int8_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_uint8 register.
+	 * \return value.
+	 */
+	void getWO_uint8(uint8_t* value) const
+	{
+		memcpy(value, &structData_.WO_uint8, WO_uint8Dim1_ * WO_uint8Dim2_ * sizeof(uint8_t));
+	}
+
+	/*!
+	 * \brief Set array WO_uint8 register.
+	 * \param value to be set.
+	 */
+	void setWO_uint8(uint8_t* value)
+	{
+		memcpy(&structData_.WO_uint8, value, WO_uint8Dim1_ * WO_uint8Dim2_ * sizeof(uint8_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_int16 register.
+	 * \return value.
+	 */
+	void getWO_int16(int16_t* value) const
+	{
+		memcpy(value, &structData_.WO_int16, WO_int16Dim1_ * WO_int16Dim2_ * sizeof(int16_t));
+	}
+
+	/*!
+	 * \brief Set array WO_int16 register.
+	 * \param value to be set.
+	 */
+	void setWO_int16(int16_t* value)
+	{
+		memcpy(&structData_.WO_int16, value, WO_int16Dim1_ * WO_int16Dim2_ * sizeof(int16_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_uint16 register.
+	 * \return value.
+	 */
+	void getWO_uint16(uint16_t* value) const
+	{
+		memcpy(value, &structData_.WO_uint16, WO_uint16Dim1_ * WO_uint16Dim2_ * sizeof(uint16_t));
+	}
+
+	/*!
+	 * \brief Set array WO_uint16 register.
+	 * \param value to be set.
+	 */
+	void setWO_uint16(uint16_t* value)
+	{
+		memcpy(&structData_.WO_uint16, value, WO_uint16Dim1_ * WO_uint16Dim2_ * sizeof(uint16_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_int32 register.
+	 * \return value.
+	 */
+	void getWO_int32(int32_t* value) const
+	{
+		memcpy(value, &structData_.WO_int32, WO_int32Dim1_ * WO_int32Dim2_ * sizeof(int32_t));
+	}
+
+	/*!
+	 * \brief Set array WO_int32 register.
+	 * \param value to be set.
+	 */
+	void setWO_int32(int32_t* value)
+	{
+		memcpy(&structData_.WO_int32, value, WO_int32Dim1_ * WO_int32Dim2_ * sizeof(int32_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_uint32 register.
+	 * \return value.
+	 */
+	void getWO_uint32(uint32_t* value) const
+	{
+		memcpy(value, &structData_.WO_uint32, WO_uint32Dim1_ * WO_uint32Dim2_ * sizeof(uint32_t));
+	}
+
+	/*!
+	 * \brief Set array WO_uint32 register.
+	 * \param value to be set.
+	 */
+	void setWO_uint32(uint32_t* value)
+	{
+		memcpy(&structData_.WO_uint32, value, WO_uint32Dim1_ * WO_uint32Dim2_ * sizeof(uint32_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_float32 register.
+	 * \return value.
+	 */
+	void getWO_float32(float* value) const
+	{
+		memcpy(value, &structData_.WO_float32, WO_float32Dim1_ * WO_float32Dim2_ * sizeof(float));
+	}
+
+	/*!
+	 * \brief Set array WO_float32 register.
+	 * \param value to be set.
+	 */
+	void setWO_float32(float* value)
+	{
+		memcpy(&structData_.WO_float32, value, WO_float32Dim1_ * WO_float32Dim2_ * sizeof(float));
+	}
+	
+	/*!
+	 * \brief Get std::string WO_string register.
+	 * \param value buffer where the value will be stored.
+	 */
+	void getWO_string(std::string* value) const
+	{
+		for (std::size_t i = 0; i < WO_stringDim1_; i++)
+		{
+			size_t len = (size_t)structData_.WO_string[i][1];
+			value[i].assign(&(structData_.WO_string[i][2]), len);
+		}
+	}
+
+	/*!
+	 * \brief Set std::string WO_string register.
+	 * \param value to be set.
+	 */
+	void setWO_string(std::string* value)
+	{
+	    for (std::size_t i = 0; i < WO_stringDim1_; i++)
+		{
+		    size_t len = (value[i].length() < WO_stringLen_) ? value[i].length() : WO_stringLen_;
+			memcpy(&(structData_.WO_string[i][2]), value[i].c_str(), len);
+			structData_.WO_string[i][0] = char(0);
+			structData_.WO_string[i][1] = char(len);
+		}
+	}
+	
+	/*!
+	 * \brief Get array WO_date register.
+	 * \return value.
+	 */
+	void getWO_date(double* value) const
+	{
+		memcpy(value, &structData_.WO_date, WO_dateDim1_ * WO_dateDim2_ * sizeof(double));
+	}
+
+	/*!
+	 * \brief Set array WO_date register.
+	 * \param value to be set.
+	 */
+	void setWO_date(double* value)
+	{
+		memcpy(&structData_.WO_date, value, WO_dateDim1_ * WO_dateDim2_ * sizeof(double));
+	}
+	
+	/*!
+	 * \brief Get array WO_char register.
+	 * \return value.
+	 */
+	void getWO_char(int8_t* value) const
+	{
+		memcpy(value, &structData_.WO_char, WO_charDim1_ * WO_charDim2_ * sizeof(int8_t));
+	}
+
+	/*!
+	 * \brief Set array WO_char register.
+	 * \param value to be set.
+	 */
+	void setWO_char(int8_t* value)
+	{
+		memcpy(&structData_.WO_char, value, WO_charDim1_ * WO_charDim2_ * sizeof(int8_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_byte register.
+	 * \return value.
+	 */
+	void getWO_byte(uint8_t* value) const
+	{
+		memcpy(value, &structData_.WO_byte, WO_byteDim1_ * WO_byteDim2_ * sizeof(uint8_t));
+	}
+
+	/*!
+	 * \brief Set array WO_byte register.
+	 * \param value to be set.
+	 */
+	void setWO_byte(uint8_t* value)
+	{
+		memcpy(&structData_.WO_byte, value, WO_byteDim1_ * WO_byteDim2_ * sizeof(uint8_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_word register.
+	 * \return value.
+	 */
+	void getWO_word(uint16_t* value) const
+	{
+		memcpy(value, &structData_.WO_word, WO_wordDim1_ * WO_wordDim2_ * sizeof(uint16_t));
+	}
+
+	/*!
+	 * \brief Set array WO_word register.
+	 * \param value to be set.
+	 */
+	void setWO_word(uint16_t* value)
+	{
+		memcpy(&structData_.WO_word, value, WO_wordDim1_ * WO_wordDim2_ * sizeof(uint16_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_dword register.
+	 * \return value.
+	 */
+	void getWO_dword(uint32_t* value) const
+	{
+		memcpy(value, &structData_.WO_dword, WO_dwordDim1_ * WO_dwordDim2_ * sizeof(uint32_t));
+	}
+
+	/*!
+	 * \brief Set array WO_dword register.
+	 * \param value to be set.
+	 */
+	void setWO_dword(uint32_t* value)
+	{
+		memcpy(&structData_.WO_dword, value, WO_dwordDim1_ * WO_dwordDim2_ * sizeof(uint32_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_int register.
+	 * \return value.
+	 */
+	void getWO_int(int16_t* value) const
+	{
+		memcpy(value, &structData_.WO_int, WO_intDim1_ * WO_intDim2_ * sizeof(int16_t));
+	}
+
+	/*!
+	 * \brief Set array WO_int register.
+	 * \param value to be set.
+	 */
+	void setWO_int(int16_t* value)
+	{
+		memcpy(&structData_.WO_int, value, WO_intDim1_ * WO_intDim2_ * sizeof(int16_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_dint register.
+	 * \return value.
+	 */
+	void getWO_dint(int32_t* value) const
+	{
+		memcpy(value, &structData_.WO_dint, WO_dintDim1_ * WO_dintDim2_ * sizeof(int32_t));
+	}
+
+	/*!
+	 * \brief Set array WO_dint register.
+	 * \param value to be set.
+	 */
+	void setWO_dint(int32_t* value)
+	{
+		memcpy(&structData_.WO_dint, value, WO_dintDim1_ * WO_dintDim2_ * sizeof(int32_t));
+	}
+	
+	/*!
+	 * \brief Get array WO_real register.
+	 * \return value.
+	 */
+	void getWO_real(float* value) const
+	{
+		memcpy(value, &structData_.WO_real, WO_realDim1_ * WO_realDim2_ * sizeof(float));
+	}
+
+	/*!
+	 * \brief Set array WO_real register.
+	 * \param value to be set.
+	 */
+	void setWO_real(float* value)
+	{
+		memcpy(&structData_.WO_real, value, WO_realDim1_ * WO_realDim2_ * sizeof(float));
+	}
+	
+	/*!
+	 * \brief Get array WO_dt register.
+	 * \return value.
+	 */
+	void getWO_dt(double* value) const
+	{
+		memcpy(value, &structData_.WO_dt, WO_dtDim1_ * WO_dtDim2_ * sizeof(double));
+	}
+
+	/*!
+	 * \brief Set array WO_dt register.
+	 * \param value to be set.
+	 */
+	void setWO_dt(double* value)
+	{
+		memcpy(&structData_.WO_dt, value, WO_dtDim1_ * WO_dtDim2_ * sizeof(double));
+	}
+
+	virtual inline size_t getSize() const
+	{
+		return sizeof(structData_);
+	}
+
+	virtual void getData(unsigned char * data) const
+	{
+		memcpy(data, &structData_, this->getSize());
+	}
+
+	virtual void setData(unsigned char * data)
+	{
+		memcpy(&structData_, data, this->getSize());
+	}
+
+	virtual inline size_t getOffset() const { return 590; }
+
+	static const std::size_t WO_int8Dim1_ = 10;
+	static const std::size_t WO_int8Dim2_ = 1;
+	static const std::size_t WO_uint8Dim1_ = 10;
+	static const std::size_t WO_uint8Dim2_ = 1;
+	static const std::size_t WO_int16Dim1_ = 10;
+	static const std::size_t WO_int16Dim2_ = 1;
+	static const std::size_t WO_uint16Dim1_ = 10;
+	static const std::size_t WO_uint16Dim2_ = 1;
+	static const std::size_t WO_int32Dim1_ = 10;
+	static const std::size_t WO_int32Dim2_ = 1;
+	static const std::size_t WO_uint32Dim1_ = 10;
+	static const std::size_t WO_uint32Dim2_ = 1;
+	static const std::size_t WO_float32Dim1_ = 10;
+	static const std::size_t WO_float32Dim2_ = 1;
+	static const std::size_t WO_stringDim1_ = 10;
+	static const std::size_t WO_stringDim2_ = 1;
+	static const std::size_t WO_stringLen_ = 64;
+	static const std::size_t WO_dateDim1_ = 10;
+	static const std::size_t WO_dateDim2_ = 1;
+	static const std::size_t WO_charDim1_ = 10;
+	static const std::size_t WO_charDim2_ = 1;
+	static const std::size_t WO_byteDim1_ = 10;
+	static const std::size_t WO_byteDim2_ = 1;
+	static const std::size_t WO_wordDim1_ = 10;
+	static const std::size_t WO_wordDim2_ = 1;
+	static const std::size_t WO_dwordDim1_ = 10;
+	static const std::size_t WO_dwordDim2_ = 1;
+	static const std::size_t WO_intDim1_ = 10;
+	static const std::size_t WO_intDim2_ = 1;
+	static const std::size_t WO_dintDim1_ = 10;
+	static const std::size_t WO_dintDim2_ = 1;
+	static const std::size_t WO_realDim1_ = 10;
+	static const std::size_t WO_realDim2_ = 1;
+	static const std::size_t WO_dtDim1_ = 10;
+	static const std::size_t WO_dtDim2_ = 1;
+
+private:
+
+#pragma pack(push, 1)
+    struct
+    {
+		int8_t WO_int8[WO_int8Dim1_];
+		uint8_t WO_uint8[WO_uint8Dim1_];
+		int16_t WO_int16[WO_int16Dim1_];
+		uint16_t WO_uint16[WO_uint16Dim1_];
+		int32_t WO_int32[WO_int32Dim1_];
+		uint32_t WO_uint32[WO_uint32Dim1_];
+		float WO_float32[WO_float32Dim1_];
+		char WO_string[WO_stringDim1_][WO_stringLen_+2];
+		double WO_date[WO_dateDim1_];
+		int8_t WO_char[WO_charDim1_];
+		uint8_t WO_byte[WO_byteDim1_];
+		uint16_t WO_word[WO_wordDim1_];
+		uint32_t WO_dword[WO_dwordDim1_];
+		int16_t WO_int[WO_intDim1_];
+		int32_t WO_dint[WO_dintDim1_];
+		float WO_real[WO_realDim1_];
+		double WO_dt[WO_dtDim1_];
+
+    } structData_;
+#pragma pack(pop)
+	
+};
+
+
+
+class Device : public SilecsServer::Device
+{
+public:
+    Device(const std::string& label, size_t number):SilecsServer::Device(label, number)
+    {	
+		blockMap_["AllTypes:MyROBlock"] = new MyROBlock();
+		blockMap_["AllTypes:MyRWBlock"] = new MyRWBlock();
+		blockMap_["AllTypes:MyWOBlock"] = new MyWOBlock();    
+    }
+
+    ~Device()
+    {    
+		delete (blockMap_["AllTypes:MyROBlock"]);
+		delete (blockMap_["AllTypes:MyRWBlock"]);
+		delete (blockMap_["AllTypes:MyWOBlock"]);    
+    }
+};
+
+
+class Design : public SilecsServer::Design
+{
+public:
+
+    Design():SilecsServer::Design("AllTypes", "0.1.0")
+    {    
+		deviceMap_["AllTypes:testDevice1"] = new Device("AllTypes:testDevice1", 0);
+		deviceMap_["AllTypes:testDevice2"] = new Device("AllTypes:testDevice2", 1);    
+    }
+
+    ~Design()
+    {    
+		delete(deviceMap_["AllTypes:testDevice1"]);
+		delete(deviceMap_["AllTypes:testDevice2"]);    
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    AllTypes_0_1_0::Device* getDevice(const std::string& label)
+    {
+        if (deviceMap_.find(label) != deviceMap_.end())
+        {
+            return dynamic_cast<AllTypes_0_1_0::Device*>(deviceMap_[label]);
+        }
+        return NULL;
+    }
+};
+
+} /* namespace */
+#endif
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensDevice.SilecsHeader.h b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensDevice.SilecsHeader.h
new file mode 100644
index 0000000000000000000000000000000000000000..85ecca60a14438414a6e1df5a886a88b03802650
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensDevice.SilecsHeader.h
@@ -0,0 +1,203 @@
+
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef SILECSHEADER_1_0_0_H_
+#define SILECSHEADER_1_0_0_H_
+
+#include <silecs-virtual-controller/interface/Block.h>
+#include <silecs-virtual-controller/interface/DeployUnit.h>
+#include <silecs-virtual-controller/interface/Design.h>
+#include <silecs-virtual-controller/interface/Device.h>
+
+namespace SilecsHeader_1_0_0
+{
+
+class Design;
+
+class HdrBlk : public SilecsServer::Block
+{
+public:
+    /*!
+     * \brief hdrBlk constructor. It creates an empty block.
+     */
+    HdrBlk() : SilecsServer::Block("SilecsHeader:hdrBlk")
+    {
+    	set_version("DEV");
+		set_checksum(0X2110E2EA);
+		set_user("schwinn");
+		set_date(0.0);
+    }
+
+    ~HdrBlk()
+    {
+    }
+    	
+	/*!
+	 * \brief Get _version register.
+	 * \return value.
+	 */
+	std::string get_version() const
+	{
+		size_t len = (size_t)structData_._version[1];
+		return std::string((char*)&(structData_._version[2]), len);
+	}
+
+	/*!
+	 * \brief Set _version register.
+	 * \param value to be set.
+	 */
+	void set_version(const std::string &value)
+	{
+		size_t len = (value.length() < _versionLen_) ? value.length() : _versionLen_;
+		memcpy((char*)&(structData_._version[2]), value.c_str(), len);
+		structData_._version[0] = char(0);
+		structData_._version[1] = char(len);
+	}
+	
+	/*!
+	 * \brief Get _checksum register.
+	 * \return value.
+	 */
+	uint32_t get_checksum() const
+	{
+		return structData_._checksum;
+	}
+
+	/*!
+	 * \brief Set _checksum register.
+	 * \param value to be set.
+	 */
+	void set_checksum(uint32_t value)
+	{
+		structData_._checksum = value;
+	}
+	
+	/*!
+	 * \brief Get _user register.
+	 * \return value.
+	 */
+	std::string get_user() const
+	{
+		size_t len = (size_t)structData_._user[1];
+		return std::string((char*)&(structData_._user[2]), len);
+	}
+
+	/*!
+	 * \brief Set _user register.
+	 * \param value to be set.
+	 */
+	void set_user(const std::string &value)
+	{
+		size_t len = (value.length() < _userLen_) ? value.length() : _userLen_;
+		memcpy((char*)&(structData_._user[2]), value.c_str(), len);
+		structData_._user[0] = char(0);
+		structData_._user[1] = char(len);
+	}
+	
+	/*!
+	 * \brief Get _date register.
+	 * \return value.
+	 */
+	double get_date() const
+	{
+		return structData_._date;
+	}
+
+	/*!
+	 * \brief Set _date register.
+	 * \param value to be set.
+	 */
+	void set_date(double value)
+	{
+		structData_._date = value;
+	}
+
+	virtual inline size_t getSize() const
+	{
+		return sizeof(structData_);
+	}
+
+	virtual void getData(unsigned char * data) const
+	{
+		memcpy(data, &structData_, this->getSize());
+	}
+
+	virtual void setData(unsigned char * data)
+	{
+		memcpy(&structData_, data, this->getSize());
+	}
+
+	virtual inline size_t getOffset() const { return 0; }
+
+	static const std::size_t _versionLen_ = 16;
+	static const std::size_t _userLen_ = 16;
+
+private:
+
+#pragma pack(push, 1)
+    struct
+    {
+		char _version[_versionLen_+2];
+		uint32_t _checksum;
+		char _user[_userLen_+2];
+		double _date;
+
+    } structData_;
+#pragma pack(pop)
+	
+};
+
+
+
+class Device : public SilecsServer::Device
+{
+public:
+    Device(const std::string& label, size_t number):SilecsServer::Device(label, number)
+    {	
+		blockMap_["SilecsHeader:hdrBlk"] = new HdrBlk();    
+    }
+
+    ~Device()
+    {    
+		delete (blockMap_["SilecsHeader:hdrBlk"]);    
+    }
+};
+
+
+class Design : public SilecsServer::Design
+{
+public:
+
+    Design():SilecsServer::Design("SilecsHeader", "1.0.0")
+    {    
+		deviceMap_["SilecsHeader:SilecsHeader"] = new Device("SilecsHeader:SilecsHeader", 0);    
+    }
+
+    ~Design()
+    {    
+		delete(deviceMap_["SilecsHeader:SilecsHeader"]);    
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsHeader_1_0_0::Device* getDevice(const std::string& label)
+    {
+        if (deviceMap_.find(label) != deviceMap_.end())
+        {
+            return dynamic_cast<SilecsHeader_1_0_0::Device*>(deviceMap_[label]);
+        }
+        return NULL;
+    }
+};
+
+} /* namespace */
+#endif
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensDevice.cpp b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensDevice.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..43c22864b768a82ba2ad177475d15288ad6e606a
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensDevice.cpp
@@ -0,0 +1,33 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cstring>
+#include <iostream>
+
+#include <silecs-virtual-controller/core/SilecsSnap7Server.h>
+#include "Virtual_SiemensDevice.h"
+
+class UserSnap7Server : public SilecsServer::SilecsSnap7Server
+{
+public:
+    UserSnap7Server(Virtual_SiemensDevice::DeployUnit* du) : SilecsSnap7Server(du, true) {}
+    virtual ~UserSnap7Server() {}
+
+    virtual void userFunction()
+    {
+      // Implement the specific process control here!
+      // Look at SILECS Wikis: 'Create a virtual controller' chapter 
+    }
+};
+
+int main(int argc, char*argv[])
+{
+    Virtual_SiemensDevice::DeployUnit du;
+    UserSnap7Server server(&du);
+    if (server.startServer() < 0)
+    {
+        std::cout << "Failed to start the VC server: " << du.getName() << std::endl;
+        return -1;
+    }
+    return 0;
+}
diff --git a/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensDevice.h b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensDevice.h
new file mode 100644
index 0000000000000000000000000000000000000000..1827c94a58cd3d50d26a1f866c1c11978e3ccfb0
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/controller/Virtual_SiemensDevice.h
@@ -0,0 +1,53 @@
+
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef VIRTUAL_SIEMENSDEVICE_H_
+#define VIRTUAL_SIEMENSDEVICE_H_
+
+#include <silecs-virtual-controller/interface/DeployUnit.h>
+#include <silecs-virtual-controller/interface/Design.h>
+#include "SilecsHeader_1.0.0.h"
+#include "AllTypes_0.1.0.h"
+
+
+namespace Virtual_SiemensDevice
+{
+
+class DeployUnit : public SilecsServer::DeployUnit
+{
+public:
+
+	DeployUnit() : SilecsServer::DeployUnit("Virtual_SiemensDevice", SilecsServer::S7Protocol, SilecsServer::DeviceMode, 0)
+	{
+    	mapDesigns_["SilecsHeader"] = new SilecsHeader_1_0_0::Design();
+	mapDesigns_["AllTypes"] = new AllTypes_0_1_0::Design();
+	}
+
+    ~DeployUnit()
+    {
+    	delete mapDesigns_["SilecsHeader"];
+	delete mapDesigns_["AllTypes"];
+	}
+
+	SilecsHeader_1_0_0::Design* getSilecsHeader()
+	{
+		return dynamic_cast<SilecsHeader_1_0_0::Design*>(mapDesigns_["SilecsHeader"]);
+	}
+	
+	AllTypes_0_1_0::Design* getAllTypes()
+	{
+		return dynamic_cast<AllTypes_0_1_0::Design*>(mapDesigns_["AllTypes"]);
+	}
+	
+};
+
+}
+
+#endif
diff --git a/silecs-codegen/src/xml/test/generated_temp/wrapper/AllTypes.h b/silecs-codegen/src/xml/test/generated_temp/wrapper/AllTypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..5900b5b05a12e769dd10eaab1b40f0757b103ce5
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/wrapper/AllTypes.h
@@ -0,0 +1,38 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPES_H_
+#define ALLTYPES_H_
+
+#include <silecs-communication/wrapper/Block.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+#include <silecs-communication/wrapper/Device.h>
+
+namespace AllTypes
+{
+
+
+class Design : public SilecsWrapper::Design
+{
+public:
+
+    Design(SilecsWrapper::DeployUnit *deployUnit) :
+                    SilecsWrapper::Design("AllTypes", "0.1.0", deployUnit)
+    {
+    }
+
+    ~Design()
+    {
+    }
+};
+
+} /* namespace AllTypes */
+
+#endif /* ALLTYPES_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_temp/wrapper/Beckhoff_BC9020.h b/silecs-codegen/src/xml/test/generated_temp/wrapper/Beckhoff_BC9020.h
new file mode 100644
index 0000000000000000000000000000000000000000..0434b104410b92134dbbb0e3e0f81f9b3107225a
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/wrapper/Beckhoff_BC9020.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Beckhoff_BC9020", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_temp/wrapper/Beckhoff_CX9020.h b/silecs-codegen/src/xml/test/generated_temp/wrapper/Beckhoff_CX9020.h
new file mode 100644
index 0000000000000000000000000000000000000000..7feef9927fc34162e92a9b9abc6b623f81eda5fc
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/wrapper/Beckhoff_CX9020.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Beckhoff_CX9020", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_temp/wrapper/Rabbit_BlockMode.h b/silecs-codegen/src/xml/test/generated_temp/wrapper/Rabbit_BlockMode.h
new file mode 100644
index 0000000000000000000000000000000000000000..c5620055cf7af94d6996aae076cc93076ae8fc41
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/wrapper/Rabbit_BlockMode.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Rabbit_BlockMode", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_temp/wrapper/Rabbit_DeviceMode.h b/silecs-codegen/src/xml/test/generated_temp/wrapper/Rabbit_DeviceMode.h
new file mode 100644
index 0000000000000000000000000000000000000000..a90d775c078fbd3334d2bbff7aab429f7e46f6a5
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/wrapper/Rabbit_DeviceMode.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Rabbit_DeviceMode", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_temp/wrapper/Schneider_M340.h b/silecs-codegen/src/xml/test/generated_temp/wrapper/Schneider_M340.h
new file mode 100644
index 0000000000000000000000000000000000000000..d31fa177a7b23b5b220ff1548ba7ffbea13267ad
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/wrapper/Schneider_M340.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Schneider_M340", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_temp/wrapper/Schneider_PremiumQuantum.h b/silecs-codegen/src/xml/test/generated_temp/wrapper/Schneider_PremiumQuantum.h
new file mode 100644
index 0000000000000000000000000000000000000000..58576f6facb5e61e418f31f9350c6aff7a0ea63b
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/wrapper/Schneider_PremiumQuantum.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Schneider_PremiumQuantum", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_temp/wrapper/Siemens_Step7Block.h b/silecs-codegen/src/xml/test/generated_temp/wrapper/Siemens_Step7Block.h
new file mode 100644
index 0000000000000000000000000000000000000000..9e32650f2ac7cd5376ac08e3f6e70ab22ab0942d
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/wrapper/Siemens_Step7Block.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Siemens_Step7Block", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_temp/wrapper/Siemens_Step7Device.h b/silecs-codegen/src/xml/test/generated_temp/wrapper/Siemens_Step7Device.h
new file mode 100644
index 0000000000000000000000000000000000000000..be5bd8a0ecafcca89b0fae15e2a2f1f4cc20c8d6
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/wrapper/Siemens_Step7Device.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Siemens_Step7Device", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_temp/wrapper/Siemens_TiaBlock.h b/silecs-codegen/src/xml/test/generated_temp/wrapper/Siemens_TiaBlock.h
new file mode 100644
index 0000000000000000000000000000000000000000..63877a39a230d8894c569d4de058e6b2c3273c70
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/wrapper/Siemens_TiaBlock.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Siemens_TiaBlock", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_temp/wrapper/Siemens_TiaDevice.h b/silecs-codegen/src/xml/test/generated_temp/wrapper/Siemens_TiaDevice.h
new file mode 100644
index 0000000000000000000000000000000000000000..e6a302939e50d1631e9cd16bc3601015035ef975
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/wrapper/Siemens_TiaDevice.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Siemens_TiaDevice", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_temp/wrapper/Virtual_SiemensBlock.h b/silecs-codegen/src/xml/test/generated_temp/wrapper/Virtual_SiemensBlock.h
new file mode 100644
index 0000000000000000000000000000000000000000..1681d8b22ba04770f1b3adf8cbd197212341b0dc
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/wrapper/Virtual_SiemensBlock.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Virtual_SiemensBlock", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/generated_temp/wrapper/Virtual_SiemensDevice.h b/silecs-codegen/src/xml/test/generated_temp/wrapper/Virtual_SiemensDevice.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b1ef2728a190215f7d3a31e8fba210523c18be4
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_temp/wrapper/Virtual_SiemensDevice.h
@@ -0,0 +1,153 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef ALLTYPESDU_H_
+#define ALLTYPESDU_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "AllTypes.h"
+
+namespace AllTypesDU
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (logTopics.empty() == false)
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design AllTypes.
+     */
+    AllTypes::Design* getAllTypes()
+    {
+        return _AllTypes;
+    }
+
+private:
+
+    AllTypes::Design* _AllTypes;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("AllTypesDU", "0.1.0", logTopics, globalConfig)
+    {
+        // Construct Design AllTypes
+        _AllTypes = new AllTypes::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _AllTypes;
+    }
+};
+
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(SilecsWrapper::Design *design, const std::string parameterFile) :
+                    SilecsWrapper::Controller("Virtual_SiemensDevice", "", design, parameterFile)
+    {
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice1", new SilecsWrapper::Device("testDevice1", this)));
+            _deviceMap.insert(std::pair<std::string, SilecsWrapper::Device*>("testDevice2", new SilecsWrapper::Device("testDevice2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, SilecsWrapper::Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    SilecsWrapper::Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, SilecsWrapper::Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice1.
+     */
+    SilecsWrapper::Device* getTestDevice1()
+    {
+        return _deviceMap["testDevice1"];
+    }
+    
+    /*!
+     * \brief Get pointer to device testDevice2.
+     */
+    SilecsWrapper::Device* getTestDevice2()
+    {
+        return _deviceMap["testDevice2"];
+    }
+    
+private:
+    std::map<std::string, SilecsWrapper::Device*> _deviceMap;
+};
+
+
+} /* namespace AllTypesDU */
+
+#endif /* ALLTYPESDU_H_ */
diff --git a/silecs-codegen/src/xml/test/testBase.py b/silecs-codegen/src/xml/test/testBase.py
new file mode 100644
index 0000000000000000000000000000000000000000..7d9b48793b390d8a7d495e85216c2d41a665f6e6
--- /dev/null
+++ b/silecs-codegen/src/xml/test/testBase.py
@@ -0,0 +1,96 @@
+import sys
+import os
+import difflib
+
+import inspect #get caller name
+
+def assertEqual( a, b ):
+    if a != b:
+        callerInfo = str(inspect.stack()[1][3]) + ":" + str(inspect.stack()[1][2])
+        print "Test Failed: " + callerInfo + "\nVariables are different. Var1: '" + str(a) + "' Var2: '" + str(b) + "'"
+        sys.exit(1)
+    else:
+         print "success: " + str(inspect.stack()[1][3])
+
+def assertTrue( condition ):
+    if not condition:
+        callerInfo = str(inspect.stack()[1][3]) + ":" + str(inspect.stack()[1][2])
+        print "Test Failed: " + callerInfo + "\nCondition expected to be True, but was False"
+        sys.exit(1)
+    else:
+         print "success: " + str(inspect.stack()[1][3])
+
+def assertFalse( condition ):
+    if condition:
+        callerInfo = str(inspect.stack()[1][3]) + ":" + str(inspect.stack()[1][2])
+        print "Test Failed: " + callerInfo + "\nCondition expected to be False, but was True"
+        sys.exit(1)
+    else:
+         print "success: " + str(inspect.stack()[1][3])
+
+def assertPLCCodeEqual(filePath1,filePath2):
+    with open(filePath1) as a: a_content = a.readlines()
+    with open(filePath2) as b: b_content = b.readlines()
+    diff = difflib.unified_diff(a_content,b_content)
+    isDifferent = False
+    for i,line in enumerate(diff):
+        if i < 2:
+            print("first 2 lines ignored .. unknown reason why they differ")
+        elif ("DT#" in line) or ("SILECS_set_dt" in  line) :  #ignore timestamps in silecsheader
+            print("date ignored")
+        elif line.startswith("-"):
+            isDifferent = True
+            print(i,' '+line)
+        elif line.startswith("+"):
+            isDifferent = True
+            print(i,' '+line)
+    if isDifferent:
+        print "Test Failed: The files: " + filePath1 + ", " + filePath2 + " are different from each other !"
+        sys.exit(1)
+    else:
+         print "success: " + str(inspect.stack()[1][3])
+
+def assertParameterFileEqual(filePath1,filePath2):
+    with open(filePath1) as a: a_content = a.readlines()
+    with open(filePath2) as b: b_content = b.readlines()
+    diff = difflib.unified_diff(a_content,b_content)
+    isDifferent = False
+    for i,line in enumerate(diff):
+        if i < 2:
+            print("first 2 lines ignored .. unknown reason why they differ")
+        elif ("<Generation date=" in line) :  #ignore timestamps
+            print("date ignored")
+        elif line.startswith("-"):
+            isDifferent = True
+            print(i,' '+line)
+        elif line.startswith("+"):
+            isDifferent = True
+            print(i,' '+line)
+    if isDifferent:
+        print "Test Failed: The files: " + filePath1 + ", " + filePath2 + " are different from each other !"
+        sys.exit(1)
+    else:
+         print "success: " + str(inspect.stack()[1][3])
+
+def assertFileEqual(filePath1,filePath2):
+    with open(filePath1) as a: a_content = a.readlines()
+    with open(filePath2) as b: b_content = b.readlines()
+    diff = difflib.unified_diff(a_content,b_content)
+    isDifferent = False
+    for i,line in enumerate(diff):
+        if i < 2:
+            print("first 2 lines ignored .. unknown reason why they differ")
+        elif line.startswith("-"):
+            isDifferent = True
+            print(i,' '+line)
+        elif line.startswith("+"):
+            isDifferent = True
+            print(i,' '+line)
+    if isDifferent:
+        print "Test Failed: The files: " + filePath1 + ", " + filePath2 + " are different from each other !"
+        sys.exit(1)
+    else:
+         print "success: " + str(inspect.stack()[1][3])
+
+def allTestsOk( ):
+         print "All tests for module: " + str(inspect.stack()[1][1]) + " run green! "
diff --git a/silecs-codegen/src/xml/test/testBase.pyc b/silecs-codegen/src/xml/test/testBase.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..33c9ce59bed3581ab2a4b5dfcd393bf3aa0d69e8
Binary files /dev/null and b/silecs-codegen/src/xml/test/testBase.pyc differ
diff --git a/silecs-codegen/src/xml/virtualS7Template.py b/silecs-codegen/src/xml/virtualS7Template.py
new file mode 100644
index 0000000000000000000000000000000000000000..abdd3fadd84c5d1ed104a260c58e7721437e8978
--- /dev/null
+++ b/silecs-codegen/src/xml/virtualS7Template.py
@@ -0,0 +1,498 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+
+# Description:
+# This module implement the methods to build each components of the sources.
+# A component source consists of one 'parameterizable' text that can
+# be specialized on call to append the string to be stored in the file.
+#
+
+import string
+import struct
+import iecommon
+
+#-------------------------------------------------------------------------
+# Hash-Table
+
+whichRegisterFormat = {
+	'uint8'   : 'uint8_t',
+	'int8'    : 'int8_t',
+	'uint16'  : 'uint16_t',
+	'int16'   : 'int16_t',
+	'uint32'  : 'uint32_t',
+	'int32'   : 'int32_t',
+	'float32' : 'float',
+	'uint64'  : 'uint64_t',
+	'int64'   : 'int64_t',
+    'string'  : 'string',    
+	'float64' : 'double',
+	'date'    : 'double',
+   	'char'	:'int8_t',
+    'byte'	:'uint8_t',
+    'word'	:'uint16_t',
+    'dword'	:'uint32_t',
+    'int'	:'int16_t',
+    'dint'	:'int32_t',
+    'real'	:'float',
+    'dt'	:'double'
+}
+
+#=========================================================================
+# Virtual S7 DEPLOY-UNIT template
+#=========================================================================
+
+duDesignInclude = """#include "%s_%s.h"
+"""
+
+duConstructor = """DeployUnit() : SilecsServer::DeployUnit("%s", SilecsServer::S7Protocol, SilecsServer::%s, %s)
+"""
+
+duDesignAlloc = """	mapDesigns_["%s"] = new %s_%s::Design();
+"""
+
+duDesignDelete = """	delete mapDesigns_["%s"];
+"""
+
+duDesignGet = """	%s_%s::Design* get%s()
+	{
+		return dynamic_cast<%s_%s::Design*>(mapDesigns_["%s"]);
+	}
+	
+"""
+
+duHeader = """
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef %s_H_
+#define %s_H_
+
+#include <silecs-virtual-controller/interface/DeployUnit.h>
+#include <silecs-virtual-controller/interface/Design.h>
+%s
+
+namespace %s
+{
+
+class DeployUnit : public SilecsServer::DeployUnit
+{
+public:
+
+	%s	{
+    %s	}
+
+    ~DeployUnit()
+    {
+    %s	}
+
+%s};
+
+}
+
+#endif
+"""
+
+mainCode = """
+#include <stdio.h>
+#include <stdlib.h>
+#include <cstring>
+#include <iostream>
+
+#include <silecs-virtual-controller/core/SilecsSnap7Server.h>
+#include "%s.h"
+
+class UserSnap7Server : public SilecsServer::SilecsSnap7Server
+{
+public:
+    UserSnap7Server(%s::DeployUnit* du) : SilecsSnap7Server(du, true) {}
+    virtual ~UserSnap7Server() {}
+
+    virtual void userFunction()
+    {
+      // Implement the specific process control here!
+      // Look at SILECS Wikis: 'Create a virtual controller' chapter 
+    }
+};
+
+int main(int argc, char*argv[])
+{
+    %s::DeployUnit du;
+    UserSnap7Server server(&du);
+    if (server.startServer() < 0)
+    {
+        std::cout << "Failed to start the VC server: " << du.getName() << std::endl;
+        return -1;
+    }
+    return 0;
+}
+"""
+
+
+#=========================================================================
+# Virtual S7 CLASS template
+#=========================================================================
+classScalarGetSet = """	
+	/*!
+	 * \\brief Get %s register.
+	 * \\return value.
+	 */
+	%s get%s() const
+	{
+		return structData_.%s;
+	}
+
+	/*!
+	 * \\brief Set %s register.
+	 * \\param value to be set.
+	 */
+	void set%s(%s value)
+	{
+		structData_.%s = value;
+	}
+"""
+
+classArrayGetSet = """	
+	/*!
+	 * \\brief Get array %s register.
+	 * \\return value.
+	 */
+	void get%s(%s* value) const
+	{
+		memcpy(value, &structData_.%s, %sDim1_ * %sDim2_ * sizeof(%s));
+	}
+
+	/*!
+	 * \\brief Set array %s register.
+	 * \\param value to be set.
+	 */
+	void set%s(%s* value)
+	{
+		memcpy(&structData_.%s, value, %sDim1_ * %sDim2_ * sizeof(%s));
+	}
+"""
+
+classScalarStringGetSet = """	
+	/*!
+	 * \\brief Get %s register.
+	 * \\return value.
+	 */
+	std::string get%s() const
+	{
+		size_t len = (size_t)structData_.%s[1];
+		return std::string((char*)&(structData_.%s[2]), len);
+	}
+
+	/*!
+	 * \\brief Set %s register.
+	 * \\param value to be set.
+	 */
+	void set%s(const std::string &value)
+	{
+		size_t len = (value.length() < %sLen_) ? value.length() : %sLen_;
+		memcpy((char*)&(structData_.%s[2]), value.c_str(), len);
+		structData_.%s[0] = char(0);
+		structData_.%s[1] = char(len);
+	}
+"""
+
+classArrayStringGetSet = """	
+	/*!
+	 * \\brief Get std::string %s register.
+	 * \\param value buffer where the value will be stored.
+	 */
+	void get%s(std::string* value) const
+	{
+		for (std::size_t i = 0; i < %sDim1_; i++)
+		{
+			size_t len = (size_t)structData_.%s[i][1];
+			value[i].assign(&(structData_.%s[i][2]), len);
+		}
+	}
+
+	/*!
+	 * \\brief Set std::string %s register.
+	 * \\param value to be set.
+	 */
+	void set%s(std::string* value)
+	{
+	    for (std::size_t i = 0; i < %sDim1_; i++)
+		{
+		    size_t len = (value[i].length() < %sLen_) ? value[i].length() : %sLen_;
+			memcpy(&(structData_.%s[i][2]), value[i].c_str(), len);
+			structData_.%s[i][0] = char(0);
+			structData_.%s[i][1] = char(len);
+		}
+	}
+"""
+
+classHeaderInit = """	set_version("%s");
+		set_checksum(%s);
+		set_user("%s");
+		set_date(0.0);"""
+
+classBlock = """
+class %s : public SilecsServer::Block
+{
+public:
+    /*!
+     * \\brief %s constructor. It creates an empty block.
+     */
+    %s() : SilecsServer::Block("%s:%s")
+    {
+    %s
+    }
+
+    ~%s()
+    {
+    }
+    %s
+	virtual inline size_t getSize() const
+	{
+		return sizeof(structData_);
+	}
+
+	virtual void getData(unsigned char * data) const
+	{
+		memcpy(data, &structData_, this->getSize());
+	}
+
+	virtual void setData(unsigned char * data)
+	{
+		memcpy(&structData_, data, this->getSize());
+	}
+
+	virtual inline size_t getOffset() const { return %s; }
+
+%s
+private:
+
+#pragma pack(push, 1)
+    struct
+    {
+%s
+    } structData_;
+#pragma pack(pop)
+	
+};
+"""
+
+classArrayDim = """	static const std::size_t %sDim1_ = %s;
+	static const std::size_t %sDim2_ = %s;
+"""
+
+classStringLen = """	static const std::size_t %sLen_ = %s;
+"""
+
+classCreateBlock = """
+		blockMap_["%s:%s"] = new %s();"""
+
+classDeleteBlock = """
+		delete (blockMap_["%s:%s"]);"""
+
+classDevice = """
+class Device : public SilecsServer::Device
+{
+public:
+    Device(const std::string& label, size_t number):SilecsServer::Device(label, number)
+    {	%s    
+    }
+
+    ~Device()
+    {    %s    
+    }
+};"""
+
+classCreateDevice = """
+		deviceMap_["%s:%s"] = new Device("%s:%s", %s);"""
+
+classDeleteDevice = """
+		delete(deviceMap_["%s:%s"]);"""
+
+classDesign = """
+class Design : public SilecsServer::Design
+{
+public:
+
+    Design():SilecsServer::Design("%s", "%s")
+    {    %s    
+    }
+
+    ~Design()
+    {    %s    
+    }
+
+    /*!
+     * \\brief Return pointer to the requested device.
+     * \\param label Device label.
+     */
+    %s_%s::Device* getDevice(const std::string& label)
+    {
+        if (deviceMap_.find(label) != deviceMap_.end())
+        {
+            return dynamic_cast<%s_%s::Device*>(deviceMap_[label]);
+        }
+        return NULL;
+    }
+};"""
+
+classHeader = """
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef %s_%s_H_
+#define %s_%s_H_
+
+#include <silecs-virtual-controller/interface/Block.h>
+#include <silecs-virtual-controller/interface/DeployUnit.h>
+#include <silecs-virtual-controller/interface/Design.h>
+#include <silecs-virtual-controller/interface/Device.h>
+
+namespace %s_%s
+{
+
+class Design;
+%s
+
+%s
+
+%s
+
+} /* namespace */
+#endif
+"""
+
+
+#=========================================================================
+# Virtual S7 generation Sub-function
+#=========================================================================
+
+# SERVER MAIN code generation ---------------------------------------------
+def vs7MainCode(deployName):
+    return mainCode %(deployName, deployName, deployName)
+     
+# DEPLOY-UNIT generation -------------------------------------------------
+def vs7DuHeader(deployName, duConstructor, designIncludes, designAllocs, designDeletes, designGetters):
+    return duHeader %(deployName.upper(), deployName.upper(), designIncludes, deployName, duConstructor, designAllocs, designDeletes, designGetters)  
+   
+def vs7DuDesignInclude(designName, designVersion):
+    return duDesignInclude %(designName, designVersion)
+
+def vs7DuConstructor(deployName, mode, baseAddr):
+    return duConstructor %(deployName, mode, baseAddr)
+   
+def vs7DuDesignAlloc(designName, designVersion):
+    designVersion = designVersion.replace(".", "_")
+    return duDesignAlloc %(designName, designName, designVersion)
+   
+def vs7DuDesignDelete(designName):
+    return duDesignDelete %(designName)
+
+def vs7DuDesignGet(designName, designVersion):
+    designVersion = designVersion.replace(".", "_")
+    return duDesignGet %(designName, designVersion, designName, designName, designVersion, designName)
+
+# CLASSES generation -----------------------------------------------------
+def hexSwap32(input):
+    input = format(input, '#02X')
+    hexswap = input[0:2]+input[8:10]+input[6:8]+input[4:6]+input[2:4]
+    return hexswap  
+   
+def vs7ClassHeader(designName, designVersion, classBlocks, classDevice, classDesign):
+    designVersion = designVersion.replace(".", "_")
+    return classHeader %(designName.upper(), designVersion, designName.upper(), designVersion, designName, designVersion, classBlocks, classDevice, classDesign)  
+
+def vs7ClassBlock(framework, owner, checksum, className, blockName, regsCode, blockOffset, regsDim, regsDef):
+    BlockName = iecommon.capitalizeString(blockName);
+    initCodeString = ""
+    if className == "SilecsHeader":
+        initCodeString = classHeaderInit %(framework, hexSwap32(checksum), owner)   
+    return classBlock %(BlockName, blockName, BlockName, className, blockName, initCodeString, BlockName, regsCode, blockOffset, regsDim, regsDef)
+
+def vs7ClassGetSet(regName, regFormat, regDim1, regDim2, regLen):
+    RegName = iecommon.capitalizeString(regName)
+    regFormat = whichRegisterFormat[regFormat]
+    if regDim1 == 1 and regDim2 == 1:	# scalar
+        if regFormat == 'string':
+            return classScalarStringGetSet %(regName, RegName, regName, regName, regName, RegName, regName, regName, regName, regName, regName)
+        else:
+            return classScalarGetSet %(regName, regFormat, RegName, regName, regName, RegName, regFormat, regName)
+    else:
+        if regFormat == 'string':
+            return classArrayStringGetSet %(regName, RegName, regName, regName, regName, regName, RegName, regName, regName, regName, regName, regName, regName)
+        else:
+            return classArrayGetSet %(regName, RegName, regFormat, regName, regName, regName, regFormat, regName, RegName, regFormat, regName, regName, regName, regFormat)
+
+def vs7ClassDimension(regName, regFormat, regDim1, regDim2, regLen):
+    dimCodeString = ''
+    if regDim1 > 1 or regDim2 > 1:	# not a scalar ==> define dimension constants
+        dimCodeString += classArrayDim %(regName, regDim1, regName, regDim2)
+    if regFormat == 'string':
+        dimCodeString += classStringLen %(regName, regLen)
+    return dimCodeString
+
+def vs7ClassDummyRegister(curRegAddress, prevRegMemSize, regMemSize, dummyIndex):
+    dummyCodeString = ''
+    if curRegAddress % 2 != 0: #is current register address an odd address?
+        if prevRegMemSize > 1 or regMemSize > 1:   #only 8bit scalar (not following array) uses 8bit alignment! 
+            dummyCodeString = "		uint8_t dummy%s;\n" %(dummyIndex)
+    return dummyCodeString
+
+def vs7ClassDataRegister(regName, regFormat, regDim1, regDim2, regLen):
+    length = ''
+    regFormat = whichRegisterFormat[regFormat]
+    if regFormat == 'string':
+        length = "[%sLen_+2]" %(regName)
+        regFormat = 'char'
+    dataCodeString = "		%s %s" %(regFormat, regName)
+    if regDim1 > 1 or regDim2 > 1:    # not scalar
+        dataCodeString += "[%sDim1_]" %(regName)    
+        if regDim2 > 1:    # not scalar
+            dataCodeString += "[%sDim2_]" %(regName)
+    dataCodeString += "%s;\n" %(length)
+    return dataCodeString
+
+def vs7ClassCreateBlock(className, blockName):
+    BlockName = iecommon.capitalizeString(blockName);
+    return classCreateBlock %(className, blockName, BlockName)
+
+def vs7ClassDeleteBlock(className, blockName):
+    return classDeleteBlock %(className, blockName)
+
+def vs7ClassCreateDevice(className, deviceLabel, deviceIndex):
+    return classCreateDevice %(className, deviceLabel, className, deviceLabel, deviceIndex)
+
+def vs7ClassDeleteDevice(className, deviceLabel):
+    return classDeleteDevice %(className, deviceLabel)
+
+def vs7ClassDevice(createBlocks, deleteBlocks):
+    return classDevice %(createBlocks, deleteBlocks)
+
+def vs7ClassDesign(className, classVersion, createDevices, deleteDevices):
+    class_version = classVersion.replace(".", "_")
+    return classDesign %(className, classVersion, createDevices, deleteDevices, className, class_version, className, class_version)
diff --git a/silecs-codegen/src/xml/virtualS7Template.pyc b/silecs-codegen/src/xml/virtualS7Template.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..14d69d4be02f12e948ad1b478c0404b33e6a1da7
Binary files /dev/null and b/silecs-codegen/src/xml/virtualS7Template.pyc differ
diff --git a/silecs-codegen/src/xml/xmltemplate$py.class b/silecs-codegen/src/xml/xmltemplate$py.class
new file mode 100644
index 0000000000000000000000000000000000000000..34dd9a3fce4319d640e1fe4cf9f38d94e2eaccd6
Binary files /dev/null and b/silecs-codegen/src/xml/xmltemplate$py.class differ
diff --git a/silecs-codegen/src/xml/xmltemplate.py b/silecs-codegen/src/xml/xmltemplate.py
new file mode 100644
index 0000000000000000000000000000000000000000..19bdc3fc4404084281753a785d3fa9047d369c2d
--- /dev/null
+++ b/silecs-codegen/src/xml/xmltemplate.py
@@ -0,0 +1,92 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+import time
+import getpass
+
+#=========================================================
+# SILECS Header
+#=========================================================
+silecsHeader = """<?xml version="1.0" encoding="UTF-8"?>
+<SILECS-Design silecs-version="%s" created="%s" updated="%s" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Information>
+        <Owner user-login="%s"/>
+        <Editor user-login="%s"/>
+    </Information>
+  <SILECS-Class domain="TEST" name="SilecsHeader" version="1.0.0">
+    <Block mode="READ-ONLY" name="hdrBlk">
+      <Register array-dim1="1" array-dim2="1" format="string" name="_version" string-len="16" synchro="MASTER"/>
+      <Register array-dim1="1" array-dim2="1" format="uint32" name="_checksum" synchro="MASTER"/>
+      <Register array-dim1="1" array-dim2="1" format="string" name="_user" string-len="16" synchro="MASTER"/>
+      <Register array-dim1="1" array-dim2="1" format="dt" name="_date" synchro="MASTER"/>
+    </Block>
+  </SILECS-Class>
+</SILECS-Design>
+"""
+def getSilecsHeader(silecsVersion):
+	date = time.strftime("%x")
+	owner = getpass.getuser()
+	return silecsHeader%(silecsVersion,date,date,owner,owner)
+
+#=========================================================
+# DESIGN TEMPLATE
+#=========================================================
+designTemplate = """<?xml version="1.0" encoding="UTF-8"?>
+<SILECS-Design silecs-version="%s" created="%s" updated="%s" 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="%s">
+    <Information>
+        <Owner user-login="%s"/>
+        <Editor user-login="%s"/>
+    </Information>
+    <SILECS-Class name="%s" version="0.1.0" domain="OPERATIONAL" >
+        <Block name="MyBlock" mode="READ-ONLY" generateFesaProperty="true">
+            <Register name="myRegister" format="int32" synchro="MASTER" generateFesaValueItem="true" />
+        </Block>
+    </SILECS-Class>
+</SILECS-Design>
+"""
+def getDesignTemplate(designName,schemaPath,silecsVersion):
+	date = time.strftime("%x")
+	owner = getpass.getuser()
+	return designTemplate%(silecsVersion,date,date,schemaPath,owner,owner,designName)
+
+
+#=========================================================
+# DEPLOY TEMPLATE
+#=========================================================
+deployTemplate = """<?xml version="1.0" encoding="UTF-8"?>
+<SILECS-Deploy silecs-version="%s" created="%s" updated="%s" 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="%s">
+    <Information>
+        <Owner user-login="%s"/>
+        <Editor user-login="%s"/>
+    </Information>
+    <Deploy-Unit name="%s" version="0.1.0"/>
+	<Controller host-name="">
+	    <Siemens-PLC system="TIA-PORTAL" model="SIMATIC_S7-300" protocol="DEVICE_MODE" base-DB-number="1"/>
+		<SilecsDesign silecs-design-version="" silecs-design-name="">
+			<Device device-name="" />
+		</SilecsDesign>
+	</Controller>
+</SILECS-Deploy>
+"""
+
+def getDeployTemplate(deployName, schemaPath, silecsVersion):
+	date = time.strftime("%x")
+	owner = getpass.getuser()
+	return deployTemplate%(silecsVersion,date,date,schemaPath,owner,owner,deployName)
diff --git a/silecs-codegen/src/xml/xmltemplate.pyc b/silecs-codegen/src/xml/xmltemplate.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..46d3c492178e07ac49213bf454153fc49bf7aa15
Binary files /dev/null and b/silecs-codegen/src/xml/xmltemplate.pyc differ
diff --git a/silecs-communication-cpp/.cproject b/silecs-communication-cpp/.cproject
new file mode 100644
index 0000000000000000000000000000000000000000..b71572d468506db98ca65fa2f567d08fccbdd09b
--- /dev/null
+++ b/silecs-communication-cpp/.cproject
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.512849333">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.512849333" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.512849333" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug">
+					<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.512849333." name="/" resourcePath="">
+						<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.291928248" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
+							<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.787865719" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
+							<builder buildPath="${workspace_loc:/silecs-communication-cpp}" id="cdt.managedbuild.target.gnu.builder.exe.debug.1509177360" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
+							<tool id="cdt.managedbuild.tool.gnu.archiver.base.1070762906" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+							<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.290909559" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
+								<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1848198526" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
+								<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.240667535" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
+								<option id="gnu.cpp.compiler.option.include.paths.773424835" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
+									<listOptionValue builtIn="false" value="/acc/sys/L866/usr/include/libxml2"/>
+									<listOptionValue builtIn="false" value="/acc/sys/L866/usr/local/natinst/ninetv/include"/>
+								</option>
+								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1806199416" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.926882765" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
+								<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.116711054" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/>
+								<option id="gnu.c.compiler.exe.debug.option.debugging.level.1551801327" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
+								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.2005171832" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1604657084" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/>
+							<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.2022173025" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug">
+								<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1144333070" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.713866492" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
+								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1838795874" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+							</tool>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry excluding="src" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+		<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.10628772">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.10628772" moduleId="org.eclipse.cdt.core.settings" name="Release">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.10628772" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
+					<folderInfo id="cdt.managedbuild.config.gnu.exe.release.10628772." name="/" resourcePath="">
+						<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.1581125062" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
+							<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.2014534690" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
+							<builder buildPath="${workspace_loc:/silecs-communication-cpp}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1372487654" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
+							<tool id="cdt.managedbuild.tool.gnu.archiver.base.1846481553" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+							<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1485392940" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
+								<option id="gnu.cpp.compiler.exe.release.option.optimization.level.1550802779" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
+								<option id="gnu.cpp.compiler.exe.release.option.debugging.level.298964746" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
+								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.2075338207" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.1258122871" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
+								<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.674087208" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/>
+								<option id="gnu.c.compiler.exe.release.option.debugging.level.391864083" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
+								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1302098703" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.1792257196" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/>
+							<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.121789533" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release">
+								<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1798359589" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.1548384146" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
+								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.317662810" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+							</tool>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry excluding="src" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="silecs-communication-cpp.cdt.managedbuild.target.gnu.exe.86499621" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.512849333;cdt.managedbuild.config.gnu.exe.debug.512849333.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.290909559;cdt.managedbuild.tool.gnu.cpp.compiler.input.1806199416">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.10628772;cdt.managedbuild.config.gnu.exe.release.10628772.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.1258122871;cdt.managedbuild.tool.gnu.c.compiler.input.1302098703">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.10628772;cdt.managedbuild.config.gnu.exe.release.10628772.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1485392940;cdt.managedbuild.tool.gnu.cpp.compiler.input.2075338207">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.512849333;cdt.managedbuild.config.gnu.exe.debug.512849333.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.926882765;cdt.managedbuild.tool.gnu.c.compiler.input.2005171832">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/silecs-communication-cpp"/>
+		</configuration>
+		<configuration configurationName="Release">
+			<resource resourceType="PROJECT" workspacePath="/silecs-communication-cpp"/>
+		</configuration>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
+		<buildTargets>
+			<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+				<buildCommand>make</buildCommand>
+				<buildArguments/>
+				<buildTarget>clean</buildTarget>
+				<stopOnError>true</stopOnError>
+				<useDefaultCommand>true</useDefaultCommand>
+				<runAllBuilders>true</runAllBuilders>
+			</target>
+			<target name="x86_64" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+				<buildCommand>make</buildCommand>
+				<buildTarget>CPU=x86_64 -j4</buildTarget>
+				<stopOnError>true</stopOnError>
+				<useDefaultCommand>true</useDefaultCommand>
+				<runAllBuilders>true</runAllBuilders>
+			</target>
+			<target name="release" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+				<buildCommand>make</buildCommand>
+				<buildArguments/>
+				<buildTarget>release RELEASE_GROUP=bel RELEASE_LOCATION=~ SVN_REPOSITORY=https://www-acc.gsi.de/svn/silecs/silecs-communication-cpp</buildTarget>
+				<stopOnError>true</stopOnError>
+				<useDefaultCommand>true</useDefaultCommand>
+				<runAllBuilders>true</runAllBuilders>
+			</target>
+		</buildTargets>
+	</storageModule>
+</cproject>
diff --git a/silecs-communication-cpp/.project b/silecs-communication-cpp/.project
new file mode 100644
index 0000000000000000000000000000000000000000..230d8b7ef6e734a4385dce18584f989654909864
--- /dev/null
+++ b/silecs-communication-cpp/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>silecs-communication-cpp</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.python.pydev.PyDevBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.core.ccnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+		<nature>org.python.pydev.pythonNature</nature>
+	</natures>
+</projectDescription>
diff --git a/silecs-communication-cpp/LICENSE b/silecs-communication-cpp/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..20d40b6bceca3a6c0237d7455ebf1820aeff3680
--- /dev/null
+++ b/silecs-communication-cpp/LICENSE
@@ -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>.
\ No newline at end of file
diff --git a/silecs-communication-cpp/Makefile b/silecs-communication-cpp/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..b6f166c75132a6913b75555b26a148870c4115d8
--- /dev/null
+++ b/silecs-communication-cpp/Makefile
@@ -0,0 +1,32 @@
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+PROJECT = silecs
+PRODUCT = communication
+VERSION = 1.0.4
+
+COMMON_MAKE_PATH ?= /opt/cern/buildsystem/generic/2.8.20
+
+# product configuration
+LIB_NAME = comm
+DBG = true
+
+COMPILER_FLAGS = -Os -fno-strict-aliasing -fexceptions -DLINUX -DARM_FIX -DDAVE_LITTLE_ENDIAN -D_GNU_SOURCE -DMAJOR=$(MAJOR) -DMINOR=$(MINOR) -DPATCH=$(PATCH)
+
+# Comment IN/Out to enable NI-Support
+#COMPILER_FLAGS += -DNI_SUPPORT_ENABLED=TRUE
+
+# Include the generic make file
+include $(COMMON_MAKE_PATH)/Make.generic
\ No newline at end of file
diff --git a/silecs-communication-cpp/Makefile.dep b/silecs-communication-cpp/Makefile.dep
new file mode 100644
index 0000000000000000000000000000000000000000..09e84717b392f028ac6e1bf451cb307e82caa7ee
--- /dev/null
+++ b/silecs-communication-cpp/Makefile.dep
@@ -0,0 +1,9 @@
+BOOST_VERSION ?= 1.54.0
+
+LIBXML_PATH = /usr/include/libxml2/
+SNAP7_BASE = ../snap7/snap7-full
+BOOST_HOME ?= /acc/local/$(CPU)/3rdparty/boost/$(BOOST_VERSION)
+
+DEPENDENT_COMPILER_OPTIONS += -I$(LIBXML_PATH)
+DEPENDENT_COMPILER_OPTIONS += -I$(SNAP7_BASE)/release/Wrappers/c-cpp
+DEPENDENT_COMPILER_OPTIONS += -I$(BOOST_HOME)/include
\ No newline at end of file
diff --git a/silecs-communication-cpp/README.md b/silecs-communication-cpp/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..62bc0e13ef24782174ea977388c214a7efbd894f
--- /dev/null
+++ b/silecs-communication-cpp/README.md
@@ -0,0 +1,19 @@
+# silecs-codegen
+
+This component of the SILECS PLC-framework establishes a PLC-connection by using brand-specific protocols
+
+## Getting Started
+
+Please check the lab-specific SILECS-Wikis for more information:
+
+[CERN SILECS Wiki Page][CERN_Wiki]
+
+[GSI SILECS Wiki Page][GSI_Wiki]
+
+## License
+
+Licensed under the GNU GENERAL PUBLIC LICENSE Version 3. See the [LICENSE file][license] for details.
+
+[license]: LICENSE
+[CERN_Wiki]: https://wikis.cern.ch/display/SIL/SILECs+Home
+[GSI_Wiki]: https://www-acc.gsi.de/wiki/Frontend/SILECS
\ No newline at end of file
diff --git a/silecs-communication-cpp/docs/Doxyfile b/silecs-communication-cpp/docs/Doxyfile
new file mode 100644
index 0000000000000000000000000000000000000000..a15894487e3824d9247cd68ca899d1232488992a
--- /dev/null
+++ b/silecs-communication-cpp/docs/Doxyfile
@@ -0,0 +1,1519 @@
+# Doxyfile 1.6.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = SILECS
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 1.m.p
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = ../API
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = NO
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = NO
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses.
+# With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this tag.
+# The format is ext=language, where ext is a file extension, and language is one of
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran),
+# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING = 
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penality.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will rougly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = NO
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = YES
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = NO
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = NO
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = NO
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = NO
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST = YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = NO
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
+# doxygen. The layout file controls the global structure of the generated output files
+# in an output format independent way. The create the layout file that represents
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name
+# of the layout file.
+
+LAYOUT_FILE = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = ../../src/interface/equipment ../../src/interface/utility/SilecsException.h ../../src/interface/core/SilecsService.h
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS = 
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS = *Block*
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER = 
+
+# If the HTML_TIMESTAMP tag is set to YES then the generated HTML
+# documentation will contain the timesstamp.
+
+HTML_TIMESTAMP = NO
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
+# are set, an additional index file will be generated that can be used as input for
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
+# HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = 
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.
+# For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION = 
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP)
+# there is already a search function so this one should typically
+# be disabled.
+
+SEARCHENGINE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE = 
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA = 
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH = 
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
diff --git a/silecs-communication-cpp/install.sh b/silecs-communication-cpp/install.sh
new file mode 100755
index 0000000000000000000000000000000000000000..002fbec4454e3b085e73da87f9f874e11dacffda
--- /dev/null
+++ b/silecs-communication-cpp/install.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+set -e
+
+INSTALL_DIR=$1
+
+SCRIPT=$(readlink -f "$0")
+SCRIPTPATH=$(dirname "$SCRIPT")     # path where this script is located in
+
+mkdir -p ${INSTALL_DIR}
+cp -r ${SCRIPTPATH}/build/include ${INSTALL_DIR}
+cp -r ${SCRIPTPATH}/build/lib ${INSTALL_DIR}
\ No newline at end of file
diff --git a/silecs-communication-cpp/make-ctb.py b/silecs-communication-cpp/make-ctb.py
new file mode 100644
index 0000000000000000000000000000000000000000..a93fdaebe4f8a53370c44a51711c75d345bc71ba
--- /dev/null
+++ b/silecs-communication-cpp/make-ctb.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+
+import os
+import sys
+
+depVersion = 'SILECS_MAKEFILE_VERSION=DEV RDA_VERSION=DEV'
+ctbPaths = 'RELEASE_LOCATION=/local/RELEASE_LOCATION'
+makeFlags = ' RELEASE_GROUP=si ' + depVersion + ' ' + ctbPaths
+
+# compile first as we can't use -j in local-devrelease
+cmd = 'make -j4' + makeFlags
+rc = os.system(cmd + ' CPU=L865')
+if(rc != 0):
+  sys.exit(-1)
+  
+rc = os.system(cmd + ' CPU=L866')
+if(rc != 0):
+  sys.exit(-1)
+  
+# now release ==========================================
+cmd = 'make local-devrelease' + makeFlags + ' TMP_DIR=.'
+rc = os.system(cmd + ' CPU=L865')
+if(rc != 0):
+  sys.exit(-1)
+  
+rc = os.system(cmd + ' CPU=L866')
+if(rc != 0):
+  sys.exit(-1)
+ 
\ No newline at end of file
diff --git a/silecs-communication-cpp/releaseSilecs.sh b/silecs-communication-cpp/releaseSilecs.sh
new file mode 100755
index 0000000000000000000000000000000000000000..999031f56a31c484809e24deb0be0e1f17f7f28b
--- /dev/null
+++ b/silecs-communication-cpp/releaseSilecs.sh
@@ -0,0 +1,87 @@
+#!/bin/sh
+set -e
+
+# Usage examples:
+# first you need to source this script, so that you can use it's methods:
+# $ source releaseSilecs.sh
+#
+# release a new version v1.0.0
+# $ release 1.0.0 /common/usr/cscofe/silecs /home/bel/schwinn/lnx/workspace-silecs-mars
+#
+# patch 2 packages of an existing version 1.2.3
+# $ patch silecs-codegen 1.2.4 1.2.3 /common/usr/cscofe/silecs /home/bel/schwinn/lnx/workspace-silecs-mars
+# $ patch silecs-model 1.2.4 1.2.3 /common/usr/cscofe/silecs /home/bel/schwinn/lnx/workspace-silecs-mars
+#
+# release a new version of the silecs-eclipse plugin
+# $ plugin_release /common/usr/cscofe/silecs /home/bel/schwinn/lnx/workspace-silecs-mars
+
+# List of silecs packages which is released or patched
+PACKAGES="silecs-codegen silecs-model silecs-communication-cpp silecs-diagnostic-cpp snap7"
+
+# releases all silecs-packages to release-dir
+function release
+{
+    VERSION=$1
+    RELEASE_DIR_BASE=$2
+    WORKSPACE=$3
+    
+    for PACKAGE in $PACKAGES; do
+        INSTALL_DIR=${RELEASE_DIR_BASE}/${PACKAGE}/${VERSION}
+        if [ -d ${INSTALL_DIR} ]; then 
+            echo "Error: Silecs version ${VERSION} is already installed in ${INSTALL_DIR}. Exiting now."
+            return 1
+        else
+            echo "installing ${INSTALL_DIR} from ${WORKSPACE}/${PACKAGE}"
+            ${WORKSPACE}/${PACKAGE}/install.sh ${INSTALL_DIR}
+        fi
+    done
+    return 0
+}
+
+function plugin_release
+{
+    RELEASE_DIR_BASE=$1
+    WORKSPACE=$2
+    PACKAGE=silecs-eclipse-plugin-update-site
+    INSTALL_DIR=${RELEASE_DIR_BASE}/${PACKAGE}
+    echo "installing ${INSTALL_DIR} from ${WORKSPACE}/${PACKAGE}"
+    ${WORKSPACE}/${PACKAGE}/install.sh ${INSTALL_DIR}
+}
+    
+# releases a specific package to release-dir. For all other packages symlinks to the base-version are generated
+function patch
+{
+    PACKAGE_TO_PATCH=$1
+    NEW_VERSION=$2
+    BASE_VERSION=$3
+    RELEASE_DIR_BASE=$4
+    WORKSPACE=$5
+
+    for PACKAGE in $PACKAGES; do
+        INSTALL_DIR=${RELEASE_DIR_BASE}/${PACKAGE}/${NEW_VERSION}
+        BASE_DIR=${RELEASE_DIR_BASE}/${PACKAGE}/${BASE_VERSION}
+        if [ "$PACKAGE" == "$PACKAGE_TO_PATCH" ]; then
+            if [ -d ${INSTALL_DIR} ]; then
+               if [ -L ${INSTALL_DIR} ]; then 
+                  # Replace Sym-Link with patch-version ... needed if more than one package is patched for the same version
+                  unlink ${INSTALL_DIR}
+                  echo "installing ${INSTALL_DIR} from ${WORKSPACE}/${PACKAGE}"
+                  ${WORKSPACE}/${PACKAGE}/install.sh ${INSTALL_DIR}
+               else
+                  echo "Error: Silecs version ${NEW_VERSION} of package ${PACKAGE} is already installed in ${INSTALL_DIR}. Exiting now."
+                  return 1
+               fi
+            else
+               echo "installing ${INSTALL_DIR} from ${WORKSPACE}/${PACKAGE}"
+               ${WORKSPACE}/${PACKAGE}/install.sh ${INSTALL_DIR}
+            fi
+        else
+           if [ ! -d ${INSTALL_DIR} ]; then
+                # no patched version for this package available --> link to base-version
+                echo "Symbolic link to base version '${BASE_VERSION}' created for package '${PACKAGE}' of version '${NEW_VERSION}'"
+                ln -s ${BASE_VERSION} ${INSTALL_DIR}
+            fi
+        fi
+    done
+    return 0
+}
\ No newline at end of file
diff --git a/silecs-communication-cpp/src/demo/Cfp774Simatic400_1_0_0.h b/silecs-communication-cpp/src/demo/Cfp774Simatic400_1_0_0.h
new file mode 100644
index 0000000000000000000000000000000000000000..257e9d2446997f434883b3b0a3b36e2007b8fb9a
--- /dev/null
+++ b/silecs-communication-cpp/src/demo/Cfp774Simatic400_1_0_0.h
@@ -0,0 +1,108 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef CFP774SIMATIC400_1_0_0_H_
+#define CFP774SIMATIC400_1_0_0_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+#include "SilecsHeader_1_0_0.h"
+#include "SilecsValid_1_0_0.h"
+
+namespace Cfp774Simatic400_1_0_0
+{
+
+typedef SilecsWrapper::DeployConfig DeployConfig;
+typedef SilecsWrapper::DesignConfig DesignConfig;
+class DeployUnit : public SilecsWrapper::DeployUnit
+{
+public:
+
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param logTopics This parameter can be used to enable/disable log topics
+     * valid topics are ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK].
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const std::string& logTopics = "",
+            const SilecsWrapper::DeployConfig& globalConfig = SilecsWrapper::DeployConfig())
+    {
+        if (_instance == NULL)
+        {
+            _instance = new DeployUnit(logTopics, globalConfig);
+        }
+        else
+        {
+            if (not logTopics.empty())
+            {
+                _instance->getService()->setLogTopics(logTopics);
+            }
+        }
+//        DeployUnit::_globalConfig = globalConfig;
+        return dynamic_cast<DeployUnit*>(_instance);
+    }
+    
+    /*!
+     * \brief Use this method to create/get the unique instance of the Deploy Unit.
+     *
+     * \param globalConfig This parameter can be used to pass different parameters to
+     * the library. I.e. enabling automatic connection.
+     */
+    static DeployUnit* getInstance(const SilecsWrapper::DeployConfig& globalConfig)
+    {
+        return getInstance("", globalConfig);
+    }
+    
+    /*!
+     * \brief Return pointer to the deployed design SilecsHeader.
+     */
+    SilecsHeader_1_0_0::Design* getSilecsHeader()
+    {
+        return _SilecsHeader;
+    }
+
+    /*!
+     * \brief Return pointer to the deployed design SilecsValid.
+     */
+    SilecsValid_1_0_0::Design* getSilecsValid()
+    {
+        return _SilecsValid;
+    }
+
+private:
+
+    SilecsHeader_1_0_0::Design* _SilecsHeader;
+    SilecsValid_1_0_0::Design* _SilecsValid;
+
+    DeployUnit(const std::string& logTopics, const SilecsWrapper::DeployConfig& globalConfig) :
+                    SilecsWrapper::DeployUnit("Cfp774Simatic400_1_0_0", "1.0.0", logTopics, globalConfig)
+    {
+        // Construct Design SilecsHeader_1_0_0
+        _SilecsHeader = new SilecsHeader_1_0_0::Design((SilecsWrapper::DeployUnit*) this);
+        
+        // Construct Design SilecsValid_1_0_0
+        _SilecsValid = new SilecsValid_1_0_0::Design((SilecsWrapper::DeployUnit*) this);
+        
+    }
+    
+    ~DeployUnit()
+    {
+        delete _SilecsHeader;
+        delete _SilecsValid;
+    }
+};
+
+} /* namespace Cfp774Simatic400_1_0_0 */
+
+#endif /* CFP774SIMATIC400_1_0_0_H_ */
diff --git a/silecs-communication-cpp/src/demo/Doxyfile b/silecs-communication-cpp/src/demo/Doxyfile
new file mode 100644
index 0000000000000000000000000000000000000000..3cc4af2f4d7ae6db2f689145759d0d9303d49a69
--- /dev/null
+++ b/silecs-communication-cpp/src/demo/Doxyfile
@@ -0,0 +1,1519 @@
+# Doxyfile 1.6.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = demo
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 1.m.p
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = ../../demo/doc
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = NO
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = NO
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses.
+# With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this tag.
+# The format is ext=language, where ext is a file extension, and language is one of
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran),
+# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING = 
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penality.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will rougly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = NO
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = YES
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = NO
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = NO
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = NO
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = NO
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST = YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = NO
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
+# doxygen. The layout file controls the global structure of the generated output files
+# in an output format independent way. The create the layout file that represents
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name
+# of the layout file.
+
+LAYOUT_FILE = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = .
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS = 
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS = *Block*
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER = 
+
+# If the HTML_TIMESTAMP tag is set to YES then the generated HTML
+# documentation will contain the timesstamp.
+
+HTML_TIMESTAMP = NO
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
+# are set, an additional index file will be generated that can be used as input for
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
+# HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = 
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.
+# For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION = 
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP)
+# there is already a search function so this one should typically
+# be disabled.
+
+SEARCHENGINE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE = 
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA = 
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH = 
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
diff --git a/silecs-communication-cpp/src/demo/SilecsHeader_1_0_0.h b/silecs-communication-cpp/src/demo/SilecsHeader_1_0_0.h
new file mode 100644
index 0000000000000000000000000000000000000000..31bce374f4d6ce2e45243b99c7e46d3d387c8ccd
--- /dev/null
+++ b/silecs-communication-cpp/src/demo/SilecsHeader_1_0_0.h
@@ -0,0 +1,269 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef SILECSHEADER_1_0_0_H_
+#define SILECSHEADER_1_0_0_H_
+
+#include <silecs-communication/wrapper/Block.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+#include <silecs-communication/wrapper/Device.h>
+
+namespace SilecsHeader_1_0_0
+{
+
+class Design;
+
+class HdrBlk : public SilecsWrapper::Block
+{
+public:
+    /*!
+     * \brief hdrBlk constructor. It creates an empty block.
+     */
+    HdrBlk() :
+                    SilecsWrapper::Block("hdrBlk"),
+                    _checksum(0),
+                    _date(0)
+    {
+    }
+
+    ~HdrBlk()
+    {
+    }
+
+    /*!
+     * \brief Get _version register.
+     * \return value.
+     */
+    const std::string& get_version() const
+    {
+        return _version;
+    }
+
+    /*!
+     * \brief Set _version register.
+     * \param value to be set.
+     */
+    void set_version(const std::string& value)
+    {
+        _version = value;
+    }
+
+    /*!
+     * \brief Get _checksum register.
+     * \return value.
+     */
+    uint32_t get_checksum() const
+    {
+        return _checksum;
+    }
+
+    /*!
+     * \brief Set _checksum register.
+     * \param value to be set.
+     */
+    void set_checksum(uint32_t value)
+    {
+        _checksum = value;
+    }
+
+    /*!
+     * \brief Get _user register.
+     * \return value.
+     */
+    const std::string& get_user() const
+    {
+        return _user;
+    }
+
+    /*!
+     * \brief Set _user register.
+     * \param value to be set.
+     */
+    void set_user(const std::string& value)
+    {
+        _user = value;
+    }
+
+    /*!
+     * \brief Get _date register.
+     * \return value.
+     */
+    double get_date() const
+    {
+        return _date;
+    }
+
+    /*!
+     * \brief Set _date register.
+     * \param value to be set.
+     */
+    void set_date(double value)
+    {
+        _date = value;
+    }
+private:
+    std::string _version;
+    uint32_t _checksum;
+    std::string _user;
+    double _date;
+
+};
+class Device : public SilecsWrapper::Device
+{
+public:
+    Device(const std::string& label, SilecsWrapper::Controller *controller) :
+                    SilecsWrapper::Device(label, controller)
+    {
+    }
+
+    ~Device()
+    {
+    }
+    
+    /*!
+     * \brief Get hdrBlk block. 
+     * \param block HdrBlk reference where to store returned value.
+     */
+    void getHdrBlk(HdrBlk &block)
+    {
+        // Copy register _version
+        block.set_version(getSilecsDevice()->getRegister("_version")->getValString());
+        // Copy register _checksum
+        block.set_checksum(getSilecsDevice()->getRegister("_checksum")->getValUInt32());
+        // Copy register _user
+        block.set_user(getSilecsDevice()->getRegister("_user")->getValString());
+        // Copy register _date
+        block.set_date(getSilecsDevice()->getRegister("_date")->getValDate());
+    }
+    
+
+    /*!
+     * \brief Receive hdrBlk block for current device.
+     */
+    void receiveHdrBlk()
+    {
+        _silecsDevice->recv("hdrBlk");
+    }
+    
+
+};
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(const std::string& name, const std::string& domain, Design *design) :
+                    SilecsWrapper::Controller(name, domain, (SilecsWrapper::Design*) design)
+    {
+            _deviceMap.insert(std::pair<std::string, Device*>("0", new Device("0", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    /*!
+     * \brief Receive hdrBlk blocks from all devices of current controller.
+     */
+    void receiveHdrBlkAllDevices()
+    {
+        _silecsPLC->recv("hdrBlk");
+    }
+    
+private:
+    std::map<std::string, Device*> _deviceMap;
+};
+
+class Design : public SilecsWrapper::Design
+{
+public:
+
+    Design(SilecsWrapper::DeployUnit *deployUnit) :
+                    SilecsWrapper::Design("SilecsHeader", "1.0.0", deployUnit)
+    {
+
+            _controllerMap.insert(
+                std::pair<std::string, Controller*>("cfp-774-csimatic-s7-02",
+                        new Controller("cfp-774-csimatic-s7-02", "TST", this)));
+
+    }
+
+    ~Design()
+    {
+        map<std::string, Controller*>::iterator it;
+        for (it = _controllerMap.begin(); it != _controllerMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested controller.
+     * \param name Controller's name.
+     */
+    Controller* getController(const std::string& name)
+    {
+        if (_controllerMap.find(name) != _controllerMap.end())
+        {
+            return _controllerMap[name];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_PLC_HOSTNAME, name);
+    }
+
+    /*!
+     * \brief Return pointer to the controller cfp-774-csimatic-s7-02.
+     */
+    Controller* getCfp_774_csimatic_s7_02()
+    {
+        return _controllerMap["cfp-774-csimatic-s7-02"];
+    }
+    
+    /*!
+     * \brief Receive hdrBlk blocks from all connected controllers.
+     */
+    void receiveHdrBlkAllControllers()
+    {
+        _silecsCluster->recv("hdrBlk");
+    }
+    
+    std::map<std::string, Controller*>& getControllerMap()
+    {
+        return _controllerMap;
+    }
+
+private:
+    std::map<std::string, Controller*> _controllerMap;
+
+};
+
+} /* namespace SilecsHeader_1_0_0 */
+
+#endif /* SILECSHEADER_1_0_0_H_ */
diff --git a/silecs-communication-cpp/src/demo/SilecsValid_1_0_0.h b/silecs-communication-cpp/src/demo/SilecsValid_1_0_0.h
new file mode 100644
index 0000000000000000000000000000000000000000..2ef4e1ff317615a210039d2ef9d11b48ad6da7a8
--- /dev/null
+++ b/silecs-communication-cpp/src/demo/SilecsValid_1_0_0.h
@@ -0,0 +1,1859 @@
+/* Copyright CERN 2015
+ *
+ * WARNING: This code is automatically generated from your SILECS deploy unit document.
+ * You should never modify the content of this file as it would break consistency.
+ * Furthermore, any changes will be overwritten in the next code generation.
+ * Any modification shall be done using the SILECS development environment
+ * and regenerating this source code.
+ */
+
+#ifndef SILECSVALID_1_0_0_H_
+#define SILECSVALID_1_0_0_H_
+
+#include <silecs-communication/wrapper/Block.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+#include <silecs-communication/wrapper/Device.h>
+
+namespace SilecsValid_1_0_0
+{
+
+class Design;
+
+class ReadBlock : public SilecsWrapper::Block
+{
+public:
+    /*!
+     * \brief readBlock constructor. It creates an empty block.
+     */
+    ReadBlock() :
+                    SilecsWrapper::Block("readBlock"),
+                    b1_ro(0),
+                    b2_ro(0),
+                    w1_ro(0),
+                    b3_ro(0),
+                    dw1_ro(0),
+                    c1_ro(0),
+                    c2_ro(0),
+                    c3_ro(0),
+                    di1_ro(0),
+                    b6_ro(0)
+    {
+    }
+
+    ~ReadBlock()
+    {
+    }
+
+    /*!
+     * \brief Get b1_ro register.
+     * \return value.
+     */
+    uint8_t getB1_ro() const
+    {
+        return b1_ro;
+    }
+
+    /*!
+     * \brief Set b1_ro register.
+     * \param value to be set.
+     */
+    void setB1_ro(uint8_t value)
+    {
+        b1_ro = value;
+    }
+
+    /*!
+     * \brief Get b2_ro register.
+     * \return value.
+     */
+    uint8_t getB2_ro() const
+    {
+        return b2_ro;
+    }
+
+    /*!
+     * \brief Set b2_ro register.
+     * \param value to be set.
+     */
+    void setB2_ro(uint8_t value)
+    {
+        b2_ro = value;
+    }
+
+    /*!
+     * \brief Get w1_ro register.
+     * \return value.
+     */
+    uint16_t getW1_ro() const
+    {
+        return w1_ro;
+    }
+
+    /*!
+     * \brief Set w1_ro register.
+     * \param value to be set.
+     */
+    void setW1_ro(uint16_t value)
+    {
+        w1_ro = value;
+    }
+
+    /*!
+     * \brief Get b3_ro register.
+     * \return value.
+     */
+    uint8_t getB3_ro() const
+    {
+        return b3_ro;
+    }
+
+    /*!
+     * \brief Set b3_ro register.
+     * \param value to be set.
+     */
+    void setB3_ro(uint8_t value)
+    {
+        b3_ro = value;
+    }
+
+    /*!
+     * \brief Set array b4_ro register.
+     * \param value to be set.
+     */
+    void getB4_ro(uint8_t* value) const
+    {
+        memcpy(value, (void *) b4_ro, b4_roDim1);
+    }
+
+    /*!
+     * \brief Set 2D array b4_ro register.
+     * \param value to be set.
+     */
+    void setB4_ro(uint8_t* value) const
+    {
+        memcpy((void *) b4_ro, value, b4_roDim1);
+    }
+
+    /*!
+     * \brief Get dw1_ro register.
+     * \return value.
+     */
+    uint32_t getDw1_ro() const
+    {
+        return dw1_ro;
+    }
+
+    /*!
+     * \brief Set dw1_ro register.
+     * \param value to be set.
+     */
+    void setDw1_ro(uint32_t value)
+    {
+        dw1_ro = value;
+    }
+
+    /*!
+     * \brief Set array i1_ro register.
+     * \param value to be set.
+     */
+    void getI1_ro(int16_t* value) const
+    {
+        memcpy(value, (void *) i1_ro, i1_roDim1);
+    }
+
+    /*!
+     * \brief Set 2D array i1_ro register.
+     * \param value to be set.
+     */
+    void setI1_ro(int16_t* value) const
+    {
+        memcpy((void *) i1_ro, value, i1_roDim1);
+    }
+
+    /*!
+     * \brief Get c1_ro register.
+     * \return value.
+     */
+    int8_t getC1_ro() const
+    {
+        return c1_ro;
+    }
+
+    /*!
+     * \brief Set c1_ro register.
+     * \param value to be set.
+     */
+    void setC1_ro(int8_t value)
+    {
+        c1_ro = value;
+    }
+
+    /*!
+     * \brief Get c2_ro register.
+     * \return value.
+     */
+    int8_t getC2_ro() const
+    {
+        return c2_ro;
+    }
+
+    /*!
+     * \brief Set c2_ro register.
+     * \param value to be set.
+     */
+    void setC2_ro(int8_t value)
+    {
+        c2_ro = value;
+    }
+
+    /*!
+     * \brief Get c3_ro register.
+     * \return value.
+     */
+    int8_t getC3_ro() const
+    {
+        return c3_ro;
+    }
+
+    /*!
+     * \brief Set c3_ro register.
+     * \param value to be set.
+     */
+    void setC3_ro(int8_t value)
+    {
+        c3_ro = value;
+    }
+
+    /*!
+     * \brief Get di1_ro register.
+     * \return value.
+     */
+    int32_t getDi1_ro() const
+    {
+        return di1_ro;
+    }
+
+    /*!
+     * \brief Set di1_ro register.
+     * \param value to be set.
+     */
+    void setDi1_ro(int32_t value)
+    {
+        di1_ro = value;
+    }
+
+    /*!
+     * \brief Set array r1_ro register.
+     * \param value to be set.
+     */
+    void getR1_ro(float* value) const
+    {
+        memcpy(value, (void *) r1_ro, r1_roDim1);
+    }
+
+    /*!
+     * \brief Set 2D array r1_ro register.
+     * \param value to be set.
+     */
+    void setR1_ro(float* value) const
+    {
+        memcpy((void *) r1_ro, value, r1_roDim1);
+    }
+
+    /*!
+     * \brief Set array b5_ro register.
+     * \param value to be set.
+     */
+    void getB5_ro(uint8_t* value) const
+    {
+        memcpy(value, (void *) b5_ro, b5_roDim1);
+    }
+
+    /*!
+     * \brief Set 2D array b5_ro register.
+     * \param value to be set.
+     */
+    void setB5_ro(uint8_t* value) const
+    {
+        memcpy((void *) b5_ro, value, b5_roDim1);
+    }
+
+    /*!
+     * \brief Get b6_ro register.
+     * \return value.
+     */
+    uint8_t getB6_ro() const
+    {
+        return b6_ro;
+    }
+
+    /*!
+     * \brief Set b6_ro register.
+     * \param value to be set.
+     */
+    void setB6_ro(uint8_t value)
+    {
+        b6_ro = value;
+    }
+
+    /*!
+     * \brief Get 2D array i2_ro register.
+     * \param value buffer where the value will be stored.
+     */
+    void getI2_ro(int16_t* value) const
+    {
+        memcpy(value, static_cast<const void *>(i2_ro), i2_roDim1 * i2_roDim2);
+    }
+
+    /*!
+     * \brief Get array i2_ro register.
+     * \param value buffer where the value will be stored.
+     */
+    void setI2_ro(int16_t* value) const
+    {
+        memcpy((void *) i2_ro, value, i2_roDim1 * i2_roDim2);
+    }
+
+    /*!
+     * \brief Get 2D array dw2_ro register.
+     * \param value buffer where the value will be stored.
+     */
+    void getDw2_ro(uint32_t* value) const
+    {
+        memcpy(value, static_cast<const void *>(dw2_ro), dw2_roDim1 * dw2_roDim2);
+    }
+
+    /*!
+     * \brief Get array dw2_ro register.
+     * \param value buffer where the value will be stored.
+     */
+    void setDw2_ro(uint32_t* value) const
+    {
+        memcpy((void *) dw2_ro, value, dw2_roDim1 * dw2_roDim2);
+    }
+
+    /*!
+     * \brief Get s1_ro register.
+     * \return value.
+     */
+    const std::string& getS1_ro() const
+    {
+        return s1_ro;
+    }
+
+    /*!
+     * \brief Set s1_ro register.
+     * \param value to be set.
+     */
+    void setS1_ro(const std::string& value)
+    {
+        s1_ro = value;
+    }
+
+    /*!
+     * \brief Get std::string s2_ro register.
+     * \param value buffer where the value will be stored.
+     */
+    void getS2_ro(std::string* value) const
+    {
+        for (std::size_t i = 0; i <  s2_roDim1; i++)
+        {
+            value[i] =  s2_ro[i];
+        }
+    }
+
+    /*!
+     * \brief Set std::string s2_ro register.
+     * \param value to be set.
+     */
+    void setS2_ro(const std::string* value)
+    {
+        for (std::size_t i = 0; i < s2_roDim1; i++)
+        {
+            s2_ro[i] = value[i];
+        }
+    }
+
+    /*!
+     * \brief Get s3_ro register.
+     * \return value.
+     */
+    const std::string& getS3_ro() const
+    {
+        return s3_ro;
+    }
+
+    /*!
+     * \brief Set s3_ro register.
+     * \param value to be set.
+     */
+    void setS3_ro(const std::string& value)
+    {
+        s3_ro = value;
+    }
+
+    /*!
+     * \brief Get s4_ro register.
+     * \return value.
+     */
+    const std::string& getS4_ro() const
+    {
+        return s4_ro;
+    }
+
+    /*!
+     * \brief Set s4_ro register.
+     * \param value to be set.
+     */
+    void setS4_ro(const std::string& value)
+    {
+        s4_ro = value;
+    }
+
+    /*!
+     * \brief Get 2D array r2_ro register.
+     * \param value buffer where the value will be stored.
+     */
+    void getR2_ro(float* value) const
+    {
+        memcpy(value, static_cast<const void *>(r2_ro), r2_roDim1 * r2_roDim2);
+    }
+
+    /*!
+     * \brief Get array r2_ro register.
+     * \param value buffer where the value will be stored.
+     */
+    void setR2_ro(float* value) const
+    {
+        memcpy((void *) r2_ro, value, r2_roDim1 * r2_roDim2);
+    }
+    static const std::size_t b4_roDim1 = 3;
+    static const std::size_t i1_roDim1 = 2;
+    static const std::size_t r1_roDim1 = 3;
+    static const std::size_t b5_roDim1 = 3;
+    static const std::size_t i2_roDim2 = 5;
+    static const std::size_t i2_roDim1 = 2;
+    static const std::size_t dw2_roDim2 = 3;
+    static const std::size_t dw2_roDim1 = 1;
+    static const std::size_t s2_roDim1 = 3;
+    static const std::size_t r2_roDim2 = 2;
+    static const std::size_t r2_roDim1 = 1;
+private:
+    uint8_t b1_ro;
+    uint8_t b2_ro;
+    uint16_t w1_ro;
+    uint8_t b3_ro;
+    uint8_t b4_ro[b4_roDim1];
+    uint32_t dw1_ro;
+    int16_t i1_ro[i1_roDim1];
+    int8_t c1_ro;
+    int8_t c2_ro;
+    int8_t c3_ro;
+    int32_t di1_ro;
+    float r1_ro[r1_roDim1];
+    uint8_t b5_ro[b5_roDim1];
+    uint8_t b6_ro;
+    int16_t i2_ro[i2_roDim1][i2_roDim2];
+    uint32_t dw2_ro[dw2_roDim1][dw2_roDim2];
+    std::string s1_ro;
+    std::string s2_ro[s2_roDim1];
+    std::string s3_ro;
+    std::string s4_ro;
+    float r2_ro[r2_roDim1][r2_roDim2];
+
+};
+
+class WriteBlock : public SilecsWrapper::Block
+{
+public:
+    /*!
+     * \brief writeBlock constructor. It creates an empty block.
+     */
+    WriteBlock() :
+                    SilecsWrapper::Block("writeBlock"),
+                    b1_wo(0),
+                    b2_wo(0),
+                    w1_wo(0),
+                    b3_wo(0),
+                    dw1_wo(0),
+                    c1_wo(0),
+                    c2_wo(0),
+                    c3_wo(0),
+                    di1_wo(0),
+                    b6_wo(0)
+    {
+    }
+
+    ~WriteBlock()
+    {
+    }
+
+    /*!
+     * \brief Get b1_wo register.
+     * \return value.
+     */
+    uint8_t getB1_wo() const
+    {
+        return b1_wo;
+    }
+
+    /*!
+     * \brief Set b1_wo register.
+     * \param value to be set.
+     */
+    void setB1_wo(uint8_t value)
+    {
+        b1_wo = value;
+    }
+
+    /*!
+     * \brief Get b2_wo register.
+     * \return value.
+     */
+    uint8_t getB2_wo() const
+    {
+        return b2_wo;
+    }
+
+    /*!
+     * \brief Set b2_wo register.
+     * \param value to be set.
+     */
+    void setB2_wo(uint8_t value)
+    {
+        b2_wo = value;
+    }
+
+    /*!
+     * \brief Get w1_wo register.
+     * \return value.
+     */
+    uint16_t getW1_wo() const
+    {
+        return w1_wo;
+    }
+
+    /*!
+     * \brief Set w1_wo register.
+     * \param value to be set.
+     */
+    void setW1_wo(uint16_t value)
+    {
+        w1_wo = value;
+    }
+
+    /*!
+     * \brief Get b3_wo register.
+     * \return value.
+     */
+    uint8_t getB3_wo() const
+    {
+        return b3_wo;
+    }
+
+    /*!
+     * \brief Set b3_wo register.
+     * \param value to be set.
+     */
+    void setB3_wo(uint8_t value)
+    {
+        b3_wo = value;
+    }
+
+    /*!
+     * \brief Set array b4_wo register.
+     * \param value to be set.
+     */
+    void getB4_wo(uint8_t* value) const
+    {
+        memcpy(value, (void *) b4_wo, b4_woDim1);
+    }
+
+    /*!
+     * \brief Set 2D array b4_wo register.
+     * \param value to be set.
+     */
+    void setB4_wo(uint8_t* value) const
+    {
+        memcpy((void *) b4_wo, value, b4_woDim1);
+    }
+
+    /*!
+     * \brief Get dw1_wo register.
+     * \return value.
+     */
+    uint32_t getDw1_wo() const
+    {
+        return dw1_wo;
+    }
+
+    /*!
+     * \brief Set dw1_wo register.
+     * \param value to be set.
+     */
+    void setDw1_wo(uint32_t value)
+    {
+        dw1_wo = value;
+    }
+
+    /*!
+     * \brief Set array i1_wo register.
+     * \param value to be set.
+     */
+    void getI1_wo(int16_t* value) const
+    {
+        memcpy(value, (void *) i1_wo, i1_woDim1);
+    }
+
+    /*!
+     * \brief Set 2D array i1_wo register.
+     * \param value to be set.
+     */
+    void setI1_wo(int16_t* value) const
+    {
+        memcpy((void *) i1_wo, value, i1_woDim1);
+    }
+
+    /*!
+     * \brief Get c1_wo register.
+     * \return value.
+     */
+    int8_t getC1_wo() const
+    {
+        return c1_wo;
+    }
+
+    /*!
+     * \brief Set c1_wo register.
+     * \param value to be set.
+     */
+    void setC1_wo(int8_t value)
+    {
+        c1_wo = value;
+    }
+
+    /*!
+     * \brief Get c2_wo register.
+     * \return value.
+     */
+    int8_t getC2_wo() const
+    {
+        return c2_wo;
+    }
+
+    /*!
+     * \brief Set c2_wo register.
+     * \param value to be set.
+     */
+    void setC2_wo(int8_t value)
+    {
+        c2_wo = value;
+    }
+
+    /*!
+     * \brief Get c3_wo register.
+     * \return value.
+     */
+    int8_t getC3_wo() const
+    {
+        return c3_wo;
+    }
+
+    /*!
+     * \brief Set c3_wo register.
+     * \param value to be set.
+     */
+    void setC3_wo(int8_t value)
+    {
+        c3_wo = value;
+    }
+
+    /*!
+     * \brief Get di1_wo register.
+     * \return value.
+     */
+    int32_t getDi1_wo() const
+    {
+        return di1_wo;
+    }
+
+    /*!
+     * \brief Set di1_wo register.
+     * \param value to be set.
+     */
+    void setDi1_wo(int32_t value)
+    {
+        di1_wo = value;
+    }
+
+    /*!
+     * \brief Set array r1_wo register.
+     * \param value to be set.
+     */
+    void getR1_wo(float* value) const
+    {
+        memcpy(value, (void *) r1_wo, r1_woDim1);
+    }
+
+    /*!
+     * \brief Set 2D array r1_wo register.
+     * \param value to be set.
+     */
+    void setR1_wo(float* value) const
+    {
+        memcpy((void *) r1_wo, value, r1_woDim1);
+    }
+
+    /*!
+     * \brief Set array b5_wo register.
+     * \param value to be set.
+     */
+    void getB5_wo(uint8_t* value) const
+    {
+        memcpy(value, (void *) b5_wo, b5_woDim1);
+    }
+
+    /*!
+     * \brief Set 2D array b5_wo register.
+     * \param value to be set.
+     */
+    void setB5_wo(uint8_t* value) const
+    {
+        memcpy((void *) b5_wo, value, b5_woDim1);
+    }
+
+    /*!
+     * \brief Get b6_wo register.
+     * \return value.
+     */
+    uint8_t getB6_wo() const
+    {
+        return b6_wo;
+    }
+
+    /*!
+     * \brief Set b6_wo register.
+     * \param value to be set.
+     */
+    void setB6_wo(uint8_t value)
+    {
+        b6_wo = value;
+    }
+
+    /*!
+     * \brief Get 2D array i2_wo register.
+     * \param value buffer where the value will be stored.
+     */
+    void getI2_wo(int16_t* value) const
+    {
+        memcpy(value, static_cast<const void *>(i2_wo), i2_woDim1 * i2_woDim2);
+    }
+
+    /*!
+     * \brief Get array i2_wo register.
+     * \param value buffer where the value will be stored.
+     */
+    void setI2_wo(int16_t* value) const
+    {
+        memcpy((void *) i2_wo, value, i2_woDim1 * i2_woDim2);
+    }
+
+    /*!
+     * \brief Get 2D array dw2_wo register.
+     * \param value buffer where the value will be stored.
+     */
+    void getDw2_wo(uint32_t* value) const
+    {
+        memcpy(value, static_cast<const void *>(dw2_wo), dw2_woDim1 * dw2_woDim2);
+    }
+
+    /*!
+     * \brief Get array dw2_wo register.
+     * \param value buffer where the value will be stored.
+     */
+    void setDw2_wo(uint32_t* value) const
+    {
+        memcpy((void *) dw2_wo, value, dw2_woDim1 * dw2_woDim2);
+    }
+
+    /*!
+     * \brief Get s1_wo register.
+     * \return value.
+     */
+    const std::string& getS1_wo() const
+    {
+        return s1_wo;
+    }
+
+    /*!
+     * \brief Set s1_wo register.
+     * \param value to be set.
+     */
+    void setS1_wo(const std::string& value)
+    {
+        s1_wo = value;
+    }
+
+    /*!
+     * \brief Get std::string s2_wo register.
+     * \param value buffer where the value will be stored.
+     */
+    void getS2_wo(std::string* value) const
+    {
+        for (std::size_t i = 0; i <  s2_woDim1; i++)
+        {
+            value[i] =  s2_wo[i];
+        }
+    }
+
+    /*!
+     * \brief Set std::string s2_wo register.
+     * \param value to be set.
+     */
+    void setS2_wo(const std::string* value)
+    {
+        for (std::size_t i = 0; i < s2_woDim1; i++)
+        {
+            s2_wo[i] = value[i];
+        }
+    }
+
+    /*!
+     * \brief Get s3_wo register.
+     * \return value.
+     */
+    const std::string& getS3_wo() const
+    {
+        return s3_wo;
+    }
+
+    /*!
+     * \brief Set s3_wo register.
+     * \param value to be set.
+     */
+    void setS3_wo(const std::string& value)
+    {
+        s3_wo = value;
+    }
+
+    /*!
+     * \brief Get s4_wo register.
+     * \return value.
+     */
+    const std::string& getS4_wo() const
+    {
+        return s4_wo;
+    }
+
+    /*!
+     * \brief Set s4_wo register.
+     * \param value to be set.
+     */
+    void setS4_wo(const std::string& value)
+    {
+        s4_wo = value;
+    }
+
+    /*!
+     * \brief Get 2D array r2_wo register.
+     * \param value buffer where the value will be stored.
+     */
+    void getR2_wo(float* value) const
+    {
+        memcpy(value, static_cast<const void *>(r2_wo), r2_woDim1 * r2_woDim2);
+    }
+
+    /*!
+     * \brief Get array r2_wo register.
+     * \param value buffer where the value will be stored.
+     */
+    void setR2_wo(float* value) const
+    {
+        memcpy((void *) r2_wo, value, r2_woDim1 * r2_woDim2);
+    }
+    static const std::size_t b4_woDim1 = 3;
+    static const std::size_t i1_woDim1 = 2;
+    static const std::size_t r1_woDim1 = 3;
+    static const std::size_t b5_woDim1 = 3;
+    static const std::size_t i2_woDim2 = 5;
+    static const std::size_t i2_woDim1 = 2;
+    static const std::size_t dw2_woDim2 = 3;
+    static const std::size_t dw2_woDim1 = 1;
+    static const std::size_t s2_woDim1 = 3;
+    static const std::size_t r2_woDim2 = 2;
+    static const std::size_t r2_woDim1 = 1;
+private:
+    uint8_t b1_wo;
+    uint8_t b2_wo;
+    uint16_t w1_wo;
+    uint8_t b3_wo;
+    uint8_t b4_wo[b4_woDim1];
+    uint32_t dw1_wo;
+    int16_t i1_wo[i1_woDim1];
+    int8_t c1_wo;
+    int8_t c2_wo;
+    int8_t c3_wo;
+    int32_t di1_wo;
+    float r1_wo[r1_woDim1];
+    uint8_t b5_wo[b5_woDim1];
+    uint8_t b6_wo;
+    int16_t i2_wo[i2_woDim1][i2_woDim2];
+    uint32_t dw2_wo[dw2_woDim1][dw2_woDim2];
+    std::string s1_wo;
+    std::string s2_wo[s2_woDim1];
+    std::string s3_wo;
+    std::string s4_wo;
+    float r2_wo[r2_woDim1][r2_woDim2];
+
+};
+
+class RwBlock : public SilecsWrapper::Block
+{
+public:
+    /*!
+     * \brief rwBlock constructor. It creates an empty block.
+     */
+    RwBlock() :
+                    SilecsWrapper::Block("rwBlock"),
+                    b1_rw(0),
+                    b2_rw(0),
+                    w1_rw(0),
+                    b3_rw(0),
+                    dw1_rw(0),
+                    c1_rw(0),
+                    c2_rw(0),
+                    c3_rw(0),
+                    di1_rw(0),
+                    b6_rw(0)
+    {
+    }
+
+    ~RwBlock()
+    {
+    }
+
+    /*!
+     * \brief Get b1_rw register.
+     * \return value.
+     */
+    uint8_t getB1_rw() const
+    {
+        return b1_rw;
+    }
+
+    /*!
+     * \brief Set b1_rw register.
+     * \param value to be set.
+     */
+    void setB1_rw(uint8_t value)
+    {
+        b1_rw = value;
+    }
+
+    /*!
+     * \brief Get b2_rw register.
+     * \return value.
+     */
+    uint8_t getB2_rw() const
+    {
+        return b2_rw;
+    }
+
+    /*!
+     * \brief Set b2_rw register.
+     * \param value to be set.
+     */
+    void setB2_rw(uint8_t value)
+    {
+        b2_rw = value;
+    }
+
+    /*!
+     * \brief Get w1_rw register.
+     * \return value.
+     */
+    uint16_t getW1_rw() const
+    {
+        return w1_rw;
+    }
+
+    /*!
+     * \brief Set w1_rw register.
+     * \param value to be set.
+     */
+    void setW1_rw(uint16_t value)
+    {
+        w1_rw = value;
+    }
+
+    /*!
+     * \brief Get b3_rw register.
+     * \return value.
+     */
+    uint8_t getB3_rw() const
+    {
+        return b3_rw;
+    }
+
+    /*!
+     * \brief Set b3_rw register.
+     * \param value to be set.
+     */
+    void setB3_rw(uint8_t value)
+    {
+        b3_rw = value;
+    }
+
+    /*!
+     * \brief Set array b4_rw register.
+     * \param value to be set.
+     */
+    void getB4_rw(uint8_t* value) const
+    {
+        memcpy(value, (void *) b4_rw, b4_rwDim1);
+    }
+
+    /*!
+     * \brief Set 2D array b4_rw register.
+     * \param value to be set.
+     */
+    void setB4_rw(uint8_t* value) const
+    {
+        memcpy((void *) b4_rw, value, b4_rwDim1);
+    }
+
+    /*!
+     * \brief Get dw1_rw register.
+     * \return value.
+     */
+    uint32_t getDw1_rw() const
+    {
+        return dw1_rw;
+    }
+
+    /*!
+     * \brief Set dw1_rw register.
+     * \param value to be set.
+     */
+    void setDw1_rw(uint32_t value)
+    {
+        dw1_rw = value;
+    }
+
+    /*!
+     * \brief Set array i1_rw register.
+     * \param value to be set.
+     */
+    void getI1_rw(int16_t* value) const
+    {
+        memcpy(value, (void *) i1_rw, i1_rwDim1);
+    }
+
+    /*!
+     * \brief Set 2D array i1_rw register.
+     * \param value to be set.
+     */
+    void setI1_rw(int16_t* value) const
+    {
+        memcpy((void *) i1_rw, value, i1_rwDim1);
+    }
+
+    /*!
+     * \brief Get c1_rw register.
+     * \return value.
+     */
+    int8_t getC1_rw() const
+    {
+        return c1_rw;
+    }
+
+    /*!
+     * \brief Set c1_rw register.
+     * \param value to be set.
+     */
+    void setC1_rw(int8_t value)
+    {
+        c1_rw = value;
+    }
+
+    /*!
+     * \brief Get c2_rw register.
+     * \return value.
+     */
+    int8_t getC2_rw() const
+    {
+        return c2_rw;
+    }
+
+    /*!
+     * \brief Set c2_rw register.
+     * \param value to be set.
+     */
+    void setC2_rw(int8_t value)
+    {
+        c2_rw = value;
+    }
+
+    /*!
+     * \brief Get c3_rw register.
+     * \return value.
+     */
+    int8_t getC3_rw() const
+    {
+        return c3_rw;
+    }
+
+    /*!
+     * \brief Set c3_rw register.
+     * \param value to be set.
+     */
+    void setC3_rw(int8_t value)
+    {
+        c3_rw = value;
+    }
+
+    /*!
+     * \brief Get di1_rw register.
+     * \return value.
+     */
+    int32_t getDi1_rw() const
+    {
+        return di1_rw;
+    }
+
+    /*!
+     * \brief Set di1_rw register.
+     * \param value to be set.
+     */
+    void setDi1_rw(int32_t value)
+    {
+        di1_rw = value;
+    }
+
+    /*!
+     * \brief Set array r1_rw register.
+     * \param value to be set.
+     */
+    void getR1_rw(float* value) const
+    {
+        memcpy(value, (void *) r1_rw, r1_rwDim1);
+    }
+
+    /*!
+     * \brief Set 2D array r1_rw register.
+     * \param value to be set.
+     */
+    void setR1_rw(float* value) const
+    {
+        memcpy((void *) r1_rw, value, r1_rwDim1);
+    }
+
+    /*!
+     * \brief Set array b5_rw register.
+     * \param value to be set.
+     */
+    void getB5_rw(uint8_t* value) const
+    {
+        memcpy(value, (void *) b5_rw, b5_rwDim1);
+    }
+
+    /*!
+     * \brief Set 2D array b5_rw register.
+     * \param value to be set.
+     */
+    void setB5_rw(uint8_t* value) const
+    {
+        memcpy((void *) b5_rw, value, b5_rwDim1);
+    }
+
+    /*!
+     * \brief Get b6_rw register.
+     * \return value.
+     */
+    uint8_t getB6_rw() const
+    {
+        return b6_rw;
+    }
+
+    /*!
+     * \brief Set b6_rw register.
+     * \param value to be set.
+     */
+    void setB6_rw(uint8_t value)
+    {
+        b6_rw = value;
+    }
+
+    /*!
+     * \brief Get 2D array i2_rw register.
+     * \param value buffer where the value will be stored.
+     */
+    void getI2_rw(int16_t* value) const
+    {
+        memcpy(value, static_cast<const void *>(i2_rw), i2_rwDim1 * i2_rwDim2);
+    }
+
+    /*!
+     * \brief Get array i2_rw register.
+     * \param value buffer where the value will be stored.
+     */
+    void setI2_rw(int16_t* value) const
+    {
+        memcpy((void *) i2_rw, value, i2_rwDim1 * i2_rwDim2);
+    }
+
+    /*!
+     * \brief Get 2D array dw2_rw register.
+     * \param value buffer where the value will be stored.
+     */
+    void getDw2_rw(uint32_t* value) const
+    {
+        memcpy(value, static_cast<const void *>(dw2_rw), dw2_rwDim1 * dw2_rwDim2);
+    }
+
+    /*!
+     * \brief Get array dw2_rw register.
+     * \param value buffer where the value will be stored.
+     */
+    void setDw2_rw(uint32_t* value) const
+    {
+        memcpy((void *) dw2_rw, value, dw2_rwDim1 * dw2_rwDim2);
+    }
+
+    /*!
+     * \brief Get s1_rw register.
+     * \return value.
+     */
+    const std::string& getS1_rw() const
+    {
+        return s1_rw;
+    }
+
+    /*!
+     * \brief Set s1_rw register.
+     * \param value to be set.
+     */
+    void setS1_rw(const std::string& value)
+    {
+        s1_rw = value;
+    }
+
+    /*!
+     * \brief Get std::string s2_rw register.
+     * \param value buffer where the value will be stored.
+     */
+    void getS2_rw(std::string* value) const
+    {
+        for (std::size_t i = 0; i <  s2_rwDim1; i++)
+        {
+            value[i] =  s2_rw[i];
+        }
+    }
+
+    /*!
+     * \brief Set std::string s2_rw register.
+     * \param value to be set.
+     */
+    void setS2_rw(const std::string* value)
+    {
+        for (std::size_t i = 0; i < s2_rwDim1; i++)
+        {
+            s2_rw[i] = value[i];
+        }
+    }
+
+    /*!
+     * \brief Get s3_rw register.
+     * \return value.
+     */
+    const std::string& getS3_rw() const
+    {
+        return s3_rw;
+    }
+
+    /*!
+     * \brief Set s3_rw register.
+     * \param value to be set.
+     */
+    void setS3_rw(const std::string& value)
+    {
+        s3_rw = value;
+    }
+
+    /*!
+     * \brief Get s4_rw register.
+     * \return value.
+     */
+    const std::string& getS4_rw() const
+    {
+        return s4_rw;
+    }
+
+    /*!
+     * \brief Set s4_rw register.
+     * \param value to be set.
+     */
+    void setS4_rw(const std::string& value)
+    {
+        s4_rw = value;
+    }
+
+    /*!
+     * \brief Get 2D array r2_rw register.
+     * \param value buffer where the value will be stored.
+     */
+    void getR2_rw(float* value) const
+    {
+        memcpy(value, static_cast<const void *>(r2_rw), r2_rwDim1 * r2_rwDim2);
+    }
+
+    /*!
+     * \brief Get array r2_rw register.
+     * \param value buffer where the value will be stored.
+     */
+    void setR2_rw(float* value) const
+    {
+        memcpy((void *) r2_rw, value, r2_rwDim1 * r2_rwDim2);
+    }
+    static const std::size_t b4_rwDim1 = 3;
+    static const std::size_t i1_rwDim1 = 2;
+    static const std::size_t r1_rwDim1 = 3;
+    static const std::size_t b5_rwDim1 = 3;
+    static const std::size_t i2_rwDim2 = 5;
+    static const std::size_t i2_rwDim1 = 2;
+    static const std::size_t dw2_rwDim2 = 3;
+    static const std::size_t dw2_rwDim1 = 1;
+    static const std::size_t s2_rwDim1 = 3;
+    static const std::size_t r2_rwDim2 = 2;
+    static const std::size_t r2_rwDim1 = 1;
+private:
+    uint8_t b1_rw;
+    uint8_t b2_rw;
+    uint16_t w1_rw;
+    uint8_t b3_rw;
+    uint8_t b4_rw[b4_rwDim1];
+    uint32_t dw1_rw;
+    int16_t i1_rw[i1_rwDim1];
+    int8_t c1_rw;
+    int8_t c2_rw;
+    int8_t c3_rw;
+    int32_t di1_rw;
+    float r1_rw[r1_rwDim1];
+    uint8_t b5_rw[b5_rwDim1];
+    uint8_t b6_rw;
+    int16_t i2_rw[i2_rwDim1][i2_rwDim2];
+    uint32_t dw2_rw[dw2_rwDim1][dw2_rwDim2];
+    std::string s1_rw;
+    std::string s2_rw[s2_rwDim1];
+    std::string s3_rw;
+    std::string s4_rw;
+    float r2_rw[r2_rwDim1][r2_rwDim2];
+
+};
+class Device : public SilecsWrapper::Device
+{
+public:
+    Device(const std::string& label, SilecsWrapper::Controller *controller) :
+                    SilecsWrapper::Device(label, controller)
+    {
+    }
+
+    ~Device()
+    {
+    }
+    
+    /*!
+     * \brief Get readBlock block. 
+     * \param block ReadBlock reference where to store returned value.
+     */
+    void getReadBlock(ReadBlock &block)
+    {
+        // Copy register b1_ro
+        block.setB1_ro(getSilecsDevice()->getRegister("b1_ro")->getValUInt8());
+        // Copy register b2_ro
+        block.setB2_ro(getSilecsDevice()->getRegister("b2_ro")->getValUInt8());
+        // Copy register w1_ro
+        block.setW1_ro(getSilecsDevice()->getRegister("w1_ro")->getValUInt16());
+        // Copy register b3_ro
+        block.setB3_ro(getSilecsDevice()->getRegister("b3_ro")->getValUInt8());
+        // Copy register b4_ro
+        uint8_t *__b4_ro = new uint8_t[block.b4_roDim1];
+        getSilecsDevice()->getRegister("b4_ro")->getValUInt8Array(__b4_ro, block.b4_roDim1);
+        block.setB4_ro(__b4_ro);
+        delete[] __b4_ro;
+        // Copy register dw1_ro
+        block.setDw1_ro(getSilecsDevice()->getRegister("dw1_ro")->getValUInt32());
+        // Copy register i1_ro
+        int16_t *__i1_ro = new int16_t[block.i1_roDim1];
+        getSilecsDevice()->getRegister("i1_ro")->getValInt16Array(__i1_ro, block.i1_roDim1);
+        block.setI1_ro(__i1_ro);
+        delete[] __i1_ro;
+        // Copy register c1_ro
+        block.setC1_ro(getSilecsDevice()->getRegister("c1_ro")->getValInt8());
+        // Copy register c2_ro
+        block.setC2_ro(getSilecsDevice()->getRegister("c2_ro")->getValInt8());
+        // Copy register c3_ro
+        block.setC3_ro(getSilecsDevice()->getRegister("c3_ro")->getValInt8());
+        // Copy register di1_ro
+        block.setDi1_ro(getSilecsDevice()->getRegister("di1_ro")->getValInt32());
+        // Copy register r1_ro
+        float *__r1_ro = new float[block.r1_roDim1];
+        getSilecsDevice()->getRegister("r1_ro")->getValFloat32Array(__r1_ro, block.r1_roDim1);
+        block.setR1_ro(__r1_ro);
+        delete[] __r1_ro;
+        // Copy register b5_ro
+        uint8_t *__b5_ro = new uint8_t[block.b5_roDim1];
+        getSilecsDevice()->getRegister("b5_ro")->getValUInt8Array(__b5_ro, block.b5_roDim1);
+        block.setB5_ro(__b5_ro);
+        delete[] __b5_ro;
+        // Copy register b6_ro
+        block.setB6_ro(getSilecsDevice()->getRegister("b6_ro")->getValUInt8());
+        // Copy register i2_ro
+        int16_t *__i2_ro = new int16_t[block.i2_roDim1 * block.i2_roDim2];
+        getSilecsDevice()->getRegister("i2_ro")->getValInt16Array2D(__i2_ro, block.i2_roDim1, block.i2_roDim2);
+        block.setI2_ro(__i2_ro);
+        delete[] __i2_ro;
+        // Copy register dw2_ro
+        uint32_t *__dw2_ro = new uint32_t[block.dw2_roDim1 * block.dw2_roDim2];
+        getSilecsDevice()->getRegister("dw2_ro")->getValUInt32Array2D(__dw2_ro, block.dw2_roDim1, block.dw2_roDim2);
+        block.setDw2_ro(__dw2_ro);
+        delete[] __dw2_ro;
+        // Copy register s1_ro
+        block.setS1_ro(getSilecsDevice()->getRegister("s1_ro")->getValString());
+        // Copy register s2_ro
+        std::string *__s2_ro = new std::string[block.s2_roDim1];
+        getSilecsDevice()->getRegister("s2_ro")->getValStringArray(__s2_ro, block.s2_roDim1);
+        block.setS2_ro(__s2_ro);
+        delete[] __s2_ro;
+        // Copy register s3_ro
+        block.setS3_ro(getSilecsDevice()->getRegister("s3_ro")->getValString());
+        // Copy register s4_ro
+        block.setS4_ro(getSilecsDevice()->getRegister("s4_ro")->getValString());
+        // Copy register r2_ro
+        float *__r2_ro = new float[block.r2_roDim1 * block.r2_roDim2];
+        getSilecsDevice()->getRegister("r2_ro")->getValFloat32Array2D(__r2_ro, block.r2_roDim1, block.r2_roDim2);
+        block.setR2_ro(__r2_ro);
+        delete[] __r2_ro;
+    }
+    
+    /*!
+     * \brief Set writeBlock block. 
+     * \param block WriteBlock reference from where value are copied.
+     */
+    void setWriteBlock(WriteBlock &block)
+    {
+        // Copy register b1_wo
+        getSilecsDevice()->getRegister("b1_wo")->setValUInt8(block.getB1_wo());
+        // Copy register b2_wo
+        getSilecsDevice()->getRegister("b2_wo")->setValUInt8(block.getB2_wo());
+        // Copy register w1_wo
+        getSilecsDevice()->getRegister("w1_wo")->setValUInt16(block.getW1_wo());
+        // Copy register b3_wo
+        getSilecsDevice()->getRegister("b3_wo")->setValUInt8(block.getB3_wo());
+        // Copy register b4_wo
+        uint8_t *__b4_wo = new uint8_t[block.b4_woDim1];
+        block.getB4_wo(__b4_wo);
+        getSilecsDevice()->getRegister("b4_wo")->setValUInt8Array(__b4_wo, block.b4_woDim1);
+        delete[] __b4_wo;
+        // Copy register dw1_wo
+        getSilecsDevice()->getRegister("dw1_wo")->setValUInt32(block.getDw1_wo());
+        // Copy register i1_wo
+        int16_t *__i1_wo = new int16_t[block.i1_woDim1];
+        block.getI1_wo(__i1_wo);
+        getSilecsDevice()->getRegister("i1_wo")->setValInt16Array(__i1_wo, block.i1_woDim1);
+        delete[] __i1_wo;
+        // Copy register c1_wo
+        getSilecsDevice()->getRegister("c1_wo")->setValInt8(block.getC1_wo());
+        // Copy register c2_wo
+        getSilecsDevice()->getRegister("c2_wo")->setValInt8(block.getC2_wo());
+        // Copy register c3_wo
+        getSilecsDevice()->getRegister("c3_wo")->setValInt8(block.getC3_wo());
+        // Copy register di1_wo
+        getSilecsDevice()->getRegister("di1_wo")->setValInt32(block.getDi1_wo());
+        // Copy register r1_wo
+        float *__r1_wo = new float[block.r1_woDim1];
+        block.getR1_wo(__r1_wo);
+        getSilecsDevice()->getRegister("r1_wo")->setValFloat32Array(__r1_wo, block.r1_woDim1);
+        delete[] __r1_wo;
+        // Copy register b5_wo
+        uint8_t *__b5_wo = new uint8_t[block.b5_woDim1];
+        block.getB5_wo(__b5_wo);
+        getSilecsDevice()->getRegister("b5_wo")->setValUInt8Array(__b5_wo, block.b5_woDim1);
+        delete[] __b5_wo;
+        // Copy register b6_wo
+        getSilecsDevice()->getRegister("b6_wo")->setValUInt8(block.getB6_wo());
+        // Copy register i2_wo
+        int16_t *__i2_wo = new int16_t[block.i2_woDim1 * block.i2_woDim2];
+        block.getI2_wo(__i2_wo);
+        getSilecsDevice()->getRegister("i2_wo")->setValInt16Array2D(__i2_wo, block.i2_woDim1, block.i2_woDim2);
+        delete[] __i2_wo;
+        // Copy register dw2_wo
+        uint32_t *__dw2_wo = new uint32_t[block.dw2_woDim1 * block.dw2_woDim2];
+        block.getDw2_wo(__dw2_wo);
+        getSilecsDevice()->getRegister("dw2_wo")->setValUInt32Array2D(__dw2_wo, block.dw2_woDim1, block.dw2_woDim2);
+        delete[] __dw2_wo;
+        // Copy register s1_wo
+        getSilecsDevice()->getRegister("s1_wo")->setValString(block.getS1_wo());
+        // Copy register s2_wo
+        std::string *__s2_wo = new std::string[block.s2_woDim1];
+        block.getS2_wo(__s2_wo);
+        getSilecsDevice()->getRegister("s2_wo")->setValStringArray(__s2_wo, block.s2_woDim1);
+        delete[] __s2_wo;
+        // Copy register s3_wo
+        getSilecsDevice()->getRegister("s3_wo")->setValString(block.getS3_wo());
+        // Copy register s4_wo
+        getSilecsDevice()->getRegister("s4_wo")->setValString(block.getS4_wo());
+        // Copy register r2_wo
+        float *__r2_wo = new float[block.r2_woDim1 * block.r2_woDim2];
+        block.getR2_wo(__r2_wo);
+        getSilecsDevice()->getRegister("r2_wo")->setValFloat32Array2D(__r2_wo, block.r2_woDim1, block.r2_woDim2);
+        delete[] __r2_wo;
+    }
+    
+    /*!
+     * \brief Get rwBlock block. 
+     * \param block RwBlock reference where to store returned value.
+     */
+    void getRwBlock(RwBlock &block)
+    {
+        // Copy register b1_rw
+        block.setB1_rw(getSilecsDevice()->getRegister("b1_rw")->getValUInt8());
+        // Copy register b2_rw
+        block.setB2_rw(getSilecsDevice()->getRegister("b2_rw")->getValUInt8());
+        // Copy register w1_rw
+        block.setW1_rw(getSilecsDevice()->getRegister("w1_rw")->getValUInt16());
+        // Copy register b3_rw
+        block.setB3_rw(getSilecsDevice()->getRegister("b3_rw")->getValUInt8());
+        // Copy register b4_rw
+        uint8_t *__b4_rw = new uint8_t[block.b4_rwDim1];
+        getSilecsDevice()->getRegister("b4_rw")->getValUInt8Array(__b4_rw, block.b4_rwDim1);
+        block.setB4_rw(__b4_rw);
+        delete[] __b4_rw;
+        // Copy register dw1_rw
+        block.setDw1_rw(getSilecsDevice()->getRegister("dw1_rw")->getValUInt32());
+        // Copy register i1_rw
+        int16_t *__i1_rw = new int16_t[block.i1_rwDim1];
+        getSilecsDevice()->getRegister("i1_rw")->getValInt16Array(__i1_rw, block.i1_rwDim1);
+        block.setI1_rw(__i1_rw);
+        delete[] __i1_rw;
+        // Copy register c1_rw
+        block.setC1_rw(getSilecsDevice()->getRegister("c1_rw")->getValInt8());
+        // Copy register c2_rw
+        block.setC2_rw(getSilecsDevice()->getRegister("c2_rw")->getValInt8());
+        // Copy register c3_rw
+        block.setC3_rw(getSilecsDevice()->getRegister("c3_rw")->getValInt8());
+        // Copy register di1_rw
+        block.setDi1_rw(getSilecsDevice()->getRegister("di1_rw")->getValInt32());
+        // Copy register r1_rw
+        float *__r1_rw = new float[block.r1_rwDim1];
+        getSilecsDevice()->getRegister("r1_rw")->getValFloat32Array(__r1_rw, block.r1_rwDim1);
+        block.setR1_rw(__r1_rw);
+        delete[] __r1_rw;
+        // Copy register b5_rw
+        uint8_t *__b5_rw = new uint8_t[block.b5_rwDim1];
+        getSilecsDevice()->getRegister("b5_rw")->getValUInt8Array(__b5_rw, block.b5_rwDim1);
+        block.setB5_rw(__b5_rw);
+        delete[] __b5_rw;
+        // Copy register b6_rw
+        block.setB6_rw(getSilecsDevice()->getRegister("b6_rw")->getValUInt8());
+        // Copy register i2_rw
+        int16_t *__i2_rw = new int16_t[block.i2_rwDim1 * block.i2_rwDim2];
+        getSilecsDevice()->getRegister("i2_rw")->getValInt16Array2D(__i2_rw, block.i2_rwDim1, block.i2_rwDim2);
+        block.setI2_rw(__i2_rw);
+        delete[] __i2_rw;
+        // Copy register dw2_rw
+        uint32_t *__dw2_rw = new uint32_t[block.dw2_rwDim1 * block.dw2_rwDim2];
+        getSilecsDevice()->getRegister("dw2_rw")->getValUInt32Array2D(__dw2_rw, block.dw2_rwDim1, block.dw2_rwDim2);
+        block.setDw2_rw(__dw2_rw);
+        delete[] __dw2_rw;
+        // Copy register s1_rw
+        block.setS1_rw(getSilecsDevice()->getRegister("s1_rw")->getValString());
+        // Copy register s2_rw
+        std::string *__s2_rw = new std::string[block.s2_rwDim1];
+        getSilecsDevice()->getRegister("s2_rw")->getValStringArray(__s2_rw, block.s2_rwDim1);
+        block.setS2_rw(__s2_rw);
+        delete[] __s2_rw;
+        // Copy register s3_rw
+        block.setS3_rw(getSilecsDevice()->getRegister("s3_rw")->getValString());
+        // Copy register s4_rw
+        block.setS4_rw(getSilecsDevice()->getRegister("s4_rw")->getValString());
+        // Copy register r2_rw
+        float *__r2_rw = new float[block.r2_rwDim1 * block.r2_rwDim2];
+        getSilecsDevice()->getRegister("r2_rw")->getValFloat32Array2D(__r2_rw, block.r2_rwDim1, block.r2_rwDim2);
+        block.setR2_rw(__r2_rw);
+        delete[] __r2_rw;
+    }
+    
+    /*!
+     * \brief Set rwBlock block. 
+     * \param block RwBlock reference from where value are copied.
+     */
+    void setRwBlock(RwBlock &block)
+    {
+        // Copy register b1_rw
+        getSilecsDevice()->getRegister("b1_rw")->setValUInt8(block.getB1_rw());
+        // Copy register b2_rw
+        getSilecsDevice()->getRegister("b2_rw")->setValUInt8(block.getB2_rw());
+        // Copy register w1_rw
+        getSilecsDevice()->getRegister("w1_rw")->setValUInt16(block.getW1_rw());
+        // Copy register b3_rw
+        getSilecsDevice()->getRegister("b3_rw")->setValUInt8(block.getB3_rw());
+        // Copy register b4_rw
+        uint8_t *__b4_rw = new uint8_t[block.b4_rwDim1];
+        block.getB4_rw(__b4_rw);
+        getSilecsDevice()->getRegister("b4_rw")->setValUInt8Array(__b4_rw, block.b4_rwDim1);
+        delete[] __b4_rw;
+        // Copy register dw1_rw
+        getSilecsDevice()->getRegister("dw1_rw")->setValUInt32(block.getDw1_rw());
+        // Copy register i1_rw
+        int16_t *__i1_rw = new int16_t[block.i1_rwDim1];
+        block.getI1_rw(__i1_rw);
+        getSilecsDevice()->getRegister("i1_rw")->setValInt16Array(__i1_rw, block.i1_rwDim1);
+        delete[] __i1_rw;
+        // Copy register c1_rw
+        getSilecsDevice()->getRegister("c1_rw")->setValInt8(block.getC1_rw());
+        // Copy register c2_rw
+        getSilecsDevice()->getRegister("c2_rw")->setValInt8(block.getC2_rw());
+        // Copy register c3_rw
+        getSilecsDevice()->getRegister("c3_rw")->setValInt8(block.getC3_rw());
+        // Copy register di1_rw
+        getSilecsDevice()->getRegister("di1_rw")->setValInt32(block.getDi1_rw());
+        // Copy register r1_rw
+        float *__r1_rw = new float[block.r1_rwDim1];
+        block.getR1_rw(__r1_rw);
+        getSilecsDevice()->getRegister("r1_rw")->setValFloat32Array(__r1_rw, block.r1_rwDim1);
+        delete[] __r1_rw;
+        // Copy register b5_rw
+        uint8_t *__b5_rw = new uint8_t[block.b5_rwDim1];
+        block.getB5_rw(__b5_rw);
+        getSilecsDevice()->getRegister("b5_rw")->setValUInt8Array(__b5_rw, block.b5_rwDim1);
+        delete[] __b5_rw;
+        // Copy register b6_rw
+        getSilecsDevice()->getRegister("b6_rw")->setValUInt8(block.getB6_rw());
+        // Copy register i2_rw
+        int16_t *__i2_rw = new int16_t[block.i2_rwDim1 * block.i2_rwDim2];
+        block.getI2_rw(__i2_rw);
+        getSilecsDevice()->getRegister("i2_rw")->setValInt16Array2D(__i2_rw, block.i2_rwDim1, block.i2_rwDim2);
+        delete[] __i2_rw;
+        // Copy register dw2_rw
+        uint32_t *__dw2_rw = new uint32_t[block.dw2_rwDim1 * block.dw2_rwDim2];
+        block.getDw2_rw(__dw2_rw);
+        getSilecsDevice()->getRegister("dw2_rw")->setValUInt32Array2D(__dw2_rw, block.dw2_rwDim1, block.dw2_rwDim2);
+        delete[] __dw2_rw;
+        // Copy register s1_rw
+        getSilecsDevice()->getRegister("s1_rw")->setValString(block.getS1_rw());
+        // Copy register s2_rw
+        std::string *__s2_rw = new std::string[block.s2_rwDim1];
+        block.getS2_rw(__s2_rw);
+        getSilecsDevice()->getRegister("s2_rw")->setValStringArray(__s2_rw, block.s2_rwDim1);
+        delete[] __s2_rw;
+        // Copy register s3_rw
+        getSilecsDevice()->getRegister("s3_rw")->setValString(block.getS3_rw());
+        // Copy register s4_rw
+        getSilecsDevice()->getRegister("s4_rw")->setValString(block.getS4_rw());
+        // Copy register r2_rw
+        float *__r2_rw = new float[block.r2_rwDim1 * block.r2_rwDim2];
+        block.getR2_rw(__r2_rw);
+        getSilecsDevice()->getRegister("r2_rw")->setValFloat32Array2D(__r2_rw, block.r2_rwDim1, block.r2_rwDim2);
+        delete[] __r2_rw;
+    }
+    
+
+    /*!
+     * \brief Receive readBlock block for current device.
+     */
+    void receiveReadBlock()
+    {
+        _silecsDevice->recv("readBlock");
+    }
+    
+    /*!
+     * \brief Send writeBlock blocks to current device.
+     */
+    void sendWriteBlock()
+    {
+        _silecsDevice->send("writeBlock");
+    }
+    
+    /*!
+     * \brief Receive rwBlock block for current device.
+     */
+    void receiveRwBlock()
+    {
+        _silecsDevice->recv("rwBlock");
+    }
+    
+    /*!
+     * \brief Send rwBlock blocks to current device.
+     */
+    void sendRwBlock()
+    {
+        _silecsDevice->send("rwBlock");
+    }
+    
+
+};
+
+class Controller : public SilecsWrapper::Controller
+{
+public:
+    Controller(const std::string& name, const std::string& domain, Design *design) :
+                    SilecsWrapper::Controller(name, domain, (SilecsWrapper::Design*) design)
+    {
+            _deviceMap.insert(std::pair<std::string, Device*>("0", new Device("0", this)));
+            _deviceMap.insert(std::pair<std::string, Device*>("1", new Device("1", this)));
+            _deviceMap.insert(std::pair<std::string, Device*>("2", new Device("2", this)));
+    }
+
+    ~Controller()
+    {
+        map<std::string, Device*>::iterator it;
+        for (it = _deviceMap.begin(); it != _deviceMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested device.
+     * \param label Device label.
+     */
+    Device* getDevice(const std::string& label)
+    {
+        if (_deviceMap.find(label) != _deviceMap.end())
+        {
+            return _deviceMap[label];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_DEVICE_NAME, label);
+    }
+
+    std::map<std::string, Device*>& getDeviceMap()
+    {
+        return _deviceMap;
+    }
+    /*!
+     * \brief Receive readBlock blocks from all devices of current controller.
+     */
+    void receiveReadBlockAllDevices()
+    {
+        _silecsPLC->recv("readBlock");
+    }
+    
+    /*!
+     * \brief Send writeBlock blocks to all devices of current controller.
+     */
+    void sendWriteBlockAllDevices()
+    {
+        _silecsPLC->send("writeBlock");
+    }
+    
+    /*!
+     * \brief Receive rwBlock blocks from all devices of current controller.
+     */
+    void receiveRwBlockAllDevices()
+    {
+        _silecsPLC->recv("rwBlock");
+    }
+    
+    /*!
+     * \brief Send rwBlock blocks to all devices of current controller.
+     */
+    void sendRwBlockAllDevices()
+    {
+        _silecsPLC->send("rwBlock");
+    }
+    
+private:
+    std::map<std::string, Device*> _deviceMap;
+};
+
+class Design : public SilecsWrapper::Design
+{
+public:
+
+    Design(SilecsWrapper::DeployUnit *deployUnit) :
+                    SilecsWrapper::Design("SilecsValid", "1.0.0", deployUnit)
+    {
+
+            _controllerMap.insert(
+                std::pair<std::string, Controller*>("cfp-774-csimatic-s7-02",
+                        new Controller("cfp-774-csimatic-s7-02", "TST", this)));
+
+    }
+
+    ~Design()
+    {
+        map<std::string, Controller*>::iterator it;
+        for (it = _controllerMap.begin(); it != _controllerMap.end(); it++)
+        {
+            delete it->second;
+        }
+    }
+
+    /*!
+     * \brief Return pointer to the requested controller.
+     * \param name Controller's name.
+     */
+    Controller* getController(const std::string& name)
+    {
+        if (_controllerMap.find(name) != _controllerMap.end())
+        {
+            return _controllerMap[name];
+        }
+        throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::PARAM_UNKNOWN_PLC_HOSTNAME, name);
+    }
+
+    /*!
+     * \brief Return pointer to the controller cfp-774-csimatic-s7-02.
+     */
+    Controller* getCfp_774_csimatic_s7_02()
+    {
+        return _controllerMap["cfp-774-csimatic-s7-02"];
+    }
+    
+    /*!
+     * \brief Receive readBlock blocks from all connected controllers.
+     */
+    void receiveReadBlockAllControllers()
+    {
+        _silecsCluster->recv("readBlock");
+    }
+    
+    /*!
+     * \brief Send writeBlock blocks to all connected controllers.
+     */
+    void sendWriteBlockAllControllers()
+    {
+        _silecsCluster->send("writeBlock");
+    }
+    
+    /*!
+     * \brief Receive rwBlock blocks from all connected controllers.
+     */
+    void receiveRwBlockAllControllers()
+    {
+        _silecsCluster->recv("rwBlock");
+    }
+    
+    /*!
+     * \brief Send rwBlock blocks to all connected controllers.
+     */
+    void sendRwBlockAllControllers()
+    {
+        _silecsCluster->send("rwBlock");
+    }
+    
+    std::map<std::string, Controller*>& getControllerMap()
+    {
+        return _controllerMap;
+    }
+
+private:
+    std::map<std::string, Controller*> _controllerMap;
+
+};
+
+} /* namespace SilecsValid_1_0_0 */
+
+#endif /* SILECSVALID_1_0_0_H_ */
diff --git a/silecs-communication-cpp/src/demo/main.cpp b/silecs-communication-cpp/src/demo/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..61379595ac0975af4db11789eded97b23b0b82a3
--- /dev/null
+++ b/silecs-communication-cpp/src/demo/main.cpp
@@ -0,0 +1,63 @@
+#include "Cfp774Simatic400_1_0_0.h"
+
+#include <iostream>
+
+int main(void)
+{
+
+    Cfp774Simatic400_1_0_0::DeployConfig config();
+    config.setAutomaticConnect(false);
+    const std::string logTopics = "ERROR,COMM,SEND,RECV";
+    Cfp774Simatic400_1_0_0::DeployUnit* du = Cfp774Simatic400_1_0_0::DeployUnit::getInstance(logTopics, config);
+
+    Cfp774Simatic400_1_0_0::DesignConfig designConfig(false);
+    du->getSilecsValid()->setConfiguration(designConfig);
+
+    du->deleteInstance();
+}
+
+
+//int main(void)
+//{
+//
+//    Cfp774Simatic400_1_0_0::DeployConfig config;
+//    config.setAutomaticConnect(false);
+//    const std::string logTopics = "ERROR,COMM,SEND,RECV";
+//    Cfp774Simatic400_1_0_0::DeployUnit* du = Cfp774Simatic400_1_0_0::DeployUnit::getInstance(logTopics, config);
+//
+//    Cfp774Simatic400_1_0_0::DesignConfig designConfig(false);
+//    du->getSilecsValid()->setConfiguration(designConfig);
+//    du->getSilecsValid()->getControllerMap()["cfp-774-csimatic-s7-02"]->connect();
+//
+//    // read block
+//    SilecsValid_1_0_0::RwBlock rwblock;
+//    du->getSilecsValid()->getCfp_774_csimatic_s7_02()->getDevice("0")->receiveRwBlock();
+//    du->getSilecsValid()->getCfp_774_csimatic_s7_02()->getDevice("0")->getRwBlock(rwblock);
+//
+//    int32_t b1_rw = rwblock.getB1_rw();
+//    uint8_t b4_rw[rwblock.b4_rwDim1];
+//    rwblock.getB4_rw(b4_rw);
+//    std::cout << "Value of register b1_rw = " << b1_rw << std::endl;
+//    std::cout << "Value of register b4_rw[0] = " << (int32_t) b4_rw[0] << std::endl;
+//    std::cout << "Value of register b4_rw[1] = " << (int32_t) b4_rw[1] << std::endl;
+//
+//    // increment b1_rw
+//    b4_rw[0] = b4_rw[0] + 1;
+//    b4_rw[1] = b4_rw[1] + 2;
+//    rwblock.setB4_rw(b4_rw);
+//    rwblock.setB1_rw(b1_rw + 2);
+//    std::cout << "Increment 2" << std::endl;
+//    du->getSilecsValid()->getCfp_774_csimatic_s7_02()->getDevice("0")->setRwBlock(rwblock);
+//    du->getSilecsValid()->getCfp_774_csimatic_s7_02()->getDevice("0")->sendRwBlock();
+//
+//    // read b1_rw
+//    du->getSilecsValid()->getCfp_774_csimatic_s7_02()->getDevice("0")->receiveRwBlock();
+//    du->getSilecsValid()->getCfp_774_csimatic_s7_02()->getDevice("0")->getRwBlock(rwblock);
+//    b1_rw = rwblock.getB1_rw();
+//    rwblock.getB4_rw(b4_rw);
+//    std::cout << "Value of register b1_rw = " << b1_rw << std::endl;
+//    std::cout << "Value of register b4_rw[0] = " << (int32_t) b4_rw[0] << std::endl;
+//    std::cout << "Value of register b4_rw[1] = " << (int32_t) b4_rw[1] << std::endl;
+//
+//    du->deleteInstance();
+//}
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.cpp b/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f807d5d77d85f9f2c03460cb54e71afd210770f2
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.cpp
@@ -0,0 +1,146 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifdef NI_SUPPORT_ENABLED
+
+#include <silecs-communication/interface/communication/CNVConnection.h>
+
+#include <silecs-communication/interface/communication/SilecsConnection.h>
+#include <silecs-communication/interface/equipment/CNVBlock.h>
+#include <silecs-communication/interface/equipment/SilecsBlock.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/utility/SilecsException.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <silecs-communication/interface/utility/StringUtilities.h>
+
+namespace Silecs
+{
+
+	CNVConnection::CNVConnection(PLC* thePLC) : Connection(thePLC)
+	{
+		LOG(ALLOC) << "CNVConnection (create): " << thePLC->getName();
+	}
+
+
+	CNVConnection::~CNVConnection()
+	{
+		//Close the connection before removing resources
+        //disable(); must be done before removing resource
+	}
+
+	/* Check for errors */
+	int CNVConnection::errChk(PLC* thePLC, int code)// throw (std::string*)
+	{
+        if(code != 0)
+        {   LOG(DEBUG) << "CNV error occurred: " << code << ": " << CNVGetErrorDescription(code);
+            //Do not close the connection if it's only for data missing (when deleting empty Data object)
+            if (code != CNVInvalidDataHandleError)
+            {
+                LOG(COMM) << "Transaction failure with PXI: " << thePLC->getName() << ". CNV[" << code << "]: " << CNVGetErrorDescription(code);
+                doClose(thePLC, /*withLock =*/true);
+			    throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, std::string(CNVGetErrorDescription(code))+" in CNVConnection");
+            }
+		}
+        return code;
+	}
+
+	/* Read Data */
+    int CNVConnection::readData(PLC* thePLC, CNVBufferedSubscriber *handle,CNVData *data)
+    {
+        CNVBufferDataStatus status;
+
+        /* Buffer is used only for performance reason.
+         * Always return the last value in the buffer discarding the oldest ones.
+         */
+
+        //read the oldest data in the buffer
+        int errorCode = errChk(thePLC, CNVGetDataFromBuffer(*handle, data, &status));
+
+        if ((errorCode == 0) && (status != CNVStaleData))
+        {
+            if (status != CNVNoData)
+            { //buffer was not empty, try to read again to get the very last data if any
+              errChk(thePLC, CNVDisposeData(*data)); //CNV requires to free the buffer on every CNVGetDataFromBuffer
+              errorCode = errChk(thePLC, CNVGetDataFromBuffer(*handle, data, &status));
+            }
+            else
+            {   LOG(DEBUG) << "CNVConnection::readData() : buffer is empty (variables may not be initialized properly)";
+                errorCode = CNVEmptyDataError;
+            }
+        }
+        return errorCode;
+    }
+
+	/* Write Data */
+	int CNVConnection::writeData(PLC* thePLC, const char *networkVariablePathname, CNVData data)
+	{
+		CNVWriter writer;
+
+		int errorCode = errChk(thePLC, CNVCreateWriter(networkVariablePathname , NULL, NULL, CNVWaitForever , 0, &writer));
+
+		if (errorCode ==0)
+		{   CNVWrite (writer, data, 0);
+            CNVDispose(writer);
+		}
+		return errorCode;
+	}
+
+	bool CNVConnection::open(PLC* thePLC)
+	{
+	    bool isOK = false;
+
+        if (IeRfcPing((char *) thePLC->getName().c_str(), 0) == 0)
+        {
+            LOG(DEBUG) << "CNVConnection::open(): Controller is reachable (ping), then subscribe input variables";
+
+            isOK = true; //all subscription is fine a priori
+
+            // Create all the subscriptions
+            blockMapType::iterator pBlockIter;
+            for(pBlockIter = thePLC->getBlockMap().begin(); pBlockIter != thePLC->getBlockMap().end(); ++pBlockIter)
+            {
+                //Attention: only CNVInputBlock has doSubscribe/unSubscribe feature (key-map can be used to select appropriate object)
+                if (pBlockIter->first.find(Block::whichAccessType(Input)) != std::string::npos)
+                { if (static_cast<CNVInputBlock*>(pBlockIter->second)->doSubscribe() == false)
+                    {  isOK = false;
+                       break;
+                    }
+                }
+            }
+        }
+        return isOK;
+	}
+
+
+	bool CNVConnection::close(PLC* thePLC)
+	{
+        LOG(DEBUG) << "CNVConnection::close(): unSubscribe input variables";
+
+		// Delete all the subscription
+		blockMapType::iterator pBlockIter;
+		for(pBlockIter = thePLC->getBlockMap().begin(); pBlockIter != thePLC->getBlockMap().end(); ++pBlockIter)
+		{
+			//Attention: only CNVInputBlock has doSubscribe/unSubscribe feature (key-map can be used to select appropriate object)
+			if (pBlockIter->first.find(Block::whichAccessType(Input)) != std::string::npos)
+			{ static_cast<CNVInputBlock*>(pBlockIter->second)->unSubscribe();
+			}
+		}
+		isConnected_ = false;
+		return true;
+	}
+
+} // namespace
+
+#endif //NI_SUPPORT_ENABLED
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.h b/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.h
new file mode 100644
index 0000000000000000000000000000000000000000..c864b306e58ffc59f8ef7d9d56e8ed07b91591c7
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/CNVConnection.h
@@ -0,0 +1,111 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifdef NI_SUPPORT_ENABLED
+#ifndef _CNV_CONNECTION_H_
+#define _CNV_CONNECTION_H_
+
+#include <silecs-communication/interface/communication/SilecsConnection.h>
+
+#include <silecs-communication/protocol/core/silecs.h>
+
+#include <iostream>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <nilibnetv.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+namespace Silecs
+{
+	/*!
+	 * \class CNVConnection
+	 * \brief CNV-communication object for PXI Shared Variable Protocol
+	 */
+	class CNVConnection : public Connection
+	{
+
+	public:
+		CNVConnection(PLC* thePLC);
+ 		virtual ~CNVConnection();
+
+ 		/*!
+		 * \brief Read Data from the specified buffer handler
+         * \return the read CNVData and error code (0 = everything is ok)
+         */
+		//CNVData readData(CNVBufferedSubscriber *handle);
+		int readData(PLC* thePLC, CNVBufferedSubscriber *handle,CNVData *data);
+
+		/*!
+		 * \brief Write the specified variable, data must be already in CNVData format.
+		 * In case of error raises a std::string* exception containing the error message
+		 * \return error code (0 = everything is ok)
+         */
+		int writeData(PLC* thePLC, const char *networkVariablePathname, CNVData data);
+
+		/*!
+		 * \brief Subscribes for changes on the the specified variable.
+		 * In case of error raises a std::string* exception containing the error message
+         */
+		void monitorData(const char *networkVariablePathname);
+
+		// not implemented. here because of virtual in super class
+		// TODO: review in order to get read of it
+		int readData(PLC* thePLC, unsigned long address,
+							 unsigned long offset,
+							 unsigned long size,
+							 unsigned char* buffer){ return -1;};
+
+		// not implemented. here because of virtual in super class
+		// TODO: review in order to get read of it
+		int writeData(PLC* thePLC, unsigned long address,
+							 unsigned long offset,
+							 unsigned long size,
+							 unsigned char* buffer){return -1;};
+
+	private:
+		// Subscriber
+		CNVSubscriber subscriber;
+
+		/*!
+		 * \brief Print the error message related to the code and throw exception if needed
+		 * \return the error code itself (0 everything is ok)
+         */
+		int errChk(PLC* thePLC, int code);
+
+		/*!
+		 * \brief Open the connection
+		 * It actually return a boolean which indicates if the server responded to a ping operation
+         */
+		bool open(PLC* thePLC);
+
+		/*!
+		 * \brief Close the connection with the server
+         */
+		bool close(PLC* thePLC);
+
+	};
+
+} // namespace
+
+#endif // _CNV_CONNECTION_H_
+
+#endif //NI_SUPPORT_ENABLED
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.cpp b/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5bf337428165e9bdf54137aac98b0d2d703f19a9
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.cpp
@@ -0,0 +1,121 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <silecs-communication/interface/utility/StringUtilities.h>
+#include <silecs-communication/interface/communication/SilecsConnection.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/communication/MBConnection.h>
+#include <silecs-communication/interface/utility/SilecsException.h>
+
+namespace Silecs
+{
+
+	MBConnection::MBConnection(PLC* thePLC) : Connection(thePLC)
+	{
+		LOG(ALLOC) << "MBConnection (create): " << thePLC->getName();
+	}
+
+
+	MBConnection::~MBConnection()
+	{
+		//Close the connection before removing resources
+		//disable(); must be done before removing resource
+	}
+
+
+	bool MBConnection::open(PLC* thePLC)
+	{
+		//Open read and write Modbus channels (using IP address to limit the naming-server accesses)
+		readCh_  = IeMdbOpen(0, (char *) thePLC->getIPAddress().c_str(), (int)thePLC->getBaseAddress());
+		writeCh_ = IeMdbOpen(0, (char *) thePLC->getIPAddress().c_str(), (int)thePLC->getBaseAddress());
+		return ((readCh_ >= 0) && (writeCh_ >= 0));
+	}
+
+
+	bool MBConnection::close(PLC* thePLC)
+	{
+		int err = 0;
+		err |= IeMdbClose(readCh_);
+		err |= IeMdbClose(writeCh_);
+		return (err == 0);
+	}
+
+
+	int MBConnection::readData(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer)
+	{
+		//Schneider uses 16bit alignment memory. Block address is expressed in bytes, must be an even value!
+		if (address % 2) throw SilecsException(__FILE__, __LINE__, PARAM_INCORRECT_BLOCK_ADDRESS, StringUtilities::toString(address));
+
+	   /* . There is one read-channel per PLC connection. It must be protected against concurrent access.
+		* . The write-channel is independent and can be accessed in parallel.
+		* . The global action (open,close,etc.) must be protected from any concurrent access.
+		* Attention!
+		* Mutexes are defined with recursive option. It allows doOpen method re-calling readData
+		* method by executing register synchronization if required.
+		*/
+
+		//(re)connect the PLC if needed and (re)synchronize the retentive registers
+		if (doOpen(thePLC))
+		{
+			//connection is established then acquire data
+			Lock lock(readMux_);
+			//Schneider uses 16bit alignment memory. Block address is expressed in bytes (==> /2)
+			unsigned short addr = ((unsigned short)address + (unsigned short)offset)/2;
+
+			//DATA topic makes sense with RECV one
+			if (RECV & Log::topics_) LOG(DATA) << "Read data, address: %MW" << addr << ", byte-size: " << size;
+
+			int error = IeMBreadData(readCh_, addr, (unsigned short)size, pBuffer);
+	        if(error)
+	        	throw SilecsException(__FILE__, __LINE__, UNEXPECTED_ERROR," ModBus Error: " + string(IeGetErrorMessage(error)));
+		}
+		return 0;
+	}
+
+
+	int MBConnection::writeData(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer)
+	{
+		//Schneider uses 16bit alignment memory. Block address is expressed in bytes, must be an even value!
+		if (address % 2) throw SilecsException(__FILE__, __LINE__, PARAM_INCORRECT_BLOCK_ADDRESS, StringUtilities::toString(address));
+
+	   /* . There is one read-channel per PLC connection. It must be protected against concurrent access.
+		* . The write-channel is independent and can be accessed in parallel.
+		* . The global action (open,close,etc.) must be protected from any concurrent access.
+		* Attention!
+		* Mutexes are defined with recursive option. It allows doOpen method re-calling sendData
+		* method by executing register synchronization if required.
+		*/
+
+		//(re)connect the PLC if needed and (re)synchronize the retentive registers
+		if (doOpen(thePLC))
+		{
+			//connection is established then send data
+
+			Lock lock(writeMux_);
+			//Schneider uses 16bit alignment memory. Block address is expressed in bytes (==> /2)
+			unsigned short addr = ((unsigned short)address + (unsigned short)offset)/2;
+
+			//DATA topic makes sense with SEND one
+			if (SEND & Log::topics_) LOG(DATA) << "Write data, address: %MW" << addr << ", byte-size: " << size;
+
+			int error = IeMBwriteData(writeCh_, (unsigned short)addr, (unsigned short)size, pBuffer);
+	        if(error)
+	        	throw SilecsException(__FILE__, __LINE__, UNEXPECTED_ERROR," ModBus Error: " + string(IeGetErrorMessage(error)));
+		}
+		return 0;
+	}
+
+} // namespace
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.h b/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.h
new file mode 100644
index 0000000000000000000000000000000000000000..953cdd8d4c6b86d9bd6fd6bfd6f246fbe94c1900
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/MBConnection.h
@@ -0,0 +1,50 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _MB_CONNECTION_H_
+#define _MB_CONNECTION_H_
+
+#include <silecs-communication/interface/communication/SilecsConnection.h>
+#include <silecs-communication/protocol/core/silecs.h>
+
+namespace Silecs
+{
+	class PLC;
+	class Connection;
+
+	/*!
+	 * \class MBConnection
+	 * \brief Plc-communication object for specific Modbus protocol
+	 */
+	class MBConnection : public Connection
+	{
+
+	public:
+		MBConnection(PLC* thePLC);
+ 		virtual ~MBConnection();
+
+ 		int readData(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer);
+ 		int writeData(PLC* thePLC, unsigned long address, unsigned long offset, unsigned long size, unsigned char* pBuffer);
+
+	private:
+		bool open(PLC* thePLC);
+		bool close(PLC* thePLC);
+
+	};
+
+} // namespace
+
+#endif // _MB_CONNECTION_H_
+
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.cpp b/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7276087145f64dd1071ff685e566673af86cdb5a
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.cpp
@@ -0,0 +1,201 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <silecs-communication/interface/utility/StringUtilities.h>
+#include <silecs-communication/interface/communication/SilecsConnection.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/communication/SNAP7Connection.h>
+#include <silecs-communication/interface/utility/SilecsException.h>
+
+namespace Silecs
+{
+
+	SNAP7Connection::SNAP7Connection(PLC* thePLC) : Connection(thePLC)
+	{
+		recvClient_ = Cli_Create();
+        sendClient_ = Cli_Create();
+		LOG(ALLOC) << "SNAP7Connection (create) PLC/Cluster: " << thePLC->getName() << "/" << thePLC->theCluster_->getClassName();
+	}
+
+
+	SNAP7Connection::~SNAP7Connection()
+	{
+	    Cli_Destroy(&recvClient_);
+        Cli_Destroy(&sendClient_);
+	}
+
+	bool SNAP7Connection::open(PLC* thePLC)
+	{
+        int err = 0;
+
+        //Slot number is not required, so try to connect on different slots (1..31), depending on hardware layout.
+        int *slotsScan;
+        int slotsS7400[4]    = { 3,4,2,1 };  //slot scan - most common layout S7-400
+        int slotsS71x00[4]  = { 1,2,3,4 };  //slot scan - most common layout S7-1200, S7-1500
+        int slotsDefault[4]   = { 2,3,4,1 }; //slot scan - most common layout S7-other (S7-300, ET200S)
+        int rackNb = 0;                              //rackNb - common rack is 0 so far
+        int slotNb;
+
+        switch (thePLC->getModelID())
+        {
+            case S7400:
+                slotsScan = slotsS7400;    break;
+            case S71200:
+            case S71500:
+                slotsScan = slotsS71x00; break;
+            default:
+                slotsScan = slotsDefault;  //S7-300, ET200S
+        }
+
+        for(int i=0; i<4; i++)
+        {
+            slotNb = slotsScan[i];
+            err = Cli_ConnectTo(recvClient_, thePLC->getIPAddress().c_str(), rackNb, slotNb);
+            if (err) // next slot
+            {
+            	LOG(DEBUG) << "SNAP7 connection (channel-2) failed on PLC/rack/slot: " << thePLC->getName() << "/" << rackNb << "/" << slotNb <<". SNAP7[" << err << "]: " << getSNAP7ErrorMessage(err);
+            	break;
+            }
+            LOG(DEBUG) << "SNAP7 connect (channel-1) successful on PLC/rack/slot: " << thePLC->getName() << "/" << rackNb << "/" << slotNb;
+            //We managed to open the first channel, just open the second one on the same slot.
+            err = Cli_ConnectTo(sendClient_, thePLC->getIPAddress().c_str(), rackNb, slotNb);
+            if (err) // next slot
+            {
+            	LOG(DEBUG) << "SNAP7 connection (channel-2) failed on PLC/rack/slot: " << thePLC->getName() << "/" << rackNb << "/" << slotNb <<". SNAP7[" << err << "]: " << getSNAP7ErrorMessage(err);
+            	break;
+            }
+            LOG(DEBUG) << "SNAP7 connect (channel-2) successful on PLC/rack/slot: " << thePLC->getName() << "/" << rackNb << "/" << slotNb;
+            return true;
+        }
+	    return false;
+	}
+
+
+	bool SNAP7Connection::close(PLC* thePLC)
+	{
+		bool ret = (Cli_Disconnect(recvClient_) == 0) &&
+		            (Cli_Disconnect(sendClient_) == 0);
+		return ret;
+	}
+
+
+    std::string SNAP7Connection::getSNAP7ErrorMessage(int err)
+    {
+        char text[100];
+        Cli_ErrorText(err, text, 100);
+        return std::string(text);
+    }
+
+
+    //-------------------------------------------------------------------------------------------------------------------
+    int SNAP7Connection::readUnitCode(PLC* thePLC, UnitCodeType& dataStruct)
+    {
+        TS7OrderCode S7data;
+        int error = Cli_GetOrderCode(recvClient_, &S7data);
+        if(error)
+        	throw SilecsException(__FILE__, __LINE__, UNEXPECTED_ERROR," SNAP7 Error: " + getSNAP7ErrorMessage(error));
+		std::ostringstream os;
+		os << S7data.Code;
+		dataStruct.code = os.str();
+		os.str().clear();
+		os << (int)S7data.V1 << "." << (int)S7data.V2 << "." << (int)S7data.V3;
+		dataStruct.version = os.str();
+		LOG(DEBUG) << "Unit order-code received: " << dataStruct.code << ", " << dataStruct.version;
+		return 0;
+    }
+
+
+    int SNAP7Connection::readUnitStatus(PLC* thePLC, UnitStatusType& dataStruct)
+    {
+        int status;
+        int error = Cli_GetPlcStatus(recvClient_, &status);
+        if(error)
+        	throw SilecsException(__FILE__, __LINE__, UNEXPECTED_ERROR," SNAP7 Error: " + getSNAP7ErrorMessage(error));
+		dataStruct.status = status;
+		LOG(DEBUG) << "Unit status received: " << (int)dataStruct.status;
+		return 0;
+    }
+
+    int SNAP7Connection::readCPUInfo(PLC* thePLC, CPUInfoType& dataStruct)
+    {
+        TS7CpuInfo S7data;
+        int error = Cli_GetCpuInfo(recvClient_, &S7data);
+        if(error)
+        	throw SilecsException(__FILE__, __LINE__, UNEXPECTED_ERROR," SNAP7 Error: " + getSNAP7ErrorMessage(error));
+		dataStruct.moduleName = std::string(S7data.ModuleName);
+		dataStruct.moduleTypeName = std::string(S7data.ModuleTypeName);
+		dataStruct.serialNumber = std::string(S7data.SerialNumber);
+		dataStruct.asName = std::string(S7data.ASName);
+		dataStruct.copyright = std::string(S7data.Copyright);
+		LOG(DEBUG) << "CPU info received: " << dataStruct.moduleName << ", " << dataStruct.moduleTypeName << ", "
+				   << dataStruct.serialNumber << ", " << dataStruct.asName << ", " << dataStruct.copyright;
+		return 0;
+    }
+
+    int SNAP7Connection::readCPInfo(PLC* thePLC, CPInfoType& dataStruct)
+    {
+        TS7CpInfo S7data;
+        int error = Cli_GetCpInfo(recvClient_, &S7data);
+        if(error)
+        	throw SilecsException(__FILE__, __LINE__, UNEXPECTED_ERROR," SNAP7 Error: " + getSNAP7ErrorMessage(error));
+		dataStruct.maxPduLength = S7data.MaxPduLengt;
+		dataStruct.maxConnections = S7data.MaxConnections;
+		dataStruct.maxMPIRate = S7data.MaxMpiRate;
+		dataStruct.maxBusRate = S7data.MaxBusRate;
+		LOG(DEBUG) << "CP info received: " << dataStruct.maxPduLength << ", " << dataStruct.maxConnections << ", "
+				   << dataStruct.maxMPIRate << ", " << dataStruct.maxBusRate;
+		return 0;
+    }
+
+
+    //-------------------------------------------------------------------------------------------------------------------
+	int SNAP7Connection::readData(PLC* thePLC, unsigned long DBn, unsigned long offset, unsigned long size, unsigned char* pBuffer)
+	{
+        //(re)connect the PLC if needed and (re)synchronize the retentive registers
+        if (doOpen(thePLC))
+        {
+            //connection is established then acquire data
+        	Lock lock(readMux_);
+
+			//DATA topic makes sense with RECV one
+			if (RECV & Log::topics_) LOG(DATA) << "Read data, DBn: " << DBn << ", ofs: " << offset << ", byte-size: " << size;
+
+			int error = Cli_DBRead(recvClient_, (int)DBn, (int)offset, (int)size, (void *)pBuffer);
+	        if(error)
+	        	throw SilecsException(__FILE__, __LINE__, UNEXPECTED_ERROR," SNAP7 Error: " + getSNAP7ErrorMessage(error));
+        }
+		return 0;
+	}
+
+	int SNAP7Connection::writeData(PLC* thePLC, unsigned long DBn, unsigned long offset, unsigned long size, unsigned char* pBuffer)
+	{
+		//(re)connect the PLC if needed and (re)synchronize the retentive registers
+		if (doOpen(thePLC))
+		{
+			//connection is established then send data
+			Lock lock(writeMux_);
+
+			//DATA topic makes sense with SEND one
+			if (SEND & Log::topics_) LOG(DATA) << "Write data, DBn: " << DBn << ", ofs: " << offset << ", byte-size: " << size;
+
+			int error = Cli_DBWrite(sendClient_, (int)DBn, (int)offset, (int)size, (void *)pBuffer);
+	        if(error)
+	        	throw SilecsException(__FILE__, __LINE__, UNEXPECTED_ERROR," SNAP7 Error: " + getSNAP7ErrorMessage(error));
+		}
+		return 0;
+	}
+
+} // namespace
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.h b/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d14818f47bade0cf3378e471f6139005dbc8e6a
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SNAP7Connection.h
@@ -0,0 +1,58 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _SNAP7_CONNECTION_H_
+#define _SNAP7_CONNECTION_H_
+
+#include <silecs-communication/protocol/core/silecs.h>
+#include <snap7.h>
+
+namespace Silecs
+{
+	class PLC;
+	class Connection;
+
+	/*!
+	 * \class SNAP7Connection
+	 * \brief Plc-communication object for specific SNAP7 protocol
+	 */
+	class SNAP7Connection : public Connection
+	{
+
+	public:
+		SNAP7Connection(PLC* thePLC);
+ 		virtual ~SNAP7Connection();
+
+        int readUnitCode(PLC* thePLC, UnitCodeType& dataStruct);
+        int readUnitStatus(PLC* thePLC, UnitStatusType& dataStruct);
+        int readCPUInfo(PLC* thePLC, CPUInfoType& dataStruct);
+        int readCPInfo(PLC* thePLC, CPInfoType& dataStruct);
+
+ 		int readData(PLC* thePLC, unsigned long DBn, unsigned long offset, unsigned long size, unsigned char* pBuffer);
+ 		int writeData(PLC* thePLC, unsigned long DBn, unsigned long offset, unsigned long size, unsigned char* pBuffer);
+
+	private:
+ 		S7Object recvClient_;
+        S7Object sendClient_;
+		bool open(PLC* thePLC);
+		bool close(PLC* thePLC);
+
+	    std::string getSNAP7ErrorMessage(int err);
+	};
+
+} // namespace
+
+#endif // _SNAP7_CONNECTION_H_
+
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fc9c8036630b5ffe6ec1292e798f9bc216b25d6f
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp
@@ -0,0 +1,387 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <silecs-communication/interface/communication/SilecsConnection.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/protocol/core/silecs.h>
+
+namespace Silecs
+{
+
+	// static definition
+	bool Connection::isInit_ = false;
+	bool Connection::isAlive_ = false;
+	const unsigned int Connection::numberConn_ = 3;
+
+	//------------------------------------------------------------------------------------------------------------------------------------------------
+	Connection::Connection(PLC* thePLC)
+	{
+		// Start the PLC Thread
+		readMux_ 	= new Mutex("readMux");
+		writeMux_ 	= new Mutex("writeMux");
+		connMux_ 	= new Mutex("connMux");
+
+		//Not yet allowed, not yet connected!
+		isEnabled_    = false;
+		isConnected_  = false;
+
+		//Reset the Reconnection mechanism
+		timeConn_ = NULL;
+		delayConn_ = UrgentConnection;   //initial reconnection delay
+		remainConn_ = numberConn_; 		 //initial number of attempt
+
+		// Silecs initialization has to be invoked only once per process
+		if (isInit_== false)
+		{	IeInit();
+			isInit_ = true;
+		}
+	}
+
+
+	//------------------------------------------------------------------------------------------------------------------------------------------------
+	Connection::~Connection()
+	{
+	    //Connection has been closed before from the concrete connection object
+		if (timeConn_ != NULL) delete timeConn_;
+
+		delete connMux_;
+		delete writeMux_;
+		delete readMux_;
+	}
+
+	//------------------------------------------------------------------------------------------------------------------------------------------------
+	bool Connection::enable(PLC* thePLC, bool connectNow)
+	{
+		{
+			Lock lock(connMux_);
+			isEnabled_ = true;
+		}
+		if (connectNow) doOpen(thePLC);
+		return isConnected_;
+	}
+
+	//------------------------------------------------------------------------------------------------------------------------------------------------
+	void Connection::disable(PLC* thePLC)
+	{
+        if (!isEnabled_) {
+            LOG(DEBUG) << "Trying to disconnect a PLC that is not enabled: " << thePLC->getName();
+            return;
+        }
+
+        Lock lock(connMux_);
+        {
+        	Lock lock(readMux_);
+        	{
+        		Lock lock(writeMux_);
+        		isEnabled_ = false;
+        		doClose(thePLC, /*withLock =*/false);
+        	}
+        }
+	}
+
+	//------------------------------------------------------------------------------------------------------------------------------------------------
+	bool Connection::doOpen(PLC* thePLC)
+	{
+		LOG((COMM|DIAG)) << "Start attempt to open connection ...";
+		bool justConnected = false;
+
+		{
+			Lock lock(connMux_);
+			if (isConnected_)
+			{	if (!isEnabled_)
+				{
+					LOG((COMM|DIAG)) << "The PLC is connected but the client wants to disable the transactions";
+					doClose(thePLC, /*withLock =*/false);
+				}
+				return isConnected_;
+			}
+
+			if (!isEnabled_)
+			{
+				LOG((COMM|DIAG)) << "The communication currently is not enabled";
+				return isConnected_;
+			}
+
+			if (isTimeToReconnect())
+			{
+				LOG((COMM|DIAG)) << "It's time to reconnect";
+				if ((thePLC->synchroMode_ == FULL_SYNCHRO) || (thePLC->synchroMode_ == SLAVE_SYNCHRO))
+				{
+					//Retentive registers synchronization is requested:
+					//connection is not allowed if Slave Registers are not all initialized
+					std::string registerNotInitialized;
+					if (thePLC->checkSlaveRegistersInit(registerNotInitialized) == false)
+					{
+						logError(thePLC);
+						throw SilecsException(__FILE__, __LINE__, DIAG_SLAVE_REGISTER_NOT_INITIALIZED, registerNotInitialized);
+					}
+				}
+
+				// It's time to open the connection according to the (re)connection timing
+				// Let's try several times with limited delay (some ms).
+				// It allows wake-up frozen PLC (SIEMENS in particular) after long stop period.
+				bool isOpen  = false;
+				unsigned int nbConn = 2;    //for fast low-level iteration
+				for(unsigned int i = 0; i<nbConn; i++)
+				{
+					LOG((COMM|DIAG)) << "Attempt to open PLC connection ....";
+					isOpen = open(thePLC);
+					if(isOpen)
+					{
+						LOG((COMM|DIAG)) << "Connection opened successfully";
+						break;
+					}
+					usleep(100000); // wait 100ms
+				}
+				if(!isOpen)
+				{
+					logError(thePLC);
+					return isConnected_;
+				}
+
+				if (thePLC->isSharedConnection())
+				{
+					LOG((COMM|DIAG)) << "Shared connection with " << thePLC->getName() << " is established.";
+				}
+				else
+				{
+					LOG((COMM|DIAG)) << "Connection with " << thePLC->getName() <<
+									  ":" << thePLC->theCluster_->getClassName() <<
+									  "/v" << thePLC->theCluster_->getClassVersion() <<
+									  " is established.";
+				}
+
+				isAlive_ = true;
+				isConnected_ = true;
+				justConnected = true; //retentive registers synchronization is required!
+
+				//Connection status has changed: update the diagnostic variables
+				LOG((COMM|DIAG)) << "Updating PLC status";
+				updateStatus(thePLC);
+			}
+		}//release lock
+
+		/* Process the Retentive registers synchronization each time the PLC is just (re)connected.
+		 * This is a recursive call: performs task::execute method from doOpen that is
+		 * called into execute itself. The recursion is terminated when SilecsHeader connection is closed finally.
+		 */
+		if (justConnected)
+		{
+			LOG((COMM|DIAG)) << "First connection - performing registers synchronization";
+			if ((thePLC->synchroMode_ == FULL_SYNCHRO) || (thePLC->synchroMode_ == MASTER_SYNCHRO))
+			{
+				thePLC->downloadMasterRegisters();
+			}
+
+			if ((thePLC->synchroMode_ == FULL_SYNCHRO) || (thePLC->synchroMode_ == SLAVE_SYNCHRO))
+			{
+				thePLC->uploadSlaveRegisters();
+			}
+		}
+		LOG((COMM|DIAG)) << "isConnected_:" << isConnected_;
+		return isConnected_;
+	}
+
+
+	//------------------------------------------------------------------------------------------------------------------------------------------------
+	void Connection::doClose(PLC* thePLC, bool withLock)
+	{
+		//This process that can be called inside and outside protected section.
+		//withLock argument is used to avoid Recursive mutex that is not supported
+		//by LynxOS platform.
+
+		if(withLock)
+			Lock lock(connMux_);
+
+		if (isConnected_)
+		{
+			if (close(thePLC))
+			{
+			  readCh_ = writeCh_ = 0;
+			  isConnected_ = false;
+
+			  //Connection status has changed: update the diagnostic variables
+			  updateStatus(thePLC);
+
+			  if (thePLC->isSharedConnection())
+			  {
+				  LOG((COMM|DIAG)) << "Shared connection with " << thePLC->getName() << " is closed.";
+			  }
+			  else
+			  {
+				  LOG((COMM|DIAG)) << "Connection with " << thePLC->getName() <<
+						  " (" << thePLC->theCluster_->getClassName() <<
+						  "/v" << thePLC->theCluster_->getClassVersion() <<
+						  ")" << " is closed.";
+			  }
+			}
+			else
+			{ LOG(COMM) << "Close connection with " << thePLC->getName() <<
+						  " (" << thePLC->theCluster_->getClassName() <<
+						  "/v" << thePLC->theCluster_->getClassVersion() <<
+						  ")" << " has failed.";
+			}
+		}
+
+	}
+
+
+	//------------------------------------------------------------------------------------------------------------------------------------------------
+	bool Connection::reOpen(PLC* thePLC)
+	{
+		if (IeRfcPing((char *) thePLC->getName().c_str(), 0) == 0)
+		{	doClose(thePLC, /*withLock =*/true);
+			return doOpen(thePLC);
+		}
+		isAlive_ = false;
+		return false;
+	}
+
+    bool Connection::isEnabled() { return isEnabled_; }
+    bool Connection::isConnected() { return isConnected_; }
+
+
+    //-------------------------------------------------------------------------------------------------------------------
+    int Connection::readUnitCode(PLC* thePLC, UnitCodeType& dataStruct)
+    {
+        throw SilecsException(__FILE__, __LINE__, DIAG_PLC_REPORT_NOT_SUPPORTED, thePLC->getName());
+        return -1;
+    }
+
+
+    int Connection::readUnitStatus(PLC* thePLC, UnitStatusType& dataStruct)
+    {
+        throw SilecsException(__FILE__, __LINE__, DIAG_PLC_REPORT_NOT_SUPPORTED, thePLC->getName());
+        return -1;
+    }
+
+
+    int Connection::readCPUInfo(PLC* thePLC, CPUInfoType& dataStruct)
+    {
+        throw SilecsException(__FILE__, __LINE__, DIAG_PLC_REPORT_NOT_SUPPORTED, thePLC->getName());
+        return -1;
+    }
+
+
+    int Connection::readCPInfo(PLC* thePLC, CPInfoType& dataStruct)
+    {
+        throw SilecsException(__FILE__, __LINE__, DIAG_PLC_REPORT_NOT_SUPPORTED, thePLC->getName());
+        return -1;
+    }
+
+
+	//-------------------------------------------------------------------------------------------------------------------
+	bool Connection::checkError(PLC* thePLC, int err, bool retry)
+	{
+		if (err < 0)
+		{
+			LOG(COMM) << "Transaction failure with PLC: " << thePLC->getName() << ". SILECS[" << err << "]: " << IeGetErrorMessage(err);
+
+			switch(err)
+			{
+			case IE_TIMEOUT_ERROR:
+			case IE_EPIPE_ERROR:
+			case IE_DISCONNECT_ERROR:
+				if (retry)
+				{
+					LOG(COMM) << "Try to reconnect the PLC: " << thePLC->getName();
+					if (reOpen(thePLC))
+					{   // can repeat the request after the connection was successfully reopened
+						return true;
+					}
+					// reconnection has failed again, just close the connection
+					LOG(COMM) << "Unable to reconnect the PLC: " << thePLC->getName();
+				}
+				// else { // no retry, we just want to close (use default case)
+			default:
+				doClose(thePLC, /*withLock =*/true);
+			}
+		}
+		return false; // no particular error
+	}
+
+
+	//------------------------------------------------------------------------------------------------------------------------------------------------
+	void Connection::updateStatus(PLC* thePLC)
+	{
+		//Connection status has changed (opened/closed)
+		//Update the PLC diagnostic variables
+		thePLC->updateStatus();
+
+		//Reset reconnection mecanisme in case of connection succeed
+		if (isConnected_)
+		{ delayConn_ = UrgentConnection;   //initial reconnection delay
+		  remainConn_ = numberConn_; 	   //initial number of attempt
+		}
+	}
+
+
+	//------------------------------------------------------------------------------------------------------------------------------------------------
+	void Connection::logError(PLC* thePLC)
+	{
+	    std::string errorMsg = "Connection with " + thePLC->getName() +
+							   ":" + thePLC->theCluster_->getClassName() +
+								"/v" + thePLC->theCluster_->getClassVersion() +
+								" has failed. ";
+
+		if (delayConn_ == LongTermConnection)
+		{	if (remainConn_ > 0)
+			{   LOG((COMM|DIAG)) << errorMsg << "Periodic attempt to reconnect, delay " << delayConn_ << "s (logging off).";
+				remainConn_ = 1; //Try to reconnect again and again (=1 means disable logging).
+			}
+			else
+			{
+				LOG((COMM|DIAG)) << errorMsg << "PLC does not respond anymore. It's probably stopped for a long time. Trying to reconnect with long-term delay";
+			}
+		}
+		else
+			LOG((COMM|DIAG)) << errorMsg << "Next attempt to reconnect in " << delayConn_ << "s if requested. Remains: " << remainConn_;
+	}
+
+	//------------------------------------------------------------------------------------------------------------------------------------------------
+	bool Connection::isTimeToReconnect()
+	{
+		bool toBeReconnected = false;
+		if (timeConn_ != NULL)
+		{	//how many time from the last connect attempt
+			double delay = timeConn_->getDelay(S_UNIT);
+			if (delay >= double(delayConn_))
+			{ 	timeConn_->getValue(S_UNIT); 	 //restart delay counting from now
+				toBeReconnected =  true;
+
+				if (remainConn_ > 0) --remainConn_;
+				if (remainConn_ == 0)
+				{	if (delayConn_ != LongTermConnection)
+					{   if (delayConn_ == UrgentConnection)
+							delayConn_ = ShortTermConnection;
+						else //(delayConn_ == ShortTermConnection)
+							delayConn_ = LongTermConnection;
+						remainConn_ = numberConn_;
+					}
+				}
+			}
+		}
+		else
+		{
+			//This is the first connection attempt, just start the Time counter.
+			timeConn_ = new TsCounter(true); //using hardware clock
+			timeConn_->getValue(S_UNIT); 	 //start delay counting from now
+			toBeReconnected =  true;
+		}
+		return toBeReconnected;
+	}
+
+} // end namespace
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.h b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.h
new file mode 100644
index 0000000000000000000000000000000000000000..ca2319a0fcf80d0ce325c9f395eda5062c6ee683
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.h
@@ -0,0 +1,175 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _SILECS_CONNECTION_H_
+#define _SILECS_CONNECTION_H_
+
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/utility/Mutex.h>
+#include <silecs-communication/interface/utility/TimeStamp.h>
+#include <silecs-communication/protocol/core/silecs.h>
+
+namespace Silecs
+{
+	class PLC;
+
+	// Time to wait (second) before next reconnection attempt
+	typedef enum
+	{  UrgentConnection=2, ShortTermConnection=20, LongTermConnection=60
+	} ConnectionDelay;
+
+#ifdef __x86_64__
+    typedef long ChannelID;  //pointer is 64bits word
+#else
+    typedef int ChannelID;     //pointer is 32bits word
+#endif
+
+    class Lock
+    {
+
+	public:
+
+    	Lock(Mutex* mutex): mutex_(mutex)
+    	{
+    		mutex_->lock();
+    	}
+
+    	~Lock()
+    	{
+    		mutex_->unlock();
+    	}
+    	Mutex* mutex_;
+    };
+
+	class Connection
+	{
+
+	public:
+		Connection(PLC* thePLC);
+		virtual ~Connection();
+
+		virtual int readData(PLC* thePLC,
+		                     unsigned long address,
+							 unsigned long offset,
+							 unsigned long size,
+							 unsigned char* buffer) = 0;
+
+		virtual int writeData(PLC* thePLC,
+		                     unsigned long address,
+							 unsigned long offset,
+							 unsigned long size,
+							 unsigned char* buffer) = 0;
+
+        /*!
+         * \fn enable/disable
+		 * \brief The client can suspend the data transmission by disabling the connection if required.
+		 * enable/disable methods are used from the high-level Cluster API: connect/disconnect.
+		 * \param connectNow can be used to force immediate connection (true)
+         */
+		virtual bool enable(PLC* thePLC, bool connectNow);
+        void disable(PLC* thePLC);
+        bool isEnabled();
+
+		static inline bool isAlive() { return isAlive_; }
+        bool isConnected();
+
+        virtual int readUnitCode(PLC* thePLC, UnitCodeType& dataStruct);
+        virtual int readUnitStatus(PLC* thePLC, UnitStatusType& dataStruct);
+        virtual int readCPUInfo(PLC* thePLC, CPUInfoType& dataStruct);
+        virtual int readCPInfo(PLC* thePLC, CPInfoType& dataStruct);
+
+	protected:
+		friend class Cluster;
+        friend class PLC;
+        friend class CNVRecvDeviceMode;
+        friend class CNVSendDeviceMode;
+
+        /*!
+         * \fn doOpen
+		 * \brief This method check the current state of the connection and open it if required.
+		 * doOpen that is called on each transaction is reponsible of the automatic reconnection mechanism.
+		 */
+		virtual bool doOpen(PLC* thePLC);
+		void doClose(PLC* thePLC, bool withLock);
+		bool reOpen(PLC* thePLC);
+
+		virtual bool open(PLC* thePLC) = 0; 	//open the connection for a particular PLC brand
+		virtual bool close(PLC* thePLC) = 0;   //close the connection for a particular PLC brand
+
+        /*!
+         * \fn checkError
+		 * \brief This method attempts to reconnect the PLC in case of "expected" transaction failure.
+		 * If the returned value is true the request must be repeated.
+		 * The retry flag defines whether the transaction will be repeated or not
+		 * IE_CONNECT_ERROR - TCP/IP connect() failed: IeOpen() (PLC is off or the max. number of open connection is reached)
+		 * Retry required:
+		 * IE_DISCONNECT_ERROR -  Explicit/unexpected disconnect request (when the connection has been unactive for some time)
+		 * IE_EPIPE_ERROR - TCP/IP send/recv failed (when one of the channel (get/set) has been unactive for some time or PLC is off)
+		 * IE_TIMEOUT_ERROR - PLC is connected but does not reply (In mean time the PLC gets off or data is lost)
+         */
+		virtual bool checkError(PLC* thePLC, int err, bool retry);
+
+        /*!
+         * \fn updatePLCStatus
+		 * \brief Responsible to update the diagnostic variables each time PLC states have changed
+         */
+		void updateStatus(PLC* thePLC);
+
+		void logError(PLC* thePLC);
+
+        /*!
+         * \fn isTimeToReconnect
+		 * \brief In order to not overload the network the reconnection attempts are gradually slowed
+		 * down from second scale to several minutes. This method checks the elapsed time since connection.
+		 * \return true if it's time to try to reconnect (time unit is second).
+         */
+		bool isTimeToReconnect();
+
+	 	// flag used to enable/disable the transactions independently from the scheduling
+		bool isEnabled_;
+
+		// Silecs descriptor for send/recv channels
+		ChannelID readCh_;
+		ChannelID writeCh_;
+
+		/* . read-channel and write channel are independent and can be accessed in parallel.
+		 * . Each channel must be protected against respective concurrent access.
+		 * . The global action (open,close,etc.) must be protected from any concurrent access.
+		 */
+		Mutex* readMux_; 	//Mutex used to protect the PLC read-channel resource
+		Mutex* writeMux_; 	//Mutex used to protect the PLC write-channel resource
+		Mutex* connMux_; 	//Mutex used to protect the global PLC connection resource (for open/close, etc.)
+
+		// Time counter to manage the automatic reconnection
+		TsCounter* timeConn_;
+		ConnectionDelay delayConn_; //current delay between two connection
+		unsigned long remainConn_;  //number of attempt before next slow-down
+		static const unsigned int numberConn_; //number of connection attempt for each connection delay
+
+		// Communication Diagnostic & Monitoring
+		static bool isAlive_; // PLC has repliyed to the ping: true/false
+		bool isConnected_; // State of this particular connection: FEC/PLC/Class
+
+		// Silecs initialization has to be invoked only once per process
+		static bool isInit_;
+
+		// not copyable object
+		Connection(const Connection&);
+		Connection& operator=(const Connection&);
+	};
+
+} // end namespace
+
+#endif // _SILECS_CONNECTION_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/CNVRecvAction.cpp b/silecs-communication-cpp/src/silecs-communication/interface/core/CNVRecvAction.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..57b425983494f0c96636d0c8f26704db3af60e74
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/CNVRecvAction.cpp
@@ -0,0 +1,171 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifdef NI_SUPPORT_ENABLED
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/core/PLCAction.h>
+#include <silecs-communication/interface/core/CNVRecvAction.h>
+#include <silecs-communication/interface/communication/SilecsConnection.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/equipment/SilecsDevice.h>
+#include <silecs-communication/interface/equipment/SilecsBlock.h>
+#include <silecs-communication/interface/core/Context.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include "../communication/CNVConnection.h.obsolete"
+#include "../equipment/CNVBlock.h.obsolete"
+
+namespace Silecs
+{
+
+	CNVRecvBlockMode::CNVRecvBlockMode(Block* block) : PLCAction(block)
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Action CNVRecvBlockMode (create): " << theBlock_->getName();
+	}
+
+	CNVRecvBlockMode::~CNVRecvBlockMode()
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Action CNVRecvBlockMode (delete): " << theBlock_->getName();
+	}
+
+	CNVRecvDeviceMode::CNVRecvDeviceMode(Block* block) : PLCAction(block)
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Action CNVRecvDeviceMode (create): " << theBlock_->getName();
+	}
+
+	CNVRecvDeviceMode::~CNVRecvDeviceMode()
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Action CNVRecvDeviceMode (delete): " << theBlock_->getName();
+	}
+
+	int CNVRecvBlockMode::execute(Context* pContext)
+	{
+		//Block mode cannot be implemented with CNV
+		return 0;
+	}
+
+	int CNVRecvDeviceMode::execute(Context* pContext)
+	{
+		timeval tod; //Time-of-day for register time-stampng
+
+		CNVData buffer;
+
+		int errorCode = 0;
+		Connection* pConn = theBlock_->getPLC()->getConnection();
+
+        //(re)connect the PLC if needed and (re)synchronize the retentive registers
+        if (pConn->doOpen(theBlock_->getPLC()))
+        {
+            try
+            {
+                //if transaction is for one device only, pContext contains its reference
+                if (pContext->isForOneDevice())
+                {
+                    //Device context: get block of one device only ====================================
+                    Device* pDev = pContext->getDevice();
+
+                    if (RECV & Log::topics_)
+                    { 	if (pConn->isEnabled())
+                        { Log(RECV).getLog() << "RecvAction (execute/ DeviceMode): " << theBlock_->getName() << ", device: " << pDev->getLabel();
+                        }
+                    }
+
+                    bufferLock();
+
+                    // read data from the buffer subscriber
+                    CNVBufferedSubscriber* handle = ((CNVInputBlock*)theBlock_)->getHandle(pDev->getLabel());
+                    errorCode = ((CNVConnection*)pConn)->readData(theBlock_->getPLC(), handle,&buffer);
+
+                    if (pConn->isConnected() && (errorCode == 0))
+                    {   //Data have just been received: get time-of-day to time-stamp the registers
+                        gettimeofday(&tod, 0);
+
+                        //Device context: Extract all the device registers from that block
+                        pDev->importRegisters(theBlock_, &buffer, tod, pContext);
+                    }
+
+                    bufferUnlock();
+
+                    //Deleting Null Data object raised a CNV exception
+                    if (errorCode != CNVEmptyDataError) errChk(CNVDisposeData(buffer));
+
+                    LOG_DELAY(RECV) << "done: " << theBlock_->getName();
+                }
+                else
+                {
+                    //Cluster/PLC context: get block of all devices one by one =========================
+                    deviceVectorType::iterator pDeviceIter;
+                    deviceVectorType& deviceCol = theBlock_->getPLC()->getDeviceMap();
+                    for(pDeviceIter = deviceCol.begin(); pDeviceIter != deviceCol.end(); ++pDeviceIter)
+                    {
+                        Device* pDev = pDeviceIter->second;
+
+                        if (RECV & Log::topics_)
+                        { 	if (pConn->isEnabled())
+                            { Log(RECV).getLog() << "RecvAction (execute/ DeviceMode): " << theBlock_->getName() << ", device: " << pDev->getLabel();
+                            }
+                        }
+
+                        bufferLock();
+
+                        // read data from the buffer subscriber
+                        CNVBufferedSubscriber* handle = ((CNVInputBlock*)theBlock_)->getHandle(pDev->getLabel());
+                        errorCode = ((CNVConnection*)pConn)->readData(theBlock_->getPLC(), handle,&buffer);
+
+                        if (pConn->isConnected() && (errorCode == 0))
+                        {   //Data have just been received: get time-of-day to time-stamp the registers
+                            gettimeofday(&tod, 0);
+
+                            //PLC context: Extract all registers value of the current device of the PLC from that block
+                            pDev->importRegisters(theBlock_, &buffer, tod, pContext);
+                        }
+
+                        bufferUnlock();
+
+                        //Deleting Null Data object raised a CNV exception
+                        if (errorCode != CNVEmptyDataError) errChk(CNVDisposeData(buffer));
+
+                        LOG_DELAY(RECV) << "done: " << theBlock_->getName();
+                    }
+                }
+            }
+            catch (const SilecsException& ex)
+            {
+                bufferUnlock();
+
+                errorCode = ex.getCode();
+            }
+        } //doOpen
+
+		return errorCode;
+	}
+
+	void CNVRecvBlockMode::errChk(int code)
+	{
+		if(code != 0)
+		{
+			throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, std::string(CNVGetErrorDescription(code))+" in CNVRecvBlockMode");
+		}
+	}
+
+	void CNVRecvDeviceMode::errChk(int code)
+	{
+		if(code != 0)
+		{
+            throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, std::string(CNVGetErrorDescription(code))+" in CNVRecvDeviceMode");
+		}
+	}
+
+} // namespace
+#endif //NI_SUPPORT_ENABLED
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/CNVRecvAction.h b/silecs-communication-cpp/src/silecs-communication/interface/core/CNVRecvAction.h
new file mode 100644
index 0000000000000000000000000000000000000000..e07dce9ac46ec7769cc77e24af76319f8f579fee
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/CNVRecvAction.h
@@ -0,0 +1,95 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifdef NI_SUPPORT_ENABLED
+
+#ifndef _RECV_CNV_ACTION_H_
+#define _RECV_CNV_ACTION_H_
+
+#include <silecs-communication/interface/core/PLCAction.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <nilibnetv.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+namespace Silecs
+{
+	class Action;
+	class Block;
+	class Context;
+
+	/*!
+	 * \class CNVRecvBlockMode
+	 * \brief Concrete action responsible to get a data block from the CNV (Block mode configuration)
+	 */
+	class CNVRecvBlockMode : public PLCAction
+	{
+
+	public:
+		CNVRecvBlockMode(Block* block);
+ 		virtual ~CNVRecvBlockMode();
+
+        /*!
+         * \fn execute
+         * Connect the CNV if necessary and Get data-block from its memory.
+         * Overwrite the abstract method
+         * \return 0 if no error occurred. else return a error status from low level library
+         */
+		int execute(Context* pContext);
+
+	private:
+
+		/* generate a string exception out of a CNV error code*/
+		void errChk(int code);
+
+	};
+
+	/*!
+	 * \class CNVRecvDeviceMode
+	 * \brief Concrete action responsible to get a data block from the CNV (Device mode configuration)
+	 */
+	class CNVRecvDeviceMode : public PLCAction
+	{
+
+	public:
+		CNVRecvDeviceMode(Block* block);
+ 		virtual ~CNVRecvDeviceMode();
+
+        /*!
+         * \fn execute
+         * Connect the CNV if necessary and Get data-block from its memory.
+         * Overwrite the abstract method
+         * \return 0 if no error occurred. else return a error status from low level library
+         */
+		int execute(Context* pContext);
+
+	private:
+
+		/* generate a string exception out of a CNV error code*/
+		void errChk(int code);
+
+	};
+
+} // namespace
+
+#endif // _RECV_CNV_ACTION_H_
+
+#endif //NI_SUPPORT_ENABLED
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/CNVSendAction.cpp b/silecs-communication-cpp/src/silecs-communication/interface/core/CNVSendAction.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8c834e8bdb33d5c6c60c423709d39dbfa6011923
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/CNVSendAction.cpp
@@ -0,0 +1,175 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifdef NI_SUPPORT_ENABLED
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/core/SilecsAction.h>
+#include <silecs-communication/interface/core/PLCAction.h>
+#include <silecs-communication/interface/communication/SilecsConnection.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/equipment/SilecsDevice.h>
+#include <silecs-communication/interface/equipment/SilecsBlock.h>
+#include <silecs-communication/interface/core/CNVSendAction.h>
+#include <silecs-communication/interface/core/Context.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include "../communication/CNVConnection.h.obsolete"
+#include "../equipment/CNVBlock.h.obsolete"
+
+namespace Silecs
+{
+
+	CNVSendBlockMode::CNVSendBlockMode(Block* block) : PLCAction(block)
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Action CNVSendBlockMode (create): " << theBlock_->getName();
+	}
+
+	CNVSendBlockMode::~CNVSendBlockMode()
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Action CNVSendBlockMode (delete): " << theBlock_->getName();
+	}
+
+	CNVSendDeviceMode::CNVSendDeviceMode(Block* block) : PLCAction(block)
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Action CNVSendDeviceMode (create): " << theBlock_->getName();
+	}
+
+	CNVSendDeviceMode::~CNVSendDeviceMode()
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Action CNVSendDeviceMode (delete): " << theBlock_->getName();
+	}
+
+	int CNVSendBlockMode::execute(Context* pContext)
+	{
+		return 0;
+	}
+
+	int CNVSendDeviceMode::execute(Context* pContext)
+	{
+		CNVData* pBuffer;
+		int errorCode = 0;
+		Connection* pConn = theBlock_->getPLC()->getConnection();
+
+        //(re)connect the PLC if needed and (re)synchronize the retentive registers
+        if (pConn->doOpen(theBlock_->getPLC()))
+        {
+            try
+            {
+                //if transaction is for one device only, pContext contains its reference
+                if (pContext->isForOneDevice())
+                {
+
+                    Device* pDev = pContext->getDevice();
+
+                    pBuffer = (CNVData*)theBlock_->getBuffer();
+
+                    bufferLock();
+
+                    if (pConn->isEnabled())
+                    {
+                        LOG(SEND) << "SendAction (execute/ DeviceMode): " << theBlock_->getName() << ", device: " << pDev->getLabel();
+
+                        //Device context: Export all the device registers to that block
+                        pDev->exportRegisters(theBlock_, pBuffer, pContext);
+                    }
+
+                    // compute the block address
+                    std::string blockAddress = "\\\\"+pDev->getPLC()->getName()+"\\'"
+                            +pDev->getPLC()->theCluster_->getClassName()+"-"+pDev->getPLC()->theCluster_->getClassVersion()+"'\\"
+                            + pDev->getLabel()+"\\"+theBlock_->getName();
+
+                    // call CNV write
+                    ((CNVConnection*)pConn)->writeData(theBlock_->getPLC(), blockAddress.c_str(),*pBuffer);
+
+                    bufferUnlock();
+
+                    if (SEND & Log::topics_)
+                    {
+                        if (pConn->isEnabled())
+                        {
+                            Log(SEND).getLogDelay() << "done: " << theBlock_->getName();
+                        }
+                    }
+                }
+                else
+                {
+                    //Cluster/PLC context: set block of all devices one by one =========================
+                    deviceVectorType::iterator pDeviceIter;
+                    deviceVectorType& deviceCol = theBlock_->getPLC()->getDeviceMap();
+                    for(pDeviceIter = deviceCol.begin(); pDeviceIter != deviceCol.end(); ++pDeviceIter)
+                    {
+                        Device* pDev = pDeviceIter->second;
+
+                        pBuffer = (CNVData*)theBlock_->getBuffer();
+
+                        bufferLock();
+
+                        if (pConn->isEnabled())
+                        {	LOG(SEND) << "SendAction (execute/ DeviceMode): " << theBlock_->getName() << ", device:" << pDev->getLabel();
+
+                            //PLC context: Export all registers value of the current device of the PLC to that block
+                            pDev->exportRegisters(theBlock_, pBuffer, pContext);
+                        }
+
+                        // compute the block address
+                        std::string blockAddress = "\\\\"+pDev->getPLC()->getName()+"\\'"
+                                +pDev->getPLC()->theCluster_->getClassName()+"-"+pDev->getPLC()->theCluster_->getClassVersion()+"'\\"
+                                + pDev->getLabel()+"\\"+theBlock_->getName();
+
+                        // call CNV write
+                        ((CNVConnection*)pConn)->writeData(theBlock_->getPLC(), blockAddress.c_str(),*pBuffer);
+
+                        bufferUnlock();
+
+                        if (SEND & Log::topics_)
+                        { 	if (pConn->isEnabled())
+                            { Log(SEND).getLogDelay() << "done: " << theBlock_->getName();
+                            }
+                        }
+                    }
+                }
+            }
+            catch (const SilecsException& ex)
+            {
+                bufferUnlock();
+
+                //LOG(DEBUG) << "CNV SendAction (execute/ DeviceMode) failed: "<< ex.getMessage();
+                //errorCode = ex.getCode();
+                LOG(DEBUG) << "CNV SendAction (execute/ DeviceMode) failed";
+                errorCode = -1; //no SilecsException expected so far
+            }
+
+        } //doOpen
+
+		return errorCode;
+	}
+
+	void CNVSendBlockMode::errChk(int code) throw (std::string*)
+	{
+		if(code != 0)
+		{
+			throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, std::string(CNVGetErrorDescription(code))+" in CNVSendBlockMode");
+		}
+	}
+
+	void CNVSendDeviceMode::errChk(int code) throw (std::string*)
+	{
+		if(code != 0)
+		{
+			throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, std::string(CNVGetErrorDescription(code))+" in CNVSendDeviceMode");
+		}
+	}
+
+} // namespace
+#endif //NI_SUPPORT_ENABLED
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/CNVSendAction.h b/silecs-communication-cpp/src/silecs-communication/interface/core/CNVSendAction.h
new file mode 100644
index 0000000000000000000000000000000000000000..bda46c211cabc6babd842d8a85d8706c1ccca22c
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/CNVSendAction.h
@@ -0,0 +1,81 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifdef NI_SUPPORT_ENABLED
+#ifndef _CNV_SEND_ACTION_H_
+#define _CNV_SEND_ACTION_H_
+
+#include <silecs-communication/interface/core/PLCAction.h>
+
+namespace Silecs
+{
+	class Action;
+	class Block;
+	class Context;
+
+	/*!
+	 * \class CNVSendBlockMode
+	 * \brief Concrete action responsible to send a data block to the CNV (Block mode configuration)
+	 */
+	class CNVSendBlockMode : public PLCAction
+	{
+
+	public:
+		CNVSendBlockMode(Block* block);
+ 		virtual ~CNVSendBlockMode();
+
+        /*!
+         * \fn execute
+         * Connect the CNV if necessary and send data-block to its memory.
+         * Overwrite the abstract method
+         * \return 0 if no error occurred. else return a error status from low level library
+         */
+		int execute(Context* pContext);
+
+	private:
+		/* generate a string exception out of a CNV error code*/
+		void errChk(int code) throw (std::string*);
+
+	};
+
+	/*!
+	 * \class CNVSendDeviceMode
+	 * \brief Concrete action responsible to send a data block to the CNV (Device mode configuration)
+	 */
+	class CNVSendDeviceMode : public PLCAction
+	{
+
+	public:
+		CNVSendDeviceMode(Block* block);
+ 		virtual ~CNVSendDeviceMode();
+
+        /*!
+         * \fn execute
+         * Connect the CNV if necessary and Get data-block to its memory.
+         * Overwrite the abstract method
+         * \return 0 if no error occurred. else return a error status from low level library
+         */
+		int execute(Context* pContext);
+
+	private:
+		/* generate a string exception out of a CNV error code*/
+		void errChk(int code) throw (std::string*);
+
+	};
+
+} // namespace
+
+#endif // _CNV_SEND_ACTION_H_
+#endif //NI_SUPPORT_ENABLED
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/Context.cpp b/silecs-communication-cpp/src/silecs-communication/interface/core/Context.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a6c2de2861e657aaf1a5063428394c6232be4a11
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/Context.cpp
@@ -0,0 +1,35 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/core/Context.h>
+#include <silecs-communication/interface/equipment/SilecsDevice.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+
+namespace Silecs
+{
+		Context::Context(Device* pDev, bool isForSynchronization):
+			pDevice_(pDev), isForSynchro_(isForSynchronization)
+		{
+			//LOG(ALLOC) << "Context (create) for Device: " << pDevice_->getLabel() << ", isForSynchronization: " <<  (isForSynchro_ ? "yes" : "no");
+		}
+
+		Context::~Context()
+		{
+			//LOG(ALLOC) << "Context (delete) for Device: " << pDevice_->getLabel()  << ", isForSynchronization: " <<  (isForSynchro_ ? "yes" : "no");
+		}
+
+} // namespace
+
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/Context.h b/silecs-communication-cpp/src/silecs-communication/interface/core/Context.h
new file mode 100644
index 0000000000000000000000000000000000000000..78fdd9ec725b0dd6584af886f6d55bb9477203fd
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/Context.h
@@ -0,0 +1,54 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _CONTEXT_H_
+#define _CONTEXT_H_
+
+namespace Silecs
+{
+	class Device;
+
+	/*!
+	 * \class Context
+	 * \brief This class defines the context of the Silecs Transaction.
+	 * A transaction can be done from Cluster or PLC levels for all-devices
+	 * and from Device level for a particular device.
+	 * A transaction can be executed by the client process (normal transaction) or
+	 * can be executed at the Cluster set-up for retentive registers synchronization.
+	 */
+   class Context
+    {
+        public:
+            Context(Device* pDev, bool isForSynchronization);
+            virtual ~Context();
+
+            inline bool isForAllDevices() { return pDevice_ == NULL; }
+            inline bool isForOneDevice() { return pDevice_ != NULL; }
+            inline Device* getDevice() 	{ return pDevice_; }
+
+            inline bool isForSynchronization() { return isForSynchro_; }
+
+        private:
+    		/// Device reference used for Device context
+			Device* pDevice_;
+
+    		/// true for synchronization transaction.
+			/// In this case only retentive registers will be updated (Master & Slave).
+			bool isForSynchro_;
+    };
+
+} // namespace
+
+#endif // _USER_CONTEXT_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/Diagnostic.cpp b/silecs-communication-cpp/src/silecs-communication/interface/core/Diagnostic.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..373d8ed1b6dd879d77e5580403910279fe19a9d2
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/Diagnostic.cpp
@@ -0,0 +1,32 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/core/Diagnostic.h>
+
+namespace Silecs
+{
+		Status::Status()
+		{
+			// Device context: only one particular device to be treated
+			connStatus_ = Undefined;
+			plcStatus_ = Unknown;
+		}
+
+		Status::~Status()
+		{
+		}
+
+} // namespace
+
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/Diagnostic.h b/silecs-communication-cpp/src/silecs-communication/interface/core/Diagnostic.h
new file mode 100644
index 0000000000000000000000000000000000000000..9471b8a7e7b1f27012e1452b97354e82517dd451
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/Diagnostic.h
@@ -0,0 +1,67 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _DIAGNOSTIC_H_
+#define _DIAGNOSTIC_H_
+
+#include <string>
+#include <iostream>
+
+namespace Silecs
+{
+	// Possible state of the FEC/PLC/Class connection
+	static const std::string ConnectionStatusString[] =
+	{ "Connected", "Disconnected", "Undefined"
+	};
+
+	typedef enum
+	{ Connected, Disconnected, Undefined
+	} ConnectionStatus;
+
+	static const std::string PLCStatusString[] =
+	{ "On", "Off", "Unknown"
+	};
+
+	typedef enum
+	{ On, Off, Unknown
+	} PLCStatus;
+
+	/*!
+	 * \class Status
+	 * \brief This class is used to manage the PLC connection status
+	 */
+   class Status
+    {
+        public:
+            Status();
+            virtual ~Status();
+
+            inline ConnectionStatus getConnectionStatus() { return connStatus_; }
+            inline PLCStatus getPLCStatus() { return plcStatus_; }
+    		inline std::string getConnectionStatusAsString() const { return ConnectionStatusString[connStatus_]; }
+    		inline std::string getPLCStatusAsString() const { return PLCStatusString[plcStatus_]; }
+
+        private:
+    		friend class PLC;
+
+    		/// Current status of the FEC/PLC/Class connection (Connected/Disconnected)
+			ConnectionStatus connStatus_;
+			/// Current status of the PLC (on/off)
+			PLCStatus plcStatus_;
+    };
+
+} // namespace
+
+#endif // _DIAGNOSTIC_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/PLCAction.h b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCAction.h
new file mode 100644
index 0000000000000000000000000000000000000000..b3fa2806dd7415a89a54c30571a8831bfd8def14
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCAction.h
@@ -0,0 +1,63 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _SILECS_PLC_ACTION_H_
+#define _SILECS_PLC_ACTION_H_
+
+#include <string>
+#include <silecs-communication/interface/utility/Mutex.h>
+#include <silecs-communication/interface/core/SilecsAction.h>
+
+namespace Silecs
+{
+	class Block;
+	class Context;
+
+	/*!
+	 * \class PLCAction
+	 * \brief PLCAction defines the abstract level of any PLC actions (recv and send)
+	 */
+	class PLCAction: public Action
+	{
+
+	public:
+		PLCAction(Block* block) : Action(block){
+	        bufferMux_  = new Mutex("bufferMux");
+		};
+ 		virtual ~PLCAction() {
+ 	        delete bufferMux_;
+ 		};
+
+        /*!
+         * \fn execute
+         * It contains the code to be executed for this action.
+         * Overwrites the code from Action class
+         */
+		virtual int execute(Context* pContext) = 0;
+
+	protected:
+        //The frame buffer update (import/export registers) and related read/write data must be done
+        //in a critical section (the same buffer is used to send/recv data to all devices).
+        inline void bufferLock()      { bufferMux_->lock();   }
+        inline void bufferUnlock()    { bufferMux_->unlock(); }
+
+	private:
+        Mutex* bufferMux_;
+
+	};
+
+} // namespace
+
+#endif // _SILECS_PLC_ACTION_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/PLCRecvAction.cpp b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCRecvAction.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..84f0a9bd149a59aafe0e165c1b6372280cae091a
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCRecvAction.cpp
@@ -0,0 +1,274 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/core/PLCAction.h>
+#include <silecs-communication/interface/core/PLCRecvAction.h>
+#include <silecs-communication/interface/communication/SilecsConnection.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/equipment/SilecsDevice.h>
+#include <silecs-communication/interface/equipment/SilecsBlock.h>
+#include <silecs-communication/interface/equipment/PLCBlock.h>
+#include <silecs-communication/interface/core/Context.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+
+namespace Silecs
+{
+
+	PLCRecvBlockMode::PLCRecvBlockMode(Block* block) : PLCAction(block)
+	{
+        if (DEBUG & Log::topics_) LOG(ALLOC) << "Action PLCRecvBlockMode (create): " << block->getName();
+	}
+
+	PLCRecvBlockMode::~PLCRecvBlockMode()
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Action PLCRecvBlockMode (delete): " << theBlock_->getName();
+	}
+
+	PLCRecvDeviceMode::PLCRecvDeviceMode(Block* block) : PLCAction(block)
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Action PLCRecvDeviceMode (create): " << theBlock_->getName();
+	}
+
+	PLCRecvDeviceMode::~PLCRecvDeviceMode()
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Action PLCRecvDeviceMode (delete): " << theBlock_->getName();
+	}
+
+	int PLCRecvBlockMode::execute(Context* pContext)
+	{
+		timeval tod; //Time-of-day for register time-stamping
+		int errorCode = 0;
+
+		Connection* pConn = theBlock_->getPLC()->getConnection();
+
+		try
+		{
+			//if transaction is for one device only, pContext contains its reference
+			if (pContext->isForOneDevice())
+			{
+				//Device context: get block of one device only ====================================
+				Device* pDev = pContext->getDevice();
+
+                //Base attributes of the device within the complete data block containing all devices.
+                unsigned long usedAddress = theBlock_->getAddress();
+                unsigned long usedSize = theBlock_->getMemSize();
+                unsigned long usedDeviceOffset = pDev->getAddress() * usedSize;
+                unsigned char* pBuffer = ((unsigned char*)theBlock_->getBuffer()) + usedDeviceOffset;
+
+                // Overwrite device-block address, offset & size in case user wants to resize the block dynamically
+                if (theBlock_->withCustomAttributes() == true)
+                {   usedAddress = theBlock_->getCustomAddress();
+                    usedSize = theBlock_->getCustomSize();
+                    usedDeviceOffset = theBlock_->getCustomOffset();
+                }
+
+				if (RECV & Log::topics_)
+				{ 	if (pConn->isEnabled())
+	                {
+						Log(RECV).getLog() << "RecvAction (execute/ BlockMode): " << ", device: " << pDev->getLabel() << ", block: " << theBlock_->getName();
+					}
+				}
+
+                bufferLock();
+
+				errorCode = pConn->readData(
+				    theBlock_->getPLC(),
+				    usedAddress, 	            //Base address (or DBn) of the block
+					usedDeviceOffset, 		    //Device data address within the block
+					usedSize,	                //Get one device-block only
+					pBuffer						//Buffer to store the data
+				);
+
+                if (pConn->isConnected() && (errorCode == 0))
+				{	//Data have just been received: get time-of-day to time-stamp the registers
+					gettimeofday(&tod, 0);
+
+					//Device context: Extract all the device registers from that block
+					pDev->importRegisters(theBlock_, pBuffer, tod, pContext);
+
+					LOG_DELAY(RECV) << "done for block: " << theBlock_->getName();
+				}
+
+                bufferUnlock();
+
+			}
+			else
+			{
+			    //Dynamic resizing of the block is not possible in BLOCK_MODE
+                if (theBlock_->withCustomAttributes() == true)
+			        throw SilecsException(__FILE__, __LINE__, COMM_BLOCK_RESIZING_NOT_ALLOWED);
+
+				deviceVectorType::iterator pDeviceIter;
+				deviceVectorType& deviceCol = theBlock_->getPLC()->getDeviceMap();
+
+				//Cluster/PLC context: get block of all devices in one go =========================
+				if (RECV & Log::topics_)
+				{ 	if (pConn->isEnabled())
+					{
+						Log(RECV).getLog() << "RecvAction (execute/ BlockMode): " << theBlock_->getName() << ", " << deviceCol.size() << " device(s)";
+					}
+				}
+
+                bufferLock();
+
+				errorCode = pConn->readData(
+	                theBlock_->getPLC(),
+					theBlock_->getAddress(),	//Base address (or DBn) of the block
+					0,							//Get all devices from the first one
+					((PLCBlock*)theBlock_)->getBufferSize(),	//Get blocks of all devices (full buffer size)
+					(unsigned char*)theBlock_->getBuffer()  	//Buffer to store the data (full buffer)
+				);
+
+                if (pConn->isConnected() && (errorCode == 0))
+				{	//Data have just been received: get time-of-day to time-stamp the registers
+					gettimeofday(&tod, 0);
+
+					//PLC context: Extract all registers value of all devices of the PLC from that block
+					for(pDeviceIter = deviceCol.begin(); pDeviceIter != deviceCol.end(); ++pDeviceIter)
+					{
+						Device* pDev = pDeviceIter->second;
+						unsigned long deviceOffset = pDev->getAddress() * theBlock_->getMemSize();
+						unsigned char* pBuffer = ((unsigned char*)theBlock_->getBuffer()) + deviceOffset;
+						pDev->importRegisters(theBlock_, pBuffer, tod, pContext);
+					}
+
+					LOG_DELAY(RECV) << "done for block: " << theBlock_->getName();
+				}
+
+                bufferUnlock();
+
+			}
+		}
+		catch (const SilecsException& ex)
+		{
+            bufferUnlock();
+			LOG(ERROR) << ex.what();
+			LOG(ERROR) << "RecvAction (execute/ BlockMode) for block " << theBlock_->getName() << " has failed";
+			return ex.getCode();
+		}
+		return 0;
+	}
+
+	int PLCRecvDeviceMode::execute(Context* pContext)
+	{
+		timeval tod; //Time-of-day for register time-stamping
+		int errorCode = 0;
+		Connection* pConn = theBlock_->getPLC()->getConnection();
+
+		try
+		{
+			//if transaction is for one device only, pContext contains its reference
+			if (pContext->isForOneDevice())
+			{
+				//Device context: get block of one device only ====================================
+				Device* pDev = pContext->getDevice();
+
+                //Set base attributes of the device blocks
+                unsigned long usedDeviceAddress = pDev->getAddress();
+                unsigned long usedBlockAddress = theBlock_->getAddress();
+                unsigned long usedSize = theBlock_->getMemSize();
+
+                // Overwrite device-block address, offset & size in case user wants to resize the block dynamically
+                if (theBlock_->withCustomAttributes() == true)
+                {   usedDeviceAddress = theBlock_->getCustomAddress();
+                    usedBlockAddress = theBlock_->getCustomOffset();
+                    usedSize = theBlock_->getCustomSize();
+                }
+
+				if (RECV & Log::topics_)
+				{ 	if (pConn->isEnabled())
+                    { Log(RECV).getLog() << "RecvAction (execute/ DeviceMode): device: " << pDev->getLabel() << ", block: " << theBlock_->getName();
+					}
+				}
+
+				bufferLock();
+
+				errorCode = pConn->readData(
+	                theBlock_->getPLC(),
+				    usedDeviceAddress,		//Base address (or DBn) of the device
+					usedBlockAddress,	    //Block data address within the device
+					usedSize,	            //Get one device-block only
+					(unsigned char*)theBlock_->getBuffer()  	//Buffer to store the data
+				);
+
+				if (pConn->isConnected() && (errorCode == 0))
+				{	//Data have just been received: get time-of-day to time-stamp the registers
+					gettimeofday(&tod, 0);
+
+					//Device context: Extract all the device registers from that block
+					pDev->importRegisters(theBlock_, (unsigned char*)theBlock_->getBuffer(), tod, pContext);
+
+					LOG_DELAY(RECV) << "done for block: " << theBlock_->getName();
+				}
+
+                bufferUnlock();
+
+			}
+			else
+			{
+                //Dynamic resizing of the block is not possible in multiple access
+                if (theBlock_->withCustomAttributes() == true)
+                    throw SilecsException(__FILE__, __LINE__, COMM_BLOCK_RESIZING_NOT_ALLOWED);
+
+				//Cluster/PLC context: get block of all devices one by one =========================
+				deviceVectorType::iterator pDeviceIter;
+				deviceVectorType& deviceCol = theBlock_->getPLC()->getDeviceMap();
+				for(pDeviceIter = deviceCol.begin(); pDeviceIter != deviceCol.end(); ++pDeviceIter)
+				{
+					Device* pDev = pDeviceIter->second;
+
+					if (RECV & Log::topics_)
+					{ 	if (pConn->isEnabled())
+	                    { Log(RECV).getLog() << "RecvAction (execute/ DeviceMode): device: " << pDev->getLabel() << ", block: " << theBlock_->getName();
+						}
+					}
+
+	                bufferLock();
+
+					errorCode = pConn->readData(
+		                theBlock_->getPLC(),
+					    pDev->getAddress(),		        //Base address (or DBn) of the device
+					    theBlock_->getAddress(),	    //Block data address within the device
+					    theBlock_->getMemSize(),	    //Get one device-block only
+						(unsigned char*)theBlock_->getBuffer()		//Buffer to store the data
+					);
+
+	                if (pConn->isConnected() && (errorCode == 0))
+					{	//Data have just been received: get time-of-day to time-stamp the registers
+						gettimeofday(&tod, 0);
+
+						//PLC context: Extract all registers value of the current device of the PLC from that block
+						pDev->importRegisters(theBlock_, (unsigned char*)theBlock_->getBuffer(), tod, pContext);
+
+						LOG_DELAY(RECV) << "done for block: " << theBlock_->getName();
+					}
+
+	                bufferUnlock();
+
+				}
+			}
+		}
+		catch (const SilecsException& ex)
+		{
+            bufferUnlock();
+			LOG(ERROR) << ex.what();
+			LOG(ERROR) << "RecvAction (execute/ DeviceMode) failed";
+			return ex.getCode();
+		}
+		return 0;
+	}
+
+} // namespace
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/PLCRecvAction.h b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCRecvAction.h
new file mode 100644
index 0000000000000000000000000000000000000000..e7bcc5a817bc032387054746ac8ed29df35940b6
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCRecvAction.h
@@ -0,0 +1,76 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _RECV_PLC_ACTION_H_
+#define _RECV_PLC_ACTION_H_
+
+#include <silecs-communication/interface/core/PLCAction.h>
+
+namespace Silecs
+{
+	class Action;
+	class Block;
+	class Context;
+
+	/*!
+	 * \class PLCRecvBlockMode
+	 * \brief Concrete action responsible to get a data block from the PLC (Block mode configuration)
+	 */
+	class PLCRecvBlockMode : public PLCAction
+	{
+
+	public:
+		PLCRecvBlockMode(Block* block);
+ 		virtual ~PLCRecvBlockMode();
+
+        /*!
+         * \fn execute
+         * Connect the PLC if necessary and Get data-block from its memory.
+         * Overwrite the abstract method
+         * \return 0 if no error occurred. else return a error status from low level library
+         */
+		int execute(Context* pContext);
+
+	private:
+
+	};
+
+	/*!
+	 * \class PLCRecvDeviceMode
+	 * \brief Concrete action responsible to get a data block from the PLC (Device mode configuration)
+	 */
+	class PLCRecvDeviceMode : public PLCAction
+	{
+
+	public:
+		PLCRecvDeviceMode(Block* block);
+ 		virtual ~PLCRecvDeviceMode();
+
+        /*!
+         * \fn execute
+         * Connect the PLC if necessary and Get data-block from its memory.
+         * Overwrite the abstract method
+         * \return 0 if no error occurred. else return a error status from low level library
+         */
+		int execute(Context* pContext);
+
+	private:
+
+	};
+
+} // namespace
+
+#endif // _RECV_PLC_ACTION_H_
+
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/PLCSendAction.cpp b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCSendAction.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ff07954f5a7549faad35d50c18da2745c0533fac
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCSendAction.cpp
@@ -0,0 +1,253 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/core/SilecsAction.h>
+#include <silecs-communication/interface/core/PLCAction.h>
+#include <silecs-communication/interface/core/PLCSendAction.h>
+#include <silecs-communication/interface/communication/SilecsConnection.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/equipment/SilecsDevice.h>
+#include <silecs-communication/interface/equipment/SilecsBlock.h>
+#include <silecs-communication/interface/equipment/PLCBlock.h>
+#include <silecs-communication/interface/core/Context.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+
+namespace Silecs
+{
+
+	PLCSendBlockMode::PLCSendBlockMode(Block* block) : PLCAction(block)
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Action PLCSendBlockMode (constructor): " << block->getName();
+	}
+
+	PLCSendBlockMode::~PLCSendBlockMode()
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Action PLCSendBlockMode (destructor): " << theBlock_->getName();
+	}
+
+	PLCSendDeviceMode::PLCSendDeviceMode(Block* block) : PLCAction(block)
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Action PLCSendDeviceMode (constructor): " << theBlock_->getName();
+	}
+
+	PLCSendDeviceMode::~PLCSendDeviceMode()
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Action PLCSendDeviceMode (delete): " << theBlock_->getName();
+	}
+
+	int PLCSendBlockMode::execute(Context* pContext)
+	{
+		int errorCode = 0;
+		Connection* pConn = theBlock_->getPLC()->getConnection();
+
+		try
+		{
+			//if transaction is for one device only, pContext contains its reference
+			if (pContext->isForOneDevice())
+			{
+				//Device context: send block of one device only ====================================
+				Device* pDev = pContext->getDevice();
+
+                //Base attributes of the device within the complete data block containing all devices.
+                unsigned long usedAddress = theBlock_->getAddress();
+                unsigned long usedSize = theBlock_->getMemSize();
+                unsigned long usedDeviceOffset = pDev->getAddress() * usedSize;
+                unsigned char* pBuffer = ((unsigned char*)theBlock_->getBuffer()) + usedDeviceOffset;
+
+                // Overwrite device-block address, offset & size in case user wants to resize the block dynamically
+                if (theBlock_->withCustomAttributes() == true)
+                {   usedAddress = theBlock_->getCustomAddress();
+                    usedSize = theBlock_->getCustomSize();
+                    usedDeviceOffset = theBlock_->getCustomOffset();
+                }
+
+                bufferLock();
+
+				if (pConn->isEnabled())
+                {   LOG(SEND) << "SendAction (execute/ BlockMode): device: " << pDev->getLabel() << ", block: " << theBlock_->getName();
+
+					//Device context: Export all the device registers to that block
+					pDev->exportRegisters(theBlock_, pBuffer, pContext);
+				}
+
+				errorCode = pConn->writeData(
+				    theBlock_->getPLC(),
+				    usedAddress, 	            //Base address (or DBn) of the block
+					usedDeviceOffset, 			//Device data address within the block
+					usedSize,	                //Set one device-block only
+					pBuffer 					//Buffer which contain the data
+				);
+
+                bufferUnlock();
+
+				if (SEND & Log::topics_)
+				{ 	if (pConn->isEnabled())
+					{ Log(SEND).getLogDelay() << "done for block: " << theBlock_->getName();
+					}
+				}
+			}
+			else
+			{
+                //Dynamic resizing of the block is not possible in BLOCK_MODE
+                if (theBlock_->withCustomAttributes() == true)
+                    throw SilecsException(__FILE__, __LINE__, COMM_BLOCK_RESIZING_NOT_ALLOWED);
+
+                bufferLock();
+
+				if (pConn->isEnabled())
+				{	deviceVectorType::iterator pDeviceIter;
+					deviceVectorType& deviceCol = theBlock_->getPLC()->getDeviceMap();
+
+					//Cluster/PLC context: set block of all devices in one go ===========================
+					LOG(SEND) << "SendAction (execute/ BlockMode): block: " << theBlock_->getName() << ", " << deviceCol.size() << " device(s)";
+
+					//PLC context: Export all registers value of all devices of the PLC to that block
+					for(pDeviceIter = deviceCol.begin(); pDeviceIter != deviceCol.end(); ++pDeviceIter)
+					{
+						Device* pDev = pDeviceIter->second;
+						unsigned long deviceOffset = pDev->getAddress() * theBlock_->getMemSize();
+						unsigned char* pBuffer = ((unsigned char*)theBlock_->getBuffer()) + deviceOffset;
+						pDev->exportRegisters(theBlock_, pBuffer, pContext);
+					}
+				}
+
+				errorCode = pConn->writeData(
+	                theBlock_->getPLC(),
+					theBlock_->getAddress(),	//Base address (or DBn) of the block
+					0,							//Set all devices from the first one
+					((PLCBlock*)theBlock_)->getBufferSize(),	//Set blocks of all devices (full buffer size)
+					(unsigned char*)theBlock_->getBuffer()  	//Buffer which contain the data (full buffer)
+				);
+
+                bufferUnlock();
+
+				if (SEND & Log::topics_)
+				{ 	if (pConn->isEnabled())
+					{ Log(SEND).getLogDelay() << "done for block: " << theBlock_->getName();
+					}
+				}
+			}
+		}
+		catch (const SilecsException& ex)
+		{
+		    bufferUnlock();
+			LOG(ERROR) << ex.what();
+			LOG(ERROR) << "SendAction (execute/ DeviceMode) on block: " << theBlock_->getName() << " has failed";
+			return ex.getCode();
+		}
+		return 0;
+	}
+
+	int PLCSendDeviceMode::execute(Context* pContext)
+	{
+		Connection* pConn = theBlock_->getPLC()->getConnection();
+		int errorCode = 0;
+		try
+		{
+			//if transaction is for one device only, pContext contains its reference
+			if (pContext->isForOneDevice())
+			{
+				//Device context: set block of one device only ====================================
+				Device* pDev = pContext->getDevice();
+
+	            //Set base attributes of the device blocks
+	            unsigned long usedDeviceAddress = pDev->getAddress();
+	            unsigned long usedBlockAddress = theBlock_->getAddress();
+	            unsigned long usedSize = theBlock_->getMemSize();
+
+	            // Overwrite device-block address, offset & size in case user wants to resize the block dynamically
+	            if (theBlock_->withCustomAttributes() == true)
+	            {   usedDeviceAddress = theBlock_->getCustomAddress();
+	                usedBlockAddress = theBlock_->getCustomOffset();
+	                usedSize = theBlock_->getCustomSize();
+	            }
+
+                bufferLock();
+
+				if (pConn->isEnabled())
+				{	LOG(SEND) << "SendAction (execute/ DeviceMode): device: " << pDev->getLabel() << ", block: " << theBlock_->getName();
+
+					//Device context: Export all the device registers to that block
+					pDev->exportRegisters(theBlock_, (unsigned char*)theBlock_->getBuffer(), pContext);
+				}
+
+				errorCode = pConn->writeData(
+	                theBlock_->getPLC(),
+				    usedDeviceAddress,			//Base address (or DBn) of the device
+					usedBlockAddress,	        //Block data address within the device
+					usedSize,	                //Set one device-block only
+					(unsigned char*)theBlock_->getBuffer()  	//Buffer which contain the data
+				);
+
+                bufferUnlock();
+
+				if (SEND & Log::topics_)
+				{ 	if (pConn->isEnabled())
+					{ Log(SEND).getLogDelay() << "done for block: " << theBlock_->getName();
+					}
+				}
+			}
+			else
+			{
+                //Dynamic resizing of the block is not possible in multiple access
+                if (theBlock_->withCustomAttributes() == true)
+                    throw SilecsException(__FILE__, __LINE__, COMM_BLOCK_RESIZING_NOT_ALLOWED);
+
+			    //Cluster/PLC context: set block of all devices one by one =========================
+				deviceVectorType::iterator pDeviceIter;
+				deviceVectorType& deviceCol = theBlock_->getPLC()->getDeviceMap();
+				for(pDeviceIter = deviceCol.begin(); pDeviceIter != deviceCol.end(); ++pDeviceIter)
+				{
+					Device* pDev = pDeviceIter->second;
+
+	                bufferLock();
+
+					if (pConn->isEnabled())
+	                {   LOG(SEND) << "SendAction (execute/ DeviceMode):  device: " << pDev->getLabel() << ", block: " << theBlock_->getName();
+
+						//PLC context: Export all registers value of the current device of the PLC to that block
+						pDev->exportRegisters(theBlock_, (unsigned char*)theBlock_->getBuffer(), pContext);
+					}
+
+					errorCode = pConn->writeData(
+		                theBlock_->getPLC(),
+	                    pDev->getAddress(),             //Base address (or DBn) of the device
+	                    theBlock_->getAddress(),        //Block data address within the device
+	                    theBlock_->getMemSize(),        //Set one device-block only
+						(unsigned char*)theBlock_->getBuffer()  	//Buffer which contain the data
+					);
+
+	                bufferUnlock();
+
+					if (SEND & Log::topics_)
+					{ 	if (pConn->isEnabled())
+						{ Log(SEND).getLogDelay() << "done for block: " << theBlock_->getName();
+						}
+					}
+				}
+			}
+		}
+		catch (const SilecsException& ex)
+		{
+            bufferUnlock();
+			LOG(ERROR) << ex.what();
+			LOG(ERROR) << "SendAction (execute/ DeviceMode) failed";
+			return ex.getCode();
+		}
+		return 0;
+	}
+
+} // namespace
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/PLCSendAction.h b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCSendAction.h
new file mode 100644
index 0000000000000000000000000000000000000000..92aff058c76122c19894ca4f2591d1c661e9a868
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCSendAction.h
@@ -0,0 +1,76 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _PLC_SEND_ACTION_H_
+#define _PLC_SEND_ACTION_H_
+
+#include <silecs-communication/interface/core/PLCAction.h>
+
+namespace Silecs
+{
+	class Action;
+	class Block;
+	class Context;
+
+	/*!
+	 * \class PLCSendBlockMode
+	 * \brief Concrete action responsible to send a data block to the PLC (Block mode configuration)
+	 */
+	class PLCSendBlockMode : public PLCAction
+	{
+
+	public:
+		PLCSendBlockMode(Block* block);
+ 		virtual ~PLCSendBlockMode();
+
+        /*!
+         * \fn execute
+         * Connect the PLC if necessary and send data-block to its memory.
+         * Overwrite the abstract method
+         * \return 0 if no error occurred. else return a error status from low level library
+         */
+		int execute(Context* pContext);
+
+	private:
+
+	};
+
+	/*!
+	 * \class PLCSendDeviceMode
+	 * \brief Concrete action responsible to send a data block to the PLC (Device mode configuration)
+	 */
+	class PLCSendDeviceMode : public PLCAction
+	{
+
+	public:
+		PLCSendDeviceMode(Block* block);
+ 		virtual ~PLCSendDeviceMode();
+
+        /*!
+         * \fn execute
+         * Connect the PLC if necessary and Get data-block to its memory.
+         * Overwrite the abstract method
+         * \return 0 if no error occurred. else return a error status from low level library
+         */
+		int execute(Context* pContext);
+
+	private:
+
+	};
+
+} // namespace
+
+#endif // _PLC_SEND_ACTION_H_
+
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsAction.h b/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsAction.h
new file mode 100644
index 0000000000000000000000000000000000000000..4aa663da5bcb6e09b2e9febe0de5a840f489df8f
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsAction.h
@@ -0,0 +1,54 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _SILECS_ACTION_H_
+#define _SILECS_ACTION_H_
+
+#include <string>
+
+namespace Silecs
+{
+	class Block;
+	class Context;
+
+	/*!
+	 * \class Action
+	 * \brief Action defines the abstract level of any action
+	 */
+	class Action
+	{
+
+	public:
+		Action(Block* block) : theBlock_(block) {};
+ 		virtual ~Action() {};
+
+        /*!
+         * \fn execute
+         * It contains the code to be executed for this action.
+         * Has to be overriden for concrete PLC action.
+         * \return 0 if no error occurred. else return a error status from low level library
+         */
+		virtual int execute(Context* pContext) = 0;
+
+	protected:
+		/// Parent block reference of that action
+		Block* theBlock_;
+
+	};
+
+} // namespace
+
+#endif // _SILECS_ACTION_H_
+
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsService.cpp b/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..82774b4a5284715c86661b52bc2ca8adb3a29f53
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsService.cpp
@@ -0,0 +1,283 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <silecs-communication/interface/utility/XMLParser.h>
+#include <silecs-communication/interface/utility/StringUtilities.h>
+#include <unistd.h>
+
+/* ----------------------------------------------------------------------
+ * RELEASE
+ * 3.1.0: initial
+ * 3.2.0: Code refactor to easily integrate new hardware equipment;
+ *        NI via shared library supported (32 bit only);
+ *        64bits CPU support (for SLC6 migration);
+ * 3.2.1: Missing and safe free (Mutex, Thread)
+ *        Safe free in libS7
+ *        Fix in libS7:
+ *        Do not recv/send empty packet in case of data-size multiple frame size.
+ * 3.3.0: Library Conditional compilation WITH_CHN={YES/NO}
+ *        Silecsop is editor of each design and deploy
+ * 		  SVN Support (can be enable from ieglobal.py)
+ * 		  Automated compilation procedure
+ * 		  CNV receive via buffer subscriber
+ * 3.3.1: Fix memory leak using correct disposal of CNV data
+ * 3.4.0: Support Rabbit Microcontroller via MB connection.
+ *        MB read baseAddress instead of address 000 at connection time.
+ * 3.4.1: FIX: consider uint8 as numeric and int8 as ASCII value while setting register value
+ * 3.5.0: FIX: add missing method to allow dynamic resizing of the send/recv data-block.
+ *        Look at: PLC::[set/reset][Read/Write]BlockAttributes() methods and related components (SilecsPLC.h)
+ * 3.5.1: FIX: Dynamic resizing didn't work properly with SCHNEIDER using BLOKC-MODE.
+ *        Full custom adressing is required to fix the problem.
+ * 3.6.0: FEATURE: Input arguments setting for FESA3 development.                        
+ * 3.7.0: Support Beckhoff PLC via MB connection.
+ *        FIX: single init/cleanup of libxml2 (not reentrant)
+ * 3.8.5: Look at release 3.8.5 content
+ * 3.8.6: Look at release 3.8.6 content
+ * --------------------------------------------------------------------*/
+
+
+/* **********************************************************************
+ * Global data definition related to the software install and versioning
+ * Must be up-to-date for each release in connection with others packages
+ * (Java tool and Environment software (Python scripts, ..)
+ * **********************************************************************
+ */
+#ifndef MAJOR
+    #error "Silecs::Service: MAJOR SYMBOL NOT DEFINED! Make sure to define symbols MAJOR, MINOR and PATCH in your Makefile."
+#endif
+
+namespace Silecs
+{
+#define STRINGIFY2(X) #X
+#define STRINGIFY(X) STRINGIFY2(X)
+
+	//Semantic versioning for SILECS packages (Tools, Environment and client library have consistent major number)
+	const std::string Service::semverMajor_ = STRINGIFY(MAJOR); //Major release, not backward compatible
+	const std::string Service::semverMinor_ = STRINGIFY(MINOR); //Minor release, backward compatible
+	const std::string Service::semverPatch_ = STRINGIFY(PATCH); //Bug fixes, backward compatible
+
+
+} // namespace
+
+/* **********************************************************************
+ * **********************************************************************
+ */
+namespace Silecs
+{
+	// static definition
+	Service* Service::instance_ = NULL;
+    bool Service::isShutingDown_ = false;
+
+	Service* Service::getInstance(int argc, char ** argv)
+	{
+		if (instance_ == NULL)
+		{
+			instance_ = new Service(argc, argv);
+			LOG((ALLOC|DIAG)) << "SILECS Service create";
+
+			XMLParser::init();
+
+			//ACET start-up message (once per process)
+			TRACE("process") << "Version=" << semverMajor_ << "." << semverMinor_ << "." << semverPatch_;
+		}
+		return instance_;
+	}
+
+	void Service::deleteInstance()
+	{
+		if (!isShutingDown_)
+		{	isShutingDown_ = true;
+			LOG((ALLOC|DIAG)) << "SILECS Resources release";
+
+            XMLParser::init();
+
+			if (instance_ != NULL) delete instance_;
+			instance_ = NULL;
+		}
+	}
+
+    void Service::setArguments(std::string usrArgs)
+    {
+        size_t pos = usrArgs.find("-plcLog");
+        if (pos != std::string::npos)
+        {   std::string topics = usrArgs.substr(pos+8);
+            char *argv[3] = { (char*)"dummy", (char*)"-plcLog", (char*)topics.c_str() };
+            if (setArgs(3, argv) == false)
+            {  throw SilecsException(__FILE__, __LINE__, PARAM_INCORRECT_ARGUMENTS);
+            }
+        }
+    }
+
+	bool Service::setLogTopics(std::string topics)
+	{
+		bool isOK = Log::getTopicsFromString(topics);
+		return isOK;
+	}
+
+	Service::Service(int argc, char ** argv)
+	{
+		isShutingDown_ = false;
+		
+		//Default client process name (in case arguments are not transmitted)
+		char *ident = (char*)"SILECS-Client";
+
+		//Start the sys-logger at first
+		if (argc>0)
+		{	//Real process name
+			ident = basename(argv[0]);
+		}
+
+		//No particular topics to log to syslog in addition to the mandatory ones (if any)
+		Log::startSyslog(ident, 0);
+
+		//Then, interpret and set the 'plc' parameters of the command line, if any
+		if ((argc>0) && (argv != NULL))
+		{
+			if (setArgs(argc, argv) == false)
+			{   printArgs();
+				/* or as following if required
+				std::cerr << std::endl;
+				std::cerr << "PLC expected arguments: " << std::endl;
+				std::cerr << Silecs::whichArgs() << std::endl;
+				*/
+				throw SilecsException(__FILE__, __LINE__, PARAM_INCORRECT_ARGUMENTS);
+			}
+		}
+	}
+
+	Service::~Service()
+	{
+        //Disconnect and remove all shared-connection if any (one per PLC)
+        PLC::deleteConnection();
+
+		// Remove all the Cluster instances of this SILECS Service
+		clusterMapType::iterator clusterMapIter;
+		for(clusterMapIter = clusterMap_.begin(); clusterMapIter != clusterMap_.end(); clusterMapIter++)
+		{ delete clusterMapIter->second;
+		}
+		clusterMap_.clear();
+
+		//close the syslog resource
+		Log::stopSyslog();
+	}
+
+
+	Cluster* Service::getCluster(std::string className, std::string classVersion)
+	{
+		std::string clusterName = className + "_" + classVersion;
+		clusterMapType::iterator iter = clusterMap_.find(clusterName);
+        if (iter == clusterMap_.end())
+        {
+        	// Does not exist yet, create a new one for this className
+            Cluster* theCluster = new Cluster(className, classVersion);
+            clusterMap_.insert(std::make_pair(clusterName, theCluster));
+            return theCluster;
+        }
+        // Already created, return the unique reference
+        return iter->second;
+	}
+
+
+	std::string Service::getSemverMajor()
+	{
+		return semverMajor_;
+	}
+
+	std::string Service::getSemverMinor()
+	{
+		return semverMinor_;
+	}
+
+	std::string Service::getSemverPatch()
+	{
+		return semverPatch_;
+	}
+
+	SynchroType Service::whichSynchroType(std::string type)
+	{
+		StringUtilities::toLower(type);
+		if (type == "master") return Master;
+		else if (type == "slave") return Slave;
+		else if (type == "none") return No;
+		else throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_SYNCHRO_TYPE, type);
+	}
+
+	bool Service::withInputAccess(AccessType& accessType)
+	{ return (accessType != Output);
+	}
+
+	bool Service::withOutputAccess(AccessType& accessType)
+	{ return (accessType != Input);
+	}
+
+	bool Service::fileExists(std::string filename)
+	{
+		struct stat fileInfo;
+
+		// Attempt to get the file attributes
+		if (stat(filename.c_str(),&fileInfo) == 0)
+		{ //No error: the file exists
+			return true;
+		}
+		else
+		{
+			if (errno == ENOENT)
+			{	//No such file or directory
+				return false;
+			}
+		}
+		//Unexpected error
+		throw SilecsException(__FILE__, __LINE__, errno, strerror(errno));
+	}
+
+	bool Service::checkArgs(int argc, char ** argv)
+	{
+		if ((argc>=2) && (argv != NULL))
+		{	for(int i=0; i< argc; i++)
+				if(strcmp(argv[i], "-plcHelp") == 0) return false;
+		}
+		return true; //help is not required
+	}
+
+	bool Service::setArgs(int argc, char ** argv)
+	{
+		if (checkArgs(argc, argv))
+			if (Log::setLogArguments(argc, argv))
+				//if ..
+					//if ..
+					return true;
+		return false;
+	}
+
+	std::string Service::whichArgs()
+	{
+		return std::string("-plcHelp") + std::string("\n") +
+			   Log::getLogArguments()  + std::string("\n")
+			   // + ..
+			   ;
+	}
+
+	void Service::printArgs()
+	{
+		std::cerr << std::endl;
+		std::cerr << "SILECS expected arguments: " << std::endl;
+		std::cerr << whichArgs() << std::endl;
+	}
+
+} // namespace
+
+
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsService.h b/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsService.h
new file mode 100644
index 0000000000000000000000000000000000000000..3eb7c8b4ad8718aacb943d589fd9d9dbd36845c8
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsService.h
@@ -0,0 +1,182 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _SILECS_SERVICE_H_
+#define _SILECS_SERVICE_H_
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <set>
+#include <map>
+
+namespace Silecs
+{
+	// Register and Block synchronization type
+	typedef enum
+	{ Master, Slave, No
+	} SynchroType;
+
+	/// @cond
+	// Register and Block access types
+	typedef enum
+	{
+	   Output, Input, InOut
+	} AccessType;
+	/// @endcond
+
+	/*!
+	 * \brief Defines the category of the SILECS Exception.
+	 * Can be used in the Exception catch to dispatch emergency actions.
+	 * Use Exception::getCategory() to retrieve it.
+	 */
+	typedef enum
+	{
+		///Default mode: Do not synchronize the retentive Registers at the PLC connection
+		NO_SYNCHRO 	   = 0,
+		///Synchronize the Master Registers at the PLC connection (downloaded from the PLC)
+		MASTER_SYNCHRO = 1,
+		///Synchronize the Slave Registers at the PLC connection (uploaded from the client)
+		SLAVE_SYNCHRO  = 2,
+		///Synchronize all the retentive Registers at the PLC connection (download Masters and upload Slaves)
+		FULL_SYNCHRO   = 3,
+	} SynchroMode;
+}
+
+#include <silecs-communication/interface/equipment/CNVRegister.h>
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/equipment/SilecsDevice.h>
+#include <silecs-communication/interface/equipment/SilecsRegister.h>
+#include <silecs-communication/interface/equipment/PLCRegister.h>
+#include <silecs-communication/interface/utility/SilecsException.h>
+
+namespace Silecs
+{
+	/// @cond
+	typedef std::map<std::string, Cluster*> clusterMapType;
+	/// @endcond
+
+	/*!
+	 * \class Service
+	 * \brief This class is the entry point of the SILECS service.
+	 * Service class is a singleton that the client process must instantiate at first.
+	 * It provides services to set-up the general tasks (set process arguments for instance)
+	 * and create the required PLC Clusters and related resources of each SILECS class:
+	 * PLC, Device and Register.
+	 */
+	class Service
+	{
+
+	public:
+        /*!
+         * \brief Use this method to create/get the unique process instance of the SILECS Service.
+         * By creating that object it's possible to transmit specific arguments to the SILECS Service,
+         * typically the SILECS logging options:
+         * -plcLog ERROR[,INFO,DEBUG,SETUP,ALLOC,RECV,SEND,COMM,DATA,LOCK]
+         *
+         * (argc=0, argv=NULL) means no arguments for SILECS Service
+         */
+		static Service* getInstance(int argc=0, char ** argv=NULL);
+
+        /*!
+         * \brief This method releases all the SILECS resources and finally removes
+         * the Service singleton itself.
+         * Attention! This method is responsible to disconnect all the PLCs but mostly to remove
+         * all the SILECS resources (Clusters and related components: PLCs, Devices, Registers, ..)
+         * Client implementation must ensure that no process is currently accessing to
+         * these resources before calling.
+	     */
+		static void deleteInstance();
+
+        /*!
+         * \brief Use this method to either get an existing Cluster object,
+         *  or to create a new one for a given className/version, if not existing.
+         *  The client is responsible to delete all the Cluster instances and related
+         *  components by deleting the Service object.
+         * \param className name of the class
+         * \param classVersion version number of the class
+         * \return reference to the unique Cluster instance for this class/version
+         */
+		Silecs::Cluster* getCluster(std::string className, std::string classVersion);
+
+
+        /*!
+         * \brief Use this method to get the library Semantic version (Major)
+         * \return the Major number of the current release: <Major>.<Minor>.<Patch>
+         */
+		static std::string getSemverMajor();
+
+        /*!
+         * \brief Use this method to get the library Semantic version (Minor)
+         * \return the Minor number of the current release: <Major>.<Minor>.<Patch>
+         */
+		static std::string getSemverMinor();
+
+        /*!
+         * \brief Use this method to get the library Semantic version (Patch)
+         * \return the Patch number of the current release: <Major>.<Minor>.<Patch>
+         */
+		static std::string getSemverPatch();
+
+        /*!
+         * \brief Use this method to propagate the input arguments to the SILECS library (-plcLog in particular)
+         */
+        void setArguments(std::string usrArgs);
+
+		/// @cond
+		// TODO: For python Diagnostic only, to be improved
+		bool setLogTopics(std::string topics);
+		/// @endcond
+
+	private:
+		friend class PLC;
+		friend class Block;
+		friend class Register;
+		friend class PLCRegister;
+		friend class CNVRegister;
+
+		Service(int argc, char ** argv);
+		virtual ~Service();
+
+		bool checkArgs(int argc, char ** argv);
+		bool setArgs(int argc, char ** argv);
+		std::string whichArgs();
+		void printArgs();
+
+		static const std::string getParamsFilesPath();
+		static SynchroType whichSynchroType(std::string type);
+		static bool withInputAccess(AccessType& accessType);
+		static bool withOutputAccess(AccessType& accessType);
+		static bool fileExists(std::string filename);
+
+		/// Cluster collection of the Service
+        clusterMapType clusterMap_;
+
+		//unique instance of the Silecs service
+		static Service* instance_;
+
+		//Semantic versioning for SILECS packages (Tools, Environment and client library consistency)
+		static const std::string semverMajor_; //Major release, not backward compatible
+		static const std::string semverMinor_; //Minor release, backward compatible
+		static const std::string semverPatch_; //Bug fixes, backward compatible
+
+		static bool isShutingDown_;
+	};
+
+} // namespace
+
+#endif // _SILECS_SERVICE_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/WrapperAction.h b/silecs-communication-cpp/src/silecs-communication/interface/core/WrapperAction.h
new file mode 100644
index 0000000000000000000000000000000000000000..f6f887080e8932c80732d3e616ccef513b1d783f
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/WrapperAction.h
@@ -0,0 +1,55 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _WRAPPER_ACTION_H_
+#define _WRAPPER_ACTION_H_
+
+#include <silecs-communication/interface/core/SilecsAction.h>
+
+namespace Silecs
+{
+	class Context;
+
+	/*!
+	 * \class WrapperAction
+	 * \brief
+	 */
+	class WrapperAction
+	{
+
+	public:
+		WrapperAction() {};
+		WrapperAction(Action* plcAction) : pAction_(plcAction) {};
+ 		virtual ~WrapperAction() {};
+
+        /*!
+         * \fn function
+         * It contains the code to be executed for this action.
+         * Has to be overriden for concrete PLC action.
+         */
+ 		static int function(WrapperAction plcWrapperAction, Context* pContext)
+ 		{
+ 			return plcWrapperAction.pAction_->execute(pContext);
+ 		}
+
+	private:
+	  	Action *pAction_;
+
+	};
+
+} // namespace
+
+#endif // _WRAPPER_ACTION_H_
+
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVBlock.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVBlock.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..53080f534936322b6f7180d564455ad8b5f36b46
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVBlock.cpp
@@ -0,0 +1,346 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifdef NI_SUPPORT_ENABLED
+#include "CNVBlock.h"
+
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/utility/Thread.h>
+#include <silecs-communication/interface/utility/XMLParser.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/equipment/SilecsBlock.h>
+#include <silecs-communication/interface/equipment/SilecsRegister.h>
+#include <silecs-communication/interface/core/SilecsAction.h>
+#include <silecs-communication/interface/core/CNVRecvAction.h>
+#include <silecs-communication/interface/core/CNVSendAction.h>
+#include <silecs-communication/interface/core/WrapperAction.h>
+#include <silecs-communication/interface/utility/SilecsException.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <silecs-communication/interface/utility/StringUtilities.h>
+
+namespace Silecs
+{
+
+	/* Check for errors */
+	void CNVBlock::errChk(int code)
+	{
+		if(code != 0)
+		{
+			LOG(DEBUG) << "CNV Exception raised: " << std::string(CNVGetErrorDescription(code));
+			throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, std::string(CNVGetErrorDescription(code))+" in block "+ name_);
+		}
+	}
+
+	//-------------------------------------------------------------------------------------------
+	//------ CNVBlock
+	//-------------------------------------------------------------------------------------------
+
+	CNVBlock::CNVBlock(PLC* thePLC, ElementXML blockNode, AccessType accessType):
+			Block(thePLC, blockNode,accessType)
+	{
+		// associate buffer pointer with created buffer
+		pBuffer_ = (CNVData*)& buffer_;
+	}
+
+	CNVBlock::~CNVBlock()
+	{
+	}
+
+	//-------------------------------------------------------------------------------------------
+	//------ CNVInputBlock
+	//-------------------------------------------------------------------------------------------
+
+	CNVInputBlock::CNVInputBlock(PLC* thePLC, ElementXML blockNode, AccessType accessType) :
+		CNVBlock(thePLC, blockNode, accessType)
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Block (create): " << name_ << ", CNV: " << getPLC()->getName() << ", access: Input" << ", hasMaster: " << (hasMasterRegister() ? "yes" : "no") << ", hasSlave: " << (hasSlaveRegister() ? "yes" : "no") << ", address: " << address_ << ", mem-size: " << memSize_ ;//<< ", buffer-size: " << bufferSize_;
+
+		handle_ = NULL;
+		subscriptionFlag_ = false;
+
+        // Creates receive task which relies on the block exchange
+		if (getPLC()->getProtocolID() == BlockMode)
+			pAction_ = new CNVRecvBlockMode(this, name_ + "_" + getPLC()->getName());
+		else
+			pAction_ = new CNVRecvDeviceMode(this, name_ + "_" + getPLC()->getName());
+
+		WrapperAction wrapperAction(pAction_);
+		pTask_ = new Task<WrapperAction>(WrapperAction::function, wrapperAction);
+	}
+
+	CNVInputBlock::~CNVInputBlock()
+	{
+	}
+
+	bool CNVInputBlock::doSubscribe()
+	{
+		if(!subscriptionFlag_)
+		{
+            LOG(ALLOC) << "CNVInputBlock::doSubscribe (create-buffer):" << name_ << std::endl;
+
+			int numberOfDevice = thePLC_->getDeviceMap().size();
+			handle_ = (CNVBufferedSubscriber*)calloc(numberOfDevice,sizeof(CNVBufferedSubscriber));
+
+            subscriptionFlag_ = true; //subscription is fine a priori
+
+			deviceVectorType::iterator pDeviceIter;
+			int i=0;
+			for(pDeviceIter = thePLC_->getDeviceMap().begin(); pDeviceIter != thePLC_->getDeviceMap().end(); ++pDeviceIter)
+			{
+
+				std::string blockAddress = "\\\\"+thePLC_->getName()+"\\'"
+							+thePLC_->theCluster_->getClassName()+"-"+thePLC_->theCluster_->getClassVersion()+"'\\"
+							+ pDeviceIter->second->getLabel()+"\\"+name_;
+
+				LOG(DEBUG) << "doSubscribe(): Subscribing to address: " << blockAddress;
+
+	            int code = CNVCreateBufferedSubscriber(blockAddress.c_str(), 0 , 0, 2, CNVWaitForever, 0, &handle_[i]);
+
+		        if(code != 0)
+		        {   LOG(DEBUG) << "doSubscribe(): CNV Exception raised: " << std::string(CNVGetErrorDescription(code));
+		            unSubscribe(); //dispose subscription resources if any and update subscriptionFlag_
+		            break;
+		        }
+				i++;
+			}
+		}
+		return subscriptionFlag_;
+	}
+
+	void CNVInputBlock::unSubscribe()
+	{
+		if(handle_!=NULL)
+		{
+			LOG(ALLOC) << "CNVInputBlock::unSubscribe (dispose):" << name_ << std::endl;
+
+			for(unsigned int i=0; i<thePLC_->getDeviceMap().size(); i++)
+			{
+                int code = CNVDispose(handle_[i]);
+                if(code != 0)
+                {   LOG(DEBUG) << "unSubscribe(): CNV Exception raised: " << std::string(CNVGetErrorDescription(code));
+                    break;
+                }
+			}
+			free(handle_);
+			handle_ = NULL;
+			subscriptionFlag_ = false;
+		}
+	}
+
+
+	CNVBufferedSubscriber* CNVInputBlock::getHandle(std::string deviceName)
+	{
+		int i=0;
+		deviceVectorType::iterator pDeviceIter;
+		for(pDeviceIter = thePLC_->getDeviceMap().begin(); pDeviceIter != thePLC_->getDeviceMap().end(); ++pDeviceIter)
+		{
+			if(pDeviceIter->second->getLabel()==deviceName)
+				return &handle_[i];
+			i++;
+		}
+		return NULL;
+	}
+
+	//-------------------------------------------------------------------------------------------
+	//------ CNVOutputBlock
+	//-------------------------------------------------------------------------------------------
+    void CNVOutputBlock::createDataValue(Silecs::Register* regRef, CNVData* builderRef)
+    {
+        if(regRef->isScalar())
+        {   // allocate space for a scalar
+            switch(regRef->getFormat())
+            {
+                /*   type                                         Buffer element     CNVType    DefaultValue*/
+                case uInt8:     { errChk(CNVCreateScalarDataValue(builderRef, CNVUInt8,  0 ));   break; }
+                case Int8:      { errChk(CNVCreateScalarDataValue(builderRef, CNVInt8,   0 ));   break; }
+                case uInt16:    { errChk(CNVCreateScalarDataValue(builderRef, CNVUInt16, 0 ));   break; }
+                case Int16:     { errChk(CNVCreateScalarDataValue(builderRef, CNVInt16,  0 ));   break; }
+                case uInt32:    { errChk(CNVCreateScalarDataValue(builderRef, CNVUInt32, 0 ));   break; }
+                case Int32:     { errChk(CNVCreateScalarDataValue(builderRef, CNVInt32,  0 ));   break; }
+                case uInt64:    { errChk(CNVCreateScalarDataValue(builderRef, CNVUInt64, 0 ));   break; }
+                case Int64:     { errChk(CNVCreateScalarDataValue(builderRef, CNVInt64,  0 ));   break; }
+                case Float32:   { errChk(CNVCreateScalarDataValue(builderRef, CNVSingle, 0 ));   break; }
+                case Float64:   { errChk(CNVCreateScalarDataValue(builderRef, CNVDouble, 0 ));   break; }
+                // CNV does not support date. Double is used instead
+                case Date:      { errChk(CNVCreateScalarDataValue(builderRef, CNVDouble, 0 ));   break; }
+                case String:    { errChk(CNVCreateScalarDataValue(builderRef, CNVString, "" ));  break; }
+            }
+        }
+        else
+        { //allocate space for an array (up to 2 dimensions)
+            long unsigned int dimension[2];
+            dimension[0] = regRef->getDimension1();
+            dimension[1] = regRef->getDimension2();
+            long unsigned int flatDimension = dimension[0] * dimension[1];
+            void* array;
+
+            switch(regRef->getFormat())
+            {
+                /*   type                          Buffer element     CNVType    array? Dimensions*/
+                case uInt8:
+                {
+                    array = (uint8_t*)calloc(flatDimension,sizeof(uint8_t));
+                    errChk(CNVCreateArrayDataValue(builderRef, CNVInt8,  array ,2 , dimension));
+                    break;
+                }
+                case Int8:
+                {
+                    array = (int8_t*)calloc(flatDimension,sizeof(int8_t));
+                    errChk(CNVCreateArrayDataValue(builderRef, CNVUInt8, array ,2 , dimension));
+                    break;
+                }
+                case uInt16:
+                {
+                    array = (uint16_t*)calloc(flatDimension,sizeof(uint16_t));
+                    errChk(CNVCreateArrayDataValue(builderRef, CNVUInt16, array ,2 , dimension));
+                    break;
+                }
+                case Int16:
+                {
+                    array = (int16_t*)calloc(flatDimension,sizeof(int16_t));
+                    errChk(CNVCreateArrayDataValue(builderRef, CNVInt16, array ,2 , dimension));
+                    break;
+                }
+                case uInt32:
+                {
+                    array = (uint32_t*)calloc(flatDimension,sizeof(uint32_t));
+                    errChk(CNVCreateArrayDataValue(builderRef, CNVUInt32, array ,2 , dimension));
+                    break;
+                }
+                case Int32:
+                {
+                    array = (int32_t*)calloc(flatDimension,sizeof(int32_t));
+                    errChk(CNVCreateArrayDataValue(builderRef, CNVInt32, array ,2 , dimension));
+                    break;
+                }
+                case uInt64:
+                {
+                    array = (uint64_t*)calloc(flatDimension,sizeof(uint64_t));
+                    errChk(CNVCreateArrayDataValue(builderRef, CNVUInt64, array ,2 , dimension));
+                    break;
+                }
+                case Int64:
+                {
+                    array = (int64_t*)calloc(flatDimension,sizeof(int64_t));
+                    errChk(CNVCreateArrayDataValue(builderRef, CNVInt64,array ,2 , dimension));
+                    break;
+                }
+                case Float32:
+                {
+                    array = (float*)calloc(flatDimension,sizeof(float));
+                    errChk(CNVCreateArrayDataValue(builderRef, CNVSingle, array ,2 , dimension));
+                    break;
+                }
+                case Float64:
+                {
+                    array = (double*)calloc(flatDimension,sizeof(double));
+                    errChk(CNVCreateArrayDataValue(builderRef, CNVDouble, array ,2 , dimension));
+                    break;
+                }
+                case Date:
+                {
+                    array = (double*)calloc(flatDimension,sizeof(double));
+                    errChk(CNVCreateArrayDataValue(builderRef, CNVDouble, array ,2 , dimension));
+                    break;
+                }
+                case String:
+                {
+                    array = (char*)calloc(flatDimension,sizeof(char*));
+                    errChk(CNVCreateArrayDataValue(builderRef, CNVString, array ,2 , dimension));
+                    break;
+                }
+            }
+            free(array);
+        }
+    }
+
+	CNVOutputBlock::CNVOutputBlock(PLC* thePLC, ElementXML blockNode, AccessType accessType) :
+		CNVBlock(thePLC, blockNode, accessType)
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Block (create): " << name_ << ", CNV: " << getPLC()->getName() << ", access: Output" << ", hasMaster: " << (hasMasterRegister() ? "yes" : "no") << ", hasSlave: " << (hasSlaveRegister() ? "yes" : "no") << ", address: " << address_ << ", mem-size: " << memSize_;// << ", buffer-size: " << bufferSize_;
+
+		/* ALLOCATE THE BUFFER */
+		deviceVectorType deviceCol = thePLC->getDeviceMap();
+		Device* currentDev = deviceCol[0].second;
+		std::vector<Register*> regCol = currentDev->getRegisterCollection(name_);
+
+		//Allocate the CNVStruct for the buffer
+		int numberOfReg = regCol.size();
+        CNVData *structBuilder = (CNVData*)calloc(numberOfReg,sizeof(CNVData)); //allocate space for number of register in the block
+
+        // Creates send task which relies on the block exchange
+		if (getPLC()->getProtocolID() == BlockMode)
+		{
+			// ALLOCATE A OUTPUT BLOCK IN BLOCK MODE
+			int numberOfDevice = thePLC->getDeviceMap().size();
+
+			CNVData *arrayBuilder = (CNVData*)calloc(numberOfDevice,sizeof(CNVData)*numberOfReg); //allocate space for number of device in the device array
+
+			for(int j=0;j<numberOfDevice;j++)
+			{
+				// for each register in the current block
+				for(int i=0;i<numberOfReg;i++)
+				{
+				    createDataValue(regCol[i], &structBuilder[i]);
+				}
+
+				errChk(CNVCreateStructDataValue (&arrayBuilder[j], 	// data handler
+												structBuilder,		// input structure
+												numberOfReg)); 		// number of fields
+			}
+
+			long unsigned int dimensions[1] = {numberOfDevice};
+			errChk(CNVCreateArrayDataValue (&buffer_,		// data handler
+											CNVStruct,		// array type
+											arrayBuilder,	// input array
+											1,				// mono-dimensional array
+											dimensions)); 	// array length
+
+			pAction_ = new CNVSendBlockMode(this, name_ + "_" + getPLC()->getName());
+
+	        free(arrayBuilder);
+		}
+		else
+		{
+			// ALLOCATE A OUTPUT BLOCK IN DEVICE MODE
+			// for each register in the current block
+			for(int i=0;i<numberOfReg;i++)
+			{
+                createDataValue(regCol[i], &structBuilder[i]);
+			}
+			errChk(CNVCreateStructDataValue (&buffer_, 	// data handler
+											structBuilder,	// input structure
+											numberOfReg)); 	// number of fields
+
+			pAction_ = new CNVSendDeviceMode(this, name_ + "_" + getPLC()->getName());
+		}
+
+        for(int i=0;i<numberOfReg;i++) // TO check if works
+            CNVDisposeData(structBuilder[i]);
+
+        free(structBuilder);
+
+		WrapperAction wrapperAction(pAction_);
+		pTask_ = new Task<WrapperAction>(WrapperAction::function, wrapperAction);
+	}
+
+	CNVOutputBlock::~CNVOutputBlock()
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "CNVOutputBlock (delete): " << name_;
+
+		CNVDisposeData(*((CNVData*)pBuffer_));
+	}
+}
+#endif //NI_SUPPORT_ENABLED
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVBlock.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVBlock.h
new file mode 100644
index 0000000000000000000000000000000000000000..4f84afc132b31d4d2d5ad00e41cb4f8af702a1f3
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVBlock.h
@@ -0,0 +1,109 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifdef NI_SUPPORT_ENABLED
+#ifndef _SILECS_CNV_BLOCK_H_
+#define _SILECS_CNV_BLOCK_H_
+
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/utility/Thread.h>
+#include <silecs-communication/interface/equipment/SilecsBlock.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <nilibnetv.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+namespace Silecs
+{
+
+	class CNVBlock : public Block
+	{
+
+	public:
+		CNVBlock(PLC* thePLC, ElementXML blockNode, AccessType accessType);
+		~CNVBlock();
+
+	protected:
+		// Check for CNV errors, log and create an exception
+		void errChk(int code);
+
+		friend class Device;
+		CNVData buffer_;
+	};
+
+	/*! -----------------------------------------------------------------------
+	 * \class InputBlock
+	 * \brief This is a specific Block for Acquisition data (from NI to client)
+	 */
+	class CNVInputBlock : public CNVBlock
+	{
+
+	public:
+		CNVInputBlock(PLC* thePLC, ElementXML blockNode, AccessType accessType);
+		virtual ~CNVInputBlock();
+
+		/*!
+		 * \brief Creates subscription
+		 * Allocates memory for the subscriber, subscribes.
+		 * if subscription was already in place does nothing.
+		 * \return True if subscription (all variables) is successful.
+		 */
+		bool doSubscribe();
+
+		/*!
+		 * \brief Delete subscription
+		 * Free memory for the subscriber, and unsubscribe.
+		 */
+		void unSubscribe();
+
+		/*!
+		 * \brief Get buffer Handler
+		 * Return a pointer to the buffer for current block / required device
+		 * \param deviceName device name as a string
+		 * \return pointer to the handler buffer
+		 */
+		CNVBufferedSubscriber* getHandle(std::string deviceName);
+
+	private:
+		// Handler
+		CNVBufferedSubscriber *handle_;
+		// Flag to avoid creating multiple buffer subscriber to the same block
+		bool subscriptionFlag_;
+	};
+
+	/*! -----------------------------------------------------------------------
+	 * \class OutputBlock
+	 * \brief This is a specific Block for Settings (from client to NI)
+	 */
+	class CNVOutputBlock : public CNVBlock
+	{
+
+	public:
+		CNVOutputBlock(PLC* thePLC, ElementXML blockNode, AccessType accessType);
+		virtual ~CNVOutputBlock();
+	private:
+	    void createDataValue(Silecs::Register* regRef, CNVData* builderRef);
+	};
+
+} // namespace
+
+#endif // _SILECS_BLOCK_H_
+#endif //NI_SUPPORT_ENABLED
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVRegister.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVRegister.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d27cdd367e0a6a0b518e04424db3295bd98de808
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVRegister.cpp
@@ -0,0 +1,784 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifdef NI_SUPPORT_ENABLED
+#include "CNVRegister.h"
+
+namespace Silecs
+{
+	// Constructor from super class
+	CNVRegister::CNVRegister(Device* theDevice, ElementXML* pDesignEl) : Register(theDevice, pDesignEl)
+	{
+	}
+
+	// Specialized Destructor
+	CNVRegister::~CNVRegister()
+	{
+
+	}
+
+	/* Check for errors */
+	void CNVRegister::errChk(int code)
+	{
+		if(code != 0)
+		{
+			LOG(DEBUG) << "CNV Exception raised: " << CNVGetErrorDescription(code);
+			throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, std::string(CNVGetErrorDescription(code))+" in register "+ name_);
+		}
+	}
+
+    template <typename T>
+    inline void CNVRegister::swapInputArray2D(FormatType F, uint32_t dim1, uint32_t dim2)
+    {
+        T *temp = (T*)calloc(dim1*dim2, size_);
+        unsigned long i = 0;
+        unsigned long index = 0;
+        for (unsigned long j=0; j < dimension1_; j++)
+        {
+            i = j;
+            while(i < (dimension1_*dimension2_))
+            {
+                temp[index] = ((T*)pRecvValue_)[i];
+                index++;
+                i += dimension1_;
+            }
+        }
+
+        memcpy(pRecvValue_, (void *)temp, size_*dimension1_*dimension2_);
+        free(temp);
+    }
+
+    template <typename T>
+    inline void CNVRegister::swapOutputArray2D(FormatType F, uint32_t dim1, uint32_t dim2)
+    {
+        T *temp = (T*)calloc(dim1*dim2, size_);
+        unsigned long i = 0;
+        unsigned long index = 0;
+        for (unsigned long j=0; j < dimension2_; j++)
+        {
+            i = j;
+            while(i < (dimension1_*dimension2_))
+            {
+                temp[index] = ((T*)pSendValue_)[i];
+                index++;
+                i += dimension2_;
+            }
+        }
+
+        memcpy(pSendValue_, (void *)temp, size_*dimension1_*dimension2_);
+        free(temp);
+    }
+
+    void CNVRegister::swapInputUInt8Array2D(uint32_t dim1, uint32_t dim2) {swapInputArray2D<uint8_t>(uInt8, dim1, dim2); }
+    void CNVRegister::swapInputInt8Array2D(uint32_t dim1, uint32_t dim2) {swapInputArray2D<int8_t>(Int8, dim1, dim2); }
+    void CNVRegister::swapInputUInt16Array2D(uint32_t dim1, uint32_t dim2) {swapInputArray2D<uint16_t>(uInt16, dim1, dim2); }
+    void CNVRegister::swapInputInt16Array2D(uint32_t dim1, uint32_t dim2) {swapInputArray2D<int16_t>(Int16, dim1, dim2); }
+    void CNVRegister::swapInputUInt32Array2D(uint32_t dim1, uint32_t dim2) {swapInputArray2D<uint32_t>(uInt32, dim1, dim2); }
+    void CNVRegister::swapInputInt32Array2D(uint32_t dim1, uint32_t dim2) {swapInputArray2D<int32_t>(Int32, dim1, dim2); }
+    void CNVRegister::swapInputUInt64Array2D(uint32_t dim1, uint32_t dim2) {swapInputArray2D<uint64_t>(uInt64, dim1, dim2); }
+    void CNVRegister::swapInputInt64Array2D(uint32_t dim1, uint32_t dim2) {swapInputArray2D<int64_t>(Int64, dim1, dim2); }
+    void CNVRegister::swapInputFloat32Array2D(uint32_t dim1, uint32_t dim2) {swapInputArray2D<float>(Float32, dim1, dim2); }
+    void CNVRegister::swapInputFloat64Array2D(uint32_t dim1, uint32_t dim2) {swapInputArray2D<double>(Float64, dim1, dim2); }
+    void CNVRegister::swapInputDateArray2D(uint32_t dim1, uint32_t dim2) {swapInputArray2D<double>(Date, dim1, dim2); }
+
+    void CNVRegister::swapOutputUInt8Array2D(uint32_t dim1, uint32_t dim2) {swapOutputArray2D<uint8_t>(uInt8, dim1, dim2); }
+    void CNVRegister::swapOutputInt8Array2D(uint32_t dim1, uint32_t dim2) {swapOutputArray2D<int8_t>(Int8, dim1, dim2); }
+    void CNVRegister::swapOutputUInt16Array2D(uint32_t dim1, uint32_t dim2) {swapOutputArray2D<uint16_t>(uInt16, dim1, dim2); }
+    void CNVRegister::swapOutputInt16Array2D(uint32_t dim1, uint32_t dim2) {swapOutputArray2D<int16_t>(Int16, dim1, dim2); }
+    void CNVRegister::swapOutputUInt32Array2D(uint32_t dim1, uint32_t dim2) {swapOutputArray2D<uint32_t>(uInt32, dim1, dim2); }
+    void CNVRegister::swapOutputInt32Array2D(uint32_t dim1, uint32_t dim2) {swapOutputArray2D<int32_t>(Int32, dim1, dim2); }
+    void CNVRegister::swapOutputUInt64Array2D(uint32_t dim1, uint32_t dim2) {swapOutputArray2D<uint64_t>(uInt64, dim1, dim2); }
+    void CNVRegister::swapOutputInt64Array2D(uint32_t dim1, uint32_t dim2) {swapOutputArray2D<int64_t>(Int64, dim1, dim2); }
+    void CNVRegister::swapOutputFloat32Array2D(uint32_t dim1, uint32_t dim2) {swapOutputArray2D<float>(Float32, dim1, dim2); }
+    void CNVRegister::swapOutputFloat64Array2D(uint32_t dim1, uint32_t dim2) {swapOutputArray2D<double>(Float64, dim1, dim2); }
+    void CNVRegister::swapOutputDateArray2D(uint32_t dim1, uint32_t dim2) {swapOutputArray2D<double>(Date, dim1, dim2); }
+
+	void CNVRegister::setRegIntoStructBuffer(CNVData *buffer,int bufferSize, CNVData reg, int regOffset)
+	{
+
+		CNVData *temp = (CNVData*)calloc(bufferSize,sizeof(CNVData));
+		try{
+			// split struct into fields
+			errChk(CNVGetStructFields (*buffer,temp,bufferSize));
+
+			// Dispose the single value that will be replaced
+			errChk(CNVDisposeData(temp[regOffset]));
+
+			// substitute value inside the appropriated field
+			temp[regOffset] = reg;
+
+			// re-packs up the struct
+			errChk(CNVSetStructDataValue(*buffer,temp,bufferSize));
+		}
+		catch (const SilecsException& ex)
+		{
+			// Cleanup before forwarding the exception
+			for(int i=0;i<bufferSize;i++)
+				CNVDisposeData(temp[i]);
+			free(temp);
+			throw;
+		}
+		// Dispose the temporary CNV data
+		for(int i=0;i<bufferSize;i++)
+			CNVDisposeData(temp[i]);
+		// Free the pointer
+		free(temp);
+	}
+
+
+	CNVData CNVRegister::getRegfromStructBuffer(CNVData buffer,int bufferSize, int regOffset)
+	{
+
+		CNVData *allFields = (CNVData*)calloc(bufferSize,sizeof(CNVData));
+		CNVData returnValue;
+		try{
+			// split struct into fields
+			errChk(CNVGetStructFields(buffer,allFields,bufferSize));
+
+			returnValue = allFields[regOffset];
+		}
+		catch (const SilecsException& ex)
+		{
+			// Cleanup before forwarding the exception
+			for(int i=0;i<bufferSize;i++)
+				if(i!=regOffset)
+					errChk(CNVDisposeData(allFields[i]));
+			free(allFields);
+			throw;
+		}
+
+		for(int i=0;i<bufferSize;i++)
+			if(i!=regOffset)
+				errChk(CNVDisposeData(allFields[i]));
+
+		free(allFields);
+		// return the researched index
+		return returnValue;
+	}
+
+	void CNVRegister::importValue(void* pBuffer, timeval ts)
+	{
+	    LOG(DEBUG) << "CNVRegister::importValue Reg " << name_ << " dim1: " << dimension1_ << " dim2: " << dimension2_;
+
+		unsigned long structBufferSize = this->getDevice()->getRegisterCollection(this->getBlockName()).size();
+
+		CNVData regContent; // will contain the register value in a CNVData format.
+
+        if (this->getDevice()->getPLC()->getProtocolID()==DeviceMode)
+		{
+			// DEVICE MODE { BlockStruct.reg(1-n) }
+			regContent = getRegfromStructBuffer((CNVData)(*(CNVData*) pBuffer), structBufferSize, address_);
+		}
+		else
+		{
+			// BLOCK MODE { Device[BlockStruct.reg(1-n)] }
+			LOG(ERROR) << "Block mode not supported for shared variables.";
+			throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, "Block mode not supported for shared variables. Error in register "+ name_);
+		}
+
+		if( dimension2_ == 1)   // scalar or 1d array
+		{
+			if( dimension1_== 1 )   // the register contains a scalar
+			{
+				// extract the register out of the struct
+                switch(format_)
+                {
+                    case uInt8: { errChk(CNVGetScalarDataValue(regContent, CNVUInt8,    pRecvValue_));  break; }
+                    case Int8:  { errChk(CNVGetScalarDataValue(regContent, CNVInt8,     pRecvValue_));  break; }
+                    case uInt16:{ errChk(CNVGetScalarDataValue(regContent, CNVUInt16,   pRecvValue_));  break; }
+                    case Int16: { errChk(CNVGetScalarDataValue(regContent, CNVInt16,    pRecvValue_));  break; }
+                    case uInt32:{ errChk(CNVGetScalarDataValue(regContent, CNVUInt32,   pRecvValue_));  break; }
+                    case Int32: { errChk(CNVGetScalarDataValue(regContent, CNVInt32,    pRecvValue_));  break; }
+                    case uInt64:{ errChk(CNVGetScalarDataValue(regContent, CNVUInt64,   pRecvValue_));  break; }
+                    case Int64: { errChk(CNVGetScalarDataValue(regContent, CNVInt64,    pRecvValue_));  break; }
+                    case Float32:{errChk(CNVGetScalarDataValue(regContent, CNVSingle,   pRecvValue_));  break; }
+                    case Float64:{errChk(CNVGetScalarDataValue(regContent, CNVDouble,   pRecvValue_));  break; }
+                    // CNV does not support date. Double is used instead
+                    case Date:  { errChk(CNVGetScalarDataValue(regContent, CNVDouble, pRecvValue_));    break; }
+                    default:
+                    {
+                        LOG(ERROR) << "Unknown shared variable format.";
+                        throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, "Unknown shared variable format. Error in register "+ name_);
+                    }
+                }
+            }
+            else    // the register contains a 1D array
+            {
+                // retrieve dimension of the array
+                long unsigned int dimension[1];
+                errChk(CNVGetArrayDataDimensions (regContent, 1, dimension));
+
+                // if received register dimension do not match with one retrieved from the XML throw an exception
+                if(dimension1_!=dimension[0])
+                {
+                    LOG(ERROR) << "Reg " << name_ << " mismatching dimension1. Expected: " << dimension1_ << " received: " << dimension[0];
+                    throw SilecsException(__FILE__, __LINE__, DATA_ARRAY_LENGTH_MISMATCH, name_);
+                }
+
+                // extract the vector content
+                switch(format_)
+                {
+                    case uInt8: { errChk(CNVGetArrayDataValue (regContent, CNVUInt8,  pRecvValue_,  dimension1_));       break; }
+                    case Int8:  { errChk(CNVGetArrayDataValue (regContent, CNVInt8,   pRecvValue_,  dimension1_));       break; }
+                    case uInt16:{ errChk(CNVGetArrayDataValue (regContent, CNVUInt16, pRecvValue_,  dimension1_));       break; }
+                    case Int16: { errChk(CNVGetArrayDataValue (regContent, CNVInt16,  pRecvValue_,  dimension1_));       break; }
+                    case uInt32:{ errChk(CNVGetArrayDataValue (regContent, CNVUInt32, pRecvValue_,  dimension1_));       break; }
+                    case Int32: { errChk(CNVGetArrayDataValue (regContent, CNVInt32,  pRecvValue_,  dimension1_));       break; }
+                    case uInt64:{ errChk(CNVGetArrayDataValue (regContent, CNVUInt64, pRecvValue_,  dimension1_));       break; }
+                    case Int64: { errChk(CNVGetArrayDataValue (regContent, CNVInt64,  pRecvValue_,  dimension1_));       break; }
+                    case Float32:{errChk(CNVGetArrayDataValue (regContent, CNVSingle, pRecvValue_,  dimension1_));       break; }
+                    case Float64:{errChk(CNVGetArrayDataValue (regContent, CNVDouble, pRecvValue_,  dimension1_));       break; }
+                    // CNV does not support date. Double is used instead
+                    case Date:  { errChk(CNVGetArrayDataValue (regContent, CNVDouble, pRecvValue_, dimension1_));        break; }
+                    default:
+                    {
+                        LOG(ERROR) << "Unknown shared variable format.";
+                        throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, "Unknown shared variable format. Error in register "+ name_);
+                    }
+                }
+            }
+        }
+        else    // dim2 >1: the register contains a 2d array
+        {
+            long unsigned int dimension[2];
+            errChk(CNVGetArrayDataDimensions (regContent, 2, dimension));
+            LOG(DEBUG) << "CNVRegister::importValue Reg " << name_ << " received dim1: " << dimension[0] << " dim2: " << dimension[1];
+
+            // if received register dimension do not match with one retrieved from the XML throw an exception
+            if((dimension1_!=dimension[0]) || (dimension2_ != dimension[1]))
+                throw SilecsException(__FILE__, __LINE__, DATA_ARRAY_LENGTH_MISMATCH, name_);
+
+            // extract the vector content
+            switch(format_)
+            {
+               case uInt8:
+               {
+                   errChk(CNVGetArrayDataValue (regContent, CNVUInt8, pRecvValue_,  dimension1_*dimension2_));
+                   swapInputUInt8Array2D(dimension1_, dimension2_);
+                   break;
+               }
+               case Int8:
+               {
+                   errChk(CNVGetArrayDataValue (regContent, CNVInt8, pRecvValue_,  dimension1_*dimension2_));
+                   swapInputInt8Array2D(dimension1_, dimension2_);
+                   break;
+               }
+               case uInt16:
+               {
+                   errChk(CNVGetArrayDataValue (regContent, CNVUInt16, pRecvValue_,  dimension1_*dimension2_));
+                   swapInputUInt16Array2D(dimension1_, dimension2_);
+                   break;
+               }
+               case Int16:
+               {
+                   errChk(CNVGetArrayDataValue (regContent, CNVInt16,  pRecvValue_,  dimension1_*dimension2_));
+                   swapInputInt16Array2D(dimension1_, dimension2_);
+                   break;
+               }
+               case uInt32:
+               {
+                   errChk(CNVGetArrayDataValue (regContent, CNVUInt32, pRecvValue_,  dimension1_*dimension2_));
+                   swapInputUInt32Array2D(dimension1_, dimension2_);
+                   break;
+               }
+               case Int32:
+               {
+                   errChk(CNVGetArrayDataValue (regContent, CNVInt32,  pRecvValue_,  dimension1_*dimension2_));
+                   swapInputInt32Array2D(dimension1_, dimension2_);
+                   break;
+               }
+               case uInt64:
+               {
+                   errChk(CNVGetArrayDataValue (regContent, CNVUInt64, pRecvValue_,  dimension1_*dimension2_));
+                   swapInputUInt64Array2D(dimension1_, dimension2_);
+                   break;
+               }
+               case Int64:
+               {
+                   errChk(CNVGetArrayDataValue (regContent, CNVInt64,  pRecvValue_,  dimension1_*dimension2_));
+                   swapInputInt64Array2D(dimension1_, dimension2_);
+                   break;
+               }
+               case Float32:
+               {
+                   errChk(CNVGetArrayDataValue (regContent, CNVSingle, pRecvValue_,  dimension1_*dimension2_));
+                   swapInputFloat32Array2D(dimension1_, dimension2_);
+                   break;
+               }
+               case Float64:
+               {
+                   errChk(CNVGetArrayDataValue (regContent, CNVDouble, pRecvValue_,  dimension1_*dimension2_));
+                   swapInputFloat64Array2D(dimension1_, dimension2_);
+                   break;
+               }
+               case Date:   // CNV does not support date. Double is used instead
+               {
+                   errChk(CNVGetArrayDataValue (regContent, CNVDouble, pRecvValue_, dimension1_*dimension2_));
+                   swapInputDateArray2D(dimension1_, dimension2_);
+                   break;
+               }
+               default:
+               {
+                   LOG(ERROR) << "Unknown shared variable format.";
+                   throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, "Unknown shared variable format. Error in register "+ name_);
+               }
+            }
+        }
+        //Set the register time-stamp
+        tod_ = ts;
+        // free the register content temporary variable
+        errChk(CNVDisposeData(regContent));
+    }
+
+    void CNVRegister::exportValue(void* pBuffer)
+    {
+        CNVData regContent; // will contain the register value in a CNVData format.
+
+        if(dimension2_ == 1)    // scalar or 1d arrray
+        {
+            if( dimension1_== 1 )   // the register contains a scalar
+            {
+                // extract the register out of the struct
+                // generate the correct CNVData register content converting from the SILECS Type
+                switch(format_)
+                {
+                    case uInt8:
+                    {
+                        errChk(CNVCreateScalarDataValue (&regContent, CNVUInt8, (uint8_t)(*((uint8_t *)pSendValue_))));
+                        errChk(CNVSetScalarDataValue(regContent, CNVUInt8, (uint8_t)(*((uint8_t *)pSendValue_))));
+                        break;
+                    }
+                    case Int8:
+                    {
+                        errChk(CNVCreateScalarDataValue (&regContent, CNVInt8, (int8_t)(*((int8_t *)pSendValue_))));
+                        errChk(CNVSetScalarDataValue(regContent, CNVInt8, (int8_t)(*((int8_t *)pSendValue_))));
+                        break;
+                    }
+                    case uInt16:
+                    {
+                        errChk(CNVCreateScalarDataValue (&regContent, CNVUInt16,(uint16_t)(*((uint16_t *)pSendValue_))) );
+                        errChk(CNVSetScalarDataValue(regContent, CNVUInt16, (uint16_t)(*((uint16_t *)pSendValue_))));
+                        break;
+                    }
+                    case Int16:
+                    {
+                        errChk(CNVCreateScalarDataValue (&regContent, CNVInt16, (int16_t)(*((int16_t *)pSendValue_))));
+                        errChk(CNVSetScalarDataValue(regContent, CNVInt16, (int16_t)(*((int16_t *)pSendValue_))));
+                        break;
+                    }
+                    case uInt32:
+                    {
+                        errChk(CNVCreateScalarDataValue (&regContent, CNVUInt32, (uint32_t)(*((uint32_t *)pSendValue_))));
+                        errChk(CNVSetScalarDataValue(regContent, CNVUInt32, (uint32_t)(*((uint32_t *)pSendValue_))));
+                        break;
+                    }
+                    case Int32:
+                    {
+                        errChk(CNVCreateScalarDataValue (&regContent, CNVInt32, (int32_t)(*((int32_t *)pSendValue_))));
+                        errChk(CNVSetScalarDataValue(regContent, CNVInt32, (int32_t)(*((int32_t *)pSendValue_))));
+                        break;
+                    }
+                    case uInt64:
+                    {
+                        errChk(CNVCreateScalarDataValue (&regContent, CNVUInt64, (uint64_t)(*((uint64_t *)pSendValue_))));
+                        errChk(CNVSetScalarDataValue(regContent, CNVUInt64, (uint64_t)(*((uint64_t *)pSendValue_))));
+                        break;
+                    }
+                    case Int64:
+                    {
+                        errChk(CNVCreateScalarDataValue (&regContent, CNVInt64, (int64_t)(*((int64_t *)pSendValue_))));
+                        errChk(CNVSetScalarDataValue(regContent, CNVInt64, (int64_t)(*((int64_t *)pSendValue_))));
+                        break;
+                    }
+                    case Float32:
+                    {
+                        errChk(CNVCreateScalarDataValue (&regContent, CNVSingle, (float)(*((float*)pSendValue_))));
+                        errChk(CNVSetScalarDataValue(regContent, CNVSingle, (float)(*((float*)pSendValue_))));
+                        break;
+                    }
+                    case Float64:
+                    {
+                        errChk(CNVCreateScalarDataValue (&regContent, CNVDouble, (double)(*((double *)pSendValue_))));
+                        errChk(CNVSetScalarDataValue(regContent, CNVDouble, (double)(*((double *)pSendValue_))));
+                        break;
+                    }
+                    case Date: // CNV does not support date. Double is used instead
+                    {
+                        errChk(CNVCreateScalarDataValue (&regContent, CNVDouble, (double)(*((double *)pSendValue_))));
+                        errChk(CNVSetScalarDataValue(regContent, CNVDouble, (double)(*((double *)pSendValue_))));
+                        break;
+                    }
+                    default:
+                    {
+                        LOG(ERROR) << "Unknown shared variable format.";
+                        throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, "Unknown shared variable format. Error in register "+ name_);
+                    }
+                }
+            }
+            else    // the register contains an array
+            {
+                long unsigned int dimensions[1];
+                dimensions[0] = dimension1_;
+
+                switch(format_)
+                {
+                    case uInt8:
+                    {
+                        errChk(CNVCreateArrayDataValue (&regContent, CNVUInt8, (uint8_t *)pSendValue_, 1, dimensions));
+                        errChk(CNVSetArrayDataValue (regContent, CNVUInt8, (uint8_t *)pSendValue_, 1, dimensions));
+                        break;
+                    }
+                    case Int8:
+                    {
+                        errChk(CNVCreateArrayDataValue (&regContent, CNVInt8, (int8_t *)pSendValue_, 1, dimensions));
+                        errChk(CNVSetArrayDataValue (regContent, CNVInt8, (int8_t *)pSendValue_, 1, dimensions));
+                        break;
+                    }
+                    case uInt16:
+                    {
+                        errChk(CNVCreateArrayDataValue (&regContent, CNVUInt16, (uint16_t *)pSendValue_, 1, dimensions));
+                        errChk(CNVSetArrayDataValue (regContent, CNVUInt16, (uint16_t *)pSendValue_, 1, dimensions));
+                        break;
+                    }
+                    case Int16:
+                    {
+                        errChk(CNVCreateArrayDataValue (&regContent, CNVInt16, (int16_t *)pSendValue_, 1, dimensions));
+                        errChk(CNVSetArrayDataValue (regContent, CNVInt16, (int16_t *)pSendValue_, 1, dimensions));
+                        break;
+                    }
+                    case uInt32:
+                    {
+                        errChk(CNVCreateArrayDataValue (&regContent, CNVUInt32, (uint32_t *)pSendValue_, 1, dimensions));
+                        errChk(CNVSetArrayDataValue (regContent, CNVUInt32, (uint32_t *)pSendValue_, 1, dimensions));
+                        break;
+                    }
+                    case Int32:
+                    {
+                        errChk(CNVCreateArrayDataValue (&regContent, CNVInt32, (int32_t *)pSendValue_, 1, dimensions));
+                        errChk(CNVSetArrayDataValue (regContent, CNVInt32, (int32_t *)pSendValue_, 1, dimensions));
+                        break;
+                    }
+                    case uInt64:
+                    {
+                        errChk(CNVCreateArrayDataValue (&regContent, CNVUInt64, (uint64_t *)pSendValue_, 1, dimensions));
+                        errChk(CNVSetArrayDataValue (regContent, CNVUInt64, (uint64_t *)pSendValue_, 1, dimensions));
+                        break;
+                    }
+                    case Int64:
+                    {
+                        errChk(CNVCreateArrayDataValue (&regContent, CNVInt64, (int64_t *)pSendValue_, 1, dimensions));
+                        errChk(CNVSetArrayDataValue (regContent, CNVInt64, (int64_t *)pSendValue_, 1, dimensions));
+                        break;
+                    }
+                    case Float32:
+                    {
+                        errChk(CNVCreateArrayDataValue (&regContent, CNVSingle, (float *)pSendValue_, 1, dimensions));
+                        errChk(CNVSetArrayDataValue (regContent, CNVSingle, (float *)pSendValue_, 1, dimensions));
+                        break;
+                    }
+                    case Float64:
+                    {
+                        errChk(CNVCreateArrayDataValue (&regContent, CNVDouble, (double *)pSendValue_, 1, dimensions));
+                        errChk(CNVSetArrayDataValue (regContent, CNVDouble, (double *)pSendValue_, 1, dimensions));
+                        break;
+                    }
+                    case Date: // CNV does not support date. Double is used instead
+                    {
+                        errChk(CNVCreateArrayDataValue (&regContent, CNVDouble, (double *)pSendValue_, 1, dimensions));
+                        errChk(CNVSetArrayDataValue (regContent, CNVDouble, (double *)pSendValue_, 1, dimensions));
+                        break;
+                    }
+                    default:
+                    {
+                        LOG(ERROR) << "Unknown shared variable format.";
+                        throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, "Unknown shared variable format. Error in register "+ name_);
+                    }
+                }
+            }
+        }
+        else    // 2d array
+        {
+            long unsigned int dimensions[2];
+            dimensions[0] = dimension1_;
+            dimensions[1] = dimension2_;
+
+            switch(format_)
+            {
+                case uInt8:
+                {
+                    swapOutputUInt8Array2D(dimension1_, dimension2_);
+                    errChk(CNVCreateArrayDataValue (&regContent, CNVUInt8, (uint8_t *)pSendValue_, 2, dimensions));
+                    errChk(CNVSetArrayDataValue (regContent, CNVUInt8, (uint8_t *)pSendValue_, 2, dimensions));
+                    break;
+                }
+                case Int8:
+                {
+                    swapOutputInt8Array2D(dimension1_, dimension2_);
+                    errChk(CNVCreateArrayDataValue (&regContent, CNVInt8, (int8_t *)pSendValue_, 2, dimensions));
+                    errChk(CNVSetArrayDataValue (regContent, CNVInt8, (int8_t *)pSendValue_, 2, dimensions));
+                    break;
+                }
+                case uInt16:
+                {
+                    swapOutputUInt16Array2D(dimension1_, dimension2_);
+                    errChk(CNVCreateArrayDataValue (&regContent, CNVUInt16, (uint16_t *)pSendValue_, 2, dimensions));
+                    errChk(CNVSetArrayDataValue (regContent, CNVUInt16, (uint16_t *)pSendValue_, 2, dimensions));
+                    break;
+                }
+                case Int16:
+                {
+                    swapOutputInt16Array2D(dimension1_, dimension2_);
+                    errChk(CNVCreateArrayDataValue (&regContent, CNVInt16, (int16_t *)pSendValue_, 2, dimensions));
+                    errChk(CNVSetArrayDataValue (regContent, CNVInt16, (int16_t *)pSendValue_, 2, dimensions));
+                    break;
+                }
+                case uInt32:
+                {
+                    swapOutputUInt32Array2D(dimension1_, dimension2_);
+                    errChk(CNVCreateArrayDataValue (&regContent, CNVUInt32, (uint32_t *)pSendValue_, 2, dimensions));
+                    errChk(CNVSetArrayDataValue (regContent, CNVUInt32, (uint32_t *)pSendValue_, 2, dimensions));
+                    break;
+                }
+                case Int32:
+                {
+                    swapOutputInt32Array2D(dimension1_, dimension2_);
+                    errChk(CNVCreateArrayDataValue (&regContent, CNVInt32, (int32_t *)pSendValue_, 2, dimensions));
+                    errChk(CNVSetArrayDataValue (regContent, CNVInt32, (int32_t *)pSendValue_, 2, dimensions));
+                    break;
+                }
+                case uInt64:
+                {
+                    swapOutputUInt64Array2D(dimension1_, dimension2_);
+                    errChk(CNVCreateArrayDataValue (&regContent, CNVUInt64, (uint64_t *)pSendValue_, 2, dimensions));
+                    errChk(CNVSetArrayDataValue (regContent, CNVUInt64, (uint64_t *)pSendValue_, 2, dimensions));
+                    break;
+                }
+                case Int64:
+                {
+                    swapOutputInt64Array2D(dimension1_, dimension2_);
+                    errChk(CNVCreateArrayDataValue (&regContent, CNVInt64, (int64_t *)pSendValue_, 2, dimensions));
+                    errChk(CNVSetArrayDataValue (regContent, CNVInt64, (int64_t *)pSendValue_, 2, dimensions));
+                    break;
+                }
+                case Float32:
+                {
+                    swapOutputFloat32Array2D(dimension1_, dimension2_);
+                    errChk(CNVCreateArrayDataValue (&regContent, CNVSingle, (float *)pSendValue_, 2, dimensions));
+                    errChk(CNVSetArrayDataValue (regContent, CNVSingle, (float *)pSendValue_, 2, dimensions));
+                    break;
+                }
+                case Float64:
+                {
+                    swapOutputFloat64Array2D(dimension1_, dimension2_);
+                    errChk(CNVCreateArrayDataValue (&regContent, CNVDouble, (double *)pSendValue_, 2, dimensions));
+                    errChk(CNVSetArrayDataValue (regContent, CNVDouble, (double *)pSendValue_, 2, dimensions));
+                    break;
+                }
+                case Date:
+                {
+                    swapOutputDateArray2D(dimension1_, dimension2_);
+                    // CNV does not support date. Double is used instead
+                    errChk(CNVCreateArrayDataValue (&regContent, CNVDouble, (double *)pSendValue_, 2, dimensions));
+                    errChk(CNVSetArrayDataValue (regContent, CNVDouble, (double *)pSendValue_, 2, dimensions));
+                    break;
+                }
+                default:
+                {
+                    LOG(ERROR) << "Unknown shared variable format.";
+                    throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, "Unknown shared variable format. Error in register "+ name_);
+                }
+            }
+        }
+
+        unsigned long structBufferSize = this->getDevice()->getRegisterCollection(this->getBlockName()).size();
+        if (this->getDevice()->getPLC()->getProtocolID()==DeviceMode)
+        {
+            // DEVICE MODE { BlockStruct.reg(1-n) }
+            setRegIntoStructBuffer((CNVData*) pBuffer,structBufferSize, regContent, address_);
+        }
+        else
+        {
+            // BLOCK MODE { Device[BlockStruct.reg(1-n)] }
+
+            LOG(ERROR) << "Block mode not supported for shared variables.";
+            throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, "Block mode not supported for shared variables. Error in register "+ name_);
+        }
+    }
+
+    void CNVRegister::importString(void* pBuffer, timeval ts)
+    {
+        unsigned long structBufferSize = this->getDevice()->getRegisterCollection(this->getBlockName()).size();
+        std::string** pRecvStringValue_ = static_cast<std::string**>(pRecvValue_);
+        CNVData regContent; // will contain the register value in a CNVData format
+
+        if (this->getDevice()->getPLC()->getProtocolID()==DeviceMode)
+        {
+            // DEVICE MODE { BlockStruct.reg(1-n) }
+            regContent = getRegfromStructBuffer((CNVData)(*(CNVData*) pBuffer), structBufferSize, address_);
+        }
+        else
+        {
+            // BLOCK MODE { Device[BlockStruct.reg(1-n)] }
+            LOG(ERROR) << "Block mode not supported for shared variables.";
+            throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, "Block mode not supported for shared variables. Error in register "+ name_);
+        }
+
+        char *temp[dimension1_*dimension2_];
+
+        if( dimension2_ == 1)   // scalar or 1D array
+        {
+            if( dimension1_== 1 )   // the register contains a scalar
+            {
+                errChk(CNVGetScalarDataValue(regContent, CNVString, temp));
+                pRecvStringValue_[0]->assign((const char*)temp[0]);
+            }
+            else    // the register contains a 1D array
+           {
+                // retrieve dimension of the mono-dimensional array
+                long unsigned int dimension[1];
+                errChk(CNVGetArrayDataDimensions (regContent, 1, dimension));
+
+                // if received register dimension do not match with one retrieved from the XML throw an exception
+                if(dimension1_!=dimension[0])
+                    throw SilecsException(__FILE__, __LINE__, DATA_ARRAY_LENGTH_MISMATCH, name_);
+
+                errChk(CNVGetArrayDataValue(regContent, CNVString, temp, dimension1_));
+                for (unsigned long i = 0; i < dimension1_; i++)
+                    pRecvStringValue_[i]->assign((const char*)temp[i]);
+           }
+        }
+        else    // the register contains a 2D array
+        {
+            // retrieve dimensions of double array
+            long unsigned int dimensions[2];
+            errChk(CNVGetArrayDataDimensions (regContent, 2, dimensions));
+
+            // if received register dimensions do not match with the ones retrieved from the XML throw an exception
+            if((dimension1_!=dimensions[0]) || (dimension2_!=dimensions[1]))
+                throw SilecsException(__FILE__, __LINE__, DATA_ARRAY_LENGTH_MISMATCH, name_);
+
+            // Warning: this method returns the element of the matrix in row-major order
+            errChk(CNVGetArrayDataValue(regContent, CNVString, temp, dimension1_*dimension2_));
+
+            // The CNV library reads the element in row-major order, whereas the SILECS CLIB works in column-major order.
+             // The following code swaps rows and columns, returning the content of pRecvValue_ correctly ordered
+            unsigned long i = 0;
+            unsigned long index = 0;
+            for (unsigned long j=0; j < dimension1_; j++)
+            {
+                i = j;
+                while(i < (dimension1_*dimension2_))
+                {
+                    pRecvStringValue_[index]->assign((const char*)temp[i]);
+                    index++;
+                    i += dimension1_;
+                }
+            }
+        }
+
+        // Set the register time-stamp
+        tod_ = ts;
+
+         // free the register content temporary variable
+        errChk(CNVDisposeData(regContent));
+    }
+
+    void CNVRegister::exportString(void* pBuffer)
+    {
+        std::string** pSendStringValue_ = static_cast<std::string**>(pSendValue_);
+        CNVData regContent; // will contain the register value in a CNVData format.
+        char *temp[dimension1_*dimension2_];
+
+        if(dimension2_ == 1)    // scalar or 1D arrray
+        {
+            if( dimension1_== 1 )   // the register contains a scalar
+            {
+                // generate the correct CNVData register content
+                errChk(CNVCreateScalarDataValue (&regContent, CNVString, (*pSendStringValue_[0]).data()));
+                errChk(CNVSetScalarDataValue(regContent, CNVString, (*pSendStringValue_[0]).data()));
+            }
+            else    // the register contains a 1D array
+            {
+                long unsigned int dimensions[1];
+                dimensions[0] = dimension1_;
+
+                for (unsigned long i = 0; i < dimension1_; i++)
+                    temp[i] = (char*)(*pSendStringValue_[i]).data();
+
+                errChk(CNVCreateArrayDataValue (&regContent, CNVString, temp, 1, dimensions));
+                errChk(CNVSetArrayDataValue(regContent, CNVString, temp, 1, dimensions));
+            }
+        }
+        else    // the register contains a 2D array
+        {
+            long unsigned int dimensions[2];
+            dimensions[0] = dimension1_;
+            dimensions[1] = dimension2_;
+
+            // The CNV library reads the element in row-major order, whereas the SILECS CLIB works in column-major order.
+             // The following code swaps rows and columns, returning the content of pSendValue_ correctly ordered
+            unsigned long i = 0;
+            unsigned long index = 0;
+            for (unsigned long j=0; j < dimension2_; j++)
+            {
+                i = j;
+                while(i < (dimension1_*dimension2_))
+                {
+                    temp[index] = (char*)(*pSendStringValue_[i]).c_str();
+                    index++;
+                    i += dimension2_;
+                }
+            }
+
+            errChk(CNVCreateArrayDataValue (&regContent, CNVString, temp, 2, dimensions));
+            errChk(CNVSetArrayDataValue(regContent, CNVString, temp, 2, dimensions));
+        }
+
+        unsigned long structBufferSize = this->getDevice()->getRegisterCollection(this->getBlockName()).size();
+        if (this->getDevice()->getPLC()->getProtocolID()==DeviceMode)
+        {
+            // DEVICE MODE { BlockStruct.reg(1-n) }
+            setRegIntoStructBuffer((CNVData*) pBuffer,structBufferSize, regContent, address_);
+        }
+        else
+        {
+            // BLOCK MODE { Device[BlockStruct.reg(1-n)] }
+            LOG(ERROR) << "Block mode not supported for shared variables.";
+            throw SilecsException(__FILE__, __LINE__, CNV_INTERNAL_ERROR, "Block mode not supported for shared variables. Error in register "+ name_);
+        }
+
+        // free the register content temporary variable
+//        errChk(CNVDisposeData(regContent));
+    }
+
+    //Transfer the value of the recvBuffer to to the sendBuffer
+    void CNVRegister::copyValue()
+    {
+        if (format_ == String)
+        {
+            std::string** pRecvStringValue_ = static_cast<std::string**>(pRecvValue_);
+            std::string** pSendStringValue_ = static_cast<std::string**>(pSendValue_);
+            for(unsigned int i=0; i<(dimension1_*dimension2_); i++)
+            {
+                *(pSendStringValue_[i]) = *(pRecvStringValue_[i]);
+            }
+        }
+        else
+        {
+            memcpy(pSendValue_, pRecvValue_, (size_*dimension1_*dimension2_));
+        }
+    }
+}
+#endif //NI_SUPPORT_ENABLED
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVRegister.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVRegister.h
new file mode 100644
index 0000000000000000000000000000000000000000..5e8df44206d8dd049a4f9e14711974d629e7fbc4
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/CNVRegister.h
@@ -0,0 +1,151 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifdef NI_SUPPORT_ENABLED
+#ifndef _SILECS_CNV_REGISTER_H_
+#define _SILECS_CNV_REGISTER_H_
+
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/utility/XMLParser.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/equipment/SilecsDevice.h>
+#include <silecs-communication/interface/equipment/SilecsRegister.h>
+#include <silecs-communication/interface/utility/SilecsException.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <silecs-communication/interface/utility/StringUtilities.h>
+#include <silecs-communication/protocol/core/silecs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include <nilibnetv.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+
+namespace Silecs
+{
+
+	/// @cond
+	class CNVRegister : public Register
+	{
+		private:
+
+			void setRegIntoStructBuffer(CNVData *buffer,int bufferSize, CNVData reg, int regOffset);
+			CNVData getRegfromStructBuffer(CNVData buffer,int bufferSize, int regOffset);
+
+			void swapInputUInt8Array2D(uint32_t dim1, uint32_t dim2);
+            void swapInputInt8Array2D(uint32_t dim1, uint32_t dim2);
+            void swapInputUInt16Array2D(uint32_t dim1, uint32_t dim2);
+            void swapInputInt16Array2D(uint32_t dim1, uint32_t dim2);
+            void swapInputUInt32Array2D(uint32_t dim1, uint32_t dim2);
+            void swapInputInt32Array2D(uint32_t dim1, uint32_t dim2);
+            void swapInputUInt64Array2D(uint32_t dim1, uint32_t dim2);
+            void swapInputInt64Array2D(uint32_t dim1, uint32_t dim2);
+            void swapInputFloat32Array2D(uint32_t dim1, uint32_t dim2);
+            void swapInputFloat64Array2D(uint32_t dim1, uint32_t dim2);
+            void swapInputDateArray2D(uint32_t dim1, uint32_t dim2);
+
+            void swapOutputUInt8Array2D(uint32_t dim1, uint32_t dim2);
+            void swapOutputInt8Array2D(uint32_t dim1, uint32_t dim2);
+            void swapOutputUInt16Array2D(uint32_t dim1, uint32_t dim2);
+            void swapOutputInt16Array2D(uint32_t dim1, uint32_t dim2);
+            void swapOutputUInt32Array2D(uint32_t dim1, uint32_t dim2);
+            void swapOutputInt32Array2D(uint32_t dim1, uint32_t dim2);
+            void swapOutputUInt64Array2D(uint32_t dim1, uint32_t dim2);
+            void swapOutputInt64Array2D(uint32_t dim1, uint32_t dim2);
+            void swapOutputFloat32Array2D(uint32_t dim1, uint32_t dim2);
+            void swapOutputFloat64Array2D(uint32_t dim1, uint32_t dim2);
+            void swapOutputDateArray2D(uint32_t dim1, uint32_t dim2);
+
+			// Check for CNV errors, log and create an exception
+			void errChk(int code);
+
+		protected:
+
+			// export register extraction methods
+			friend class PLC;
+			friend class Device;
+
+			/*!
+			 * \fn importValue
+			 * \brief Used to convert and transfered data from the data-block receiver to the register value
+			 * Overloads the virtual method inherited from the class SilecsRegister.
+			 * \param pBuffer points the data-block buffer
+			 * \param ts is the time-of-day to time-stamp the register
+			 */
+			void importValue(void* pBuffer, timeval ts);
+
+			/*!
+			 * \fn exportValue
+			 * \brief Used to transfered the register value to the data data-block to be sent
+			 * Overloads the virtual method inherited from the class SilecsRegister.
+			 * \param pBuffer points the data-block buffer
+			 */
+			void exportValue(void* pBuffer);
+
+			/*!
+			 * \fn importString
+             * \brief Import values from the received buffer to the register. Pure vistual to be implemented by the inheriting classes.
+             * \param pBuffer received data buffer
+             * \param ts register time-stamp
+             */
+            void importString(void* pBuffer, timeval ts);
+
+            /*!
+             * \fn exportString
+             * \brief Export the string from the register to the correct position in the buffer. Pure virtual to be implemented by inheriting classes.
+             * \param pBuffer the output buffer where to update the data
+             */
+            void exportString(void* pBuffer);
+
+			/*!
+			 * \fn copyValue
+			 * \brief Copies the register content from the input buffer the output buffer.
+			 * Overloads the virtual method inherited from the class SilecsRegister.
+			 * This method is used for Retentive InOut registers synchronization.
+			 */
+			void copyValue();
+
+			/*!
+			 * \fn swapInputArray2D
+			 * \brief The CNV library reads the element in row-major order, whereas the SILECS CLIB works in column-major order.
+			 *  The following code swaps rows and columns, returning the content of pRecvValue_ correctly ordered
+			 */
+			template <typename T> void swapInputArray2D(FormatType F, uint32_t dim1, uint32_t dim2);
+
+			/*!
+             * \fn swapOutputArray2D
+             * \brief The CNV library reads the element in row-major order, whereas the SILECS CLIB works in column-major order.
+             *  The following code swaps rows and columns, returning the content of pSendValue_ correctly ordered
+             */
+            template <typename T> void swapOutputArray2D(FormatType F, uint32_t dim1, uint32_t dim2);
+
+		public:
+			// Constructor from super class
+			CNVRegister(Device* theDevice, ElementXML* pDesignEl);
+
+			// Destructor from super class
+			~CNVRegister();
+
+	};
+	/// @endcond
+}
+#endif // _SILECS_CNV_REGISTER_H_
+#endif //NI_SUPPORT_ENABLED
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..69a3b8af823d889596a310f9808da4519f67693e
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.cpp
@@ -0,0 +1,92 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/utility/Thread.h>
+#include <silecs-communication/interface/utility/XMLParser.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/equipment/SilecsBlock.h>
+#include <silecs-communication/interface/equipment/SilecsRegister.h>
+#include <silecs-communication/interface/core/SilecsAction.h>
+#include <silecs-communication/interface/core/PLCRecvAction.h>
+#include <silecs-communication/interface/core/PLCSendAction.h>
+#include <silecs-communication/interface/core/WrapperAction.h>
+#include <silecs-communication/interface/utility/SilecsException.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <silecs-communication/interface/utility/StringUtilities.h>
+#include <silecs-communication/interface/equipment/PLCBlock.h>
+
+namespace Silecs
+{
+
+	PLCBlock::PLCBlock(PLC* thePLC,ElementXML blockNode, AccessType accessType):
+			Block(thePLC, blockNode,accessType)
+	{
+		// Create buffer for the block exchanges
+		bufferSize_ = memSize_; //size of one block type (including alignements)
+		if (getPLC()->getProtocolID() == BlockMode)
+		{ //BlockMode ==> access all devices in once
+		  bufferSize_ *= getPLC()->getDeviceMap().size();
+		}
+		pBuffer_ = (unsigned char*)calloc(bufferSize_, sizeof(unsigned char));
+	}
+
+	PLCBlock::~PLCBlock()
+	{
+		//Remove the buffer
+		if (pBuffer_ != NULL) free(pBuffer_); pBuffer_ = NULL;
+	}
+
+	InputBlock::InputBlock(PLC* thePLC,ElementXML blockNode, AccessType accessType) :
+		PLCBlock(thePLC, blockNode, accessType)
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Block (create): " << name_ << ", plc: " << getPLC()->getName() << ", access: Input" << ", hasMaster: " << (hasMasterRegister() ? "yes" : "no") << ", hasSlave: " << (hasSlaveRegister() ? "yes" : "no") << ", address: " << address_ << ", mem-size: " << memSize_ << ", buffer-size: " << bufferSize_;
+
+        // Creates receive task which relies on the block exchange
+		if (getPLC()->getProtocolID() == BlockMode)
+			pAction_ = new PLCRecvBlockMode(this);
+		else
+			pAction_ = new PLCRecvDeviceMode(this);
+
+		WrapperAction wrapperAction(pAction_);
+		pTask_ = new Task<WrapperAction>(WrapperAction::function, wrapperAction);
+	}
+
+
+	InputBlock::~InputBlock()
+	{
+	}
+
+
+	OutputBlock::OutputBlock(PLC* thePLC,ElementXML blockNode, AccessType accessType) :
+		PLCBlock(thePLC, blockNode, accessType)
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Block (create): " << name_ << ", plc: " << getPLC()->getName() << ", access: Output" << ", hasMaster: " << (hasMasterRegister() ? "yes" : "no") << ", hasSlave: " << (hasSlaveRegister() ? "yes" : "no") << ", address: " << address_ << ", mem-size: " << memSize_ << ", buffer-size: " << bufferSize_;
+
+        // Creates send task which relies on the block exchange
+		if (getPLC()->getProtocolID() == BlockMode)
+			pAction_ = new PLCSendBlockMode(this);
+		else
+			pAction_ = new PLCSendDeviceMode(this);
+
+		WrapperAction wrapperAction(pAction_);
+		pTask_ = new Task<WrapperAction>(WrapperAction::function, wrapperAction);
+	}
+
+	OutputBlock::~OutputBlock()
+	{
+	}
+
+}
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.h
new file mode 100644
index 0000000000000000000000000000000000000000..432145c50f04bcd59377a2b2fbca0f8633b16788
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCBlock.h
@@ -0,0 +1,71 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _SILECS_PLC_BLOCK_H_
+#define _SILECS_PLC_BLOCK_H_
+
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/utility/Thread.h>
+#include <silecs-communication/interface/equipment/SilecsBlock.h>
+
+namespace Silecs
+{
+
+	class PLCBlock : public Block
+	{
+
+	public:
+		PLCBlock(PLC* thePLC,ElementXML blockNode, AccessType accessType);
+		~PLCBlock();
+
+		inline unsigned long& getBufferSize() { return bufferSize_; }
+
+	protected:
+		friend class Device;
+
+		/// Send/Receive data size (size of block * nb of device)
+		unsigned long bufferSize_;
+
+	};
+
+	/*! -----------------------------------------------------------------------
+	 * \class InputBlock
+	 * \brief This is a specific Block for Acquisition data (from PLC to client)
+	 */
+	class InputBlock : public PLCBlock
+	{
+
+	public:
+		InputBlock(PLC* thePLC,ElementXML blockNode, AccessType accessType);
+		virtual ~InputBlock();
+
+	};
+
+	/*! -----------------------------------------------------------------------
+	 * \class OutputBlock
+	 * \brief This is a specific Block for Settings (from client to PLC)
+	 */
+	class OutputBlock : public PLCBlock
+	{
+
+	public:
+		OutputBlock(PLC* thePLC,ElementXML blockNode, AccessType accessType);
+		virtual ~OutputBlock();
+
+	};
+
+} // namespace
+
+#endif // _SILECS_BLOCK_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d4773eb52c16d1fb381327cbb42aca53b7d035f3
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.cpp
@@ -0,0 +1,505 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include "PLCRegister.h"
+
+namespace Silecs
+{
+
+	PLCRegister::PLCRegister(Device* theDevice,const boost::shared_ptr<ElementXML>& registerNode) : Register(theDevice, registerNode) {}
+	PLCRegister::~PLCRegister() {}
+
+	BigEndianRegister::BigEndianRegister(Device* theDevice,const boost::shared_ptr<ElementXML>& registerNode) : PLCRegister(theDevice, registerNode)  {}
+    BigEndianRegister::~BigEndianRegister() {}
+
+	LittleEndianRegister::LittleEndianRegister(Device* theDevice,const boost::shared_ptr<ElementXML>& registerNode) : PLCRegister(theDevice, registerNode) {}
+	LittleEndianRegister::~LittleEndianRegister() {}
+
+	S7Register::S7Register(Device* theDevice,const boost::shared_ptr<ElementXML>& registerNode) : BigEndianRegister(theDevice, registerNode) {}
+    S7Register::~S7Register() {}
+
+	UnityRegister::UnityRegister(Device* theDevice,const boost::shared_ptr<ElementXML>& registerNode) : LittleEndianRegister(theDevice, registerNode) {}
+	UnityRegister::~UnityRegister() {}
+
+	TwinCATRegister::TwinCATRegister(Device* theDevice,const boost::shared_ptr<ElementXML>& registerNode) : UnityRegister(theDevice, registerNode) {}
+	TwinCATRegister::~TwinCATRegister() {}
+
+
+    /// Generic methods for byte-swapping ----------------------------------------------
+    uint16_t PLCRegister::_swaps(uint16_t s)
+    {
+        return ( ((s & 0x00ff) << 8) + ((s & 0xff00) >> 8) );
+    }
+
+    uint32_t PLCRegister::_swapl(uint32_t l)
+    {
+        uint32_t ul;
+        void *pl = &l;
+        void *pul = &ul;
+        *((uint16_t *)pul)   = _swaps(*((uint16_t *)pl+1));
+        *((uint16_t *)pul+1) = _swaps(*((uint16_t *)pl));
+        return(ul);
+    }
+
+    //Beckhoff/BC9020 PLC uses the same memory swapping than Unity PLCs except for float32 data
+    //This method is used to specialized the 32bits data swapping inherited from the UnityRegister class.
+    uint32_t TwinCATRegister::_swapl(uint32_t l)
+    {
+        uint32_t ul;
+        void *pl = &l;
+        void *pul = &ul;
+
+        if ( (getPLC()->getModel() == "BC9020") && (getFormat() == Silecs::Float32) )
+        {  //Particular case for BC9020 PLC:  swap only bytes together (not the words)
+            *((uint16_t *)pul)   = _swaps(*((uint16_t *)pl));
+            *((uint16_t *)pul+1) = _swaps(*((uint16_t *)pl+1));
+        }
+        else
+        { //Same as base-class methods for other controllers
+            ul = PLCRegister::_swapl(l);
+        }
+        return(ul);
+    }
+
+    float PLCRegister::_swapf(float f)
+    {
+        uint32_t l;
+        void *pl = &l;
+        void *pf = &f;
+        l = _swapl(*((uint32_t *)pf));
+        return(*((float *)pl));
+    }
+
+    double PLCRegister::_swapd(double d)
+    {
+        uint64_t ld;
+        void *pd = &d;
+        void *pld = &ld;
+        *((uint32_t *)pld)   = _swapl(*((uint32_t *)pd+1));
+        *((uint32_t *)pld+1) = _swapl(*((uint32_t *)pd));
+        return(*((double *)pld));
+    }
+
+
+    // BIG-ENDIANNESS  ---------------------------------------------------------------------------
+    void BigEndianRegister::swapBytesNToH(unsigned char *data, unsigned long size)
+    {
+        switch(size)
+        {
+            case 1:
+                //for CHAR and BYTE, nothing to do in that case.
+                break;
+            case 2: {
+                //WORD or INT type
+                uint16_t s = ntohs(*(uint16_t *)data);
+                //no swap, just convert to network format
+                *(uint16_t *)data = s;
+                break;
+            }
+            case 4: {
+                //DWORD, DINT or REAL type
+                uint32_t l = ntohl(*(uint32_t *)data);
+                //no swap, just convert to network format
+                *(uint32_t *)data = l;
+                break;
+            }
+    #ifdef __x86_64__
+            case 8: {
+                //uInt64, Int64 or Float64
+                //direct conversion from little-endian to host exists only from SLC6 version
+                uint64_t l64 = le64toh(*(uint64_t *)data);
+                *(uint64_t *)data = l64;
+                break;
+            }
+    #endif
+            default:
+                //nothing to do unknown type
+                break;
+        }
+    }
+
+    void BigEndianRegister::swapBytesHToN(unsigned char *data, unsigned long size)
+    {
+        switch(size)
+        {
+            case 1:
+                //for CHAR and BYTE, nothing to do in that case.
+                break;
+            case 2: {
+                //WORD or INT type
+                uint16_t s = htons(*(uint16_t *)data);
+                //no swap, just convert to network format
+                *(uint16_t *)data = s;
+                break;
+            }
+            case 4: {
+                //DWORD, DINT or REAL type
+                uint32_t l = htonl(*(uint32_t *)data);
+                //no swap, just convert to network format
+                *(uint32_t *)data = l;
+                break;
+            }
+    #ifdef __x86_64__
+            case 8: {
+                //uInt64, Int64 or Float64
+                //direct conversion from host to little-endian exists only from SLC6 version
+                uint64_t l64 = htole64(*(uint64_t *)data);
+                *(uint64_t *)data = l64;
+                break;
+            }
+    #endif
+            default:
+                //nothing to do unknown type
+                break;
+          }
+    }
+
+    // LITTLE-ENDIANNESS  ---------------------------------------------------------------------------
+    void LittleEndianRegister::swapBytesNToH(unsigned char *data, unsigned long size)
+    {
+        switch(size)
+        {
+            case 1:
+                //for CHAR and BYTE, nothing to do in that case.
+                break;
+            case 2: {
+                //WORD or INT type
+                uint16_t s = ntohs(*(uint16_t *)data);
+                  //convert to network format and word swapping
+                  *(uint16_t *)data = _swaps(s);
+                break;
+            }
+            case 4: {
+                //DWORD, DINT or REAL type
+                uint32_t l = ntohl(*(uint32_t *)data);
+                //convert to network format and word swapping
+                *(uint32_t *)data = _swapl(l);
+                break;
+            }
+            #ifdef __x86_64__
+            case 8: {
+                //uInt64, Int64 or Float64
+                //direct conversion from big-endian to host exists only from SLC6 version
+                uint64_t l64 = be64toh(*(uint64_t *)data);
+                *(uint64_t *)data = l64;
+                break;
+            }
+            #endif
+            default:
+                //nothing to do unknown type
+                break;
+            }
+    }
+
+    void LittleEndianRegister::swapBytesHToN(unsigned char *data, unsigned long size)
+    {
+        switch(size)
+        {
+            case 1:
+                //for CHAR and BYTE, nothing to do in that case.
+                break;
+            case 2: {
+                //WORD or INT type
+                uint16_t s = htons(*(uint16_t *)data);
+                //convert to network format and word swapping
+                *(uint16_t *)data = _swaps(s);
+                break;
+            }
+            case 4: {
+                //DWORD, DINT or REAL type
+                uint32_t l = htonl(*(uint32_t *)data);
+                //convert to network format and word swapping
+                *(uint32_t *)data = _swapl(l);
+                break;
+            }
+    #ifdef __x86_64__
+            case 8: {
+                //uInt64, Int64 or Float64
+                //direct conversion from host to big-endian exists only from SLC6 version
+                uint64_t l64 = htobe64(*(uint64_t *)data);
+                *(uint64_t *)data = l64;
+                break;
+            }
+    #endif
+            default:
+                //nothing to do unknown type
+                break;
+          }
+    }
+
+
+    // ----------------------------------------------------------------------------------------
+	void PLCRegister::importValue(void* pBuffer, timeval ts)
+	{
+		//Compute the register address within the block: block-address + register-offset
+		unsigned char* pDataBase = ((unsigned char*)pBuffer) + address_;
+		unsigned char* pData = pDataBase;
+
+		if ((format_ == Int8) || (format_ == uInt8))
+		{
+			//Some PLC use more than 1 byte for this format (exp.: SCHNEIDER aligns char on 16bits)
+		    unsigned int step = memSize_ / dimension1_ / dimension2_ / size_;
+		    /*TODO:
+			 * Optimization a tester: utiliser un memcpy si (step == 1) au lieu du for
+			 * (idem pour l'export)
+			 */
+		    for (unsigned int i=0; i<(dimension1_); i++)
+            {
+                for (unsigned int j=0; j<(dimension2_); j++)    // works also for 1d, in this case j is always 0 and points to the element on the array
+                {
+                    // compact the array by removing the alignment added
+                    ((unsigned char*)pRecvValue_)[(i*dimension2_)+j] = pData[(i*step*dimension2_)+j];
+                }
+            }
+		}
+		else
+		{
+			if (format_ != Date)
+			{ 	//Short, uShort, Long, uLong, Float
+			    for (unsigned int i=0; i<(dimension1_*dimension2_); i++)
+				{
+				    swapBytesNToH(pData, size_);
+				    pData += size_;
+				}
+
+				//The buffer is correctly aligned and swapped now. We can transfer the value to the register cell.
+				memcpy(pRecvValue_, (void*)pDataBase, (size_*dimension1_*dimension2_));
+			}
+			else
+			{
+			    //Date&Time
+                unsigned long dtSize = size_; //Most of controllers use 64bits coding for DT type
+                                             //Beckhoff controller uses 32bits (see below)
+
+			    for (unsigned int i=0; i<dimension1_; i++)
+                {
+                    for (unsigned int j=0; j<dimension2_; j++)    // works also for 1d, in this case j is always 0 and points to the element on the array
+                    {
+                        switch(getPLC()->getBrandID())
+                        {
+                            case Siemens:
+                                ((double *)pRecvValue_)[i*dimension2_+j] = IeRfcGetTime(pData);
+                                break;
+                            case Schneider:
+                            case Digi:
+                                ((double *)pRecvValue_)[i*dimension2_+j] = IeMdbGetTime(pData);
+                                break;
+                            case Ni:
+                                //TODO
+                                break;
+                            case Beckhoff:
+                                //Beckhoff controller implement the standard EPOCH on 32bits word
+                                dtSize = sizeof(uint32_t);
+                                uint32_t *timeVal = (uint32_t *)pData;
+                                swapBytesNToH((unsigned char *)&(timeVal[0]), sizeof(uint32_t));
+                                ((double *)pRecvValue_)[i*dimension2_+j] = static_cast<double>(timeVal[0]);
+                                break;
+                        }
+                        pData += dtSize;
+                    }
+                }
+			}
+		}
+
+		//Set the register time-stamp
+		tod_ = ts;
+
+		//DATA topic makes sense with RECV one
+		if (RECV & Log::topics_) LOG(DATA) << theDevice_->getPLC()->getName() << "/" << theDevice_->getLabel() << "/" << getName() << ", len: " << getLength() << ", dim1: " << getDimension1() << ", dim2: " << getDimension2() << ", ts: " << getTimeStampAsString() <<  ", value: " << getValAsByteString(pRecvValue_, 10);
+	}
+
+
+	void PLCRegister::exportValue(void* pBuffer)
+	{
+		//DATA topic makes sense with SEND one
+		if (SEND & Log::topics_) LOG(DATA) << theDevice_->getPLC()->getName() << "/" << theDevice_->getLabel() << "/" << getName() << ", len: " << getLength() << ", dim1: " << getDimension1() << ", dim2: " << getDimension2() <<  ", value: " << getValAsByteString(pSendValue_, 10);
+
+		//Compute the register address within the block: block-address + register-offset
+		unsigned char* pData = ((unsigned char*)pBuffer) + address_;
+
+		if ((format_ == Int8) || (format_ == uInt8))
+		{
+			//Some PLC use more than 1 byte for this format (exp.: SCHNEIDER aligns char on 16bits)
+			unsigned int step = memSize_ / dimension1_ / dimension2_ / size_;
+
+			for (unsigned int i=0; i<dimension1_; i++)
+            {
+                for (unsigned int j=0; j<(dimension2_); j++)
+                {
+                    // expand the array by adding required space
+                    pData[(i*step*dimension2_)+j] = ((unsigned char*)pSendValue_)[(i*dimension2_)+j];
+                }
+            }
+		}
+		else
+		{
+			if (format_ != Date)
+			{
+				//Short, uShort, Long, uLong, Float
+				//Transfert the value of the register cell to the buffer
+				memcpy((void*)pData, pSendValue_, (size_*dimension1_*dimension2_));
+
+				for (unsigned int i=0; i<(dimension1_*dimension2_); i++)
+				{
+				    swapBytesHToN(pData, size_);
+				    pData += size_;
+				}
+			}
+			else
+			{ 	//Date&Time
+			    unsigned long dtSize = size_; //Most of controllers use 64bits coding for DT type
+			                                 //Beckhoff controller uses 32bits (see below)
+
+                for (unsigned int i=0; i<(dimension1_*dimension2_); i++)
+                {
+                    time_t epoch = static_cast<time_t>((double)((double *)pSendValue_)[i]);
+                    switch(getPLC()->getBrandID())
+                    {
+                        case Siemens:
+                            IeRfcSetTime(pData, epoch);
+                            break;
+                        case Schneider:
+                        case Digi:
+                            IeMdbSetTime(pData, epoch);
+                            break;
+                        case Ni:
+                            //TODO
+                            break;
+                        case Beckhoff:
+                            //Beckhoff controller implement the standard EPOCH on 32bits word
+                            dtSize = sizeof(uint32_t);
+                            uint32_t *timeVal = (uint32_t *)pData;
+                            timeVal[0] = static_cast<uint32_t>(epoch);
+                            swapBytesHToN((unsigned char *)&(timeVal[0]), sizeof(uint32_t));
+                            break;
+                    }
+                    pData += dtSize;
+                }
+			}
+		}
+	}
+
+	void PLCRegister::copyValue()
+	{
+	    //Transfer the value of the recvBuffer to to the sendBuffer
+	    if (format_ == String)
+        {
+	        std::string** pRecvStringValue_ = static_cast<std::string**>(pRecvValue_);
+	        std::string** pSendStringValue_ = static_cast<std::string**>(pSendValue_);
+	        for(unsigned int i=0; i<(dimension1_*dimension2_); i++)
+            {
+	            *(pSendStringValue_[i]) = *(pRecvStringValue_[i]);
+            }
+        }
+	    else
+	    {
+	        memcpy(pSendValue_, pRecvValue_, (size_*dimension1_*dimension2_));
+	    }
+	}
+
+
+    // S7 METHODS -------------------------------------------------------------------------------
+	void S7Register::importString(void* pBuffer, timeval ts)
+	{
+        // Compute the register address within the block: block-address + register-offset
+        unsigned char* pDataBase = ((unsigned char*)pBuffer) + address_;
+        std::string** pRecvStringValue_ = static_cast<std::string**>(pRecvValue_);
+
+        //Some PLC use more than 1 byte for this format (exp.: SIEMENS aligns string on 16bits address)
+        unsigned int step = memSize_ / dimension1_ / dimension2_ / size_;
+
+        // for each string of the single/double array -
+        for (unsigned long i=0; i<(dimension1_*dimension2_); i++) // scalar has dim1=dim2=1
+        {    unsigned char* pData = &(pDataBase[i*step]);
+            pRecvStringValue_[i]->assign((const char*)&(pData[2]), (size_t)pData[1]);
+        }
+        //Set the register time-stamp
+        tod_ = ts;
+
+        //DATA topic makes sense with RECV one
+        if (RECV & Log::topics_) LOG(DATA) << theDevice_->getPLC()->getName() << "/" << theDevice_->getLabel() << "/" << getName() << ", len: " << getLength() << ", dim1: " << getDimension1() << ", dim2: " << getDimension2() << ", ts: " << getTimeStampAsString() <<  ", value: " << getValAsByteString(pRecvValue_, 10);
+	}
+
+	void S7Register::exportString(void* pBuffer)
+	{
+        //DATA topic makes sense with SEND one
+        if (SEND & Log::topics_) LOG(DATA) << theDevice_->getPLC()->getName() << "/" << theDevice_->getLabel() << "/" << getName() << ", len: " << getLength() << ", dim1: " << getDimension1() << ", dim2: " << getDimension2() <<  ", value: " << getValAsByteString(pSendValue_, 10);
+
+        //Compute the register address within the block: block-address + register-offset
+        unsigned char* pData = ((unsigned char*)pBuffer) + address_;
+        std::string** pSendStringValue_ = static_cast<std::string**>(pSendValue_);
+
+        //Some PLC use more than 1 byte for this format (exp.: SIEMENS aligns string on 16bits address)
+        unsigned int step = memSize_ / dimension1_ / dimension2_ / size_;
+
+        // for each string of the single/double array -
+        for (unsigned long i=0; i<dimension1_*dimension2_; i++)  // scalar has dim1=dim2=1
+        {   //Current size of the sent string should not exceed the register string max length
+            std::string sendStringValue = *(pSendStringValue_[i]);
+            if (sendStringValue.size() > length_) sendStringValue = sendStringValue.substr(0, length_);
+            // S7 requires that the first two bytes of string are reserved for length and max length of string
+            pData[(i*step)+0] = (unsigned char)length_ & 0XFF;    // convert to byte (max length is 254 (+2) = 1 byte)
+            pData[(i*step)+1] = (unsigned char)sendStringValue.size() & 0XFF;
+            memcpy((void *)&(pData[(i*step)+2]), (void *)sendStringValue.c_str(), sendStringValue.size());
+        }
+	}
+
+    // UNITY METHODS -----------------------------------------------------------------------------------
+	// TwinCAT object inherit from the same methods than UNITY.
+	void UnityRegister::importString(void* pBuffer, timeval ts)
+    {
+        // Compute the register address within the block: block-address + register-offset
+        unsigned char* pDataBase = ((unsigned char*)pBuffer) + address_;
+        std::string** pRecvStringValue_ = static_cast<std::string**>(pRecvValue_);
+
+        //Some PLC use more than 1 byte for this format (exp.: SCHNEIDER aligns char on 16bits)
+        unsigned int step = memSize_ / dimension1_ / dimension2_ / size_;
+
+        // for each string of the single/double array -
+        for (unsigned long i=0; i<(dimension1_*dimension2_); i++) // scalar has dim1=dim2=1
+        {   unsigned char* pData = &(pDataBase[i*step]);
+            size_t strSize =  min((size_t)length_, strlen((const char*)pData));
+            pRecvStringValue_[i]->assign((const char*)pData, strSize);
+        }
+        tod_ = ts;
+
+        //DATA topic makes sense with RECV one
+        if (RECV & Log::topics_) LOG(DATA) << theDevice_->getPLC()->getName() << "/" << theDevice_->getLabel() << "/" << getName() << ", len: " << getLength() << ", dim1: " << getDimension1() << ", dim2: " << getDimension2() << ", ts: " << getTimeStampAsString() <<  ", value: " << getValAsByteString(pRecvValue_, 10);
+    }
+
+	void UnityRegister::exportString(void* pBuffer)
+	{
+        //DATA topic makes sense with SEND one
+        if (SEND & Log::topics_) LOG(DATA) << theDevice_->getPLC()->getName() << "/" << theDevice_->getLabel() << "/" << getName() << ", len: " << getLength() << ", dim1: " << getDimension1() << ", dim2: " << getDimension2() <<  ", value: " << getValAsByteString(pSendValue_, 10);
+
+        //Compute the register address within the block: block-address + register-offset
+        unsigned char* pData = ((unsigned char*)pBuffer) + address_;
+        std::string** pSendStringValue_ = static_cast<std::string**>(pSendValue_);
+
+        // Some PLC use more than 1 byte for this format (exp.: SCHNEIDER aligns char on 16bits)
+        unsigned int step = memSize_ / dimension1_ / dimension2_ / size_;
+
+        // for each string of the single/double array -
+        for (unsigned long i=0; i<dimension1_*dimension2_; i++)  // scalar has dim1=dim2=1
+        {   //Current size of the sent string should not exceed the register string max length
+            size_t strSize = pSendStringValue_[i]->size();
+            std::string sendStringValue = pSendStringValue_[i]->substr(0, min((size_t)length_, strSize));
+            bzero((void *)&(pData[i*step]), step);  //TwinCAT string requires '\0' terminator (mem-size of the string (~step) has been properly dimensioned in the mapping).
+            memcpy((void *)&(pData[i*step]), (void *)sendStringValue.c_str(), sendStringValue.size());
+        }
+	}
+
+} // namespace
+
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.h
new file mode 100644
index 0000000000000000000000000000000000000000..86dc939d98da0740750da785727f376cde7476a3
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/PLCRegister.h
@@ -0,0 +1,195 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _SILECS_PLC_REGISTER_H_
+#define _SILECS_PLC_REGISTER_H_
+
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/utility/XMLParser.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/equipment/SilecsDevice.h>
+#include <silecs-communication/interface/equipment/SilecsRegister.h>
+#include <silecs-communication/interface/utility/SilecsException.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <silecs-communication/interface/utility/StringUtilities.h>
+#include <silecs-communication/protocol/core/silecs.h>
+
+#ifdef __x86_64__
+#include <endian.h>
+#endif
+
+namespace Silecs
+{
+	/// @cond
+	class PLCRegister : public Register
+	{
+		private:
+
+		protected:
+			PLCRegister(Device* theDevice,const boost::shared_ptr<ElementXML>& registerNode);
+			virtual ~PLCRegister();
+
+			// export register extraction methods
+			friend class PLC;
+			friend class Device;
+
+			/*!
+			 * \fn importValue
+			 * \brief Used to convert and transfered data from the data-block receiver to the register value
+			 * Overloads the virtual method inherited from the class SilecsRegister.
+			 * \param pBuffer points the data-block buffer
+			 * \param ts is the time-of-day to time-stamp the register
+			 */
+			void importValue(void* pBuffer, timeval ts);
+
+			/*!
+			 * \fn exportValue
+			 * \brief Used to transfer the register value to the data data-block to be sent
+			 * Overloads the virtual method inherited from the class SilecsRegister.
+			 * \param pBuffer points the data-block buffer
+			 */
+			void exportValue(void* pBuffer);
+
+			/*!
+			 * \fn copyValue
+			 * \brief Copies the register content from the input buffer the output buffer.
+			 * Overloads the virtual method inherited from the class SilecsRegister.
+			 * This method is used for Retentive InOut registers synchronization.
+			 */
+			void copyValue();
+
+			/// Generic methods for byte-swapping ---------------------------------
+			virtual  uint16_t _swaps(uint16_t s);
+			virtual uint32_t _swapl(uint32_t l);
+			virtual float _swapf(float f);
+			virtual double _swapd(double d);
+
+			virtual void swapBytesNToH(unsigned char *data, unsigned long size) = 0;
+			virtual void swapBytesHToN(unsigned char *data, unsigned long size) = 0;
+
+	};
+
+
+	/*!
+	 * \class BigEndianRegister
+	 * \brief Specific register using Big-endian memory convention
+	 */
+	class BigEndianRegister : public PLCRegister
+	{
+
+	public:
+		BigEndianRegister(Silecs::Device* theDevice,const boost::shared_ptr<ElementXML>& registerNode);
+		virtual ~BigEndianRegister();
+
+	protected:
+		void swapBytesNToH(unsigned char *data, unsigned long size);
+		void swapBytesHToN(unsigned char *data, unsigned long size);
+
+	};
+
+
+	/*!
+	 * \class LittleEndianRegister
+	 * \brief Specific register using Little-endian memory convention
+	 */
+	class LittleEndianRegister : public PLCRegister
+	{
+
+	public:
+		LittleEndianRegister(Silecs::Device* theDevice,const boost::shared_ptr<ElementXML>& registerNode);
+		virtual ~LittleEndianRegister();
+
+    protected:
+		void swapBytesNToH(unsigned char *data, unsigned long size);
+		void swapBytesHToN(unsigned char *data, unsigned long size);
+
+	};
+	
+	/*!
+	 * \class S7Register
+	 * \brief Specific register for S7 hardware
+	 */
+	class S7Register : public BigEndianRegister
+	{
+	    public:
+            S7Register(Silecs::Device* theDevice,const boost::shared_ptr<ElementXML>& registerNode);
+            virtual ~S7Register();
+
+	    private:
+            /*!
+             * \fn importString
+             * \brief Used to convert and transfer strings from the data-block receiver to the register value
+             * \param pBuffer points the data-block buffer
+             * \param ts is the time-of-day to timestamp the register
+             */
+            void importString(void* pBuffer, timeval ts);
+
+            /*!
+             * \fn exportString
+             * \brief Used to transfer the register value to the data-block to be sent
+             * \param pBuffer points the data-block buffer
+             */
+            void exportString(void* pBuffer);
+
+	};
+
+	/*!
+	 * \class UnityRegister
+	 * \brief Specific register for Schneider hardware
+	 */
+	class UnityRegister : public LittleEndianRegister
+	{
+	    public:
+	        UnityRegister(Silecs::Device* theDevice,const boost::shared_ptr<ElementXML>& registerNode);
+	        virtual ~UnityRegister();
+
+	    private:
+	        /*!
+             * \fn importString
+             * \brief Used to convert and transfer strings from the data-block receiver to the register value
+             * \param pBuffer points the data-block buffer
+             * \param ts is the time-of-day to timestamp the register
+             */
+	        void importString(void* pBuffer, timeval ts);
+
+            /*!
+             * \fn exportString
+             * \brief Used to transfer the register value to the data-block to be sent
+             * \param pBuffer points the data-block buffer
+             */
+	        void exportString(void* pBuffer);
+
+	};
+
+    /*!
+     * \class TwinCATRegister
+     * \brief Beckhoff BCxx/CXxx PLC use the same memory swapping than Unity PLCs except for float32 data
+     * This class is used to specialized the 32bits data swapping inherited from the UnityRegister class.
+     * It overwrites the swapl() method responsible for 32bits data swapping.
+     */
+    class TwinCATRegister : public UnityRegister
+    {
+        public:
+	        TwinCATRegister(Silecs::Device* theDevice,const boost::shared_ptr<ElementXML>& registerNode);
+            virtual ~TwinCATRegister();
+
+        protected:
+            //Dedicated method for specific 64bit swapping (other come from the base-class)
+            uint32_t _swapl(uint32_t l);
+    };
+	/// @endcond
+
+}
+#endif // _SILECS_PLC_REGISTER_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsBlock.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsBlock.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bb4ee710446c48b2db3dd6c1c178dcefc5f6d3dc
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsBlock.cpp
@@ -0,0 +1,114 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/utility/Thread.h>
+#include <silecs-communication/interface/utility/XMLParser.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/equipment/SilecsBlock.h>
+#include <silecs-communication/interface/equipment/SilecsRegister.h>
+#include <silecs-communication/interface/core/SilecsAction.h>
+#include <silecs-communication/interface/core/WrapperAction.h>
+#include <silecs-communication/interface/utility/SilecsException.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <silecs-communication/interface/utility/StringUtilities.h>
+
+namespace Silecs
+{
+
+	Block::Block(PLC* thePLC, ElementXML blockNode, AccessType accessType) :
+			thePLC_ (thePLC), hasMaster_(false), hasSlave_(false)
+	{
+		std::string designName = blockNode.getAttribute("name");
+
+        name_ = designName;
+		StringUtilities::fromString(size_,blockNode.getAttribute("size"));
+		StringUtilities::fromString(memSize_,blockNode.getAttribute("mem-size"));
+		StringUtilities::fromString(address_,blockNode.getAttribute("address"));
+
+        resetCustomAttributes(); //by default custom-size of the block is the maximum size
+
+        /*In case of InOut block we will instantiate 2 different blocks (input/output)
+         * and the accessType is given by the caller.
+		*/
+        accessType_ = accessType;
+
+        // Adjust the synchro-type of the block relying on its own registers
+        // . hasMaster if the block contains 1 MASTER register at least
+        // . hasSlave if the block contains 1 SLAVE register at least
+        // can be a mix or none if only Volatile registers
+		std::vector< boost::shared_ptr<ElementXML> > registerNodes = blockNode.childList_;
+		std::vector< boost::shared_ptr<ElementXML> >::const_iterator registerIter;
+		for(registerIter = registerNodes.begin(); registerIter != registerNodes.end(); registerIter++)
+		{
+			std::string synchro = (*registerIter)->getAttribute("synchro");
+			if (!hasMaster_ && Service::whichSynchroType(synchro) == Master)
+				hasMaster_ = true;
+			if (!hasSlave_ && Service::whichSynchroType(synchro) == Slave)
+				hasSlave_ = true;
+		}
+	}
+
+	Block::~Block()
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Block (delete): " << name_;
+
+		if (pAction_ != NULL) delete pAction_;
+		if (pTask_ != NULL) delete pTask_;
+	}
+
+
+	AccessType Block::whichAccessType(std::string type)
+	{
+		StringUtilities::toLower(type);
+		if (type == "write-only") return Output;
+		else if (type == "read-only") return Input;
+		else if (type == "read-write") return InOut;
+		else throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_ACCESS_TYPE, type);
+	}
+
+
+	std::string Block::whichAccessType(AccessType type)
+	{
+		switch(type)
+		{
+		case Output: return "WRITE-ONLY"; break;
+		case Input: return "READ-ONLY"; break;
+		case InOut: return "READ-WRITE"; break;
+		default: throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_ACCESS_TYPE, StringUtilities::toString(type));
+		}
+	}
+
+    void Block::setCustomAttributes(const unsigned long customAddress, const unsigned long customOffset, const unsigned long customSize)
+    {
+        //user wants to limit the size of data to be sent/receive - check that it is lower than design allocation size
+        if (customSize > memSize_)
+            throw SilecsException(__FILE__, __LINE__, PARAM_EXCEEDED_BLOCK_SIZE, StringUtilities::toString(memSize_));
+
+        customAddress_      = customAddress;
+        customOffset_       = customOffset;
+        customSize_         = customSize;
+        customAttributes_   = true;
+        LOG(DEBUG) << "Set custom attributes of block: " << name_ << ", memSize: " << memSize_ << ", customSize: " << customSize << ", customAddress: " << customAddress << ", customOffset: " << customOffset;
+    }
+
+    void Block::resetCustomAttributes()
+    {
+        customAttributes_ = false;
+        LOG(DEBUG) << "Reset custom attributes of block: " << name_;
+    }
+
+
+} // namespace
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsBlock.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsBlock.h
new file mode 100644
index 0000000000000000000000000000000000000000..01dbdace83662e1df0d54febf71c68eb814d09ce
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsBlock.h
@@ -0,0 +1,122 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _SILECS_BLOCK_H_
+#define _SILECS_BLOCK_H_
+
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/utility/Thread.h>
+
+#include <boost/shared_ptr.hpp>
+
+namespace Silecs
+{
+	class Action;
+	class WrapperAction;
+	class PLC;
+	class ElementXML;
+
+	/*! -----------------------------------------------------------------------
+	 * \class Block
+	 * \brief This object maintains a reference of all the device registers.
+	 * It is responsible to serialize, de-serialize data for the network transfer
+	 * (alignment, data swapping, ..). It can be used also to trig the communication
+	 * for a particular device (make sense for DEVICE-MODE only) if needed.
+	 */
+	class Block
+	{
+
+	public:
+		Block(PLC* thePLC, ElementXML blockNode, AccessType accessType);
+		virtual ~Block();
+
+        /*!
+         * \fn whichAccessType
+         * \return the enumeration value of the given access-type string
+         */
+		static AccessType whichAccessType(std::string type);
+		static std::string whichAccessType(AccessType type);
+
+		inline bool hasInputAccess() { return (accessType_ != Output); }
+		inline bool hasOutputAccess() { return (accessType_ != Input); }
+
+		inline PLC* getPLC() { return thePLC_; }
+		inline std::string& getName() { return name_; }
+		inline AccessType getAccessType() { return (accessType_); }
+		inline unsigned long& getAddress() { return address_; }
+		inline unsigned long& getMemSize() { return memSize_; }
+		inline Task<WrapperAction>* getTask() { return pTask_; }
+		inline void* getBuffer() { return pBuffer_; }
+		inline bool hasMasterRegister() { return hasMaster_; }
+		inline bool hasSlaveRegister() { return hasSlave_; }
+
+        /// @cond
+	    void setCustomAttributes(const unsigned long customAddress, const unsigned long customOffset, const unsigned long customSize);
+	    void resetCustomAttributes();
+        inline bool& withCustomAttributes() { return customAttributes_; }
+        inline unsigned long& getCustomAddress() { return customAddress_; }
+        inline unsigned long& getCustomOffset() { return customOffset_; }
+        inline unsigned long& getCustomSize() { return customSize_; }
+        /// @endcond
+
+	protected:
+		friend class Device;
+
+		/// Parent PLC reference of that device
+		PLC* thePLC_;
+
+		/// Block attributes
+		std::string name_;
+
+		/// Block access-type: Input, Output or InOut
+		AccessType accessType_;
+
+		/// Block size
+		unsigned long size_;
+
+		/// Block memory size (including alignments)
+		unsigned long memSize_;
+
+        /* Block custom attributes
+         * Can be used to limit dynamically the size of sent/received data.
+         * Interesting for specific application. (e.g. Cryo) which design maximum size of the block and adjust
+         * the real data size at runtime (using PLC::setCustomBlockAttributes() method.
+         * !! This mechanism can be used only with device access mode (DEVICE-MODE or BLOCK-MODE from device)
+		*/
+        // Flag used to enable/disable use of custom attributes
+        bool customAttributes_;
+        unsigned long customAddress_;
+        unsigned long customOffset_;
+        unsigned long customSize_;
+
+		unsigned long address_;
+
+		/// Related PLC task to this data-block
+		Action* pAction_;
+		Task<WrapperAction>* pTask_;
+
+		// Send/Receive data buffer
+		void *pBuffer_;
+
+		/// True if the block contains 1 MASTER and/or 1 Slave register at least
+		/// MASTER en SLAVE registers can be mixed in the same block.
+		/// Only Volatile (NONE) ==> both are false
+		bool hasMaster_;
+		bool hasSlave_;
+	};
+
+} // namespace
+
+#endif // _SILECS_BLOCK_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsCluster.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsCluster.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..843649fbe94e791c6f923558929c0f26960dd911
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsCluster.cpp
@@ -0,0 +1,250 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/equipment/SilecsDevice.h>
+#include <silecs-communication/interface/equipment/SilecsBlock.h>
+#include <silecs-communication/interface/utility/SilecsException.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <silecs-communication/protocol/core/silecs.h>
+
+namespace Silecs
+{
+    bool ClusterConfig::getSharedConnection() const
+    {
+        return sharedConnection;
+    }
+
+    void ClusterConfig::setSharedConnection(bool sharedConnectionFlag)
+    {
+        sharedConnection = sharedConnectionFlag;
+    }
+
+
+	Cluster::Cluster(const std::string className, const std::string classVersion) : className_ (className), classVersion_ (classVersion)
+	{
+		char hostName[128];
+	    if (gethostname(hostName, 128) == -1)
+			throw SilecsException(__FILE__, __LINE__, errno, strerror(errno));
+
+	    //store the hostname by removing the domain-name (.cern.ch) if any.
+	    hostName_ = std::string(hostName);
+	    removeDomainName(hostName_);
+
+	    //Default run-time configuration setup
+	    configuration.sharedConnection = false;  //Do not shared connection with other clusters by default
+
+		LOG((ALLOC|DIAG)) << "CLUSTER (create): " << className_ << "/" << classVersion_;
+	}
+
+	Cluster::~Cluster()
+	{
+		LOG(ALLOC) << "CLUSTER (delete): " << className_ << "/" << classVersion_;
+
+		// Remove the PLCs instances related to this Cluster (hostName_/className_)
+		plcMapType::iterator plcMapIter;
+		for(plcMapIter = plcMap_.begin(); plcMapIter != plcMap_.end(); ++plcMapIter)
+		{ delete plcMapIter->second;
+		}
+	    plcMap_.clear();
+	    IPAddrMap_.clear(); //this map refer the same PLC object (not necessary to delete them)
+	}
+
+	void Cluster::removeDomainName(std::string& hostName)
+	{   size_t domain = hostName.find_first_of('.');
+		if (domain != std::string::npos) hostName.erase(domain);
+	}
+
+	bool Cluster::getHostNameByAddress(const std::string IPAddress, std::string& hostName)
+	{
+		struct hostent *he = NULL;
+		struct in_addr ipv4addr;
+
+		if (inet_pton(AF_INET, IPAddress.c_str(), &ipv4addr) == 1)
+		{   he = gethostbyaddr(&ipv4addr, sizeof ipv4addr, AF_INET);
+		}
+
+		if (he)
+		{	hostName = std::string(he->h_name);
+			if (DEBUG & Log::topics_) LOG(COMM) << "getHostNameByAddress()  IPaddr: " << IPAddress << ", host-name: " << hostName;
+			return true;
+		}
+		return false;
+	}
+
+	bool Cluster::getAddressByHostName(const std::string hostName, std::string& IPAddress)
+	{
+		struct in_addr addr;
+		struct hostent *hp;
+		char *ipstr;
+
+		hp = gethostbyname(hostName.c_str());
+		if (hp)
+		{
+			addr.s_addr = *((unsigned long int *) hp->h_addr);
+			ipstr = inet_ntoa(addr);
+			IPAddress = std::string(ipstr);
+			if (DEBUG & Log::topics_) LOG(COMM) << "getAddressByHostName()  host-name: " <<  hostName << ", IPaddr: " << IPAddress;
+			return true;
+		}
+		return false;
+	}
+
+
+	Block* Cluster::getBlock(const std::string blockName, AccessType accessType)
+	{	// Retrieve the block from the first PLC (same for each of them)
+		return plcMap_.begin()->second->getBlock(blockName, accessType);
+	}
+
+
+	std::string Cluster::getBlockList(AccessType accessType)
+	{
+		std::string blockList = "";
+		//At first, check this class/version is already deployed (one PLC in the Cluster at least)
+		if (plcMap_.size() > 0)
+		{	// Retrieve the block-map from the first PLC (same for each of them)
+			blockMapType blockMap = plcMap_.begin()->second->getBlockMap();
+
+			blockMapType::iterator blockMapIter;
+			//Retrieve the name of each Block object of the Map that has selected access-type
+			for(blockMapIter = blockMap.begin(); blockMapIter != blockMap.end(); ++blockMapIter)
+			{	Block* pBlock = blockMapIter->second;
+				if (pBlock->getAccessType() == accessType)
+				{   std::string blockName = pBlock->getName();
+					//Do not append the same name twice (read-write Block has two instances)
+					if (blockList.find(blockName) == std::string::npos)
+					{	 //Do not insert blank before the first name
+						if (!blockList.empty()) blockList.append(" ");
+						blockList.append(blockName);
+					}
+				}
+			}
+		}
+		return blockList;
+	}
+
+	PLC* Cluster::getPLC(std::string plcID, string parameterFile)
+	{
+		//getPLC() supports IP and host-name addressing, but both are required to register the PLC object:
+		//Host-name will be used to manage related configuration documents.
+		//IP-addr is used to connect PLC in order to reduce the naming-server accesses.
+
+        //Force PLC hostname lower-case
+        StringUtilities::toLower(plcID);
+
+		//At first, check if the given ID is already registered in that Cluster (host-name or IP-address)
+		bool plcNotFound = false;
+		plcMapType::iterator iter = plcMap_.find(plcID);   //check the host-name map at first
+		if (iter == plcMap_.end())
+		{	//we didn't find PLC by host-name, try to find it by IP address
+			iter = IPAddrMap_.find(plcID);
+			plcNotFound = (iter == IPAddrMap_.end());
+		}
+
+		if (plcNotFound)
+		{
+			//Retrieve Host-name & IP-address of the PLC
+			std::string hostName;
+			std::string IPAddress;
+
+			if (isdigit(plcID[0]))
+			{   //user provided an IP address (start with digit character)
+				IPAddress = plcID;
+				if (!getHostNameByAddress(IPAddress, hostName))
+					throw SilecsException(__FILE__, __LINE__, PARAM_UNKNOWN_IP_ADDRESS, IPAddress);
+			}
+			else
+			{	//user provided an PLC network name (start with alpha-character)
+				hostName = plcID;
+				if (!getAddressByHostName(hostName, IPAddress))
+					throw SilecsException(__FILE__, __LINE__, PARAM_UNKNOWN_PLC_HOSTNAME, hostName);
+			}
+			removeDomainName(hostName); //remove ".cern.ch" if any
+
+			//Then create the new instance of the PLC
+
+			PLC* pPLC = new PLC(this, hostName, IPAddress, parameterFile);
+			plcMap_.insert(std::make_pair(hostName, pPLC));      //update host-name map
+			IPAddrMap_.insert(std::make_pair(IPAddress, pPLC));  //update IP address map
+			return pPLC;
+		}
+		return iter->second;
+	}
+
+
+	std::string Cluster::getHostName() { return hostName_; }
+	std::string Cluster::getClassName() { return className_; }
+	std::string Cluster::getClassVersion() { return classVersion_; }
+
+
+	std::string Cluster::getPLCList()
+	{
+		std::string PLCList = "";
+		plcMapType::iterator plcMapIter;
+		for(plcMapIter = plcMap_.begin(); plcMapIter != plcMap_.end(); ++plcMapIter)
+		{	if (!PLCList.empty()) PLCList.append(" ");
+			PLCList.append(plcMapIter->second->getName());
+		}
+		return PLCList;
+	}
+
+
+	const plcMapType& Cluster::getPLCMap() { return plcMap_; }
+
+
+	void Cluster::recv(std::string blockName)
+	{
+		//Asynchronous data receive
+		plcMapType::iterator plcMapIter;
+
+	    // Schedule task on each PLC using asynchronous call for parallelism
+		for(plcMapIter = plcMap_.begin(); plcMapIter != plcMap_.end(); ++plcMapIter)
+		{	plcMapIter->second->recvAsync(blockName);
+		}
+
+	    // then wait for the completion of each PLC thread (finally, maximum delay will be the longest one).
+		for(plcMapIter = plcMap_.begin(); plcMapIter != plcMap_.end(); ++plcMapIter)
+		{	plcMapIter->second->waitAsync();
+		}
+	}
+
+
+	void Cluster::send(std::string blockName)
+	{
+		//Asynchronous data send
+		plcMapType::iterator plcMapIter;
+
+	    // Schedule task on each PLC using asynchronous call for parallelism
+		for(plcMapIter = plcMap_.begin(); plcMapIter != plcMap_.end(); ++plcMapIter)
+		{	plcMapIter->second->sendAsync(blockName);
+		}
+
+	    // then wait for the completion of each PLC thread (finally, maximum delay will be the longest one).
+		for(plcMapIter = plcMap_.begin(); plcMapIter != plcMap_.end(); ++plcMapIter)
+		{	plcMapIter->second->waitAsync();
+		}
+	}
+
+	void Cluster::copyInToOut(const std::string blockName)
+	{
+		plcMapType::iterator plcMapIter;
+		for(plcMapIter = plcMap_.begin(); plcMapIter != plcMap_.end(); ++plcMapIter)
+			plcMapIter->second->copyInToOut(blockName);
+	}
+
+
+} // namespace
+
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsCluster.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsCluster.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d523ec054e269656fa419c3b3c6a20b68b98896
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsCluster.h
@@ -0,0 +1,202 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _SILECS_CLUSTER_H_
+#define _SILECS_CLUSTER_H_
+
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/utility/Thread.h>
+#include <map>
+#include <vector>
+
+namespace Silecs
+{
+	class Cluster;
+	class PLC;
+	class Device;
+	class Block;
+	class WrapperAction;
+
+	/// @cond
+	typedef std::map<std::string, std::vector<Task<WrapperAction> >* > taskMapType;
+	/// @endcond
+	typedef std::map<std::string, PLC*> plcMapType;
+
+    /*!
+     * \class ClusterConfig
+     * \brief Run-time configuration of the cluster.
+     * The default parameters of the cluster can be changed by setting the public Cluster::configuration structure.
+     * \param sharedConnection = true to share the same connection with other clusters deployed on that PLC.
+     * By default the sharedConnection of the cluster is false, and it uses a dedicated connection (2 channels: r/w)
+     * to communicate with the controller.
+     * Setting the configuration parameters must be done at first just after getting the cluster from the service.
+     */
+    class ClusterConfig
+    {
+    public:
+	    ClusterConfig():sharedConnection(false) {};
+	    ClusterConfig(bool sharedConnectionFlag):sharedConnection(sharedConnectionFlag) {};
+
+	    bool getSharedConnection() const;
+	    void setSharedConnection(bool sharedConnectionFlag);
+
+    //private: direct access of the variable is deprecated - should be private from next MAJOR release (use set/get only)
+        bool sharedConnection;  //default: not shared (1 dedicated connection (r+w) per class per PLC.
+    };
+
+    //deprecated type - User should use directly Silecs::ClusterConfig class
+    typedef ClusterConfig clusterConfigType;
+
+	/*!
+	 * \class Cluster
+	 * \brief An SILECS configuration is defined by a class name and a version number.
+	 * A Cluster is a tree that defines the set of components for a given configuration.
+	 * It's the root component of the tree that is used to instantiate each PLC object
+	 * in which is deployed the given class/version configuration.
+	 * Finally, the Cluster is the entry point to create and clean-up all the SILECS resources
+	 * within the process.
+	 * It can be used to trig the data-block exchanges for all PLCs of the Cluster at the same time.
+	 */
+	class Cluster
+	{
+
+	public:
+        /*!
+         * \brief Returns the network name of the client process host
+         * \return client host-name
+         */
+		std::string getHostName();
+
+		/*!
+         * \brief Returns the name of the SILECS class attached to the Cluster
+         * \return class name
+         */
+		std::string getClassName();
+
+		/*!
+         * \brief Returns the version number of the SILECS class attached to the Cluster
+         * \return class version
+         */
+		std::string getClassVersion();
+
+        /*!
+         * \brief Provides the list of Blocks defined in the corresponding Class/Version.
+         * At least one PLC must be attached (connected) to the Cluster, otherwise getBlockList()
+         * returns an empty string.
+         * \param select access-type of the blocks (Input, Output, InOut)
+         * \return String list (space separated value) of Blocks name that have selected access-type
+         */
+		std::string getBlockList(AccessType accessType);
+
+        /*!
+         * \brief Returns a PLC instance of the Cluster, by its name or IP-address
+         * Instantiates a new PLC object if required, on the first call.
+         * The related class/version must be deployed in that PLC (else generate an Exception).
+         * The PLC connection is disabled for the time being.
+         * \param plcID host-name or IP-address of the PLC
+         * \param parameterFile parameterFile whixch should be used to configure this PLC
+         * \return Reference of the PLC object
+         */
+		PLC* getPLC(std::string plcID, string parameterFile);
+
+        /*!
+         * \brief Provides the list of the PLCs attached to the Cluster (using getPLC() method)
+         * \return String list (space separated value) of PLCs name
+         */
+		std::string getPLCList();
+
+        /*!
+         * \brief Provides the  map of the PLC objects attached to the Cluster (using getPLC() method)
+         * \return PLC object map
+         */
+		const plcMapType& getPLCMap();
+
+        /*!
+         * \brief Acquires one particular registers block of all devices of all enabled PLCs of that cluster.
+         * The method tries to (re)connect each PLC if the connection is not established yet or unexpectedly interrupted (network failure, PLC down, etc.).
+         * \param blockName name of the block to be acquired
+         */
+		void recv(std::string blockName);
+
+        /*!
+         * \brief Transmits the registers block to all devices of all enabled PLCs of that cluster.
+         * The method tries to (re)connect each PLC if the connection is not established yet or unexpectedly interrupted (network failure, PLC down, etc.).
+         * \param blockName name of the block to be transmitted
+         */
+		void send(std::string blockName);
+
+        /*!
+         * \brief Copies input buffer in output buffer
+         * The method copies the input buffer in the output buffer for each READ-WRITE register register in the cluster for the block passed as parameter
+         * \param blockName name of the block for which the copy must be performed
+         */
+		void copyInToOut(const std::string blockName);
+
+	    /*!
+	     * \struct configuration
+	     * \brief Run-time configuration of the cluster.
+	     * The default parameters of the cluster can be changed by setting the public Cluster::configuration structure.
+	     * \param sharedConnection = true to share the same connection with other clusters deployed on that PLC.
+	     * By default the sharedConnection of the cluster is false, and it uses a dedicated connection (2 channels: r/w)
+	     * to communicate with the controller.
+	     */
+	    clusterConfigType configuration;
+
+	private:
+		friend class Service;
+		friend class PLC;
+		friend class Device;
+
+        // private, because this class is a unique per className
+		Cluster(const std::string className, const std::string classVersion);
+
+        /*!
+         * \brief The client process is responsible to delete the Cluster object that has been
+         * instantiated with getCluster() call.
+         * Deleting the Cluster object delete also all the related components of that Cluster
+         * (PLCs, Devices and Registers)
+         */
+		~Cluster();
+
+        /*!
+         * \brief returns the input hostname without domain-name extension (cern.ch for instance)
+         */
+		void removeDomainName(std::string& hostName);
+
+		bool getHostNameByAddress(const std::string IPAddress, std::string& hostName);
+		bool getAddressByHostName(const std::string hostName, std::string& IPAddress);
+
+        /*!
+         * \fn getBlock
+         * \brief returns one instance of the requested block checking its access-type
+         */
+		Block* getBlock(const std::string blockName, AccessType accessType = InOut);
+
+		/// Store the current FEC name
+		std::string hostName_;
+
+		/// Class related to the cluster
+		std::string className_;
+		std::string classVersion_;
+
+		/// PLC collection of the cluster
+        plcMapType plcMap_; 	//by plc hostname
+        plcMapType IPAddrMap_;  //by plc IP address
+
+	};
+
+} // namespace
+
+#endif // _SILECS_CLUSTER_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e609f60d681c1e6ad4851f71bcf05c60523226d8
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.cpp
@@ -0,0 +1,284 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/equipment/SilecsDevice.h>
+
+#include <silecs-communication/interface/core/Context.h>
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/core/WrapperAction.h>
+#include <silecs-communication/interface/equipment/SilecsBlock.h>
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/equipment/SilecsRegister.h>
+#include <silecs-communication/interface/equipment/PLCRegister.h>
+#include <silecs-communication/interface/utility/SilecsException.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <silecs-communication/interface/utility/XMLParser.h>
+
+#include <silecs-communication/interface/equipment/CNVRegister.h>
+
+namespace Silecs
+{
+	Device::Device(PLC* thePLC, std::string deviceName, std::string deviceAddress, boost::ptr_vector<ElementXML>& blockNodes) : thePLC_ (thePLC)
+	{
+		// Update Device ElementXML attributes
+        label_ = deviceName;
+		StringUtilities::fromString(address_,deviceAddress );
+
+        LOG(ALLOC) << "Device (create): " << label_;
+
+        boost::ptr_vector<ElementXML>::const_iterator blockIter;
+        for(blockIter = blockNodes.begin(); blockIter != blockNodes.end(); blockIter++)
+		{
+			std::string blockName = blockIter->getAttribute("name");
+			AccessType accessType = Block::whichAccessType(blockIter->getAttribute("mode"));
+			std::vector< boost::shared_ptr<ElementXML> > registerNodes = blockIter->childList_;
+			instantiateRegisters(blockName, accessType, registerNodes);
+		}
+	}
+
+	Device::~Device()
+	{
+		LOG(ALLOC) << "Device (delete): " << label_;
+
+		// Remove the register instances related to this Device
+		registerVectorType::iterator pRegisterIter;
+		for(pRegisterIter = registerCol_.begin(); pRegisterIter != registerCol_.end(); ++pRegisterIter) delete pRegisterIter->second;
+		registerCol_.clear();
+
+		// Register instances have been deleted before, just clear the block-register Map.
+	    blockRegisterMap_.clear();
+	}
+
+
+	PLC* Device::getPLC()
+	{ return thePLC_;
+	}
+
+
+	Register* Device::getRegister(std::string registerName)
+	{
+		registerVectorType::iterator iter;
+		for(iter = registerCol_.begin(); iter != registerCol_.end(); ++iter)
+		{
+			if (iter->first == registerName)
+			{
+				return iter->second;
+			}
+		}
+        throw SilecsException(__FILE__, __LINE__, PARAM_UNKNOWN_REGISTER_NAME, registerName);
+        return NULL; // to suppress warning
+	}
+
+
+	std::vector<Register*>& Device::getRegisterCollection(std::string blockName)
+	{
+		blockRegisterMapType::iterator iter = blockRegisterMap_.find(blockName);
+        if (iter == blockRegisterMap_.end())
+        { throw SilecsException(__FILE__, __LINE__, PARAM_UNKNOWN_BLOCK_NAME, blockName);
+        }
+        return iter->second;
+	}
+
+
+	int Device::recv(std::string blockName)
+	{
+		//Synchronous device data receive
+
+		//Context of the transaction:
+		//this = the device to be treated,
+		//false = is not for registers synchronization (normal transaction)
+		Context context(this, false);
+
+		//Execute the receive action for the required device (from the current thread)
+		return getBlock(blockName, Input)->getTask()->execute(&context);
+	}
+
+
+	int Device::send(std::string blockName)
+	{
+		//Synchronous device data send
+
+		//Context of the transaction:
+		//this = the device to be treated,
+		//false = is not for registers synchronization (normal transaction)
+		Context context(this, false);
+
+		//Execute the receive action for the required device (from the current thread)
+		return getBlock(blockName, Output)->getTask()->execute(&context);
+	}
+
+
+	std::string Device::getLabel() { return label_; }
+
+
+	std::string Device::getRegisterList()
+	{
+		std::string registerList = "";
+		registerVectorType::iterator pRegisterIter;
+		for(pRegisterIter = registerCol_.begin(); pRegisterIter != registerCol_.end(); ++pRegisterIter)
+		{	if (!registerList.empty()) registerList.append(" ");
+			registerList.append(pRegisterIter->second->getName());
+		}
+		return registerList;
+	}
+
+
+	Register* Device::instantiateRegister(const boost::shared_ptr<ElementXML>& registerNode)
+	{
+		switch (getPLC()->getBrandID())
+		{
+			// SIEMENS PLCs use Motorola memory convention (BigEndianRegister)
+			case Siemens:
+				return new S7Register(this, registerNode);
+
+			// SCHNEIDER PLCs use Intel memory convention (LittleEndianRegister)
+			// RABBIT microcontrollers use Intel memory convention (LittleEndianRegister)
+			case Schneider:
+			case Digi:
+				return new UnityRegister(this, registerNode);
+
+			// BECKHOFF PLCs use different memory convention depending on PLC type:
+			// . CX model: same convention than Unity
+			// . BC model: special convention for 64 bits data (float, ..): swap only the two 16bits words together (no bytes swap).
+			case Beckhoff:
+				return new TwinCATRegister(this, registerNode);
+
+#ifdef NI_SUPPORT_ENABLED
+			//NI Shared variables use specific convention
+            case Ni:
+                return new CNVRegister(this, registerNode);
+#endif
+
+			default:
+				throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_PLC_MANUFACTURER, getPLC()->getBrand());
+
+		} //switch
+	}
+
+
+	void Device::instantiateRegisters(std::string blockName, AccessType accessType, std::vector< boost::shared_ptr<ElementXML> >& registerNodes)
+	{
+		std::vector<Register*> registerCol;
+
+		//LOG(SETUP) << "Ordering registers for block: " <<  blockName << " on Device: " << getLabel();
+
+		std::vector< boost::shared_ptr<ElementXML> >::const_iterator registerIter;
+		for(registerIter = registerNodes.begin(); registerIter != registerNodes.end(); registerIter++)
+		{
+			std::string registerName = (*registerIter)->getAttribute("name");
+			Register* pReg = instantiateRegister(*registerIter);
+			pReg->setAccessType(accessType);
+			pReg->setBlockName(blockName);
+			registerCol.push_back(pReg);
+			registerCol_.push_back(std::make_pair(registerName, pReg));
+		}
+		blockRegisterMap_.insert(std::make_pair(blockName, registerCol));
+	}
+
+	void Device::keepMasterRegisters(std::string blockName)
+	{
+		blockRegisterMapType::iterator iter = blockRegisterMap_.find(blockName);
+        if (iter == blockRegisterMap_.end())
+        { throw SilecsException(__FILE__, __LINE__, PARAM_UNKNOWN_BLOCK_NAME, blockName);
+        }
+
+		for (unsigned int i=0; i<iter->second.size(); i++)
+		{	Register* pReg = iter->second[i];
+			if (pReg->getSynchroType() == Master) pReg->copyValue();
+		}
+	}
+
+	Block* Device::getBlock(const std::string blockName, AccessType accessType)
+	{ return thePLC_->getBlock(blockName, accessType);
+	}
+
+
+	void Device::importRegisters(Block* pBlock, void* pBuffer, timeval ts, Context* pContext)
+	{
+		std::vector<Register*>& registerCol = getRegisterCollection(pBlock->getName());
+
+		if (pContext->isForSynchronization())
+		{	// Transaction has been done within the context of retentive registers synchronization,
+			// do not update volatile registers (client has to force a transaction himself if required).
+			for (unsigned int i=0; i<registerCol.size(); i++)
+			{	
+				Register* pReg = registerCol[i];
+				if (pReg->isRetentive())
+				{
+					if(pReg->getFormat() == String)
+				        pReg->importString(pBuffer, ts);
+				    else // all registers but those having string format
+				        pReg->importValue(pBuffer, ts);
+				}
+			}
+		}
+		else
+		{	// It's a normal transaction from the client process,
+			// all registers of the block have to be updated.
+			for (unsigned int i=0; i<registerCol.size(); i++)
+			{
+				if(registerCol[i]->getFormat() == String)
+                    registerCol[i]->importString(pBuffer, ts);
+                else // all registers but those having string format
+                    registerCol[i]->importValue(pBuffer, ts);
+			}
+		}
+	}
+
+	void Device::exportRegisters(Block* pBlock, void* pBuffer, Context* pContext)
+	{
+		std::vector<Register*>& registerCol = getRegisterCollection(pBlock->getName());
+
+		if (pContext->isForSynchronization())
+		{	// Transaction has been done within the context of retentive registers synchronization,
+			// do not update volatile register (client has to force a transaction himself if required).
+			for (unsigned int i=0; i<registerCol.size(); i++)
+			{
+			    Register* pReg = registerCol[i];
+			    if (pReg->isRetentive())
+			    {
+                    if(pReg->getFormat() == String)
+                        pReg->exportString(pBuffer);
+                    else    // all registers but those having string format
+                        pReg->exportValue(pBuffer);
+			    }
+			}
+		}
+		else
+		{	// It's a normal transaction from the client process,
+			// all registers of the block have to be updated.
+			for (unsigned int i=0; i<registerCol.size(); i++)
+			{
+			    if(registerCol[i]->getFormat() == String)
+			        registerCol[i]->exportString(pBuffer);
+			    else
+			        registerCol[i]->exportValue(pBuffer);
+			}
+		}
+	}
+
+	void Device::copyInToOut(const std::string blockName)
+	{
+		std::vector<Register*>& registerCol = getRegisterCollection(blockName);
+		for (unsigned int i=0; i<registerCol.size(); i++)
+		{	Register* pReg = registerCol[i];
+			if (pReg->hasInputAccess() && pReg->hasOutputAccess())
+				pReg->copyValue();
+		}
+
+	}
+
+} // namespace
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.h
new file mode 100644
index 0000000000000000000000000000000000000000..11014b115680cb7e2f49ad7cd9259cb2d52e177d
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.h
@@ -0,0 +1,184 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _SILECS_DEVICE_H_
+#define _SILECS_DEVICE_H_
+
+#include <silecs-communication/interface/core/SilecsService.h>
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+
+namespace Silecs
+{
+	class PLC;
+	class Block;
+	class ElementXML;
+	class Register;
+	class Context;
+
+	/// @cond
+	typedef std::vector<std::pair<std::string, Register*> > registerVectorType;
+	typedef std::map<std::string, std::vector<Register*> > blockRegisterMapType;
+	/// @endcond
+
+	/*!
+	 * \class Device
+	 * \brief This object maintains a reference of all the device registers.
+	 * It is responsible to serialize, de-serialize data for the network transfer (alignment, data swapping, ..).
+	 * It can be used to trig the data-block exchange for one particular device (make sense for DEVICE-MODE only).
+	 */
+	class Device
+	{
+	public:
+
+		/*!
+		 * \brief Returns reference of the PLC where the device is instantiated
+         * \return Reference of the PLC object
+         */
+		PLC* getPLC();
+
+        /*!
+		 * \brief Returns the label of the device as defined in the Deployment document.
+		 *  A device label is not visible from the supervision. It's the device identifier within
+		 *  the PLC/Class scope. If label has not been defined, the device is identified by its
+		 *  corresponding index [1..n] in the device collection.
+         * \return label or index of the device as string
+         */
+		std::string getLabel();
+
+		/*!
+		 * \brief Returns one register instance of the device by its name
+		 * \param registerName name of the register
+         * \return Reference of the register object
+         */
+		Register* getRegister(std::string registerName);
+
+        /*!
+         * \brief Acquires one particular registers block of the device.
+         * The method tries to (re)connect the PLC if the connection is not established yet or unexpectedly interrupted (network failure, PLC down, etc.).
+         * It generates an Silecs::SilecsException if the related PLC has not been enabled (using the connect() method).
+         * \param blockName name of the block to be acquired
+         * \return 0 if operation was successful else an error code (when available).
+         */
+		int recv(std::string blockName);
+
+        /*!
+         * \brief Transmits the registers block to the device
+         * The method tries to (re)connect the PLC if the connection is not established yet or unexpectedly interrupted (network failure, PLC down, etc.).
+         * It generates an Silecs::SilecsException if the related PLC has not been enabled (using the connect() method).
+         * \param blockName name of the block to be transmitted
+         * \return 0 if operation was successful else an error code (when available).
+         */
+		int send(std::string blockName);
+
+        /*!
+         * \brief Copies input buffer in output buffer
+         * The method copies the input buffer in the output buffer for each READ-WRITE register for the block passed as parameter
+         * \param blockName name of the block for which the copy must be performed
+         */
+		void copyInToOut(const std::string blockName);
+
+		/// @cond
+        /*!
+         * \return all registers of the device for a given block
+         */
+		std::vector<Register*>& getRegisterCollection(std::string blockName);
+
+        /*!
+         * \return String list (space separated value) of the Device registers
+         */
+		std::string getRegisterList();
+		/// @endcond
+
+	private:
+		// export device attributes to the Actions
+		friend class PLC;
+		friend class Register;
+		friend class PLCRegister;
+		friend class PLCRecvBlockMode;
+		friend class PLCRecvDeviceMode;
+		friend class PLCSendBlockMode;
+		friend class PLCSendDeviceMode;
+		friend class Context;
+
+        friend class CNVRegister;
+        friend class CNVRecvBlockMode;
+        friend class CNVRecvDeviceMode;
+        friend class CNVSendBlockMode;
+        friend class CNVSendDeviceMode;
+
+		Device(PLC* thePLC, std::string deviceName, std::string deviceAddress, boost::ptr_vector<ElementXML>& blockNodes);
+		virtual ~Device();
+
+		inline unsigned long& getAddress() { return address_; }
+
+		Register* instantiateRegister(const boost::shared_ptr<ElementXML>& registerNode);
+
+		void instantiateRegisters(std::string blockName, AccessType accessType, std::vector< boost::shared_ptr<ElementXML> >& registerNodes);
+
+        /*!
+         * \fn keepMasterRegisters
+         * \brief This method is used for Retentive registers synchronization on each PLC (re)connection.
+         * Update local value of the RW Master registers to maintain the PLC values during
+         * the synchronization of Slave registers.
+         */
+		void keepMasterRegisters(std::string blockName);
+
+		/*!
+         * \fn getBlock
+         * \brief returns one instance of the requested block checking its access-type
+         */
+		Block* getBlock(const std::string blockName, AccessType accessType = InOut);
+
+        /*!
+         * \fn importRegisters
+         * \brief Extract all the concerned registers data of that device from a given block and set the registers value.
+         * \param pBlock: block which contain list of registers to be imported
+         * \param pBuffer: direct pointer on the buffer which contain the registers data
+         * \param ts is the time-of-day to time-stamp each register
+         */
+		void importRegisters(Block* pBlock, void* pBuffer, timeval ts, Context* pContext);
+
+        /*!
+         * \fn exportRegisters
+         * \brief Export all the concerned registers value of that device to a given block.
+         * \param pBlock: block which contain list of registers to be exported
+         * \param pBuffer: direct pointer on the buffer which will contain the registers data
+         */
+		void exportRegisters(Block* pBlock, void* pBuffer, Context* pContext);
+
+		/// Parent PLC reference of that device
+		PLC* thePLC_;
+
+		/// Device attributes
+		std::string label_;
+		unsigned long address_;
+
+		/// Register collection of that device
+		registerVectorType registerCol_;
+
+		/// Collections of the device registers by block
+		blockRegisterMapType blockRegisterMap_;
+
+	};
+
+} // namespace
+
+#endif // _SILECS_DEVICE_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..57884b5b701df10cd216040592be14a4c1ec3d01
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp
@@ -0,0 +1,725 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+
+#include <silecs-communication/interface/core/Diagnostic.h>
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/core/WrapperAction.h>
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/interface/equipment/SilecsDevice.h>
+#include <silecs-communication/interface/equipment/SilecsBlock.h>
+#include <silecs-communication/interface/equipment/SilecsRegister.h>
+#include <silecs-communication/interface/equipment/PLCBlock.h>
+#include <silecs-communication/interface/equipment/PLCRegister.h>
+#include <silecs-communication/interface/utility/SilecsException.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <silecs-communication/interface/utility/StringUtilities.h>
+#include <silecs-communication/interface/utility/XMLParser.h>
+
+//Supported protocol
+#include <silecs-communication/interface/communication/MBConnection.h>
+#include <silecs-communication/interface/communication/SNAP7Connection.h>
+
+#include <silecs-communication/interface/communication/CNVConnection.h>
+#include <silecs-communication/interface/equipment/CNVBlock.h>
+
+#include <fstream>
+
+namespace Silecs
+{
+        connMapType PLC::connMap_;
+		PLC::PLC(Cluster* theCluster, std::string plcName, std::string plcIPaddr, string parameterFile) :
+				theCluster_ (theCluster), IPaddr_(plcIPaddr), parameterFile_(parameterFile)
+		{
+			//Force PLC hostname lower-case
+			name_ = plcName;
+			StringUtilities::toLower(name_);
+
+			LOG(ALLOC) << "PLC (create): " << name_ << "/ " << IPaddr_;
+
+			// Upload the parameters file and build the PLC configuration
+			extractDatabase();
+
+			 //Do not synchronize retentive Registers by default (overwritten at connection time)
+			synchroMode_  = NO_SYNCHRO;
+
+			// Start the PLC Thread
+			pThread_ = new Thread<WrapperAction>::Thread();
+
+			// create default contexts for all-devices transaction (normal and for synchronization)
+			allDevicesTransaction_ 		= new Context(NULL/*no Device: for all devices)*/, false);
+			allDevicesSynchronization_	= new Context(NULL/*no Device: for all devices)*/, true);
+
+            // Instantiate the communication interface
+			plcConn_ = NULL;
+			isSharedConn_ = false; // No shared connection by default and for CNV protocol (PXI platform).
+		}
+
+
+		PLC::~PLC()
+		{
+			LOG(ALLOC) << "PLC (delete): " << name_;
+
+            //Before removing the PLC resources, we need to interrupt all the related accesses (if connection is not shared)
+			if (isSharedConn_ == false)	disconnect();
+
+            // Remove PLC communication resources
+            if (pThread_ != NULL) { delete pThread_; pThread_ = NULL; }
+            if ((plcConn_ != NULL) && (isSharedConn_ == false)) { delete plcConn_; plcConn_ = NULL; }
+
+			//theHeader object and the shared-connection objects (if any) must not be delete from the PLC since
+            //it is shared between all the PLC instances. It will be removed by the Service destructor at the end.
+
+			delete allDevicesTransaction_;
+			delete allDevicesSynchronization_;
+
+			// Remove the Device instances related to this PLC
+			deviceVectorType::iterator pDeviceIter;
+			for(pDeviceIter = deviceCol_.begin(); pDeviceIter != deviceCol_.end(); ++pDeviceIter) delete pDeviceIter->second;
+			deviceCol_.clear();
+
+			// Remove the Block instances related to this PLC
+			blockMapType::iterator pBlockIter;
+			for(pBlockIter = blockMap_.begin(); pBlockIter != blockMap_.end(); ++pBlockIter)
+			{	delete pBlockIter->second;
+				pBlockIter->second = NULL;
+			}
+			blockMap_.clear();
+
+			// Clear Blocks collection used for retentive registers synchronization
+			masterInputBlockCol_.clear();
+			slaveOutputBlockCol_.clear();
+		}
+
+		void PLC::connect(SynchroMode synchroMode, bool connectNow, bool compareChecksums)
+		{
+		    //At first, Instantiate the PLC connection object if needed
+			LOG((COMM|DIAG)) << "Attempt to establish connection ... ";
+		    /*plcConn_ =*/ getConnection();
+			//Check PLC is not already Enabled
+			std::string connStr = name_ + "(" + IPaddr_ + ")" + ":" + theCluster_->getClassName() + "/v" + theCluster_->getClassVersion();
+			LOG(ERROR) << connStr;
+
+	        if ( (connectNow == false) && plcConn_->isEnabled() )
+	        {   //Trying to connect a connected PLC should not be necessary an ERROR
+				//throw SilecsException(__FILE__, __LINE__, COMM_ALREADY_ENABLED, connStr);
+	        	LOG(ERROR) << "This PLC connection is already enabled: " << connStr;
+	        	return;
+	        }
+
+	        LOG(COMM) << (connectNow ? "Open" : "Enable") << " Connection request for " << connStr;
+
+			//Store the synchonization mode for this particular PLC/Cluster connection request (can change at any connect() call.
+            synchroMode_  = synchroMode;
+
+			// Whatever the outcome of the connection that will follow, the PLC must be Enabled in any case.
+			// Thus, even if the PLC is off and rejects the first connection to upload the Header (see updateHeader),
+			// we will automatically attempt to reconnect later at the next PLC accesses (send/recv) ... again and again.
+			plcConn_->enable(this, connectNow);
+
+			if( compareChecksums )
+			{
+		        /* PLC memory could have change during a disconnection time (downloading or other).
+		           The Header registers must be reloaded for consistency checking.
+		           Do not continue the connection sequence if it is not even possible to load the header.
+				*/
+				LOG(COMM) << "getting checksum";
+				remoteChecksum_ = theHeader_->getRegister("_checksum")->getValULong();
+				if (remoteChecksum_ != localChecksum_)
+				{   //Client and PLC mapping are not consistent ... no transaction are possible!
+					disconnect();
+					std::ostringstream message;
+					message << "Checksum comparison failed. Checksum in parameter file: '" << localChecksum_ << "' Checksum in PLC: '" << remoteChecksum_<<  "' Disconnecting PLC now.";
+					throw SilecsException(__FILE__, __LINE__, CONFIG_CLIENT_PLC_NOT_CONSISTENT, message.str());
+				}
+			}
+		};
+
+
+		void PLC::disconnect()
+		{
+		    LOG(COMM) << "Disconnection request for " << name_ << ":" << theCluster_->getClassName() << "/v" << theCluster_->getClassVersion();
+			//close the connection (also close the connection if shared with other cluster on the same PLC!)
+			getConnection()->disable(this);
+            synchroMode_  = NO_SYNCHRO; //Do not synchronize retentive Registers by default
+		};
+
+		bool PLC::isEnabled() { return ((plcConn_ == NULL) ? false : plcConn_->isEnabled()); /*do not use getConnection() here*/}
+		bool PLC::isConnected(bool connectNow)
+		{
+			return (connectNow ? getConnection()->doOpen(this): getConnection()->isConnected());
+		}
+
+
+		unsigned int PLC::getThreadPriority()
+		{
+			LOG(SETUP) << "Thread RT-priority of PLC " << name_ << " is: " << pThread_->getPriority();
+			return pThread_->getPriority();
+		}
+
+
+		void PLC::setThreadPriority(unsigned int rtprio)
+		{
+			LOG(SETUP) << "Set Thread RT-priority of PLC " << name_ << ": " << rtprio;
+			return pThread_->setPriority(rtprio);
+		}
+
+
+		const std::string PLC::getParamsFileName()
+		{
+			return parameterFile_;
+		}
+
+
+		Device* PLC::getDevice(std::string deviceName)
+		{
+			deviceVectorType::iterator iter;
+
+			for(iter = deviceCol_.begin(); iter != deviceCol_.end(); ++iter)
+			{
+				if (DEBUG & Log::topics_) LOG(COMM) << "getDevice - deviceName: '" << iter->first <<  "'";
+			}
+
+			for(iter = deviceCol_.begin(); iter != deviceCol_.end(); ++iter)
+			{
+				if (iter->first == deviceName)
+				{
+					return iter->second;
+				}
+			}
+
+	        throw SilecsException(__FILE__, __LINE__, PARAM_UNKNOWN_DEVICE_NAME, deviceName+"/"+name_);
+	        return NULL;//to suppress warning
+		}
+
+
+		std::vector<std::string> PLC::getDeviceList()
+		{
+			std::vector<std::string> deviceList;
+			deviceVectorType::iterator pDeviceIter;
+			for(pDeviceIter = deviceCol_.begin(); pDeviceIter != deviceCol_.end(); ++pDeviceIter)
+			{
+				deviceList.push_back(pDeviceIter->first);
+			}
+			return deviceList;
+		}
+
+
+		std::string PLC::getName() { return name_; }
+		std::string PLC::getIPAddress() { return IPaddr_; }
+		std::string PLC::getDomain() { return domain_; }
+		std::string PLC::getBrand() { return brand_; }
+        std::string PLC::getSystem() { return system_; }
+		std::string PLC::getModel() { return model_; }
+		std::string PLC::getProtocolType() { return protocolType_; }
+		std::string PLC::getProtocolMode() { return protocolMode_; }
+		unsigned long PLC::getBaseAddress() { return baseAddr_; }
+
+		deviceVectorType& PLC::getDeviceMap() { return deviceCol_; }
+		std::string PLC::getLocalRelease() { return localRelease_; }
+		std::string PLC::getLocalOwner() { return localOwner_; }
+		std::string PLC::getLocalDate() { return localDate_; }
+		unsigned long PLC::getLocalChecksum() { return localChecksum_; }
+
+
+		void PLC::downloadMasterRegisters()
+		{
+			if (masterInputBlockCol_.size())
+			{
+				if (DEBUG & Log::topics_) LOG(COMM) << "Download Master registers of " << name_ << ":" << theCluster_->getClassName() << "/v" << theCluster_->getClassVersion();
+			}
+
+			// Read all the Master Blocks (containing 1 MASTER register at least)
+			// to update retentive values on client side.
+			for (unsigned int i=0; i<masterInputBlockCol_.size(); i++)
+			{
+				Block* pBlock = masterInputBlockCol_[i];
+				LOG(COMM) << "Attempt to download Block: " << pBlock->getName();
+				pBlock->getTask()->execute(allDevicesSynchronization_);
+
+				// Then update local RW Master registers with values coming from PLC source
+				if (pBlock->hasOutputAccess())
+				{   // Perform keepMasterRegisters for each device of the Cluster.
+					deviceVectorType::iterator pDeviceIter;
+					for(pDeviceIter = deviceCol_.begin(); pDeviceIter != deviceCol_.end(); ++pDeviceIter)
+					{
+						pDeviceIter->second->keepMasterRegisters(pBlock->getName());
+					}
+				}
+			}
+		}
+
+
+		bool PLC::checkSlaveRegistersInit(std::string& registerNotInitialized)
+		{
+			//We should not allow update Slave Registers if only one of them has never been setted (not initialized)
+			//for each Block that contains Slave register(s)
+			for (unsigned int i=0; i<slaveOutputBlockCol_.size(); i++)
+			{   //for each Device of the collection
+				for(deviceVectorType::iterator pDeviceIter = deviceCol_.begin(); pDeviceIter != deviceCol_.end(); ++pDeviceIter)
+				{   //for each register of this block
+					std::vector<Register*>& registerCol = pDeviceIter->second->getRegisterCollection(slaveOutputBlockCol_[i]->getName());
+					for (unsigned int i=0; i<registerCol.size(); i++)
+					{   //check that Slave register is initialized and stop the connection process if needed
+						Register* pReg = registerCol[i];
+						if ((pReg->getSynchroType() == Slave) && (pReg->isInitialized() == false))
+						{	//Slave registers synchronization is not allowed
+							registerNotInitialized = pDeviceIter->first + "/" + pReg->getName();
+							return false;
+				        }
+					}
+				}
+			}
+			return true;
+		}
+
+
+		void PLC::uploadSlaveRegisters()
+		{
+			if (slaveOutputBlockCol_.size())
+			{ // There are Slave registers and they are all well-initialized, PLC memory can be updated with their local values
+			  LOG((COMM|DIAG)) << "Upload Slave registers to " << name_ << ":" << theCluster_->getClassName() << "/v" << theCluster_->getClassVersion();
+			}
+
+			// Write all the Slave Blocks (containing 1 SLAVE register at least)
+			// to update retentive values on PLC side.
+			for (unsigned int i=0; i<slaveOutputBlockCol_.size(); i++)
+			{
+				LOG(COMM) << "Attempt to upload Block: " << slaveOutputBlockCol_[i]->getName();
+				slaveOutputBlockCol_[i]->getTask()->execute(allDevicesSynchronization_);
+			}
+		}
+
+
+        int PLC::recvUnitCode(UnitCodeType& dataStruct)
+        {
+            return getConnection()->readUnitCode(this, dataStruct);
+        }
+
+
+        int PLC::recvUnitStatus(UnitStatusType& dataStruct)
+        {
+            return getConnection()->readUnitStatus(this, dataStruct);
+        }
+
+
+        int PLC::recvCPUInfo(CPUInfoType& dataStruct)
+        {
+            return getConnection()->readCPUInfo(this, dataStruct);
+        }
+
+
+        int PLC::recvCPInfo(CPInfoType& dataStruct)
+        {
+            return getConnection()->readCPInfo(this, dataStruct);
+        }
+
+
+		int PLC::recv(std::string blockName)
+		{
+			//Synchronous data receive
+
+			//Execute the receive action for all the PLC devices (from the current thread)
+			return getBlock(blockName, Input)->getTask()->execute(allDevicesTransaction_);
+		}
+
+
+		int  PLC::send(std::string blockName)
+		{
+			//Synchronous data send
+
+			//Execute the send action for all the PLC devices (from the current thread)
+			return getBlock(blockName, Output)->getTask()->execute(allDevicesTransaction_);
+		}
+
+
+		void PLC::recvAsync(std::string blockName)
+		{
+			//Asynchronous data receive (used from Cluster level only)
+
+		    //Schedule task using asynchronous call for parallelism (submit to thread)
+			pThread_->schedule(getBlock(blockName, Input)->getTask(), allDevicesTransaction_);
+		}
+
+
+		void PLC::sendAsync(std::string blockName)
+		{
+			//Asynchronous data send (used from Cluster level only)
+
+		    //Schedule task using asynchronous call for parallelism (submit to thread)
+			pThread_->schedule(getBlock(blockName, Output)->getTask(), allDevicesTransaction_);
+		}
+
+		void PLC::waitAsync()
+		{
+			pThread_->waitForTaskCompletion();
+		}
+
+		void PLC::extractDatabase()
+		{
+			LOG(SETUP) << "Extract SILECS configuration from: " << parameterFile_;
+			XMLParser xmlParser(parameterFile_,true);
+
+			// Extract general information ===========================================
+			ElementXML rootNode = xmlParser.getFirstElementFromXPath("/SILECS-Param");
+			localRelease_ = rootNode.getAttribute("silecs-version");
+
+			ElementXML ownerNode = xmlParser.getFirstElementFromXPath("/SILECS-Param/Mapping-Info/Owner");
+			localOwner_ = ownerNode.getAttribute("user-login");
+
+			ElementXML generationNode = xmlParser.getFirstElementFromXPath("/SILECS-Param/Mapping-Info/Generation");
+			localDate_ = generationNode.getAttribute("date");
+
+			ElementXML deploymentNode = xmlParser.getFirstElementFromXPath("/SILECS-Param/Mapping-Info/Deployment");
+			StringUtilities::fromString(localChecksum_,deploymentNode.getAttribute("checksum") );
+
+			// Extract PLC general configuration ======================================
+			ElementXML mappingNode = xmlParser.getFirstElementFromXPath("/SILECS-Param/SILECS-Mapping");
+			//name_ = pEl->getStringAttribute("name"); already done before
+			domain_ = mappingNode.getAttribute("domain");
+			brand_ = mappingNode.getAttribute("plc-brand");
+            system_ = mappingNode.getAttribute("plc-system");
+            protocolMode_ = mappingNode.getAttribute("protocol");
+			brandID_ = whichPLCBrand(brand_);
+            systemID_ = whichPLCSystem(system_);
+			protocolModeID_ = whichProtocolMode(protocolMode_);
+			protocolTypeID_ = whichProtocolType(system_);
+
+			switch(protocolTypeID_)
+			{
+				case MBProtocol: 	protocolType_ = "MODBUS-TCP"; break;
+				case S7Protocol: protocolType_ = "SNAP7-TCP"; break;
+				case CNVProtocol: 	protocolType_ = "CNV-TCP"; break;
+			};
+
+			model_ = mappingNode.getAttribute("plc-model");
+            modelID_ = whichPLCModel(model_);
+			StringUtilities::fromString(baseAddr_,mappingNode.getAttribute("address") );
+			usedMem_ = mappingNode.getAttribute("used-mem");
+
+			std::vector< boost::shared_ptr<ElementXML> > classNodes = mappingNode.childList_;
+			std::vector< boost::shared_ptr<ElementXML> >::const_iterator classIter;
+			for(classIter = classNodes.begin(); classIter != classNodes.end(); classIter++)
+			{
+				std::string className = (*classIter)->getAttribute("name");
+
+				boost::ptr_vector<ElementXML> blockNodes = xmlParser.getElementsFromXPath_throwIfEmpty("/SILECS-Param/SILECS-Mapping/SILECS-Class[@name='"+ className + "']/Block");
+				boost::ptr_vector<ElementXML>::const_iterator blockIter;
+
+				boost::ptr_vector<ElementXML> instanceNodes = xmlParser.getElementsFromXPath_throwIfEmpty("/SILECS-Param/SILECS-Mapping/SILECS-Class[@name='"+ className + "']/Instance");
+				boost::ptr_vector<ElementXML>::const_iterator instanceIter;
+				for(instanceIter = instanceNodes.begin(); instanceIter != instanceNodes.end(); instanceIter++)
+				{
+					std::string deviceName = (*instanceIter).getAttribute("label");
+					std::string deviceAddress = (*instanceIter).getAttribute("address");
+					Device* pDevice = new Device(this, deviceName, deviceAddress, blockNodes);
+					deviceCol_.push_back(std::make_pair(deviceName, pDevice));
+					if(deviceName == "SilecsHeader")
+						theHeader_ = pDevice;
+				}
+
+				for(blockIter = blockNodes.begin(); blockIter != blockNodes.end(); blockIter++)
+				{
+					std::string blockNameFull; //"block-name" + "access-type"
+					std::string blockName = (*blockIter).getAttribute("name");
+					AccessType accessType = Block::whichAccessType((*blockIter).getAttribute("mode"));
+
+					Block* pBlock = 0;
+					// Instantiate Input blocks ------------------------------------------------------
+					if (Service::withInputAccess(accessType)) //Input or InOut access
+					{  	//Instantiate the block, forcing it to Input access for InOut case
+
+						if(whichPLCBrand(brand_)==Ni)
+#ifdef NI_SUPPORT_ENABLED
+							pBlock = new CNVInputBlock(this, (*pBlockElCol)[i], accessType, pCurrentBlockElCol);
+#else
+							throw SilecsException(__FILE__, __LINE__, "Support for NI-Devices is disabled");
+#endif
+						else
+							pBlock = new InputBlock(this,*blockIter, accessType);
+						blockNameFull = blockName + Block::whichAccessType(Input);
+
+						//Store references of Input Master blocks for retentive registers synchronization
+						if (pBlock->hasMasterRegister()) masterInputBlockCol_.push_back(pBlock);
+					}
+
+					// Instantiate Output blocks ------------------------------------------------------
+					if (Service::withOutputAccess(accessType))  //Output or InOut accessprotocol
+					{   //Instantiate the block, forcing it to Output access for InOut case
+
+
+						if(whichPLCBrand(brand_)==Ni)
+#ifdef NI_SUPPORT_ENABLED
+							pBlock = new CNVOutputBlock(this, (*pBlockElCol)[i], accessType, pCurrentBlockElCol);
+#else
+						throw SilecsException(__FILE__, __LINE__, "Support for NI-Devices is disabled");
+#endif
+						else
+							pBlock = new OutputBlock(this, *blockIter, accessType);
+
+						blockNameFull = blockName + Block::whichAccessType(Output);
+
+						//Store references of Ouput Slave blocks for retentive registers synchronization
+						if (pBlock->hasSlaveRegister()) slaveOutputBlockCol_.push_back(pBlock);
+					}
+
+					//Store reference of the block for general communication purpose
+					blockMap_.insert(std::make_pair(blockNameFull, pBlock));
+				} //for blocks
+			} //for classes
+		}
+
+
+        Connection* PLC::createConnection()
+        {
+            Connection* theConn = NULL;
+            try
+            {
+                switch(protocolTypeID_)
+                {
+                    case S7Protocol:
+                        theConn = new SNAP7Connection(this); break;
+                    case MBProtocol:
+                        theConn = new MBConnection(this); break;
+                    case CNVProtocol:
+#ifdef NI_SUPPORT_ENABLED
+                    	theConn = new CNVConnection(this);break;
+#else
+                    	throw SilecsException(__FILE__, __LINE__, "Support for NI-Devices is disabled");
+#endif
+                    default:
+                    	throw SilecsException(__FILE__, __LINE__, "Unknown protocolTypeID_");
+                }
+            }
+            catch (const SilecsException& ex)
+            {   //Something has failed. Nothing to do, we trust the re-open mechanism from now.
+            	LOG(ERROR) << ex.what();
+            	throw ex;
+            }
+
+            if (DEBUG & Log::topics_) LOG(COMM) << "PLC::createConnection(): " << connID_ << ", isShared: " << (isSharedConn_? "true":"false");
+            return theConn;
+        }
+
+
+        Connection* PLC::getConnection()
+        {
+            if (plcConn_ == NULL)
+            {
+            	LOG((COMM|DIAG)) << "No connection found. Attempt to establish connection ... ";
+                //Connection not instantiated yet. Check if it will be shared or not?
+                if (protocolTypeID_ != CNVProtocol)
+                {
+                    /*TODO: get from the param file (extractDatabase): Major release??*/
+                    isSharedConn_ =  theCluster_->configuration.sharedConnection;
+                }
+                connID_ = (isSharedConn_) ? name_+"SharedConnection" : name_+theCluster_->getClassName();
+
+                if (isSharedConn_)
+                {
+                	LOG((COMM|DIAG)) << "Creating shared connection";
+                    //Create/re-used the shared connection
+                    connMapType::iterator iter = connMap_.find(connID_);
+                    if (iter == connMap_.end()) //one shared-connection per PLC
+                    {   Connection* theConn = createConnection();
+                        connMap_.insert(std::make_pair(connID_, theConn));
+                        plcConn_ = theConn;
+                    }
+                    else
+                    {   plcConn_ = iter->second;
+                    }
+                }
+                else
+                {   //Create the specific PLC/Cluster connection
+                	LOG((COMM|DIAG)) << "Creating non-shared connection";
+                    plcConn_ = createConnection();
+                }
+            }
+            return plcConn_;
+        }
+
+
+        void PLC::deleteConnection()
+        {
+            // Remove all shared-connection if any (one per PLC)
+            connMapType::iterator iter;
+            for(iter = connMap_.begin(); iter != connMap_.end(); ++iter)
+            {   delete iter->second;
+            }
+            connMap_.clear();
+        }
+
+
+        Block* PLC::getBlock(const std::string blockName, AccessType accessType)
+		{
+        	blockMapType::iterator pBlockMapIter;
+
+			switch(accessType)
+			{	case Input:
+					//Doest the block exist with the Input access-type?
+		        	pBlockMapIter = blockMap_.find(blockName + Block::whichAccessType(Input));
+					if (pBlockMapIter == blockMap_.end())
+					{
+						//No! then check if it exists with other access-type
+						pBlockMapIter = blockMap_.find(blockName + Block::whichAccessType(Output));
+						if (pBlockMapIter == blockMap_.end())
+							//This block does not exist at all?
+							throw SilecsException(__FILE__, __LINE__, PARAM_UNKNOWN_BLOCK_NAME, blockName);
+						else
+							//This block exists but with the opposite access-type
+							throw SilecsException(__FILE__, __LINE__, PARAM_ACCESS_TYPE_MISMATCH, blockName);
+					}
+				break;
+				case Output:
+					//Doest the block exist with the Output access-type?
+		        	pBlockMapIter = blockMap_.find(blockName + Block::whichAccessType(Output));
+					if (pBlockMapIter == blockMap_.end())
+					{
+						//No! then check if it exists with other access-type
+						pBlockMapIter = blockMap_.find(blockName + Block::whichAccessType(Input));
+						if (pBlockMapIter == blockMap_.end())
+							//This block does not exist at all?
+							throw SilecsException(__FILE__, __LINE__, PARAM_UNKNOWN_BLOCK_NAME, blockName);
+						else
+							//This block exists but with the opposite access-type
+							throw SilecsException(__FILE__, __LINE__, PARAM_ACCESS_TYPE_MISMATCH, blockName);
+					}
+				break;
+				default:
+					//should never occure!
+				    throw SilecsException(__FILE__, __LINE__, (int)UNEXPECTED_ERROR, "Input or Output argument is required!");
+			}
+
+			//block with expected access-type has been found
+			return pBlockMapIter->second;
+		}
+
+
+		blockMapType& PLC::getBlockMap() { return blockMap_; }
+
+
+		PLCBrand PLC::whichPLCBrand(std::string brand)
+		{
+			StringUtilities::toLower(brand);
+			if (brand == "siemens")			return Siemens;
+			else if (brand == "schneider")	return Schneider;
+            else if (brand == "beckhoff")   return Beckhoff;
+			else if (brand == "rabbit")		return Digi;
+			else if (brand == "ni")			return Ni;
+			else throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_PLC_MANUFACTURER, brand);
+		}
+
+        PLCModel PLC::whichPLCModel(std::string model)
+        {
+            StringUtilities::toLower(model);
+            if (model == "simatic_et-200s")    return ET200S;
+            else if (model == "simatic_s7-300")    return S7300;
+            else if (model == "simatic_s7-400")  return S7400;
+            else if (model == "simatic_s7-1200")   return S71200;
+            else if (model == "simatic_s7-1500")         return S71500;
+            else if (model == "premium")         return Premium;
+            else if (model == "quantum")         return Quantum;
+            else if (model == "m340")         return M340;
+            else if (model == "bc9020")         return BC9020;
+            else if (model == "cx9020")         return CX9020;
+            else if (model == "rcm_4010")         return RCM4010;
+            else if (model == "rcm_2000")         return RCM2000;
+            else if (model == "compact_rio")         return CompactRIO;
+            else if (model == "pxi_rt")             return PXIRT;
+            else if (model == "pxi_windows")         return PXIWindows;
+            else if (model == "pc_windows")         return PCWindows;
+            else if (model == "other_support_cnv")         return OtherSupportCNV;
+            else throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_PLC_MODEL, model);
+        }
+
+	   PLCSystem PLC::whichPLCSystem(std::string system)
+       {
+	       StringUtilities::toLower(system);
+           if (system == "step-7")          return Step7;
+           if (system == "tia-portal")      return TiaPortal;
+           else if (system == "unity pro")  return Unity;
+           else if (system == "twincat")    return TwinCat;
+           else if (system == "standard-c") return StdC;
+           else if (system == "labview")    return Labview;
+           else throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_PLC_SYSTEM, system);
+       }
+
+
+		ProtocolType PLC::whichProtocolType(std::string system)
+		{
+            StringUtilities::toLower(system);
+            if (system == "step-7")          return S7Protocol;
+            if (system == "tia-portal")      return S7Protocol;
+            else if (system == "unity pro")  return MBProtocol;
+            else if (system == "twincat")    return MBProtocol;
+            else if (system == "standard-c") return MBProtocol;
+            else if (system == "labview")    return CNVProtocol;
+            else throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_PLC_SYSTEM, system);
+		}
+
+
+		ProtocolMode PLC::whichProtocolMode(std::string mode)
+		{
+			StringUtilities::toLower(mode);
+			if (mode == "block_mode") return BlockMode;
+			else if (mode == "device_mode") return DeviceMode;
+			else throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_PROTOCOL_MODE, mode);
+		}
+
+
+		void PLC::updateStatus()
+		{
+			status_.connStatus_ = (getConnection()->isConnected()) ? Connected : Disconnected;
+			status_.plcStatus_ = (getConnection()->isAlive()) ? On : Off;
+			//#FLO problem: qui remet Undefined/Unknown pour ces 2 variables le cas echeant?
+
+			if (DEBUG & Log::topics_) LOG(COMM) << "PLC Status:\n\t" <<
+				getName() << " mode: " << status_.getPLCStatusAsString() << "\n\t" <<
+				theCluster_->getHostName() << "/" << getName() << "/" << theCluster_->getClassName() << " connection: " << status_.getConnectionStatusAsString();
+		}
+
+		void PLC::copyInToOut(const std::string blockName)
+		{
+			deviceVectorType::iterator pDeviceIter;
+			for(pDeviceIter = deviceCol_.begin(); pDeviceIter != deviceCol_.end(); ++pDeviceIter)
+				pDeviceIter->second->copyInToOut(blockName);
+		}
+
+        void PLC::setReadBlockAttributes(const std::string blockName, const unsigned long customAddress, const unsigned long customOffset, const unsigned long customSize)
+	    {
+            //Set the custom offset/size of the referred Input block if any.
+            //Will throw an exception if that block-name does not exist.
+            getBlock(blockName, Input)->setCustomAttributes(customAddress, customOffset, customSize);
+	    }
+
+        void PLC::resetReadBlockAttributes(const std::string blockName)
+        {
+            getBlock(blockName, Input)->resetCustomAttributes();
+        }
+
+        void PLC::setWriteBlockAttributes(const std::string blockName, const unsigned long customAddress, const unsigned long customOffset, const unsigned long customSize)
+        {
+            //Set the custom address/offset/size of the referred Output block if any.
+            //Will throw an exception if that block-name does not exist.
+            getBlock(blockName, Output)->setCustomAttributes(customAddress, customOffset, customSize);
+        }
+
+        void PLC::resetWriteBlockAttributes(const std::string blockName)
+        {
+            getBlock(blockName, Output)->resetCustomAttributes();
+        }
+
+} // namespace
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.h
new file mode 100644
index 0000000000000000000000000000000000000000..d969a79a973656154803e26ab58e864614aca28e
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.h
@@ -0,0 +1,553 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _SILECS_PLC_H_
+#define _SILECS_PLC_H_
+
+#include <silecs-communication/interface/core/Diagnostic.h>
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/utility/Thread.h>
+
+#include <stdint.h>
+#include <string>
+
+namespace Silecs
+{
+	class Connection;
+	class Cluster;
+	class Device;
+	class Block;
+	class WrapperAction;
+
+	/// @cond
+	typedef std::vector<std::pair<std::string, Device*> > deviceVectorType;
+	typedef std::map<std::string, Block*> blockMapType;
+	typedef std::vector<Block*> blockVectorType;
+    typedef std::map<std::string, Connection*> connMapType;
+
+	// PLC brand, system, protocol type and mode
+	typedef enum
+	{
+	   Siemens, Schneider, Ni, Digi, Beckhoff
+	} PLCBrand;
+
+    typedef enum
+    {
+        ET200S, S7300, S7400, S71200, S71500,
+        S7VIRTUAL,
+        Premium, Quantum,
+        M340,
+        BC9020, CX9020,
+        RCM4010, RCM2000,
+        CompactRIO,
+        PXIRT, PXIWindows, PCWindows, OtherSupportCNV
+    } PLCModel;
+
+    typedef enum
+    {
+       Step7, TiaPortal, Unity, TwinCat, StdC, ServerS7, Labview
+    } PLCSystem;
+
+	typedef enum
+	{
+	   MBProtocol, S7Protocol, CNVProtocol
+	} ProtocolType;
+
+	typedef enum
+	{
+	   BlockMode, DeviceMode
+	} ProtocolMode;
+	/// @endcond
+
+    // PLC unit status
+    typedef struct {
+        int status; //bit-pattern hardware specific (look at the related documentation)
+    } UnitStatusType;
+
+	// Order code
+	typedef struct {
+	   std::string code;
+       std::string version;
+	} UnitCodeType;
+
+	// CPU Info
+	typedef struct {
+	   std::string moduleName;
+	   std::string moduleTypeName;
+	   std::string serialNumber;
+	   std::string asName;
+	   std::string copyright;
+	} CPUInfoType;
+
+	// CP Info
+	typedef struct {
+	   int maxPduLength;
+	   int maxConnections;
+	   int maxMPIRate;
+	   int maxBusRate;
+	} CPInfoType;
+
+	/*!
+	 * \class PLC
+	 * \brief This object provides all services related to a PLC. It provides the information
+	 * of the PLC hardware configuration, connection status and diagnostic.
+	 * It maintains a reference of all the PLC devices.
+	 * It can be used to trig the data-block exchanges for all devices of the PLC at the same time.
+	 */
+	class PLC
+	{
+
+	public:
+		/// @cond
+        /*!
+         * \return List of the related Cluster instances (Class/Version) for the PLC.
+         */
+		std::vector<std::string> getDeviceList();
+
+		deviceVectorType& getDeviceMap();
+		/// @endcond
+
+		// Diagnostic features ----------------------------------------
+
+        /*!
+         * \brief Returns the PLC network name
+         * \return PLC host-name
+         */
+		std::string getName();
+
+        /*!
+         * \brief Returns the PLC network address
+         * \return PLC TCP-IP address
+         */
+		std::string getIPAddress();
+
+        /*!
+         * \brief Returns the PLC configuration domain: CPS, PSB, ADE, .., TST
+         * \return Accelerator domain
+         */
+		std::string getDomain();
+
+        /*!
+         * \brief Returns the PLC manufacturer: SIEMENS, SCHNEIDER, BECKHOFF, RABBIT, NI
+         * \return PLC brand
+         */
+		std::string getBrand();
+
+        /*!
+         * \brief Returns the PLC development system: STEP-7, TIA-PORTAL, UNITY Pro, TWINCat, Standard-C, Labview
+         * \return PLC development system
+         */
+        std::string getSystem();
+
+        /*!
+         * \brief Returns PLC hardware model: UNITY_Premium, SIMATIC_S7-300, ..
+         * \return PLC hardware model
+         */
+		std::string getModel();
+
+        /*!
+         * \brief Returns the protocol type used for the PLC communication: MODBUS-TCP, S7-TCP, CNV-TCP
+         * \return PLC protocol type
+         */
+		std::string getProtocolType();
+
+        /*!
+         * \brief Returns the SILECS mode used to map the data within the PLC memory: DEVICE_MODE, BLOCK_MODE
+         * \return PLC protocol mode
+         */
+		std::string getProtocolMode();
+
+        /*!
+         * \brief Returns the base address of the SILECS configuration within the PLC memory
+         * \return DB number for SIMATIC-S7
+         * \return 16bits absolute memory address for UNITY Premium/Quantum
+         * \return 32bits absolute memory address for UNITY M340
+         */
+		unsigned long getBaseAddress();
+
+        /*!
+         * \brief Extracts SILECS release information from the client configuration parameters.
+         * Provides detail about SILECS software used to generate the client documents.
+         * \return SILECS release number
+         */
+		std::string getLocalRelease();
+
+        /*!
+         * \brief Extracts Owner information from the client configuration parameters.
+         * Owner of the deployment document is not necessary responsible for the 'Generate' action
+         * who can be done by any Editor of the document.
+         * \return Owner name
+         */
+		std::string getLocalOwner();
+
+        /*!
+         * \brief Extracts the Date information from the client configuration parameters.
+         * Date of the client parameters file generation.
+         * \return Coordinate Universal Time (UTC)
+         */
+		std::string getLocalDate();
+
+        /*!
+         * \brief Extracts the Checksum information from the client configuration parameters.
+         * CRC-32 Checksum relies on Classes and Deployment documents that have been used to
+         * design the client configuration.
+         * \return CRC32 checksum
+         */
+		unsigned long getLocalChecksum();
+
+		// Miscellaneous features ----------------------------------------
+
+        /*!
+         * \brief Returns one device instance of that PLC by label or index
+         * \param deviceName label or index of the device
+         * \return Reference of the device object
+         */
+		Device* getDevice(std::string deviceName);
+
+        /*!
+         * \brief Used to get the rt-priority of the PLC related thread
+         * \return rt-priority value
+         */
+		unsigned int getThreadPriority();
+
+        /*!
+         * \brief Used to set the real-time priority of the PLC related thread
+         * \param rtPrio value of the priority
+         */
+		void setThreadPriority(unsigned int rtprio);
+
+        /*!
+         * \brief Used to Enable the Client/PLC connection and connect the PLC immediately if needed (connectNow=true).
+         * Just Enabling the connection (connectNow=false) means the connection is allowed and systematically checked on each PLC access (send/recv).
+         * In any case, connect() method downloads the Diagnostic data from the PLC Header memory and checks the Client/PLC configuration consistency.
+         * The 'synchroMode' parameter is used to select the synchronization mode of the retentive Registers.
+         * It must be used carefully since it can overwrite all the PLC Slave registers at the connection time.
+         * \param connectNow = true: Connection is maintained immediately after the Header data update.
+         * connectNow = false: delay the real data connection to the first access attempt (send/recv blocks).
+         * \param synchroMode = NO_SYNCHRO: connect() method does not synchronize any retentive Registers at connection time.
+         * synchroMode = MASTER_SYNCHRO: connect() method downloads all the Master Registers from the PLC memory and updates local Register values at connection time.
+         * synchroMode = SLAVE_SYNCHRO: connect() method transmits all the local Slave Registers values to the PLC at connection time.
+         * synchroMode = FULL_SYNCHRO: connect() method executes MASTER and SLAVE Registers synchronizationat connection time (see above).
+         * \param compareChecksums: Set to false if you want to skip the checksum comparison. Default is true
+         */
+		void connect(SynchroMode synchroMode, bool connectNow, bool compareChecksums = true);
+
+        /*!
+         * \brief Used to disable the Client/PLC connection.
+         * Connection is closed (if needed) and send/recv transaction are not possible anymore (PLC connection is Disabled).
+         * The PLC object still exists on the Cluster and the Registers are available locally.
+         */
+		void disconnect();
+
+        /*!
+         * \brief Returns true if the PLC connection has been requested using connect() method.
+         * \return Enable status
+         */
+		bool isEnabled();
+
+        /*!
+         * \brief Check the connection status and reconnect the controller if required (optional)
+         * Returns true if the PLC connection is established.
+         * \param reconnectNow can be used to force reconnection before checking (false by default).
+         * \return Connection status
+         */
+		bool isConnected(bool reconnectNow=false);
+        bool isSharedConnection() { return isSharedConn_; }
+
+        int recvUnitCode(UnitCodeType& dataStruct);
+        int recvUnitStatus(UnitStatusType& dataStruct);
+        int recvCPUInfo(CPUInfoType& dataStruct);
+        int recvCPInfo(CPInfoType& dataStruct);
+
+        /*!
+         * \brief Acquires one particular registers block of all devices of that PLC.
+         * The method tries to (re)connect the PLC if the connection is not established yet or unexpectedly interrupted (network failure, PLC down, etc.).
+         * It generates an Silecs::SilecsException if the PLC has not been enabled (using the connect() method).
+         * \param blockName name of the block to be acquired
+         * \return 0 if operation was successful else an error code (when available).
+         */
+		int recv(std::string blockName);
+
+        /*!
+         * \brief Transmits the registers block to all devices of that PLC.
+         * The method tries to (re)connect the PLC if the connection is not established yet or unexpectedly interrupted (network failure, PLC down, etc.).
+         * It generates an Silecs::SilecsException if the PLC has not been enabled (using the connect() method).
+         * \param blockName name of the block to be transmitted
+         * \return 0 if operation was successful else an error code (when available).
+         */
+		int send(std::string blockName);
+
+        /*!
+         * \brief Copies input buffer in output buffer
+         * The method copies the input buffer in the output buffer for each READ-WRITE register in the PLC for the block passed as parameter
+         * \param blockName name of the block for which the copy must be performed
+         */
+		void copyInToOut(const std::string blockName);
+
+        /*!
+         * \brief Used to change designed attributes of data block.
+         * In that version, can be used to limit dynamically size of data to be received (recv).
+         * Interesting for specific application that uses general purpose data block with maximum size and adjusts the real data size at communication time.
+         * Caution! This option can be used only with single device access (using DEVICE_MODE or send/recv from the Device level).
+         * \param blockName name of the related block
+         * \param customAddress base address (DBn or absolute in byte) of the data block to be received
+         * \param customOffset offset (in byte) of the data block to be received
+         * \param customSize real size (in byte) of the data block to be received
+         */
+        void setReadBlockAttributes(const std::string blockName, const unsigned long customAddress, const unsigned long customOffset, const unsigned long customSize);
+
+        /*!
+         * \brief Sets back the default attributes of the data block (the ones defined by the design)
+         * \param blockName name of the related block
+         */
+        void resetReadBlockAttributes(const std::string blockName);
+
+        /*!
+         * \brief Used to change designed attributes of a data block.
+         * In that version, can be used to limit dynamically size of data to be sent (send).
+         * Interesting for specific application that uses general purpose data block with maximum size and adjusts the real data size at communication time.
+         * Caution! This option can be used only with single device access (using DEVICE_MODE or send/recv from the Device level).
+         * \param blockName name of the related block
+         * \param customAddress base address (DBn or absolute in byte) of the data block to be sent
+         * \param customOffset offset (in byte) of the data block to be sent
+         * \param customSize real size (in byte) of the data block to be sent
+         */
+        void setWriteBlockAttributes(const std::string blockName, const unsigned long customAddress, const unsigned long customOffset, const unsigned long customSize);
+
+        /*!
+         * \brief Sets back the default attributes of the data block (the ones defined by the design)
+         * \param blockName name of the related block
+         */
+	    void resetWriteBlockAttributes(const std::string blockName);
+
+        /// @cond
+        /*!
+         * \fn getConnection
+         * \brief Use this method to either get an existing Connection object,
+         *  or to create a new one for a given PLC, if not existing.
+         *  Allow sharing connection pipe between different classes if required (from mapping configuration)
+         * \return reference to the [shared-]connection instance of this PLC instance
+         */
+        Connection* createConnection(); //just to instantiate the object
+        Connection* getConnection();
+        static void deleteConnection(); //just to remove shared-connection objects
+        /// @endcond
+
+		const std::string getParamsFileName();
+
+	private:
+		friend class Cluster;
+		friend class Device;
+		friend class Register;
+		friend class Connection;
+		friend class S7Connection;
+		friend class MBConnection;
+        friend class SNAP7Connection;
+
+		// export plcConn_ to Silecs Action
+		friend class Block;
+
+		friend class PLCBlock;
+		friend class InputBlock;
+		friend class OutputBlock;
+		friend class PLCRegister;
+		friend class PLCRecvBlockMode;
+		friend class PLCRecvDeviceMode;
+		friend class PLCSendBlockMode;
+		friend class PLCSendDeviceMode;
+
+        friend class CNVBlock;
+        friend class CNVConnection;
+        friend class CNVInputBlock;
+        friend class CNVOutputBlock;
+        friend class CNVRegister;
+        friend class CNVRecvBlockMode;
+        friend class CNVRecvDeviceMode;
+        friend class CNVSendBlockMode;
+        friend class CNVSendDeviceMode;
+
+		PLC(Cluster* theCluster, std::string plcName, std::string plcIPaddr, string parameterFile);
+		virtual ~PLC();
+
+		inline PLCBrand& getBrandID() { return brandID_; }
+        inline PLCModel& getModelID() { return modelID_; }
+        inline PLCSystem& getSystemID() { return systemID_; }
+		inline ProtocolMode& getProtocolID() { return protocolModeID_; }
+
+        /*!
+         * \fn downloadMasterRegisters
+         * \brief This method is used for Retentive registers synchronization on each PLC (re)connection.
+         * Connects PLC and acquires all Input blocks which contain at least one MASTER retentive register.
+         */
+		void downloadMasterRegisters();
+
+        /*!
+         * \fn checkSlaveRegistersInit
+         * \brief This method checks that all of the retentive Slave Registers are initialized and return
+         * false if not. For obvious security reason, immediate connection of the PLC is not allowed in this case.
+         * \param registerNotInitialized receive first name of the register that is not initialized yet.
+         */
+		bool checkSlaveRegistersInit(std::string& registerNotInitialized);
+
+        /*!
+         * \fn uploadSlaveRegisters
+         * \brief This method is used for Retentive registers synchronization on each PLC (re)connection.
+         * Connects PLC and transmits all Output blocks which contain at least one SLAVE retentive register.
+         */
+		void uploadSlaveRegisters();
+
+        /*!
+         * \fn updateHeader
+         * \brief This method is used to update the unique 'SilecsHeader' Device data of the PLC config.
+         * It consists to create the corresponding Cluster if needed, connect the current PLC,
+         * upload the diagnostic block registers ('hdrBlk') then disconnect the PLC.
+         * \return True if uploading was correctly done.
+         */
+		bool updateHeader();
+
+        /*!
+         * \fn recvAsync/ recvWait
+         * \brief Acquires the 'blockname' data block of all devices of that PLC using asynchronous mode
+         */
+		void recvAsync(std::string blockName);
+
+        /*!
+         * \fn sendAsync/ sendWait
+         * \brief Sends the 'blockname' data block to all devices of that PLC using asynchronous mode
+         */
+		void sendAsync(std::string blockName);
+
+        /*!
+         * \fn waitAsync
+         * \brief Wait for asynchronous call completion (recv/send)
+         */
+		void waitAsync();
+
+        /*!
+         * \fn whichPLC, whichProtocol...
+         * \return the enumeration value of the given Protocol type/mode string
+         */
+		static PLCBrand whichPLCBrand(std::string brand); //SIEMENS, SCHNEIDER, BECKHOFF, ...
+        static PLCModel whichPLCModel(std::string model); //S7-400, S7-300, ...
+        static PLCSystem whichPLCSystem(std::string system); //STEP-7, UNITY, TWINCAT, ...
+		static ProtocolType whichProtocolType(std::string system); //S7, Modbus, CNV, ...
+		static ProtocolMode whichProtocolMode(std::string mode); //Device or Block
+
+        /*!
+         * \fn ExtractDatabase
+         * \brief Parse the Silecs params file and extract the configuration of that PLC.
+         */
+		void extractDatabase();
+
+        /*!
+         * \fn getBlock
+         * \brief returns one instance of the requested block checking its access-type
+         */
+		Block* getBlock(const std::string blockName, AccessType accessType);
+
+        /*!
+         * \brief Provides the  map of the Block objects attached to the underlying PLC(s)
+         * \return Block object map
+         */
+		blockMapType& getBlockMap();
+
+        /*!
+         * \fn updateStatus
+         * \brief update all the status variables of the PLC.
+         */
+		void updateStatus();
+
+		/// Parent cluster reference of that PLC
+		Cluster* theCluster_;
+
+		/// PLC attributes
+		std::string name_;
+		std::string IPaddr_;
+		std::string domain_; //TST, ADE, PSB, CPS, ..
+		std::string brand_; //SIEMENS, SCHNEIDER, ..
+        std::string system_; //STEP-7, UNITY, TWINCAT, ..
+		std::string model_; //SIMATIC S7-300, Premium, ..
+		std::string protocolMode_; //Device, Block
+		std::string protocolType_; //MODBUS-TCP, S7-TCP, ..
+		
+		PLCBrand brandID_; //Siemens, Schneider, ... enumeration
+        PLCModel modelID_; //S7-400, S7-300, ... enumeration
+        PLCSystem systemID_; //Step7, Unity, TwinCat, ... enumeration
+		ProtocolMode protocolModeID_; //BlockMode, DeviceMode enumeration
+		ProtocolType protocolTypeID_; //Modbus, S7 enumeration
+
+		long baseAddr_;
+		std::string usedMem_;
+
+		string parameterFile_;
+
+		// Unique instance of the Header Device for diagnostic purpose
+		Device* theHeader_;
+
+		/* Diagnostic registers are used to check the consistency between the
+		 * PLC memory (remote data) and the client parameters (local data).
+		*/
+		//Local data, extracted from the parameters file
+		std::string localRelease_;  //Release number of the SILECS software
+		std::string localOwner_;	//Owner of the deployment document
+		std::string localDate_;     //Date of the Generation (Client parameters and PLC Sources)
+		uint32_t localChecksum_; //Checksum of the deployed configuration
+
+		//Remote data, uploaded from the PLC memory
+		std::string remoteVersion_;
+		std::string remoteOwner_;
+		std::string remoteDate_;
+		uint32_t remoteChecksum_;
+
+		Context* allDevicesTransaction_;
+		Context* allDevicesSynchronization_;
+
+		/// Related thread allowing cluster PLCs parallelism
+		Thread<WrapperAction>* pThread_;
+
+		/// Device collection of the PLC
+		deviceVectorType deviceCol_;
+
+		/// Block collection of the PLC listed by name.
+		blockMapType blockMap_;
+
+		/// Store references of Slave and Master Blocks for retentive registers synchronization
+		blockVectorType masterInputBlockCol_;
+		blockVectorType slaveOutputBlockCol_;
+
+		/// Object to manage the plc communication
+		/* By default, we instantiate 1 connection (2 channels: r/w) per PLC/Cluster
+		 * In order to safe PLC resources it's possible to share 1 connection between clusters of the same PLC.
+		 * A connection ID is used to define if the connection is shared or not.
+		*/
+		Connection* plcConn_;  // the connection object that can be individual per PLC/Cluster or shared
+		std::string connID_;  // use to identify the connection object in the map (connMap_):
+		                      // individual connection:  <plcName>+<ClassName>
+		                      // shared connection: <plcName>+"SharedConnection"
+        bool isSharedConn_;   // use to know if plcConn_ is shared with others Cluster or not
+
+        /// Connection collection to allow sharing connection channels between different clusters
+        static connMapType connMap_;
+
+        // synchronization mode for each occurence of PLC/Cluster connection: [NO|FULL|SLAVE|MASTER]_SYNCHRO
+        SynchroMode synchroMode_;
+
+		/// Diagnostic status
+		Status status_;
+	};
+
+} // namespace
+
+#endif // _SILECS_PLC_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..901fb367450958b58b6e146ca5b3fd2771f6ff93
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.cpp
@@ -0,0 +1,890 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/utility/XMLParser.h>
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+#include <silecs-communication/interface/equipment/SilecsDevice.h>
+#include <silecs-communication/interface/equipment/SilecsRegister.h>
+#include <silecs-communication/interface/utility/SilecsException.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <silecs-communication/interface/utility/StringUtilities.h>
+#include <silecs-communication/protocol/core/silecs.h>
+
+#include <arpa/inet.h>
+#include <math.h>
+
+namespace Silecs
+{
+
+	Register::Register(Device* theDevice,const boost::shared_ptr<ElementXML>& registerNode) : theDevice_ (theDevice)
+	{
+        name_ = registerNode->getAttribute("name");
+		format_ = whichFormatType(registerNode->getAttribute("format"));
+		StringUtilities::fromString(dimension1_,registerNode->getAttribute("array-dim1") );
+		StringUtilities::fromString(dimension2_,registerNode->getAttribute("array-dim2") );
+		StringUtilities::fromString(size_,registerNode->getAttribute("size") );
+		StringUtilities::fromString(memSize_,registerNode->getAttribute("mem-size") );
+		StringUtilities::fromString(address_,registerNode->getAttribute("address") );
+		synchro_ = Service::whichSynchroType(registerNode->getAttribute("synchro"));
+		isInitialized_ = false; //register not initialized yet (used for output registers)
+
+		// if format is string, retrieve also string-len attribute
+		if (format_ == String)
+		{
+		    StringUtilities::fromString(length_,registerNode->getAttribute("string-len") );
+		    if (DEBUG & Log::topics_) LOG(ALLOC) << "Register (create): " << name_ << ", format: " << getFormatAsString() << ", string-len: " << length_ << ", dim: " << dimension1_ << ", dim2: " << dimension2_ << ", synchro: " << getSynchroTypeAsString() << ", offset: " << address_;
+		}
+		else
+		{
+		    length_ = 1;
+		    if (DEBUG & Log::topics_) LOG(ALLOC) << "Register (create): " << name_ << ", format: " << getFormatAsString() << ", dim: " << dimension1_ << ", dim2: " << dimension2_ << ", synchro: " << getSynchroTypeAsString() << ", offset: " << address_;
+		}
+	}
+
+	Register::~Register()
+	{
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Register (delete): " << name_;
+
+		//Remove the value buffers
+		if (pRecvValue_ != NULL)
+		{   
+            if (format_ == String)
+		    {
+		        // loop through array of pointers and delete them
+		        std::string** pRecvStringValue = static_cast<std::string**>(pRecvValue_);
+		        for (unsigned int i=0; i<dimension1_*dimension2_; i++)
+                {
+		            delete pRecvStringValue[i];
+                }
+		        pRecvStringValue = NULL;
+		    }
+            free(pRecvValue_);
+            pRecvValue_ = NULL;
+		}
+
+		if (pSendValue_ != NULL)
+		{
+		    if(format_ == String)
+		    {
+		        // loop through array of pointers and delete them
+                std::string** pSendStringValue = static_cast<std::string**>(pSendValue_);
+                for (unsigned int i=0; i<dimension1_*dimension2_; i++)
+                {
+                    delete pSendStringValue[i];
+                }
+                pSendStringValue = NULL;
+		    }
+            free(pSendValue_);
+		    pSendValue_ = NULL;
+		}
+	}
+
+	PLC* Register::getPLC() { return theDevice_->getPLC(); }
+	Device* Register::getDevice() { return theDevice_;	}
+
+	// GET methods =============================================================
+	template <typename T>
+	inline T Register::getVal(FormatType F)
+	{
+		if (!hasInputAccess())
+			throw SilecsException(__FILE__, __LINE__, DATA_READ_ACCESS_TYPE_MISMATCH, getName());
+		if ((format_ != F) || !isScalar())
+			throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+		return *((T*)pRecvValue_);
+	}
+
+	template <typename T>
+	inline void Register::getValArray(FormatType F, T* pValue, uint32_t dim)
+	{
+		if (!hasInputAccess())
+			throw SilecsException(__FILE__, __LINE__, DATA_READ_ACCESS_TYPE_MISMATCH, getName());
+		if ((format_ != F) || !isSingleArray())
+			throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+		if (dimension1_ != dim)
+			throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName());
+		memcpy((void *)pValue, pRecvValue_, size_*dimension1_);
+	}
+
+	template <typename T>
+	inline void Register::getValArray2D(FormatType F, T* pValue, uint32_t dim1, uint32_t dim2)
+	{
+	    if(!hasInputAccess())
+	        throw SilecsException(__FILE__, __LINE__, DATA_READ_ACCESS_TYPE_MISMATCH, getName());
+	    if((format_ != F) || !isDoubleArray())
+	        throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+	    if ((dimension1_ != dim1) || (dimension2_ != dim2))
+            throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName());
+	    memcpy((void *)pValue, pRecvValue_, size_*dimension1_*dimension2_);
+	}
+
+	template <typename Tsrc, typename Tdst>
+	inline void Register::convGetValArray(FormatType F, Tdst* pValue, uint32_t dim)
+	{
+		if (!hasInputAccess())
+			throw SilecsException(__FILE__, __LINE__, DATA_READ_ACCESS_TYPE_MISMATCH, getName());
+        if ((format_ != F) || !isSingleArray())
+			throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+		if (dimension1_ != dim)
+			throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName());
+		//automatic conversion from T to F
+		for(unsigned long i=0; i<dimension1_; i++)
+            pValue[i] = ((Tsrc*)pRecvValue_)[i];
+	}
+	
+	template <typename Tsrc, typename Tdst>
+	inline void Register::convGetValArray2D(FormatType F, Tdst* pValue, uint32_t dim1, uint32_t dim2)
+	{
+	    if (!hasInputAccess())
+            throw SilecsException(__FILE__, __LINE__, DATA_READ_ACCESS_TYPE_MISMATCH, getName());
+        if((format_ != F) || !isDoubleArray())
+            throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+        if ((dimension1_ != dim1) || (dimension2_ != dim2))
+            throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName());
+        //automatic conversion from T to F
+        for (unsigned int i=0; i<(dimension1_*dimension2_); i++)
+            ((Tdst*)pValue)[i] = ((Tsrc*)pRecvValue_)[i];
+	}
+
+	template <typename T>
+	inline T* Register::getRefArray(FormatType F, uint32_t& dim)
+	{
+		if (!hasInputAccess())
+			throw SilecsException(__FILE__, __LINE__, DATA_READ_ACCESS_TYPE_MISMATCH, getName());
+        if ((format_ != F) || !isSingleArray())
+			throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+		dim = dimension1_;
+		return  (T*)pRecvValue_;
+	}
+
+	template <typename T>
+	inline T* Register::getRefArray2D(FormatType F, uint32_t& dim1, uint32_t& dim2)
+	{
+	    if (!hasInputAccess())
+            throw SilecsException(__FILE__, __LINE__, DATA_READ_ACCESS_TYPE_MISMATCH, getName());
+        if((format_ != F) || !isDoubleArray())
+	        throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+	    dim1 = dimension1_;
+	    dim2 = dimension2_;
+	    return (T*)pRecvValue_;
+	}
+	
+	// .........................................................................
+	// No template for string format
+    std::string Register::getValString()
+    {
+        if (!hasInputAccess())
+            throw SilecsException(__FILE__, __LINE__, DATA_READ_ACCESS_TYPE_MISMATCH, getName());
+        if ((format_ != String) || (dimension1_ != 1)|| (dimension2_ != 1))
+            throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+        std::string** pRecvStringValue = static_cast<std::string**>(pRecvValue_);
+        return *(pRecvStringValue[0]);
+    }
+
+    void Register::getValStringArray(std::string* pVal, uint32_t dim)
+    {
+        if (!hasInputAccess())
+            throw SilecsException(__FILE__, __LINE__, DATA_READ_ACCESS_TYPE_MISMATCH, getName());
+        if (format_ != String)
+            throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+        if ((dimension1_ != dim) || (dimension2_ > 1))
+            throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName());
+        std::string** pRecvStringValue = static_cast<std::string**>(pRecvValue_);
+        for(unsigned long i=0; i<dimension1_; i++)
+        {   pVal[i] = *(pRecvStringValue[i]);
+        }
+    }
+
+    void Register::getValStringArray2D(std::string* pVal, uint32_t dim1, uint32_t dim2)
+    {
+        if (!hasInputAccess())
+            throw SilecsException(__FILE__, __LINE__, DATA_READ_ACCESS_TYPE_MISMATCH, getName());
+        if (format_ != String)
+            throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+        if ((dimension1_ != dim1) || (dimension2_ != dim2))
+            throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName());
+        std::string** pRecvStringValue = static_cast<std::string**>(pRecvValue_);
+        for(unsigned long i=0; i<dimension1_; i++)
+        {   for(unsigned long j=0; j<dimension2_; j++)
+            {   pVal[(i*dimension2_)+j] = *(pRecvStringValue[(i*dimension2_)+j]);
+            }
+        }
+    }
+
+    const std::string** Register::getRefStringArray(uint32_t& dim)
+    {
+        if (!hasInputAccess())
+            throw SilecsException(__FILE__, __LINE__, DATA_READ_ACCESS_TYPE_MISMATCH, getName());
+        if (dimension1_ <= 1)
+            throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName());
+        dim = dimension1_;
+        return (const std::string**)pRecvValue_;
+    }
+
+    const std::string** Register::getRefStringArray2D(uint32_t& dim1, uint32_t& dim2)
+    {
+        if (!hasInputAccess())
+            throw SilecsException(__FILE__, __LINE__, DATA_READ_ACCESS_TYPE_MISMATCH, getName());
+        if (dimension2_ <= 1)
+            throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName());
+        dim1 = dimension1_;
+        dim2 = dimension2_;
+        return (const std::string**)pRecvValue_;
+    }
+	
+	// .........................................................................
+	//Deprecated: initially for SLC5 (32bits platform)
+	char Register::getValChar() { return (char)getVal<int8_t>(Char);}
+	void Register::getValCharArray(char* pVal, uint32_t dim) { getValArray<int8_t>(Char, (int8_t*)pVal, dim); }
+	void Register::getValCharArray2D(char* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<int8_t>(Char, (int8_t*)pVal, dim1, dim2); }
+	const char* Register::getRefCharArray(uint32_t& dim) { return (const char*)getRefArray<int8_t>(Char, dim); }
+	const char* Register::getRefCharArray2D(uint32_t& dim1, uint32_t& dim2) { return (const char*)getRefArray2D<int8_t>(Char, dim1, dim2); }
+
+	unsigned char Register::getValUChar() { return getVal<uint8_t>(uChar); }
+	void Register::getValUCharArray(unsigned char* pVal, uint32_t dim) { getValArray<uint8_t>(uChar, (uint8_t*)pVal, dim); }
+	void Register::getValUCharArray2D(unsigned char* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<uint8_t>(uChar, (uint8_t*)pVal, dim1, dim2); }
+	void Register::getValUCharArray(short* pVal, uint32_t dim) { convGetValArray<unsigned char,short>(uChar, pVal, dim); }
+	void Register::getValUCharArray2D(short* pVal, uint32_t dim1, uint32_t dim2) { convGetValArray2D<unsigned char,short>(uChar, pVal, dim1, dim2); }
+	const unsigned char* Register::getRefUCharArray(uint32_t& dim) { return (const unsigned char*)getRefArray<uint8_t>(uChar, dim); }
+	const unsigned char* Register::getRefUCharArray2D(uint32_t& dim1, uint32_t& dim2) { return (const unsigned char*)getRefArray2D<uint8_t>(uChar, dim1, dim2); }
+
+	short Register::getValShort() { return (short)getVal<int16_t>(Short); }
+	void Register::getValShortArray(short* pVal, uint32_t dim) { getValArray<int16_t>(Short, (int16_t*)pVal, dim); }
+	void Register::getValShortArray2D(short* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<int16_t>(Short, (int16_t*)pVal, dim1, dim2); }
+	const short* Register::getRefShortArray(uint32_t& dim) { return (short*)getRefArray<int16_t>(Short, dim); }
+	short* Register::getRefShortArray2D(uint32_t& dim1, uint32_t& dim2) { return (short*)getRefArray2D<int16_t>(Short, dim1, dim2); }
+
+	unsigned short Register::getValUShort() { return (unsigned short)getVal<uint16_t>(uShort); }
+	void Register::getValUShortArray(unsigned short* pVal, uint32_t dim) { getValArray<uint16_t>(uShort, (uint16_t*)pVal, dim); }
+	void Register::getValUShortArray2D(unsigned short* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<uint16_t>(uShort, (uint16_t*)pVal, dim1, dim2); }
+	void Register::getValUShortArray(long* pVal, uint32_t dim) { convGetValArray<unsigned short, long>(uShort, pVal, dim); }
+	void Register::getValUShortArray2D(long* pVal, uint32_t dim1, uint32_t dim2) { convGetValArray2D<unsigned short, long>(uShort, pVal, dim1, dim2); }
+	const unsigned short* Register::getRefUShortArray(uint32_t& dim)  { return (const unsigned short*)getRefArray<uint16_t>(uShort, dim); }
+	const unsigned short* Register::getRefUShortArray2D(uint32_t& dim1, uint32_t& dim2)  { return (const unsigned short*)getRefArray2D<uint16_t>(uShort, dim1, dim2); }
+
+	#ifndef __x86_64__
+		//not supported anymore from SLC6 platform (look at <.h> comments)
+		long Register::getValLong() { return (long)getVal<int32_t>(Long); }
+		void Register::getValLongArray(long* pVal, uint32_t dim) { getValArray<int32_t>(Long, (int32_t*)pVal, dim); }
+		void Register::getValLongArray2D(long* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<int32_t>(Long, (int32_t*)pVal, dim1, dim2); }
+		const long* Register::getRefLongArray(uint32_t& dim) { return (const long*)getRefArray<int32_t>(Long, dim); }
+		const long* Register::getRefLongArray2D(uint32_t& dim1, uint32_t& dim2) { return (const long*)getRefArray2D<int32_t>(Long, dim1, dim2); }
+
+		unsigned long Register::getValULong() { return (unsigned long)getVal<uint32_t>(uLong); }
+		void Register::getValULongArray(unsigned long* pVal, uint32_t dim) { getValArray<uint32_t>(uLong, (uint32_t*)pVal, dim); }
+		void Register::getValULongArray2D(unsigned long* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<uint32_t>(uLong, (uint32_t*)pVal, dim1, dim2); }
+		void Register::getValULongArray(long long* pVal, uint32_t dim) { convGetValArray<unsigned long, long long>(uLong, pVal, dim); }
+		void Register::getValULongArray2D(long long* pVal, uint32_t dim1, uint32_t dim2) { convGetValArray2D<unsigned long, long long>(uLong, pVal, dim1, dim2); }
+		const unsigned long* Register::getRefULongArray(uint32_t& dim) { return (const unsigned long*)getRefArray<uint32_t>(uLong, dim); }
+		const unsigned long* Register::getRefULongArray2D(uint32_t& dim1, uint32_t& dim2) { return (const unsigned long*)getRefArray2D<uint32_t>(uLong, dim1, dim2); }
+	#endif
+
+	float Register::getValFloat() { return getVal<float>(Float); }
+	void Register::getValFloatArray(float* pVal, uint32_t dim) { getValArray<float>(Float, pVal, dim); }
+	void Register::getValFloatArray2D(float* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<float>(Float, pVal, dim1, dim2); }
+	const float* Register::getRefFloatArray(uint32_t& dim) { return getRefArray<float>(Float, dim); }
+	const float* Register::getRefFloatArray2D(uint32_t& dim1, uint32_t& dim2) { return getRefArray2D<const float>(Float, dim1, dim2); }
+
+	double Register::getValDate() { return getVal<double>(Date); }
+	void Register::getValDateArray(double* pVal, uint32_t dim) { getValArray<double>(Date, pVal, dim); }
+	void Register::getValDateArray2D(double* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<double>(Date, pVal, dim1, dim2); }
+	const double* Register::getRefDateArray(uint32_t& dim) { return getRefArray<double>(Date, dim); }
+	double* Register::getRefDateArray2D(uint32_t& dim1, uint32_t& dim2) { return getRefArray2D<double>(Date, dim1, dim2); }
+
+	// .........................................................................
+	//Recommended: from SLC6 (32bits and 64bits platform)
+	int8_t Register::getValInt8() { return getVal<int8_t>(Int8); }
+	void Register::getValInt8Array(int8_t* pVal, uint32_t dim) { getValArray<int8_t>(Int8, pVal, dim); }
+	void Register::getValInt8Array2D(int8_t* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<int8_t>(Int8, pVal, dim1, dim2); }
+	const int8_t* Register::getRefInt8Array(uint32_t& dim) { return getRefArray<int8_t>(Int8, dim); }
+	int8_t* Register::getRefInt8Array2D(uint32_t& dim1, uint32_t& dim2) { return getRefArray2D<int8_t>(Int8, dim1, dim2); }
+
+	uint8_t Register::getValUInt8() { return getVal<uint8_t>(uInt8); }
+	void Register::getValUInt8Array(uint8_t* pVal, uint32_t dim) { getValArray<uint8_t>(uInt8, pVal, dim); }
+	void Register::getValUInt8Array2D(uint8_t* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<uint8_t>(uInt8, pVal, dim1, dim2); }
+	void Register::getValUInt8Array(int16_t* pVal, uint32_t dim) { convGetValArray<uint8_t, int16_t>(uInt8, pVal, dim); }
+	void Register::getValUInt8Array2D(int16_t* pVal, uint32_t dim1, uint32_t dim2) { convGetValArray2D<uint8_t, int16_t>(uInt8, pVal, dim1, dim2); }
+	const uint8_t* Register::getRefUInt8Array(uint32_t& dim) { return getRefArray<uint8_t>(uInt8, dim); }
+	uint8_t* Register::getRefUInt8Array2D(uint32_t& dim1, uint32_t& dim2) { return getRefArray2D<uint8_t>(uInt8, dim1, dim2); }
+
+	int16_t Register::getValInt16() { return getVal<int16_t>(Int16); }
+	void Register::getValInt16Array(int16_t* pVal, uint32_t dim) { getValArray<int16_t>(Int16, pVal, dim); }
+	void Register::getValInt16Array2D(int16_t* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<int16_t>(Int16, pVal, dim1, dim2); }
+	const int16_t* Register::getRefInt16Array(uint32_t& dim) { return getRefArray<int16_t>(Int16, dim); }
+	int16_t* Register::getRefInt16Array2D(uint32_t& dim1, uint32_t& dim2) { return getRefArray2D<int16_t>(Int16, dim1, dim2); }
+
+	uint16_t Register::getValUInt16() { return getVal<uint16_t>(uInt16); }
+	void Register::getValUInt16Array(uint16_t* pVal, uint32_t dim) { getValArray<uint16_t>(uInt16, pVal, dim); }
+	void Register::getValUInt16Array2D(uint16_t* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<uint16_t>(uInt16, pVal, dim1, dim2); }
+	void Register::getValUInt16Array(int32_t* pVal, uint32_t dim) { convGetValArray<uint16_t, int32_t>(uInt16, pVal, dim); }
+	void Register::getValUInt16Array2D(int32_t* pVal, uint32_t dim1, uint32_t dim2) { convGetValArray2D<uint16_t, int32_t>(uInt16, pVal, dim1, dim2); }
+	const uint16_t* Register::getRefUInt16Array(uint32_t& dim) { return getRefArray<uint16_t>(uInt16, dim); }
+	uint16_t* Register::getRefUInt16Array2D(uint32_t& dim1, uint32_t& dim2) { return getRefArray2D<uint16_t>(uInt16, dim1, dim2); }
+
+	int32_t Register::getValInt32() { return getVal<int32_t>(Int32); }
+	void Register::getValInt32Array(int32_t* pVal, uint32_t dim) { getValArray<int32_t>(Int32, pVal, dim); }
+	void Register::getValInt32Array2D(int32_t* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<int32_t>(Int32, pVal, dim1, dim2); }
+	const int32_t* Register::getRefInt32Array(uint32_t& dim) { return getRefArray<int32_t>(Int32, dim); }
+	int32_t* Register::getRefInt32Array2D(uint32_t& dim1, uint32_t& dim2) { return getRefArray2D<int32_t>(Int32, dim1, dim2); }
+
+	uint32_t Register::getValUInt32() { return getVal<uint32_t>(uInt32); }
+	void Register::getValUInt32Array(uint32_t* pVal, uint32_t dim) { getValArray<uint32_t>(uInt32, pVal, dim); }
+	void Register::getValUInt32Array2D(uint32_t* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<uint32_t>(uInt32, pVal, dim1, dim2); }
+	void Register::getValUInt32Array(int64_t* pVal, uint32_t dim) { convGetValArray<uint32_t, int64_t>(uInt32, pVal, dim); }
+	void Register::getValUInt32Array2D(int64_t* pVal, uint32_t dim1, uint32_t dim2) { convGetValArray2D<uint32_t, int64_t>(uInt32, pVal, dim1, dim2); }
+	const uint32_t* Register::getRefUInt32Array(uint32_t& dim) { return getRefArray<uint32_t>(uInt32, dim); }
+	uint32_t* Register::getRefUInt32Array2D(uint32_t& dim1, uint32_t& dim2) { return getRefArray2D<uint32_t>(uInt32, dim1, dim2); }
+
+	int64_t Register::getValInt64() { return getVal<int64_t>(Int64); }
+	void Register::getValInt64Array(int64_t* pVal, uint32_t dim) { getValArray<int64_t>(Int64, pVal, dim); }
+	void Register::getValInt64Array2D(int64_t* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<int64_t>(Int64, pVal, dim1, dim2); }
+	const int64_t* Register::getRefInt64Array(uint32_t& dim) { return getRefArray<int64_t>(Int64, dim); }
+	int64_t* Register::getRefInt64Array2D(uint32_t& dim1, uint32_t& dim2) { return getRefArray2D<int64_t>(Int64, dim1, dim2); }
+
+	uint64_t Register::getValUInt64() { return getVal<uint64_t>(uInt64); }
+	void Register::getValUInt64Array(uint64_t* pVal, uint32_t dim) { getValArray<uint64_t>(uInt64, pVal, dim); }
+	void Register::getValUInt64Array2D(uint64_t* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<uint64_t>(uInt64, pVal, dim1, dim2); }
+	const uint64_t* Register::getRefUInt64Array(uint32_t& dim) { return getRefArray<uint64_t>(uInt64, dim); }
+	uint64_t* Register::getRefUInt64Array2D(uint32_t& dim1, uint32_t& dim2) { return getRefArray2D<uint64_t>(uInt64, dim1, dim2); }
+
+	float Register::getValFloat32() { return getVal<float>(Float32); }
+	void Register::getValFloat32Array(float* pVal, uint32_t dim) { getValArray<float>(Float32, pVal, dim); }
+	void Register::getValFloat32Array2D(float* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<float>(Float32, pVal, dim1, dim2); }
+	const float* Register::getRefFloat32Array(uint32_t& dim) { return getRefArray<float>(Float32, dim); }
+	float* Register::getRefFloat32Array2D(uint32_t& dim1, uint32_t& dim2) { return getRefArray2D<float>(Float32, dim1, dim2); }
+
+	double Register::getValFloat64() { return getVal<double>(Float64); }
+	void Register::getValFloat64Array(double* pVal, uint32_t dim) { getValArray<double>(Float64, pVal, dim); }
+	void Register::getValFloat64Array2D(double* pVal, uint32_t dim1, uint32_t dim2) { getValArray2D<double>(Float64, pVal, dim1, dim2); }
+	const double* Register::getRefFloat64Array(uint32_t& dim) { return getRefArray<double>(Float64, dim); }
+	double* Register::getRefFloat64Array2D(uint32_t& dim1, uint32_t& dim2) { return getRefArray2D<double>(Float64, dim1, dim2); }
+
+	// SET methods =============================================================
+	void Register::setAccessType(AccessType accessType)
+	{
+	  accessType_ =  accessType;
+
+	  // By knowing the register type we can allocate 1 or 2 buffers for data exchanges.
+	  pRecvValue_ = pSendValue_ = NULL;
+
+	  if (Service::withInputAccess(accessType))
+	  {
+	      if (format_ == String)
+	      {
+	          pRecvValue_ = calloc(dimension1_*dimension2_, sizeof(void*));
+	          std::string** pRecvStringValue = static_cast<std::string**>(pRecvValue_);
+
+              // allocate memory for the required pointers to the strings
+              for (unsigned long i=0; i<dimension1_*dimension2_; i++)
+              { pRecvStringValue[i] = new std::string();
+              }
+	      }
+	      else  // If not string register just allocate space for data
+	      {
+	          pRecvValue_ = calloc(dimension1_*dimension2_, size_);
+	      }
+	  }
+
+	  if (Service::withOutputAccess(accessType))
+	  {
+	      if (format_ == String)
+	      {
+                pSendValue_ = calloc(dimension1_*dimension2_, sizeof(void*));
+                std::string** pSendStringValue = static_cast<std::string**>(pSendValue_);
+
+                //allocate memory for the required pointers to the strings
+                for (unsigned long i=0; i<dimension1_*dimension2_; i++)
+                {   // allocate space for the string object
+                    pSendStringValue[i] = new std::string();
+                }
+	      }
+          else  // if not string register just allocate space for data
+          {
+              pSendValue_ = calloc(dimension1_*dimension2_, size_);
+          }
+	  }
+
+	  /* The synchronization mode and the Access type of the register must be compatible:
+	   * - Read-only register cannot have SLAVE synchronization (not supported: has to be Read-Write register)
+	   * - Write-only register cannot have MASTER synchronization (does not make sense)
+	   */
+	  if ( ((accessType_ == Input) && (synchro_ == Slave) ) ||
+		   ((accessType_ == Output) && (synchro_ == Master) ))
+		  throw SilecsException(__FILE__, __LINE__, DATA_SYNCHRO_ACCESS_TYPE_MISMATCH, name_);
+	}
+
+	template <typename T>
+	inline void Register::setVal(FormatType F, T val)
+	{
+		if (!hasOutputAccess())
+			throw SilecsException(__FILE__, __LINE__, DATA_WRITE_ACCESS_TYPE_MISMATCH, getName());
+		if ((format_ != F) || (dimension1_ != 1))
+			throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+		*((T*)pSendValue_) = val;
+		isInitialized_ = true; //the register value has been set once at least
+	}
+
+	template <typename T>
+	inline void Register::setValArray(FormatType F, const T* pVal, uint32_t dim)
+	{
+		if (!hasOutputAccess())
+			throw SilecsException(__FILE__, __LINE__, DATA_WRITE_ACCESS_TYPE_MISMATCH, getName());
+		if (format_ != F)
+			throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+		if (dimension1_ != dim)
+			throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName());
+		memcpy(pSendValue_, (void *)pVal, size_*dimension1_);
+		isInitialized_ = true; //the register value has been set once at least
+	}
+
+	template <typename T>
+    inline void Register::setValArray2D(FormatType F, const T* pVal, uint32_t dim1, uint32_t dim2)
+    {
+        if (!hasOutputAccess())
+            throw SilecsException(__FILE__, __LINE__, DATA_WRITE_ACCESS_TYPE_MISMATCH, getName());
+        if (format_ != F)
+            throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+        if ((dimension1_ != dim1) || (dimension2_ != dim2))
+            throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName());
+        memcpy(pSendValue_, (void *)pVal, size_*dimension1_*dimension2_);
+        isInitialized_ = true; //the register value has been set once at least
+    }
+
+	template <typename Tsrc, typename Tdst>
+	inline void Register::convSetValArray(FormatType F, const Tsrc* pVal, uint32_t dim)
+	{
+		if (!hasOutputAccess())
+			throw SilecsException(__FILE__, __LINE__, DATA_WRITE_ACCESS_TYPE_MISMATCH, getName());
+		if (format_ != F)
+			throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+		if (dimension1_ != dim)
+			throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName());
+		// conversion from Type-source to Type-destination
+		for(unsigned long i=0; i<dimension1_; i++)
+		    ((Tdst*)pSendValue_)[i] = pVal[i];
+		isInitialized_ = true; //the register value has been set once at least
+	}
+	
+	template <typename Tsrc, typename Tdst>
+    inline void Register::convSetValArray2D(FormatType F, const Tsrc* pVal, uint32_t dim1, uint32_t dim2)
+    {
+        if (!hasOutputAccess())
+            throw SilecsException(__FILE__, __LINE__, DATA_WRITE_ACCESS_TYPE_MISMATCH, getName());
+        if (format_ != F)
+            throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+        if ((dimension1_ != dim1) || (dimension2_ != dim2))
+            throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName());
+        // conversion from Type-source to Type-destination
+        for(unsigned long i=0; i<(dimension1_*dimension2_); i++)
+            ((Tdst*)pSendValue_)[i] = ((Tsrc*)pVal)[i];
+        isInitialized_ = true; //the register value has been set once at least
+    }
+
+	// .........................................................................
+    // No template for string format
+	void Register::setValString(std::string val)
+	{
+	    if (!hasOutputAccess())
+            throw SilecsException(__FILE__, __LINE__, DATA_WRITE_ACCESS_TYPE_MISMATCH, getName());
+	    if ((format_ != String) || (dimension1_ != 1)|| (dimension2_ != 1))
+	        throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+
+        std::string** pSendStringValue = static_cast<std::string**>(pSendValue_);
+        *(pSendStringValue[0]) = val;
+        isInitialized_ = true; //the register value has been set once at least
+	}
+
+	void Register::setValStringArray(const std::string* pVal, uint32_t dim)
+	{
+	    if (!hasOutputAccess())
+            throw SilecsException(__FILE__, __LINE__, DATA_WRITE_ACCESS_TYPE_MISMATCH, getName());
+        if (format_ != String)
+            throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+        if (dimension1_ != dim || dimension2_ > 1)
+            throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName());
+
+        std::string** pSendStringValue = static_cast<std::string**>(pSendValue_);
+        for(unsigned long i=0; i<dimension1_; i++)
+        {  *(pSendStringValue[i]) = pVal[i];
+        }
+        isInitialized_ = true; //the register value has been set once at least
+	}
+
+	void Register::setValStringArray2D(const std::string* pVal, uint32_t dim1, uint32_t dim2)
+	{
+        if (!hasOutputAccess())
+            throw SilecsException(__FILE__, __LINE__, DATA_WRITE_ACCESS_TYPE_MISMATCH, getName());
+        if (format_ != String)
+            throw SilecsException(__FILE__, __LINE__, PARAM_FORMAT_TYPE_MISMATCH, getName());
+        if (dimension1_ != dim1 || dimension2_ != dim2)
+            throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName());
+
+        std::string** pSendStringValue = static_cast<std::string**>(pSendValue_);
+        for (unsigned long i=0; i<dimension1_; i++)
+        {   for (unsigned long j=0; j<dimension2_; j++)
+            {   *(pSendStringValue[(i*dimension2_)+j]) = pVal[(i*dimension2_)+j];
+            }
+        }
+        isInitialized_ = true;  //the register value has been set once at least
+	}
+
+	// .........................................................................
+	//Deprecated: initially for SLC5 (32bits platform)
+	void Register::setValChar(char val) { setVal<int8_t>(Int8, (int8_t)val); }
+	void Register::setValCharArray(const char* pVal, uint32_t dim) { setValArray<int8_t>(Char, (int8_t*)pVal, dim); }
+	void Register::setValCharArray2D(const char* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<int8_t>(Char, (const int8_t*)pVal, dim1, dim2); }
+
+	void Register::setValUChar(unsigned char val) { setVal<uint8_t>(uChar, (uint8_t)val); }
+	void Register::setValUCharArray(const unsigned char* pVal, uint32_t dim) { setValArray<uint8_t>(uChar, (uint8_t*)pVal, dim); }
+	void Register::setValUCharArray2D(const unsigned char* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<uint8_t>(uChar, (const uint8_t*)pVal, dim1, dim2); }
+	void Register::setValUCharArray(const short* pVal, uint32_t dim) { convSetValArray<short,unsigned char>(uChar, pVal, dim); }
+	void Register::setValUCharArray2D(const short* pVal, uint32_t dim1, uint32_t dim2) { convSetValArray2D<short,unsigned char>(uChar, pVal, dim1, dim2); }
+
+	void Register::setValShort(short val) { setVal<int16_t>(Short, (int16_t)val); }
+	void Register::setValShortArray(const short* pVal, uint32_t dim) { setValArray<int16_t>(Short, (int16_t*)pVal, dim); }
+	void Register::setValShortArray2D(const short* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<int16_t>(Short, (const int16_t*)pVal, dim1, dim2); }
+
+	void Register::setValUShort(unsigned short val) { setVal<uint16_t>(uShort, (uint16_t)val); }
+	void Register::setValUShortArray(const unsigned short* pVal, uint32_t dim) { setValArray<uint16_t>(uShort, (uint16_t*)pVal, dim); }
+	void Register::setValUShortArray2D(const unsigned short* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<uint16_t>(uShort, (const uint16_t*)pVal, dim1,  dim2); }
+	void Register::setValUShortArray(const long* pVal, uint32_t dim) { convSetValArray<long,unsigned short>(uShort, pVal, dim); }
+	void Register::setValUShortArray2D(const long* pVal, uint32_t dim1, uint32_t dim2) { convSetValArray2D<long,unsigned short>(uShort, pVal, dim1, dim2); }
+
+	#ifndef __x86_64__
+		//not supported anymore from SLC6 platform (look at <.h> comments)
+		void Register::setValLong(long val) { setVal<int32_t>(Long, (int32_t)val); }
+		void Register::setValLongArray(const long* pVal, uint32_t dim) { setValArray<int32_t>(Long, (int32_t*)pVal, dim); }
+		void Register::setValLongArray2D(const long* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<int32_t>(Long, (int32_t*)pVal, dim1, dim2); }
+
+		void Register::setValULong(unsigned long val) { setVal<uint32_t>(uLong, (uint32_t)val); }
+		void Register::setValULongArray(const unsigned long* pVal, uint32_t dim) { setValArray<uint32_t>(uLong, (uint32_t*)pVal, dim); }
+		void Register::setValULongArray2D(const unsigned long* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<uint32_t>(uLong, (uint32_t*)pVal, dim1, dim2); }
+		void Register::setValULongArray(const long long* pVal, uint32_t dim) { convSetValArray<long long,unsigned long>(uLong, pVal, dim); }
+		void Register::setValULongArray2D(const long long* pVal, uint32_t dim1, uint32_t dim2) { convSetValArray2D<long long,unsigned long>(uLong, pVal, dim1, dim2); }
+	#endif
+
+	void Register::setValFloat(float val) { setVal<float>(Float, val); }
+	void Register::setValFloatArray(const float* pVal, uint32_t dim) { setValArray<float>(Float, pVal, dim); }
+	void Register::setValFloatArray2D(const float* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<float>(Float, pVal, dim1, dim2); }
+
+	//Set date is not required for the time being
+	void Register::setValDate(double val) { setVal<double>(Date, val); }
+	void Register::setValDateArray(const double* pVal, uint32_t dim) { setValArray<double>(Date, pVal, dim); }
+    void Register::setValDateArray2D(const double* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<double>(Date, pVal, dim1, dim2); }
+
+	// .........................................................................
+	//Recommended: from SLC6 (32bits and 64bits platform)
+	void Register::setValInt8(int8_t val) { setVal<int8_t>(Int8, val); }
+	void Register::setValInt8Array(const int8_t* pVal, uint32_t dim) { setValArray<int8_t>(Int8, pVal, dim); }
+	void Register::setValInt8Array2D(const int8_t* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<int8_t>(Int8, pVal, dim1, dim2); }
+
+	void Register::setValUInt8(uint8_t val) { setVal<uint8_t>(uInt8, val); }
+	void Register::setValUInt8Array(const uint8_t* pVal, uint32_t dim) { setValArray<uint8_t>(uInt8, pVal, dim); }
+	void Register::setValUInt8Array2D(const uint8_t* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<uint8_t>(uInt8, pVal, dim1, dim2); }
+	void Register::setValUInt8Array(const int16_t* pVal, uint32_t dim) { convSetValArray<int16_t, uint8_t>(uInt8, pVal, dim); }
+	void Register::setValUInt8Array2D(const int16_t* pVal, uint32_t dim1, uint32_t dim2) { convSetValArray2D<int16_t, uint8_t>(uInt8, pVal, dim1, dim2); }
+
+	void Register::setValInt16(int16_t val) { setVal<int16_t>(Int16, val); }
+	void Register::setValInt16Array(const int16_t* pVal, uint32_t dim) { setValArray<int16_t>(Int16, pVal, dim); }
+	void Register::setValInt16Array2D(const int16_t* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<int16_t>(Int16, pVal, dim1, dim2); }
+
+	void Register::setValUInt16(uint16_t val) { setVal<uint16_t>(uInt16, val); }
+	void Register::setValUInt16Array(const uint16_t* pVal, uint32_t dim) { setValArray<uint16_t>(uInt16, pVal, dim); }
+	void Register::setValUInt16Array2D(const uint16_t* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<uint16_t>(uInt16, pVal, dim1, dim2); }
+	void Register::setValUInt16Array(const int32_t* pVal, uint32_t dim) { convSetValArray<int32_t, uint16_t>(uInt16, pVal, dim); }
+	void Register::setValUInt16Array2D(const int32_t* pVal, uint32_t dim1, uint32_t dim2) { convSetValArray2D<int32_t, uint16_t>(uInt16, pVal, dim1, dim2); }
+
+	void Register::setValInt32(int32_t val) { setVal<int32_t>(Int32, val); }
+	void Register::setValInt32Array(const int32_t* pVal, uint32_t dim) { setValArray<int32_t>(Int32, pVal, dim); }
+	void Register::setValInt32Array2D(const int32_t* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<int32_t>(Int32, pVal, dim1, dim2); }
+
+	void Register::setValUInt32(uint32_t val) { setVal<uint32_t>(uInt32, val); }
+	void Register::setValUInt32Array(const uint32_t* pVal, uint32_t dim) { setValArray<uint32_t>(uInt32, pVal, dim); }
+	void Register::setValUInt32Array2D(const uint32_t* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<uint32_t>(uInt32, pVal, dim1, dim2); }
+	void Register::setValUInt32Array(const int64_t* pVal, uint32_t dim) { convSetValArray<int64_t, uint32_t>(uInt32, pVal, dim); }
+	void Register::setValUInt32Array2D(const int64_t* pVal, uint32_t dim1, uint32_t dim2) { convSetValArray2D<int64_t, uint32_t>(uInt32, pVal, dim1, dim2); }
+
+	void Register::setValInt64(int64_t val) { setVal<int64_t>(Int64, val); }
+	void Register::setValInt64Array(const int64_t* pVal, uint32_t dim) { setValArray<int64_t>(Int64, pVal, dim); }
+	void Register::setValInt64Array2D(const int64_t* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<int64_t>(Int64, pVal, dim1, dim2); }
+
+	void Register::setValUInt64(uint64_t val) { setVal<uint64_t>(uInt64, val); }
+	void Register::setValUInt64Array(const uint64_t* pVal, uint32_t dim) { setValArray<uint64_t>(uInt64, pVal, dim); }
+	void Register::setValUInt64Array2D(const uint64_t* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<uint64_t>(uInt64, pVal, dim1, dim2); }
+
+	void Register::setValFloat32(float val) { setVal<float>(Float32, val); }
+	void Register::setValFloat32Array(const float* pVal, uint32_t dim) { setValArray<float>(Float32, pVal, dim); }
+	void Register::setValFloat32Array2D(const float* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<float>(Float32, pVal, dim1, dim2); }
+
+	void Register::setValFloat64(double val) { setVal<double>(Float64, val); }
+	void Register::setValFloat64Array(const double* pVal, uint32_t dim) { setValArray<double>(Float64, pVal, dim); }
+	void Register::setValFloat64Array2D(const double* pVal, uint32_t dim1, uint32_t dim2) { setValArray2D<double>(Float64, pVal, dim1, dim2); }
+
+	// .........................................................................
+	std::string Register::getName() { return name_; }
+	unsigned long Register::getDimension(uint16_t whichDim) { return ((whichDim == 2) ? dimension2_ : dimension1_); }
+	uint32_t Register::getDimension1() { return dimension1_; }
+	uint32_t Register::getDimension2() { return dimension2_; }
+	uint32_t Register::getLength() {return length_; };
+	FormatType Register::getFormat() { return format_; }
+	std::string Register::getBlockName() { return blockName_; }
+	std::string Register::getFormatAsString() { return FormatTypeString[format_]; }
+	SynchroType Register::getSynchroType() { return synchro_; }
+	std::string Register::getSynchroTypeAsString() { return SynchroTypeString[synchro_]; }
+
+	bool Register::hasInputAccess() { return (accessType_ != Output); }
+	bool Register::hasOutputAccess() { return (accessType_ != Input); }
+
+	bool Register::isRetentive() { return (synchro_ != No); }
+	bool Register::isVolatile() { return (synchro_ == No); }
+    bool Register::isScalar() { return ((dimension1_ == 1) && (dimension2_ == 1)); }
+    bool Register::isSingleArray() { return ((dimension1_ > 1) && (dimension2_ == 1)); }
+    bool Register::isDoubleArray() { return (dimension2_ > 1); }
+	bool Register::isInitialized() { return isInitialized_; }
+
+	FormatType Register::whichFormatType(std::string type)
+	{
+		StringUtilities::toLower(type);
+#ifndef __x86_64__
+//SLC5 (32bits platform) still uses deprecated types ========
+		if (type == "byte") return uChar;
+		else if (type == "int") return Short;
+		else if (type == "word") return uShort;
+		else if (type == "dint") return Long;
+		else if (type == "dword") return uLong;
+		else if (type == "real") return Float;
+#else
+//SLC6 (64bits platform) ====================================
+		if (type == "byte") return uInt8;
+		else if (type == "int") return Int16;
+		else if (type == "word") return uInt16;
+		else if (type == "dint") return Int32;
+		else if (type == "dword") return uInt32;
+		else if (type == "real") return Float32;
+#endif
+// ANY platform =============================================
+		if (type == "char") return Char;
+
+		else if (type == "dt") return Date;
+		else if (type == "date") return Date;
+
+		else if (type == "int8") return Int8;
+		else if (type == "uint8") return uInt8;
+		else if (type == "int16") return Int16;
+		else if (type == "uint16") return uInt16;
+		else if (type == "int32") return Int32;
+		else if (type == "uint32") return uInt32;
+		else if (type == "int64") return Int64;
+		else if (type == "uint64") return uInt64;
+		else if (type == "float32") return Float32;
+		else if (type == "float64") return Float64;
+		else if (type == "string") return String;
+		else throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_FORMAT_TYPE, type);
+	}
+
+
+	std::string Register::getValAsByteString(void* pValue, unsigned long maxSize)
+	{
+		std::ostringstream os;
+        std::string** pStringValue = static_cast<std::string**>(pValue);
+        unsigned long nbElement = dimension1_*dimension2_;
+        unsigned long byteSize = nbElement*size_;
+        unsigned long nbLoop = (getFormat() == String) ? nbElement : byteSize;
+
+        for (unsigned int i=0; i<nbLoop; i++)
+        {
+            if ((i==maxSize) && (nbLoop > 2*maxSize))
+            {   i = nbLoop - maxSize;
+                os << ".... ";
+            }
+
+          if (getFormat() == String) {
+              os << *pStringValue[i] << " ";
+          }
+          else {
+              os << (unsigned int)((unsigned char*)pValue)[i] << " ";
+          }
+        }
+	    return os.str();
+	}
+
+
+	std::string Register::getValAsString(void* pValue, unsigned long i, unsigned long j)
+	{
+		struct tm dscst;
+		std::ostringstream os;
+
+		//get element whatever is the value dimension (scalar, single array or flat 2D-array)
+        unsigned long index = (i*dimension2_)+j;
+
+        if ((i>=dimension1_) || (j>=dimension2_))
+		{   throw SilecsException(__FILE__, __LINE__, PARAM_ARRAY_DIMENSION_MISMATCH, getName());
+		}
+
+		switch (format_)
+		{	// -------- Deprecated types (32bits platform only)
+			//case Char:	os << (char)((char*)pValue)[index]; 					break;
+			//case uChar:	os << (unsigned int)((unsigned char*)pValue)[index];	break;
+			//case Short:	os << (short)((short*)pValue)[index];					break;
+			//case uShort:	os << (unsigned short)((unsigned short*)pValue)[index];	break;
+			//case Long:	os << (long)((long*)pValue)[index];						break;
+			//case uLong:	os << (unsigned long)((unsigned long*)pValue)[index];	break;
+			//case Float:	os << (float)((float*)pValue)[index];					break;
+			//-------- Supported types (32 and 64bits platform)
+			case Int8:		os << (int8_t)((int8_t*)pValue)[index];					break;
+			case uInt8:		os << (uint16_t)((uint8_t*)pValue)[index];				break;
+			case Int16:		os << (int16_t)((int16_t*)pValue)[index];				break;
+			case uInt16:	os << (uint16_t)((uint16_t*)pValue)[index];				break;
+			case Int32:		os << (int32_t)((int32_t*)pValue)[index];				break;
+			case uInt32:	os << (uint32_t)((uint32_t*)pValue)[index];				break;
+			case Int64:		os << (int64_t)((int64_t*)pValue)[index];				break;
+			case uInt64:	os << (uint64_t)((uint64_t*)pValue)[index];				break;
+			case Float32:	os << (float)((float*)pValue)[index];					break;
+			case Float64:	os << (double)((double*)pValue)[index];					break;
+			case String:
+			{   std::string** pStringValue = static_cast<std::string**>(pValue);
+			    os << *(pStringValue[index]);
+			    break;
+			}
+			case Date:
+			{	 dscst = getTMDate(((double*)pValue)[index]);
+				 os << dscst.tm_year+1900 << "-" << dscst.tm_mon+1 << "-" << dscst.tm_mday << "-" << dscst.tm_hour << ":" << dscst.tm_min << ":" << dscst.tm_sec << " ";
+				 break;
+			}
+			default:
+				throw SilecsException(__FILE__, __LINE__, DATA_UNKNOWN_FORMAT_TYPE, StringUtilities::toString(format_));
+		}
+	    return os.str();
+	}
+
+
+    std::string Register::getInputValAsString() { return getInputValAsString(0, 0); };
+    std::string Register::getInputValAsString(unsigned long i) { return getInputValAsString(i, 0); };
+	std::string Register::getInputValAsString(unsigned long i, unsigned long j)
+	{
+		if (hasInputAccess())
+		{   return getValAsString(pRecvValue_,i,j);
+		}
+		else
+			throw SilecsException(__FILE__, __LINE__, DATA_READ_ACCESS_TYPE_MISMATCH, getName());
+	}
+
+
+    std::string Register::getOutputValAsString() { return getOutputValAsString(0, 0); };
+    std::string Register::getOutputValAsString(unsigned long i) { return getOutputValAsString(i, 0); };
+	std::string Register::getOutputValAsString(unsigned long i, unsigned long j)
+	{
+		if (hasOutputAccess())
+        {   return getValAsString(pSendValue_,i,j);
+		}
+		else
+			throw SilecsException(__FILE__, __LINE__, DATA_READ_ACCESS_TYPE_MISMATCH, getName());
+	}
+
+
+	std::string Register::dumpInputVal(bool asAsciiChar)
+	{
+		std::ostringstream os;
+		unsigned long byteSize = dimension1_*dimension2_*size_;
+		for (unsigned int i=0; i<byteSize; i++)
+		{
+		    if (asAsciiChar)
+		    {
+		        // Returns when end of string is found
+		        // TODO Release 4.0.0: add this check only for String registers
+		        if(((char)((unsigned char*)pRecvValue_)[i]) == 0)   // returns as soon as it reaches the end of the string
+                    break;
+		        os << (char)((unsigned char*)pRecvValue_)[i];
+		    }
+		    else
+		        os << hex << (unsigned int)((unsigned char*)pRecvValue_)[i] << " ";
+		}
+	    return os.str();
+	}
+
+
+	std::string Register::dumpOutputVal(bool asAsciiChar)
+	{
+		std::ostringstream os;
+		unsigned long byteSize = dimension1_*dimension2_*size_;
+		for (unsigned int i=0; i<byteSize; i++)
+		{ 
+			if (asAsciiChar)
+				os << (char)((unsigned char*)pSendValue_)[i];
+		  	else
+		  		os << hex << (unsigned int)((unsigned char*)pSendValue_)[i] << " ";
+		}
+	    return os.str();
+	}
+
+
+	struct tm Register::getTMDate(double date)
+	{
+		struct tm dscst;
+		time_t dt = (time_t)date;
+		localtime_r(&dt, &dscst);
+		return dscst;
+	}
+
+    time_t Register::getEpochDate(double date)
+    {
+        return static_cast<time_t>(round(date));
+    }
+
+
+	timeval Register::getTimeStamp()
+	{
+		if (hasInputAccess()) return tod_;
+		throw SilecsException(__FILE__, __LINE__, PARAM_NO_TIME_STAMP, getName());
+	}
+
+
+	std::string Register::getTimeStampAsString()
+	{
+		if (hasInputAccess())
+		{ 	
+			std::ostringstream os;
+			double ts = (double)tod_.tv_sec + (double)tod_.tv_usec/1000000.0; //second
+			os << std::setprecision(20) << ts << "s";
+			return os.str();
+		}
+		else
+			return "not defined";
+	}
+
+
+	void Register::printVal()
+	{
+		std::ostringstream os;
+		os << getName() << " " << getFormatAsString() << "[" << dimension1_ << "][" << dimension2_ << "] " << getSynchroTypeAsString();
+		if(getFormat() == String) os << ", string-length: " << getLength();
+
+        if (hasInputAccess()) {
+            os << ", input: ";
+            for (unsigned int i=0; i<dimension1_; i++)
+                for (unsigned int j=0; j<dimension2_; j++)
+                        os << getValAsString(pRecvValue_, i, j) << " ";
+        }
+
+        if (hasOutputAccess()) {
+            os << ", output: ";
+            for (unsigned int i=0; i<dimension1_; i++)
+                for (unsigned int j=0; j<dimension2_; j++)
+                        os << getValAsString(pSendValue_, i, j) << " ";
+        }
+        std::cout << os.str() << std::endl;
+	}
+
+} // namespace
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.h
new file mode 100644
index 0000000000000000000000000000000000000000..5a5023c2086fc704c0f8c4d8f71c54aee57735d9
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsRegister.h
@@ -0,0 +1,1727 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _SILECS_REGISTER_H_
+#define _SILECS_REGISTER_H_
+
+#include <stdint.h>
+#include <boost/shared_ptr.hpp>
+
+namespace Silecs
+{
+	class PLC;
+	class Device;
+	class ElementXML;
+
+	/// @cond
+	// Register supported format
+	static const std::string FormatTypeString[] =
+	{ //!!Must be synchronized with FormatType enumeration
+
+	  //"uChar",	/*!<: SLC5 deprecated: 8-bits unsigned char	 = PLC BYTE	*/
+	  //"Char",		/*!<: 8-bits ascii char 					 = PLC CHAR	*/
+	  //"uShort",	/*!<: SLC5 deprecated: 16-bits unsigned int	 = PLC WORD	*/
+	  //"Short",	/*!<: SLC5 deprecated: 16-bits signed int 	 = PLC INT	*/
+	  //"uLong",	/*!<: SLC5 deprecated: 32-bits unsigned long = PLC DWORD*/
+	  //"Long",		/*!<: SLC5 deprecated: 32-bits signed long	 = PLC DINT	*/
+	  //"Float",	/*!<: SLC5 deprecated: 32-bits signed float	 = PLC REAL	*/
+
+	  "uInt8",  /*!<: 8-bits unsigned integer*/
+	  "Int8",   /*!<: 8-bits integer*/
+	  "uInt16", /*!<: 16-bits unsigned integer*/
+	  "Int16",  /*!<: 16-bits integer*/
+	  "uInt32", /*!<: 32-bits unsigned integer*/
+	  "Int32",  /*!<: 32-bits integer*/
+	  "Float32",/*!<: 32-bits signed float*/
+	  "Date",   /*!<: 64-bits time (elapsed time since the POSIX.1 Epoch (00:00:00 UTC, January 1, 1970)	= dt  */
+
+	  "uInt64", /*!<: 64-bits unsigned integer*/
+	  "Int64",  /*!<: 64-bits integer*/
+	  "Float64", /*!<: 64-bits signed float*/
+	  "String"  /*!<: String of ASCII characters*/
+	};
+
+	// Register synchronization type
+	static const std::string SynchroTypeString[] =
+	{
+		"Master",		//register is retentive, PLC is the source
+	  	"Slave",		//register is retentive, client is the source
+	  	"NoSynchro"	//register is volatile
+	};
+	/// @endcond
+
+
+	/*!
+	 * \brief Enumeration for the Register data type. Used by Register::getFormat() method.
+	 * Each type has a PLC type equivalent (see below)
+	 */
+	typedef enum
+	{
+	  //!!Must be synchronized with FormatTypeString[]
+	  uChar=0,	/*!<: SLC5 deprecated: 8-bits unsigned char	 = PLC BYTE	*/
+	  Char=1,	/*!<: 8-bits ascii char 					 = PLC CHAR	*/
+	  uShort=2,	/*!<: SLC5 deprecated: 16-bits unsigned int	 = PLC WORD	*/
+	  Short=3,	/*!<: SLC5 deprecated: 16-bits signed int 	 = PLC INT	*/
+	  uLong=4,	/*!<: SLC5 deprecated: 32-bits unsigned long = PLC DWORD*/
+	  Long=5,	/*!<: SLC5 deprecated: 32-bits signed long	 = PLC DINT	*/
+	  Float=6,	/*!<: SLC5 deprecated: 32-bits signed float	 = PLC REAL	*/
+	  Date=7,   /*!<: 64-bits double (elapsed time since the POSIX.1 Epoch (00:00:00 UTC, January 1, 1970)	= dt  */
+
+	  uInt8=0,	/*!<: 8-bits unsigned integer*/
+	  Int8=1,	/*!<: 8-bits integer*/
+	  uInt16=2,	/*!<: 16-bits unsigned integer*/
+	  Int16=3,	/*!<: 16-bits integer*/
+	  uInt32=4,	/*!<: 32-bits unsigned integer*/
+	  Int32=5,	/*!<: 32-bits integer*/
+	  Float32=6,/*!<: 32-bits signed float*/
+
+	  uInt64=8,		/*!<: 64-bits unsigned integer*/
+	  Int64=9,		/*!<: 64-bits integer*/
+	  Float64=10,	/*!<: 64-bits signed float*/
+	  String=11
+
+	} FormatType;
+
+	/*!
+	 * \class Register
+	 * \brief This object stores the final device data.
+	 * It provides interface to update and extract the register value.
+	 * The Register name is unique within the scope of the device class.
+	 */
+	class Register
+	{
+	public:
+
+		/*!
+		 * \brief Returns reference of the Device where the register is instantiated
+         * \return Reference of the Device object
+         */
+		Device* getDevice();
+
+        /*!
+         * \brief Returns the register name as defined in the Class design
+         * \return Register name
+         */
+		std::string getName();
+
+        /*!
+         * \brief Returns the format of the register data
+         * \return value from the FormatType enumeration
+         */
+		FormatType getFormat();
+
+        /*!
+         * \brief Returns number of elements in case of array register (1 in case of scalar register)
+         * \return Register dimension1
+         */
+		unsigned long getDimension(uint16_t whichDim=1 /*1,2*/); //for backward compatibility getDimension() ~= getDimension1()
+		uint32_t getDimension1();
+
+        /*!
+         * \brief Returns second dimension in case of 2D-array (1 in case of array register)
+         * \return Register dimension2
+         */
+        uint32_t getDimension2();
+
+        /*!
+         * \brief Returns length of string in case of a string/array of strings register
+         * \return Register length
+         */
+        uint32_t getLength();
+
+		/*!
+		 * \brief Returns the synchronization type of the current register (Master, Slave or No)
+		 * \return value from the SynchroType enumeration
+		 */
+		SynchroType getSynchroType();
+
+		/*!
+		 * \brief Returns the synchronization type of the current register
+		 * \return String value of the Synchronization type ("Master", "Slave" or "NoSynchro")
+		 */
+		std::string getSynchroTypeAsString();
+
+        /*!
+         * \brief Returns the name of the block which contains the register as defined in the Class design
+         * \return Block name of the register
+         */
+		std::string getBlockName();
+
+        /*!
+         * \brief Time-of-day: number of seconds and microseconds since the POSIX.1 Epoch (00:00:00 UTC, January 1, 1970)
+		 * Use to time-stamp the register coming from PLC (no time-stamping on send).
+		 * FEC clock and Timing are synchronized using SNTP (common GPS source)
+         * \return Register time-stamping as timeval structure
+         */
+		timeval getTimeStamp();
+
+        /*!
+         * \brief A register can have read-only, write-only or read-write access mode as defined in the Class design.
+         * \return true if register has read-only or read-write access mode
+         */
+		bool hasInputAccess();
+
+        /*!
+         * \brief A register can have read-only, write-only or read-write access mode as defined in the Class design.
+         * \return true if the register has write-only or read-write access mode
+         */
+		bool hasOutputAccess();
+
+        /*!
+         * \brief A retentive register can be a persistent or a constant data.
+         * Its value must be initialized at the system start-up.
+         * - From the client side if the synchro register is 'Slave'
+         * - From the PLC side if the synchro register is 'Master'
+         * \return true if the register has Master or Slave synchro as defined in the Class design
+         */
+		bool isRetentive();
+
+        /*!
+         * \brief A register that has not persistent or constant value is Volatile.
+         * Its value is not initialized at the system start-up.
+         * \return true if the register has 'No' synchro as defined in the Class design
+         */
+		bool isVolatile();
+
+        /*!
+         * \brief A scalar is a single value register (dimension1_ and dimension2_ attributes == 1)
+         * \return true if register is a scalar
+         */
+        bool isScalar();
+
+        /*!
+         * \brief A single array is a register with dimension1_ attribute > 1
+         * \return true if register is a single array
+         */
+        bool isSingleArray();
+
+        /*!
+         * \brief A double array is a register with dimension2_ attribute > 1
+         * \return true if register has second dimension
+         */
+        bool isDoubleArray();
+
+		// GET methods =============================================================
+
+		// .........................................................................
+		//Deprecated: initially for SLC5 (32bits platform)
+
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a char format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValInt8 instead.
+         */
+		char getValChar();
+		
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a char* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValInt8Array instead.
+         */
+		void getValCharArray(char* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a char* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValInt8Array2D instead.
+         */
+        void getValCharArray2D(char* pVal, uint32_t dim1, uint32_t dim2);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method give direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in format unsigned long
+         * \return a char* reference directly to the memory location where the array begins in the buffer
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getRefInt8Array instead.
+         */
+		const char* getRefCharArray(uint32_t& dim);
+
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array  in unsigned long format
+         * \return a char* reference directly to the memory location where the flat 2D-array begins in the buffer
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getRefInt8Array2D instead.
+         */
+        const char* getRefCharArray2D(uint32_t& dim1, uint32_t& dim2);
+
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a unsigned char format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValUInt8 instead.
+         */
+		unsigned char getValUChar();
+		
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a unsigned char* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValUInt8Array instead.
+         */
+		void getValUCharArray(unsigned char* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a unsigned char* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValUInt8Array2D instead.
+         */
+        void getValUCharArray2D(unsigned char* pVal, uint32_t dim1, uint32_t dim2);
+
+        //specific methods with automatic conversion (JAVA does not support unsigned type)
+        void getValUCharArray(short* pVal, uint32_t dim);
+        void getValUCharArray2D(short* pVal, uint32_t dim1, uint32_t dim2);
+        
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in format unsigned long
+         * \return a unsigned char* reference directly to the memory location where the array begins in the buffer
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getRefUInt8Array instead.
+         */
+		const unsigned char* getRefUCharArray(uint32_t& dim);
+		
+		 /*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array  in unsigned long format
+         * \return a unsigned char* reference directly to the memory location where the flat 2D-array begins in the buffer
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getRefUInt8Array2D instead.
+         */
+        const unsigned char* getRefUCharArray2D(uint32_t& dim1, uint32_t& dim2);
+		
+
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a short format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValInt16 instead.
+         */
+		short getValShort();
+		
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a short* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValInt16Array instead.
+         */
+		void getValShortArray(short* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a short* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValInt16Array2D instead.
+         */
+		void getValShortArray2D(short* pVal, uint32_t dim1, uint32_t dim2);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can sped up reading and writing operation when the buffer is very big and a small part of
+         * information is requested. This method give direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in format unsigned long
+         * \return a short* reference directly to the memory location where the array begins in the buffer
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getRefInt16Array instead.
+         */
+		const short* getRefShortArray(uint32_t& dim);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array in unsigned long format
+         * \return a short* reference directly to the memory location where the flat 2D-array begins in the buffer
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getRefInt16Array2D instead.
+         */
+        short* getRefShortArray2D(uint32_t& dim1, uint32_t& dim2);
+
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a unsigned short format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValUInt16 instead.
+         */
+		unsigned short getValUShort();
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a unsigned short* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValUInt16Array instead.
+         */
+		void getValUShortArray(unsigned short* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a unsigned short* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValUInt16Array2D instead.
+         */
+        void getValUShortArray2D(unsigned short* pVal, uint32_t dim1, uint32_t dim2);
+
+        //specific method with automatic conversion (JAVA does not support unsigned type)
+        void getValUShortArray(long* pVal, uint32_t dim);
+        void getValUShortArray2D(long* pVal, uint32_t dim1, uint32_t dim2);
+				
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can sped up reading and writing operation when the buffer is very big and a small part of
+         * information is requested. This method give direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in format unsigned long
+         * \return a unsigned short* reference directly to the memory location where the array begins in the buffer
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getRefUInt16Array instead.
+         */
+		const unsigned short* getRefUShortArray(uint32_t& dim);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array in unsigned long format
+         * \return a unsigned short* reference directly to the memory location where the flat 2D-array begins in the buffer
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getRefUInt16Array2D instead.
+         */
+		const unsigned short* getRefUShortArray2D(uint32_t& dim1, uint32_t& dim2);
+		
+
+	#ifndef __x86_64__ //long type is platform dependent (32bits or 64bits integer)
+		//SLC5: support for 'long' type as 32bits
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValInt32 instead.
+         */
+		long getValLong();
+
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a long* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValInt32Array instead.
+         */
+		void getValLongArray(long* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a long* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValInt32Array2D instead.
+         */
+        void getValLongArray2D(long* pVal, uint32_t dim1, uint32_t dim2);
+        
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can sped up reading and writing operation when the buffer is very big and a small part of
+         * information is requested. This method give direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in format unsigned long
+         * \return a long* reference directly to the memory location where the array begins in the buffer
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getRefInt32Array instead.
+         */
+		const long* getRefLongArray(uint32_t& dim);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array  in unsigned long format
+         * \return a long* reference directly to the memory location where the flat 2D-array begins in the buffer
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getRefInt32Array2D instead.
+         */
+        const long* getRefLongArray2D(uint32_t& dim1, uint32_t& dim2);
+
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValUInt32 instead.
+         */
+		unsigned long getValULong();
+		
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a unsigned long* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValUInt32Array instead.
+         */
+		void getValULongArray(unsigned long* pVal, uint32_t dim);
+		
+		 /*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a unsigned long* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValUInt32Array2D instead.
+         */
+        void getValULongArray2D(unsigned long* pVal, uint32_t dim1, uint32_t dim2);
+
+        //specific method with automatic conversion (JAVA does not support unsigned type)
+        void getValULongArray(long long* pVal, uint32_t dim);
+        void getValULongArray2D(long long* pVal, uint32_t dim1, uint32_t dim2);
+				
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can sped up reading and writing operation when the buffer is very big and a small part of
+         * information is requested. This method give direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in format unsigned long
+         * \return a unsigned long* reference directly to the memory location where the array begins in the buffer
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getRefUInt32Array instead.
+         */
+		const unsigned long* getRefULongArray(uint32_t& dim);
+		
+		 /*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array  in unsigned long format
+         * \return a unsigned long* reference directly to the memory location where the flat 2D-array begins in the buffer
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getRefUInt32Array2D instead.
+         */
+        const unsigned long* getRefULongArray2D(uint32_t& dim1, uint32_t& dim2);
+		
+	#else
+		//from SLC6: 'long' methods still used as 32bits but with explicit typing instead
+		//It's recommended to use new appropriate methods instead: Int32/UInt32
+		#define getValLong 			getValInt32
+		#define getValLongArray 	getValInt32Array
+		#define getRefLongArray 	getRefInt32Array
+
+		#define getValULong		 	getValUInt32
+		#define getValULongArray	getValUInt32Array
+		#define getRefULongArray	getRefUInt32Array
+	#endif
+
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a unsigned float format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValFloat32 instead.
+         */
+		float getValFloat();
+		
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a float* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValFloat32Array instead.
+         */
+		void getValFloatArray(float* pVal, uint32_t dim);
+		
+		 /*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a float* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getValFloat32Array2D instead.
+         */
+        void getValFloatArray2D(float* pVal, uint32_t dim1, uint32_t dim2);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can sped up reading and writing operation when the buffer is very big and a small part of
+         * information is requested. This method give direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in format unsigned long
+         * \return a float* reference directly to the memory location where the array begins in the buffer
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getRefFloat32Array instead.
+         */
+		const float* getRefFloatArray(uint32_t& dim);
+
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array  in unsigned long format
+         * \return a float* reference directly to the memory location where the flat 2D-array begins in the buffer
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of getRefFloat32Array2D instead.
+         */
+        const float* getRefFloatArray2D(uint32_t& dim1, uint32_t& dim2);
+
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * Date type represents the number of millisecond elapsed since 00:00:00
+         * on January 1, 1970, Coordinated Universal Time (UTC)
+         * \return the buffer content in a unsigned double format
+         */
+		double getValDate();
+		
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * Date type represents the number of millisecond elapsed since 00:00:00
+         * on January 1, 1970, Coordinated Universal Time (UTC)
+         * \param pVal a double* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         */
+		void getValDateArray(double* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * Date type represents the number of millisecond elapsed since 00:00:00
+         * on January 1, 1970, Coordinated Universal Time (UTC)
+         * \param pVal a double* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of 2D-array in unsigned long format
+         * \param dim2 second dimension of 2D-array in unsigned long format
+         */
+        void getValDateArray2D(double* pVal, uint32_t dim1, uint32_t dim2);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * Date type represents the number of millisecond elapsed since 00:00:00
+         * on January 1, 1970, Coordinated Universal Time (UTC)
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim reference location where to store the array dimension in unsigned long format
+         * \return a double* reference directly to the memory location where the flat 2D-array begins in the buffer
+         */
+		const double* getRefDateArray(uint32_t& dim);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * Date type represents the number of millisecond elapsed since 00:00:00
+         * on January 1, 1970, Coordinated Universal Time (UTC)
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array  in unsigned long format
+         * \return a double* reference directly to the memory location where the flat 2D-array begins in the buffer
+         */
+        double* getRefDateArray2D(uint32_t& dim1, uint32_t& dim2);
+
+		// .........................................................................
+		//Recommended: from SLC6 (32bits and 64bits platform)
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a int8_t format
+         */
+		int8_t getValInt8();
+		
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a int8_t* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         */
+		void getValInt8Array(int8_t* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a int8_t* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         */
+        void getValInt8Array2D(int8_t* pVal, uint32_t dim1, uint32_t dim2);
+				
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in unsigned long format
+         * \return a int8_t* reference directly to the memory location where the array begins in the buffer
+         */
+		const int8_t* getRefInt8Array(uint32_t& dim);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 reference where to store the second dimension of flat 2D-array in unsigned long format
+         * \return a int8_t* reference directly to the memory location where the flat 2D-array begins in the buffer
+         */
+        int8_t* getRefInt8Array2D(uint32_t& dim1, uint32_t& dim2);
+
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a uint8_t format
+         */
+		uint8_t getValUInt8();
+		
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a uint8_t* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         */
+		void getValUInt8Array(uint8_t* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a uint8_t* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         */
+        void getValUInt8Array2D(uint8_t* pVal, uint32_t dim1, uint32_t dim2);
+
+		//specific method with automatic conversion (JAVA does not support unsigned type)
+		void getValUInt8Array(int16_t* pVal, uint32_t dim);
+		void getValUInt8Array2D(int16_t* pVal, uint32_t dim1, uint32_t dim2);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can sped up reading and writing operation when the buffer is very big and a small part of
+         * information is requested. This method give direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in format unsigned long
+         * \return a uint8_t* reference directly to the memory location where the array begins in the buffer
+         */
+		const uint8_t* getRefUInt8Array(uint32_t& dim);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array  in unsigned long format
+         * \return a uint8_t* reference directly to the memory location where the flat 2D-array begins in the buffer
+         */
+        uint8_t* getRefUInt8Array2D(uint32_t& dim1, uint32_t& dim2);
+
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a int16_t format
+         */
+		int16_t getValInt16();
+
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a int16_t* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         */
+		void getValInt16Array(int16_t* pval, uint32_t dim);
+
+        /*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a int16_t* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         */
+        void getValInt16Array2D(int16_t* pVal, uint32_t dim1, uint32_t dim2);
+
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can sped up reading and writing operation when the buffer is very big and a small part of
+         * information is requested. This method give direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in format unsigned long
+         * \return a int16_t* reference directly to the memory location where the array begins in the buffer
+         */
+		const int16_t* getRefInt16Array(uint32_t& dim);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array  in unsigned long format
+         * \return a int16_t* reference directly to the memory location where the flat 2D-array begins in the buffer
+         */
+        int16_t* getRefInt16Array2D(uint32_t& dim1, uint32_t& dim2);
+
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a uint16_t format
+         */
+		uint16_t getValUInt16();
+		
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a uint16_t* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         */
+		void getValUInt16Array(uint16_t* pVal, uint32_t dim);
+		
+		 /*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a uint16_t* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         */
+        void getValUInt16Array2D(uint16_t* pVal, uint32_t dim1, uint32_t dim2);
+
+		//specific method with automatic conversion (JAVA does not support unsigned type)
+		void getValUInt16Array(int32_t* pVal, uint32_t dim);
+		void getValUInt16Array2D(int32_t* pVal, uint32_t dim1, uint32_t dim2);
+				
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can sped up reading and writing operation when the buffer is very big and a small part of
+         * information is requested. This method give direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in format unsigned long
+         * \return a uint16_t* reference directly to the memory location where the array begins in the buffer
+         */
+		const uint16_t* getRefUInt16Array(uint32_t& dim);
+	
+		 /*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array  in unsigned long format
+         * \return a uint16_t* reference directly to the memory location where the flat 2D-array begins in the buffer
+         */
+        uint16_t* getRefUInt16Array2D(uint32_t& dim1, uint32_t& dim2);
+		
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a int32_t format
+         */
+		int32_t getValInt32();
+		
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a int32_t* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         */
+		void getValInt32Array(int32_t* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a int32_t* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         */
+        void getValInt32Array2D(int32_t* pVal, uint32_t dim1, uint32_t dim2);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can sped up reading and writing operation when the buffer is very big and a small part of
+         * information is requested. This method give direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in format unsigned long
+         * \return a int32_t* reference directly to the memory location where the array begins in the buffer
+         */
+		const int32_t* getRefInt32Array(uint32_t& dim);
+		
+		 /*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array  in unsigned long format
+         * \return a int32_t* reference directly to the memory location where the flat 2D-array begins in the buffer
+         */
+        int32_t* getRefInt32Array2D(uint32_t& dim1, uint32_t& dim2);
+
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a uint32_t format
+         */
+		uint32_t getValUInt32();
+		
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a uint32_t* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         */
+		void getValUInt32Array(uint32_t* pVal, uint32_t dim);
+		
+		 /*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a uint32_t* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         */
+        void getValUInt32Array2D(uint32_t* pVal, uint32_t dim1, uint32_t dim2);
+        
+		//specific method with automatic conversion (JAVA does not support unsigned type)
+		void getValUInt32Array(int64_t* pVal, uint32_t dim);
+		void getValUInt32Array2D(int64_t* pVal, uint32_t dim1, uint32_t dim2);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can sped up reading and writing operation when the buffer is very big and a small part of
+         * information is requested. This method give direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in format unsigned long
+         * \return a uint32_t* reference directly to the memory location where the array begins in the buffer
+         */
+		const uint32_t* getRefUInt32Array(uint32_t& dim);
+
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array  in unsigned long format
+         * \return a uint32_t* reference directly to the memory location where the flat 2D-array begins in the buffer
+         */
+        uint32_t* getRefUInt32Array2D(uint32_t& dim1, uint32_t& dim2);
+		
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a int64_t format
+         */
+		int64_t getValInt64();
+		
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a int64_t* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         */
+		void getValInt64Array(int64_t* pVal, uint32_t dim);
+		
+		 /*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a int8_t* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         */
+        void getValInt64Array2D(int64_t* pVal, uint32_t dim1, uint32_t dim2);
+				
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can sped up reading and writing operation when the buffer is very big and a small part of
+         * information is requested. This method give direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in format unsigned long
+         * \return a int64_t* reference directly to the memory location where the array begins in the buffer
+         */
+		const int64_t* getRefInt64Array(uint32_t& dim);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array  in unsigned long format
+         * \return a int64_t* reference directly to the memory location where the flat 2D-array begins in the buffer
+         */
+        int64_t* getRefInt64Array2D(uint32_t& dim1, uint32_t& dim2);
+		
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a uint64_t format
+         */
+		uint64_t getValUInt64();
+		
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a uint64_t* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         */
+		void getValUInt64Array(uint64_t* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a uint64_t* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         */
+        void getValUInt64Array2D(uint64_t* pVal, uint32_t dim1, uint32_t dim2);
+		
+		//specific method with automatic conversion (JAVA does not support unsigned type)
+		//void getValUInt64Array(int128_t* pVal, uint32_t dim); not supported (128bits)!
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can sped up reading and writing operation when the buffer is very big and a small part of
+         * information is requested. This method give direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in format unsigned long
+         * \return a uint64_t* reference directly to the memory location where the array begins in the buffer
+         */
+		const uint64_t* getRefUInt64Array(uint32_t& dim);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array  in unsigned long format
+         * \return a uint64_t* reference directly to the memory location where the flat 2D-array begins in the buffer
+         */
+        uint64_t* getRefUInt64Array2D(uint32_t& dim1, uint32_t& dim2);
+
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a float format
+         */
+		float getValFloat32();
+		
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a float* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         */
+		void getValFloat32Array(float* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a float* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         */
+        void getValFloat32Array2D(float* pVal, uint32_t dim1, uint32_t dim2);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can sped up reading and writing operation when the buffer is very big and a small part of
+         * information is requested. This method give direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in format unsigned long
+         * \return a float* reference directly to the memory location where the array begins in the buffer
+         */
+		const float* getRefFloat32Array(uint32_t& dim);
+		
+        /*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array  in unsigned long format
+         * \return a float* reference directly to the memory location where the flat 2D-array begins in the buffer
+         */
+        float* getRefFloat32Array2D(uint32_t& dim1, uint32_t& dim2);
+
+		/*!
+         * \brief Extracts the current value from the register input buffer.
+         * \return the buffer content in a double format
+         */
+		double getValFloat64();
+		
+		/*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a double* pointer to a memory location where the method will store a copy of the array
+         * \param dim vector length in unsigned long format
+         */
+		void getValFloat64Array(double* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Extracts the 2D-array of values from the register input buffer.
+         * \param pVal a double* pointer to a memory location where the method will store a copy of the flat 2D-array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         */
+        void getValFloat64Array2D(double* pVal, uint32_t dim1, uint32_t dim2);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method give direct access on the buffer and his adoption is not recommended.
+         * \param dim Reference where to store the vector dimension in unsigned long format
+         * \return a double* reference directly to the memory location where the array begins in the buffer
+         */
+		const double* getRefFloat64Array(uint32_t& dim);
+		
+		/*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Reference where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Reference where to store the second dimension of flat 2D-array in unsigned long format
+         * \return a double* reference directly to the memory location where the flat 2D-array begins in the buffer
+         */
+        double* getRefFloat64Array2D(uint32_t& dim1, uint32_t& dim2);
+
+        /*!
+         * \brief Extracts the current value from the register input buffer. (receive must be done ahead)
+         * \return the buffer content in a string format
+         */
+        std::string getValString();
+
+        /*!
+         * \brief Extracts the vector of values from the register input buffer.
+         * \param pVal a std::string* pointer to a memory location where the method will store a copy of the string
+         * \param dim vector length in unsigned long format
+         */
+        void getValStringArray(std::string* pVal, uint32_t dim);
+
+        /*!
+         * \brief Extracts the string array from the register input buffer.
+         * \param pVal a std::string* pointer to a memory location where the method will store a copy of the 2D (flat) array
+         * \param dim1 first dimension of flat 2D-array in unsigned long format
+         * \param dim2 second dimension of flat 2D-array in unsigned long format
+         */
+        void getValStringArray2D(std::string* pVal, uint32_t dim1, uint32_t dim2);
+
+        /*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer us very big and a small part of
+         * information is requested. This methos give direct access on the buffer and his adoption is not recommended.
+         * \param dim Location where to store the vector dimension in unsigned long format
+         * \return a str::string** reference directly to the memory location where the array of pointers begins in the buffer
+         */
+        const std::string** getRefStringArray(uint32_t& dim);
+
+        /*!
+         * \brief Return a reference to register input buffer.
+         * The usage of this method can speed up reading and writing operations when the buffer is very big and a small part of
+         * information is requested. This method gives direct access on the buffer and his adoption is not recommended.
+         * \param dim1 Location where to store the first dimension of flat 2D-array in unsigned long format
+         * \param dim2 Location where to store the second dimension of flat 2D-array in unsigned long format
+         * \return a str::string** reference directly to the memory location where the flat 2D-array of pointers begins in the buffer
+         */
+        const std::string** getRefStringArray2D(uint32_t& dim1, uint32_t& dim2);
+		
+        /*!
+         * \brief Converts the double Date type to tm broken-down time structure
+		 * conforming to POSIX convention (look at localtime() manpages)
+		 * \return tm broken-down time structure
+		 */
+		static struct tm getTMDate(double date);
+	    static time_t getEpochDate(double date);
+
+		// SET methods ========================================================
+
+		// .........................................................................
+		//Deprecated: initially for SLC5 (32bits platform)
+		/*!
+         * \brief Set the value for the register output buffer. (Send must be done afterwards)
+         * \param val Value to be written in the buffer in a char format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValInt8 instead.
+         */
+		void setValChar(char val);
+		
+		/*!
+         * \brief Set the value for the array register output buffer. (Send must be done afterwards)
+         * \param pVal A char* pointer to a memory location from where the method will get the array values
+         * \param dim Vector length in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValInt8Array instead.
+         */
+		void setValCharArray(const char* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A char* pointer to a memory location from where the method will get the flat 2D-array values
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValInt8Array2D instead.
+         */
+        void setValCharArray2D(const char* pVal, uint32_t dim1, uint32_t dim2);
+		
+		/*!
+         * \brief Set the value for the register output buffer.(Send must be done afterwards)
+         * \param val Value to be written in the buffer in a unsigned char format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValUInt8 instead.
+         */
+		void setValUChar(unsigned char val);
+		
+		/*!
+         * \brief Set the value for the array register output buffer.(Send must be done afterwards)
+         * \param pVal A unsigned char* pointer to a memory location from where the method will get the array values
+         * \param dim Vector length in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValUInt8Array instead.
+         */
+		void setValUCharArray(const unsigned char* pVal, uint32_t dim);
+		
+		 /*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A unsigned char* pointer to a memory location from where the method will get the flat 2D-array values
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValUInt8Array2D instead.
+         */
+        void setValUCharArray2D(const unsigned char* pVal, uint32_t dim1, uint32_t dim2);
+
+		//specific method with automatic conversion (JAVA does not support unsigned type)
+		void setValUCharArray(const short* pVal, uint32_t dim);
+        void setValUCharArray2D(const short* pVal, uint32_t dim1, uint32_t dim2);
+
+		/*!
+         * \brief Set the value for the register output buffer.(Send must be done afterwards)
+         * \param val Value to be written in the buffer in a short format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValInt16 instead.
+         */
+		void setValShort(short val);
+		
+		/*!
+         * \brief Set the value for the array register output buffer.(Send must be done afterwards)
+         * \param pVal A short* pointer to a memory location from where the method will get the array values
+         * \param dim Vector length in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValInt16Array instead.
+         */
+		void setValShortArray(const short* pVal, uint32_t dim);
+
+		/*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A short* pointer to a memory location from where the method will get the flat 2D-array values
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValInt16Array2D instead.
+         */
+        void setValShortArray2D(const short* pVal, uint32_t dim1, uint32_t dim2);
+        
+		/*!
+         * \brief Set the value for the register output buffer.(Send must be done afterwards)
+         * \param val Value to be written in the buffer in a unsigned short format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValUInt16 instead.
+         */
+		void setValUShort(unsigned short val);
+		
+		/*!
+         * \brief Set the value for the array register output buffer.(Send must be done afterwards)
+         * \param pVal A unsigned short* pointer to a memory location from where the method will get the array values
+         * \param dim Vector length in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValUInt16Array instead.
+         */
+		void setValUShortArray(const unsigned short* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A unsigned short* pointer to a memory location from where the method will get the flat 2D-array values
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValUInt16Array2D instead.
+         */
+        void setValUShortArray2D(const unsigned short* pVal, uint32_t dim1, uint32_t dim2);
+
+		//specific method with automatic conversion (JAVA does not support unsigned type)
+		void setValUShortArray(const long* pVal, uint32_t dim);
+        void setValUShortArray2D(const long* pVal, uint32_t dim1, uint32_t dim2);
+
+		#ifndef __x86_64__  //long type is platform dependant (32bits or 64bits integer)
+	    //SLC5: support for 'long' type as 32bits
+			/*!
+			 * \brief Set the value for the register output buffer.(Send must be done afterwards)
+			 * \param val Value to be written in the buffer in a long format
+			 * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValInt32 instead.
+			 */
+			void setValLong(long val);
+			
+			/*!
+	         * \brief Set the value for the array register output buffer.(Send must be done afterwards)
+	         * \param pVal A long* pointer to a memory location from where the method will get the array values
+	         * \param dim Vector length in unsigned long format
+	         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValInt32Array instead.
+	         */
+			void setValLongArray(const long* pVal, uint32_t dim);
+			
+			 /*!
+	         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+	         * \param pVal A long* pointer to a memory location from where the method will get the flat 2D-array values
+	         * \param dim1 First dimension of flat 2D-array in unsigned long format
+	         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+	         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValInt32Array2D instead.
+	         */
+	        void setValLongArray2D(const long* pVal, uint32_t dim1, uint32_t dim2);
+
+			/*!
+	         * \brief Set the value for the register output buffer.(Send must be done afterwards)
+	         * \param val Value to be written in the buffer in a unsigned long format
+	         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValUInt32 instead.
+	         */
+			void setValULong(unsigned long val);
+			
+			/*!
+	         * \brief Set the value for the array register output buffer.(Send must be done afterwards)
+	         * \param pVal A unsigned long* pointer to a memory location from where the method will get the array values
+	         * \param dim Vector length in unsigned long format
+	         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValUInt32Array instead.
+	         */
+			void setValULongArray(const unsigned long* pVal, uint32_t dim);
+			
+			/*!
+	         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+	         * \param pVal A unsigned long* pointer to a memory location from where the method will get the flat 2D-array values
+	         * \param dim1 First dimension of flat 2D-array in unsigned long format
+	         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+	         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValUInt32Array2D instead.
+	         */
+	        void setValULongArray2D(const unsigned long* pVal, uint32_t dim1, uint32_t dim2);
+
+			//specific method with automatic conversion (JAVA does not support unsigned type)
+			void setValULongArray(const long long* pVal, uint32_t dim);
+			void setValULongArray2D(const long long* pVal, uint32_t dim1, uint32_t dim2);
+
+		#else
+		//from SLC6: 'long' methods still used as 32bits but with explicit typing instead
+		//It's recommended to use new appropriate methods instead: Int32/UInt32
+			#define setValLong 			setValInt32
+			#define setValLongArray 	setValInt32Array
+			#define setValULong		 	setValUInt32
+			#define setValULongArray	setValUInt32Array
+		#endif
+
+		/*!
+		 * \brief Set the value for the register output buffer.(Send must be done afterwards)
+		 * \param val Value to be written in the buffer in a float format
+		 * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValFloat32 instead.
+		 */
+		void setValFloat(float val);
+		
+		/*!
+         * \brief Set the value for the array register output buffer.(Send must be done afterwards)
+         * \param pVal A float* pointer to a memory location from where the method will get the array values
+         * \param dim Vector length in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValFloat32Array instead.
+         */
+		void setValFloatArray(const float* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A float* pointer to a memory location from where the method will get the flat 2D-array values
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         * \deprecated This method is supported for backward compatibility (version <= 3.2.*). Suggested usage of setValFloat32Array2D instead.
+         */
+        void setValFloatArray2D(const float* pVal, uint32_t dim1, uint32_t dim2);
+		
+		//Set date is not required for the time being
+		void setValDate(double val);
+		void setValDateArray(const double* pVal, uint32_t dim);
+		void setValDateArray2D(const double* pVal, uint32_t dim1, uint32_t dim2);
+		
+
+		// .........................................................................
+		//Recommended: from SLC6 (32bits and 64bits platform)
+		/*!
+		 * \brief Set the value for the register output buffer.(Send must be done afterwards)
+		 * \param val Value to be written in the buffer in a int8_t format
+		 */
+		void setValInt8(int8_t val);
+		
+		/*!
+         * \brief Set the value for the array register output buffer.(Send must be done afterwards)
+         * \param pVal A int8_t* pointer to a memory location from where the method will get the array values
+         * \param dim Vector length in unsigned long format
+         */
+		void setValInt8Array(const int8_t* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A int8_t* pointer to a memory location from where the method will get the flat 2D-array values
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         */
+        void setValInt8Array2D(const int8_t* pVal, uint32_t dim1, uint32_t dim2);
+
+		/*!
+		 * \brief Set the value for the register output buffer.(Send must be done afterwards)
+		 * \param val Value to be written in the buffer in a uint8_t format
+		 */
+		void setValUInt8(uint8_t val);
+		/*!
+         * \brief Set the value for the array register output buffer.(Send must be done afterwards)
+         * \param pVal A uint8_t* pointer to a memory location from where the method will get the array values
+         * \param dim Vector length in unsigned long format
+         */
+		void setValUInt8Array(const uint8_t* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A uint8_t* pointer to a memory location from where the method will get the flat 2D-array values
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         */
+        void setValUInt8Array2D(const uint8_t* pVal, uint32_t dim1, uint32_t dim2);
+		
+		//specific method with automatic conversion (JAVA does not support unsigned type)
+		void setValUInt8Array(const int16_t* pVal, uint32_t dim);
+		void setValUInt8Array2D(const int16_t* pVal, uint32_t dim1, uint32_t dim2);
+
+		/*!
+		 * \brief Set the value for the register output buffer.(Send must be done afterwards)
+		 * \param val Value to be written in the buffer in a int16_t format
+		 */
+		void setValInt16(int16_t val);
+		
+		/*!
+         * \brief Set the value for the array register output buffer.(Send must be done afterwards)
+         * \param pVal A int16_t* pointer to a memory location from where the method will get the array values
+         * \param dim Vector length in unsigned long format
+         */
+		void setValInt16Array(const int16_t* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A int16_t* pointer to a memory location from where the method will get the flat 2D-array values
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         */
+        void setValInt16Array2D(const int16_t* pVal, uint32_t dim1, uint32_t dim2);
+		
+		/*!
+		 * \brief Set the value for the register output buffer.(Send must be done afterwards)
+		 * \param val Value to be written in the buffer in a uint16_t format
+		 */
+		void setValUInt16(uint16_t val);
+		
+		/*!
+         * \brief Set the value for the array register output buffer.(Send must be done afterwards)
+         * \param pVal A uint16_t* pointer to a memory location from where the method will get the array values
+         * \param dim Vector length in unsigned long format
+         */
+		void setValUInt16Array(const uint16_t* pVal, uint32_t dim);
+		
+		 /*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A uint16_t* pointer to a memory location from where the method will get the flat 2D-array values
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         */
+        void setValUInt16Array2D(const uint16_t* pVal, uint32_t dim1, uint32_t dim2);
+
+		//specific method with automatic conversion (JAVA does not support unsigned type)
+		void setValUInt16Array(const int32_t* pVal, uint32_t dim);
+        void setValUInt16Array2D(const int32_t* pVal, uint32_t dim1, uint32_t dim2);
+
+		/*!
+		 * \brief Set the value for the register output buffer.(Send must be done afterwards)
+		 * \param val Value to be written in the buffer in a int32_t format
+		 */
+		void setValInt32(int32_t val);
+		
+		/*!
+         * \brief Set the value for the array register output buffer. (Send must be done afterwards)
+         * \param pVal A int32_t* pointer to a memory location from where the method will get the array values
+         * \param dim Vector length in unsigned long format
+         */
+		void setValInt32Array(const int32_t* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A int32_t* pointer to a memory location from where the method will get the flat 2D-array values
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         */
+        void setValInt32Array2D(const int32_t* pVal, uint32_t dim1, uint32_t dim2);
+		
+		/*!
+		 * \brief Set the value for the register output buffer. (Send must be done afterwards)
+		 * \param val Value to be written in the buffer in a uint32_t format
+		 */
+		void setValUInt32(uint32_t val);
+		
+		/*!
+         * \brief Set the value for the array register output buffer.(Send must be done afterwards)
+         * \param pVal A uint32_t* pointer to a memory location from where the method will get the array values
+         * \param dim Vector length in unsigned long format
+         */
+		void setValUInt32Array(const uint32_t* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A uint32_t* pointer to a memory location from where the method will get the flat 2D-array values
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         */
+        void setValUInt32Array2D(const uint32_t* pVal, uint32_t dim1, uint32_t dim2);
+
+		//specific method with automatic conversion (JAVA does not support unsigned type)
+		void setValUInt32Array(const int64_t* pVal, uint32_t dim);
+        void setValUInt32Array2D(const int64_t* pVal, uint32_t dim1, uint32_t dim2);
+
+		/*!
+		 * \brief Set the value for the register output buffer.(Send must be done afterwards)
+		 * \param val Value to be written in the buffer in a int64_t format
+		 */
+		void setValInt64(int64_t val);
+
+		/*!
+         * \brief Set the value for the array register output buffer.(Send must be done afterwards)
+         * \param pVal A int64_t* pointer to a memory location from where the method will get the array values
+         * \param dim Vector length in unsigned long format
+         */
+		void setValInt64Array(const int64_t* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A int64_t* pointer to a memory location from where the method will get the flat 2D-array values
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         */
+        void setValInt64Array2D(const int64_t* pVal, uint32_t dim1, uint32_t dim2);
+		
+		/*!
+		 * \brief Set the value for the register output buffer.(Send must be done afterwards)
+		 * \param val Value to be written in the buffer in a uint64_t format
+		 */
+		void setValUInt64(uint64_t val);
+
+		/*!
+         * \brief Set the value for the array register output buffer.(Send must be done afterwards)
+         * \param pVal A uint64_t* pointer to a memory location from where the method will get the array values
+         * \param dim Vector length in unsigned long format
+         */
+		void setValUInt64Array(const uint64_t* pVal, uint32_t dim);
+		
+		 /*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A uint64_t* pointer to a memory location from where the method will get the flat 2D-array values
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         */
+        void setValUInt64Array2D(const uint64_t* pVal, uint32_t dim1, uint32_t dim2);
+
+		//specific method with automatic conversion (JAVA does not support unsigned type)
+		//void setValUInt64Array(const int128_t* pVal, uint32_t dim); not supported (128bits)!
+
+		/*!
+		 * \brief Set the value for the register output buffer.(Send must be done afterwards)
+		 * \param val Value to be written in the buffer in a float format
+		 */
+		void setValFloat32(float val);
+		
+		/*!
+         * \brief Set the value for the array register output buffer.(Send must be done afterwards)
+         * \param pVal A float* pointer to a memory location from where the method will get the array values
+         * \param dim Vector length in unsigned long format
+         */
+		void setValFloat32Array(const float* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A float* pointer to a memory location from where the method will get the flat 2D-array values
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         */
+        void setValFloat32Array2D(const float* pVal, uint32_t dim1, uint32_t dim2);
+
+		/*!
+		 * \brief Set the value for the register output buffer.(Send must be done afterwards)
+		 * \param val Value to be written in the buffer in a double format
+		 */
+		void setValFloat64(double val);
+		
+		/*!
+         * \brief Set the value for the array register output buffer.(Send must be done afterwards)
+         * \param pVal A double* pointer to a memory location from where the method will get the array values
+         * \param dim Vector length in unsigned long format
+         */
+		void setValFloat64Array(const double* pVal, uint32_t dim);
+		
+		/*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A double* pointer to a memory location from where the method will get the flat 2D-array values
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         */
+        void setValFloat64Array2D(const double* pVal, uint32_t dim1, uint32_t dim2);
+		
+		/*!
+         * \brief Set the value for the register output buffer. (Send must be done afterwards)
+         * \param val string to be written in the buffer
+         */
+        void setValString(std::string val);
+
+        /*!
+         * \brief Set the value for the array register output buffer. (Send must be done afterwards)
+         * \param pVal A std::string* pointer to a memory location from where the method will get the array
+         * \param dim Vector length in unsigned long format
+         */
+        void setValStringArray(const std::string* pVal, uint32_t dim);
+
+        /*!
+         * \brief Set the value for the 2D-array register output buffer. (Send must be done afterwards)
+         * \param pVal A std::string* pointer to a memory location from where the method will get the flat 2D-array
+         * \param dim1 First dimension of flat 2D-array in unsigned long format
+         * \param dim2 Second dimension of flat 2D-array in unsigned long format
+         */
+        void setValStringArray2D(const std::string* pVal, uint32_t dim1, uint32_t dim2);
+
+        // .........................................................................
+        /*!
+         * \brief Returns the format of the register data as string value
+         * \return Format-type of the register (Enumeration: "char", "uChar", "short", "uShort", ..)
+         */
+		std::string getFormatAsString();
+
+        /*!
+         * \brief Returns the register time-stamping as readable value
+         * \return number of seconds since the Epoch (floating point value)
+         */
+		std::string getTimeStampAsString();
+
+        /*!
+         * \brief Interprets the input register value and return the corresponding string.
+         * In case of array or 2D-array, it return string value of the appropriate element.
+         * Generates an Exception if register is write-only or if index(es) exceed the array dimension(s)
+         * \param i,j indexes of the element in the (2D)array if any (optional)
+         * \return input register value or element as string
+         */
+        std::string getInputValAsString(); //for scalar
+		std::string getInputValAsString(unsigned long i); //for single array
+        std::string getInputValAsString(unsigned long i, unsigned long j); //for 2D array (flat)
+
+        /*!
+         * \brief Interprets the output register value and return the corresponding string.
+         * In case of array or 2D-array, it return string value of the appropriate element.
+         * Generates an Exception if register is read-only or if index(es) exceed the array dimension(s)
+         * \param i,j indexes of the element in the (2D)array if any (optional)
+         * \return input register value or element as string
+         */
+        std::string getOutputValAsString(); //for scalar
+        std::string getOutputValAsString(unsigned long i); //for single array
+        std::string getOutputValAsString(unsigned long i, unsigned long j); //for 2D array (flat)
+
+        /*!
+         * \brief Returns the Input register value as sequence of 8-bit words
+         * \param asAsciiChar = true to dump the buffer as Ascii characters (default is Hexadecimal dump)
+         * \return string blank-separated value
+         */
+		std::string dumpInputVal(bool asAsciiChar = false);
+
+        /*!
+         * \brief Returns the Output register value as sequence of 8-bit word
+         * \param asAsciiChar = true to dump the buffer as Ascii characters (default is Hexadecimal dump)
+         * \return string blank-separated value
+         */
+		std::string dumpOutputVal(bool asAsciiChar = false);
+
+        /*!
+         * \brief Display all the register information to the standard output for debugging purpose:
+         * name, format, dimension, synchro and input/output value(s).
+         */
+		void printVal();
+
+		/// @cond
+        /*!
+         * \fn whichFormatType
+         * \return Enumeration value of the given format-type string
+         */
+		FormatType whichFormatType(std::string type);
+
+		bool isInitialized();
+		/// @endcond
+
+		/// @cond
+	protected:
+		Register(Device* theDevice,const boost::shared_ptr<ElementXML>& registerNode);
+		virtual ~Register();
+
+		// export register extraction methods
+		friend class PLC;
+		friend class Device;
+
+        /*!
+         * \brief Set access type.
+         * \param accessType Input, Ouput or InOut
+         */
+		void setAccessType(AccessType accessType);
+
+		inline void setBlockName(const std::string blockName) { blockName_ = blockName; }
+
+        /*!
+         * \fn getValAsString
+         * \return return a copy of the corresponding string from the buffer (scalar, array or 2D-array)
+         */
+		std::string getValAsString(void* pValue, unsigned long i, unsigned long j);
+
+        /*!
+         * \fn getValAsByteString
+         * \brief Debug purpose: return the register value as array of bytes
+         * \param maxSize is the used to limit the string size in case of huge data array.
+         * \return interprets the register value and return the corresponding string
+         */
+		std::string getValAsByteString(void* pValue, unsigned long maxSize);
+
+		inline unsigned long getAddress() { return address_; }
+
+        /*!
+         * \brief Import values from the received buffer to the register. Pure virtual to be implemented by the inheriting classes.
+         * \param pBuffer received data buffer
+         * \param ts register time-stamp
+         */
+		virtual void importValue(void* pBuffer, timeval ts) = 0 ;
+		
+        /*!
+         * \brief Export the value from the register to the correct position in the buffer. Pure virtual to be implemented by the inheriting classes.
+         * \param pBuffer the output buffer where to update the data
+         */
+		virtual void exportValue(void* pBuffer) = 0 ;
+		
+		/*!
+		 * \brief Import values from the received buffer to the register. Pure vistual to be implemented by the inheriting classes.
+		 * \param pBuffer received data buffer
+		 * \param ts register time-stamp
+		 */
+		virtual void importString(void* pBuffer, timeval ts) = 0;
+
+		/*!
+		 * \brief Export the string from the register to the correct position in the buffer. Pure virtual to be implemented by inheriting classes.
+		 * \param pBuffer the output buffer where to update the data
+		 */
+		virtual void exportString(void* pBuffer) = 0;
+		
+		/*!
+		 * \brief Copies the register content from the input buffer to the output buffer. Pure virtual to be implemented by the inheriting classes.
+		 */
+		virtual void copyValue() = 0 ;
+
+		/// Parent reference of that register
+		Device* theDevice_;
+
+		/// Register name
+		std::string name_;
+
+		/// Register access-type: Input, Ouput or InOut (following its related block)
+		AccessType accessType_;
+
+		/// Enum format: char, uchar, short, ushort, long, ulong, float, double
+		FormatType format_;
+
+		/// Data first dimension (>1 for single array)
+		uint32_t dimension1_;
+
+        /// Data second dimension (>1 for double array)
+        uint32_t dimension2_;
+
+        // String length
+        unsigned long length_;
+
+		/// Data size (relies on format)
+		unsigned long size_;
+
+		/// Data memory size (relies on format, including alignments)
+		unsigned long memSize_;
+
+		/// data address within the PLC memory (from the block base-address)
+		unsigned long address_;
+
+		/// Synchronization mode: Master, Slave, No
+		SynchroType synchro_;
+
+		/// Flag used to check if the register has been setted once at least.
+		/// Uploading Slave registers at connection time is allowed only if all
+		/// the retentive Slave registers are initialized!
+		bool isInitialized_;
+
+		/// Buffer to store the value of the register
+		/// 2 different buffers are used in case of InOut access.
+		void* pRecvValue_;
+		void* pSendValue_;
+
+		/// Name of the "parent" Block name (for general information)
+		std::string blockName_;
+
+		// Time-of-day: number of seconds and microseconds since the POSIX.1 Epoch (00:00:00 UTC, January 1, 1970)
+		// Use to time-stamp the register coming from PLC (no time-stamping on send).
+		// FEC clock and Timing are synchronized using SNTP (common GPS source)
+		timeval tod_;
+
+		PLC* getPLC();
+		/// @endcond
+
+	//private:
+		//template <typename T> inline T getVal(FormatType F, unsigned char* pValue);
+		template <typename T> T getVal(FormatType F);
+		template <typename T> void getValArray(FormatType F, T* pValue, uint32_t dim);
+		template <typename T> void getValArray2D(FormatType F, T* pValue, uint32_t dim1, uint32_t dim2);
+		template <typename Tsrc, typename Tdst> void convGetValArray(FormatType F, Tdst* pValue, uint32_t dim);
+		template <typename Tsrc, typename Tdst> void convGetValArray2D(FormatType F, Tdst* pValue, uint32_t dim1, uint32_t dim2);
+		template <typename T> T* getRefArray(FormatType F, uint32_t& dim);
+		template <typename T> T* getRefArray2D(FormatType F, uint32_t& dim1, uint32_t& dim2);
+
+		template <typename T> void setVal(FormatType F, T val);
+		template <typename T> void setValArray(FormatType F, const T* pVal, uint32_t dim);
+		template <typename T> void setValArray2D(FormatType F, const T* pVal, uint32_t dim1, uint32_t dim2);
+		template <typename Tsrc, typename Tdst> void convSetValArray(FormatType F, const Tsrc* pVal, uint32_t dim);
+		template <typename Tsrc, typename Tdst> void convSetValArray2D(FormatType F, const Tsrc* pVal, uint32_t dim1, uint32_t dim2);
+	};
+
+} // namespace
+
+#endif // _SILECS_REGISTER_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/Condition.cpp b/silecs-communication-cpp/src/silecs-communication/interface/utility/Condition.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ec1caa86e05b20b41b83958acb55b0ae81fc8cf2
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/Condition.cpp
@@ -0,0 +1,81 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <string.h>
+#include <silecs-communication/interface/utility/Condition.h>
+
+namespace Silecs
+{
+
+	Condition::Condition(std::string name)
+	{
+		int err;
+
+		// Condition name if any, used for logging in particular
+    	name_ = name;
+
+    	//create the related mutex using the same name
+        pMutex_ = new Mutex(name_);
+
+		if ((err = pthread_cond_init(&condVar_, NULL)) != 0)
+			throw SilecsException(__FILE__, __LINE__, errno, strerror(errno));
+	}
+
+	Condition::~Condition()
+	{
+		int err;
+		if ((err = pthread_cond_destroy(&condVar_)) != 0)
+		{   //can be broken by SIGKILL (just leave with no Exception)
+			//throw SilecsException(__FILE__, __LINE__, errno, strerror(errno));
+		}
+		delete pMutex_;
+	}
+
+	void Condition::lock()
+	{
+		pMutex_->lock();
+	}
+
+	void Condition::unlock()
+	{
+		pMutex_->unlock();
+	}
+
+	void Condition::signal()
+	{
+		int err;
+		if ((err = pthread_cond_signal(&condVar_)) != 0)
+			throw SilecsException(__FILE__, __LINE__, errno, strerror(errno));
+        LOG(LOCK) << "Has signaled condition: " << this->name_;
+	}
+
+	void Condition::broadcast()
+	{
+		int err;
+		if ((err = pthread_cond_broadcast(&condVar_)) != 0)
+			throw SilecsException(__FILE__, __LINE__, errno, strerror(errno));
+	}
+
+	void Condition::wait()
+	{
+		int err;
+        LOG(LOCK) << "Waiting for condition: " << this->name_;
+		if ((err = pthread_cond_wait(&condVar_, pMutex_->pMutex_)) != 0)
+			throw SilecsException(__FILE__, __LINE__, errno, strerror(errno));
+        LOG(LOCK) << "Has get condition: " << this->name_;
+	}
+
+}// end namespace
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/Condition.h b/silecs-communication-cpp/src/silecs-communication/interface/utility/Condition.h
new file mode 100644
index 0000000000000000000000000000000000000000..38e41a2564b60db6a3f1c3e3151e7dfdc3c9c5aa
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/Condition.h
@@ -0,0 +1,54 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _CONDITION_H_
+#define _CONDITION_H_
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <silecs-communication/interface/utility/Mutex.h>
+
+namespace Silecs {
+
+	/*!
+	 * \class Condition
+	 * \brief This class implement the basic methods to manage the thread synchronization
+	 * with Conditional Variable. In particular, it manages the related mutex.
+	 */
+	class Condition
+	{
+		public:
+			Condition(std::string name = "undefined");
+			virtual ~Condition();
+
+	        void lock();
+	        void unlock();
+
+			void signal();
+			void broadcast();
+			void wait();
+
+		private:
+			// Condition name if any, used for logging in particular
+			std::string name_;
+
+			pthread_cond_t condVar_;
+			Mutex* pMutex_;
+	};
+
+} // namespace
+
+#endif /* _CONDITION_H_ */
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/Mutex.cpp b/silecs-communication-cpp/src/silecs-communication/interface/utility/Mutex.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9573a227b014458ef25ffa8c2e7fc7f0e17ee5b7
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/Mutex.cpp
@@ -0,0 +1,92 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/utility/Mutex.h>
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <string.h>
+
+namespace Silecs
+{
+
+	Mutex::Mutex(std::string name)
+    {
+    	int err;
+
+		// Mutex name if any, used for logging in particular
+    	name_ = name;
+
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Mutex (create): " << name_;
+
+    	//create the pthread-mutex using the default parameters + recursive option
+        pMutex_ = new pthread_mutex_t();
+
+        if ((err = pthread_mutexattr_init(&attr_)) != 0)
+			throw SilecsException(__FILE__, __LINE__, errno, strerror(errno));
+
+        //Mutex supports re-entrance for re-open mechanism inside send/recv action (doOpen() method call)
+        if ((err = pthread_mutexattr_settype(&attr_, PTHREAD_MUTEX_RECURSIVE)) !=0)
+                throw SilecsException(__FILE__, __LINE__, errno, strerror(errno));
+
+		if ((err = pthread_mutex_init(pMutex_, &attr_)) != 0)
+			throw SilecsException(__FILE__, __LINE__, errno, strerror(errno));
+    }
+
+    Mutex::~Mutex()
+    {
+    	int err;
+
+		if (DEBUG & Log::topics_) LOG(ALLOC) << "Mutex (delete): " << name_;
+
+		if ((err = pthread_mutexattr_destroy(&attr_)) != 0)
+			throw SilecsException(__FILE__, __LINE__, errno, strerror(errno));
+
+		if ((err = pthread_mutex_destroy(pMutex_)) != 0)
+		{  //can be broken by SIGKILL (just leave with no Exception)
+		   //throw SilecsException(__FILE__, __LINE__, errno, strerror(errno));
+		}
+
+	    // patch by Stefano Magnoni (20-03-2012)
+	    // avoid memory leak when deallocating the mutex
+	    if(pMutex_!=NULL)
+	    {
+	    	delete pMutex_;
+	  	    pMutex_ = NULL;
+	    }
+    }
+
+    void Mutex::lock()
+    {
+    	int err;
+    	LOG(LOCK) << "Waiting for lock: " << this->name_;
+		if ((err = pthread_mutex_lock(pMutex_)) != 0)
+		{   // lock can be broken by SIGKILL (just release it with no Exception)
+			pthread_mutex_unlock(pMutex_);
+			//throw SilecsException(__FILE__, __LINE__, errno, strerror(errno));
+		}
+    	LOG(LOCK) << "Has locked: " << this->name_;
+    }
+
+    void Mutex::unlock()
+    {
+    	int err;
+		if ((err = pthread_mutex_unlock(pMutex_)) != 0)
+		{   // unlock can be broken by SIGKILL (just force release again but no Exception)
+			pthread_mutex_unlock(pMutex_);
+			//throw SilecsException(__FILE__, __LINE__, errno, strerror(errno));
+		}
+    	LOG(LOCK) << "Has unlocked: " << this->name_;
+    }
+
+}
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/Mutex.h b/silecs-communication-cpp/src/silecs-communication/interface/utility/Mutex.h
new file mode 100644
index 0000000000000000000000000000000000000000..ecf693deadb7276ec45697861bc7d9400cb82133
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/Mutex.h
@@ -0,0 +1,55 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _MUTEX_H_
+#define _MUTEX_H_
+
+#include <pthread.h>
+#include <errno.h>
+#include <string>
+#include <map>
+
+#include <silecs-communication/interface/utility/SilecsException.h>
+
+namespace Silecs
+{
+
+	class Condition;
+
+	class Mutex
+	{
+		public:
+			Mutex(std::string name = "undefined");
+			~Mutex();
+
+			void lock();
+			void unlock();
+
+		private:
+			friend class Condition;
+
+			// Mutex name if any, used for logging in particular
+			std::string name_;
+
+			// Mutex object
+			pthread_mutex_t* pMutex_;
+
+			// Mutex Attributes
+			pthread_mutexattr_t attr_;
+	};
+
+} // namespace
+
+#endif /* _MUTEX_H_ */
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsException.cpp b/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsException.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ae114f73de6a4132a11092d48ae65043dab08814
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsException.cpp
@@ -0,0 +1,331 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include "SilecsException.h"
+#include "SilecsLog.h"
+
+#include <string>
+
+namespace Silecs
+{
+
+    SilecsException::SilecsException(const std::string& file, const uint32_t line, const ErrorCode code, const std::string& extMsg)
+	{
+		errFile_ = file;
+		errLine_ = line;
+		errCode_ = code;
+		fillCategoryMessageFromCode(code);
+		errMessage_ += extMsg;
+		buildFullMessage();
+		//Log the error to the std. output (if ERROR topic is enable)
+		log();
+	}
+
+
+	SilecsException::SilecsException(const std::string& file, const uint32_t line, const int err, const char *str)
+	{
+		errFile_ = file;
+		errLine_ = line;
+		errCategory_ = CLIENT_SYSTEM_FAULT;
+		errCode_ = UNEXPECTED_ERROR;
+		errMessage_ = str;
+		buildFullMessage();
+
+		//Log the error to the std. output (if ERROR topic is enable)
+		log();
+	}
+
+    SilecsException::SilecsException(const std::string& file, const uint32_t line, const std::string& msg)
+    {
+        errFile_ = file;
+        errLine_ = line;
+        errCategory_ = CLIENT_SYSTEM_FAULT;
+        errCode_ = UNEXPECTED_ERROR;
+        errMessage_ = msg;
+        buildFullMessage();
+        //Log the error to the std. output (if ERROR topic is enable)
+        log();
+    }
+
+	SilecsException::SilecsException(const SilecsException& ex)
+	{
+		errMessage_ = ex.errMessage_;
+
+		//----------------------------------
+		// Not used... initialized for safety. suggested by static analysis
+		errFile_ 		= "";
+		errLine_ 		= -1;
+		errCategory_ 	= CLIENT_SYSTEM_FAULT;
+		errCode_ 		= UNEXPECTED_ERROR;
+		//----------------------------------
+
+		//Log the error to the std. output (if ERROR topic is enable)
+		log();
+	}
+
+	SilecsException::~SilecsException() throw()
+	{
+	}
+
+	const char* SilecsException::what() const throw()
+    {
+        return errFullMessage_.c_str();
+    }
+
+
+	ErrorCategory SilecsException::getCategory() const
+	{
+		return errCategory_;
+	}
+
+
+	ErrorCode SilecsException::getCode() const
+	{
+		return errCode_;
+	}
+
+
+	const char* SilecsException::getMessage() const
+	{
+		return errMessage_.c_str();
+	}
+
+
+	void SilecsException::fillCategoryMessageFromCode(ErrorCode code)
+	{
+		switch(code)
+		{
+			case XML_FILE_NOT_WELLFORMED:
+				errCategory_ = XML_PARSING_FAULT;
+				errMessage_ = "This XML parameters file is not well-formed: ";
+				break;
+			case XML_ELEMENT_NOT_FOUND:
+				errCategory_ = XML_PARSING_FAULT;
+				errMessage_ = "XML Element not found within the parameters file: ";
+				break;
+			case XML_EXPRESSION_MISMATCH:
+				errCategory_ = XML_PARSING_FAULT;
+				errMessage_ = "The following rule does not match any XML Element within the parameters file:\n";
+				break;
+			case XML_CREATE_XPATH_FAULT:
+				errCategory_ = XML_PARSING_FAULT;
+				errMessage_ = "Cannot create the XML path context.";
+				break;
+			case XML_EVALUATE_XPATH_FAULT:
+				errCategory_ = XML_PARSING_FAULT;
+				errMessage_ = "Cannot find evaluate xPath expression.";
+				break;
+			case XML_ATTRIBUTE_NOT_FOUND:
+				errCategory_ = XML_PARSING_FAULT;
+				errMessage_ = "XML Attribute not found within the parameters file.";
+				break;
+			case XML_DATA_NOT_CONSISTENT:
+				errCategory_ = XML_PARSING_FAULT;
+				errMessage_ = "Design and Deployment data are not consistent (Registers and Blocks list.";
+				break;
+			case XML_DATA_TYPE_MISMATCH:
+				errCategory_ = XML_PARSING_FAULT;
+				errMessage_ = "XML data type mismatch within the parameters file.";
+				break;
+			case DATA_UNKNOWN_FORMAT_TYPE:
+				errCategory_ = DATA_FAULT;
+				errMessage_ = "Register Design has a wrong data format: ";
+				break;
+			case DATA_UNKNOWN_ACCESS_TYPE:
+				errCategory_ = DATA_FAULT;
+				errMessage_ = "Block Design has a wrong access-type: ";
+				break;
+			case DATA_UNKNOWN_SYNCHRO_TYPE:
+				errCategory_ = DATA_FAULT;
+				errMessage_ = "Register Design has a wrong synchronization type: ";
+				break;
+			case DATA_UNKNOWN_PLC_MANUFACTURER:
+				errCategory_ = DATA_FAULT;
+				errMessage_ = "Controller Deployment has a wrong manufacturer: ";
+				break;
+            case DATA_UNKNOWN_PLC_MODEL:
+                errCategory_ = DATA_FAULT;
+                errMessage_ = "Controller Deployment has a wrong model: ";
+                break;
+            case DATA_UNKNOWN_PLC_SYSTEM:
+                errCategory_ = DATA_FAULT;
+                errMessage_ = "Controller Deployment has a wrong system: ";
+                break;
+			case DATA_UNKNOWN_PROTOCOL_MODE:
+				errCategory_ = DATA_FAULT;
+				errMessage_ = "Controller Deployment has a wrong protocol mode: ";
+				break;
+			case DATA_READ_ACCESS_TYPE_MISMATCH:
+				errCategory_ = DATA_FAULT;
+				errMessage_ = "Trying to read a write-only register: ";
+				break;
+			case DATA_WRITE_ACCESS_TYPE_MISMATCH:
+				errCategory_ = DATA_FAULT;
+				errMessage_ = "Trying to write a read-only register: ";
+				break;
+			case DATA_SYNCHRO_ACCESS_TYPE_MISMATCH:
+				errCategory_ = DATA_FAULT;
+				errMessage_ = "Synchronization and Access types of this register are not compatible: ";
+				break;
+			case DATA_ARRAY_LENGTH_MISMATCH:
+				errCategory_ = DATA_FAULT;
+				errMessage_ = "ArrCOMM_BLOCK_RESIZING_NOT_ALLOWEDay length is not compatible: ";
+				break;
+			case PARAM_INCORRECT_ARGUMENTS:
+				errCategory_ = PARAM_FAULT;
+				errMessage_ = "Incorrect SILECS service arguments.";
+				break;
+			case PARAM_FILE_NOT_FOUND:
+				errCategory_ = PARAM_FAULT;
+				errMessage_ = "This parameters file does not exist: ";
+				break;
+			case PARAM_UNKNOWN_BLOCK_NAME:
+				errCategory_ = PARAM_FAULT;
+				errMessage_ = "Unknown block-name: ";
+				break;
+			case PARAM_UNKNOWN_DEVICE_NAME:
+				errCategory_ = PARAM_FAULT;
+				errMessage_ = "Unknown device-name: ";
+				break;
+			case PARAM_UNKNOWN_REGISTER_NAME:
+				errCategory_ = PARAM_FAULT;
+				errMessage_ = "Unknown register-name: ";
+				break;
+			case PARAM_ACCESS_TYPE_MISMATCH:
+				errCategory_ = PARAM_FAULT;
+				errMessage_ = "Use of inappropriate method (access-type) to access the block: ";
+				break;
+			case PARAM_FORMAT_TYPE_MISMATCH:
+				errCategory_ = PARAM_FAULT;
+				errMessage_ = "Use of inappropriate method (format/dimension) to access the register: ";
+				break;
+			case PARAM_ARRAY_DIMENSION_MISMATCH:
+				errCategory_ = PARAM_FAULT;
+				errMessage_ = "Trying to access the following array-register with wrong index or dimension: ";
+				break;
+			case PARAM_NO_TIME_STAMP:
+				errCategory_ = PARAM_FAULT;
+				errMessage_ = "Trying to access the Time-Stamp of a Write-Only register: ";
+				break;
+			case PARAM_INCORRECT_BLOCK_ADDRESS:
+				errCategory_ = PARAM_FAULT;
+				errMessage_ = "Schneider uses 16bit alignment addressing. The Block address should be an even value: ";
+				break;
+            case PARAM_EXCEEDED_BLOCK_SIZE:
+                errCategory_ = PARAM_FAULT;
+                errMessage_ = "The specified block-size exceeds the one allocated: ";
+                break;
+			case PARAM_UNKNOWN_IP_ADDRESS:
+				errCategory_ = PARAM_FAULT;
+				errMessage_ = "This IP address is unknown or not well-formed: ";
+				break;
+			case PARAM_UNKNOWN_PLC_HOSTNAME:
+				errCategory_ = PARAM_FAULT;
+				errMessage_ = "This controller hostname is unknown or not well-formed: ";
+				break;
+			case COMM_CONNECT_FAILURE:
+				errCategory_ = COMM_FAULT;
+				errMessage_ = "Unable to connect the controller: ";
+				break;
+			case COMM_RECONNECT_FAILURE:
+				errCategory_ = COMM_FAULT;
+				errMessage_ = "Unable to re-connect the controller: ";
+				break;
+			case COMM_CONNECT_CLOSED:
+				errCategory_ = COMM_FAULT;
+				errMessage_ = "Connection has been closed with the controller: ";
+				break;
+			case COMM_ALREADY_ENABLED:
+				errCategory_ = COMM_FAULT;
+				errMessage_ = "Controller connection already enabled: ";
+				break;
+			case COMM_NOT_CONNECTED_YET:
+				errCategory_ = COMM_FAULT;
+				errMessage_ = "Trying to access (send/recv) a controller that is not connected yet: ";
+				break;
+            case COMM_ALREADY_CONNECTED:
+                errCategory_ = COMM_FAULT;
+                errMessage_ = "Controller already connected: ";
+                break;
+
+            case COMM_BLOCK_RESIZING_NOT_ALLOWED:
+                errCategory_ = COMM_FAULT;
+                errMessage_ = "Data-block resizing is allowed only with single device access (send/recv).";
+                break;
+			case CONFIG_CLASS_NOT_DEPLOYED:
+				errCategory_ = CONFIG_FAULT;
+				errMessage_ = "This controller/Design deployment does not exist: ";
+				break;
+			case CONFIG_CLIENT_PLC_NOT_CONSISTENT:
+				errCategory_ = CONFIG_FAULT;
+				errMessage_ = "The client configuration is not consistent with the mapping of the controller: ";
+				break;
+			case CONFIG_CLIENT_PLC_NOT_AVAILABLE:
+				errCategory_ = CONFIG_FAULT;
+				errMessage_ = "Reading the controller Header data has failed: IP address of that client is not allowed or the controller memory is empty: ";
+				break;
+			case DIAG_SLAVE_REGISTER_NOT_INITIALIZED:
+				errCategory_ = DIAG_FAULT;
+				errMessage_ = "Connection is not allowed now because some of retentive slave registers are not initialized yet: ";
+				break;
+            case DIAG_PLC_REPORT_NOT_SUPPORTED:
+                errCategory_ = DIAG_FAULT;
+                errMessage_ = "Diagnostic and status report are not supported with this controller type: ";
+                break;
+			case CNV_INTERNAL_ERROR:
+				errCategory_ = CNV_SYSTEM_FAULT;
+				errMessage_ = "CNV library error: ";
+				break;
+			case UNEXPECTED_ERROR:
+				errCategory_ = CLIENT_SYSTEM_FAULT;
+				errMessage_ = "Unexpected error: ";
+				break;
+			default:
+				errCategory_ = UNKNOWN_FAULT;
+				errMessage_ = "Unknown fault.";
+		}
+	}
+
+	void SilecsException::buildFullMessage()
+	{
+		errFullMessage_ = errCategory_ + "/" + errCode_;
+		errFullMessage_ += " ";
+
+		char errLineAsString[5] = {0};
+		sprintf(errLineAsString, "%d", int(errLine_));
+
+		errFullMessage_ += errFile_ + ":" + errLineAsString;
+		errFullMessage_ += " " + errMessage_;
+	}
+
+	void SilecsException::print() const
+	{
+    	std::cerr << "Silecs::SilecsException [" << errCategory_ << "/" << errCode_ << "] "
+				  << errFile_  << ":" << errLine_ << ", "
+				  << errMessage_
+				  << std::endl;
+	}
+
+
+	void SilecsException::log() const
+	{
+		unsigned long topic = ERROR; //Exception means ERROR topic
+		if (errCategory_ == DIAG_FAULT) topic |= DIAG; //and DIAG topic if required for syslog purpose
+    	LOG(topic) << "[" << errCategory_ << "/" << errCode_ << "] "
+				   << errFile_  << ":" << errLine_ << ", "
+				   << errMessage_;
+	}
+
+} // namespace
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsException.h b/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsException.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d1f5f8031dfab8bca75ef453bdd21c0dfa2a3c2
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsException.h
@@ -0,0 +1,185 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _SILECS_EXCEPTION_H_
+#define _SILECS_EXCEPTION_H_
+
+#include <stdexcept>
+#include <stdint.h>
+
+
+namespace Silecs
+{
+
+	/*!
+	 * \brief Defines the category of the SILECS Exception.
+	 * Can be used in the Exception catch to dispatch emergency actions.
+	 * Use Exception::getCategory() to retrieve it.
+	 */
+	typedef enum
+	{
+		CLIENT_SYSTEM_FAULT = 1,
+		PLC_SYSTEM_FAULT,
+		CNV_SYSTEM_FAULT,
+		XML_PARSING_FAULT,
+		DATA_FAULT,
+		PARAM_FAULT,
+		COMM_FAULT,
+		CONFIG_FAULT,
+		DIAG_FAULT,
+		NO_FAULT,
+		UNKNOWN_FAULT
+	} ErrorCategory;
+
+	/*!
+	 * \brief Defines the detailed code of the SILECS Exception.
+	 * Can be used in the Exception catch to execute the appropriate action.
+	 * Use SilecsException::getCode() to retrieve it.
+	 */
+	typedef enum
+	{
+		XML_FILE_NOT_WELLFORMED = 1,
+		XML_ELEMENT_NOT_FOUND,
+		XML_EXPRESSION_MISMATCH,
+		XML_CREATE_XPATH_FAULT,
+		XML_EVALUATE_XPATH_FAULT,
+		XML_ATTRIBUTE_NOT_FOUND,
+		XML_DATA_NOT_CONSISTENT,
+		XML_DATA_TYPE_MISMATCH,
+		DATA_UNKNOWN_FORMAT_TYPE,
+		DATA_UNKNOWN_ACCESS_TYPE,
+		DATA_UNKNOWN_SYNCHRO_TYPE,
+		DATA_UNKNOWN_PLC_MANUFACTURER,
+        DATA_UNKNOWN_PLC_MODEL,
+        DATA_UNKNOWN_PLC_SYSTEM,
+		DATA_UNKNOWN_PROTOCOL_MODE,
+		DATA_READ_ACCESS_TYPE_MISMATCH,
+		DATA_WRITE_ACCESS_TYPE_MISMATCH,
+		DATA_SYNCHRO_ACCESS_TYPE_MISMATCH,
+		DATA_ARRAY_LENGTH_MISMATCH,
+		PARAM_INCORRECT_ARGUMENTS,
+		PARAM_FILE_NOT_FOUND,
+		PARAM_UNKNOWN_BLOCK_NAME,
+		PARAM_UNKNOWN_DEVICE_NAME,
+		PARAM_UNKNOWN_REGISTER_NAME,
+		PARAM_ACCESS_TYPE_MISMATCH,
+		PARAM_FORMAT_TYPE_MISMATCH,
+		PARAM_ARRAY_DIMENSION_MISMATCH,
+		PARAM_NO_TIME_STAMP,
+		PARAM_INCORRECT_BLOCK_ADDRESS,
+		PARAM_EXCEEDED_BLOCK_SIZE,
+		PARAM_UNKNOWN_IP_ADDRESS,
+		PARAM_UNKNOWN_PLC_HOSTNAME,
+		COMM_CONNECT_FAILURE,
+		COMM_RECONNECT_FAILURE,
+		COMM_CONNECT_CLOSED,
+		COMM_ALREADY_ENABLED,
+		COMM_ALREADY_CONNECTED,
+		COMM_NOT_CONNECTED_YET,
+        COMM_BLOCK_RESIZING_NOT_ALLOWED,
+		CONFIG_CLASS_NOT_DEPLOYED,
+		CONFIG_CLIENT_PLC_NOT_CONSISTENT,
+		CONFIG_CLIENT_PLC_NOT_AVAILABLE,
+		DIAG_SLAVE_REGISTER_NOT_INITIALIZED,
+        DIAG_PLC_REPORT_NOT_SUPPORTED,
+		CNV_INTERNAL_ERROR,
+		UNEXPECTED_ERROR,
+		UNKNOWN_ERROR
+	} ErrorCode;
+
+	/*!
+	 * \class SilecsException
+	 * \brief This class is the based class for the Exceptions generated by the SILECS library.
+	 * An error belongs to a category, it has a code identifier within the category and
+	 * a description message.
+	 */
+	class SilecsException : public std::exception
+	{
+	public:
+
+		/// @cond
+        SilecsException(const SilecsException & ex);
+        virtual ~SilecsException() throw();
+
+        /*!
+         * \brief Constructor and copy-constructors
+         * \param file-name, line-number and error-code for specific faults
+         * \param file-name, line-number, error-no and error-str for system faults or extra-str if needed
+         */
+		SilecsException(const std::string& file, const uint32_t line, const ErrorCode code, const std::string& extMsg = std::string());
+		SilecsException(const std::string& file, const uint32_t line, const int err, const char *str);
+        SilecsException(const std::string& file, const uint32_t line, const std::string& msg);
+
+        /*!
+         * \return a string with the error description
+         */
+        const char* what() const throw();
+
+        /*!
+         * \brief This method displays a warning for a not defined exception
+         */
+		//static void unknown(const std::string file, const long line);
+		/// @endcond
+
+        /*!
+         * \brief Returns the category of the Exception object.
+         * \return value from the ErrorCategory enumeration
+         */
+		ErrorCategory getCategory() const;
+
+        /*!
+         * \brief Returns the error code of the Exception object.
+         * \return value from the ErrorCode enumeration
+         */
+		ErrorCode getCode() const;
+
+        /*!
+         * \brief Returns string message describing the Exception object.
+         * \return Error message as string
+         */
+		const char* getMessage() const;
+
+        /*!
+         * \brief Print readable message of the exception to the standard output (console):
+         * Time-stamp, Category, Code, Source File/Line and extra message
+         */
+		void print() const;
+
+	private:
+        /*!
+         * \fn fillCategoryMessageFromCode
+         * \brief This method assign the appropriate message to a given errCode
+         */
+		void fillCategoryMessageFromCode(ErrorCode code);
+
+		void buildFullMessage();
+
+        /*!
+         * \brief Log readable message of the exception to the standard output (if ERROR topic enable):
+         * Time-stamp, Category, Code, Source File/Line and extra message
+         */
+		void log() const;
+
+        std::string errFile_;
+        long errLine_;
+        ErrorCategory errCategory_;
+        ErrorCode errCode_;
+		std::string errMessage_;
+		std::string errFullMessage_;
+	};
+
+} // namespace
+
+#endif //_SILECS_EXCEPTION_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsLog.cpp b/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsLog.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0891e4661a9b767fc0af77b2b2e9c9c269a069a3
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsLog.cpp
@@ -0,0 +1,169 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/interface/utility/SilecsLog.h>
+#include <silecs-communication/interface/utility/StringUtilities.h>
+#include <silecs-communication/interface/utility/TimeStamp.h>
+#include <syslog.h>
+#include <string.h>
+
+
+namespace Silecs
+{
+	//TRACE is a particular topic used to feed ACET tracing service with static information
+	//of the running program (SILECS library in that case). Sys-logging of it is mandatory and
+	//cannot be disabled to insure ACET does not miss sources.
+	//DIAG is a particular topic used to feed the standard syslog with minimal information for
+    //debugging purpose, sys-logging cannot be disabled as well
+	unsigned long Log::topics_    = 0;
+	unsigned long Log::systopics_ = TRACE|DIAG;
+
+	bool Log::syslogIsStarted_ = false; //syslog not yet started
+	TsCounter Log::timeStamp_(true);
+
+	Log::Log(unsigned long topic)
+	{	topic_ = topic;
+	}
+
+	Log::~Log()
+	{
+		if (topic_ & topics_) {
+			//this topic is enabled for std. output
+			std::cerr << os.str().c_str() << std::endl;
+		}
+
+	    if (topic_ & systopics_)
+	    	//this topic is enabled for syslog output
+	    	syslog(LOG_INFO, os.str().c_str());
+	}
+
+	bool Log::getTopicsFromString(const std::string& topicArgv)
+	{
+		unsigned long topicsTemp 	= NO_TOPIC; // Remove all the topics
+
+		unsigned int i; int j;
+		bool wrongTopic = false;
+		std::vector<std::string> topicCol;
+		StringUtilities::tokenize(topicArgv, topicCol, ",");
+		for (i=0; i<topicCol.size(); ++i)
+		{	for (j=0; j<topicNb; ++j)
+			{	if (topicCol[i] == topicList[j])
+				{ topicsTemp |= 1<<j;
+				  break;
+				}
+			}
+			if (j==topicNb)
+			{	wrongTopic = true;
+				std::cerr << "SILECS setup failed: Unknown diagnostic topic: " << topicCol[i] << std::endl;
+				break;
+			}
+
+		}
+		//Return false if topic parameters are not correct or empty
+		//if (!(wrongTopic || topicCol.size()==0)) // replaced for performance
+		if (!(wrongTopic || topicCol.empty()))
+		{
+			topics_ = topicsTemp;
+			return true;
+		}
+		return false;
+	}
+
+	std::string Log::setTopicToString(unsigned long topic)
+	{
+		int i=0;
+		while(topic > 1) { topic >>=1; i++; }
+		if (i>=topicNb)
+		{	std::cerr << "Unknown topic id: '" << topic << "'. Giving ERROR topic as default." << std::endl;
+			i = 0;
+		}
+        return ("/"+topicList[i]);
+	}
+
+	std::ostringstream& Log::getLog()
+	{
+	    os << "TIME " << std::setprecision(5) << timeStamp_.getValue(S_UNIT);
+	    os << "s SILECS" << setTopicToString(topic_) << "(thread " << pthread_self() << "): ";
+	    return os;
+	}
+
+	std::ostringstream& Log::getTrace(std::string source)
+	{
+		os << "Environment=prod|MessageType=static|MessageSeverity=info|SenderType=library|SenderDomain=silecs|SenderSubdomain=client|";
+		os << "SenderSource=" << source << "||";
+	    return os;
+	}
+
+	std::ostringstream& Log::getLogDelay()
+	{
+	    os << "DELAY " << std::setprecision(5) << timeStamp_.getDelay(MS_UNIT);
+	    os << "ms SILECS" << setTopicToString(topic_) << "(thread " << pthread_self() << "): ";
+	    return os;
+	}
+
+	bool Log::setLogArguments(int argc, char ** argv)
+	{
+		bool argsOk = true;
+		for(int i=0; i< argc; i++)
+		{   if((strcmp(argv[i], "-plcLog") == 0) && (i+1 < argc))
+			{   argsOk = Log::getTopicsFromString(argv[i+1]);
+		        break;
+			}
+		}
+		return argsOk;
+	}
+
+	std::string Log::getLogArguments()
+	{
+		int j;
+		std::string argsList;
+		argsList = "-plcLog " + topicList[0] + "[,";
+		for (j=1; j<topicNb-1; ++j)	argsList += topicList[j] + ",";
+		argsList += topicList[j] + "] ";
+		return argsList;
+	}
+
+	void Log::startSyslog(char* ident, unsigned long topics)
+	{
+		if  (!syslogIsStarted_)
+		{
+			systopics_ |= topics;
+
+			/* syslog service uses file configuration (required root access):
+			 * /etc/<syslog.conf>     : to define the ouput channel (file, console, host)
+			 * /etc/<sysconfig/syslog>: to set-up the syslogd daemon
+			 * For SILECS log we use LOCAL2 facility that is required for ACET service.
+			 * LOCAL2 is also compliant with SILECS diagnostic purpose since by default
+			 * LOG_LOCAL[1..5] are stored into /var/log/messages NFS files, as required.
+			 * Ask to system expert (Nmn) to know about syslogd redirection details.
+			 */
+			openlog (ident, LOG_NDELAY, LOG_LOCAL2);
+			syslogIsStarted_ = true;
+		}
+	}
+
+	void Log::stopSyslog()
+	{
+		if  (syslogIsStarted_)
+		{
+			syslogIsStarted_ = false;
+			//remove syslog resources
+			closelog();
+
+			LOG(SETUP) << "syslog service has been stopped.";
+		}
+	}
+
+} // namespace
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsLog.h b/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsLog.h
new file mode 100644
index 0000000000000000000000000000000000000000..bf0ae830185041fd7db09d7c928d9c98915e9af1
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsLog.h
@@ -0,0 +1,115 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _SILECS_LOG_H_
+#define _SILECS_LOG_H_
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <stdio.h>
+#include <iomanip>
+
+
+namespace Silecs
+{
+	class TsCounter;
+
+	#define NO_TOPIC 0	//used to call LOG without filtering: LOG(NO_TOPIC)
+	#define LOG(topic) if (topic & (Log::topics_ | Log::systopics_)) Log(topic).getLog()
+	#define LOG_DELAY(topic) if (topic & (Log::topics_ | Log::systopics_)) Log(topic).getLogDelay()
+	#define TRACE(source) if (TRACE & Log::systopics_) Log(TRACE).getTrace(source)
+
+	//Different topics can be used to filter the log messages to print on the std. output (console)
+	//In addition, 'DIAG' messages are sent to the syslog for post-diagnostic to ease tracking of
+	//unexpected process behavior (general messages to trace the process sequencing (not ERRORs)).
+	//By default, console logging is disabled for all topics but can be enable using '-plcLog' arguments.
+	//The DIAG console output can be enable/disable as well while DIAG syslog output is mandatory.
+	enum LogTopic
+	{
+		TRACE	= 1<<0, //special topic sent to the ACET tracing service
+		DIAG 	= 1<<1,	//special topic sent to the console (if enable) and to the syslog (everytime)
+		ERROR 	= 1<<2, //std. topic to trace the SILECS processing errors, sent to the console (if enable)
+		DEBUG 	= 1<<3, //std. topic to trace the SILECS debug info, sent to the console (if enable)
+		SETUP 	= 1<<4, //std. topic to trace details of SILECS start-up, sent to the console (if enable)
+		ALLOC 	= 1<<5, //std. topic to trace allocation memory, sent to the console (if enable)
+		RECV 	= 1<<6, //std. topic to trace transaction from PLC, sent to the console (if enable)
+		SEND 	= 1<<7, //std. topic to trace transaction toward PLC, sent to the console (if enable)
+		COMM 	= 1<<8, //std. topic to trace PLC communication stuff, sent to the console (if enable)
+		DATA	= 1<<9, //std. topic to trace transaction details (need SEND/RECV), sent to the console (if enable and )
+		LOCK	= 1<<10, //std. topic to trace resources lock details, sent to the console (if enable and )
+	};
+
+	const int topicNb = 11;
+	const std::string topicList[topicNb] =
+	{
+		"TRACE",
+		"DIAG",
+		"ERROR",
+		"DEBUG",
+		"SETUP",
+		"ALLOC",
+		"RECV",
+		"SEND",
+		"COMM",
+		"DATA",
+		"LOCK",
+	};
+
+	class Log
+	{
+	public:
+	    Log(unsigned long topic);
+	    virtual ~Log();
+
+	    std::ostringstream& getLog();
+	    std::ostringstream& getLogDelay();
+		std::ostringstream& getTrace(std::string source);
+
+	    // set log arguments: '-plcLog topic1[,topic2,..]'
+		static bool setLogArguments(int argc, char ** argv);
+
+        /*!
+         * \fn startSyslog
+         * \brief Used to enable the standard syslog mechanism
+         * \parameter topics: bit-set of the topics to be stored using the syslog (in addition to mandatory TRACE and DIAG)
+         */
+		static void startSyslog(char* ident, unsigned long systopics);
+		static void stopSyslog();
+
+	    // return valid log arguments as string: '-plcLog topic1[,topic2,..]'
+		static std::string getLogArguments();
+
+	    static std::string setTopicToString(unsigned long topic);
+
+	    static bool getTopicsFromString(const std::string& topicArgv);
+
+	    unsigned long topic_; 			//current topic of the logger
+	    static unsigned long topics_;	//enabled topics (coming from the process arguments)
+	    static unsigned long systopics_;//set of topics to be logged using the syslog mechanism
+
+	private:
+	    Log(const Log&);
+	    Log& operator =(const Log&);
+	    std::ostringstream os;
+	    static TsCounter timeStamp_;
+	    static bool syslogIsStarted_;
+	};
+
+} // namespace
+
+#endif //_SILECS_LOG_H_
+
+
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/StringUtilities.cpp b/silecs-communication-cpp/src/silecs-communication/interface/utility/StringUtilities.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2dbcffce08d99754af5902cc543fc8076bd0e183
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/StringUtilities.cpp
@@ -0,0 +1,120 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include "StringUtilities.h"
+#include <stdio.h>
+
+
+namespace Silecs
+{
+	const unsigned int StringUtilities::c_emptyStringArraySize = 1;
+	const char StringUtilities::c_emptyString[] = "\0";
+	const char* StringUtilities::c_emptyStringArray[1] = {"\0"};
+
+	void StringUtilities::tokenize(const std::string& str, std::vector<std::string>& tokens,
+			const std::string& delimiters) {
+
+	  size_t startPos = 0;
+	  size_t endPos = str.find_first_of(delimiters, 0);
+	  if (endPos == std::string::npos) {
+		//no delimiters
+		tokens.push_back(str);
+		return;
+	  }
+	  size_t maxLenght = str.size();
+	  while (startPos != std::string::npos && endPos != std::string::npos) {
+		// Found a token, add it to the vector.
+		std::string s = str.substr(startPos, endPos - startPos);
+		tokens.push_back(s);
+		// Next start delimiter
+		if (endPos < maxLenght -1)
+		  startPos = endPos+1;
+		else
+		  // string size exceeded
+		  break;
+		endPos = str.find_first_of(delimiters, startPos);
+		if (endPos == std::string::npos) {
+		  // no delimiter at the end : last token
+		  std::string s = str.substr(startPos, maxLenght - startPos);
+		  tokens.push_back(s);
+		}
+	  }
+	}
+
+	void StringUtilities::trimWhiteSpace(std::string& str) {
+		size_t pos = str.find(" ");
+		while (pos != std::string::npos) {
+			str.erase(pos, 1);
+			pos = str.find(" ");
+		}
+	}
+
+	std::string StringUtilities::toString(unsigned int data)
+	{
+		char tmp[32];
+		sprintf(tmp, "%u", data);
+		return tmp;
+	}
+
+	std::string StringUtilities::toString(int data)
+	{
+		char tmp[32];
+		sprintf(tmp, "%d", data);
+		return tmp;
+	}
+
+	std::string StringUtilities::toString(long data)
+	{
+		char tmp[32];
+		sprintf(tmp, "%ld", data);
+		return tmp;
+	}
+
+	std::string StringUtilities::toString(unsigned long data)
+	{
+		char tmp[32];
+		sprintf(tmp, "%lu", data);
+		return tmp;
+	}
+
+	std::string StringUtilities::toString(long long data)
+	{
+		char tmp[32];
+		sprintf(tmp, "%lld", data);
+		return tmp;
+	}
+
+	std::string StringUtilities::toString(double data)
+	{
+		char tmp[32];
+		sprintf(tmp, "%f", data);
+		return tmp;
+	}
+
+	std::string StringUtilities::toString(const void * ptr)
+	{
+		char tmp[32];
+		sprintf(tmp, "%p", ptr);
+		return tmp;
+	}
+
+	void StringUtilities::toLower(std::string& str)
+	{  //cannot used std::transform() method because of ppc4 support!
+	   for(unsigned int i=0;i<str.length();i++)
+	   { str[i] = tolower(str[i]);
+	   }
+	}
+
+} // namespace
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/StringUtilities.h b/silecs-communication-cpp/src/silecs-communication/interface/utility/StringUtilities.h
new file mode 100644
index 0000000000000000000000000000000000000000..a6bea35337f4aa8dccda1a19f076738def673129
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/StringUtilities.h
@@ -0,0 +1,74 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _STRING_UTILITIES_H_
+#define _STRING_UTILITIES_H_
+
+#include <string>
+#include <vector>
+#include <silecs-communication/interface/utility/SilecsException.h>
+#include <sstream>
+
+namespace Silecs
+{
+
+	class StringUtilities
+	{
+		public:
+			static void tokenize(const std::string& str, std::vector<std::string>& tokens,
+									const std::string& delimiters = " ");
+
+			static void trimWhiteSpace(std::string& str);
+
+			// define an array of one pointer on an empty string
+			static const unsigned int c_emptyStringArraySize;
+			static const char* c_emptyStringArray[1];
+			// define an empty string
+			static const char c_emptyString[];
+
+			static std::string toString(unsigned int data);
+			static std::string toString(int data);
+			static std::string toString(unsigned long data);
+			static std::string toString(long data);
+			static std::string toString(long long data);
+			static std::string toString(double data);
+			static std::string toString(const void * ptr);
+			static void toLower(std::string& str);
+
+		    /*!
+		     * \brief transform a string into any integer-type
+		     * \param str the string to transform
+		     * \param value that will receive the conversion
+		     */
+		    template<typename T> static void fromString(T& value, const std::string& str);
+
+	};
+
+	template<typename T>
+	inline void StringUtilities::fromString(T& value, const std::string& str)
+	{
+	    std::istringstream iss(str);
+	    if ((iss >> value).fail())
+	    {
+			std::ostringstream message;
+			message << "Failed to convert the string: '" << str << "' to numeric type";
+			throw SilecsException(__FILE__, __LINE__,message.str().c_str());
+	    }
+	}
+
+} // namespace
+
+
+#endif //_STRING_UTILITIES_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/Thread.h b/silecs-communication-cpp/src/silecs-communication/interface/utility/Thread.h
new file mode 100644
index 0000000000000000000000000000000000000000..fd2adbce634e3fcc914482e163caac3e6d05a51c
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/Thread.h
@@ -0,0 +1,250 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef _THREAD_H_
+#define _THREAD_H_
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <list>
+#include <utility>
+#include <map>
+#include <queue>
+#include <pthread.h>
+#include <signal.h>
+#include <malloc.h>
+#include <string.h>
+
+
+#include <silecs-communication/interface/core/Context.h>
+#include <silecs-communication/interface/utility/Condition.h>
+
+
+using namespace std;
+
+
+namespace Silecs
+{
+	class Context;
+
+	/*! -------------------------------------------------------------------------
+	 * \class Task
+	 * \brief Template for the Task class.
+	 * A Task class is defined by what the user wants to execute (user_function)
+	 * and by the data he wants to use (user_data).
+	 * It is up to the user to specify the Task template according to
+	 * his data type.
+	 */
+	template<typename UserDataType>
+	class Task
+	{
+	 public:
+		Task(int (*pFunc)(UserDataType, Context* pContext), UserDataType data);
+		int execute(Context* pContext);
+
+	 private:
+		int (*userFunc)(UserDataType, Context* pContext);	//function user
+		UserDataType userData_;          //data user
+	};
+
+	template<typename UserDataType>
+	Task<UserDataType>::Task::Task(int (*pFunc)(UserDataType, Context* pContext), UserDataType data):
+			userFunc(pFunc), userData_(data)
+	{
+	}
+
+	template<typename UserDataType>
+	int Task<UserDataType>::execute(Context* pContext)
+	{
+		return userFunc(userData_, pContext);
+	}
+
+	/*! -------------------------------------------------------------------------
+	 * \class Thread
+	 * \brief Template for the Thread class.
+	 * One Thread instance is required per PLC connection.
+	 * The thread allows delegated transaction from the Cluster API level.
+	 * Thus, a Send/Recv Cluster call can start action on each PLC in parallel.
+	 */
+	template<typename UserDataType>
+	class Thread
+	{
+	public:
+		Thread();
+		~Thread();
+		unsigned int getPriority();
+		void setPriority(unsigned int rtprio);
+		void schedule(Task<UserDataType> *pt, Context* pContext);
+		void waitForTaskCompletion();
+	private:
+		static void *run(void *arg);
+		void execute();
+		Task<UserDataType> *pTask_;
+		Context* pContext_;	//to transmit data from the caller context: Cluster, PLC or Device
+		pthread_t *pTid_;
+		Condition* pThreadCompletion_;	//condition-variable for thread loop synchronization
+		bool endThread_;				//boolean predicate associated with pThreadCompletion
+		Condition* pTaskCompletion_;	//condition-variable for task process synchronization
+		bool endTask_;					//boolean predicate associated with pTaskCompletion
+		Mutex* pThreadBusy_;			//mutex to protect thread against concurrent asynchronous call
+	};
+
+	template<typename UserDataType>
+	Thread<UserDataType>::Thread(): endThread_(false), endTask_(true)
+	{
+	  int err;
+	  pThreadBusy_			= new Mutex("threadBusy");
+	  pThreadCompletion_	= new Condition("threadCompletion");
+	  pTaskCompletion_		= new Condition("taskCompletion");
+
+	  pTid_ = (pthread_t *)malloc(sizeof(pthread_t));
+	  pThreadCompletion_->lock();		// The constructor will wait until thread is ready
+	  if ((err = pthread_create(pTid_, NULL, run, this)) != 0)
+		  throw SilecsException(__FILE__, __LINE__, errno, strerror(err));
+	  //err = pthread_detach(*pTid_); not necessary because PLC thread are infinite loop
+	  pThreadCompletion_->wait();		// Wait until thread is ready
+	  pThreadCompletion_->unlock();	// Thread is ready
+	};
+
+	template<typename UserDataType>
+	void *Thread<UserDataType>::run(void *pThisThread)
+	{
+	  Thread *pthis = (Thread*) pThisThread;
+
+	  //An SILECS thread should not be disturbed by signals that may come from the host process.
+	  //Then, block signals which are generated by the system itself (means RT signals).
+	  sigset_t smask;
+	  sigemptyset(&smask);
+	  for(int snum=SIGRTMIN; snum<=SIGRTMAX; sigaddset(&smask, snum++))
+	  {	  int err;
+		  if ((err = pthread_sigmask(SIG_BLOCK, &smask, NULL)) != 0)
+			throw SilecsException(__FILE__, __LINE__, errno, strerror(err));
+	  }
+	  pthis->execute();
+	  return 0;
+	};
+
+	template<typename UserDataType>
+	void Thread<UserDataType>::execute()
+	{
+	  pThreadCompletion_->lock();		// The constructor will waiting until thread is ready
+	  pThreadCompletion_->signal();		// Thread is ready (for constructor waiting)
+
+	  while (endThread_ != true)
+	  {
+		pThreadCompletion_->wait();		// Wait for schedule or end-Thread request
+		if (endThread_ == true) break;	// end-thread request: exit infinite loop
+
+		try
+		{ pTaskCompletion_->lock();		// To protect the enTask_ condition variable
+		  //check if pThreadCompletion.wait has not been canceled by spurious signal
+		  if (endTask_ == false)
+		  {   //ok, the task has to be executed
+			  pTask_->execute(pContext_);	// Schedule request: task execution
+			  endTask_ = true;				// Task is finished
+			  pTaskCompletion_->signal();	// Inform caller thread that task has been completed
+		  }
+		  pTaskCompletion_->unlock();
+		}
+		catch(std::exception& ex)
+		{
+		 std::cerr << "[Thread::execute] ERROR: during execution:" << ex.what() << std::endl;
+		}
+		catch(...)
+		{
+		 std::cerr << "[Thread::execute] ERROR: during execution - unknown exception received" << std::endl;
+		}
+	  }
+
+	  pThreadCompletion_->unlock();	// Thread is terminated
+	};
+
+	template<typename UserDataType>
+	unsigned int Thread<UserDataType>::getPriority()
+	{
+		int policy;
+		sched_param params;
+
+		if (pthread_getschedparam(*pTid_, &policy, &params) != 0)
+		{	string errMsg(string("Cannot get dynamically schedparams: ") + strerror(errno));
+			throw errMsg;
+		}
+		return params.sched_priority;
+	}
+
+	template<typename UserDataType>
+	void Thread<UserDataType>::setPriority(unsigned int rtprio)
+	{
+		int policy;
+		sched_param params;
+
+		if (pthread_getschedparam(*pTid_, &policy, &params) == 0)
+		{	params.sched_priority = rtprio;
+			if (pthread_setschedparam(*pTid_, sched_getscheduler(getpid()), &params) == 0)
+				return;
+		}
+		string errMsg(string("Cannot set dynamically schedparams: ") + strerror(errno));
+		throw errMsg;
+	}
+
+	template<typename UserDataType>
+	void Thread<UserDataType>::waitForTaskCompletion()
+	{
+		pTaskCompletion_->lock();		// To protect the enTask_ condition variable check
+		while (endTask_ == false)
+		{	pTaskCompletion_->wait(); 	// Wait for task completion
+		}
+		pTaskCompletion_->unlock(); 	// Task has been completed
+		pThreadBusy_->unlock();			// Thread has finished to execute the current task (resource is free)
+	}
+
+	template<typename UserDataType>
+	void Thread<UserDataType>::schedule(Task<UserDataType> *pt, Context* pContext)
+	{
+	  pThreadBusy_->lock();			// Thread resource must be locked until full task completion
+	  pThreadCompletion_->lock();	// To protect the endThread_ condition variable update
+	  pContext_ = pContext;			// Update the caller context and
+	  pTask_ = pt;					// the task reference to be executed
+	  endTask_ = false;				// Task is not completed yet
+	  pThreadCompletion_->signal();	// Wake-up the thread to execute this referred task
+	  pThreadCompletion_->unlock();
+	};
+
+	template<typename UserDataType>
+	Thread<UserDataType>::~Thread()
+	{
+	  int err;
+	  pThreadCompletion_->lock();		// To protect the endThread_ condition variable
+	  endThread_ = true;				// Thread shall stop on the next loop
+	  pThreadCompletion_->signal();		// Wake-up the thread to execute this referred task
+	  pThreadCompletion_->unlock();
+
+	  err = pthread_join(*pTid_, NULL); // Wait for thread end before continuing clean-up
+
+	  delete pTaskCompletion_;
+	  delete pThreadCompletion_;
+	  delete pThreadBusy_;
+
+	  // patch by Stefano Magnoni (20-03-2012)
+	  // avoid memory leak when deallocating the thread
+	  free(pTid_);
+	  pTid_ = NULL;
+
+	};
+
+} // namespace
+
+#endif // _THREAD_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/TimeStamp.cpp b/silecs-communication-cpp/src/silecs-communication/interface/utility/TimeStamp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5d4605def0afb2ca0a51eebf8b10902d5a34afaa
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/TimeStamp.cpp
@@ -0,0 +1,126 @@
+/*
+ *  Piece of code adapted for SILECS.
+ *  Original version references:
+ *
+ *  Portable Agile C++ Classes (PACC)
+ *  Copyright (C) 2004 by Marc Parizeau
+ *  http://manitou.gel.ulaval.ca/~parizeau/PACC
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Contact:
+ *  Laboratoire de Vision et Systemes Numeriques
+ *  Departement de genie electrique et de genie informatique
+ *  Universite Laval, Quebec, Canada, G1K 7P4
+ *  http://vision.gel.ulaval.ca
+ *
+*/
+
+#include <silecs-communication/interface/utility/TimeStamp.h>
+#include <iostream>
+
+namespace Silecs
+{
+
+	double TsCounter::mPeriod = 0;
+
+	void
+	TsCounter::calibrateCountPeriod(unsigned int inDelay/*ms*/, unsigned int inTimes) {
+
+		if(mHardware) {
+			#if defined (__GNUG__) && (defined (__i386__) || defined (__PPC__))
+			double lPeriod = 0;
+			// calibrate by matching the time-stamps with the micro-seconds of gettimeofday
+			for(unsigned int i = 0; i < inTimes; ++ i) {
+				timeval lStartTime, lTime;
+				::gettimeofday(&lStartTime, 0);
+				unsigned long long lStartCount = getCount();
+
+				struct timespec theDelay, time_left_before_wakeup;
+				int sec = inDelay/1000; // number of seconds since delay is expressed in ms
+				long nsec = 0;
+				if ((nsec = inDelay%1000)) // check remainder
+					nsec *= (long)1E6;   // convert remainder into ns
+				theDelay.tv_sec = sec;
+				theDelay.tv_nsec = nsec;
+				#ifdef __Lynx__
+				  //UNIX variants often use a kernel timer resolution (HZ value)
+				  //of about 10ms. So it' not possible to manage delays less than 10ms
+				  //to wait 10ms you need specify a delay 0 othewhise your delay will b 20ms
+				  if((inDelay%10)<5){
+					theDelay.tv_nsec -= 20000000;
+				  }else{
+					theDelay.tv_nsec -= 10000000;
+				  }
+				  if (theDelay.tv_nsec < 0)
+					theDelay.tv_nsec = 0;
+				#endif
+				nanosleep(&theDelay, &time_left_before_wakeup) ;
+
+				::gettimeofday(&lTime, 0);
+				unsigned long long lCount = getCount() - lStartCount;
+				lTime.tv_sec -= lStartTime.tv_sec;
+				lTime.tv_usec -= lStartTime.tv_usec;
+				// dismiss the first run of the loop
+				if(i != 0) lPeriod += (lTime.tv_sec + lTime.tv_usec*0.000001)/lCount;
+			}
+			mPeriod = lPeriod/(inTimes-1);
+			#else
+			// use the microseconds of gettimeofday
+			mPeriod = 0.000001;
+			#endif
+		} else {
+		// use the microseconds of gettimeofday
+		mPeriod = 0.000001;
+		}
+	}
+
+	unsigned long long
+	TsCounter::getCount(void) const {
+	unsigned long long lCount = 0;
+
+		if(mHardware) {
+			#if defined (__GNUG__) && defined (__i386__)
+			__asm__ volatile("rdtsc" : "=A" (lCount));
+			#else
+			#if defined (__GNUG__) && defined (__PPC__)
+			register unsigned int lLow;
+			register unsigned int lHigh1;
+			register unsigned int lHigh2;
+			do {
+			// make sure that high bits have not changed
+			__asm__ volatile ( "mftbu %0" : "=r" (lHigh1) );
+			__asm__ volatile ( "mftb  %0" : "=r" (lLow) );
+			__asm__ volatile ( "mftbu %0" : "=r" (lHigh2) );
+			} while(lHigh1 != lHigh2);
+			// transfer to lCount
+			unsigned int *lPtr = (unsigned int*) &lCount;
+			*lPtr++ = lHigh1; *lPtr = lLow;
+			#else
+			timeval lCurrent;
+			::gettimeofday(&lCurrent, 0);
+			lCount = (unsigned long long)lCurrent.tv_sec*1000000 + lCurrent.tv_usec;
+			#endif
+			#endif
+		} else {
+			timeval lCurrent;
+			::gettimeofday(&lCurrent, 0);
+			lCount = (unsigned long long)lCurrent.tv_sec*1000000 + lCurrent.tv_usec;
+		}
+
+		return lCount;
+	}
+
+} // namespace
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/TimeStamp.h b/silecs-communication-cpp/src/silecs-communication/interface/utility/TimeStamp.h
new file mode 100644
index 0000000000000000000000000000000000000000..e17dea719e820a8e56af013745dfbaf0717d1c89
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/TimeStamp.h
@@ -0,0 +1,91 @@
+/*
+ *  Piece of code adapted for SILECS.
+ *  Original version references:
+ *
+ *  Portable Agile C++ Classes (PACC)
+ *  Copyright (C) 2004 by Marc Parizeau
+ *  http://manitou.gel.ulaval.ca/~parizeau/PACC
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Contact:
+ *  Laboratoire de Vision et Systemes Numeriques
+ *  Departement de genie electrique et de genie informatique
+ *  Universite Laval, Quebec, Canada, G1K 7P4
+ *  http://vision.gel.ulaval.ca
+ *
+*/
+
+#ifndef _TimeStamp_H_
+#define _TimeStamp_H_
+
+#include <unistd.h>
+#ifdef __Lynx__
+#include <time.h>
+#else
+#include <sys/time.h>
+#endif
+
+
+namespace Silecs {
+
+#define S_UNIT		1.0  //express delay in second
+#define MS_UNIT		1.e3 //express delay in milli-second
+#define YS_UNIT		1.e6 //express delay in micro-second
+#define NS_UNIT		1.e9 //express delay in nano-second
+
+	class TsCounter {
+
+		public:
+			TsCounter(bool inHardware=true) : mHardware(inHardware) {
+				if (mPeriod == 0) calibrateCountPeriod();
+				mValueCount = 0;
+				reset();
+			}
+
+			void calibrateCountPeriod(unsigned int inDelay=50/*ms*/, unsigned int inTimes=10);
+			static double getCountPeriod(void) { return mPeriod; }
+			static void setCountPeriod(double period) { mPeriod = period; }
+			void reset(void) { mValueCount = getCount();  mDelayCount = 0; }
+
+			unsigned long long getCount(void) const;
+			double getCount(double unit) const { return (double)getCount()*mPeriod*unit; }
+
+			double getValue(double unit)
+			{	unsigned long long count = getCount();
+				mDelayCount = count;
+				return (double)(count-mValueCount)*mPeriod*unit;
+			}
+
+			double getDelay(double unit)
+			{	return (double)(getCount()-mDelayCount)*mPeriod*unit;
+			}
+
+			double getTimeOfDay(double unit) {
+					timeval lCurrent;
+					::gettimeofday(&lCurrent, 0);
+					return ((lCurrent.tv_sec*YS_UNIT + lCurrent.tv_usec)*(unit/YS_UNIT));
+			}
+
+		protected:
+			bool mHardware;
+			unsigned long long mValueCount; //duration from start
+			unsigned long long mDelayCount; //duration from previous getCount
+			static double mPeriod;
+	};
+
+} //namespace Silecs
+
+#endif // _TimeStamp_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/XMLParser.cpp b/silecs-communication-cpp/src/silecs-communication/interface/utility/XMLParser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..488c853229c3fa7dca24e3f971361a7865cb9bad
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/XMLParser.cpp
@@ -0,0 +1,242 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+
+#include <silecs-communication/interface/utility/XMLParser.h>
+#include <silecs-communication/interface/utility/SilecsException.h>
+#include <silecs-communication/interface/utility/StringUtilities.h>
+
+#include <cstring>
+#include <fstream>
+
+namespace
+{
+	bool isInitialized_ = false;
+}
+namespace Silecs
+{
+
+XMLParser::XMLParser(const std::string& fileName, bool validateFile) :
+    fileName_(fileName)
+{
+	if( !isInitialized_)
+	{
+        throw SilecsException(__FILE__, __LINE__, "Silecs XML-Parser needs to be initialized before usage!");
+	}
+    if (validateFile)
+    {
+        const std::ifstream file(fileName.c_str());
+        if (file.fail())
+        {
+            std::ostringstream message;
+            message << "The Parameter File " << fileName << " was not found";
+            throw SilecsException(__FILE__, __LINE__, message.str().c_str());
+        }
+        // Check if file is valid
+    }
+}
+
+XMLParser::~XMLParser()
+{
+}
+
+void XMLParser::init()
+{
+        xmlInitParser();
+        isInitialized_ = true;
+}
+
+void XMLParser::cleanUp()
+{
+	xmlCleanupParser();
+}
+
+void XMLParser::trimCarrierReturn(std::string& s) const
+{
+    size_t startPos = 0;
+    while ((startPos = s.find("\n", startPos)) != std::string::npos)
+    {
+        s.erase(startPos, 2);
+    }
+}
+
+void XMLParser::fillElement(xmlNodePtr node, ElementXML& element) const
+{
+    xmlChar* value = xmlNodeListGetString(node->doc, node->children, 1);
+    // If the node contains text, the carrier return is removed
+    if (value)
+    {
+        std::string trimString(reinterpret_cast<const char*>(value));
+        trimCarrierReturn(trimString);
+        element.value_ = trimString.c_str();
+        xmlFree(value);
+        value = NULL;
+    }
+    element.name_ = reinterpret_cast<const char*>(node->name);
+    // Loop over all the attributes of the XML element
+    if (node->properties != NULL)
+    {
+        xmlAttrPtr curAttr;
+        for (curAttr = node->properties; curAttr != NULL; curAttr = curAttr->next)
+        {
+            boost::shared_ptr<AttributeXML> attribute(new AttributeXML());
+            attribute->name_ = reinterpret_cast<const char*>(curAttr->name);
+            value = xmlGetProp(node, reinterpret_cast<const xmlChar*>(attribute->name_.c_str()));
+            attribute->value_ = reinterpret_cast<const char*>(value);
+            xmlFree(value);
+            value = NULL;
+            element.attributeList_.push_back(attribute);
+        }
+    }
+    // Loop over all the child nodes of the XML element
+    if (node->xmlChildrenNode != NULL)
+    {
+        xmlNodePtr curNode;
+        for (curNode = node->xmlChildrenNode; curNode != NULL; curNode = curNode->next)
+        {
+            if ((curNode->type == XML_ELEMENT_NODE))
+            {
+                boost::shared_ptr<ElementXML> child(new ElementXML());
+                fillElement(curNode, *child);
+                element.childList_.push_back(child);
+            }
+        }
+    }
+}
+
+boost::optional<boost::ptr_vector<ElementXML> > XMLParser::getElementsFromXPath(const std::string& xpathExpression) const
+{
+    boost::optional<boost::ptr_vector<ElementXML> > elements;
+    // Load the XML document
+    const xmlDocPtr document = xmlParseFile(fileName_.c_str());
+    if (document == NULL)
+    {
+        std::ostringstream message;
+        message << "The Parameter File " << fileName_ << " could not be parsed";
+        throw SilecsException(__FILE__, __LINE__, message.str().c_str());
+    }
+    // Create an XPath evaluation context
+    const xmlXPathContextPtr xpathContext = xmlXPathNewContext(document);
+    if (xpathContext == NULL)
+    {
+        xmlFreeDoc(document);
+        return elements;
+    }
+    // Evaluate the XPath expression
+    const xmlXPathObjectPtr xpathObject = xmlXPathEvalExpression(reinterpret_cast<const xmlChar*>(xpathExpression.c_str()), xpathContext);
+    if (xpathObject == NULL)
+    {
+        xmlXPathFreeContext(xpathContext);
+        xmlFreeDoc(document);
+        return elements;
+    }
+    // Loop over the node set returned by XPath
+    if (xmlXPathNodeSetIsEmpty(xpathObject->nodesetval) == false)
+    {
+        for (int i = 0; i < xpathObject->nodesetval->nodeNr; ++i)
+        {
+            std::auto_ptr<ElementXML> element(new ElementXML());
+            fillElement(xpathObject->nodesetval->nodeTab[i], *element);
+            if (!elements)
+            {
+                elements = boost::ptr_vector<ElementXML>();
+            }
+            elements->push_back(element.release());
+        }
+    }
+    // Cleanup
+    xmlXPathFreeObject(xpathObject);
+    xmlXPathFreeContext(xpathContext);
+    xmlFreeDoc(document);
+    return elements;
+}
+
+boost::ptr_vector<ElementXML> XMLParser::getElementsFromXPath_throwIfEmpty(const std::string& xpathExpression) const
+{
+	boost::optional<boost::ptr_vector<ElementXML> > result = getElementsFromXPath(xpathExpression);
+	if( !result )
+	{
+		std::ostringstream message;
+		message << "The xpathExpression: '" << xpathExpression << "' did not find a match";
+		throw SilecsException(__FILE__, __LINE__, message.str().c_str());
+	}
+	if( result.get().size() == 0)
+	{
+		std::ostringstream message;
+		message << "The xpathExpression: '" << xpathExpression << "' returned an empty collection of xml-Elements";
+		throw SilecsException(__FILE__, __LINE__, message.str().c_str());
+	}
+	return result.get();
+}
+
+ElementXML XMLParser::getFirstElementFromXPath(const std::string& xpathExpression) const
+{
+	boost::optional<boost::ptr_vector<ElementXML> > result = getElementsFromXPath_throwIfEmpty(xpathExpression);
+	return result.get()[0];
+}
+
+xmlChar* XMLParser::ConvertInput(const char *in, const char *encoding)
+{
+    xmlChar *out;
+    int32_t ret;
+    int32_t size;
+    int32_t out_size;
+    int32_t temp;
+    xmlCharEncodingHandlerPtr handler;
+
+    if (in == 0)
+        return 0;
+
+    handler = xmlFindCharEncodingHandler(encoding);
+
+    if (!handler)
+    {
+		std::ostringstream message;
+		message << "The encoding: '" << encoding << "' was not found";
+		throw SilecsException(__FILE__, __LINE__, message.str().c_str());
+    }
+
+    size = (int32_t)std::strlen(in) + 1;
+    out_size = size * 2 - 1;
+    out = (unsigned char *) xmlMalloc((size_t) out_size);
+
+    if (out == 0)
+    {
+    	std::ostringstream message;
+    	message << "Failed to convert the xml to: '" << encoding << "'";
+    	throw SilecsException(__FILE__, __LINE__, message.str().c_str());
+    }
+
+	temp = size - 1;
+	ret = handler->input(out, &out_size, (const xmlChar *) in, &temp);
+	if ((ret < 0) || (temp - size + 1))
+	{
+		std::ostringstream message;
+		message << "Failed to convert the xml to: '" << encoding << "'";
+		throw SilecsException(__FILE__, __LINE__, message.str().c_str());
+		xmlFree(out);
+		out = 0;
+	}
+	else
+	{
+		out = (unsigned char *) xmlRealloc(out, out_size + 1);
+		out[out_size] = 0; /*null terminating out */
+	}
+
+
+    return out;
+}
+
+} // fesa
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/XMLParser.h b/silecs-communication-cpp/src/silecs-communication/interface/utility/XMLParser.h
new file mode 100644
index 0000000000000000000000000000000000000000..b403b40026601735079c3aab44dde5904b6c7100
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/XMLParser.h
@@ -0,0 +1,191 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+
+#ifndef _XMLPARSER_HPP_
+#define _XMLPARSER_HPP_
+
+#include <boost/optional.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/shared_ptr.hpp>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <unistd.h>
+#include <sstream>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/encoding.h>
+
+#include <silecs-communication/interface/utility/SilecsException.h>
+
+#define MY_ENCODING "UTF-8"
+
+namespace Silecs
+{
+
+/*!
+ * \class AttributeXML
+ * \brief This class represents an XML attribute containing name and value
+ */
+class AttributeXML
+{
+  public:
+    /*!
+     * \brief name_ of the attribute
+     */
+    std::string name_;
+
+    /*!
+     * \brief value_ of the attribute
+     */
+    std::string value_;
+};
+
+/*!
+ * \class ElementXML
+ * \brief This class represents an XML element containing name, value, a list of attributes
+ * and a list of child XML elements
+ */
+class ElementXML
+{
+  public:
+    /*!
+     * \brief name of the element
+     */
+    std::string name_;
+
+    /*!
+     * \brief value of the element
+     */
+    std::string value_;
+
+    /*!
+     * \brief list of attributes of the element
+     */
+    std::vector<boost::shared_ptr<AttributeXML> > attributeList_;
+
+    /*!
+     * \brief list of children of the element
+     */
+    std::vector<boost::shared_ptr<ElementXML> > childList_;
+
+    bool hasAttribute(const std::string& attributeName) const
+    {
+        std::vector<boost::shared_ptr<AttributeXML> >::const_iterator attributeIter;
+        for(attributeIter = attributeList_.begin();attributeIter != attributeList_.end();++attributeIter)
+        {
+            if((*attributeIter)->name_ == attributeName)
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    std::string getAttribute(const std::string& attributeName) const
+    {
+        std::vector<boost::shared_ptr<AttributeXML> >::const_iterator attributeIter;
+        for(attributeIter = attributeList_.begin();attributeIter != attributeList_.end();++attributeIter)
+        {
+            if((*attributeIter)->name_ == attributeName)
+            {
+                return (*attributeIter)->value_;
+            }
+        }
+        std::ostringstream message;
+        message << "The XML Attribute " << (*attributeIter)->name_ << " was not found";
+        throw SilecsException(__FILE__, __LINE__, message.str().c_str());
+    }
+};
+
+
+/*!
+ * \class XMLParser
+ * \brief This class offers functions to extract information from an XML file.
+ * It uses the xPath functions of the library libXML
+ */
+class XMLParser
+{
+  public:
+
+    /*!
+     * \brief constructor
+     * \param fileName path of the file that represents the xml element
+     * \param validateFile if true, file is validated
+     */
+    XMLParser(const std::string& fileName, bool validateFile);
+
+    /*!
+     * \brief destructor
+     */
+    virtual ~XMLParser();
+
+    /*!
+     * \brief Retrieve the elements identified by the XPath expression from the XML file
+     * \param xpathExpression The XPath expression
+     */
+    virtual boost::optional<boost::ptr_vector<ElementXML> > getElementsFromXPath(const std::string& xpathExpression) const;
+
+    virtual ElementXML getFirstElementFromXPath(const std::string& xpathExpression) const;
+
+    virtual boost::ptr_vector<ElementXML> getElementsFromXPath_throwIfEmpty(const std::string& xpathExpression) const;
+
+
+    /*!
+     * \brief Has to be executed from the main-thread before this class can be used
+     */
+    static void init();
+
+    /*!
+     * \brief Has to be executed from the main-thread on shutdown
+     */
+    static void cleanUp();
+
+  private:
+
+    /*!
+     * \brief removes carrier return from string
+     * \param s the string to remove the carrier from
+     */
+    void trimCarrierReturn(std::string& s) const;
+
+    /*!
+     * \brief fills instance of the class ElementXML with nodes from an XML file
+     * \param node that contains the xml info
+     * \param [out] pElement into which the info will be put
+     */
+    void fillElement(xmlNodePtr node, ElementXML& element) const;
+
+    /*!
+     * \brief converts a char array to a xmlChar array
+     * \param in The char array
+     * \param encoding the coding format
+     * \return the xmlChararray
+     */
+    xmlChar* ConvertInput(const char *in, const char *encoding);
+
+    /*!
+     * \brief path of the file
+     */
+    std::string fileName_;
+};
+
+} // fesa
+
+#endif // XML_PARSER_H_
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/core/ietype.h b/silecs-communication-cpp/src/silecs-communication/protocol/core/ietype.h
new file mode 100644
index 0000000000000000000000000000000000000000..6d07415e9e7dd02861deb7055664797685caefbb
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/core/ietype.h
@@ -0,0 +1,166 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+
+/*
+ * Revision : v1.0
+ * Date     : 08/2003 - F.Locci
+ * Objet    : original version for SCHNEIDER and SIMATIC PLCs
+ * Action   : 
+ *
+ * Revision : v1.1
+ * Date     : 10/2003 - F.Locci
+ * Objet    : original version for SCHNEIDER and SIMATIC PLCs
+ * Action   : 
+ *
+ * Revision : v1.2
+ * Date     : 10/2005 - F.Locci
+ * Objet    : Allow absolute offset for eveyr protocol       
+ * Action   : To prevent interface modification we use 
+ *          : following convention:
+ *		    : . negative constant to use relative offset (BLK_..)
+ *		    : . positive value to use absolute offset
+ *
+ * Revision : v1.3
+ * Date     : 03/2007 - F.Locci
+ * Objet    : Increase receive buffer size (MAX_DATA_REP_..) to 64kb
+ * Action   : Increase cosntant from 21504 to 64kb to fulfill some      
+ *          : specific user requirement (BOFISOP class) - adjust timeout
+ *
+ * Revision : v1.4
+ * Date     : 04/2007 - F.Locci
+ * Objet    : Prevent SIEMENS PLC disconnection                       
+ * Action   : Provide Keep-Alive transaction to be called periodically  
+ *
+*/
+
+#ifndef _IETYPE_H_
+#define _IETYPE_H_
+
+/* ---------------------------------------------------------*/
+/* INCLUDE FILES																						*/
+/* ---------------------------------------------------------*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#ifdef __Lynx__
+#include <time.h>
+#else
+#include <sys/time.h>
+#endif
+#include <pthread.h>
+
+/* ---------------------------------------------------------*/
+/* LOCAL CONSTANT DEFINITIONS                               */
+/* ---------------------------------------------------------*/
+
+/* protocol parameters */
+/*v1.1 modif.
+  Create individual constant for defer cmd data in order to
+  allow large command for fetch/write & modbus protocol.
+*/
+/*v1.1 modif. (previous one, still valid)
+  DATA_CMD_DEFER_SIZE: 8192 --> 4096 (RFC) to support deferred 
+  mode with S7-300 PLC. This modification was necessary to avoid 
+  S7-341 ethernet coupler crashing when receiving to big command
+  defer frame.
+  Size = 8192 had been choosen for S7-400 ISOLDE project but is too
+  large for S7-300 memory. 
+  Attention! This v1.1 modification double the number of 
+  deferred transation with pisobeam if we recompile 'plcgenrt' process
+  with this new version (normally we woudln't have to do it)
+*/
+#define MAX_RFC_CMD_DEFER_SIZE   4096  /*byte - see PLC code      				 */
+#define MAX_FEW_CMD_DEFER_SIZE   16384 /*byte - no constraint on PLC side		 */
+#define MAX_MDB_CMD_DEFER_SIZE   16384 /*byte - no constraint on PLC side		 */
+#define MAX_S7_CMD_DEFER_SIZE    16384 /*byte - no constraint on PLC side		 */
+#define MAX_DATA_CMD_DEFER_SIZE  16384 /*byte - MUST BE the max 3 above constants*/
+
+#define MAX_DATA_REP_DEFER_SIZE  65536 /*v1.3, byte - see PLC code*/
+#define MAX_DATA_REP_ASYNC_SIZE  4096  /*byte - see PLC code*/
+
+/* error constant */
+// silecs internal error ...................................
+// don't forget to modify IeGetErrorMessage(..) function
+#define RFC_SYS_ERROR			(int)-1
+#define RFC_PARAM_ERROR			(int)-2
+#define RFC_CONNECT_ERROR		(int)-3
+#define RFC_DISCONNECT_ERROR	(int)-4
+#define RFC_TIMEOUT_ERROR		(int)-5
+#define RFC_EPIPE_ERROR			(int)-6
+#define RFC_FRAME_ERROR			(int)-7
+
+#define IE_SYS_ERROR              RFC_SYS_ERROR
+#define IE_PARAM_ERROR            RFC_PARAM_ERROR
+#define IE_CONNECT_ERROR          RFC_CONNECT_ERROR
+#define IE_DISCONNECT_ERROR       RFC_DISCONNECT_ERROR
+#define IE_TIMEOUT_ERROR          RFC_TIMEOUT_ERROR
+#define IE_EPIPE_ERROR            RFC_EPIPE_ERROR
+#define IE_FRAME_ERROR            RFC_FRAME_ERROR
+#define IE_DEFER_CMD_BUFFER_FULL  (int)-100
+#define IE_DEFER_REP_BUFFER_EMPTY (int)-101
+#define IE_NB_MONITORING_ERROR    (int)-102
+#define IE_HOST_PING_ERROR        (int)-103
+#define IE_CONFIG_FILE_ERROR      (int)-104
+#define IE_BLOCK_SIZE_ERROR       (int)-105
+#define IE_HOST_UNKNOWN_ERROR     (int)-106
+
+// PLC report error .......................................
+#define IE_EQUIPMENT_UNKNOWN_ERROR (int)-200 // Class/Eqp unknow
+#define IE_MEMORY_OVERFLOW_ERROR   (int)-201 // get data buffer too long
+#define IE_ACCESS_VIOLATION_ERROR  (int)-202 // DB unknown or get/set access violation
+#define IE_MD_MONITORING_ERROR     (int)-203 // bad monitoring desc. or already used
+#define IE_ALLOC_MONITORING_ERROR  (int)-204 // monitoring record allocation failed
+#define IE_UNALLOC_MONITORING_ERROR (int)-205 // monitoring record unallocation failed
+#define IE_SET_TIME_IOCTL_ERROR     (int)-206 // PLC date_time SET failed
+#define IE_KEEP_ALIVE_IOCTL_ERROR   (int)-207 // PLC keep-alive transaction failed
+
+/* protocol parameters */
+#define MAX_CONNECT_TIMEOUT					2  /*s  */
+#define MAX_DATA_TIMEOUT					12 /*s  v1.3*/
+
+/* ---------------------------------------------------------*/
+/* MACRO DEFINITIONS					  													  */
+/* ---------------------------------------------------------*/
+
+// Used to convert DT PLC format to/from DSC time format
+// see convert functions below
+#define _frombcd(a) (int)(((a>>4)*10)+(a&0x0F))
+#define _tobcd(a)   (((unsigned char)((a)/10)<<4)+((a)%10))
+
+/* ---------------------------------------------------------*/
+/* TYPE DEFINITIONS                                         */
+/* ---------------------------------------------------------*/
+
+/* PLCs data format ........................................*/
+typedef char               _CHAR;
+typedef unsigned char      _BYTE;
+typedef unsigned short     _WORD;
+typedef unsigned long      _DWORD;
+typedef short              _INT;
+typedef long               _DINT;
+typedef float              _REAL;
+typedef unsigned char      _DT[8];
+
+
+#endif /* _IETYPE_H_ */
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/core/silecs.cpp b/silecs-communication-cpp/src/silecs-communication/protocol/core/silecs.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..def46b4105ec9ae7d223b18e473354dbc523544d
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/core/silecs.cpp
@@ -0,0 +1,360 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+
+/*
+ *
+ * Revision : v1.0
+ * Date     : 01/2010 - F.Locci
+ * Objet    : Initial version - From previous Silecs-2
+ * Action   :
+ */
+
+/*
+ * This library was developped to provide communication between
+ * Linux/LynxOS active host (client) and a PLC passive server.
+ * Based on S7 or MODBUS std. protocole, it defines generic
+ * set and get functions to read and write data into/from PLC
+ * memory.
+ *
+ */
+
+/* ---------------------------------------------------------*/
+/* INCLUDE FILES																						*/
+/* ---------------------------------------------------------*/
+#include <fcntl.h>
+#include <signal.h>
+
+#include <silecs-communication/protocol/core/silecs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ---------------------------------------------------------*/
+/* MACRO DEFINITION																				  */
+/* ---------------------------------------------------------*/
+
+/* This macro is used to trap the unexpected broken pipe and
+   return an error instead of exit process.
+*/
+static __sighandler_t sigpipeHandler = (__sighandler_t)-1;
+#define _DISABLE_SIGPIPE sigpipeHandler = signal(SIGPIPE, SIG_IGN)
+#define _ENABLE_SIGPIPE signal(SIGPIPE, sigpipeHandler)
+
+/*----------------------------------------------------------*/
+/* Time funtion
+ * IeRfcSetTime: Convert lynxos time_t format to PLC _DT format
+ * (SIMATIC).
+ *
+ * Details:
+ * PLC DATE_AND_TIME (or DT) format is coded on 8 byte in BCD
+ * format:
+ * 0      1      2      3      4      5      6       7
+ * YY     MM     DD     HH     MN     SC     SC/100  SC/10e4
+ */
+void IeRfcSetTime(unsigned char *dt, time_t epoch)  // to PLC
+{
+  struct tm *dscst;
+  dscst = localtime(&epoch);
+
+  dt[7] = 0;   // not used at the moment
+  dt[6] = 0;   // not used at the moment
+  dt[5] = _tobcd(dscst->tm_sec);
+  dt[4] = _tobcd(dscst->tm_min);
+  dt[3] = _tobcd(dscst->tm_hour);
+  dt[2] = _tobcd(dscst->tm_mday);
+  dt[1] = _tobcd(dscst->tm_mon+1);
+  dt[0] = _tobcd(dscst->tm_year-100);
+}
+
+/*----------------------------------------------------------*/
+/* Time funtion
+ * IeRfcGetTime: Convert PLC _DT format to time_t format (SIMATIC).
+ *
+ * Details:
+ * PLC DATE_AND_TIME (or DT) format is coded on 8 byte in BCD
+ * format:
+ * 0      1      2      3      4      5      6       7
+ * YY     MM     DD     HH     MN     SC     SC/100  SC/10e4
+ */
+double IeRfcGetTime(unsigned char *dt) // from PLC
+{
+	struct tm plcst;
+	time_t plctm;
+	double ms;
+	int year;
+
+  plcst.tm_sec  = _frombcd(dt[5]);
+  plcst.tm_min  = _frombcd(dt[4]);
+  plcst.tm_hour = _frombcd(dt[3]);
+  plcst.tm_mday = _frombcd(dt[2]);
+  plcst.tm_mon  = _frombcd(dt[1])-1;
+  year = _frombcd(dt[0]);
+  //look at Siemens DATA_AND_TIME type documentation
+  plcst.tm_year = ((year >= 90) ? year : year+100);
+
+  ms = ((double)_frombcd(dt[6])/100.)+((double)_frombcd(dt[7])/10000.);
+  plcst.tm_isdst = -1; // daylight saving time unavailable
+  plctm = mktime(&plcst);
+
+  return((double)plctm + ms);
+}
+
+/*----------------------------------------------------------*/
+/* This is a function used to connect an host on a port.
+ * 'ip' is the ip address string
+ * 'port' is the port number (102 for rfc1006 server)
+ * 'dst' is the TSAP destination string (exp: "TCP-1")
+ * 'src' is the TSAP source string (exp: "TCP-1")
+ * 'ts' timeout in second (1s minimum)
+ * return a socket descriptor or <0 on error
+ * (see constant error)
+ *
+ * Details:
+ * intermediate connect_nonb() function is used to perform a non-blockant connection.
+ * intermediate rfcPing() function is used to check if PLC is ON
+ */
+int connect_nonb(int sockfd, struct sockaddr *saptr, socklen_t salen, int nsec)
+{
+	int				flags, n, error;
+	socklen_t		len;
+	fd_set			rset, wset;
+	struct timeval	tval;
+
+	flags = fcntl(sockfd, F_GETFL, 0);
+	fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
+
+	error = 0;
+  /*v1.1*/
+  _DISABLE_SIGPIPE;
+	n = connect(sockfd, (struct sockaddr *) saptr, salen);
+  _ENABLE_SIGPIPE;
+	if (n < 0){
+		if (errno != EINPROGRESS)
+			return(-1);
+	}
+
+	/* Do whatever we want while the connect is taking place. */
+
+	if (n == 0)
+		goto done;	/* connect completed immediately */
+
+	FD_ZERO(&rset);
+	FD_SET(sockfd, &rset);
+	wset = rset;
+	tval.tv_sec = nsec;
+	tval.tv_usec = 0;
+
+	if ( (n = select(sockfd+1, &rset, &wset, NULL,
+					 nsec ? &tval : NULL)) == 0) {
+		close(sockfd);		/* timeout */
+		errno = ETIMEDOUT;
+		return(-1);
+	}
+
+	if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
+		len = sizeof(error);
+		if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
+			return(-1);			/* Solaris pending error */
+		}
+	}
+
+done:
+	fcntl(sockfd, F_SETFL, flags);	/* restore file status flags */
+
+	if (error) {
+		/*close(sockfd); just in case */
+		errno = error;
+		return(-1);
+	}
+
+	return(0);
+}
+
+/*----------------------------------------------------------*/
+int rfcPing(char *ip, long ts)
+{
+	int err, s, val = 1;
+	struct protoent *pent;
+	struct sockaddr_in rsock;
+
+	/* Socket create/connect */
+	memset ((char *)&rsock,0,sizeof(rsock));
+
+	if ((s=socket(AF_INET,SOCK_STREAM,0)) == -1)
+	{
+	  #ifdef COMMENT
+		printf("#Error - Can't create socket: %s\n", strerror(errno));
+	  #endif
+		return RFC_SYS_ERROR;
+	}
+
+	/* Set TCP_NODELAY option to force immediate TCP/IP acknowledgement */
+	if ((pent=getprotobyname("TCP")) == NULL)
+	{
+	  #ifdef COMMENT
+		printf("#Error - Can't configure socket: %s\n", strerror(errno));
+	  #endif
+		return RFC_SYS_ERROR;
+	}
+	if (setsockopt(s,pent->p_proto,TCP_NODELAY,&val,4) == -1)
+	{
+	  #ifdef COMMENT
+		printf("#Error - Can't configure socket: %s\n", strerror(errno));
+	  #endif
+		return RFC_SYS_ERROR;
+	}
+
+	#ifdef COMMENT
+	printf("#Comment - Socket created: %i\n", s);
+	#endif
+
+	rsock.sin_addr.s_addr=inet_addr(ip);
+	rsock.sin_family=AF_INET;
+	/*check any port to detect if the host is OFF*/
+	rsock.sin_port=htons(102);
+
+	err = 0;
+	if (connect_nonb(s,(struct sockaddr *)(&rsock),sizeof(rsock), ts) == -1)
+	{
+	  /*if hostname is OFF, connect() fails on TIMEOUT*/
+      if ((errno == ETIMEDOUT) || (errno == EHOSTDOWN) || (errno == EHOSTUNREACH)) {
+	  	err = RFC_TIMEOUT_ERROR;
+	  }
+	}
+
+  	close(s);
+	return err;
+}
+
+/*..........................................................*/
+int IeRfcPing (char *hostName, char *plcIP)
+{
+  struct in_addr addr;
+  struct hostent *hp;
+  char *ipstr = plcIP;
+
+  if ((hostName == NULL) && (plcIP == NULL))
+	  return(IE_PARAM_ERROR);
+
+  // use hostName reference in priority else plcIP
+  if (hostName)
+	{
+	  hp = gethostbyname(hostName);
+		if (hp)
+		{
+		  addr.s_addr = *((unsigned long int *) hp->h_addr);
+		  ipstr = inet_ntoa(addr);
+		}
+	}
+
+  if (ipstr == NULL)
+ 	return(IE_HOST_UNKNOWN_ERROR);
+
+  /*trying to connect PLC (1 second max)*/
+  return (rfcPing(ipstr, 1));
+}
+
+/*----------------------------------------------------------*/
+/* This function return the string which describes the
+ * error given by 'error' parameter.
+ * 'error': error from ie library or PLC server (in)
+ * return string pointer
+ *
+ * Details:
+ */
+char *IeGetErrorMessage(int err)
+{
+  int i;
+
+  static struct
+  {
+	int ie_code;
+	char * ie_mes;
+  } errorMap[] =
+  {
+	{IE_SYS_ERROR, "[RFC lib.] function system error"},
+	{IE_PARAM_ERROR, "[IE/RFC lib.] bad parameter(s) value/format"},
+	{IE_CONNECT_ERROR, "[RFC lib.] PLC connection failed"},
+	{IE_DISCONNECT_ERROR, "[RFC lib.] PLC disconnection requested"},
+	{IE_TIMEOUT_ERROR, "[RFC lib.] communication (connect/send/recv) timeout occurred"},
+	{IE_EPIPE_ERROR, "[RFC lib.] PLC communication broken"},
+	{IE_FRAME_ERROR, "[RFC lib.] PLC data frame error"},
+	{IE_DEFER_CMD_BUFFER_FULL, "[IE lib.] deferred commands buffer overflow"},
+	{IE_DEFER_REP_BUFFER_EMPTY, "[IE lib.] deferred replies empty"},
+	{IE_BLOCK_SIZE_ERROR, "[IE lib.] block size exceed PLC memory allocation"},
+	{IE_NB_MONITORING_ERROR, "[IE lib.] monitoring descriptor out of limit"},
+	{IE_HOST_PING_ERROR, "[IE lib.] PLC does not reply to ping"},
+	{IE_HOST_UNKNOWN_ERROR, "[IE lib.] PLC hostname unknown"},
+	{IE_CONFIG_FILE_ERROR, "[IE lib.] pair PLC/FEC not found in the config. file"},
+	{IE_EQUIPMENT_UNKNOWN_ERROR, "[PLC] equipment id (devclass+eqp) unknown"},
+	{IE_MEMORY_OVERFLOW_ERROR, "[PLC] get data buffer overflow"},
+	{IE_ACCESS_VIOLATION_ERROR, "[PLC] DB unknown or get/set access violation"},
+	{IE_MD_MONITORING_ERROR, "[PLC] bad monitoring descriptor or already used"},
+	{IE_ALLOC_MONITORING_ERROR, "[PLC] monitoring record allocation failed"},
+	{IE_UNALLOC_MONITORING_ERROR, "[PLC] monitoring record unallocation failed"},
+	{IE_SET_TIME_IOCTL_ERROR, "[PLC] PLC date and time setting failed"},
+	{IE_KEEP_ALIVE_IOCTL_ERROR, "[PLC] PLC keep-alive transactions failed"},
+  };
+
+  static int errorMapSize = sizeof(errorMap)/sizeof(errorMap[0]);
+
+  if (err == 0)
+	return ("No error");
+
+  for (i=0; i<errorMapSize; i++)
+	if (errorMap[i].ie_code == err)
+	  return (errorMap[i].ie_mes);
+
+  return ("Unknown IE error");
+}
+
+/*----------------------------------------------------------*/
+/* This function initializes the DSC-PLC communication.
+ * return 0 or <0 on error (see constant error)
+ *
+ * Details:
+ * Must be executed at first.
+ */
+int IeInit (void)
+{
+  int err=0;
+
+  err |= IeMdbInit();
+
+  return (err);
+}
+
+/*----------------------------------------------------------*/
+/* This function de-initializes the DSC-PLC communication.
+ * return 0 or <0 on error (see constant error)
+ *
+ * Details:
+ * Must be executed at end.
+ */
+int IeExit (void)
+{
+  int err=0;
+
+  err |= IeMdbExit();
+
+  return (err);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/core/silecs.h b/silecs-communication-cpp/src/silecs-communication/protocol/core/silecs.h
new file mode 100644
index 0000000000000000000000000000000000000000..782495b2baea04d37276163140d6428c6daad085
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/core/silecs.h
@@ -0,0 +1,114 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+/*
+ *
+ * Revision : v1.0
+ * Date     : 01/2010 - F.Locci
+ * Objet    : Initial version - From previous Silecs-2
+ * Action   :
+ */
+
+#ifndef _SILECS_H_
+#define _SILECS_H_
+
+/*
+ * This library was developped to provide communication between
+ * Linux/LynxOS active host (client) and a PLC passive server.
+ * Based on S7 or MODBUS std. protocole, it defines generic
+ * set and get functions to read and write data into/from PLC
+ * memory.
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ---------------------------------------------------------*/
+/* INCLUDE FILES																						*/
+/* ---------------------------------------------------------*/
+#include "ietype.h"
+
+/* ---------------------------------------------------------*/
+/* PROTOTYPE DEFINITIONS                                    */
+/* ---------------------------------------------------------*/
+#include <silecs-communication/protocol/modbus/iemdb.h>  /* modbus interface  */
+
+/*----------------------------------------------------------*/
+/* Time funtion
+ * IeRfcSetTime: Convert time_t epoch date to PLC _DT format
+ * (SIMATIC).
+ *
+ * Details:
+ * PLC DATE_AND_TIME (or DT) format is coded on 8 byte in BCD
+ * format:
+ * 0      1      2      3      4      5      6       7
+ * YY     MM     DD     HH     MN     SC     SC/100  SC/10e4
+ */
+void IeRfcSetTime(unsigned char *dt, time_t epoch);  // to PLC
+
+/*----------------------------------------------------------*/
+/* Time funtion
+ * IeRfcGetTime: Convert PLC _DT format to lynxOS time_t format
+ * (SIMATIC).
+ *
+ * Details:
+ * PLC DATE_AND_TIME (or DT) format is coded on 8 byte in BCD
+ * format:
+ * 0      1      2      3      4      5      6       7
+ * YY     MM     DD     HH     MN     SC     SC/100  SC/10e4
+ */
+double IeRfcGetTime(unsigned char *dt); // from PLC
+
+/*----------------------------------------------------------*/
+/* IeRfcPing function is a function used to check
+ * if PLC is ON (~ping) before trying to connect it.
+ */
+int IeRfcPing (char *hostName, char *plcIP);
+
+/*----------------------------------------------------------*/
+/* This function return the string which describes the
+ * error given by 'error' parameter.
+ * 'error': error from ie library or PLC server (in)
+ * return string pointer
+ *
+ * Details:
+ */
+char *IeGetErrorMessage(int err);
+
+/*----------------------------------------------------------*/
+/* This function initializes the DSC-PLC communication.
+ * return 0 or <0 on error (see constant error)
+ *
+ * Details:
+ * Must be executed at first.
+ */
+int IeInit (void);
+
+/*----------------------------------------------------------*/
+/* This function initializes the DSC-PLC communication.
+ * return 0 or <0 on error (see constant error)
+ *
+ * Details:
+ * Must be executed at end.
+ */
+int IeExit (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SILECS_H_ */
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.cpp b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..94a55b1c559895c45034b8bbaec2001c330a616d
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.cpp
@@ -0,0 +1,441 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+/*
+ * Revision : v1.0
+ * Date     : 08/2003 - F.Locci
+ * Objet    : original version for PS7-SCHNEIDER PLC
+ * Action   :
+ *
+ * Revision : v1.1
+ * Date     : 05/2004 - F.Locci
+ * Objet    : .remove when data size = 0
+ *			  .set err on read/write error
+ *            Look at v1.1 comments
+ *
+ * Revision : v1.2
+ * Date     : 11/2004 - F.Locci
+ * Objet    : .move mb_master_init() call to IeMdbInit() function
+ *            to make modbus code reentrant.
+ *            Look at v1.2 comments
+ *
+ * Revision : v1.3
+ * Date     : 10/2004 - F.Locci
+ * Objet    : .Allow absolute offset for read/write action
+ *			  .Allow variable size for read/write action
+ *            => use offset sign convention for absolute/relative
+ *            => use application size instead of config.table one
+ *            Look at v1.3 comments
+ *
+ * Revision : v1.4
+ * Date     : 03/2006 - F.Locci
+ * Objet    : .Extend the number of possible connection (7 --> 32)
+ *			  in order to allow more than 7 connections with
+ *            DIFFERENT PLC (SPS/EA project in particular).
+ *            We keep 7 connection  for SIEMENS (F/W) protocole
+ *            to respect material constraint (14 ISO-ON-TCP max.)
+ *
+ * Revision : v1.5
+ * Date     : 01/2007 - F.Locci
+ * Objet    : implement BLOCK mode
+ * Action   : .Add IeMdbGetBlock() and IeMdbSetBlock() function
+ *            .Upgrade mdbFindEqp() function
+ *            Look at v1.5 comments
+ *
+ * Revision : v1.6
+ * Date     : 03/2007 - F.Locci
+ * Objet    : Protect Get data buffer overflow
+ *            Look at v1.5 comments
+ *
+ * Revision : v1.7
+ * Date     : 04/2007 - F.Locci
+ * Objet    : Direct byte swapping into MdbSetTime function
+ *            Look at v1.5 comments
+ */
+
+/*
+ * This library was developped to provide communication between
+ * Linux/LynxOS active host (client) and a PLC passive server.
+ * Based on MODBUS std. protocole, it defines generic
+ * set and get functions to read and write data into/from PLC
+ * memory.
+ */
+
+/* ---------------------------------------------------------*/
+/* INCLUDE FILES																						*/
+/* ---------------------------------------------------------*/
+#include <silecs-communication/protocol/core/ietype.h>
+#include "mb_addr.h"
+#include "mb_master.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ---------------------------------------------------------*/
+/* LOCAL CONSTANT DEFINITIONS																*/
+/* ---------------------------------------------------------*/
+
+/* For Modbus protocol */
+#define MODBUS_MAX_CONNECTION    64 /*v1.4*/
+#define MODBUS_SENDRETRIES_DEF   1
+#define MODBUS_TIMEOUT_DEF       2    /* in seconds */
+
+/*Config.Table entries offset - SCHNEIDER memory implementation - word alignment*/
+#define FEC_CMD_OFS	      0    	/* Command from FEC: first entry of cfg.table*/
+#define PARAMS_CMD_OFS	  2/2   /* Params of FEC command 		*/
+#define CURRENT_DATE_OFS  10/2  /* PLC current dat&time */
+#define SYS_INFO_OFS	  18/2  /* HW/SW info variables */
+#define DIAG_INFO_OFS     78/2  /* PLC SW/HW diagnostic */
+#define NB_EQP_OFS  	  132/2  /*nb table row */
+#define ADDR_TBL_OFS  	  134/2  /*table data (addr/size)*/
+
+#define swap16(w) ((((unsigned short)w & 0x00ff)<<8)+(((unsigned short)w & 0xff00)>>8))
+
+/* ---------------------------------------------------------*/
+/* TYPE DEFINITIONS					  															*/
+/* ---------------------------------------------------------*/
+/* an entry in the network array */
+typedef struct
+{
+	const char      *name;
+	node_addr_t     addr;
+	int             nd; /* the node descriptor... */
+	struct timespec timeout;
+	u32				send_retries;
+} network_t;
+
+/* ---------------------------------------------------------*/
+/* GLOBAL DECLARATIONS																			*/
+/* ---------------------------------------------------------*/
+
+/* ---------------------------------------------------------*/
+/* FUNCTIONS CODE																						*/
+/* ---------------------------------------------------------*/
+
+/*----------------------------------------------------------*/
+/* Local functions                                          */
+/* ---------------------------------------------------------*/
+
+/* Function to load a struct timeval correctly
+ * from a double.
+ */
+static inline struct timespec d_to_timespec(double time) {
+  struct timespec tmp;
+
+  tmp.tv_sec  = time;
+  tmp.tv_nsec = 1e9*(time - tmp.tv_sec);
+  return tmp;
+}
+
+/*----------------------------------------------------------*/
+/* Glocal functions                                         */
+/* ---------------------------------------------------------*/
+
+/*----------------------------------------------------------*/
+/* Time funtion
+ * IeMdbSetTime: Convert lynxos time_t format to PLC SCHNEIDER
+ * format.
+ *
+ * Details:
+ * PLC SCHNEIER format is coded on 8 bytes BCD
+ * format:
+ *
+ *  0      1      2      3      4      5     6     7
+ *  SC     00     HH     MN     MM     DD    YY	   YY
+ *
+ *  byte 1 is used by gateway to synchronize time setting.
+ */
+void IeMdbSetTime(unsigned char *dt, time_t epoch)  // to PLC
+{
+  struct tm *dscst;
+  dscst = localtime(&epoch);
+
+  /*v1.7*/
+  /*In fact, each 16bits word is swapped with SCHNEIDER PLC
+    1      0      3      2      5      4     7     6
+    SC     00     HH     MN     MM     DD    YY	   YY
+
+	Swapping can do it directly during data transferring
+  */
+
+  dt[1] = _tobcd(dscst->tm_sec);
+  dt[0] = 0x00; /*not used*/
+  dt[3] = _tobcd(dscst->tm_hour);
+  dt[2] = _tobcd(dscst->tm_min);
+  dt[5] = _tobcd(dscst->tm_mon+1);
+  dt[4] = _tobcd(dscst->tm_mday);
+  dt[7] = _tobcd(2000/100);
+  dt[6] = _tobcd(dscst->tm_year-100);
+}
+
+/*----------------------------------------------------------*/
+/* Time funtion
+ * IeMdbGetTime: Convert PLC SCHNEIDER format to time_t format.
+ *
+ * Details:
+ * PLC SCHNEIER format is coded on 8 bytes BCD
+ * format:
+ *
+ *  0      1        2      3      4      5     6     7
+ *  SC     SC/100   HH     MN     MM     DD    YY	 YY
+ *
+ */
+double IeMdbGetTime(unsigned char *dt) // from PLC
+{
+  struct tm plcst;
+  time_t plctm;
+  double ms;
+  int year;
+
+  /*In fact, each 16bits word is swapped with SCHNEIDER PLC
+    1      0        3      2      5      4     7     6
+    SC     SC/100   HH     MN     MM     DD    YY	 YY
+
+	Swapping can do it directly during data transferring
+  */
+
+  plcst.tm_sec  = _frombcd(dt[1]);
+  plcst.tm_hour = _frombcd(dt[3]);
+  plcst.tm_min  = _frombcd(dt[2]);
+  plcst.tm_mon  = _frombcd(dt[5])-1;
+  plcst.tm_mday = _frombcd(dt[4]);
+  year = _frombcd(dt[6]);
+  //look at Schneider DATA_AND_TIME type documentation
+  plcst.tm_year = ((year >= 90) ? year : year+100);
+  /*plcst.tm_wday = no used in PLC*/
+  /*plcst.tm_yday = no used in PLC*/
+
+  ms = ((double)_frombcd(dt[0])/100.);
+  plcst.tm_isdst = -1; // daylight saving time unavailable
+  plctm = mktime(&plcst);
+
+  return((double)plctm + ms);
+}
+
+/*----------------------------------------------------------*/
+/* This function initializes the DSC-PLC communication.
+ * return 0 or <0 on error (see constant error)
+ *
+ * Details:
+ * Must be executed at first.
+ */
+int IeMdbInit (void)
+{
+  /*v1.2*/
+  if (mb_master_init(MODBUS_MAX_CONNECTION) < 0)
+  {
+  #ifdef DEBUG
+    /* could not init network! */
+  	printf("\n#Error: mb_master_init() failed");
+  #endif
+    return (IE_SYS_ERROR);
+  }
+
+  return 0;
+}
+
+/*----------------------------------------------------------*/
+/* This function de-initializes the DSC-PLC communication.
+ * return 0 or <0 on error (see constant error)
+ *
+ * Details:
+ * Must be executed at end.
+ */
+int IeMdbExit (void)
+{
+  mb_master_done();
+  return 0;
+}
+
+/*----------------------------------------------------------*/
+/* This function creates a synchronous OSI-ON-TCP socket
+ * channel used for sending/receiving communication with PLC.
+ * 'hostName': Name of the host (in)
+ * 'plcIP': PLC ip address string (in)
+ * return socket descriptor or <0 on error (see const. error)
+ *
+ * Details:
+ * 'plcIP' parameter is necessary only when 'hostName' is NULL.
+ * Only one synchronous channel per PLC at the same time
+ * supported in that version.
+ */
+int IeMdbOpen (char *hostName, char *plcIP, int baseAddress)
+{
+  network_t net;
+  char *ipstr = plcIP;
+  _WORD dummy;
+
+  // use hostName reference in priority else plcIP
+  if (hostName) ipstr = hostName;
+
+  if (ipstr == NULL)
+  {
+    printf("#Error: ipstr NULL\n");
+	return(IE_PARAM_ERROR);
+  }
+
+  /* init network .........................................*/
+  /*net.name				= not used here*/
+  net.addr.naf 				= naf_tcp;
+  net.addr.addr.tcp.host	= ipstr;
+  net.addr.addr.tcp.service = "502";       //specific modbus
+  net.addr.addr.tcp.close_on_silence = 1;  // TRUE
+  net.timeout       		= d_to_timespec(MODBUS_TIMEOUT_DEF);
+  net.send_retries  		= MODBUS_SENDRETRIES_DEF;
+
+  /* connection ......................................*/
+  if ( (net.nd = mb_master_connect(net.addr)) >= 0)
+  {
+	  /*Try to access PLC memory, just to confirm modbus connection (for example,
+		read config. table address.
+	  */
+  	  if (read_bdata(
+					1,					/*int slave,*/
+					baseAddress/2,	    /*int start_addr (/2 is used to convert the byte alignment to 16bit alignment) */
+					sizeof(dummy),		/*int byte count,*/
+					(_BYTE *)&dummy,	/*uchar *dest,*/
+					net.nd,				/*int ttyfd,*/
+					net.send_retries,	/*int send_retries,*/
+					&net.timeout		/*const struct timespec *response_timeout*/
+				) >= 0)
+	  {
+    	/* node opened successfully! */
+		#ifdef DEBUG
+    	printf("Connecting to network %s: OK\n", net.addr.addr.tcp.host);
+		#endif
+
+		return (net.nd);
+	  }
+	  #ifdef DEBUG
+	  else
+	  {
+    	/* could not read registers from slave! */
+    	printf("#Error: could not establish connection to %s\n", net.addr.addr.tcp.host);
+	  }
+	  #endif
+
+  	  mb_master_close(net.nd);
+  }
+  #ifdef DEBUG
+  else
+  {
+    /* could not connect to slave! */
+    printf("#Error: could not establish connection to %s\n", net.addr.addr.tcp.host);
+  }
+  #endif
+
+  return(IE_CONNECT_ERROR);
+}
+
+/*----------------------------------------------------------*/
+int IeMBwriteData(int cid, _WORD dataOfs, _WORD dataSize, _BYTE* dataBuffer)
+{
+  int err;
+  network_t net;
+
+  /* init network .........................................*/
+  net.timeout       = d_to_timespec(MODBUS_TIMEOUT_DEF);
+  net.send_retries  = MODBUS_SENDRETRIES_DEF;
+
+  /*then SET&DATE cmd into command word*/
+  if (write_bdata(1,				/*int slave,*/
+				  dataOfs,			/*int start_addr (!16 bits alignment)*/
+				  dataSize,	        /*int byte count */
+				  dataBuffer,	    /*uchar *src */
+				  cid,	    		/*int connection id */
+				  net.send_retries,	/*int send_retries,*/
+				  &net.timeout		/*const struct timespec *response_timeout*/
+				  ) >= 0)
+  {
+	#ifdef DEBUG
+	printf("IeMBwriteData has been done successfully\n");
+	#endif
+	err = 0; /*no problem*/
+  }
+  else
+  {
+	#ifdef DEBUG
+	  printf("#Error on IeMBwriteData\n");
+	#endif
+	err = IE_EPIPE_ERROR;
+  }
+
+  return err;
+}
+
+/*----------------------------------------------------------*/
+int IeMBreadData(int cid, _WORD dataOfs, _WORD dataSize, _BYTE* dataBuffer)
+{
+  int err;
+  network_t net;
+
+  /* init network .........................................*/
+  net.timeout       = d_to_timespec(MODBUS_TIMEOUT_DEF);
+  net.send_retries  = MODBUS_SENDRETRIES_DEF;
+
+  /*unusefull to read empty data buffer*/
+  if (dataSize > 0)
+  {
+	 err = read_bdata(1,				/*int slave,*/
+					  dataOfs,			/*int start_addr (!16 bits alignment)*/
+					  dataSize,	        /*int byte count */
+					  dataBuffer,	    /*uchar *src */
+					  cid,	    		/*int connection id */
+				      net.send_retries,	/*int send_retries,*/
+				      &net.timeout		/*const struct timespec *response_timeout*/
+				      );
+  }
+
+  if ((dataSize == 0) || (err >= 0))
+  {
+	#ifdef DEBUG
+	printf("IeMBreadData has been done successfully\n");
+	#endif
+	err = 0; /*no problem*/
+  }
+  else
+  {
+	#ifdef DEBUG
+	  printf("#Error on IeMBreadData\n");
+	#endif
+	err = IE_EPIPE_ERROR;
+  }
+
+  return err;
+}
+
+/*----------------------------------------------------------*/
+/* This function closes the synchronous OSI-ON-TCP socket
+ * channel.
+ * 'sk': socket descriptor (in) - MUST BE a synch. pipe
+ * return 0 or <0 on error (see constant error)
+ *
+ * Details:
+ */
+int IeMdbClose(int cid)
+{
+  int err = 0;
+
+  err |= mb_master_close(cid);
+
+  if (err != 0) err = IE_DISCONNECT_ERROR;
+  return(err);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.h
new file mode 100644
index 0000000000000000000000000000000000000000..8a055c727d0b3eb87ff1f8bd142658c962c8f2bc
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/iemdb.h
@@ -0,0 +1,156 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+/*
+ * Revision : v1.0
+ * Date     : 08/2003 - F.Locci
+ * Objet    : original version for PS7-SCHNEIDER PLC
+ * Action   : 
+ *
+ * Revision : v1.5
+ * Date     : 01/2007 - F.Locci
+ * Objet    : implement BLOCK mode
+ * Action   : Add IeMdbGetBlock() and IeMdbSetBlock() function 
+ *            Look at v1.5 comments
+ *
+ */
+
+#ifndef _IEMDB_H_
+#define _IEMDB_H_
+
+/*
+ * This library was developped to provide communication between 
+ * Linux/LynxOS active host (client) and a PLC passive server. 
+ * Based on MODBUS std. protocole, it defines generic
+ * set and get functions to read and write data into/from PLC 
+ * memory.
+  */
+
+/* ---------------------------------------------------------*/
+/* LOCAL CONSTANT DEFINITIONS                               */
+/* ---------------------------------------------------------*/
+
+/* ---------------------------------------------------------*/
+/* TYPE DEFINITIONS                                         */
+/* ---------------------------------------------------------*/
+
+/* ---------------------------------------------------------*/
+/* PROTOTYPE DEFINITIONS                                    */
+/* ---------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*----------------------------------------------------------*/
+/* Time funtion
+ * IeMdbSetTime: Convert time_t epoch date to PLC SCHNEIDER
+ * format.
+ *
+ * Details:
+ * PLC SCHNEIER format is coded on 8 bytes BCD
+ * format:
+ *
+ *  0      1      2      3      4      5     6     7 
+ *  SC     --     HH     MN     MM     DD    YY	   YY
+ *
+ *  byte 1 is used by gateway to synchronize time setting.
+ */
+void IeMdbSetTime(unsigned char *dt, time_t epoch);  // to PLC
+
+/*----------------------------------------------------------*/
+/* Time funtion
+ * IeMdbGetTime: Convert PLC SCHNEIDER format to lynxOS 
+ * time_t format.
+ *
+ * Details:
+ * PLC SCHNEIER format is coded on 8 bytes BCD
+ * format:
+ *
+ *  0      1        2      3      4      5     6     7 
+ *  SC     SC/100   HH     MN     MM     DD    YY	 YY
+ *
+ */
+double IeMdbGetTime(unsigned char *dt); // from PLC
+
+/*----------------------------------------------------------*/
+/* This function initializes the DSC-PLC communication.
+ * return 0 or <0 on error (see constant error)
+ *
+ * Details:
+ * Must be executed at first.
+ */
+int IeMdbInit (void);
+
+/*----------------------------------------------------------*/
+/* This function initializes the DSC-PLC communication.
+ * return 0 or <0 on error (see constant error)
+ *
+ * Details:
+ * Must be executed at end.
+ */
+int IeMdbExit (void);
+
+/*----------------------------------------------------------*/
+/* This function creates a synchronous OSI-ON-TCP socket 
+ * channel used for sending/receiving communication with PLC.
+ * 'hostName': Name of the host (in)
+ * 'plcIP': PLC ip address string (in)
+ * return socket descriptor or <0 on error (see const. error)
+ *
+ * Details:
+ * 'plcIP' parameter is necessary only when 'hostName' is NULL.
+ * Only one synchronous channel per PLC at the same time 
+ * supported in that version.
+ */
+int IeMdbOpen (char *hostName, char *plcIP, int baseAddress);
+
+/*----------------------------------------------------------*/
+/* This function send a data segment to the PLC using the
+ * MODBUS protocole.
+ * 'cid': write channel id of the MB connection
+ * 'dataOfs': target adress of the data segment within the PLC memory
+ * 'dataSize': byte size of the data segment to be sent
+ * 'dataBuffer': buffer of the data to be sent
+ * return 0 or <0 on error (see constant error)
+ */
+int IeMBwriteData(int cid, _WORD dataOfs, _WORD dataSize, _BYTE* dataBuffer);
+
+/*----------------------------------------------------------*/
+/* This function read a data segment from the PLC using the
+ * MODBUS protocole.
+ * 'cid': read channel id of the MB connection
+ * 'dataOfs': adress of the data segment within the PLC memory
+ * 'dataSize': byte size of the data segment to be read
+ * 'dataBuffer': buffer to store the data
+ * return 0 or <0 on error (see constant error)
+ */
+int IeMBreadData(int cid, _WORD dataOfs, _WORD dataSize, _BYTE* dataBuffer);
+
+/*----------------------------------------------------------*/
+/* This function closes the synchronous OSI-ON-TCP socket 
+ * channel.
+ * 'cid1': connection id (in) - MUST BE a synch. pipe
+ * return 0 or <0 on error (see constant error)
+ *
+ * Details:
+ */
+int IeMdbClose(int cid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IEMDB_H_ */
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_addr.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_addr.h
new file mode 100644
index 0000000000000000000000000000000000000000..353639638d859a159680a1a6dcdc310c448b9dec
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_addr.h
@@ -0,0 +1,111 @@
+/*
+ * (c) 2002 Mario de Sousa
+ *
+ * Offered to the public under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ */
+
+
+#ifndef MODBUS_LAYER2_H
+#define MODBUS_LAYER2_H
+
+/*F.Locci #include <plc.h>*/  /* get the plc data types */
+#include <time.h> /* struct timespec data type */
+
+/*F.Locci - 28/10/2003*/
+/*types only defined with linux version: <asm/types.h>*/
+#ifndef __Lynx__
+#include <asm/types.h>
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+
+#else
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+
+#ifndef __ppc4__ /*new <socket.h> with ppc4 environment*/
+/*F.Locci - 03/11/2004, add x86 platform support*/
+#ifndef __x86__
+typedef unsigned short int sa_family_t;
+
+/* The following constants should be used for the second parameter of
+   `shutdown'.  */
+enum
+{
+  SHUT_RD = 0,		/* No more receptions.  */
+#define SHUT_RD		SHUT_RD
+  SHUT_WR,		/* No more transmissions.  */
+#define SHUT_WR		SHUT_WR
+  SHUT_RDWR		/* No more receptions or transmissions.  */
+#define SHUT_RDWR	SHUT_RDWR
+};
+#endif
+#endif
+
+/*constant conversion for LynxOS*/
+#define AF_ROSE 11
+#define AF_X25  9
+#define AF_AX25 3
+#define SOL_TCP 6
+#define SOL_IP  0
+#endif
+
+typedef enum {optimize_speed, optimize_size} optimization_t;
+
+
+typedef enum {
+        naf_ascii,
+        naf_rtu,
+        naf_tcp,
+  } node_addr_family_t;
+
+typedef struct {
+        const char *host;
+        const char *service;
+        int         close_on_silence;  
+  } node_addr_tcp_t;
+
+typedef struct {
+        const char *device;
+        int         baud;       /* plain baud rate, eg 2400; zero for the default 9600 */
+        int         parity;     /* 0 for none, 1 for odd, 2 for even                   */
+        int         data_bits;
+        int         stop_bits;
+        int         ignore_echo; /* 1 => ignore echo; 0 => do not ignore echo */
+  } node_addr_rtu_t;
+
+typedef node_addr_rtu_t node_addr_ascii_t;
+
+typedef union {
+        node_addr_ascii_t ascii;
+        node_addr_rtu_t   rtu;
+        node_addr_tcp_t   tcp;
+  } node_addr_common_t;
+
+typedef struct {
+        node_addr_family_t  naf;
+        node_addr_common_t  addr;
+  } node_addr_t;
+
+#endif  /* MODBUS_LAYER2_H */
+
+
+
+
+
+
+
+
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_layer1.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_layer1.h
new file mode 100644
index 0000000000000000000000000000000000000000..9a335086ee36b44c6dc794a06c0608d095d66722
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_layer1.h
@@ -0,0 +1,127 @@
+/*
+ * (c) 2001 Mario de Sousa
+ *
+ * Offered to the public under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ *
+ * Revision : v1.0
+ * Date     : 11/2004 - F.Locci
+ * Objet    : move global recv_buf_ to local one into read/write_bdata()
+ *            to make module reentrant.
+ *            Look at v1.0 comment
+ */
+
+
+#ifndef MODBUS_LAYER1_H
+#define MODBUS_LAYER1_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*F.Locci #include <plc.h>*/  /* get the plc data types */
+#include <time.h> /* struct timespec data type */
+
+#include "mb_addr.h" /* get definitions of common variable types */
+
+
+ /* write a modbus frame */
+ /* WARNING: when calling this functio, the *frame_data buffer
+  *          must be allocated with an extra *extra_bytes
+  *          beyond those required for the frame_length.
+  *          This is because the extra bytes will be used
+  *          to store the crc before sending the frame.
+  *
+  *          The *extra_bytes value will be returned by the
+  *          modbus_init() function call.
+  */
+ /* NOTE: calling this function will flush the input stream,
+  *       which means any frames that may have arrived
+  *       but have not yet been read using modbus_read()
+  *       will be permanently lost...
+  */
+int modbus_write(int    nd,
+                 u8    *frame_data,
+                 size_t frame_length,
+                 u16    transaction_id);
+
+ /* read a modbus frame */
+ /* NOTE: calling modbus_write() will flush the input stream,
+  *       which means any frames that may have arrived
+  *       but have not yet been read using modbus_read()
+  *       will be permanently lost...
+  *
+  * NOTE: Ususal select semantics for (a: recv_timeout == NULL) and
+  *       (b: *recv_timeout == 0) also apply.
+  *
+  *       (a) Indefinite timeout
+  *       (b) Try once, and and quit if no data available.
+  */
+int modbus_read(int *nd,                /* node descriptor */
+                u8 *recv_data_ptr/*v1.0*/,
+                u16 *transaction_id,
+                u8 *send_data,         /* ignored ! */
+                int send_length,       /* ignored ! */
+                const struct timespec *recv_timeout);
+
+
+ /* init the library */
+int modbus_init(int nd_count,        /* maximum number of nodes... */
+                optimization_t opt,
+                int *extra_bytes);
+
+ /* shutdown the library...*/
+int modbus_done(void);
+
+
+/* Open a node for master / slave operation.
+ * Returns the node descriptor, or -1 on error.
+ */
+int modbus_connect(node_addr_t node_addr);
+int modbus_listen(node_addr_t node_addr);
+
+/* Close a node, needs a node descriptor as argument... */
+int modbus_close(int nd);
+
+/* Tell the library that the user will probably not be communicating
+ * for some time...
+ * This will allow the library to release any resources it will not
+ * be needing during the silence.
+ * NOTE: This is onlyused by the TCP version to close down tcp connections
+ *       when the silence will going to be longer than  second.
+ */
+int modbus_silence_init(void);
+
+ /* determine the minmum acceptable timeout... */
+ /* NOTE: timeout values passed to modbus_read() lower than the value returned
+  *       by this function may result in frames being aborted midway, since they
+  *       take at least modbus_get_min_timeout() seconds to transmit.
+  */
+double modbus_get_min_timeout(int baud,
+                              int parity,
+                              int data_bits,
+                              int stop_bits);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* MODBUS_LAYER1_H */
+
+
+
+
+
+
+
+
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master.cpp b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e4436018cebf12f1ccd478f9aef63cfc5a3e501b
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master.cpp
@@ -0,0 +1,483 @@
+/* mb_master.c
+
+   By P.Costigan email: phil@pcscada.com.au http://pcscada.com.au
+
+   These library of functions are designed to enable a program send and
+   receive data from a device that communicates using the Modbus protocol.
+
+   Copyright (C) 2000 Philip Costigan  P.C. SCADA LINK PTY. LTD.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+   The functions included here have been derived from the
+   Modicon Modbus Protocol Reference Guide
+   which can be obtained from Schneider at www.schneiderautomation.com.
+
+   This code has its origins with
+   paul@pmcrae.freeserve.co.uk (http://www.pmcrae.freeserve.co.uk)
+   who wrote a small program to read 100 registers from a modbus slave.
+
+   I have used his code as a catalist to produce this more functional set
+   of functions. Thanks paul.
+
+
+
+   10/2001 - Mario de Sousa
+		Slightly re-organized the code.
+                Miscelaneous cleanups
+                Removed layer1 functions (i.e. write and read to /dev/ttySx)
+                Added support for transaction id
+
+                TODO
+                add retries at layer2 (i.e. in this file)
+                check response frame for correctness
+*
+*
+* Revision : v1.0
+* Date     : 11/2004 - F.Locci
+* Objet    : .remove static prefix into modbus_tcp_write() declaration 
+*            to make code reentrant.
+*           .move global recv_buf_ to local one into read/write_bdata()
+*            Look at v1.0 comments
+*
+* Revision : v2.0
+* Date     : 11/2006 - F.Locci
+* Objet    : swap16 bits from SILECS client instead of application level
+*            Look at v2.0 comments
+*/
+
+#include <fcntl.h>	/* File control definitions */
+#include <stdio.h>	/* Standard input/output */
+#include <string.h>
+#include <stdlib.h>
+#include <termio.h>	/* POSIX terminal control definitions */
+#include <time.h>	/* Time structures for select() */
+#include <unistd.h>	/* POSIX Symbolic Constants */
+#include <errno.h>	/* Error definitions */
+
+#include <netinet/in.h> /* required for htons() and ntohs() */
+#include "mb_layer1.h"
+#include "mb_master.h"
+#include "mb_master_private.h"
+/*v1.0*/
+#include "mb_tcp_private.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* #define DEBUG */		/* uncomment to see the data sent and received */
+
+
+#ifndef TRUE
+#define TRUE  1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+
+/******************************************/
+/******************************************/
+/**                                      **/
+/**         Global Variables...          **/
+/**                                      **/
+/******************************************/
+/******************************************/
+
+/*v1.0
+static u8 *query_buffer_ = NULL;
+*/
+#ifndef __Lynx__ 
+#if RECV_BUFFER_SIZE < 5 //TCP_HEADER_LENGTH
+#error The receive buffer is smaller than the frame header length.
+#endif
+#endif
+/**/
+
+/******************************************/
+/******************************************/
+/**                                      **/
+/**       Local Utility functions...     **/
+/**                                      **/
+/******************************************/
+/******************************************/
+
+
+/*
+ * Function to determine next transaction id.
+ *
+ * We use a library wide transaction id, which means that we
+ * use a new transaction id no matter what slave to which we will
+ * be sending the request...
+ */
+static inline u16 next_transaction_id(void) {
+
+  static u16 next_id = 0;
+
+  return next_id++;
+}
+
+
+/*
+ * Functions to convert u16 variables
+ * between network and host byte order
+ *
+ * NOTE: Modbus uses MSByte first, just like
+ *       tcp/ip, so we use the htons() and
+ *       ntoh() functions to guarantee
+ *       code portability.
+ */
+
+static inline u16 mb_hton(u16 h_value) {
+/*  return h_value; */
+  return htons(h_value);
+}
+
+static inline u16 mb_ntoh(u16 m_value) {
+/*  return m_value; */
+  return ntohs(m_value);
+}
+
+
+
+static inline u8 msb(u16 value) {
+/*  return Most Significant Byte of value; */
+  return (value >> 8) & 0xFF;
+}
+
+static inline u8 lsb(u16 value) {
+/*  return Least Significant Byte of value; */
+  return value & 0xFF;
+}
+
+#define u16_v(char_ptr)  (*((u16 *)(&(char_ptr))))
+
+
+/***********************************************************************
+
+	The following functions construct the required query into
+	a modbus query packet.
+
+***********************************************************************/
+
+static inline int build_query_packet(u8  slave,
+                                     u8  function,
+                                     u16 start_addr,
+                                     u16 count,
+                                     u8 *packet)
+{
+        packet[ 0 ] = slave,
+        packet[ 1 ] = function;
+          /* NOTE:
+           *  Modbus uses high level addressing starting off from 1, but
+           *  this is sent as 0 on the wire!
+           */
+        u16_v(packet[2]) = mb_hton(start_addr - 1);
+        u16_v(packet[4]) = mb_hton(count);
+
+        return 6;
+}
+
+
+/************************************************************************
+
+	read_bdata
+
+    F.Locci: just read raw byte array. Take care of frame which exceeds 
+    modbus frame std. length.
+
+*************************************************************************/
+/*v2.0*/
+#define swap16(w) ((((unsigned short)w & 0x00ff)<<8)+(((unsigned short)w & 0xff00)>>8))
+
+int read_bdata(int slave,    /* slave id */
+             int start_addr, /* word pointer addr. */
+             int count,      /* byte count to read */
+             u8 *dest,       /* byte array */
+             int ttyfd,      /* connection id */
+             int send_retries, /* number of request retries */
+             const struct timespec *response_timeout) /* timeout value */
+{
+	/*v1.0*/
+    u8 data[RECV_BUFFER_SIZE];
+	u8 packet[QUERY_BUFFER_SIZE];
+	/**/
+	int rl, response_length=0;
+    int query_length;
+    u16 send_transaction_id, recv_transaction_id;
+	u8  *destp  = dest;
+	int global_length, length;            /* word count for read     */
+
+    /*Attention! ModBus travaille sur une zone memoire [1..n] tandis que l'espace memoire
+	  du PLC est definie [0..n-1] => start_addr = start_addr +1
+	  start_addr est exprime en word pour le PLC (alignement 16bits).
+	*/
+	start_addr+=1;
+
+
+	/*'global_length' is a word counter*/
+	global_length = (count/2) + (count%2);
+		  
+    while(count) {
+
+		if (count > MAX_READ_BDATA)
+		   /*'length' is a word counter*/
+		   length = MAX_READ_BDATA/2;
+		else
+		  /*'length' is a word counter*/
+		  length = (count/2) + (count%2);
+		  
+        /* We must also initialize the recv_transaction_id with the same value,
+         * since some layer 1 protocols do not support transaction id's, so
+         * simply return the recv_transaction_id variable without any changes...
+         */
+        send_transaction_id = recv_transaction_id = next_transaction_id();
+
+        query_length = build_query_packet(slave, 0x03, /*function*/
+                                          start_addr, length,
+                                          packet);
+        if (query_length < 0)
+          return -1;
+
+		if (modbus_write(ttyfd, packet, query_length, send_transaction_id) < 0 )
+        	  return PORT_FAILURE;
+
+		rl = modbus_read(&ttyfd, data/*v1.0*/, &recv_transaction_id,
+                         packet, query_length,
+                         response_timeout);
+
+		if( rl <= 0 )  return PORT_FAILURE;
+
+        /* first check whther we have correct transaction id */
+        if (send_transaction_id != recv_transaction_id)
+          return PORT_FAILURE;
+
+        if( rl > 0 )  
+		{ rl -= 3; /*F.Locci, bug: 2->3*/
+		  if (count<MAX_READ_BDATA)
+		    rl -= (count%2);
+		}
+
+        if( rl > 0 ) {
+		   memcpy(destp, (u8 *)&(data[3]), rl);
+		   destp += rl;
+		   start_addr += length; /*F.Locci, bug if rl = 0 */
+		}
+		
+		/* start_addr += length;  F.Locci, bug if rl = 0 */
+		response_length += rl;
+		count -= rl;
+	}
+
+	/*v2.0:
+	  Independamment de son mapping memoire (Little-endian), le PLC SCHNEIDER
+	  swap chaque mot de 16bits qu'il transmet. Cette ligne permet de redresser
+	  les donnees pour transmettre l'image exacte du mapping memoire. Charge 
+	  a l'application ensuite d'appliquer le swapping necessaire relatif a son 
+	  "Endianness".
+	*/
+	{
+	int j;
+	u16 *wdestp = (u16 *)dest; /* for swapping 16bit  */
+	for(j=0; j<global_length; j++){ wdestp[j] = swap16(wdestp[j]); }
+	}
+	/**/
+
+    #ifdef DEBUG
+    { int i;
+	printf("read_bdata: ");
+	for(i=0; i<response_length; printf("%02x ", dest[i++]));
+	printf("\n");
+	}
+	#endif
+	
+	return response_length;
+}
+
+/*************************************************************************
+
+	write_bdata
+
+    F.Locci: just write raw byte array. Take care of frame which exceeds 
+    modbus frame std. length.
+	!!byte count MUST be even value - 16 bits alignment in that PLC
+
+***************************************************************************/
+
+int write_bdata(int slave,   /* slave id */
+             int start_addr, /* word pointer addr.  */
+             int count,      /* byte count to write - MUST be even value */
+             u8 *data,       /* byte array */
+             int ttyfd,      /* connection id */
+             int send_retries, /* number of request retries */
+             const struct timespec *response_timeout) /* timeout value */
+{
+	int byte_count;
+	int i, rl, response_length=0;
+    int query_length;
+	/*v1.0*/
+    u8 rdata[RECV_BUFFER_SIZE];
+	u8 packet[QUERY_BUFFER_SIZE];
+    u16 send_transaction_id, recv_transaction_id;
+	int length;        /* word count */
+	u8 *destp, *srcp = data;
+
+    /*Attention! ModBus travaille sur une zone memoire [1..n] tandis que l'espace memoire
+	  du PLC est definie [0..n-1] => start_addr = start_addr +1
+	  start_addr est exprime en word pour le PLC (alignement 16bits).
+	*/
+	start_addr+=1;
+	
+    while(count) {
+
+		if (count > MAX_WRITE_BDATA) 
+		{
+		   /*'length' is a word counter*/
+		   length = MAX_WRITE_BDATA/2;
+		}
+		else
+		{
+		  /*'length' is a word counter*/
+		  length = (count/2) + (count%2);
+		}
+
+        /* We must also initialize the recv_transaction_id with the same value,
+         * since some layer 1 protocols do not support transaction id's, so
+         * simply return the recv_transaction_id variable without any changes...
+         */
+        send_transaction_id = recv_transaction_id = next_transaction_id();
+
+        query_length = build_query_packet(slave, 0x10 /* function */,
+                                          start_addr, length,
+                                          packet);
+        if (query_length < 0)
+          return -1;
+
+		byte_count = (length * 2);
+		packet[ query_length ] = byte_count;
+
+        destp = &(packet[ ++query_length ]);
+		memcpy(destp, srcp, byte_count-(count%2));
+		
+		/*v2.0:
+		  Independamment de son mapping memoire (Little-endian), le PLC SCHNEIDER
+		  swap chaque mot de 16bits qu'il transmet. Cette ligne permet de redresser
+		  les donnees pour transmettre l'image exacte du mapping memoire. Charge 
+		  a l'application ensuite d'appliquer le swapping necessaire relatif a son 
+		  "Endianness".
+		*/
+		{
+		u16 *wdestp = (u16 *)destp;
+		for(i=0; i<length; i++){ wdestp[i] = swap16(wdestp[i]); }
+		}
+		/**/
+
+		srcp += byte_count-(count%2);
+		query_length += byte_count;
+
+		if( modbus_write( ttyfd, packet, query_length, send_transaction_id) < 0 )
+		  return PORT_FAILURE;
+
+		rl = modbus_read(&ttyfd, rdata/*v1.0*/, &recv_transaction_id,
+                         packet, query_length, response_timeout);
+
+        if( rl <= 0 ) return PORT_FAILURE;
+
+        /* first check whther we have correct transaction id */
+        if (send_transaction_id != recv_transaction_id)
+          return PORT_FAILURE;
+		  
+		start_addr += length;
+		response_length += byte_count;
+		count -= (byte_count - (count%2));
+    }
+
+    return response_length;
+}
+
+/************************************************************************
+
+	initialise / shutdown the library
+
+	These functions sets up/shut down the library state
+        (allocate memory for buffers, initialise data strcutures, etc)
+
+**************************************************************************/
+
+int mb_master_init(int nd_count) {
+        int extra_bytes;
+
+#ifdef DEBUG
+	fprintf( stderr, "mb_master_init()\n");
+	fprintf( stderr, "creating %d nodes\n", nd_count);
+#endif
+
+            /* initialise layer 1 library */
+        if (modbus_init(nd_count, DEF_OPTIMIZATION, &extra_bytes)
+            < 0)
+          goto error_exit_0;
+
+        /*v1.0 initialise send buffer
+        query_buffer_ = (u8 *)malloc(QUERY_BUFFER_SIZE + extra_bytes);
+        if (query_buffer_ == NULL)
+          goto error_exit_1;
+		*/  
+
+        return 0;
+
+error_exit_0:
+        return -1;
+}
+
+
+int mb_master_done(void) {
+/*v1.0
+        free(query_buffer_);
+        query_buffer_ = NULL;
+*/
+        return modbus_done();
+}
+
+/************************************************************************
+
+	open/close master connection
+
+	This function opens/closes a connection to the remote slave.
+
+**************************************************************************/
+
+int mb_master_connect(node_addr_t node_addr) {
+#ifdef DEBUG
+	fprintf( stderr, "mb_master_connect()\n");
+#endif
+          /* call layer 1 library */
+        return modbus_connect(node_addr);
+}
+
+
+int mb_master_close(int nd) {
+#ifdef DEBUG
+	fprintf( stderr, "mb_master_close(): nd = %d\n", nd);
+#endif
+          /* call layer 1 library */
+        return modbus_close(nd);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master.h
new file mode 100644
index 0000000000000000000000000000000000000000..774598539ed57421c7a5f035cd0ac7350cd8eee1
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master.h
@@ -0,0 +1,157 @@
+/* 		modbus_rtu.h
+
+   By P.Costigan email: phil@pcscada.com.au http://pcscada.com.au
+
+   These library of functions are designed to enable a program send and
+   receive data from a device that communicates using the Modbus protocol.
+
+   Copyright (C) 2000 Philip Costigan  P.C. SCADA LINK PTY. LTD.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+
+
+   The functions included here have been derived from the
+   Modicon Modbus Protocol Reference Guide
+   which can be obtained from Schneider at www.schneiderautomation.com.
+
+   This code has its origins with
+   paul@pmcrae.freeserve.co.uk (http://www.pmcrae.freeserve.co.uk)
+   who wrote a small program to read 100 registers from a modbus slave.
+
+   I have used his code as a catalist to produce this more functional set
+   of functions. Thanks paul.
+
+
+ */
+
+
+#ifndef MODBUS_MASTER_H
+#define MODBUS_MASTER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*F.Locci #include <plc.h>*/  /* get the plc data types */
+#include <time.h> /* struct timespec data structure */
+
+#include "mb_addr.h"  /* get definition of common variable types */
+
+
+
+/***********************************************************************
+
+	 Note: All functions used for sending or receiving data via
+	       modbus return these return values.
+
+
+	Returns:	string_length if OK
+			0 if failed
+			Less than 0 for exception errors
+
+***********************************************************************/
+
+
+/*F.Locci: error constants adjustement to be SILECS conformed
+#define COMMS_FAILURE 0
+#define ILLEGAL_FUNCTION -1
+#define ILLEGAL_DATA_ADDRESS -2
+#define ILLEGAL_DATA_VALUE -3
+#define SLAVE_DEVICE_FAILURE -4
+#define ACKNOWLEDGE -5
+#define SLAVE_DEVICE_BUSY -6
+#define NEGATIVE_ACKNOWLEDGE -7
+#define MEMORY_PARITY_ERROR -8
+
+#define PORT_FAILURE -11
+*/
+#define PORT_FAILURE -3
+
+
+/************************************************************************
+
+	read_bdata
+
+    F.Locci: just read raw byte array. Take care of frame longer than 
+	125 words.
+
+*************************************************************************/
+
+#define MAX_READ_BDATA  200
+
+int read_bdata(int slave,    /* slave id */
+             int start_addr, /* word pointer addr. */
+             int count,      /* byte count to read */
+             u8 *dest,       /* byte array */
+             int ttyfd,      /* connection id */
+             int send_retries, /* number of request retries */
+             const struct timespec *response_timeout); /* timeout value */
+
+
+/*************************************************************************
+
+	write_bdata
+
+    F.Locci: just write raw byte array. Take care of frame which exceeds 
+    modbus frame std. length.
+	!!byte count MUST be even value - 16 bits alignment in that PLC
+
+***************************************************************************/
+
+#define MAX_WRITE_BDATA  200
+
+int write_bdata(int slave,   /* slave id */
+             int start_addr, /* word pointer addr.  */
+             int count,      /* byte count to write - MUST be even value */
+             u8 *data,       /* byte array */
+             int ttyfd,      /* connection id */
+             int send_retries, /* number of request retries */
+             const struct timespec *response_timeout); /* timeout value */
+
+
+/************************************************************************
+
+	initialise
+
+	This function sets up the libraries
+        (allocate memory for buffers, initialise data strcutures, etc)
+
+**************************************************************************/
+int mb_master_init(int nd_count);
+
+int mb_master_done(void);
+
+
+/***************************************************************************
+
+	set_up_comms
+
+	This function sets up (closes) a connection to a remote modbus
+	slave.
+
+
+***************************************************************************/
+int mb_master_connect(node_addr_t node_addr);
+
+int mb_master_close(int nd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* MODBUS_MASTER_H */
+
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master_private.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master_private.h
new file mode 100644
index 0000000000000000000000000000000000000000..5f9d4b7f63fa40160e90ad9597ab0fbddf8c6366
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_master_private.h
@@ -0,0 +1,43 @@
+/*
+ * (c) 2002 Mario de Sousa
+ *
+ * Offered to the public under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ */
+
+
+#ifndef MODBUS_MASTER_PRIVATE_H
+#define MODBUS_MASTER_PRIVATE_H
+
+/*F.Locci #include <plc.h>*/  /* get the plc data types */
+#include "mb_util.h"
+#include "mb_master.h"
+
+
+#define QUERY_BUFFER_SIZE       MAX_L2_FRAME_LENGTH
+
+#define DEF_LAYER2_SEND_RETRIES 1
+
+#define DEF_IGNORE_ECHO         0
+
+#define DEF_OPTIMIZATION        optimize_speed
+
+
+#endif  /* MODBUS_MASTER_PRIVATE_H */
+
+
+
+
+
+
+
+
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_tcp.cpp b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_tcp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f918409981c6121c59e24e1c930489b3b755c63d
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_tcp.cpp
@@ -0,0 +1,1407 @@
+/*
+ * (c) 2002 Mario de Sousa
+ *
+ * Offered to the public under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ *
+ *
+ * Revision : v1.0
+ * Date     : 11/2004 - F.Locci
+ * Objet    : .remove static prefix into modbus_tcp_write() declaration 
+ *            to make code reentrant.
+ *            .move global recv_buf_ to local one into read/write_bdata()
+ *            Look at v1.0 comments
+ *
+ * Revision : v1.1
+ * Date     : 12/2006 - F.Locci
+ * Objet    : .modify code (pointing things) to be Lces platform compatible      
+ *            Look at v1.1 comments
+ */
+
+
+/* TODO:
+ *       - clean up the code (access to nw_array_, etc...)
+ *       - closing sockets that will be idle for more than 1 second...
+ */
+
+
+#include <fcntl.h>      /* File control definitions */
+#include <stdio.h>      /* Standard input/output */
+#include <string.h>
+#include <stdlib.h>
+#include <termio.h>     /* POSIX terminal control definitions */
+#include <unistd.h>     /* POSIX Symbolic Constants */
+#include <assert.h>
+#include <errno.h>      /* Error definitions */
+#include <time.h>       /* clock_gettime()   */
+#include <sys/types.h>
+#ifdef __Lynx__
+#include <bsd/in_systm.h>
+#include <uio.h>
+#endif
+#include <sys/socket.h>
+#include <netinet/in.h>  /* required for htons() and ntohs() */
+#include <netinet/tcp.h> /* TCP level socket options */
+#include <netinet/ip.h>  /* IP  level socket options */
+
+/*F.Locci, 
+#include <plc.h>
+#include <misc/sin_util.h>
+*/
+#include <silecs-communication/protocol/core/ietype.h>
+
+#include "sin_util.h"
+/*F.Locci end*/
+
+#include "mb_layer1.h"  /* The public interface this file implements... */
+#include "mb_tcp_private.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* #define DEBUG */       /* uncomment to see the data sent and received */
+
+
+#define modbus_tcp_write           modbus_write
+#define modbus_tcp_read            modbus_read
+#define modbus_tcp_init            modbus_init
+#define modbus_tcp_done            modbus_done
+#define modbus_tcp_connect         modbus_connect
+#define modbus_tcp_listen          modbus_listen
+#define modbus_tcp_close           modbus_close
+#define modbus_tcp_silence_init    modbus_silence_init
+#define modbus_tcp_get_min_timeout modbus_get_min_timeout
+
+
+
+
+/************************************/
+/**                                **/
+/** Include common code...         **/
+/**                                **/
+/************************************/
+
+#include "mb_time_util.h"
+
+
+
+
+/**************************************************************/
+/**************************************************************/
+/****                                                      ****/
+/****                                                      ****/
+/****                Forward Declarations                  ****/
+/****                    and Defaults                      ****/
+/****                                                      ****/
+/**************************************************************/
+/**************************************************************/
+
+
+  /* A Node Descriptor metadata,
+   *   Due to the fact that modbus TCP is connection oriented,
+   *   and that if the client detects an error the connection
+   *   must be shut down and re-established automatically,
+   *   the modbus TCP layer needs to keep the address of the remote server.
+   *
+   * We do this by implementing a node descriptor table, in which each
+   *   entry will have the remote address, and the file descriptor
+   *   of the socket currently in use.
+   *
+   * We do not pass the file descriptor up to the next higher layer. We
+   *   send them the node descriptor instead...
+   */
+#define MB_MASTER_NODE AF_INET  /* This MUST be set to AF_INET !! */
+#define MB_LISTEN_NODE AF_AX25  /* actually any value will do, as long as it is != AF_INET */
+#define MB_SLAVE_NODE  AF_X25   /* actually any value will do, as long as it is != AF_INET */
+#define MB_FREE_NODE   AF_ROSE  /* actually any value will do, as long as it is != AF_INET */
+typedef sa_family_t nd_type_t;
+
+typedef struct {
+    int    fd;                 /* socket descriptor == file descriptor */
+                               /* NOTE:
+                                *   Modbus TCP says that on error, we should close
+                                *   a connection and retry with a new connection.
+                                *   Since it takes time for a socket to close
+                                *   a connection if the remote server is down,
+                                *   we close the connection on the socket, close the
+                                *   socket itself, and create a new one for the new
+                                *   connection. There will be times when the node will
+                                *   not have any valid socket, and it will have to
+                                *   be created on the fly.
+                                *   When the node does not have a valid socket,
+                                *   fd will be set to -1
+                                */
+    struct sockaddr_in addr;   /* NOTE:
+                                *   We re-use the addr.sin_family member to define the
+                                *   state of the node descriptor.
+                                *   If addr.sin_family == MB_MASTER_NODE
+                                *      The node descriptor was initialised by the
+                                *      modbus_connect() function.
+                                *      The node descriptor is being used by a master
+                                *      device, and the addr contains the address of the slave.
+                                *      Remember that in this case fd may be >= 0 while
+                                *      we have a valid connection, or it may be < 0 when
+                                *      the connection needs to be reset.
+                                *   If addr.sin_family == MB_LISTEN_NODE
+                                *      The node descriptor was initialised by the
+                                *      modbus_listen() function.
+                                *      The node is merely used to accept() new connection
+                                *      requests. The new slave connections will use another
+                                *      node to transfer data.
+                                *      In this case fd must be >= 0.
+                                *      fd < 0 is an ilegal state and should never occur.
+                                *   If addr.sin_family == MB_SLAVE_NODE
+                                *      The node descriptor was initialised when a new
+                                *      connection request arrived on a MB_LISTEN type node.
+                                *      The node descriptor is being used by a slave device,
+                                *      and is currently being used to connect to a master.
+                                *      In this case fd must be >= 0.
+                                *      fd < 0 is an ilegal state and should never occur.
+                                *   If addr.sin_family == FREE_ND
+                                *      The node descriptor is currently not being used.
+                                *      In this case fd is set to -1, but is really irrelevant.
+                                */
+    int close_on_silence;      /* A flag used only by Master Nodes.
+                                * When (close_on_silence > 0), then the connection to the
+                                * slave device will be shut down whenever the
+                                * modbus_tcp_silence_init() function is called.
+                                * Remember that the connection will be automatically
+                                * re-established the next time the user wishes to communicate
+                                * with the same slave (using this same node descripto).
+                                * If the user wishes to comply with the sugestion
+                                * in the OpenModbus Spec, (s)he should set this flag
+                                * if a silence interval longer than 1 second is expected.
+                                */
+} nd_entry_t;
+
+
+static void nd_entry_init(nd_entry_t *nde) {
+  nde->addr.sin_family = MB_FREE_NODE;
+  nde->fd = -1; /* not currently connected... */
+}
+
+
+
+
+typedef struct {
+      /* the array of node descriptors, and current size... */
+    nd_entry_t *node;
+    int        node_count;      /* total number of nodes in the node[] array */
+    int        free_node_count; /*  number of free nodes in the node[] array */
+      /* fd set with all the fd in the node array already set
+       * This saves time in not having to re-initialize a fd_set every time
+       * the modbus_read() function is called...
+       */
+    fd_set     all_fds;
+      /* the highest fd in the fds set... This is used for the select() call */
+    int        all_fd_high;
+      /* fd set with all the fd belonging to MB_MASTER_NODE and MB_SLAVE_NODE
+       * type nodes already set.
+       * This saves time in not having to re-initialize a fd_set every time
+       * the modbus_read() function is called...
+       */
+    fd_set     ms_fds;
+      /* the highest fd in the fds set... This is used for the select() call */
+    int        ms_fd_high;
+} nd_table_t;
+
+
+/*F.Locci, add connection timeout - look at <rfcsock.c> file*/
+extern int connect_nonb(int sockfd, struct sockaddr *saptr, socklen_t salen, int nsec);
+
+
+static int nd_table_init(nd_table_t *ndt, int nd_count) {
+  int count;
+
+  /* initialise the node table with default values... */
+  ndt->node  = NULL;
+  ndt->node_count = 0;
+  ndt->free_node_count = 0;
+  FD_ZERO(&(ndt->all_fds));
+  ndt->all_fd_high = -1;
+  FD_ZERO(&(ndt->ms_fds));
+  ndt->ms_fd_high  = -1;
+
+  /* initialise the node descriptor metadata array... */
+  ndt->node = (nd_entry_t*) malloc(sizeof(nd_entry_t) * nd_count);
+  if (ndt->node == NULL) {
+    /*F.Locci 
+	plc_log_errmsg(1, "Out of memory: error initializing node address buffer");
+	*/
+	printf("\nOut of memory: error initializing node address buffer\n");
+    return -1;
+  }
+  ndt->node_count = nd_count;
+  ndt->free_node_count = nd_count;
+
+    /* initialise the state of each node in the array... */
+  for (count = 0; count < nd_count; count++) {
+    nd_entry_init(&ndt->node[count]);
+  } /* for() */
+
+  return nd_count; /* number of succesfully created nodes! */
+}
+
+
+
+static int nd_table_get_free_node(nd_table_t *ndt, nd_type_t nd_type) {
+  int count;
+
+  /* check for free nodes... */
+  if (ndt->free_node_count <= 0)
+    /* no free nodes... */
+    return -1;
+
+  /* Decrement the free node counter...*/
+  ndt->free_node_count--;
+
+  /* search for a free node... */
+  for (count = 0; count < ndt->node_count; count++) {
+    if(ndt->node[count].addr.sin_family == MB_FREE_NODE) {
+      /* found one!! */
+      ndt->node[count].addr.sin_family = nd_type;
+      return count;
+    }
+  } /* for() */
+
+  /* Strange... We should have free nodes, but we didn't finda any! */
+  /* Let's try to get into a consistent state, and return an error! */
+  ndt->free_node_count = 0;
+  return -1;
+}
+
+
+
+static void nd_table_close_node(nd_table_t *ndt, int nd) {
+
+  if(ndt->node[nd].addr.sin_family == MB_FREE_NODE)
+    /* Node already free... */
+    return;
+
+  /* Increment the free node counter...*/
+  ndt->free_node_count++;
+  /* Mark the node as being free. */
+  ndt->node[nd].addr.sin_family = MB_FREE_NODE;
+
+  return;
+}
+
+
+
+/**************************************************************/
+/**************************************************************/
+/****                                                      ****/
+/****                                                      ****/
+/****                Global Library State                  ****/
+/****                                                      ****/
+/****                                                      ****/
+/**************************************************************/
+/**************************************************************/
+
+ /* The receive buffer... */
+ /* NOTE: The library supports multiple simultaneous connections,
+  *       but will only read a message from one at a time.
+  *       (i.e. once it starts receiving a message from one node, it
+  *       will read that message to the end, even though another message
+  *       may start arriving later on another node, but finish arriving
+  *       earlier than the first. The second message will be ignored until
+  *       the first has been completely received, or a timeout occurs...)
+  *       This means we can re-use the same buffer for all the nodes.
+  *       It doesn't seem to be worth the hassle and increased memory
+  *       use to implement it properly with one buffer per node...
+  v1.0
+static u8 *recv_buf_ = NULL;
+*/
+
+ /* The node descriptor table... */
+ /* NOTE: This variable is also used to check whether the library
+  *       has been previously initialised.
+  *       If == NULL, �> library not yet initialised...
+  */
+static nd_table_t *nd_table_ = NULL;
+
+
+
+/**************************************************************/
+/**************************************************************/
+/****                                                      ****/
+/****                                                      ****/
+/****              Local Utility functions...              ****/
+/****                                                      ****/
+/****                                                      ****/
+/**************************************************************/
+/**************************************************************/
+
+
+#define min(a,b) ((a<b)?a:b)
+#define max(a,b) ((a>b)?a:b)
+
+/************************************/
+/**                                **/
+/**  Configure socket for Modbus   **/
+/**                                **/
+/************************************/
+
+
+static int configure_socket(int socket_id) {
+
+  /* configure the socket */
+    /* set the TCP no delay flag. */
+  {int bool_opt = 1;
+  if (setsockopt(socket_id, SOL_TCP, TCP_NODELAY,
+                 (const void *)&bool_opt, sizeof(bool_opt))
+      < 0)
+    return -1;
+  }
+
+    /* set the IP low delay option. */
+  {int priority_opt = IPTOS_LOWDELAY;
+  if (setsockopt(socket_id, SOL_IP, IP_TOS,
+                 (const void *)&priority_opt, sizeof(priority_opt))
+      < 0)
+    return -1;
+  }
+
+#if 0
+    /* send buffer */
+    /* NOTE: For slave devices, that may be receiving multiple
+     *       requests before they have a chance to reply to the first,
+     *       it probably is a good idea to have a larger receive buffer.
+     *
+     *       For the send buffer, it probably does not make sense to
+     *       waste time asking for a smaller buffer, since the larger
+     *       default buffer has already been allocated (the socket has already
+     *       been created!)
+     *
+     *       We might just as well leave out the configuration of the socket
+     *       buffer size...
+     */
+#define SOCK_BUF_SIZE 300 /* The size proposed in the Modbus TCP spec. */
+  {int sock_buf_size;
+  sock_buf_size = SOCK_BUF_SIZE;
+  if (setsockopt(socket_id, SOL_SOCKET, SO_SNDBUF,
+                 (const void *)&sock_buf_size, sizeof(sock_buf_size))
+      < 0)
+    return -1;
+    /* recv buffer */
+  sock_buf_size = SOCK_BUF_SIZE;
+  if (setsockopt(socket_id, SOL_SOCKET, SO_RCVBUF,
+             (const void *)&sock_buf_size, sizeof(sock_buf_size))
+      < 0)
+    return -1;
+  }
+#endif
+
+  return 0;
+}
+
+
+/************************************/
+/**                                **/
+/** Connect socket to remote host  **/
+/**                                **/
+/************************************/
+
+/* This function will create a new socket, and connect it to a remote host... */
+static inline int open_connection(int nd) {
+  int socket_id;
+
+  if (nd_table_->node[nd].fd >= 0)
+    /* nd already connected) */
+    return nd_table_->node[nd].fd;
+
+  if (nd_table_->node[nd].addr.sin_family != AF_INET)
+    /* invalid remote address, or invalid nd */
+    return -1;
+
+  /* lets try to connect... */
+    /* create the socket */
+  if ((socket_id = socket(PF_INET, DEF_TYPE, 0 /* protocol_num */)) < 0)
+    return -1;
+
+  /* configure the socket */
+  if (configure_socket(socket_id) < 0) {
+    close(socket_id);
+    return -1;
+  };
+
+    /* establish the connection to remote host */
+  if (connect_nonb(socket_id,
+      (struct sockaddr *)&(nd_table_->node[nd].addr),
+      sizeof(nd_table_->node[nd].addr), MAX_CONNECT_TIMEOUT) < 0) {
+    close(socket_id);
+    return -1;
+  }
+
+  nd_table_->node[nd].fd = socket_id;
+  FD_SET(socket_id, &(nd_table_->all_fds));
+  nd_table_->all_fd_high = max(nd_table_->all_fd_high, socket_id);
+  FD_SET(socket_id, &(nd_table_->ms_fds));
+  nd_table_->ms_fd_high = max(nd_table_->ms_fd_high, socket_id);
+
+  return socket_id;
+}
+
+
+/* This function will accept a new connection request, and attribute it to a new node... */
+static inline int accept_connection(int nd) {
+  int socket_id, new_nd;
+
+  if ((new_nd = nd_table_get_free_node(nd_table_, MB_SLAVE_NODE)) < 0)
+    /* no available free nodes for the new connection... */
+    return -1;
+
+  /* lets accept new connection request... */
+  if ((socket_id = accept(nd_table_->node[nd].fd, NULL, NULL)) < 0) {
+    /* error establishing new connection... */
+    nd_table_close_node(nd_table_, new_nd);  /* first free up the un-used node. */
+    return -1;
+  }
+
+  /* configure the socket */
+  if (configure_socket(socket_id) < 0) {
+    nd_table_close_node(nd_table_, new_nd);  /* first free up the un-used node. */
+    close(socket_id);
+    return -1;
+  };
+
+  /* set up the node entry and update the fd sets */
+  nd_table_->node[new_nd].fd = socket_id;
+  FD_SET(socket_id, &(nd_table_->all_fds));
+  nd_table_->all_fd_high = max(nd_table_->all_fd_high, socket_id);
+  FD_SET(socket_id, &(nd_table_->ms_fds));
+  nd_table_->ms_fd_high = max(nd_table_->ms_fd_high, socket_id);
+
+  return new_nd;
+}
+
+
+static inline void close_connection(int nd) {
+  if (nd_table_->node[nd].fd < 0)
+    /* nd already disconnected */
+    return;
+
+  int res = shutdown(nd_table_->node[nd].fd, SHUT_RDWR);
+#ifdef DEBUG
+{
+	/* could not read registers from slave! */
+	printf("shutdown()  returned %d\n",res);
+}
+#endif
+
+  close(nd_table_->node[nd].fd);
+  FD_CLR(nd_table_->node[nd].fd, &nd_table_->all_fds);
+  FD_CLR(nd_table_->node[nd].fd, &nd_table_->ms_fds);
+  nd_table_->node[nd].fd = -1;
+}
+
+
+
+/************************************/
+/**                                **/
+/**     Data format conversion     **/
+/**                                **/
+/************************************/
+
+/*
+ * Functions to convert u16 variables
+ * between network and host byte order
+ *
+ * NOTE: Modbus uses MSByte first, just like
+ *       tcp/ip, so we use the htons() and
+ *       ntoh() functions to guarantee
+ *       code portability.
+ */
+
+static inline u16 mb_hton(u16 h_value) {
+/*  return h_value; */
+  return htons(h_value);
+}
+
+static inline u16 mb_ntoh(u16 m_value) {
+/*  return m_value; */
+  return ntohs(m_value);
+}
+
+static inline u8 msb(u16 value) {
+/*  return Most Significant Byte of value; */
+  return (value >> 8) & 0xFF;
+}
+
+static inline u8 lsb(u16 value) {
+/*  return Least Significant Byte of value; */
+  return value & 0xFF;
+}
+
+#define u16_v(char_ptr)  (*((u16 *)(&(char_ptr))))
+
+
+/************************************/
+/**                                **/
+/**   Build/Check a frame header   **/
+/**                                **/
+/************************************/
+
+/* A modbus TCP frame header has 6 bytes...
+ *   header[0-1] -> transaction id
+ *   header[2-3] -> must be 0
+ *   header[4-5] -> frame data length (must be <= 255)
+ */
+#if TCP_HEADER_LENGTH < 6
+#error This code assumes a header size of 6 bytes, but TCP_HEADER_LENGTH < 6
+#endif
+
+static inline void build_header(u8 *header,
+                                u16 transaction_id,
+                                u16 byte_count)
+{
+  u16_v(header[0]) = mb_hton(transaction_id);
+  header[2] = 0;
+  header[3] = 0;
+  u16_v(header[4]) = mb_hton(byte_count);
+}
+
+
+static inline int check_header(u8  *header,
+                               u16 *transaction_id,
+                               u16 *byte_count)
+{
+  if ((header[2] != 0) || (header[3] != 0))
+    return -1;
+
+  *transaction_id = mb_ntoh(*(u16 *)(header + 0));
+  *byte_count     = mb_ntoh(*(u16 *)(header + 4));
+
+  if (*byte_count > MAX_L2_FRAME_LENGTH)
+    return -1;
+
+  return 0;
+}
+
+
+
+
+
+/**************************************************************/
+/**************************************************************/
+/****                                                      ****/
+/****                                                      ****/
+/****              Sending of Modbus TCP Frames            ****/
+/****                                                      ****/
+/****                                                      ****/
+/**************************************************************/
+/**************************************************************/
+
+int modbus_tcp_write(int nd,  /* node descriptor */
+                     u8 *data,
+                     size_t data_length,
+                     u16 transaction_id)
+{
+#define data_vector_size 2
+
+  /* NOTE: The following variables do not have to be static for the code to work
+   *       correctly. It simply does not make sense to re-initialize these
+   *       structures with the same values every time the function is called.
+   */
+  /*v1.0*/
+  u8            header[TCP_HEADER_LENGTH], *ptriovec/*v1.1*/;
+  struct iovec  data_vector[data_vector_size] = {{(void *)header, TCP_HEADER_LENGTH},{NULL, 0}};
+  struct msghdr msg = {NULL, 0, data_vector, data_vector_size, NULL, 0, 0};
+  int res, bytes_sent;
+
+#ifdef DEBUG
+  printf("modbus_tcp_write(): called...  nd=%d\n", nd);
+#endif
+
+  if ((nd >= nd_table_->node_count) || (nd < 0))
+    /* invalid node descriptor... */
+    return -1;
+
+  /*************************
+  * prepare the header...  *
+  *************************/
+  build_header(header, transaction_id, data_length);
+#ifdef DEBUG
+/* Print the hex value of each character that is about to be
+ * sent over the bus.
+ */
+  { int i;
+    printf("modbus_tcp_write(): sending data...\n");
+    for(i = 0; i < TCP_HEADER_LENGTH; i++)
+      printf("[0x%2X]", header[i]);
+    for(i = 0; i < data_length; i++)
+      printf("[0x%2X]", data[i]);
+    printf("\n");
+  }
+#endif
+
+  /******************************************
+   * do we need to re-establish connection? *
+   ******************************************/
+  if (open_connection(nd) < 0) {
+#ifdef DEBUG
+    printf("modbus_tcp_write(): could not establish connection...\n");
+#endif
+    return -1;
+  }
+
+  /**********************
+   * write to output... *
+   **********************/
+  /* We are optimising for the most likely case, and in doing that
+   * we are making the least likely case have worse behaviour!
+   * Read on for an explanation...
+   *
+   * - The optimised behaviour for the most likely case:
+   * We have set the NO_DELAY flag on the socket, so the IP datagram
+   * is not delayed and is therefore sent as soon as any data is written to
+   * the socket.
+   * In order to send the whole message in a single IP datagram, we have to
+   * write both the the header and the data with a single call to write()
+   * In order to not to have to copy the data around just to add the
+   * message header, we use sendmsg() instead of write()!
+   *
+   * - The worse behaviour for the least likely case:
+   * If for some reason only part of the data is sent with the first call to
+   * write(), a datagram is sent right away, and the subsequent data will
+   * be sent in another datagram. :-(
+   */
+  data_vector[data_vector_size - 1].iov_base = data;
+  data_vector[data_vector_size - 1].iov_len  = data_length;
+  bytes_sent = 0;
+  while (1) {
+     /* Please see the comment just above the main loop!! */
+    res = sendmsg(nd_table_->node[nd].fd, &msg, 0);
+    if (res < 0) {
+      if ((errno != EAGAIN ) && (errno != EINTR )) {
+        /* error sending message... */
+        close_connection(nd);
+        return -1;
+      } else {
+        continue;
+      }
+    } else {
+      /* res >= 0 */
+      bytes_sent += res;
+      if (bytes_sent >= data_length + TCP_HEADER_LENGTH) {
+        /* query succesfully sent! */
+#ifdef DEBUG
+        printf("modbus_tcp_write(): sent %d bytes\n", bytes_sent);
+#endif
+        return data_length;
+      }
+
+      /* adjust the data_vector... */
+	  /*v1.1*/
+      if (res < data_vector[0].iov_len) {
+        data_vector[0].iov_len -= res;
+		ptriovec = (u8 *)data_vector[0].iov_base;
+		ptriovec += res;
+        data_vector[0].iov_base = (void *)ptriovec;
+      } else {
+        res -= data_vector[0].iov_len;
+        data_vector[0].iov_len  = 0;
+        data_vector[1].iov_len -= res;
+		ptriovec = (u8 *)data_vector[1].iov_base;
+		ptriovec += res;
+        data_vector[1].iov_base = (void *)ptriovec;
+      }
+    }
+  } /* while (1) */
+
+  /* humour the compiler... */
+  return -1;
+}
+
+
+
+/**************************************************************/
+/**************************************************************/
+/****                                                      ****/
+/****                                                      ****/
+/****              Receiving Modbus TCP Frames             ****/
+/****                                                      ****/
+/****                                                      ****/
+/**************************************************************/
+/**************************************************************/
+
+
+/* A helper function to modbus_tcp_read()
+ *
+ * WARNING: The semantics of this function are not what you would expect!
+ *
+ *          if (data_already_available != 0)
+ *          It assumes that select() has already been called before
+ *          this function got called, and we are therefore guaranteed
+ *          to have at least one byte to read off the socket (the fd).
+ *
+ *          if (data_already_available == 0)
+ *          it starts off by calling select()!
+ *
+ *
+ * NOTE: Ususal select semantics for (a: end_time == NULL) and
+ *       (b: *end_time == 0) also apply.
+ *
+ *       (a) Indefinite timeout
+ *       (b) Try once, and and quit if no data available.
+ */
+static int read_bytes(int fd,
+                      u8 *data,
+                      int max_data_count,
+                      const struct timespec *end_time,
+                      int data_already_available)
+{
+  fd_set rfds;
+  int res, data_count;
+
+  data_count = 0;
+  while (data_count < max_data_count) {
+    /*============================*
+     * wait for data availability *
+     *============================*/
+    if (data_already_available == 0) {
+      FD_ZERO(&rfds);
+      FD_SET(fd, &rfds);
+      if (my_select(fd + 1, &rfds, end_time) < 0)
+        return -1;
+    }
+
+    /*============================*
+     * read the available data... *
+     *============================*/
+    res = read(fd, data + data_count, max_data_count - data_count);
+    if (res == 0) {
+      /* We are guaranteed to have data to read off the fd since we called
+       * select(), but read() returned 0 bytes.
+       * This means that the remote process has closed down the connection,
+       * so we return 0.
+       */
+      return 0;
+    }
+
+    if (res < 0) {
+      if (errno != EINTR)
+        return -1;
+      else
+        res = 0;
+    }
+	#ifdef DEBUG
+    {/* display the hex code of each character received */
+      int i;
+      for (i=0; i < res; i++)
+        printf("%2X ", *(data + data_count + i));
+    }
+	#endif
+    data_count += res;
+    data_already_available = 0;
+  } /* while ()*/
+
+  /* data read succesfully... */
+  return data_count;
+}
+
+
+
+
+/************************************/
+/**                                **/
+/**    Read a Modbus TCP frame     **/
+/**                                **/
+/************************************/
+
+/* The public function that reads a valid modbus frame.
+ * The frame is read from:
+ *   -  the node descriptor nd, if nd >= 0
+ *   -  any valid and initialised node descriptor, if nd = -1
+ *      In this case, the node where the data is eventually read from
+ *      is returned in *nd.
+ *
+ * The send_data and send_length parameters are ignored...
+ *
+ * return value: The length (in bytes) of the valid frame,
+ *               -1 on error
+ *
+ * NOTE: Ususal select semantics for (a: recv_timeout == NULL) and
+ *       (b: *recv_timeout == 0) also apply.
+ *
+ *       (a) Indefinite timeout
+ *       (b) Try once, and and quit if no data available.
+ */
+
+/* NOTES:
+ *  - We re-use the recv_buf_ to load the frame header, so we have to make
+ *    sure that the buffer is large enough to take it...
+ */
+/*v1.0 
+#ifndef __Lynx__ 
+#if RECV_BUFFER_SIZE < 5 //TCP_HEADER_LENGTH
+#error The receive buffer is smaller than the frame header length.
+#endif
+#endif
+*/
+
+int modbus_tcp_read(int *nd,                /* node descriptor */
+                    u8 *recv_data_ptr/*v1.0*/,
+                    u16 *transaction_id,
+                    u8 *send_data,         /* ignored ! */
+                    int send_length,       /* ignored ! */
+                    const struct timespec *recv_timeout) {
+
+  struct timespec cur_time, end_time, *ts_ptr;
+  /*v1.0
+  u8 *local_recv_data_ptr;
+  */
+  u16 local_transaction_id = 0;
+  u16 frame_length;
+  int orig_nd, fd, fd_high, data_already_available;
+
+#ifdef DEBUG
+  printf("modbus_tcp_read(): called...  nd=%d\n", *nd);
+#endif
+
+  if (nd == NULL)
+    return -1;
+
+  if (*nd >= nd_table_->node_count)
+    /* invalid *nd                      */
+    /* remember that *nd < 0 is valid!! */
+    return -1;
+
+  /*v1.0
+  if (recv_data_ptr == NULL)
+    recv_data_ptr = &local_recv_data_ptr;
+  */	
+  if (transaction_id == NULL)
+    transaction_id = &local_transaction_id;
+
+  /* We will potentially call read() multiple times to read in a single frame.
+   * We therefore determine the absolute time_out, and use this as a parameter
+   * for each call to read_bytes() instead of using a relative timeout.
+   *
+   * NOTE: see also the timeout related comment in the read_bytes() function!
+   *
+   * NOTE: clock_gettime() is rather expensive, between 7000 and 7500 clock
+   *       cycles (measured with rdtsc on an Intel Pentium)
+   *       gettimeofday() is half as expensive (3000 to 3500 clock cycles),
+   *       but is not POSIX compliant... :-(
+   *       Nevertheless this is peanuts (20 us on a 350 MHz cpu) compared to
+   *       the timescales required to read a modbus frame over a serial bus
+   *       (aprox. 10 ms for a 10 byte frame on a 9600 baud bus!)
+   */
+  /* get the current time... */
+  if (recv_timeout == NULL) {
+    ts_ptr = NULL;
+  } else {
+    ts_ptr = &end_time;
+    if ((recv_timeout->tv_sec == 0) && (recv_timeout->tv_nsec == 0)) {
+      end_time = *recv_timeout;
+    } else {
+      if (clock_gettime(CLOCK_REALTIME, &cur_time) < 0)
+        return -1;
+      end_time = timespec_add(cur_time, *recv_timeout);
+    }
+  }
+
+  /* We will loop forever...
+   * We jump out of the loop and return from the function as soon as:
+   *  - we receive a valid modbus message;
+   *    OR
+   *  - we time out.
+   */
+  orig_nd = *nd;
+  while(1) {
+    *nd = orig_nd;
+
+    /* If we must read off a single node... */
+    if (*nd >= 0)
+      /* but the node does not have a valid fd */
+      if ((nd_table_->node[*nd].addr.sin_family == MB_FREE_NODE) ||
+          (nd_table_->node[*nd].fd < 0))
+        /* then we return an error... */
+        return -1;
+
+    /* We want to call the read_bytes() function only after we are sure there
+     * is data waiting to be read on the socket, so we call select here.
+     *
+     * We only call select() here for the case when (*nd >= 0),
+     * since for the other case select() will be called later on...
+     */
+    data_already_available = 1;
+    if (*nd >= 0)
+      data_already_available = 0;
+
+    /* if *nd < 0, we will be:
+     *  - reading off any valid node descriptor!!
+     *  - and accepting new connection requests, if we have free nodes available!!
+     */
+    while (*nd < 0) {
+      int nd_count;
+      fd_set rfds;
+
+      if (nd_table_->free_node_count > 0) {
+        /* We have free nodes, so we will also listen on nodes
+         * that will accept new connections requests...
+         */
+        rfds = nd_table_->all_fds;
+        fd_high = nd_table_->all_fd_high;
+      } else {
+        /* We do not have free nodes, so we will only listen on nodes
+         * that do not accept new connections requests...
+         */
+        rfds = nd_table_->ms_fds;
+        fd_high = nd_table_->ms_fd_high;
+      }
+
+      if (my_select(fd_high + 1, &rfds, ts_ptr) < 0)
+        return -1;
+
+      /* figure out which nd is ready to be read... */
+      for (nd_count = 0; nd_count < nd_table_->node_count; nd_count++) {
+        if (nd_table_->node[nd_count].addr.sin_family != MB_FREE_NODE) {
+          if (FD_ISSET(nd_table_->node[nd_count].fd, &rfds)) {
+            /* Found the node descriptor... */
+            if (nd_table_->node[nd_count].addr.sin_family == MB_LISTEN_NODE) {
+              /* We must accept a new connection...
+               * No need to check for errors.
+               * If one occurs, there is nothing we can do...
+               */
+              *nd = accept_connection(nd_count);
+#ifdef DEBUG
+              printf("modbus_tcp_read(): new connection request on nd=%d\n", nd_count);
+              printf("modbus_tcp_read(): new connection accepted on nd=%d", *nd);
+#endif
+              *nd = -1; /* this will keep us in the while loop */
+            } else {
+              /* We will read a frame off this nd */
+              *nd = nd_count; /* this will get us out of the while loop later on. */
+            }
+            /* we have found the node descriptor, so let's jump out of the for(;;) loop */
+            break;
+          }
+        }
+      } /* for(;;) */
+    } /* while (*nd < 0) */
+
+    /* Just a consistency check... */
+    if (*nd < 0)
+      /* If the code is correct, this should never occur... */
+      return -1;
+
+#ifdef DEBUG
+    printf("modbus_tcp_read(): reading off nd=%d\n", *nd);
+#endif
+    /*=========================*
+     * read a Modbus TCP frame *
+     *=========================*/
+    /* assume error... */
+    fd = nd_table_->node[*nd].fd;
+	/*v1.0
+    *recv_data_ptr = NULL;
+	*/
+
+    /*-------------*
+     * read header *
+     *-------------*/
+    if (read_bytes(fd, recv_data_ptr/*v1.0*/, TCP_HEADER_LENGTH, ts_ptr, data_already_available)
+        == TCP_HEADER_LENGTH) {
+      /* let's check for header consistency... */
+      if (check_header(recv_data_ptr/*v1.0*/, transaction_id, &frame_length) < 0) {
+#ifdef DEBUG
+        printf("modbus_tcp_read(): frame with non valid header...\n");
+#endif
+        /* We let the code fall through to the error handler, that will
+         * close the connection!
+         * This is exactly what the modbus TCP protocol specifies!
+         */
+      } else {
+        /*-----------*
+         * read data *
+         *-----------*/
+        /* NOTE: the function read_bytes() assumes that there is data ready to be
+         *       read off the socket, so we have to call select() ourselves
+         *       before calling it.
+         */
+
+        data_already_available = 0;
+        if (read_bytes(fd, recv_data_ptr/*v1.0*/, frame_length, ts_ptr, data_already_available)
+            == frame_length) {
+          /* frame received succesfully... */
+#ifdef DEBUG
+          printf("\n");
+#endif
+		  /*v1.0
+          *recv_data_ptr = recv_buf_;
+		  */
+          return frame_length;
+        }
+      }
+    }
+
+    /* We had an error reading the frame...
+     * We handle it by closing the connection, as specified by
+     * the modbus TCP protocol!
+     */
+
+#ifdef DEBUG
+    printf("modbus_tcp_read(): error reading frame. Closing connection...\n");
+#endif
+    /* We close the socket... */
+    close_connection(*nd);
+
+    /* If it is a slave, we free the node... */
+    if(nd_table_->node[*nd].addr.sin_family == MB_SLAVE_NODE)
+        nd_table_close_node(nd_table_, *nd);
+
+    /* We try to read another frame... */
+  } /* while(1) */
+
+  /* humour the compiler... */
+  return -1;
+}
+
+
+
+
+
+
+/**************************************************************/
+/**************************************************************/
+/****                                                      ****/
+/****                                                      ****/
+/****        Initialising and Shutting Down Library        ****/
+/****                                                      ****/
+/****                                                      ****/
+/**************************************************************/
+/**************************************************************/
+
+
+/******************************/
+/**                          **/
+/**   Load Default Values    **/
+/**                          **/
+/******************************/
+
+static void set_defaults(const char **service) {
+  /* Set the default values, if required... */
+  if (*service == NULL)
+    *service = DEF_SERVICE;
+}
+
+
+/******************************/
+/**                          **/
+/**    Initialise Library    **/
+/**                          **/
+/******************************/
+/* returns the number of nodes succesfully initialised...
+ * returns -1 on error.
+ */
+int modbus_tcp_init(int nd_count,
+                    optimization_t opt /* ignored... */,
+                    int *extra_bytes) {
+#ifdef DEBUG
+  printf("modbus_tcp_init(): called...\n");
+  printf("creating %d nodes:\n", nd_count);
+#endif
+
+  if (nd_table_ != NULL)
+    /* library already previously initialised! */
+    return -1;
+
+  if (nd_count <= 0)
+    /* invalid node count... */
+    goto error_exit_0;
+
+    /* set the extra_bytes value... */
+    /* Please see note before the modbus_rtu_write() function for a
+     * better understanding of this extremely ugly hack... This will be
+     * in the mb_rtu.c file!!
+     *
+     * The number of extra bytes that must be allocated to the data buffer
+     * before calling modbus_tcp_write()
+     */
+  if (extra_bytes != NULL)
+    *extra_bytes = 0;
+
+  /* V1.0:  initialise recv buffer
+  recv_buf_ = malloc(sizeof(u8) * RECV_BUFFER_SIZE);
+  if (recv_buf_ == NULL) {
+    //plc_log_errmsg(1, "Out of memory: error initializing receive buffer");
+	printf("\nOut of memory: error initializing receive buffer\n");
+    goto error_exit_0;
+  }
+  */
+
+  /* create the node table structure... */
+  nd_table_ = (nd_table_t*) malloc(sizeof(nd_table_t));
+  if (nd_table_ == NULL) {
+    /*F.Locci 
+    plc_log_errmsg(1, "Out of memory: error initializing node table");
+	*/
+	printf("\nOut of memory: error initializing node table\n");
+    goto error_exit_1;
+  }
+
+  /* initialise the node table... */
+  if (nd_table_init(nd_table_, nd_count) < 0)
+    goto error_exit_2;
+
+#ifdef DEBUG
+  printf("modbus_tcp_init(): %d node(s) opened succesfully\n", nd_count);
+#endif
+  return nd_count; /* number of succesfully created nodes! */
+
+/*
+error_exit_3:
+  free(nd_table_->node);
+  nd_table_->node = NULL;
+  nd_table_->count = 0;
+*/
+error_exit_2:
+  free(nd_table_); nd_table_ = NULL;
+error_exit_1:
+  /*V1.0
+  free(recv_buf_); recv_buf_ = NULL;
+  */
+error_exit_0:
+  return -1;
+}
+
+
+
+
+
+
+/******************************/
+/**                          **/
+/**    Open a Master Node    **/
+/**                          **/
+/******************************/
+
+int modbus_tcp_connect(node_addr_t node_addr) {
+  int node_descriptor;
+  struct sockaddr_in tmp_addr;
+
+#ifdef DEBUG
+  printf("modbus_tcp_connect(): called...\n");
+  printf("        %s:%s\n",
+         node_addr.addr.tcp.host,
+         node_addr.addr.tcp.service);
+#endif
+
+  /* Check for valid address family */
+  if (node_addr.naf != naf_tcp)
+    /* wrong address type... */
+    return -1;
+
+  /* set the default values... */
+  set_defaults(&(node_addr.addr.tcp.service));
+
+  /* Check the parameters we were passed... */
+  if(sin_init_addr(&tmp_addr,
+                   node_addr.addr.tcp.host,
+                   node_addr.addr.tcp.service,
+                   DEF_PROTOCOL)
+       < 0) {
+    /*
+    plc_log_wrnmsg(1, "Error parsing/resolving address %s:%s",
+                   node_addr.addr.tcp.host,
+                   node_addr.addr.tcp.service);
+    */
+    return -1;
+  }
+
+  /* find a free node descriptor */
+    /* NOTE: The following code line works beacuse MB_MASTER_NODE is set to AF_INET! */
+#if MB_MASTER_NODE != AF_INET
+#error The code only works if MB_MASTER_NODE == AF_INET, which they are not!
+#endif
+  if ((node_descriptor = nd_table_get_free_node(nd_table_, MB_MASTER_NODE)) < 0)
+    /* if no free nodes to initialize, then we are finished... */
+    return -1;
+
+  nd_table_->node[node_descriptor].addr = tmp_addr;
+  nd_table_->node[node_descriptor].fd   = -1; /* not currently connected... */
+  nd_table_->node[node_descriptor].close_on_silence = node_addr.addr.tcp.close_on_silence;
+
+  if (nd_table_->node[node_descriptor].close_on_silence < 0)
+    nd_table_->node[node_descriptor].close_on_silence = DEF_CLOSE_ON_SILENCE;
+
+#ifdef DEBUG
+  printf("modbus_tcp_connect(): returning nd=%d\n", node_descriptor);
+#endif
+  return node_descriptor;
+}
+
+
+
+
+/******************************/
+/**                          **/
+/**    Open a Slave Node     **/
+/**                          **/
+/******************************/
+
+int modbus_tcp_listen(node_addr_t node_addr) {
+  int fd, nd;
+
+#ifdef DEBUG
+  printf("modbus_tcp_listen(): called...\n");
+  printf("        %s:%s\n",
+         node_addr.addr.tcp.host,
+         node_addr.addr.tcp.service);
+#endif
+
+  /* Check for valid address family */
+  if (node_addr.naf != naf_tcp)
+    /* wrong address type... */
+    goto error_exit_0;
+
+  /* set the default values... */
+  set_defaults(&(node_addr.addr.tcp.service));
+
+  /* create a socket and bind it to the appropriate port... */
+  fd = bind_socket(node_addr.addr.tcp.host,
+                   node_addr.addr.tcp.service,
+                   DEF_PROTOCOL);
+  if (fd < 0)
+    goto error_exit_0;
+  if (listen(fd, DEF_MAX_PENDING_CONNECTION_REQUESTS) < 0)
+    goto error_exit_0;
+
+  /* find a free node descriptor */
+  if ((nd = nd_table_get_free_node(nd_table_, MB_LISTEN_NODE)) < 0) {
+    /* if no free nodes to initialize, then we are finished... */
+    goto error_exit_1;
+  }
+
+  /* nd_table_->node[nd].addr = tmp_addr; */ /* does not apply for MB_LISTEN_NODE */
+  nd_table_->node[nd].fd = fd; /* not currently connected... */
+
+  /* update the fd sets...*/
+  FD_SET(fd, &(nd_table_->all_fds));
+  nd_table_->all_fd_high = max(nd_table_->all_fd_high, fd);
+
+#ifdef DEBUG
+  printf("modbus_tcp_listen(): returning nd=%d\n", nd);
+#endif
+  return nd;
+
+error_exit_1:
+  close(fd);
+error_exit_0:
+  return -1;
+}
+
+
+
+/******************************/
+/**                          **/
+/**       Close a node       **/
+/**                          **/
+/******************************/
+
+int modbus_tcp_close(int nd) {
+#ifdef DEBUG
+  printf("modbus_tcp_close(): called... nd=%d\n", nd);
+#endif
+
+/*F.Locci*/
+  if (nd_table_ == NULL) return -1;
+/**/  
+  
+  if ((nd < 0) || (nd >= nd_table_->node_count))
+   	/* invalid nd */
+   	return -1;
+
+  if (nd_table_->node[nd].addr.sin_family == MB_FREE_NODE)
+    /* already free node */
+    return 0;
+
+  close_connection(nd);
+
+  nd_table_->node[nd].addr.sin_family = MB_FREE_NODE;
+  nd_table_->free_node_count++;
+
+  return 0;
+}
+
+
+
+/**********************************/
+/**                              **/
+/**  Close all open connections  **/
+/**                              **/
+/**********************************/
+
+int modbus_tcp_silence_init(void) {
+  int nd;
+
+#ifdef DEBUG
+  printf("modbus_tcp_silence_init(): called...\n");
+#endif
+
+  /* close all master connections that remain open... */
+  for (nd = 0; nd < nd_table_->node_count; nd++)
+    if (nd_table_->node[nd].addr.sin_family == MB_MASTER_NODE)
+      if (nd_table_->node[nd].close_on_silence > 0)
+        /* node is is being used for a master device,
+         * and wishes to be closed...   ...so we close it!
+         */
+         close_connection(nd);
+
+  return 0;
+}
+
+
+
+/******************************/
+/**                          **/
+/**   Shutdown the Library   **/
+/**                          **/
+/******************************/
+
+int modbus_tcp_done(void) {
+  int i;
+
+/*F.Locci*/
+  if (nd_table_ == NULL) return -1;
+/**/  
+
+    /* close all the connections... */
+  for (i = 0; i < nd_table_->node_count; i++)
+    modbus_tcp_close(i);
+
+  /* Free memory... */
+  free(nd_table_->node);
+  /*V1.0
+  free(recv_buf_); recv_buf_ = NULL;
+  */
+  free(nd_table_); nd_table_ = NULL;
+
+  return 0;
+}
+
+
+
+
+double modbus_tcp_get_min_timeout(int baud,
+                                  int parity,
+                                  int data_bits,
+                                  int stop_bits) {
+  return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_tcp_private.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_tcp_private.h
new file mode 100644
index 0000000000000000000000000000000000000000..b05ca22cc8800608d9d67ab8d3c43a6beea0fb26
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_tcp_private.h
@@ -0,0 +1,84 @@
+/*
+ * (c) 2002 Mario de Sousa
+ *
+ * Offered to the public under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ */
+
+
+#ifndef MODBUS_TCP_PRIVATE_H
+#define MODBUS_TCP_PRIVATE_H
+
+/*F.Locci #include <plc.h>*/  /* get the plc data types */
+#include "mb_util.h"
+
+
+/* tcp port default configuration... */
+#define DEF_SERVICE  "502"        /* port used by modbus */
+#define DEF_PROTOCOL "tcp"        /* protocol used by modbus tcp */
+#define DEF_TYPE     SOCK_STREAM  /* Quality of service required of the socket... */
+#define DEF_MAX_PENDING_CONNECTION_REQUESTS 5
+                                  /* maximum number of pending connection requests
+                                   * that have not yet been accept()'ed
+                                   */
+#define DEF_CLOSE_ON_SILENCE 1    /* Used only by master nodes.
+                                   * Flag indicating whether, by default, the connection
+                                   * to the slave device should be closed whenever the
+                                   * modbus_tcp_silence_init() function is called.
+                                   *
+                                   * 0  -> do not close connection
+                                   * >0 -> close connection
+                                   *
+                                   * The spec sugests that connections that will not
+                                   * be used for longer than 1 second should be closed.
+                                   * Even though we expect most connections to have
+                                   * silence intervals much shorted than 1 second, we
+                                   * decide to use the default of shuting down the
+                                   * connections because it is safer, and most other
+                                   * implementations seem to do the same.
+                                   * If we do not close we risk using up all the possible
+                                   * connections that the slave can simultaneouly handle,
+                                   * effectively locking out every other master that
+                                   * wishes to communicate with that same slave.
+                                   */
+
+ /* Since the receive buffer is also re-used to store the frame header,
+  * we set it to the larger of the two.
+  */
+#ifndef __Lynx__
+
+#if     TCP_HEADER_LENGTH > MAX_L2_FRAME_LENGTH
+#define RECV_BUFFER_SIZE    TCP_HEADER_LENGTH
+#else
+#define RECV_BUFFER_SIZE    MAX_L2_FRAME_LENGTH
+#endif
+
+#else  
+
+#if     defined(TCP_HEADER_LENGTH) > defined(MAX_L2_FRAME_LENGTH)
+#define RECV_BUFFER_SIZE    TCP_HEADER_LENGTH
+#else
+#define RECV_BUFFER_SIZE    MAX_L2_FRAME_LENGTH
+#endif
+
+#endif  
+
+
+#endif  /* MODBUS_TCP_PRIVATE_H */
+
+
+
+
+
+
+
+
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_time_util.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_time_util.h
new file mode 100644
index 0000000000000000000000000000000000000000..e17dc5291874284712bbac99529a309af53c88da
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_time_util.h
@@ -0,0 +1,159 @@
+/*
+ * (c) 2002 Mario de Sousa
+ *
+ * Offered to the public under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ */
+
+
+ /* Time handling functions used by the modbus protocols... */
+#include <time.h>
+
+#ifndef __MODBUS_TIME_UTIL_H
+#define __MODBUS_TIME_UTIL_H
+
+
+/************************************/
+/**                                **/
+/**     Time format conversion     **/
+/**                                **/
+/************************************/
+
+/* Function to load a struct timeval correctly
+ * from a double.
+ */
+static inline struct timeval d_to_timeval(double time) {
+  struct timeval tmp;
+
+  tmp.tv_sec  = time;
+  tmp.tv_usec = 1e6*(time - tmp.tv_sec);
+  return tmp;
+}
+
+/* Function to ... */
+static inline struct timespec timespec_dif(struct timespec ts1, struct timespec ts2) {
+  struct timespec ts;
+
+  ts.tv_sec  = ts1.tv_sec  - ts2.tv_sec;
+  if(ts1.tv_nsec > ts2.tv_nsec) {
+    ts.tv_nsec = ts1.tv_nsec - ts2.tv_nsec;
+  } else {
+    ts.tv_nsec = 1000000000 + ts1.tv_nsec - ts2.tv_nsec;
+    ts.tv_sec--;
+  }
+
+  if (ts.tv_sec < 0)
+    ts.tv_sec = ts.tv_nsec = 0;
+
+  return ts;
+}
+
+/* Function to ... */
+static inline struct timespec timespec_add(struct timespec ts1, struct timespec ts2) {
+  struct timespec ts;
+
+  ts.tv_sec  = ts1.tv_sec  + ts2.tv_sec;
+  ts.tv_nsec = ts1.tv_nsec + ts2.tv_nsec;
+  ts.tv_sec += ts.tv_nsec / 1000000000;
+  ts.tv_nsec = ts.tv_nsec % 1000000000;
+  return ts;
+}
+
+/* Function to convert a struct timespec to a struct timeval. */
+static inline struct timeval timespec_to_timeval(struct timespec ts) {
+  struct timeval tv;
+
+  tv.tv_sec  = ts.tv_sec;
+  tv.tv_usec = ts.tv_nsec/1000;
+  return tv;
+}
+
+
+
+/************************************/
+/**                                **/
+/** select() with absolute timeout **/
+/**                                **/
+/************************************/
+
+
+/* My private version of select using an absolute timeout, instead of the
+ * usual relative timeout.
+ *
+ * NOTE: Ususal select semantics for (a: end_time == NULL) and
+ *       (b: *end_time == 0) also apply.
+ *
+ *       (a) Indefinite timeout
+ *       (b) Try once, and and quit if no data available.
+ */
+static int my_select(int fd, fd_set *rfds, const struct timespec *end_time) {
+
+  int res;
+  struct timespec cur_time;
+  struct timeval timeout, *tv_ptr;
+  fd_set tmp_fds;
+
+  /*============================*
+   * wait for data availability *
+   *============================*/
+  do {
+    tmp_fds = *rfds;
+      /* NOTE: To do the timeout correctly we would have to revert to timers
+       *       and asociated signals. That is not very thread friendly, and is
+       *       probably too much of a hassle trying to figure out which signal
+       *       to use. What if we don't have any free signals?
+       *
+       *       The following solution is not correct, as it includes a race
+       *       condition. The following five lines of code should really
+       *       be atomic!
+       *
+       * NOTE: see also the timeout related comment in the
+       *       modbus_tcp_read() function!
+       */
+    if (end_time == NULL) {
+      tv_ptr = NULL;
+    } else {
+      tv_ptr = &timeout;
+      if ((end_time->tv_sec == 0) && (end_time->tv_nsec == 0)) {
+        timeout.tv_sec = timeout.tv_usec = 0;
+      } else {
+        /* ATOMIC - start */
+        if (clock_gettime(CLOCK_REALTIME, &cur_time) < 0)
+          return -1;
+        timeout = timespec_to_timeval(timespec_dif(*end_time, cur_time));
+      }
+    }
+
+    res = select(fd, &tmp_fds, NULL, NULL, tv_ptr);
+  /* ATOMIC - end */
+
+    if (res == 0) {
+#ifdef DEBUG
+      printf("Comms time out\n");
+#endif
+      return -1;
+    }
+    if ((res < 0) && (errno != EINTR)) {
+      return -1;
+    }
+  } while (res <= 0);
+
+  *rfds = tmp_fds;
+  return res;
+}
+
+
+
+
+
+
+#endif  /* __MODBUS_TIME_UTIL_H */
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_util.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_util.h
new file mode 100644
index 0000000000000000000000000000000000000000..9d8ea0868bf986eeeb164985cefb0208aafac55a
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/mb_util.h
@@ -0,0 +1,92 @@
+/*
+ * (c) 2002 Mario de Sousa
+ *
+ * Offered to the public under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ */
+
+
+#ifndef MB_UTIL_H
+#define MB_UTIL_H
+
+/* This file has constants related to the modbus protocol */
+/*
+ * Some of these constants are specific to the layer two protocols
+ * (i.e. master and slave), while others are specific of the
+ * layer one protocols (i.e. rtu, ascii, tcp).
+ *
+ * a) Unfortunately, due to the nature of the modbus protocol, that does not
+ * include a frame size field in the layer 1 frame (see note 1), and the
+ * fact that we are implementing it at the user level, the implementation
+ * of some layer 1 protocols need to know the content of the layer 2 protocol
+ * in order to determine the size of the frame.
+ *
+ * b) The layer two message formats are in fact the same, just reversing the role
+ * being played (master or slave).
+ *
+ * Bothe a) and b) mean we need the same modbus protocol constants in several files.
+ * It ends up making more sense to put them all together in a single file, which
+ * makes updating easier, even though we are trying to strictly seperate the layer 1
+ * and layer 2 protocols.
+ *
+ *
+ *
+ * Notes:
+ *  (1) There is no layer 1 field with the frame size, nevertheless this
+ *      size can be determined indirectly due to timing restrictions on the rtu
+ *      protocol. Unfortunately, due to the fact that we are implementing
+ *      it at the user level, we are not guaranteed to detect these timings
+ *      correctly, and therefore have to rely on layer 2 protocol info to
+ *      determine the frame size.
+ *      For the ascii protocol, the frame size is determined indirectly by
+ *      a frame header and tail, so we do not use layer 2 protocol info.
+ */
+
+
+ /* Layer 2 Frame Structure...                */
+ /* Valid for both master and slave protocols */
+#define L2_FRAME_HEADER_LENGTH    6
+#define L2_FRAME_BYTECOUNT_LENGTH 1
+#define L2_FRAME_DATABYTES_LENGTH 255
+#define MAX_L2_FRAME_LENGTH (L2_FRAME_HEADER_LENGTH + L2_FRAME_BYTECOUNT_LENGTH + L2_FRAME_DATABYTES_LENGTH)
+
+#define L2_FRAME_SLAVEID_OFS    0
+#define L2_FRAME_FUNCTION_OFS   1
+
+ /* Layer 1 - Ascii Frame sizes... */
+#define L2_TO_ASC_CODING        2 /* number of ascii bytes used to code a Layer 2 frame byte */
+#define ASC_FRAME_HEADER_LENGTH 1
+#define ASC_FRAME_HEADER        ':'
+#define ASC_FRAME_TAIL_LENGTH   2
+#define ASC_FRAME_TAIL_0        '\13' /* 'CR' */
+#define ASC_FRAME_TAIL_1        '\10' /* 'LF' */
+#define ASC_FRAME_LRC_LENGTH    2
+
+ /* Layer 1 - RTU Frame sizes... */
+#define RTU_FRAME_CRC_LENGTH    2
+
+ /* Layer 1 - TCP Frame sizes... */
+#define TCP_HEADER_LENGTH       6
+
+ /* Global Frame sizes */
+#define MAX_RTU_FRAME_LENGTH MAX_L2_FRAME_LENGTH + RTU_FRAME_CRC_LENGTH
+#define MAX_ASC_FRAME_LENGTH ((MAX_L2_FRAME_LENGTH * L2_TO_ASC_CODING) + ASC_FRAME_HEADER_LENGTH + ASC_FRAME_TAIL_LENGTH + ASC_FRAME_LRC_LENGTH)
+
+#endif  /* MB_UTIL_H */
+
+
+
+
+
+
+
+
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/sin_util.cpp b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/sin_util.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..682f4bbc2679bfd2f311b60fb9d9416b18c799db
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/sin_util.cpp
@@ -0,0 +1,229 @@
+/*
+ * (c) 2000 Jiri Baum
+ *          Mario de Sousa
+ *
+ * Offered to the public under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ */
+
+
+/*
+ * Socket INET utility routines
+ *
+ * This file implements the routines in sin_util.h
+ *
+ * These routines merely make life simpler when working with
+ * internet protocol sockets
+ */
+#include "sin_util.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <string.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define ERR_EXIT(mesg, err_num) {perror(mesg);return err_num;}
+#define MSG_EXIT(mesg, err_num) {fprintf(stderr, "%s\n", mesg);return err_num;}
+
+
+int sin_init_dot_addr(struct sockaddr_in *sad_in,
+                  char *dot_addr,
+                  unsigned short int port)
+{
+sad_in->sin_family = AF_INET;
+
+if( inet_aton(dot_addr, &(sad_in->sin_addr)) == 0 )
+   ERR_EXIT("inet_aton", -1);
+
+sad_in->sin_port = htons(port);
+
+return 1;
+}  /* sin_init_dot_addr */
+
+
+
+
+
+int sin_init_addr(struct sockaddr_in *addr,
+                  const char *host,
+                  const char *service,
+                  const char *protocol)
+/* initialize an address structure */
+{
+int port_flag;
+long int tmp_numb;
+long long int lli = 1;
+char *error_char;
+
+struct servent *serv_entry_ptr;
+struct hostent *host_entry_ptr;
+
+bzero ((char *)addr, sizeof(*addr));
+addr->sin_family = AF_INET;
+
+/* Map service name to port number */
+port_flag = 0;
+if (port_flag == 0)
+ if ((service == NULL) || (strcmp(service, "") == 0))
+   {addr->sin_port = htons(0); /* OS will sugest a port when binding */
+    port_flag = 1;
+   }
+
+if (port_flag == 0)
+   if ((serv_entry_ptr = getservbyname ((char *)service, (char *)protocol)) )
+      {addr->sin_port = serv_entry_ptr->s_port;
+       port_flag = 1;
+      }
+
+if (port_flag == 0)
+   {tmp_numb = strtol(service, &error_char, 0);
+    if ((*error_char == '\0') && (error_char != service) && 
+        (tmp_numb >= 0) && (tmp_numb < (lli << (8*sizeof(addr->sin_port)))))
+       {addr->sin_port = htons(tmp_numb);
+        port_flag = 1;
+       }
+   }
+
+if (port_flag == 0)
+   MSG_EXIT("sin_init_addr: Could not determine the port number.", -1);
+ 
+/* Map host name to IP address, allowing dotted decimal */
+addr->sin_addr.s_addr = INADDR_NONE;
+ 
+if (addr->sin_addr.s_addr == INADDR_NONE)
+   if ( (host_entry_ptr = gethostbyname ((char *)host)) )
+      bcopy (host_entry_ptr->h_addr, 
+             (char *)&(addr->sin_addr), 
+             host_entry_ptr->h_length);
+
+if (addr->sin_addr.s_addr == INADDR_NONE)
+   inet_aton (host, (struct in_addr *)addr);  
+
+if (addr->sin_addr.s_addr == INADDR_NONE)
+   MSG_EXIT("sin_init_addr: Could not determine the host IP address.", -1);
+
+return 1;
+} /* sin_init_addr(...) */
+
+
+
+
+int sin_init_proto(int *type,
+                   int *protocol_num,
+                   const char *protocol)
+{
+struct protoent *proto_entry_ptr;
+
+/* determine the protocol */
+*type = SOCK_RDM;
+if (strcasecmp (protocol, "udp") == 0) *type = SOCK_DGRAM;
+if (strcasecmp (protocol, "tcp") == 0) *type = SOCK_STREAM;
+if (strcasecmp (protocol, "raw") == 0) *type = SOCK_RAW;
+if (*type == SOCK_RDM)
+   MSG_EXIT ("sin_init_proto: protocol not supported.", -1);
+
+/* map protocol name to protocol number */
+if ( (proto_entry_ptr = getprotobyname ((char *)protocol)) == NULL )
+   MSG_EXIT ("sin_init_proto: can't get protocol number.", -1);
+*protocol_num = proto_entry_ptr->p_proto;
+
+return 1;
+} /* sin_init_proto(...) */
+
+
+int bind_socket(const char *host,
+                const char *service,
+                const char *protocol)
+/* create a socket and bind to a local port */
+{
+struct sockaddr_in sock_addr;
+int socket_id, type, protocol_num;
+
+/* initialize the sock_addr sturcture */
+if ( (sin_init_addr (&sock_addr, host, service, protocol)) < 0)
+   MSG_EXIT ("bind_socket: wrong address format", -1);
+
+/* determine the protocol */
+if ( (sin_init_proto (&type, &protocol_num, protocol)) < 0)
+   MSG_EXIT ("bind_socket: wrong protocol format", -1);
+
+/* create the socket */
+if ( (socket_id = socket (PF_INET, type, protocol_num)) < 0)
+   ERR_EXIT ("socket", -1);
+
+/* bind the socket */
+if ( bind (socket_id, (struct sockaddr *)&sock_addr, sizeof (sock_addr)) < 0)
+   ERR_EXIT ("bind", -1);
+
+return socket_id;
+} /* bind_socket(...) */
+
+
+
+int connect_socket(const char *host,
+                   const char *service,
+                   const char *protocol)
+/* create a socket and connect to a remote host */
+{
+struct sockaddr_in sock_addr;
+int socket_id, type, protocol_num;
+
+/* initialize the sock_addr sturcture */
+if ( (sin_init_addr (&sock_addr, host, service, protocol)) < 0)
+   MSG_EXIT ("bind_socket: wrong address format", -1);
+
+/* determine the protocol */
+if ( (sin_init_proto (&type, &protocol_num, protocol)) < 0)
+   MSG_EXIT ("bind_socket: wrong protocol format", -1);
+
+/* create the socket */
+if ( (socket_id = socket (PF_INET, type, protocol_num)) < 0)
+   ERR_EXIT ("socket", -1);
+
+/* bind the socket */
+if ( connect(socket_id, (struct sockaddr *)&sock_addr, sizeof (sock_addr)) < 0)
+   ERR_EXIT ("bind", -1);
+
+return socket_id;
+} /* connect_socket(...) */
+
+
+
+int get_socket_port(int sock)
+/* returns the port to which the socket is bound */ 
+{
+ int length;
+ struct sockaddr_in srv_addr;  
+
+ length = sizeof(srv_addr);
+ if (getsockname(sock, (struct sockaddr *)&srv_addr, (socklen_t *)&length) < 0)
+   return -1;
+
+ if (srv_addr.sin_family == AF_INET)
+   return ntohs(srv_addr.sin_port);
+
+ return -1; /* not INET socket... */
+} /* get_socket_port(...) */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/silecs-communication-cpp/src/silecs-communication/protocol/modbus/sin_util.h b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/sin_util.h
new file mode 100644
index 0000000000000000000000000000000000000000..5e6a6b6499532c60288bc7a463aee775fb51310c
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/protocol/modbus/sin_util.h
@@ -0,0 +1,59 @@
+/*
+ * (c) 2000 Jiri Baum
+ *          Mario de Sousa
+ *
+ * Offered to the public under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ */
+
+
+#ifndef SIN_UTIL_H
+#define SIN_UTIL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+
+
+int sin_init_addr(struct sockaddr_in *addr,
+                  const char *host,
+                  const char *service,
+                  const char *protocol);
+/* initialize an address structure */
+
+
+int bind_socket(const char *host,
+                const char *service,
+                const char *protocol);
+/* create a socket and bind to a local port */
+
+
+int connect_socket(const char *host,
+                   const char *service,
+                   const char *protocol);
+/* create a socket and connect to a remote host */
+
+
+int get_socket_port(int sock);
+/* returns the port to which the socket is bound */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/silecs-communication-cpp/src/silecs-communication/wrapper/Block.h b/silecs-communication-cpp/src/silecs-communication/wrapper/Block.h
new file mode 100644
index 0000000000000000000000000000000000000000..c1e1300c675ea457ea72f7d320852259240c05ae
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/wrapper/Block.h
@@ -0,0 +1,46 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef SILECSWRAPER_BLOCK_H_
+#define SILECSWRAPER_BLOCK_H_
+
+#include <string>
+
+namespace SilecsWrapper
+{
+class Block
+{
+public:
+    Block(const std::string& name) :
+                    _name(name)
+    {
+    }
+
+    virtual ~Block()
+    {
+    }
+
+    const std::string& getName() const
+    {
+        return _name;
+    }
+
+protected:
+    const std::string _name;
+};
+
+} //namespace SilecsWrapper
+
+#endif
diff --git a/silecs-communication-cpp/src/silecs-communication/wrapper/Controller.cpp b/silecs-communication-cpp/src/silecs-communication/wrapper/Controller.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..73d19dd633447c0d04dd2e47e94af737cd9bc299
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/wrapper/Controller.cpp
@@ -0,0 +1,52 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/wrapper/Controller.h>
+#include <silecs-communication/wrapper/Design.h>
+
+namespace SilecsWrapper
+{
+
+Controller::Controller(const std::string& name, const std::string& domain, Design *design, const std::string parameterFile) :
+                _name(name),
+                _domain(domain),
+                _silecsPLC(design->getSilecsCluster()->getPLC(_name, parameterFile))
+{
+
+}
+
+Controller::~Controller()
+{
+
+}
+
+void Controller::connect()
+{
+    //By default: Controller connected right-away and Master registers download.
+    _silecsPLC->connect(Silecs::MASTER_SYNCHRO, true);
+}
+
+void Controller::connect(Silecs::SynchroMode synchroMode, bool connectNow)
+{
+    //Connect parameters can be set in manual connection mode (Automatic connect==false)
+    _silecsPLC->connect(synchroMode, connectNow);
+}
+
+void Controller::disconnect()
+{
+    _silecsPLC->disconnect();
+}
+
+} //namespace SilecsWrapper
diff --git a/silecs-communication-cpp/src/silecs-communication/wrapper/Controller.h b/silecs-communication-cpp/src/silecs-communication/wrapper/Controller.h
new file mode 100644
index 0000000000000000000000000000000000000000..ec4f74f599166289948f8940fa076ee21644fe8a
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/wrapper/Controller.h
@@ -0,0 +1,64 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef SILECSWRAPER_CONTROLLER_H_
+#define SILECSWRAPER_CONTROLLER_H_
+
+#include <silecs-communication/interface/equipment/SilecsPLC.h>
+
+#include <string>
+
+namespace SilecsWrapper
+{
+
+class Design;
+
+class Controller
+{
+public:
+    Controller(const std::string& name, const std::string& domain, Design *design,const std::string parameterFile);
+
+    const std::string& getName() const
+    {
+        return _name;
+    }
+
+    Silecs::PLC* getSilecsPLC()
+    {
+        return _silecsPLC;
+    }
+
+    void connect();
+    void connect(Silecs::SynchroMode synchroMode, bool connectNow);
+
+    void disconnect();
+
+    virtual ~Controller();
+
+protected:
+    const std::string _name;
+    const std::string _domain;
+
+    Silecs::PLC* _silecsPLC;
+
+private:
+    // Non copyable
+    Controller(const Controller& other);
+    Controller& operator=(const Controller&);
+};
+
+} //namespace SilecsWrapper
+
+#endif
diff --git a/silecs-communication-cpp/src/silecs-communication/wrapper/DeployUnit.cpp b/silecs-communication-cpp/src/silecs-communication/wrapper/DeployUnit.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a73e1dc92ed33280d4556446d2b33baf887d90e6
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/wrapper/DeployUnit.cpp
@@ -0,0 +1,98 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/wrapper/DeployUnit.h>
+
+namespace SilecsWrapper
+{
+
+DeployConfig::DeployConfig() :
+                _automaticConnect(true)
+{
+}
+
+DeployConfig::DeployConfig(bool automaticConnect) :
+                _automaticConnect(automaticConnect)
+{
+}
+
+bool DeployConfig::getAutomaticConnect() const
+{
+    return _automaticConnect;
+}
+
+void DeployConfig::setAutomaticConnect(bool automaticConnect)
+{
+    _automaticConnect = automaticConnect;
+}
+
+//===============================================
+
+DeployUnit* DeployUnit::_instance = NULL;
+//SilecsWrapper::DeployConfig DeployUnit::_globalConfig = SilecsWrapper::DeployConfig();
+
+DeployUnit::DeployUnit(const std::string& name, const std::string& version, const std::string& logTopics,const DeployConfig& globalConfig) :
+                _name(name),
+                _version(version),
+                _globalConfig(globalConfig)
+{
+    // Process log topics
+    char *argv[2] =
+    { (char *) "-plcLog", const_cast<char*>(logTopics.c_str()) };
+
+    // Get singleton instance
+    _silecsService = Silecs::Service::getInstance(2, argv);
+}
+
+void DeployUnit::deleteInstance()
+{
+    if (_instance != NULL)
+    {
+        delete _instance;
+        _instance = NULL;
+    }
+}
+
+const std::string& DeployUnit::getName() const
+{
+    return _name;
+}
+
+const std::string& DeployUnit::getVersion() const
+{
+    return _version;
+}
+
+Silecs::Service* DeployUnit::getService() const
+{
+    return _silecsService;
+}
+
+DeployConfig& DeployUnit::getGlobalConfig()
+{
+    return _globalConfig;
+}
+
+void DeployUnit::setGlobalConfig(DeployConfig& globalConfig)
+{
+    _globalConfig = globalConfig;
+}
+
+DeployUnit::~DeployUnit()
+{
+}
+
+}
+ //namespace SilecsWrapper
diff --git a/silecs-communication-cpp/src/silecs-communication/wrapper/DeployUnit.h b/silecs-communication-cpp/src/silecs-communication/wrapper/DeployUnit.h
new file mode 100644
index 0000000000000000000000000000000000000000..290253618f158d662733d85c48eaf5286b74079f
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/wrapper/DeployUnit.h
@@ -0,0 +1,72 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef SILECSWRAPER_DEPLOY_UNIT_H_
+#define SILECSWRAPER_DEPLOY_UNIT_H_
+
+#include <silecs-communication/interface/core/SilecsService.h>
+
+#include <string>
+
+namespace SilecsWrapper
+{
+
+    class DeployConfig
+    {
+    public:
+        DeployConfig();
+        DeployConfig(bool automaticConnect);
+        bool getAutomaticConnect() const;
+        void setAutomaticConnect(bool automaticConnect);
+
+    private:
+        bool _automaticConnect;
+
+    };
+
+    class DeployUnit
+    {
+    public:
+    DeployUnit(const std::string& name, const std::string& version, const std::string& logTopics,
+            const DeployConfig& globalConfig);
+        virtual ~DeployUnit();
+
+        void deleteInstance();
+
+        const std::string& getName() const;
+        const std::string& getVersion() const;
+        Silecs::Service* getService() const;
+    DeployConfig& getGlobalConfig();
+
+        void setGlobalConfig(DeployConfig& globalConfig);
+
+    protected:
+        const std::string _name;
+        const std::string _version;
+    DeployConfig _globalConfig;
+        Silecs::Service* _silecsService;
+        //singleton instance
+        static DeployUnit* _instance;
+
+    private:
+        // Non copyable
+        DeployUnit(const DeployUnit& other);
+        DeployUnit& operator=(const DeployUnit&);
+
+    };
+
+} //namespace SilecsWrapper
+
+#endif
diff --git a/silecs-communication-cpp/src/silecs-communication/wrapper/Design.cpp b/silecs-communication-cpp/src/silecs-communication/wrapper/Design.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..415b346f1d622f645e5387fe07fa5dccaf9db43c
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/wrapper/Design.cpp
@@ -0,0 +1,77 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-communication/wrapper/DeployUnit.h>
+#include <silecs-communication/wrapper/Design.h>
+
+namespace SilecsWrapper
+{
+
+Design::Design(const std::string& name, const std::string& version, DeployUnit *deployUnit) :
+                _name(name),
+                _version(version),
+                _deployUnit(deployUnit)
+{
+    _silecsCluster = _deployUnit->getService()->getCluster(_name, _version);
+}
+
+Design::~Design()
+{
+
+}
+
+const std::string& Design::getName() const
+{
+    return _name;
+}
+
+const std::string& Design::getVersion() const
+{
+    return _version;
+}
+
+Silecs::Cluster* Design::getSilecsCluster() const
+{
+    return _silecsCluster;
+}
+
+DeployUnit* Design::getDeployUnit() const
+{
+    return _deployUnit;
+}
+
+void Design::setConfiguration(const DesignConfig& configuration)
+{
+    Silecs::plcMapType plcMap = _silecsCluster->getPLCMap();
+    Silecs::plcMapType::iterator plcMapIter;
+    for (plcMapIter = plcMap.begin(); plcMapIter != plcMap.end(); ++plcMapIter)
+    {
+        //if (plcMapIter->second->isConnected({*connectNow = *}false))
+        if (plcMapIter->second->isEnabled())
+        {
+            //at least one PLC is already enabled (PLC object created). Does not make sense to set configuration after.
+            throw Silecs::SilecsException(__FILE__, __LINE__, Silecs::COMM_ALREADY_ENABLED,
+                    std::string("Design configuration must be set before instantiating any controller! Disable the 'Automatic connect' flag of the deploy configuration if needed."));
+        }
+    }
+    _silecsCluster->configuration = configuration;
+}
+
+const DesignConfig& Design::getConfiguration()
+{
+    return _silecsCluster->configuration;
+}
+
+} //namespace SilecsWrapper
diff --git a/silecs-communication-cpp/src/silecs-communication/wrapper/Design.h b/silecs-communication-cpp/src/silecs-communication/wrapper/Design.h
new file mode 100644
index 0000000000000000000000000000000000000000..ded6b7aa89cf3757e95aaad21f762c11a7e66639
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/wrapper/Design.h
@@ -0,0 +1,65 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef SILECSWRAPER_DESIGN_H_
+#define SILECSWRAPER_DESIGN_H_
+
+#include <silecs-communication/interface/equipment/SilecsCluster.h>
+#include <silecs-communication/wrapper/DeployUnit.h>
+
+#include <string>
+
+namespace SilecsWrapper
+{
+class DeployUnit;
+class Controller;
+
+typedef Silecs::ClusterConfig DesignConfig;
+
+class Design
+{
+public:
+    Design(const std::string& name, const std::string& version, DeployUnit *deployUnit);
+
+    const std::string& getName() const;
+
+    const std::string& getVersion() const;
+
+    Silecs::Cluster* getSilecsCluster() const;
+
+    DeployUnit* getDeployUnit() const;
+
+    void setConfiguration(const DesignConfig& configuration);
+
+    const DesignConfig& getConfiguration();
+
+    virtual ~Design();
+
+protected:
+    const std::string _name;
+    const std::string _version;
+    DeployUnit* _deployUnit;
+    Silecs::Cluster* _silecsCluster;
+    const DeployConfig _config;
+
+private:
+    // Non copyable
+    Design(const Design& other);
+    Design& operator=(const Design&);
+};
+
+} //namespace SilecsWrapper
+
+#endif
diff --git a/silecs-communication-cpp/src/silecs-communication/wrapper/Device.h b/silecs-communication-cpp/src/silecs-communication/wrapper/Device.h
new file mode 100644
index 0000000000000000000000000000000000000000..774cb712ae150d7fdb1dd8b5b2866c8b1019d03d
--- /dev/null
+++ b/silecs-communication-cpp/src/silecs-communication/wrapper/Device.h
@@ -0,0 +1,65 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef SILECSWRAPER_DEVICE_H_
+#define SILECSWRAPER_DEVICE_H_
+
+#include <silecs-communication/interface/core/SilecsService.h>
+#include <silecs-communication/interface/equipment/SilecsDevice.h>
+#include <silecs-communication/wrapper/Controller.h>
+
+#include <string>
+
+namespace SilecsWrapper
+{
+
+class Device
+{
+public:
+    Device(const std::string& label, Controller *controller) :
+                    _label(label),
+                    _controller(controller)
+    {
+        _silecsDevice = _controller->getSilecsPLC()->getDevice(label);
+    }
+
+    const std::string& getLabel() const
+    {
+        return _label;
+    }
+
+    Silecs::Device* getSilecsDevice()
+    {
+        return _silecsDevice;
+    }
+
+    virtual ~Device()
+    {
+    }
+
+protected:
+    std::string _label;
+    Controller* _controller;
+    Silecs::Device* _silecsDevice;
+
+private:
+    // Non copyable
+    Device(const Device& other);
+    Device& operator=(const Device&);
+};
+
+} //namespace SilecsWrapper
+
+#endif
diff --git a/silecs-diagnostic-cpp/.cproject b/silecs-diagnostic-cpp/.cproject
new file mode 100644
index 0000000000000000000000000000000000000000..bf123f3919aebd79b80d4e4d566e92edfaf72804
--- /dev/null
+++ b/silecs-diagnostic-cpp/.cproject
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1063983837">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1063983837" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1063983837" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug">
+					<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1063983837." name="/" resourcePath="">
+						<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.940654093" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
+							<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.530430318" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
+							<builder buildPath="${workspace_loc:/silecs-diagnostic-cpp}" id="cdt.managedbuild.target.gnu.builder.exe.debug.153658845" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
+							<tool id="cdt.managedbuild.tool.gnu.archiver.base.160739010" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+							<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1203858904" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
+								<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.894792522" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
+								<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.2108944082" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
+								<option id="gnu.cpp.compiler.option.include.paths.464457323" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/silecs-communication-cpp/build/include}&quot;"/>
+									<listOptionValue builtIn="false" value="/usr/lib64/qt4/mkspecs/linux-g++-64"/>
+									<listOptionValue builtIn="false" value="/usr/include/QtCore"/>
+									<listOptionValue builtIn="false" value="/usr/include/QtGui"/>
+									<listOptionValue builtIn="false" value="/acc/local/L866/cmw/cmw-rbac/6.1.0/include"/>
+								</option>
+								<option id="gnu.cpp.compiler.option.preprocessor.def.1628203586" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="WITH_RBAC=1"/>
+								</option>
+								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.2102143749" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.77525709" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
+								<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.2144307006" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/>
+								<option id="gnu.c.compiler.exe.debug.option.debugging.level.1892440763" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
+								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.2107742755" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.790245700" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/>
+							<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.257658351" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug">
+								<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.789035040" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.2055585130" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
+								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.2041912470" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+							</tool>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry excluding="src" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+		<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.1657185205">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.1657185205" moduleId="org.eclipse.cdt.core.settings" name="Release">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.1657185205" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
+					<folderInfo id="cdt.managedbuild.config.gnu.exe.release.1657185205." name="/" resourcePath="">
+						<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.560150810" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
+							<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.912642921" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
+							<builder buildPath="${workspace_loc:/silecs-diagnostic-cpp}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1380387983" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
+							<tool id="cdt.managedbuild.tool.gnu.archiver.base.778967991" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+							<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1778190641" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
+								<option id="gnu.cpp.compiler.exe.release.option.optimization.level.398288828" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
+								<option id="gnu.cpp.compiler.exe.release.option.debugging.level.1708164638" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
+								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.21478264" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.360129580" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
+								<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.1415471960" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/>
+								<option id="gnu.c.compiler.exe.release.option.debugging.level.2119369567" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
+								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1744674238" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.1223430146" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/>
+							<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.888395652" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release">
+								<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1851287355" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.41779867" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
+								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.727371022" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+							</tool>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry excluding="src" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="silecs-diagnostic-cpp.cdt.managedbuild.target.gnu.exe.694059999" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1657185205;cdt.managedbuild.config.gnu.exe.release.1657185205.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.360129580;cdt.managedbuild.tool.gnu.c.compiler.input.1744674238">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1657185205;cdt.managedbuild.config.gnu.exe.release.1657185205.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1778190641;cdt.managedbuild.tool.gnu.cpp.compiler.input.21478264">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1063983837;cdt.managedbuild.config.gnu.exe.debug.1063983837.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1203858904;cdt.managedbuild.tool.gnu.cpp.compiler.input.2102143749">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1063983837;cdt.managedbuild.config.gnu.exe.debug.1063983837.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.77525709;cdt.managedbuild.tool.gnu.c.compiler.input.2107742755">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/silecs-diagnostic-cpp"/>
+		</configuration>
+		<configuration configurationName="Release">
+			<resource resourceType="PROJECT" workspacePath="/silecs-diagnostic-cpp"/>
+		</configuration>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
+		<buildTargets>
+			<target name="clean LOCAL" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+				<buildCommand>make</buildCommand>
+				<buildArguments/>
+				<buildTarget>clean LOCAL=TRUE</buildTarget>
+				<stopOnError>true</stopOnError>
+				<useDefaultCommand>true</useDefaultCommand>
+				<runAllBuilders>true</runAllBuilders>
+			</target>
+			<target name="x86_64 LOCAL" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+				<buildCommand>make</buildCommand>
+				<buildArguments/>
+				<buildTarget>CPU=x86_64 -j1 LOCAL=TRUE</buildTarget>
+				<stopOnError>true</stopOnError>
+				<useDefaultCommand>true</useDefaultCommand>
+				<runAllBuilders>true</runAllBuilders>
+			</target>
+		</buildTargets>
+	</storageModule>
+</cproject>
diff --git a/silecs-diagnostic-cpp/.project b/silecs-diagnostic-cpp/.project
new file mode 100644
index 0000000000000000000000000000000000000000..ba5f221ca01401f50dbae4201c763e586e41274b
--- /dev/null
+++ b/silecs-diagnostic-cpp/.project
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>silecs-diagnostic-cpp</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.core.ccnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+</projectDescription>
diff --git a/silecs-diagnostic-cpp/LICENSE b/silecs-diagnostic-cpp/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..20d40b6bceca3a6c0237d7455ebf1820aeff3680
--- /dev/null
+++ b/silecs-diagnostic-cpp/LICENSE
@@ -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>.
\ No newline at end of file
diff --git a/silecs-diagnostic-cpp/Makefile b/silecs-diagnostic-cpp/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..6ce3be8a8aa6cd0b4b0c788f158ef90d7895a2b5
--- /dev/null
+++ b/silecs-diagnostic-cpp/Makefile
@@ -0,0 +1,63 @@
+# Copyright 2016 CERN and GSI
+#
+# 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/>.
+
+PROJECT = silecs
+PRODUCT = diagnostic
+VERSION = 1.0.2
+
+COMMON_MAKE_PATH ?= /opt/cern/buildsystem/generic/2.8.20
+
+# product configuration
+BIN_NAME = $(PROJECT)-$(PRODUCT)
+DBG = false
+
+#DEFINES = -DWITH_RBAC -D_REENTRANT -DQT_NO_DEBUG_OUTPUT -DQT_NO_WARNING_OUTPUT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED
+DEFINES = -D_REENTRANT -DQT_NO_DEBUG_OUTPUT -DQT_NO_WARNING_OUTPUT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED
+COMPILER_FLAGS = -O2 -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -mtune=generic $(DEFINES)
+LINKER_FLAGS = -Wl,-O1
+
+# list Qt generated files
+EXTRA_HEADERS = generated/ui_diagnostictoolmainview.h\
+ generated/ui_displayarraydialog.h\
+ generated/ui_logindialog.h
+
+EXTRA_SRCS = generated/qrc_images.cpp\
+ generated/moc_diagnostictoolmainview.cpp\
+ generated/moc_displayarraydialog.cpp\
+ generated/moc_logindialog.cpp\
+ generated/moc_stderrredirect.cpp
+
+# Include the generic make file
+include $(COMMON_MAKE_PATH)/Make.generic
+
+QT_RCC = /usr/bin/rcc
+QT_UIC = /usr/bin/uic-qt4
+QT_MOC = /usr/bin/moc-qt4
+
+# rules to generate Qt files
+before_compile::
+	$(QT_RCC) -name images src/silecs-diagnostic/resources/images.qrc -o src/silecs-diagnostic/generated/qrc_images.cpp
+	
+	$(QT_UIC) src/silecs-diagnostic/resources/gui/diagnostictoolmainview.ui -o src/silecs-diagnostic/generated/ui_diagnostictoolmainview.h
+	$(QT_UIC) src/silecs-diagnostic/resources/gui/displayarraydialog.ui -o src/silecs-diagnostic/generated/ui_displayarraydialog.h
+	$(QT_UIC) src/silecs-diagnostic/resources/gui/logindialog.ui -o src/silecs-diagnostic/generated/ui_logindialog.h
+	
+	$(QT_MOC) $(DEFINES) $(DEPENDENT_COMPILER_OPTIONS) src/silecs-diagnostic/diagnostictoolmainview.h -o src/silecs-diagnostic/generated/moc_diagnostictoolmainview.cpp
+	$(QT_MOC) $(DEFINES) $(DEPENDENT_COMPILER_OPTIONS) src/silecs-diagnostic/displayarraydialog.h -o src/silecs-diagnostic/generated/moc_displayarraydialog.cpp
+	$(QT_MOC) $(DEFINES) $(DEPENDENT_COMPILER_OPTIONS) src/silecs-diagnostic/logindialog.h -o src/silecs-diagnostic/generated/moc_logindialog.cpp
+	$(QT_MOC) $(DEFINES) $(DEPENDENT_COMPILER_OPTIONS) src/silecs-diagnostic/stderrredirect.h -o src/silecs-diagnostic/generated/moc_stderrredirect.cpp
+
+after_clean::
+	rm -f src/silecs-diagnostic/generated/*
\ No newline at end of file
diff --git a/silecs-diagnostic-cpp/Makefile.dep b/silecs-diagnostic-cpp/Makefile.dep
new file mode 100644
index 0000000000000000000000000000000000000000..7454b8d53b310e3487f549aed18b2d6868a7813b
--- /dev/null
+++ b/silecs-diagnostic-cpp/Makefile.dep
@@ -0,0 +1,27 @@
+BOOST_VERSION ?= 1.54.0
+RBAC_VERSION ?= 6.1.0
+SILECS_COMM_VERSION = 1.0.2
+
+BOOST_HOME ?= /acc/local/$(CPU)/3rdparty/boost/$(BOOST_VERSION)
+RBACK_HOME ?= /acc/local/$(CPU)/cmw/cmw-rbac/$(RBAC_VERSION)
+
+SILECS_COMM_HOME ?= ../silecs-communication-cpp/build
+
+LIBXML_PATH  	= /usr/include/libxml2/
+
+SNAP7_BASE = ../snap7/snap7-full
+
+DEPENDENT_COMPILER_OPTIONS += -I$(RBACK_HOME)/include
+DEPENDENT_COMPILER_OPTIONS += -I$(SILECS_COMM_HOME)/include
+DEPENDENT_COMPILER_OPTIONS += -I$(LIBXML_PATH)
+DEPENDENT_COMPILER_OPTIONS += -I$(BOOST_HOME)/include
+DEPENDENT_COMPILER_OPTIONS += -I/usr/lib64/qt4/mkspecs/linux-g++-64
+DEPENDENT_COMPILER_OPTIONS += -I/usr/include/QtCore
+DEPENDENT_COMPILER_OPTIONS += -I/usr/include/QtGui
+ 
+DEPENDENT_LINKER_OPTIONS += -L$(RBACK_HOME)/lib
+DEPENDENT_LINKER_OPTIONS += -L$(SILECS_COMM_HOME)/lib/$(CPU)
+DEPENDENT_LINKER_OPTIONS += -L$(SNAP7_BASE)/build/bin/$(CPU)-linux -lsnap7
+DEPENDENT_LINKER_OPTIONS += -L/usr/lib64 -lxml2
+DEPENDENT_LINKER_OPTIONS += -lsilecs-comm
+DEPENDENT_LINKER_OPTIONS += -lstdc++ -lxml2 -lcurl -lQtGui -lQtCore
diff --git a/silecs-diagnostic-cpp/README.md b/silecs-diagnostic-cpp/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..f16ec42f56d99659d2715efa7062669e37d73ac1
--- /dev/null
+++ b/silecs-diagnostic-cpp/README.md
@@ -0,0 +1,19 @@
+# silecs-codegen
+
+This component of the SILECS PLC-framework allows easy visible access to PLC variables for existing silecs-projects by making use of the package silecs-communication-cpp
+
+## Getting Started
+
+Please check the lab-specific SILECS-Wikis for more information:
+
+[CERN SILECS Wiki Page][CERN_Wiki]
+
+[GSI SILECS Wiki Page][GSI_Wiki]
+
+## License
+
+Licensed under the GNU GENERAL PUBLIC LICENSE Version 3. See the [LICENSE file][license] for details.
+
+[license]: LICENSE
+[CERN_Wiki]: https://wikis.cern.ch/display/SIL/SILECs+Home
+[GSI_Wiki]: https://www-acc.gsi.de/wiki/Frontend/SILECS
\ No newline at end of file
diff --git a/silecs-diagnostic-cpp/SILECS.pro b/silecs-diagnostic-cpp/SILECS.pro
new file mode 100644
index 0000000000000000000000000000000000000000..789134104bf4937da44eda0207ee8701fd1f0b75
--- /dev/null
+++ b/silecs-diagnostic-cpp/SILECS.pro
@@ -0,0 +1,106 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2011-09-27T14:25:35
+#
+#-------------------------------------------------
+
+QT       += core gui
+TEMPLATE = app
+SOURCES += src/silecs-diagnostic/*.cpp
+HEADERS += src/silecs-diagnostic/*.h
+FORMS   += src/silecs-diagnostic/resources/gui/diagnostictoolmainview.ui \
+           src/silecs-diagnostic/resources/gui/displayarraydialog.ui \
+           src/silecs-diagnostic/resources/gui/logindialog.ui
+
+INCLUDEPATH += src/         								# Source directory to be included
+RESOURCES   += src/silecs-diagnostic/resources/images.qrc   # Resource file
+DESTDIR     =  bin          								# Target file directory
+OBJECTS_DIR =  build        								# Intermediate object files directory
+MOC_DIR     =  build        								# Intermediate moc files directory
+
+UI_DIR      =  build        								# Store ui generated source file with other headers
+INCLUDEPATH += build/       								# Build includes the header for the gui
+
+# Disable debugger
+DEFINES     += QT_NO_DEBUG_OUTPUT QT_NO_WARNING_OUTPUT
+
+# Enable console
+CONFIG += console
+
+# Define RBAC support
+#QMAKE_CXXFLAGS += -DWITH_RBAC
+
+#Settings
+CPU = L866
+SILECS_VERSION = 1.m.p
+CONFIG += SILECSLOCAL
+
+
+#======================================================
+#------------------TARGET------------------------------
+#======================================================
+equals( CPU, L865 ){
+    TARGET = silecs-diagnostic-32
+} else {
+    TARGET = silecs-diagnostic-64
+}
+
+#======================================================
+#------------------LIBRARIES---------------------------
+#======================================================
+#RBAC Library
+#BOOST_VERSION = 1.54.0
+#RBAC_VERSION = 6.1.0
+#RBAC_HOME = /acc/local/$${CPU}/cmw/cmw-rbac/$${RBAC_VERSION}
+#BOOST_HOME = /acc/local/$${CPU}/3rdparty/boost/$${BOOST_VERSION}
+
+#DEPENDENT_COMPILER_OPTIONS = $${RBAC_HOME}/include \
+#        $${BOOST_HOME}/include
+
+#DEPENDENT_LINKER_OPTIONS = $${RBAC_HOME}/lib/libcmw-rbac.a \
+#        $${RBAC_HOME}/lib/libcmw-serializer.a \
+#        $${RBAC_HOME}/lib/libcmw-log.a \
+#        $${RBAC_HOME}/lib/libcmw-util.a \
+#        $${BOOST_HOME}/lib/libboost_1_54_0_thread.a \
+#        $${BOOST_HOME}/lib/libboost_1_54_0_system.a \
+#        $${BOOST_HOME}/lib/libboost_1_54_0_filesystem.a
+
+LIBS            += -L/usr/lib64 $${DEPENDENT_LINKER_OPTIONS} -lcurl
+INCLUDEPATH     += $${DEPENDENT_COMPILER_OPTIONS}
+DEPENDPATH      += $${DEPENDENT_LINKER_OPTIONS}
+
+#-------SILECS Operational Library-------
+SILECSLOCAL{
+    SILECS_HOME = ../silecs-communication-cpp/build
+    message("linking with local silecs library")
+} else {
+    SILECS_HOME = /acc/local/$${CPU}/silecs/$${SILECS_VERSION}/library/
+    message("linking with operational silecs library")
+}
+
+SILECS_LIBS      = $${SILECS_HOME}/lib/$${CPU} -lsilecs-comm
+
+LIBS            += -L$${SILECS_LIBS}
+INCLUDEPATH     += $${SILECS_HOME}/include/
+DEPENDPATH      += $${SILECS_HOME}/include/
+
+#-------Lib XML 2-------
+XML2_HOME       = /usr/lib/
+XML2_LIBS       = $${XML2_HOME} -lxml2
+XML2_INCLUDES   = /usr/include/libxml2
+LIBS            += -L$${XML2_LIBS}
+INCLUDEPATH     += $${XML2_INCLUDES}
+DEPENDPATH      += $${XML2_INCLUDES}
+
+#-------CNV-------
+#CNV_HOME        = /acc/sys/$${CPU}/usr/local/natinst/ninetv
+CNV_PATH		= /home/sd/rhaseitl/lnx/workspace.luna/CNV/ninetv
+CNV_INC         = $${CNV_HOME}/include
+equals( CPU, L865 ){
+    CNV_LIBS    = $${CNV_HOME}/lib -lstdc++ -lninetv -llkdynam -llkrealt -llksec -llksock
+} else {
+    CNV_LIBS    = $${CNV_HOME}/lib64 -lstdc++ -lninetv -llkdynam -llkrealt -llksec -llksock -llkbrow
+}
+LIBS            += -L$${CNV_LIBS}
+INCLUDEPATH     += $${CNV_INC}
+DEPENDPATH      += $${CNV_INC}
diff --git a/silecs-diagnostic-cpp/SILECS.pro.user b/silecs-diagnostic-cpp/SILECS.pro.user
new file mode 100644
index 0000000000000000000000000000000000000000..485219cbc20b34239cf195060b2d41da658b13fe
--- /dev/null
+++ b/silecs-diagnostic-cpp/SILECS.pro.user
@@ -0,0 +1,434 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QtCreatorProject>
+<!-- Written by Qt Creator 2.5.2, 2015-03-11T11:36:51. -->
+<qtcreator>
+ <data>
+  <variable>ProjectExplorer.Project.ActiveTarget</variable>
+  <value type="int">0</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.EditorSettings</variable>
+  <valuemap type="QVariantMap">
+   <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
+   <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
+   <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
+    <value type="QString" key="language">Cpp</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QString" key="CurrentPreferences">CppGlobal</value>
+    </valuemap>
+   </valuemap>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+    <value type="QString" key="language">QmlJS</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QString" key="CurrentPreferences">QmlJSGlobal</value>
+    </valuemap>
+   </valuemap>
+   <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
+   <value type="QByteArray" key="EditorConfiguration.Codec">System</value>
+   <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
+   <value type="int" key="EditorConfiguration.IndentSize">4</value>
+   <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
+   <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
+   <value type="int" key="EditorConfiguration.PaddingMode">1</value>
+   <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
+   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
+   <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
+   <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
+   <value type="int" key="EditorConfiguration.TabSize">8</value>
+   <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
+   <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
+   <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
+   <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
+   <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
+   <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.PluginSettings</variable>
+  <valuemap type="QVariantMap"/>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Target.0</variable>
+  <valuemap type="QVariantMap">
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Target.DesktopTarget</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+    <value type="QString" key="ProjectExplorer.BuildCOnfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:{4c7374d2-29fb-477e-9f85-559f725c99c9}</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">false</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 4.6.2 (System) Release</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory">/nfs/cs-ccr-nfsdev/vol1/u1/smagnoni/jython/workspace/IEPLC-4/branches/IEPLC-4/tools/app/IEPLCDiagnosticToolRBAC6</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId">4</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">false</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+    <value type="QString" key="ProjectExplorer.BuildCOnfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:{4c7374d2-29fb-477e-9f85-559f725c99c9}</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">false</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 4.6.2 (System) Release2</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory">/nfs/cs-ccr-nfsdev/vol1/u1/smagnoni/jython/workspace/IEPLC-4/branches/IEPLC-4/tools/app/IEPLCDiagnosticToolRBAC6</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId">4</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">false</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">No deployment</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+    <value type="bool" key="Analyzer.Project.UseGlobal">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">SILECS</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4RunConfiguration.BaseEnvironmentBase">2</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">SILECS.pro</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">true</value>
+    <valuelist type="QVariantList" key="Qt4ProjectManager.Qt4RunConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">true</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Target.1</variable>
+  <valuemap type="QVariantMap">
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Embedded Linux</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Embedded Linux</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.EmbeddedLinuxTarget</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+    <value type="QString" key="ProjectExplorer.BuildCOnfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:{4c7374d2-29fb-477e-9f85-559f725c99c9}</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">false</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 4.6.2 (System) Release</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory">/nfs/cs-ccr-nfsdev/vol1/u1/smagnoni/jython/workspace/IEPLC-4/branches/IEPLC-4/tools/app/IEPLCDiagnosticToolRBAC6</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId">4</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">false</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+    <value type="QString" key="ProjectExplorer.BuildCOnfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:{4c7374d2-29fb-477e-9f85-559f725c99c9}</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">false</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 4.6.2 (System) Release2</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory">/nfs/cs-ccr-nfsdev/vol1/u1/smagnoni/jython/workspace/IEPLC-4/branches/IEPLC-4/tools/app/IEPLCDiagnosticToolRBAC6</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId">4</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">false</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Upload files via SFTP</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.DirectUploadStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployedFiles"/>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployedHosts"/>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployedRemotePaths"/>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployedSysroots"/>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployedTimes"/>
+      <value type="bool" key="RemoteLinux.GenericDirectUploadStep.Incremental">true</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy to Remote Linux Host</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">DeployToGenericLinux</value>
+    <value type="qulonglong" key="Qt4ProjectManager.MaemoRunConfiguration.DeviceId">0</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+    <value type="bool" key="Analyzer.Project.UseGlobal">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">SILECS (on Remote Device)</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinuxRunConfiguration</value>
+    <value type="QString" key="Qt4ProjectManager.MaemoRunConfiguration.Arguments"></value>
+    <value type="int" key="Qt4ProjectManager.MaemoRunConfiguration.BaseEnvironmentBase">1</value>
+    <value type="QString" key="Qt4ProjectManager.MaemoRunConfiguration.ProFile">SILECS.pro</value>
+    <valuelist type="QVariantList" key="Qt4ProjectManager.MaemoRunConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="RemoteLinux.RunConfig.AlternateRemoteExecutable"></value>
+    <value type="bool" key="RemoteLinux.RunConfig.UseAlternateRemoteExecutable">false</value>
+    <value type="QString" key="RemoteLinux.RunConfig.WorkingDirectory"></value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">true</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.TargetCount</variable>
+  <value type="int">2</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Updater.EnvironmentId</variable>
+  <value type="QString">{44ef3bd6-a242-4916-ba41-2b32f74f7189}</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
+  <value type="int">11</value>
+ </data>
+</qtcreator>
diff --git a/silecs-diagnostic-cpp/install.sh b/silecs-diagnostic-cpp/install.sh
new file mode 100755
index 0000000000000000000000000000000000000000..837fe86514b5eefcb9a86de6ad2d74af314815c4
--- /dev/null
+++ b/silecs-diagnostic-cpp/install.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+set -e
+
+INSTALL_DIR=$1
+
+SCRIPT=$(readlink -f "$0")
+SCRIPTPATH=$(dirname "$SCRIPT")     # path where this script is located in
+
+mkdir -p ${INSTALL_DIR}
+cp -r ${SCRIPTPATH}/build/bin ${INSTALL_DIR}
+cp -r ${SCRIPTPATH}/build/resources ${INSTALL_DIR}
\ No newline at end of file
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/constants.h b/silecs-diagnostic-cpp/src/silecs-diagnostic/constants.h
new file mode 100755
index 0000000000000000000000000000000000000000..f92c82aea9e6f511ef96c19124b084f50304b968
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/constants.h
@@ -0,0 +1,59 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef CONSTANTS_H
+#define CONSTANTS_H
+#include <string>
+#include <silecs-communication/interface/core/SilecsService.h>
+
+using namespace Silecs;
+
+/*
+ * CHANGE THE MAJOR HERE TO ADAPT THE TOOL WITH THE CURRENT VERSION
+ */
+const std::string MAJOR     = Service::getSemverMajor();
+const std::string MINOR     = Service::getSemverMinor();
+const std::string PATCH     = Service::getSemverPatch();
+
+/*
+ * Different string type
+ */
+const std::string CLUSTER_TYPE       = "CLUSTER";
+const std::string PLC_TYPE           = "PLC";
+const std::string DEVICE_TYPE        = "DEVICE";
+const std::string REGISTER_TYPE      = "REGISTER";
+
+/*
+* Different project path
+*/
+
+// SILECS HEADER
+const std::string HEADER_NAME            = "SilecsHeader";
+const std::string HEADER_VERSION         = "1.0.0";
+const std::string HEADER_DEVICE          = "0";
+const std::string HEADER_BLOCK           = "hdrBlk";
+const std::string HEADER_RELEASE_REG     = "_version";
+const std::string HEADER_OWNER_REG       = "_user";
+const std::string HEADER_DATE_REG        = "_date";
+const std::string HEADER_CHECKSUM_REG    = "_checksum";
+
+//splash screen time (in seconds)
+const unsigned long SPLASH_SCREEN_TIME  = 1;
+const int NUMBER_PASSWORD_ATTEMPTS      = 3;
+
+// max buffer lenght for PLC name
+const int MAX_BUFFER = 1024;
+
+#endif // CONSTANTS_H
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..6539eccba4058a911ab08b662c653a9dbdac1e2f
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.cpp
@@ -0,0 +1,1095 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-diagnostic/diagnostictoolmainview.h>
+#include <silecs-diagnostic/generated/ui_diagnostictoolmainview.h>
+#include <silecs-diagnostic/utils.h>
+
+#include <silecs-communication/interface/utility/XMLParser.h>
+
+#include <exception>
+extern silecsModule *mysilecs;
+extern std::string UserName;
+
+template <class T>bool from_string(T& t, const std::string& s, std::ios_base& (*f)(std::ios_base&))
+{
+    std::istringstream iss(s);
+    return !(iss >> f >> t).fail();
+}
+
+diagnosticToolMainView::diagnosticToolMainView(QWidget *parent) :
+    QMainWindow(parent),
+    ui(new Ui::diagnosticToolMainView)
+{
+    ui->setupUi(this);
+
+    this->redirector = NULL;
+    mysilecs = NULL;
+
+    ui->dbVersionLabel->setText("SILECS service: "+QString::fromStdString(MAJOR)+"."+QString::fromStdString(MINOR)+"."+QString::fromStdString(PATCH));
+
+    // Set tree widget coloumn and headers
+    ui->treeWidget->setColumnCount(3);
+    QStringList headers;
+    headers << "Resource name"<< "Block name" << "PLC Value" << "Local Value";
+    ui->treeWidget->setHeaderLabels(headers);
+
+    // Create context menu to let the user the posibility of cleaning the console
+    ui->console->setReadOnly(true);
+    ui->InformationMessage->setReadOnly(true);
+    connect(ui->console, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(ctxMenu(const QPoint &)));
+
+    //set vertical/horizontal splitter
+    ui->verticalSplitter->setStretchFactor(1,1);
+    ui->verticalSplitter->setStretchFactor(0,0);
+}
+
+diagnosticToolMainView::~diagnosticToolMainView()
+{
+    // If closing application without closing cluster
+    if(redirector!=NULL) delete redirector;
+
+    delete ui;
+}
+
+std::string diagnosticToolMainView::generateLogTopics()
+{
+    // generate string of log parameters
+    std::ostringstream logTopics;
+    if(ui->checkERROR->isChecked()) logTopics << "ERROR";
+    if(ui->checkDEBUG->isChecked()) logTopics << ",DEBUG";
+    if(ui->checkSETUP->isChecked()) logTopics << ",SETUP";
+    if(ui->checkALLOC->isChecked()) logTopics << ",ALLOC";
+    if(ui->checkLOCK->isChecked())  logTopics << ",LOCK";
+    if(ui->checkCOMM->isChecked())  logTopics << ",COMM";
+    if(ui->checkSEND->isChecked())  logTopics << ",SEND";
+    if(ui->checkRECV->isChecked())  logTopics << ",RECV";
+    if(ui->checkDATA->isChecked())  logTopics << ",DATA";
+    if(ui->checkDIAG->isChecked())  logTopics << ",DIAG";
+    return logTopics.str();
+}
+
+void diagnosticToolMainView::resetGUI()
+{
+	try
+	{
+		//Stop periodic receiving if any
+		if(ui->periodicReceiveButton->isChecked()==true)
+		{
+			ui->periodicReceiveButton->setChecked(false);
+			Utils::logInfo(ui->console,"Monitoring was stopped due to cluster closure.");
+		}
+		ui->sendButton->setEnabled(false);
+		ui->receiveButton->setEnabled(false);
+		ui->periodicReceiveButton->setEnabled(false);
+		ui->copyButton->setEnabled(false);
+		//Clear the tree
+		ui->treeWidget->clear();
+
+		ui->sendComboBox->clear();
+		ui->receiveComboBox->clear();
+		ui->copyComboBox->clear();
+		// disable connect and disconnect
+		ui->connectButton->setEnabled(false);
+		ui->disconnectButton->setEnabled(false);
+
+		if(mysilecs!=NULL)
+		{
+		    delete mysilecs;
+		    mysilecs = NULL;
+		}
+
+		if(redirector!=NULL)
+		{
+		    delete redirector;
+		    redirector = NULL;
+		}
+	}
+    catch(std::string *str)
+    {
+        Utils::logError(ui->console,QString::fromStdString(*str));
+    }
+    catch(std::exception& ex)
+    {
+        Utils::logError(ui->console,QString::fromStdString(ex.what()));
+    }
+	catch(...)
+	{
+		Utils::logError(ui->console,"Unexpected error while reseting GUI. Please notify SILECS support");
+	}
+}
+
+
+void diagnosticToolMainView::loadFiles()
+{
+	resetGUI();
+    try
+    {
+        this->redirector = new StdErrRedirect(ui->console);
+        mysilecs = new silecsModule(generateLogTopics(), ui->console);
+
+        ui->treeWidget->clear();
+        Item * root = mysilecs->generateTree(designName.toStdString(),deployFile.toStdString());
+
+        if(root == NULL)
+        {
+            Utils::logError(ui->console,"Error while opening the design/deploy");
+        }
+        else
+        {
+            ui->treeWidget->addTopLevelItem(root);
+            /*
+             * Create Block List for combo boxes
+             */
+            Item* topLevelItem = dynamic_cast<Item*>(ui->treeWidget->topLevelItem(0));
+            Silecs::Cluster* cluster = (Silecs::Cluster*)topLevelItem->getLinkedObject();
+
+            std::string writeBlockList = cluster->getBlockList(Output)+" "+cluster->getBlockList(InOut);
+
+            istringstream blockListSplitted(writeBlockList);
+            Utils::logInfo(ui->console,"[Info:] - " + QString::fromStdString(writeBlockList));
+            do
+            {
+                std::string blockName;
+                blockListSplitted >> blockName;
+                // avoid last empty block
+                if(!blockName.compare("")) break;
+
+                ui->sendComboBox->addItem(QString::fromStdString(blockName));
+            }while(blockListSplitted);
+
+            // Receive combo box
+            std::string readBlockList = cluster->getBlockList(Input)+" "+cluster->getBlockList(InOut);
+            istringstream blockListSplitted2(readBlockList);
+            Utils::logInfo(ui->console,QString::fromStdString(readBlockList));
+            do
+            {
+                std::string blockName;
+                blockListSplitted2 >> blockName;
+                // avoid last empty block
+                if(!blockName.compare("")) break;
+
+                ui->receiveComboBox->addItem(QString::fromStdString(blockName));
+            }while(blockListSplitted2);
+
+            // Send combo box
+            std::string copyBlockList = cluster->getBlockList(InOut);
+            istringstream blockListSplitted3(copyBlockList);
+            Utils::logInfo(ui->console, QString::fromStdString(copyBlockList));
+            do
+            {
+                std::string blockName;
+                blockListSplitted3 >> blockName;
+                // avoid last empty block
+                if(!blockName.compare("")) break;
+
+                ui->copyComboBox->addItem(QString::fromStdString(blockName));
+            }while(blockListSplitted3);
+
+            // Disable opening button
+            // close must be pressed before opening again
+            //GSI-Hack - file dialog
+            //ui->openButton->setEnabled(false);
+
+
+            //ui->closeButton->setEnabled(true);
+
+        }
+    }
+    catch(std::string *str)
+    {
+        Utils::logError(ui->console,QString::fromStdString(*str));
+    }
+    catch(std::exception& ex)
+    {
+        Utils::logError(ui->console,QString::fromStdString(ex.what()));
+    }
+    catch (...) //catch any exception
+    {
+    	Utils::logError(ui->console,"Error while opening the specified Class. Please contact SILECS support");
+    }
+}
+
+void diagnosticToolMainView::on_connectButton_clicked()
+{
+    // Connect button
+
+    // Get current Item
+    Item *currentItem = dynamic_cast<Item*>(ui->treeWidget->currentItem());
+
+    // Cast the linked object PLC type
+    Silecs::PLC* plc = (Silecs::PLC*)(currentItem->getLinkedObject());
+
+	try
+	{
+		plc->connect(Silecs::MASTER_SYNCHRO,true,ui->compareChecksums->isChecked());
+		if(!plc->isConnected())
+		{
+			Utils::logError(ui->console,"Connection to PLC failed.");
+			return;
+		}
+		mysilecs->updatePLCItem(currentItem,false);
+		if(!plc->isConnected())
+		{
+			Utils::logError(ui->console,"Updating PLC-items failed.");
+			return;
+		}
+
+		// disable connect button
+		ui->connectButton->setEnabled(false);
+		ui->disconnectButton->setEnabled(true);
+
+		// enable send and receive
+		ui->sendBox->setEnabled(true);
+		ui->receiveBox->setEnabled(true);
+		ui->copyBox->setEnabled(true);
+
+		//refresh console
+		Utils::displayPLCInformation(plc,ui->InformationMessage);
+
+		//highlight PLC background in green
+		ui->treeWidget->currentItem()->setBackgroundColor(0,Qt::green);
+
+		// Increment number of connected PLC
+		mysilecs->counterConnectedPLC++;
+	}
+    catch(std::string *str)
+    {
+        Utils::logError(ui->console,QString::fromStdString(*str));
+    }
+    catch(std::exception& ex)
+    {
+        Utils::logError(ui->console,QString::fromStdString(ex.what()));
+    }
+	catch(...)
+	{
+		Utils::logError(ui->console,"Unknown error while connecting to the selected PLC.");
+	}
+
+}
+
+void diagnosticToolMainView::on_disconnectButton_clicked()
+{
+    // Disconnect button
+    try
+    {
+        // Get current Item
+        Item *currentItem = dynamic_cast<Item*>(ui->treeWidget->currentItem());
+
+        // Cast the linked object PLC type
+        Silecs::PLC* plc = (Silecs::PLC*)(currentItem->getLinkedObject());
+
+        // Disconnect
+        plc->disconnect();
+
+        // disable disconnect button
+        ui->disconnectButton->setEnabled(false);
+        ui->connectButton->setEnabled(true);
+
+        // disable send and receive
+        ui->sendBox->setEnabled(false);
+        ui->receiveBox->setEnabled(false);
+        ui->copyBox->setEnabled(false);
+
+        // refresh console
+        Utils::displayPLCInformation(plc,ui->InformationMessage);
+
+        // remove green background
+        ui->treeWidget->currentItem()->setBackgroundColor(0,Qt::white);
+
+        // Decrement number of connected PLC
+        mysilecs->counterConnectedPLC--;
+        if(mysilecs->counterConnectedPLC==0)
+        {
+            // if there are no more plc connected stop monitoring
+            if(ui->periodicReceiveButton->isChecked()==true)
+            {
+                ui->periodicReceiveButton->setChecked(false);
+                Utils::logInfo(ui->console,"Monitoring was stopped because no more PLC are connected.");
+            }
+        }
+    }
+    catch(std::string *str)
+    {
+        Utils::logError(ui->console,QString::fromStdString(*str));
+    }
+    catch(std::exception& ex)
+    {
+        Utils::logError(ui->console,QString::fromStdString(ex.what()));
+    }
+    catch(...)
+    {
+        Utils::logError(ui->console,"Unknown Error while disconnecting to the selected PLC.");
+    }
+}
+
+void diagnosticToolMainView::on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
+{
+    (void)current; // to suppress unused warning
+    (void)previous; // to suppress unused warning
+    try
+    {
+        if(current == NULL)
+        {
+            qDebug()<< "Current item does not exist. probably the tree has bean cleared";
+            ui->InformationMessage->clear();
+            ui->treeWidget->resizeColumnToContents(0);
+            return;
+        }
+
+		Item *currentItem = dynamic_cast<Item*>(current);
+
+		/*
+		 * If the selected item is a Cluster
+		 */
+		if(!currentItem->whatsThis(0).compare(QString::fromStdString(CLUSTER_TYPE)))
+		{
+			qDebug() << "Cluster selected";
+			Utils::displayClusterInformation(((Silecs::Cluster*)(currentItem->getLinkedObject())),ui->InformationMessage);
+		}
+
+		/*
+		 * If the selected item is a PLC
+		 */
+		if(!currentItem->whatsThis(0).compare(QString::fromStdString(PLC_TYPE)))
+		{
+			qDebug() << "Plc selected";
+			Utils::displayPLCInformation(((Silecs::PLC*)(currentItem->getLinkedObject())),ui->InformationMessage);
+
+			bool connected = ((Silecs::PLC*)(currentItem->getLinkedObject()))->isConnected();
+			ui->connectButton->setEnabled(!connected);
+			ui->disconnectButton->setEnabled(connected);
+		}
+		else
+		{
+			ui->connectButton->setEnabled(false);
+			ui->disconnectButton->setEnabled(false);
+		}
+
+		/*
+		 * If the selected item is a device
+		 */
+		if(!currentItem->whatsThis(0).compare(QString::fromStdString(DEVICE_TYPE)))
+		{
+			qDebug() << "Device selected";
+			Utils::displayDeviceInformation(((Silecs::Device*)(currentItem->getLinkedObject())),ui->InformationMessage);
+
+			bool connected = ((Silecs::PLC*)dynamic_cast<Item*>(currentItem->parent())->getLinkedObject())->isConnected();
+
+			ui->sendBox->setEnabled(connected);
+			ui->receiveBox->setEnabled(connected);
+			ui->copyBox->setEnabled(connected);
+			ui->sendButton->setEnabled(connected);
+			ui->receiveButton->setEnabled(connected);
+			ui->copyButton->setEnabled(connected);
+			ui->periodicReceiveButton->setEnabled(connected);
+		}
+		else
+		{
+			ui->sendBox->setEnabled(false);
+			ui->receiveBox->setEnabled(false);
+			ui->copyBox->setEnabled(false);
+			ui->sendButton->setEnabled(false);
+			ui->receiveButton->setEnabled(false);
+			ui->copyButton->setEnabled(false);
+			ui->periodicReceiveButton->setEnabled(false);
+		}
+
+		/*
+		 * If the selected item is a register
+		 */
+		if(!currentItem->whatsThis(0).compare(QString::fromStdString(REGISTER_TYPE)))
+		{
+			qDebug() << "Register selected";
+			Utils::displayRegisterInformation(((Silecs::Register*)(currentItem->getLinkedObject())),ui->InformationMessage);
+
+			//bool connected = ((Silecs::PLC*)dynamic_cast<Item*>(currentItem->parent()->parent())->getLinkedObject())->isConnected();
+			Utils::displayRegisterValue((Silecs::Register*)(currentItem->getLinkedObject()),
+										ui->binValueLabel,
+										ui->HexValueLabel,
+										ui->DecValueLabel,
+										ui->asciiValueLabel);
+		}
+		else
+		{
+			ui->binValueLabel->setText("--Not relevant--");
+			ui->HexValueLabel->setText("--Not relevant--");
+			ui->DecValueLabel->setText("--Not relevant--");
+			ui->asciiValueLabel->setText("--Not relevant--");
+		}
+        // Automaticaly resize the coloumn with the item name
+        ui->treeWidget->resizeColumnToContents(0);
+    }
+    catch(std::string *str)
+    {
+        Utils::logError(ui->console,QString::fromStdString(*str));
+    }
+    catch(std::exception& ex)
+    {
+        Utils::logError(ui->console,QString::fromStdString(ex.what()));
+    }
+    catch(...)
+    {
+        Utils::logError(ui->console,"Unknown error in currentItemChanged. Please notify SILECS support");
+    }
+}
+
+std::vector<QString> diagnosticToolMainView::openArrayDialogBase(Silecs::Register* reg, std::vector<QString> dataVector, bool localData)
+{
+	DisplayArrayDialog arrayDialog;
+	arrayDialog.setDataVector(dataVector,localData,reg->getDimension2());
+	arrayDialog.setWindowTitle("Array View");
+	arrayDialog.setModal(true);
+	if(arrayDialog.exec()==1) // ok pressed
+	{
+		return arrayDialog.getDataVector();
+	}
+	return dataVector;
+}
+
+std::vector<QString> diagnosticToolMainView::open1DArrayDialog(Silecs::Register* reg, bool localData)
+{
+	std::vector<QString> dataVector;
+	for(unsigned long i=0;i<reg->getDimension1();i++)
+	{
+		if( localData )
+			dataVector.push_back(QString::fromStdString(reg->getOutputValAsString(i)));
+		else
+			dataVector.push_back(QString::fromStdString(reg->getInputValAsString(i)));
+	}
+
+	return openArrayDialogBase(reg, dataVector, localData);
+}
+
+std::vector<QString> diagnosticToolMainView::open2DArrayDialog(Silecs::Register* reg, bool localData)
+{
+	std::vector<QString> dataVector;
+	for(unsigned long i=0; i<reg->getDimension1(); i++)
+	{
+		for(unsigned long j=0; j<reg->getDimension2(); j++)
+		{
+			if( localData )
+				dataVector.push_back(QString::fromStdString(reg->getOutputValAsString(i,j)));
+			else
+				dataVector.push_back(QString::fromStdString(reg->getInputValAsString(i,j)));
+		}
+	}
+	return openArrayDialogBase(reg, dataVector, localData);
+}
+
+void diagnosticToolMainView::markItemNotEdiable(QTreeWidgetItem *item)
+{
+	item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
+    qDebug()<< "item marked as not editable";
+}
+
+void diagnosticToolMainView::on_treeWidget_doubleClicked(const QModelIndex &index)
+{
+    (void)index; // to suppress unused warning
+    try
+    {
+    	QTreeWidgetItem *itm = ui->treeWidget->currentItem();
+    	if( itm->whatsThis(0).toStdString().compare(REGISTER_TYPE) != 0 )
+    	{
+    		markItemNotEdiable(itm);
+            return;
+    	}
+        Item *registerItem = dynamic_cast<Item*>(itm);
+        Silecs::Register* reg = (Silecs::Register*)registerItem->getLinkedObject();
+
+        switch(ui->treeWidget->currentColumn())
+        {
+			case 2:// double click performed on 2th column (PLC value) --> open non-editable ArrayDialog for arrays
+				if(reg->getDimension2()<=1)  // scalar or 1d array (noting happens for scalar)
+				{
+					if(reg->getDimension1()<=1) //scalar
+					{
+						return;
+					}
+					open1DArrayDialog(reg,false);
+				}
+				else    // 2d array
+				{
+					open2DArrayDialog(reg,false);
+				}
+				markItemNotEdiable(itm);
+				return;
+			case 3:// double click performed on 3th column (local value)
+				if(!reg->hasOutputAccess() )// is READ only for silecs or is wrong column
+				{
+					markItemNotEdiable(itm);
+					return;
+				}
+				if(reg->getDimension2()<=1)  // scalar or 1d array
+				{
+					if(reg->getDimension1()<=1) //scalar
+					{
+			            itm->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsEditable);
+			        	return;
+					}
+					std::vector<QString> dataVector = open1DArrayDialog(reg,true);
+					mysilecs->setArrayRegValue(registerItem,&dataVector);
+				}
+				else    // 2d array
+				{
+					std::vector<QString> dataVector= open2DArrayDialog(reg,true);
+					mysilecs->setArrayRegValue(registerItem,&dataVector);
+				}
+				return;
+			default: // other columns are not editable
+				markItemNotEdiable(itm);
+				return;
+        }
+    }
+    catch(std::string *str)
+    {
+        Utils::logError(ui->console,QString::fromStdString(*str));
+    }
+    catch(std::exception& ex)
+    {
+        Utils::logError(ui->console,QString::fromStdString(ex.what()));
+    }
+    catch(...)
+    {
+        Utils::logError(ui->console,"Unknown error in treeWidget_doubleClicked. Please notify SILECS support");
+    }
+}
+
+void diagnosticToolMainView::on_sendButton_clicked()
+{
+    try{
+        Item *currentItem = dynamic_cast<Item*>(ui->treeWidget->currentItem());
+
+        /*
+         * If the selected item is a cluster
+         */
+        if(!currentItem->whatsThis(0).compare(QString::fromStdString(CLUSTER_TYPE)))
+        {
+            // Cast the linked object to cluster type
+            Silecs::Cluster* cluster = (Silecs::Cluster*)(currentItem->getLinkedObject());
+            int numberOfPLC = currentItem->childCount();
+
+            // Set all the PLC whithin the cluster
+            for(int i=0;i<numberOfPLC;i++)
+            {
+                int numberOfdevice = currentItem->childCount();
+                Item* plcItem = (Item*)currentItem->child(i);
+                // Set all the device whithin the PLC
+                for(int j=0;j<numberOfdevice;j++)
+                {
+                    Silecs::PLC* plc = (Silecs::PLC*)(plcItem->getLinkedObject());
+                    if (plc->isConnected())
+                        mysilecs->setScalarDataInDeviceFromItem((Item*)plcItem->child(i),ui->sendComboBox->currentText().toStdString());
+                }
+			}
+			try{
+				//send and mesure sending time
+				QTime mytimer;
+				mytimer.start();
+				cluster->send(ui->sendComboBox->currentText().toStdString());
+				logCommunicationSuccess(mytimer.elapsed());
+			}
+			catch(...)
+			{
+				qDebug()<<"Error while calling cluster.send()";
+				Utils::logError(ui->console,"Error while sending the block to the selected cluster.");
+			}
+        }
+
+        /*
+         * If the selected item is a plc
+         */
+        if(!currentItem->whatsThis(0).compare(QString::fromStdString(PLC_TYPE)))
+        {
+            // Cast the linked object to PLC type
+            Silecs::PLC* plc = (Silecs::PLC*)(currentItem->getLinkedObject());
+            int numberOfdevice = currentItem->childCount();
+
+            // Set all the device whithin the PLC
+            for(int i=0;i<numberOfdevice;i++)
+                mysilecs->setScalarDataInDeviceFromItem((Item*)currentItem->child(i),ui->sendComboBox->currentText().toStdString());
+            try{
+                //send and mesure sending time
+                QTime mytimer;
+                mytimer.start();
+                int ret = plc->send(ui->sendComboBox->currentText().toStdString());
+                if(ret != 0)
+                {
+                	Utils::logError(ui->console,QString::fromStdString("Error while receiving the block to the selected device"));
+                	return;
+                }
+                logCommunicationSuccess(mytimer.elapsed());
+            }
+            catch(...)
+            {
+                qDebug()<<"Error while calling plc.send()";
+                Utils::logError(ui->console,"Error while sending the block to the selected plc.");
+            }
+        }
+
+        /*
+         * If the selected item is a device
+         */
+        if(!currentItem->whatsThis(0).compare(QString::fromStdString(DEVICE_TYPE)))
+        {
+            try{
+                mysilecs->setScalarDataInDeviceFromItem(currentItem,ui->sendComboBox->currentText().toStdString());
+                Silecs::Device* device = (Silecs::Device*)(currentItem->getLinkedObject());
+
+                //send and mesure sending time
+                QTime mytimer;
+                mytimer.start();
+                int ret = device->send(ui->sendComboBox->currentText().toStdString());
+                if(ret != 0)
+                {
+                	Utils::logError(ui->console,QString::fromStdString("Error while receiving the block to the selected device"));
+                	return;
+                }
+                logCommunicationSuccess( mytimer.elapsed());
+            }
+            catch(...)
+            {
+                qDebug()<<"Error while calling plc.send()";
+                Utils::logError(ui->console,"Error while sending the block to the selected device.");
+            }
+        }
+    }
+    catch(std::string *str)
+    {
+        Utils::logError(ui->console,QString::fromStdString(*str));
+    }
+    catch(std::exception& ex)
+    {
+        Utils::logError(ui->console,QString::fromStdString(ex.what()));
+    }
+    catch(...)
+    {
+        Utils::logError(ui->console,"Unexpected error while sending. Please notify SILECS support");
+    }
+}
+
+void diagnosticToolMainView::on_receiveButton_clicked()
+{
+    // Receive Button
+    try{
+        Item *currentItem = dynamic_cast<Item*>(ui->treeWidget->currentItem());
+
+        // block to be received
+        std::string blockName = ui->receiveComboBox->currentText().toStdString();
+
+    	if( currentItem->whatsThis(0).toStdString().compare(DEVICE_TYPE) != 0 ) // actually this should not be possible at all
+    	{
+    		Utils::logError(ui->console,"Please select a device");
+    		return;
+    	}
+
+        this->receiveDevice(blockName,currentItem);
+    }
+    catch(std::string *str)
+    {
+        Utils::logError(ui->console,QString::fromStdString(*str));
+    }
+    catch(std::exception& ex)
+    {
+        Utils::logError(ui->console,QString::fromStdString(ex.what()));
+    }
+    catch(...)
+    {
+        Utils::logError(ui->console,"Unknown error while receiving. Please notify SILECS support");
+    }
+}
+
+
+void diagnosticToolMainView::on_classNameComboBox_currentIndexChanged(const QString &arg1)
+{
+	if( !deployFile.isEmpty() )
+	{
+		ui->DesignName->setText("");
+		designName = ui->classNameComboBox->currentText();
+		loadFiles();
+	}
+	return;
+}
+
+void diagnosticToolMainView::on_loadDeployButton_clicked()
+{
+	deployFile = QFileDialog::getOpenFileName(this, tr("Deploy to Open"), "" ,tr("Silecs Deploy Files (*.silecsdeploy)"));
+	if( !deployFile.isEmpty() )
+	{
+		ui->DeployName->setText(deployFile);
+		ui->DesignName->setText("pick a design");
+		fillClassNameComboBox();
+	}
+	return;
+}
+
+void diagnosticToolMainView::setDeployFile(QString file)
+{
+	deployFile = file;
+	ui->DeployName->setText(deployFile);
+	ui->DesignName->setText("pick a design");
+	fillClassNameComboBox();
+}
+
+void diagnosticToolMainView::fillClassNameComboBox()
+{
+	Utils::logInfo(ui->console,"Loading deploy file: " + deployFile);
+	XMLParser parserDeploy(deployFile.toStdString(),true);
+	boost::ptr_vector<ElementXML> classNodes = parserDeploy.getElementsFromXPath_throwIfEmpty("/SILECS-Deploy/Controller/SilecsDesign");
+	if(classNodes.size() == 0)
+	{
+		Utils::logError(ui->console,"No classes found for this Deploy");
+		return;
+	}
+	QStringList list;
+
+	boost::ptr_vector<ElementXML>::const_iterator classIter;
+	for(classIter = classNodes.begin(); classIter != classNodes.end(); classIter++)
+	{
+		QString className(classIter->getAttribute("silecs-design-name").c_str());
+		if(!list.contains(className))
+			list += className;
+	}
+	ui->classNameComboBox->clear();
+	ui->classNameComboBox->addItems(list);
+}
+
+void diagnosticToolMainView::ctxMenu(const QPoint &pos)
+{
+    QMenu *menu = new QMenu;
+    menu->addAction(tr("Clear information console"), this, SLOT(clearConsole_slot()));
+    menu->exec(ui->console->mapToGlobal(pos));
+}
+
+void diagnosticToolMainView::clearConsole_slot()
+{
+    ui->console->clear();
+}
+
+void diagnosticToolMainView::on_treeWidget_itemExpanded(QTreeWidgetItem *item)
+{
+    (void)item;// to supress unused warning
+    // Automaticaly resize the coloumn with the item name
+    ui->treeWidget->resizeColumnToContents(0);
+}
+
+void diagnosticToolMainView::logBlockReceived(std::string blockName, int elapsedTime)
+{
+	std::ostringstream message;
+	message << "Block '" << blockName << "' received successfully from the device in " <<  elapsedTime << " milliseconds";
+	Utils::logInfo(ui->console,message.str().c_str());
+}
+
+void diagnosticToolMainView::logCommunicationSuccess(int elapsedTime)
+{
+	std::ostringstream message;
+	message << "PLC communication successful. Elapsed time: " <<  elapsedTime << " milliseconds";
+	Utils::logInfo(ui->console,message.str().c_str());
+}
+
+
+void diagnosticToolMainView::receiveDevice(std::string blockName, Item* deviceItem)
+{
+    Silecs::Device *device = (Silecs::Device*)deviceItem->getLinkedObject();
+    qDebug() << "try to receive " << QString::fromStdString(blockName);
+    try{
+        //receive device and mesure sending time
+        QTime mytimer;
+        mytimer.start();
+        int ret = device->recv(blockName);
+        int elapsedTime = mytimer.elapsed();
+        if(ret != 0)
+        {
+        	Utils::logError(ui->console,QString::fromStdString("Error while receiving the block to the selected device"));
+        	return;
+        }
+        logBlockReceived(blockName, elapsedTime);
+    }
+    catch(std::string *str)
+    {
+        Utils::logError(ui->console,QString::fromStdString(*str));
+    }
+    catch(std::exception& ex)
+    {
+        Utils::logError(ui->console,QString::fromStdString(ex.what()));
+    }
+    catch (...)
+    {
+    	Utils::logError(ui->console,"unknown error in diagnosticToolMainView::receiveDevice");
+    }
+    mysilecs->updateDeviceItem(deviceItem,true);
+}
+
+void diagnosticToolMainView::periodicReceiveDevice()
+{
+    Silecs::Device *device = (Silecs::Device*)currentItemForPeriodicReceive->getLinkedObject();
+    qDebug()<< "try to receive "<< QString::fromStdString(blockNameForPeriodicReceive);
+    try{
+        //receive device and mesure sending time
+        QTime mytimer;
+        mytimer.start();
+        device->recv(blockNameForPeriodicReceive);
+        int elapsedTime = mytimer.elapsed();
+        logBlockReceived(blockNameForPeriodicReceive,elapsedTime);
+    }
+    catch(std::string *str)
+    {
+    	Utils::logError(ui->console,"error while receiving block: " + QString::fromStdString(blockNameForPeriodicReceive));
+        Utils::logError(ui->console,QString::fromStdString(*str));
+    }
+    catch(std::exception& ex)
+    {
+    	Utils::logError(ui->console,"error while receiving block: " + QString::fromStdString(blockNameForPeriodicReceive));
+        Utils::logError(ui->console,QString::fromStdString(ex.what()));
+    }
+    catch (...)
+    {
+    	Utils::logError(ui->console,"error while receiving block: " + QString::fromStdString(blockNameForPeriodicReceive));
+    	Utils::logError(ui->console,"unknown error in diagnosticToolMainView::periodicReceiveDevice");
+    }
+    mysilecs->updateDeviceItem(currentItemForPeriodicReceive,true);
+}
+
+void diagnosticToolMainView::on_periodicReceiveButton_toggled(bool checked)
+{
+    if(checked)
+    {
+        // receive periodic Button
+        try{
+            this->currentItemForPeriodicReceive = dynamic_cast<Item*>(ui->treeWidget->currentItem());
+
+            // block to be received
+            this->blockNameForPeriodicReceive = ui->receiveComboBox->currentText().toStdString();
+
+            periodicReceiveTimer = new QTimer(this);
+            /*
+                 * If the selected item is a cluster
+                 */
+            if(!currentItemForPeriodicReceive->whatsThis(0).compare(QString::fromStdString(CLUSTER_TYPE)))
+            {
+                connect(periodicReceiveTimer,SIGNAL(timeout()),SLOT(periodicReceiveCluster()));
+                ui->monitoringLabel->setText("<font color='blue'>"+ui->treeWidget->currentItem()->text(0)+"</font>");
+            }
+
+            /*
+                 * If the selected item is a plc
+                 */
+            if(!currentItemForPeriodicReceive->whatsThis(0).compare(QString::fromStdString(PLC_TYPE)))
+            {
+                connect(periodicReceiveTimer,SIGNAL(timeout()),SLOT(periodicReceivePLC()));
+                ui->monitoringLabel->setText("<font color='blue'>"+currentItemForPeriodicReceive->parent()->text(0)+"/"
+                                             +ui->treeWidget->currentItem()->text(0)+"</font>");
+            }
+
+            /*
+                 * If the selected item is a device
+                 */
+            if(!currentItemForPeriodicReceive->whatsThis(0).compare(QString::fromStdString(DEVICE_TYPE)))
+            {
+                connect(periodicReceiveTimer,SIGNAL(timeout()),SLOT(periodicReceiveDevice()));
+                ui->monitoringLabel->setText("<font color='blue'>"+currentItemForPeriodicReceive->parent()->parent()->text(0)+"/"
+                                             +currentItemForPeriodicReceive->parent()->text(0)+"/"
+                                             +ui->treeWidget->currentItem()->text(0)+"</font>");
+            }
+            periodicReceiveTimer->start((int)(ui->timeSpinBox->value()*1000));
+        }
+        catch(...)
+        {
+            Utils::logError(ui->console,"Unexpected error while setting up the timed operation.");
+            ui->periodicReceiveButton->setChecked(false);
+        }
+        ui->timeSpinBox->setEnabled(false);
+    }
+    else
+    {
+        // better checking if button was enabled because code is called as well
+        // when a cluster is closed
+        if(periodicReceiveTimer->isActive())
+            periodicReceiveTimer->stop();
+        delete periodicReceiveTimer;
+
+        //delete monitoring label text
+        ui->monitoringLabel->setText("");
+
+        ui->timeSpinBox->setEnabled(true);
+    }
+
+}
+
+void diagnosticToolMainView::on_copyButton_clicked()
+{
+    // copy input value to output Button
+
+    try{
+        std::string blockName = ui->copyComboBox->currentText().toStdString();
+
+        Item *currentItem = dynamic_cast<Item*>(ui->treeWidget->currentItem());
+
+        /*
+         * If the selected item is a cluster
+         */
+        if(!currentItem->whatsThis(0).compare(QString::fromStdString(CLUSTER_TYPE)))
+        {
+            Silecs::Cluster* cluster = (Silecs::Cluster*)(currentItem->getLinkedObject());
+            if(QMessageBox::question(this,"Copy input value to output ",
+                                     "You are trying to copy all the input value to the output values.\nThe copy will effect all the register of the block "+ui->copyComboBox->currentText()+" of all the connected PLC.\nDo you confirm this operation?",
+                                     QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes)
+            {
+                cluster->copyInToOut(blockName);
+                mysilecs->updateClusterItem(currentItem,false);
+            }
+        }
+
+        /*
+         * If the selected item is a plc
+         */
+        if(!currentItem->whatsThis(0).compare(QString::fromStdString(PLC_TYPE)))
+        {
+            Silecs::PLC* plc = (Silecs::PLC*)(currentItem->getLinkedObject());
+            if(QMessageBox::question(this,"Copy input value to output ",
+                                     "You are trying to copy all the input value to the output values.\nThe copy will effect all the register of the block "+ui->copyComboBox->currentText()+" in the PLC "+QString::fromStdString(plc->getName())+".\nDo you confirm this operation?",
+                                     QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes)
+            {
+                plc->copyInToOut(blockName);
+                mysilecs->updatePLCItem(currentItem,false);
+            }
+        }
+
+        /*
+         * If the selected item is a device
+         */
+        if(!currentItem->whatsThis(0).compare(QString::fromStdString(DEVICE_TYPE)))
+        {
+            Silecs::Device* device = (Silecs::Device*)(currentItem->getLinkedObject());
+            if(QMessageBox::question(this,"Copy input value to output ",
+                                     "You are trying to copy all the input value to the output values.\nThe copy will effect all the register of the block "+ui->copyComboBox->currentText()+" in the device "+QString::fromStdString(device->getLabel())+".\nDo you confirm this operation?",
+                                     QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes)
+            {
+                device->copyInToOut(blockName);
+                mysilecs->updateDeviceItem(currentItem,false);
+            }
+        }
+
+    }
+    catch(...)
+    {
+        Utils::logError(ui->console,"Unexpected error while trying to copy input value to output value.");
+    }
+}
+
+void diagnosticToolMainView::on_checkERROR_stateChanged(int arg1)
+{
+    (void) arg1;
+    qDebug()<<"checkERROR changed";
+    if(mysilecs != NULL)
+    {
+        mysilecs->setLogTopics(this->generateLogTopics());
+    }
+}
+void diagnosticToolMainView::on_checkDEBUG_stateChanged(int arg1)
+{
+    (void) arg1;
+    qDebug()<<"checkDEBUG changed";
+    if(mysilecs != NULL)
+    {
+        mysilecs->setLogTopics(this->generateLogTopics());
+        mysilecs->enableDebugLog();
+    }
+}
+
+void diagnosticToolMainView::on_checkSETUP_stateChanged(int arg1)
+{
+    (void) arg1;
+    qDebug()<<"checkSETUP changed";
+    if(mysilecs != NULL)
+    {
+        mysilecs->setLogTopics(this->generateLogTopics());
+    }
+}
+
+void diagnosticToolMainView::on_checkALLOC_stateChanged(int arg1)
+{
+    (void) arg1;
+    qDebug()<<"checkALLOC changed";
+    if(mysilecs != NULL)
+    {
+        mysilecs->setLogTopics(this->generateLogTopics());
+    }
+}
+
+void diagnosticToolMainView::on_checkLOCK_stateChanged(int arg1)
+{
+    (void) arg1;
+    qDebug()<<"checkLOCK changed";
+    if(mysilecs != NULL)
+    {
+        mysilecs->setLogTopics(this->generateLogTopics());
+    }
+}
+
+void diagnosticToolMainView::on_checkCOMM_stateChanged(int arg1)
+{
+    (void) arg1;
+    qDebug()<<"checkCOMM changed";
+    if(mysilecs != NULL)
+    {
+        mysilecs->setLogTopics(this->generateLogTopics());
+    }
+}
+
+void diagnosticToolMainView::on_checkSEND_stateChanged(int arg1)
+{
+    (void) arg1;
+    qDebug()<<"checkSEND changed";
+    if(mysilecs != NULL)
+    {
+        mysilecs->setLogTopics(this->generateLogTopics());
+    }
+}
+
+void diagnosticToolMainView::on_checkRECV_stateChanged(int arg1)
+{
+    (void) arg1;
+    qDebug()<<"checkRECV changed";
+    if(mysilecs != NULL)
+    {
+        mysilecs->setLogTopics(this->generateLogTopics());
+    }
+}
+
+void diagnosticToolMainView::on_checkDATA_stateChanged(int arg1)
+{
+    (void) arg1;
+    qDebug()<<"checkDATA changed";
+    if(mysilecs != NULL)
+    {
+        mysilecs->setLogTopics(this->generateLogTopics());
+    }
+}
+
+void diagnosticToolMainView::on_checkDIAG_stateChanged(int arg1)
+{
+    (void) arg1;
+    qDebug()<<"checkDIAG changed";
+    if(mysilecs != NULL)
+    {
+        mysilecs->setLogTopics(this->generateLogTopics());
+    }
+}
+
+void diagnosticToolMainView::on_treeWidget_clicked()
+{
+
+}
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.h b/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.h
new file mode 100755
index 0000000000000000000000000000000000000000..b1774129c1fbb9e40ab18d02ecb5695067ae78da
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/diagnostictoolmainview.h
@@ -0,0 +1,120 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef DIAGNOSTICTOOLMAINVIEW_H
+#define DIAGNOSTICTOOLMAINVIEW_H
+
+#include <QMainWindow>
+
+#include <silecs-diagnostic/displayarraydialog.h>
+#include <silecs-diagnostic/item.h>
+#include <silecs-diagnostic/silecsmodule.h>
+#include <silecs-diagnostic/stderrredirect.h>
+
+#include <iostream>
+#include <typeinfo>
+#include <map>
+
+
+namespace Ui {
+    class diagnosticToolMainView;
+}
+
+using namespace Silecs;
+
+
+class diagnosticToolMainView : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    explicit diagnosticToolMainView(QWidget *parent = 0);
+    ~diagnosticToolMainView();
+
+    void setDeployFile(QString file);
+
+private slots:
+
+    // Tree view
+    void on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
+    void on_treeWidget_doubleClicked(const QModelIndex &index);
+    void on_treeWidget_itemExpanded(QTreeWidgetItem *item);
+
+    // Class name combo
+    void on_classNameComboBox_currentIndexChanged(const QString &arg1);
+
+    // Buttons
+    void on_sendButton_clicked();
+    void on_receiveButton_clicked();
+    void on_connectButton_clicked();
+    void on_loadDeployButton_clicked();
+    void on_disconnectButton_clicked();
+    void on_copyButton_clicked();
+
+    // Context menu for the console
+    void ctxMenu(const QPoint &pos);
+    void clearConsole_slot();
+
+    // different way of receiving
+    void receiveDevice(std::string blockName,Item* currentItem);
+    void periodicReceiveDevice();
+
+    // monitor
+    void on_periodicReceiveButton_toggled(bool checked);
+
+    // Log Topics change
+    void on_checkERROR_stateChanged(int arg1);
+    void on_checkDEBUG_stateChanged(int arg1);
+    void on_checkSETUP_stateChanged(int arg1);
+    void on_checkALLOC_stateChanged(int arg1);
+    void on_checkLOCK_stateChanged(int arg1);
+    void on_checkCOMM_stateChanged(int arg1);
+    void on_checkSEND_stateChanged(int arg1);
+    void on_checkRECV_stateChanged(int arg1);
+    void on_checkDATA_stateChanged(int arg1);
+    void on_checkDIAG_stateChanged(int arg1);
+
+    void on_treeWidget_clicked();
+
+private:
+
+    // GSI-Hack - load directly from file
+    QString designName;
+    QString deployFile;
+    void resetGUI();
+    void loadFiles();
+
+    void fillClassNameComboBox();
+
+    void logBlockReceived(std::string blockName, int elapsedTime);
+    void logCommunicationSuccess(int elapsedTime);
+
+    std::vector<QString> openArrayDialogBase(Silecs::Register* reg, std::vector<QString> dataVector, bool localData);
+    std::vector<QString> open1DArrayDialog(Silecs::Register* reg, bool localData);
+    std::vector<QString> open2DArrayDialog(Silecs::Register* reg, bool localData);
+    void markItemNotEdiable(QTreeWidgetItem *item);
+
+    Ui::diagnosticToolMainView *ui;
+
+    //BlockName and current item for periodic receive
+    std::string blockNameForPeriodicReceive;
+    Item* currentItemForPeriodicReceive;
+    QTimer *periodicReceiveTimer;
+
+    StdErrRedirect *redirector;
+    std::string generateLogTopics();
+};
+
+#endif // DIAGNOSTICTOOLMAINVIEW_H
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/displayarraydialog.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/displayarraydialog.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..71a41ac7f10f3c9d3be205f793e6ee9441b3aa8e
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/displayarraydialog.cpp
@@ -0,0 +1,87 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-diagnostic/displayarraydialog.h>
+#include <silecs-diagnostic/generated/ui_displayarraydialog.h>
+
+#include <QDebug>
+
+DisplayArrayDialog::DisplayArrayDialog(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::DisplayArrayDialog)
+{
+    ui->setupUi(this);
+
+}
+
+DisplayArrayDialog::~DisplayArrayDialog()
+{
+    delete ui;
+}
+
+void DisplayArrayDialog::setDataVector(std::vector<QString> dataVector, bool editable, unsigned long dim2)
+{
+    this->dataVector = dataVector;
+
+    // display informations
+    if(dim2 <= 1)   // 1d array
+    {
+        int numberOfValues = this->dataVector.size();
+        ui->tableWidget->setColumnCount(1);
+        ui->tableWidget->setRowCount(numberOfValues);
+
+        for(int i= 0; i< numberOfValues; i++)
+        {
+            QTableWidgetItem *item = new QTableWidgetItem(dataVector[i],1);
+
+            if(!editable) // default flag contain editable
+                item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
+
+            ui->tableWidget->setItem(0,i,item);
+        }
+    }
+    else    // 2d array
+    {
+        unsigned long dim1 = (this->dataVector.size())/dim2;
+        ui->tableWidget->setColumnCount(dim2);
+        ui->tableWidget->setRowCount(dim1);
+
+        for(unsigned long i=0; i<dim1; i++)
+        {
+            for(unsigned long j=0; j<dim2; j++)
+            {
+                QTableWidgetItem *item = new QTableWidgetItem(dataVector[i*dim2+j],1);
+                if(!editable)   // default flag contains editable
+                    item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
+
+                ui->tableWidget->setItem(i,j,item);
+            }
+        }
+    }
+    // display informations end
+}
+
+std::vector<QString> DisplayArrayDialog::getDataVector()
+{
+    return this->dataVector;
+}
+
+void DisplayArrayDialog::on_buttonBox_accepted()
+{
+    int numberOfValues = this->dataVector.size();
+    for(int i= 0; i< numberOfValues; i++)
+        this->dataVector[i] = ui->tableWidget->item(0,i)->text();
+
+}
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/displayarraydialog.h b/silecs-diagnostic-cpp/src/silecs-diagnostic/displayarraydialog.h
new file mode 100755
index 0000000000000000000000000000000000000000..ff4254466b02f7d705b7c9936d5d0d12e0e41bac
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/displayarraydialog.h
@@ -0,0 +1,47 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef DISPLAYARRAYDIALOG_H
+#define DISPLAYARRAYDIALOG_H
+
+#include <QDialog>
+
+namespace Ui {
+    class DisplayArrayDialog;
+}
+
+class DisplayArrayDialog : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit DisplayArrayDialog(QWidget *parent = 0);
+    ~DisplayArrayDialog();
+
+    void setDataVector(std::vector<QString> dataVector, bool editable, unsigned long dim2);
+
+    std::vector<QString> getDataVector();
+
+private slots:
+    void on_buttonBox_accepted();
+
+private:
+    Ui::DisplayArrayDialog *ui;
+
+    std::vector<QString> dataVector;
+
+};
+
+#endif // DISPLAYARRAYDIALOG_H
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/headerinformations.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/headerinformations.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..14c44bcdff52901bc81e4b9f9bb5bc89162de68e
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/headerinformations.cpp
@@ -0,0 +1,63 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-diagnostic/headerinformations.h>
+
+HeaderInformations::HeaderInformations()
+{
+}
+
+// String setter
+void HeaderInformations::setheaderRelease(std::string headerRelease)
+{
+    this->headerRelease = headerRelease;
+}
+
+void HeaderInformations::setheaderOwner(std::string headerOwner)
+{
+    this->headerOwner = headerOwner;
+}
+
+void HeaderInformations::setheaderDate(std::string headerDate)
+{
+    this->headerDate = headerDate;
+}
+
+void HeaderInformations::setHeaderChecksum(std::string HeaderChecksum)
+{
+    this->HeaderChecksum = HeaderChecksum;
+}
+
+
+// String getter
+std::string HeaderInformations::getheaderRelease()
+{
+    return this->headerRelease;
+}
+
+std::string HeaderInformations::getheaderOwner()
+{
+    return this->headerOwner;
+}
+
+std::string HeaderInformations::getheaderDate()
+{
+    return this->headerDate;
+}
+
+std::string HeaderInformations::getHeaderChecksum()
+{
+    return this->HeaderChecksum;
+}
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/headerinformations.h b/silecs-diagnostic-cpp/src/silecs-diagnostic/headerinformations.h
new file mode 100755
index 0000000000000000000000000000000000000000..b3750cc19a2223770b2213674be127d3477a6e12
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/headerinformations.h
@@ -0,0 +1,46 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef HEADERINFORMATIONS_H
+#define HEADERINFORMATIONS_H
+
+#include <string>
+
+class HeaderInformations
+{
+
+private:
+    std::string headerRelease;
+    std::string headerOwner;
+    std::string headerDate;
+    std::string HeaderChecksum;
+
+public:
+    HeaderInformations();
+
+    // String setter
+    void setheaderRelease(std::string headerRelease);
+    void setheaderOwner(std::string headerOwner);
+    void setheaderDate(std::string headerDate);
+    void setHeaderChecksum(std::string HeaderChecksum);
+
+    // String getter
+    std::string getheaderRelease();
+    std::string getheaderOwner();
+    std::string getheaderDate();
+    std::string getHeaderChecksum();
+};
+
+#endif // HEADERINFORMATIONS_H
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/item.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/item.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..4232b672a49f1fab7d9aad59a2c3f13f14bc2d46
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/item.cpp
@@ -0,0 +1,33 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-diagnostic/item.h>
+
+
+Item::Item(void* linkedObject)
+{
+    this->linkedObject    = linkedObject;
+}
+
+void Item::setLinkedObject(void* linkedObject)
+{
+    this->linkedObject    = linkedObject;
+}
+
+void* Item::getLinkedObject()
+{
+    return this->linkedObject;
+}
+
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/item.h b/silecs-diagnostic-cpp/src/silecs-diagnostic/item.h
new file mode 100755
index 0000000000000000000000000000000000000000..be317ae21ad5ab89676458d33b89b039aa0bb4c5
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/item.h
@@ -0,0 +1,37 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef ITEM_H
+#define ITEM_H
+
+#include <QTreeWidgetItem>
+
+class QDomDocument;
+class Item : public QTreeWidgetItem {
+//  Q_PROPERTY( QString Name READ name WRITE setName );
+ private:
+        void *linkedObject;
+ public:
+        Item(void* linkedObject);
+        Item();
+
+        // set the pointer to the related object
+        void setLinkedObject(void* linkedObject);
+
+        // return the pointer to the related object
+        void* getLinkedObject();
+};
+
+#endif // ITEM_H
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/logindialog.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/logindialog.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..d460b0a4cd3d652de6b44fbf139dfec6477d5504
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/logindialog.cpp
@@ -0,0 +1,59 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-diagnostic/logindialog.h>
+#include <silecs-diagnostic/generated/ui_logindialog.h>
+
+
+LoginDialog::LoginDialog(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::LoginDialog)
+{
+    ui->setupUi(this);
+}
+
+LoginDialog::~LoginDialog()
+{
+    delete ui;
+}
+
+//set and get username
+//void LoginDialog::setUsername(std::string username)
+//{
+//    this->username = username;
+//}
+
+std::string LoginDialog::getUsername()
+{
+    return this->username;
+}
+
+//set and get password
+//void LoginDialog::setPassword(std::string password)
+//{
+//    this->password = password;
+//}
+
+std::string LoginDialog::getPassword()
+{
+    return this->password;
+}
+
+void LoginDialog::on_buttonBox_accepted()
+{
+    this->username = ui->usernameLineEdit->text().toStdString();
+    this->password = ui->passwordLineEdit->text().toStdString();
+}
+
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/logindialog.h b/silecs-diagnostic-cpp/src/silecs-diagnostic/logindialog.h
new file mode 100755
index 0000000000000000000000000000000000000000..d337ea7a650e39c610f2696a06dd4b1a7a456f2f
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/logindialog.h
@@ -0,0 +1,54 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef LOGINDIALOG_H
+#define LOGINDIALOG_H
+
+#include <QDialog>
+
+#include <silecs-diagnostic/constants.h>
+
+namespace Ui {
+    class LoginDialog;
+}
+
+class LoginDialog : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit LoginDialog(QWidget *parent = 0);
+    ~LoginDialog();
+
+    //set and get username
+//    void setUsername(std::string username);
+    std::string getUsername();
+
+    //set and get password
+//    void setPassword(std::string password);
+    std::string getPassword();
+
+private slots:
+    void on_buttonBox_accepted();
+
+private:
+    Ui::LoginDialog *ui;
+
+    // login and password
+    std::string username;
+    std::string password;
+};
+
+#endif // LOGINDIALOG_H
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/loginhandler.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/loginhandler.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..962bd5ec7e4b534ac8cd7c1565a39fa5538f58aa
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/loginhandler.cpp
@@ -0,0 +1,71 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-diagnostic/loginhandler.h>
+
+#ifdef WITH_RBAC
+    extern std::string UserName;
+
+    loginHandler::loginHandler()
+    {
+    }
+
+    bool loginHandler::requestLogin()
+    {
+        LoginDialog *loginDialog = new LoginDialog();
+
+        for(int i=0;i<NUMBER_PASSWORD_ATTEMPTS;i++)
+        {
+            try
+            {
+                //Popup interface requesting password
+
+                loginDialog->setModal(true);
+
+                if(loginDialog->exec()==1)
+                {
+                    auto_ptr<cmw::rbac::TokenClass> token = cmw::rbac::LoginContext::login("SILECS Diagnostic Tool",
+                                                                                           loginDialog->getUsername(),
+                                                                                           loginDialog->getPassword());
+                    if (token.get() != NULL)
+                    {
+                        //password correct
+                        extern std::string UserName;
+                        UserName = loginDialog->getUsername();
+                        delete loginDialog;
+                        return true;
+                    }
+                }
+                else
+                {
+                    //cancell button was pressed
+                    delete loginDialog;
+                    return false;
+                }
+            }
+            catch (const cmw::rbac::AuthenticationFailure & ex)
+            {
+                qDebug() << "Autentication failure!";
+            }
+            catch(...)
+            {
+                qDebug() << "unknown exception";
+            }
+        }
+
+        delete loginDialog;
+        return false;
+    }
+#endif
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/loginhandler.h b/silecs-diagnostic-cpp/src/silecs-diagnostic/loginhandler.h
new file mode 100755
index 0000000000000000000000000000000000000000..aad9937007932018492a6747fb5c10ac62698732
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/loginhandler.h
@@ -0,0 +1,46 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef LOGINHANDLER_H
+#define LOGINHANDLER_H
+
+#include <QtGui>
+#include <QtCore>
+
+#include <silecs-diagnostic/logindialog.h>
+#include <silecs-diagnostic/constants.h>
+
+#include <iostream>
+
+#ifdef WITH_RBAC
+    #include <cmw-rbac/LoginContext.h>
+    #include <cmw-rbac/AuthenticationFailure.h>
+#endif
+
+using namespace std;
+
+#ifdef WITH_RBAC
+    extern std::string USER_NAME;
+
+    class loginHandler
+    {
+    public:
+        loginHandler();
+        bool requestLogin();
+    };
+#endif
+
+
+#endif // LOGINHANDLER_H
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/main.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/main.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..1ac7fa0fe457aa0954e090fd5b579e5a8dc16516
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/main.cpp
@@ -0,0 +1,88 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <QtGui/QApplication>
+
+#include <silecs-diagnostic/constants.h>
+#include <silecs-diagnostic/diagnostictoolmainview.h>
+#include <silecs-diagnostic/loginhandler.h>
+#include <silecs-diagnostic/silecsmodule.h>
+
+
+silecsModule *mysilecs;
+
+class I : public QThread
+{
+public:
+        static void sleep(unsigned long secs) {
+                QThread::sleep(secs);
+        }
+};
+
+// Logged in user. (To be set at runtime)
+std::string UserName;
+
+
+    // main with splash screen and login
+    int main(int argc, char *argv[])
+    {
+		mysilecs = NULL;
+    	try
+    	{
+    		Silecs::XMLParser::init();
+#ifdef WITH_RBAC
+			//Login
+			loginHandler* login = new loginHandler();
+			if(!login->requestLogin())
+			{
+				return 0;
+			}
+#endif
+
+            QApplication app(argc, argv);
+			QPixmap pixmap( ":/Images/splash-silecs.png" );
+
+			QSplashScreen splash(pixmap);
+			splash.show();
+
+			diagnosticToolMainView mainWin;
+			mainWin.setWindowTitle("SILECS Diagnostic Tool");
+
+			if (argc >= 3) // an argument was passed
+			{
+				if (strcmp(argv[1],"-d") == 0)
+					mainWin.setDeployFile(QString::fromStdString(argv[2]));
+			}
+
+			I::sleep(SPLASH_SCREEN_TIME);
+
+			mainWin.showMaximized();
+			splash.finish(&mainWin);
+				return app.exec();
+    	}
+        catch(std::string *str)
+        {
+        	std::cout << str;
+        }
+        catch(std::exception& ex)
+        {
+        	std::cout << ex.what();
+        }
+    	catch(...)
+    	{
+    		std::cout << "Unexpected error caught in Main. Please notify SILECS support";
+    	}
+        return -1;
+    }
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/gui/ArrayVisualizationDialog.ui b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/gui/ArrayVisualizationDialog.ui
new file mode 100755
index 0000000000000000000000000000000000000000..eaebf5f9edcc4afd9c76cc428a29320110cf1d2b
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/gui/ArrayVisualizationDialog.ui
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>180</width>
+    <height>481</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTableWidget" name="tableWidget"/>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>Dialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>Dialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/gui/diagnostictoolmainview.ui b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/gui/diagnostictoolmainview.ui
new file mode 100755
index 0000000000000000000000000000000000000000..cc67f7870c8fdac52f3f6400cc9f2b07dca677d9
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/gui/diagnostictoolmainview.ui
@@ -0,0 +1,684 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>diagnosticToolMainView</class>
+ <widget class="QMainWindow" name="diagnosticToolMainView">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>909</width>
+    <height>805</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>diagnosticToolMainView</string>
+  </property>
+  <widget class="QWidget" name="centralWidget">
+   <layout class="QVBoxLayout" name="verticalLayout_11">
+    <item>
+     <widget class="QGroupBox" name="clusterGroupBox">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="maximumSize">
+       <size>
+        <width>16777215</width>
+        <height>16777215</height>
+       </size>
+      </property>
+      <property name="title">
+       <string>Cluster operations</string>
+      </property>
+      <property name="flat">
+       <bool>true</bool>
+      </property>
+      <layout class="QHBoxLayout" name="horizontalLayout">
+       <item>
+        <layout class="QVBoxLayout" name="verticalLayout_5">
+         <item>
+          <widget class="QPushButton" name="loadDeployButton">
+           <property name="toolTip">
+            <string>Select a Deploy to load</string>
+           </property>
+           <property name="text">
+            <string>Load Deploy</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="classNameComboBox"/>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QVBoxLayout" name="verticalLayout_2">
+         <item>
+          <widget class="QLabel" name="DeployName">
+           <property name="text">
+            <string>&lt; Please Load a Deploy &gt;</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLabel" name="DesignName">
+           <property name="text">
+            <string>&lt; and Pick a Design &gt;</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QGridLayout" name="gridLayout_4">
+         <item row="0" column="0">
+          <spacer name="horizontalSpacer">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>88</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item row="0" column="2">
+          <widget class="QCheckBox" name="checkERROR">
+           <property name="enabled">
+            <bool>false</bool>
+           </property>
+           <property name="toolTip">
+            <string>standard topic to trace the IEPLC processing errors, sent to the console (if enable)</string>
+           </property>
+           <property name="text">
+            <string>ERROR</string>
+           </property>
+           <property name="checked">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <spacer name="horizontalSpacer_2">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>88</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item row="0" column="6">
+          <widget class="QCheckBox" name="checkDATA">
+           <property name="toolTip">
+            <string>standard topic to trace transaction details, sent to the console (if enable with SEND/RECV)</string>
+           </property>
+           <property name="text">
+            <string>DATA</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="5">
+          <widget class="QCheckBox" name="checkSEND">
+           <property name="toolTip">
+            <string>standard topic to trace transaction toward PLC, sent to the console (if enable)</string>
+           </property>
+           <property name="text">
+            <string>SEND</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="5">
+          <widget class="QCheckBox" name="checkRECV">
+           <property name="toolTip">
+            <string>standard topic to trace transaction from PLC, sent to the console (if enable)</string>
+           </property>
+           <property name="text">
+            <string>RECV</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="4">
+          <widget class="QCheckBox" name="checkCOMM">
+           <property name="toolTip">
+            <string>standard topic to trace PLC communication, sent to the console (if enable)</string>
+           </property>
+           <property name="text">
+            <string>COMM</string>
+           </property>
+           <property name="checked">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="2">
+          <widget class="QCheckBox" name="checkDEBUG">
+           <property name="toolTip">
+            <string>standard topic to trace the IEPLC debug info, sent to the console (if enable)</string>
+           </property>
+           <property name="text">
+            <string>DEBUG</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="3">
+          <widget class="QCheckBox" name="checkSETUP">
+           <property name="toolTip">
+            <string>standard topic to trace details of IEPLC client start-up, sent to the console (if enable)</string>
+           </property>
+           <property name="text">
+            <string>SETUP</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="3">
+          <widget class="QCheckBox" name="checkALLOC">
+           <property name="toolTip">
+            <string>standard topic to trace allocation memory, sent to the console (if enable)</string>
+           </property>
+           <property name="text">
+            <string>ALLOC</string>
+           </property>
+           <property name="checked">
+            <bool>false</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="4">
+          <widget class="QCheckBox" name="checkLOCK">
+           <property name="toolTip">
+            <string>standard topic to trace resources lock details, sent to the console (if enable)</string>
+           </property>
+           <property name="text">
+            <string>LOCK</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="6">
+          <widget class="QCheckBox" name="checkDIAG">
+           <property name="toolTip">
+            <string>special topic sent to the console (if enable) and to the syslog (in any cases)</string>
+           </property>
+           <property name="text">
+            <string>DIAG</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QCheckBox" name="compareChecksums">
+           <property name="enabled">
+            <bool>true</bool>
+           </property>
+           <property name="text">
+            <string>compare Checksums</string>
+           </property>
+           <property name="checked">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </widget>
+    </item>
+    <item>
+     <widget class="QSplitter" name="splitter_2">
+      <property name="orientation">
+       <enum>Qt::Vertical</enum>
+      </property>
+      <widget class="QSplitter" name="splitter">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <widget class="QWidget" name="layoutWidget">
+        <layout class="QVBoxLayout" name="verticalLayout_10">
+         <item>
+          <widget class="QTreeWidget" name="treeWidget">
+           <property name="cursor" stdset="0">
+            <cursorShape>ArrowCursor</cursorShape>
+           </property>
+           <property name="frameShadow">
+            <enum>QFrame::Sunken</enum>
+           </property>
+           <property name="alternatingRowColors">
+            <bool>false</bool>
+           </property>
+           <property name="columnCount">
+            <number>3</number>
+           </property>
+           <column>
+            <property name="text">
+             <string notr="true"/>
+            </property>
+           </column>
+           <column>
+            <property name="text">
+             <string notr="true"/>
+            </property>
+           </column>
+           <column>
+            <property name="text">
+             <string notr="true"/>
+            </property>
+           </column>
+          </widget>
+         </item>
+         <item>
+          <widget class="QGroupBox" name="groupBox_2">
+           <property name="title">
+            <string>PLC Value</string>
+           </property>
+           <layout class="QVBoxLayout" name="verticalLayout_7">
+            <item>
+             <layout class="QGridLayout" name="gridLayout_5">
+              <item row="0" column="0">
+               <widget class="QLabel" name="label_7">
+                <property name="text">
+                 <string>Binary value:</string>
+                </property>
+               </widget>
+              </item>
+              <item row="0" column="1">
+               <widget class="QLabel" name="binValueLabel">
+                <property name="text">
+                 <string>--value--</string>
+                </property>
+               </widget>
+              </item>
+              <item row="1" column="0">
+               <widget class="QLabel" name="label_8">
+                <property name="text">
+                 <string>Hexadecimal value:</string>
+                </property>
+               </widget>
+              </item>
+              <item row="1" column="1">
+               <widget class="QLabel" name="HexValueLabel">
+                <property name="text">
+                 <string>--value--</string>
+                </property>
+               </widget>
+              </item>
+              <item row="3" column="0">
+               <widget class="QLabel" name="label_13">
+                <property name="text">
+                 <string>ASCII representation:</string>
+                </property>
+               </widget>
+              </item>
+              <item row="2" column="0">
+               <widget class="QLabel" name="label_9">
+                <property name="text">
+                 <string>Decimal value</string>
+                </property>
+               </widget>
+              </item>
+              <item row="3" column="1">
+               <widget class="QLabel" name="asciiValueLabel">
+                <property name="text">
+                 <string>--value--</string>
+                </property>
+               </widget>
+              </item>
+              <item row="2" column="1">
+               <widget class="QLabel" name="DecValueLabel">
+                <property name="text">
+                 <string>--value--</string>
+                </property>
+               </widget>
+              </item>
+             </layout>
+            </item>
+           </layout>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+       <widget class="QSplitter" name="verticalSplitter">
+        <property name="orientation">
+         <enum>Qt::Vertical</enum>
+        </property>
+        <widget class="QWidget" name="layoutWidget">
+         <layout class="QVBoxLayout" name="verticalLayout_4">
+          <property name="spacing">
+           <number>10</number>
+          </property>
+          <item>
+           <layout class="QHBoxLayout" name="horizontalLayout_3">
+            <property name="spacing">
+             <number>6</number>
+            </property>
+            <item>
+             <widget class="QPushButton" name="disconnectButton">
+              <property name="enabled">
+               <bool>false</bool>
+              </property>
+              <property name="toolTip">
+               <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Disconnect from PLC.&lt;br /&gt;Available only if a PLC element is selected.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+              </property>
+              <property name="text">
+               <string>Disconnect PLC</string>
+              </property>
+              <property name="icon">
+               <iconset>
+                <normaloff>:/Images/disconnect.png</normaloff>:/Images/disconnect.png</iconset>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+          <item>
+           <widget class="QPushButton" name="connectButton">
+            <property name="enabled">
+             <bool>false</bool>
+            </property>
+            <property name="toolTip">
+             <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Connect to PLC.&lt;br /&gt;Available only if a PLC element is selected.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+            </property>
+            <property name="text">
+             <string>Connect PLC</string>
+            </property>
+            <property name="icon">
+             <iconset>
+              <normaloff>:/Images/connect.png</normaloff>:/Images/connect.png</iconset>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QGroupBox" name="copyBox">
+            <property name="title">
+             <string>Copy Value from PLC to Local</string>
+            </property>
+            <property name="flat">
+             <bool>true</bool>
+            </property>
+            <layout class="QGridLayout" name="gridLayout_3">
+             <property name="topMargin">
+              <number>0</number>
+             </property>
+             <property name="bottomMargin">
+              <number>0</number>
+             </property>
+             <property name="verticalSpacing">
+              <number>6</number>
+             </property>
+             <item row="0" column="0">
+              <widget class="QLabel" name="label_6">
+               <property name="text">
+                <string>Block:</string>
+               </property>
+               <property name="alignment">
+                <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+               </property>
+              </widget>
+             </item>
+             <item row="0" column="1">
+              <widget class="QComboBox" name="copyComboBox"/>
+             </item>
+             <item row="1" column="1">
+              <widget class="QPushButton" name="copyButton">
+               <property name="enabled">
+                <bool>false</bool>
+               </property>
+               <property name="toolTip">
+                <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Copy the input buffer value of the selected BLOCK to theoutput values.&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Copying is available at:&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; - Cluster level.&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; - PLC level.&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; - Device level.&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+               </property>
+               <property name="text">
+                <string>Copy</string>
+               </property>
+               <property name="icon">
+                <iconset>
+                 <normaloff>:/Images/copy.png</normaloff>:/Images/copy.png</iconset>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </widget>
+          </item>
+          <item>
+           <widget class="QGroupBox" name="sendBox">
+            <property name="title">
+             <string>Send</string>
+            </property>
+            <property name="flat">
+             <bool>true</bool>
+            </property>
+            <layout class="QGridLayout" name="gridLayout_2">
+             <property name="topMargin">
+              <number>0</number>
+             </property>
+             <property name="bottomMargin">
+              <number>0</number>
+             </property>
+             <property name="verticalSpacing">
+              <number>6</number>
+             </property>
+             <item row="0" column="0">
+              <widget class="QLabel" name="label_5">
+               <property name="text">
+                <string>Block:</string>
+               </property>
+               <property name="alignment">
+                <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+               </property>
+              </widget>
+             </item>
+             <item row="0" column="1">
+              <widget class="QComboBox" name="sendComboBox"/>
+             </item>
+             <item row="1" column="1">
+              <widget class="QPushButton" name="sendButton">
+               <property name="enabled">
+                <bool>false</bool>
+               </property>
+               <property name="toolTip">
+                <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Send the selected BLOCK to the selected item just one time.&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Sending is available at:&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; - Cluster level.&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; - PLC level.&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; - Device level.&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+               </property>
+               <property name="text">
+                <string> Send </string>
+               </property>
+               <property name="icon">
+                <iconset>
+                 <normaloff>:/Images/send1.png</normaloff>:/Images/send1.png</iconset>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </widget>
+          </item>
+          <item>
+           <widget class="QGroupBox" name="receiveBox">
+            <property name="title">
+             <string>Receive</string>
+            </property>
+            <property name="flat">
+             <bool>true</bool>
+            </property>
+            <layout class="QGridLayout" name="gridLayout">
+             <property name="topMargin">
+              <number>0</number>
+             </property>
+             <property name="bottomMargin">
+              <number>0</number>
+             </property>
+             <item row="0" column="0">
+              <widget class="QLabel" name="label_4">
+               <property name="text">
+                <string>Block:</string>
+               </property>
+               <property name="alignment">
+                <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+               </property>
+              </widget>
+             </item>
+             <item row="0" column="1">
+              <widget class="QComboBox" name="receiveComboBox"/>
+             </item>
+             <item row="1" column="0">
+              <widget class="QLabel" name="label_3">
+               <property name="text">
+                <string>Sec:</string>
+               </property>
+               <property name="alignment">
+                <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+               </property>
+              </widget>
+             </item>
+             <item row="1" column="1">
+              <widget class="QDoubleSpinBox" name="timeSpinBox"/>
+             </item>
+             <item row="4" column="1">
+              <widget class="QPushButton" name="receiveButton">
+               <property name="enabled">
+                <bool>false</bool>
+               </property>
+               <property name="toolTip">
+                <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Receive the selected BLOCK from the selected item just one time.&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Receiving is available at:&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; - Cluster level.&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; - PLC level.&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; - Device level.&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+               </property>
+               <property name="text">
+                <string>Receive</string>
+               </property>
+               <property name="icon">
+                <iconset>
+                 <normaloff>:/Images/glasses1.png</normaloff>:/Images/glasses1.png</iconset>
+               </property>
+              </widget>
+             </item>
+             <item row="2" column="1">
+              <widget class="QPushButton" name="periodicReceiveButton">
+               <property name="enabled">
+                <bool>false</bool>
+               </property>
+               <property name="toolTip">
+                <string>Receive the selected BLOCK from the selected item periodicaly (every &quot;Interval&quot; seconds).
+Receiving is available at:
+ - Cluster level.
+ - PLC level.
+ - Device level.</string>
+               </property>
+               <property name="text">
+                <string>Monitor</string>
+               </property>
+               <property name="icon">
+                <iconset>
+                 <normaloff>:/Images/glasses.png</normaloff>
+                 <normalon>:/Images/stop.png</normalon>:/Images/glasses.png</iconset>
+               </property>
+               <property name="checkable">
+                <bool>true</bool>
+               </property>
+               <property name="checked">
+                <bool>false</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="2" column="0">
+              <widget class="QLabel" name="monitoringLabel">
+               <property name="font">
+                <font>
+                 <pointsize>7</pointsize>
+                </font>
+               </property>
+               <property name="text">
+                <string/>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+        <widget class="QTextEdit" name="InformationMessage">
+         <property name="enabled">
+          <bool>true</bool>
+         </property>
+        </widget>
+       </widget>
+      </widget>
+      <widget class="QGroupBox" name="groupBox">
+       <property name="title">
+        <string/>
+       </property>
+       <layout class="QVBoxLayout" name="verticalLayout">
+        <item>
+         <widget class="QTextBrowser" name="console"/>
+        </item>
+       </layout>
+      </widget>
+     </widget>
+    </item>
+    <item>
+     <widget class="QLabel" name="dbVersionLabel">
+      <property name="text">
+       <string>Loaded database version:</string>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <action name="actionOperation_1">
+   <property name="icon">
+    <iconset>
+     <normaloff>:/new/prefix1/Images/array.png</normaloff>:/new/prefix1/Images/array.png</iconset>
+   </property>
+   <property name="text">
+    <string>operation 1</string>
+   </property>
+  </action>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <tabstops>
+  <tabstop>treeWidget</tabstop>
+  <tabstop>disconnectButton</tabstop>
+  <tabstop>sendComboBox</tabstop>
+  <tabstop>sendButton</tabstop>
+  <tabstop>receiveComboBox</tabstop>
+  <tabstop>timeSpinBox</tabstop>
+  <tabstop>periodicReceiveButton</tabstop>
+  <tabstop>receiveButton</tabstop>
+  <tabstop>InformationMessage</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/gui/displayarraydialog.ui b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/gui/displayarraydialog.ui
new file mode 100755
index 0000000000000000000000000000000000000000..cdca18fa07847d43f2e98192e5da74d5a8d30cee
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/gui/displayarraydialog.ui
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DisplayArrayDialog</class>
+ <widget class="QDialog" name="DisplayArrayDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>474</width>
+    <height>437</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Buffer data</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTableWidget" name="tableWidget"/>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>DisplayArrayDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>DisplayArrayDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/gui/logindialog.ui b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/gui/logindialog.ui
new file mode 100755
index 0000000000000000000000000000000000000000..363ef4feb0e25c057040ecd10038276287598146
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/gui/logindialog.ui
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>LoginDialog</class>
+ <widget class="QDialog" name="LoginDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>299</width>
+    <height>134</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Login dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Login:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QLineEdit" name="usernameLineEdit">
+       <property name="text">
+        <string/>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Password:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QLineEdit" name="passwordLineEdit">
+       <property name="inputMask">
+        <string/>
+       </property>
+       <property name="echoMode">
+        <enum>QLineEdit::Password</enum>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>LoginDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>LoginDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images.qrc b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images.qrc
new file mode 100755
index 0000000000000000000000000000000000000000..e7af029df07fa9219f628dd70848b8005115b7b5
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images.qrc
@@ -0,0 +1,17 @@
+<RCC>
+    <qresource prefix="/silecs-diagnostic/resources/images">
+        <file alias="splash-silecs.png">images/splash-silecs.png</file>
+        <file alias="array.png">images/array.png</file>
+        <file alias="DEV.png">images/DEV.png</file>
+        <file alias="PLC.png">images/PLC.png</file>
+        <file alias="REG.png">images/REG.png</file>
+        <file alias="glasses.png">images/glasses.png</file>
+        <file alias="glasses1.png">images/glasses1.png</file>
+        <file alias="send.png">images/send.png</file>
+        <file alias="send1.png">images/send1.png</file>
+        <file alias="stop.png">images/stop.png</file>
+        <file alias="disconnect.png">images/disconnect.png</file>
+        <file alias="connect.png">images/connect.png</file>
+        <file alias="copy.png">images/copy.png</file>
+    </qresource>
+</RCC>
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/DEV.png b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/DEV.png
new file mode 100755
index 0000000000000000000000000000000000000000..9d0e4417bb6583f06a4657f66c8b537f61555a7f
Binary files /dev/null and b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/DEV.png differ
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/PLC.png b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/PLC.png
new file mode 100755
index 0000000000000000000000000000000000000000..cd18f5420ca4038577bfe04fb2669e3992504999
Binary files /dev/null and b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/PLC.png differ
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/REG.png b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/REG.png
new file mode 100755
index 0000000000000000000000000000000000000000..a11048a58c704d2429d296a5a28c9984f776e5a5
Binary files /dev/null and b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/REG.png differ
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/array.png b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/array.png
new file mode 100755
index 0000000000000000000000000000000000000000..8fd9bededea4babc1428f98121cd3e5f677f0827
Binary files /dev/null and b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/array.png differ
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/connect.png b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/connect.png
new file mode 100755
index 0000000000000000000000000000000000000000..5141d635a797f07630840dbc3061cdf4e1d7a37e
Binary files /dev/null and b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/connect.png differ
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/copy.png b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/copy.png
new file mode 100755
index 0000000000000000000000000000000000000000..2293a0127066c31aec2a1da71e16e8ac8a25afa1
Binary files /dev/null and b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/copy.png differ
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/disconnect.png b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/disconnect.png
new file mode 100755
index 0000000000000000000000000000000000000000..f472534f444b10f0ac3f4ec694ce4c8faddf59f4
Binary files /dev/null and b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/disconnect.png differ
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/glasses.png b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/glasses.png
new file mode 100755
index 0000000000000000000000000000000000000000..f3b17afe95961106d96bda5c1535dfaff1346a9d
Binary files /dev/null and b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/glasses.png differ
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/glasses1.png b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/glasses1.png
new file mode 100755
index 0000000000000000000000000000000000000000..aa97fa591444dcc11211fdf855d492d0bd5a7ff1
Binary files /dev/null and b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/glasses1.png differ
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/send.png b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/send.png
new file mode 100755
index 0000000000000000000000000000000000000000..6b3884073d6ff4708e7d61d2adfa3a2570fd8872
Binary files /dev/null and b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/send.png differ
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/send1.png b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/send1.png
new file mode 100755
index 0000000000000000000000000000000000000000..8eb536fdb4998958ec892333e53225fb8c6e2c89
Binary files /dev/null and b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/send1.png differ
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/splash-silecs.png b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/splash-silecs.png
new file mode 100644
index 0000000000000000000000000000000000000000..2229d4aa8d6fe11b607f83f70b2ed16f37ddad2f
Binary files /dev/null and b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/splash-silecs.png differ
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/stop.png b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/stop.png
new file mode 100755
index 0000000000000000000000000000000000000000..03a9a672daea270f0e35b47ef02fbe4b8124cccf
Binary files /dev/null and b/silecs-diagnostic-cpp/src/silecs-diagnostic/resources/images/stop.png differ
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..5567b14f5f03183b2cbc34332713e6a09826f5f6
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.cpp
@@ -0,0 +1,989 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-diagnostic/silecsmodule.h>
+#include <silecs-communication/interface/utility/XMLParser.h>
+
+extern std::string UserName;
+
+//---------------------------------------------------------------------------------
+// TODO: to move this to utility
+// remove then from diagnostictoolmainview as well!
+
+template <class T>bool from_string(T& t, const std::string& s, std::ios_base& (*f)(std::ios_base&))
+{
+    std::istringstream iss(s);
+    return !(iss >> f >> t).fail();
+}
+//---------------------------------------------------------------------------------
+
+silecsModule::silecsModule(std::string logTopics, QTextBrowser *messageConsole):
+		messageConsole_(messageConsole), debugLoggingEnabled_(false)
+{
+    silecsService = NULL;
+    silecsCluster = NULL;
+    counterConnectedPLC = 0;
+
+    if(logTopics.length() == 0)
+    {
+    	Utils::logInfo(messageConsole_,"no log topics defined");
+        silecsService  = Silecs::Service::getInstance(0, NULL);
+    }
+    else
+    {
+    	Utils::logInfo(messageConsole_,"the following log topics will be used: " + QString::fromStdString(logTopics));
+        char *a = new char[logTopics.size()+1];
+        a[logTopics.size()]=0;
+        memcpy(a,logTopics.c_str(),logTopics.size());
+        char *argv[2] = { (char *)"-plcLog", a };
+        silecsService  = Silecs::Service::getInstance(2,argv);
+    }
+}
+
+silecsModule::~silecsModule()
+{
+    silecsService->deleteInstance();
+    silecsService = NULL;
+    silecsCluster = NULL;
+    Utils::logInfo(messageConsole_,"silecsModule destructor executed");
+}
+
+void silecsModule::setLogTopics(std::string logTopics)
+{
+    if(silecsService != NULL)
+    {
+        if(!silecsService->setLogTopics(logTopics))
+        	Utils::logError(messageConsole_,"Error while setting log topics ");
+    }
+}
+
+bool silecsModule::isDebugLogEnabled()
+{
+	return debugLoggingEnabled_;
+}
+
+void silecsModule::enableDebugLog()
+{
+	debugLoggingEnabled_ = true;
+}
+
+Item *silecsModule::generateTree(string className, string deployFile)
+{
+    Item *root = NULL;
+    try{
+
+    	Utils::logInfo(messageConsole_,"Loading deploy file: " + QString::fromStdString(deployFile));
+        XMLParser parserDeploy(deployFile,true);
+
+        ElementXML silecsDesign = parserDeploy.getFirstElementFromXPath("/SILECS-Deploy/Controller/SilecsDesign[@silecs-design-name='" + className + "']");
+        string classVersion = silecsDesign.getAttribute("silecs-design-version");
+        ElementXML deployUnitNode = parserDeploy.getFirstElementFromXPath("/SILECS-Deploy/Deploy-Unit");
+        string deployName = deployUnitNode.getAttribute("name");
+
+        silecsCluster       = silecsService->getCluster(className,classVersion);
+        root = new Item(silecsCluster);
+        root->setText(0,QString::fromStdString(className+" v"+classVersion));
+        root->setWhatsThis(0,QString::fromStdString(CLUSTER_TYPE));
+        root->setLinkedObject(silecsCluster);
+
+        boost::ptr_vector<ElementXML> controllerNodes = parserDeploy.getElementsFromXPath_throwIfEmpty("/SILECS-Deploy/Controller");
+        if(controllerNodes.size() == 0)
+        {
+        	Utils::logError(messageConsole_,"No controller defined");
+            return root;
+        }
+        boost::ptr_vector<ElementXML>::const_iterator controllerIter;
+		for(controllerIter = controllerNodes.begin(); controllerIter != controllerNodes.end(); controllerIter++)
+        {
+            std::string plcName = controllerIter->getAttribute("host-name");
+            if(plcName.compare("")==true)
+            {
+            	Utils::logError(messageConsole_,"PLC name empty - will be skipped");
+                break;
+            }
+            Silecs::PLC *plc;
+            try
+            {
+            	std::size_t deployFolderPos = deployFile.find(deployName);
+            	string deployProject = deployFile.substr(0,deployFolderPos) + deployName;
+            	string parameterFile = deployProject + "/generated/client/" + plcName + ".silecsparam";
+
+            	Utils::logInfo(messageConsole_,"Loading parameter file: " + QString::fromStdString(parameterFile));
+                plc = silecsCluster->getPLC(plcName,parameterFile);
+            }
+            catch(const Silecs::SilecsException& ex2)
+            {
+            	Utils::logError(messageConsole_,"Error while loading "+QString::fromStdString(plcName)+". "+QString::fromStdString(ex2.what()));
+                continue;
+            }
+
+            // add plc on the tree
+            Item *plcItem = Utils::addTreeItem(root,QString::fromStdString(plcName),
+                                               "",QString::fromStdString(PLC_TYPE),plc,":/Images/PLC.png");
+
+            // get devices for the current PLC
+            deviceVectorType deviceMap = plc->getDeviceMap();
+
+            deviceVectorType::iterator pDeviceIter;
+			for(pDeviceIter = deviceMap.begin(); pDeviceIter != deviceMap.end(); ++pDeviceIter)
+			{
+                std::string deviceName = pDeviceIter->first;
+
+                Silecs::Device *device = pDeviceIter->second;
+                Utils::logInfo(messageConsole_,"found device: '" + QString::fromStdString(deviceName) + "' in parameter-file");
+
+                // add device on the tree
+                Item *deviceItem = Utils::addTreeItem(plcItem,QString::fromStdString(deviceName),"",QString::fromStdString(DEVICE_TYPE),device,":/Images/DEV.png");
+
+                // get register List for the current device
+                std::string registerList = device->getRegisterList();
+                istringstream registerListSplitted(registerList);
+
+                do
+                {
+                    std::string registerName;
+                    registerListSplitted >> registerName;
+                    Utils::logInfo(messageConsole_,"found Register: '" + QString::fromStdString(registerName) + "' in parameter file");
+                    //avoid last empty register
+                    if(registerName.compare("")==0) break;
+
+                    Silecs::Register *reg = device->getRegister(registerName);
+
+                    Item *registerItem = Utils::addTreeItem(deviceItem,QString::fromStdString(registerName),"",QString::fromStdString(REGISTER_TYPE),reg,":/Images/REG.png" );
+
+                    // Set the block name
+                    registerItem->setText(1 , QString::fromStdString(reg->getBlockName()));
+
+                    // Color background of input and output buffer
+                    registerItem->setBackgroundColor(2,QColor(255,255,204));//light yellow
+                    registerItem->setBackgroundColor(3,QColor(204,255,255));//light blue
+
+                }while(registerListSplitted);
+            }
+        } // END OF PLC LOOP
+    }
+    catch (const Silecs::SilecsException& ex)
+    {
+    	Utils::logError(messageConsole_,"getTreeroot - '" + QString::fromStdString(ex.what()));
+        return NULL;
+    }
+    catch(...)
+    {
+    	Utils::logError(messageConsole_,"getTreeroot - Unknown Error '");
+        return NULL;
+    }
+
+    // Reset the number of connected PLC
+    this->counterConnectedPLC =0;
+    return root;
+}
+
+
+void silecsModule::setScalarDataInDeviceFromItem(Item *currentItem, std::string blockName) throw (std::string*)
+{
+    Silecs::Device* device = (Silecs::Device*)(currentItem->getLinkedObject());
+
+    // PLC and device name just for error messages
+    std::string plcName = ((Silecs::PLC*)dynamic_cast<Item*>(currentItem->parent())->getLinkedObject())->getName();
+    std::string deviceName = device->getLabel();
+
+    std::string registerList = device->getRegisterList();
+    istringstream registerListSplitted(registerList);
+
+    int registerIndex = -1;
+    do
+    {
+        registerIndex++;
+        std::string registerName;
+        registerListSplitted >> registerName;
+
+        qDebug() << "get Register"<<QString::fromStdString(registerName);
+        //avoid last empty register
+
+        if(registerName.compare("")==0) break;
+
+        Silecs::Register *reg = device->getRegister(registerName);
+
+        // analyse just the register within the selected block
+        if(reg->getBlockName().compare(blockName)!=0)
+        {
+            qDebug() << "Continue";
+            continue;
+        }
+
+        std::string stringValue = currentItem->child(registerIndex)->text(3).toStdString();
+
+        Silecs::FormatType format = reg->getFormat();
+
+        switch(format)
+        {
+            case uInt8:
+            {
+                if(reg->isScalar())
+                {
+                    qDebug() << "uInt8";
+                    //Casting to uint16 and later to uint 8 to avoid it being converted for his ASCII character
+                    uint16_t val;
+                    if(!from_string<uint16_t>(val, stringValue, std::dec))
+                    {
+                        qDebug()<< "Conversion from string to unsigned uInt8 failed";
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt8");
+                    }
+                    reg->setValUInt8((uint16_t)val);
+                }
+                break;
+            }
+
+            case Int8:
+            {
+                if(reg->isScalar())
+                {
+                    qDebug() << "Int8";
+                    int8_t val;
+                    if(stringValue.length()!=1)
+                    {
+                        qDebug()<< "Conversion from string to Int8 failed";
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int8 ");
+                    }
+                    else
+                    {
+                        val = (int8_t)stringValue[0];
+                    }
+                    reg->setValInt8(val);
+                }
+                break;
+            }
+
+            case uInt16:
+            {
+                if(reg->isScalar())
+                {
+                    qDebug() << "uInt16";
+                    uint16_t val;
+                    if(!from_string<uint16_t>(val, stringValue, std::dec))
+                    {
+                        qDebug()<< "Conversion from string to uInt16 failed";
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt16");
+                    }
+                    reg->setValUInt16(val);
+                }
+                break;
+            }
+
+            case Int16:
+            {
+                if(reg->isScalar())
+                {
+                    qDebug() << "Int16";
+                    int16_t val;
+                    if(!from_string<int16_t>(val, stringValue, std::dec))
+                    {
+                        qDebug()<< "Conversion from string to Int16 failed";
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int16");
+                    }
+                    reg->setValInt16(val);
+                }
+                break;
+            }
+
+            case uInt32:
+            {
+                if(reg->isScalar())
+                {
+                    qDebug() << "uInt32";
+                    uint32_t val;
+                    if(!from_string<uint32_t>(val, stringValue, std::dec))
+                    {
+                        qDebug()<< "Conversion from string to uInt32 failed";
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt32");
+                    }
+                    reg->setValUInt32(val);
+                }
+                break;
+            }
+
+            case Int32:
+            {
+                if(reg->isScalar())
+                {
+                    qDebug() << "Int32";
+                    int32_t val;
+                    if(!from_string<int32_t>(val, stringValue, std::dec))
+                    {
+                        qDebug()<< "Conversion from string to Int32 failed";
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int32");
+                    }
+                    reg->setValInt32(val);
+                }
+                break;
+            }
+
+            case uInt64:
+            {
+                if(reg->isScalar())
+                {
+                    qDebug() << "uInt64";
+                    uint64_t val;
+                    if(!from_string<uint64_t>(val, stringValue, std::dec))
+                    {
+                        qDebug()<< "Conversion from string to uInt64 failed";
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt64");
+                    }
+                    reg->setValUInt64(val);
+                }
+                break;
+            }
+
+            case Int64:
+            {
+                if(reg->isScalar())
+                {
+                    qDebug() << "Int64";
+                    int64_t val;
+                    if(!from_string<int64_t>(val, stringValue, std::dec))
+                    {
+                        qDebug()<< "Conversion from string to Int64 failed";
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int64");
+                    }
+                    reg->setValInt64(val);
+                }
+                break;
+            }
+
+            case Float32:
+            {
+                if(reg->isScalar())
+                {
+                    qDebug() << "Float32";
+                    float val;
+                    if(!from_string<float>(val, stringValue, std::dec))
+                    {
+                        qDebug()<< "Conversion from string to Float32 failed";
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Float32");
+                    }
+                    reg->setValFloat32(val);
+                }
+                break;
+            }
+
+            case Float64:
+            {
+                if(reg->isScalar())
+                {
+                    qDebug() << "Float64";
+                    double val;
+                    if(!from_string<double>(val, stringValue, std::dec))
+                    {
+                        qDebug()<< "Conversion from string to Float64 failed";
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Float64");
+                    }
+                    reg->setValFloat64(val);
+                }
+                break;
+            }
+            case String:
+            {
+                if(reg->isScalar())
+                {
+                    qDebug() << "String";
+                    reg->setValString(stringValue);
+                }
+                break;
+            }
+            case Date:
+            {
+                qDebug() << "Date";
+                break;
+            }
+        }
+    }while(registerListSplitted);
+}
+
+
+void silecsModule::setArrayRegValue(Item *currentItem, std::vector<QString> *dataVector)
+{
+    Silecs::Register* reg = (Silecs::Register*)currentItem->getLinkedObject();
+    Silecs::FormatType format = reg->getFormat();
+
+    //get device an plc name for message errors
+    std::string deviceName = ((Silecs::Device*)dynamic_cast<Item*>(currentItem->parent())->getLinkedObject())->getLabel();
+    std::string plcName = ((Silecs::PLC*)dynamic_cast<Item*>(currentItem->parent()->parent())->getLinkedObject())->getName();
+    std::string registerName = reg->getName();
+
+    // convert to the proper format
+    switch(format)
+    {
+        case uInt8:
+        {
+            Utils::logError(messageConsole_,"format = uInt8");
+            if(reg->isDoubleArray()) // is 2DArray
+            {
+                uint8_t vector[reg->getDimension1()][reg->getDimension2()];
+                uint16_t val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    for(unsigned long j=0; j<reg->getDimension2(); j++)
+                    {
+                        qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
+                        if(!from_string<uint16_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                            throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt8");
+                        else
+                            vector[i][j] = (uint8_t)val;
+                    }
+                }
+                reg->setValUInt8Array2D((const uint8_t*)vector,reg->getDimension1(),reg->getDimension2());
+                qDebug() << "uInt8 2D array set";
+            }
+            else
+            {
+                uint8_t vector[reg->getDimension1()];
+                // Cast first to uint16_t to avoid conversion to ASCII character
+                uint16_t val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    qDebug() << QString((*dataVector)[i]);
+                    if(!from_string<uint16_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt8");
+                    else
+                        vector[i] = (uint8_t)val;
+                }
+                reg->setValUInt8Array(vector,reg->getDimension1());
+                qDebug() << "uInt8 array set";
+            }
+            break;
+        }
+        case Int8:
+        {
+            qDebug() << "format = Char";
+            if(reg->isDoubleArray())
+            {
+                int8_t vector[reg->getDimension1()][reg->getDimension2()];
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    for(unsigned long j=0; j<reg->getDimension2(); j++)
+                    {
+                        qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
+                        if(QString((*dataVector)[i*reg->getDimension2()+j]).toStdString().length()!=1)
+                            throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int8");
+                        else
+                            vector[i][j] = QString((*dataVector)[i*reg->getDimension2()+j]).toStdString()[0];
+                    }
+                }
+                reg->setValInt8Array2D((const int8_t*)vector,reg->getDimension1(),reg->getDimension2());
+                qDebug() << "Int8 2D array set";
+            }
+            else
+            {
+                int8_t vector[reg->getDimension1()];
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    qDebug() << QString((*dataVector)[i]);
+                    if(QString((*dataVector)[i]).toStdString().length()!=1)
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int8");
+                    else
+                        vector[i] = QString((*dataVector)[i]).toStdString()[0];
+                }
+                reg->setValInt8Array(vector,reg->getDimension1());
+                qDebug() << "Int8 array set";
+            }
+            break;
+        }
+        case uInt16:
+        {
+            qDebug() << "format = uInt16";
+            if(reg->isDoubleArray())
+            {
+                uint16_t vector[reg->getDimension1()][reg->getDimension2()];
+                uint16_t val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    for(unsigned long j=0; j<reg->getDimension2(); j++)
+                    {
+                        qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
+                        if(!from_string<uint16_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                            throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt16");
+                        else
+                            vector[i][j] = val;
+                    }
+                }
+                reg->setValUInt16Array2D((const uint16_t*)vector,reg->getDimension1(),reg->getDimension2());
+                qDebug() << "uInt16 2D array set";
+            }
+            else
+            {
+                uint16_t vector[reg->getDimension1()];
+                uint16_t val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    qDebug() << QString((*dataVector)[i]);
+                    if(!from_string<uint16_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt16");
+                    else
+                        vector[i] = val;
+                }
+                reg->setValUInt16Array(vector,reg->getDimension1());
+                qDebug() << "uInt16 array set";
+            }
+            break;
+        }
+        case Int16:
+        {
+            qDebug() << "format = Int16";
+            if(reg->isDoubleArray())
+            {
+                int16_t vector[reg->getDimension1()][reg->getDimension2()];
+                int16_t val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    for(unsigned long j=0; j<reg->getDimension2(); j++)
+                    {
+                        qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
+                        if(!from_string<short>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                            throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int16");
+                        else
+                            vector[i][j] = val;
+                    }
+                }
+                reg->setValInt16Array2D((const int16_t*)vector,reg->getDimension1(),reg->getDimension2());
+                qDebug() << "Int16 2D array set";
+            }
+            else
+            {
+                int16_t vector[reg->getDimension1()];
+                int16_t val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    qDebug() << QString((*dataVector)[i]);
+                    if(!from_string<short>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int16");
+                    else
+                        vector[i] = val;
+                }
+                reg->setValInt16Array(vector,reg->getDimension1());
+                qDebug() << "Int16 array set";
+            }
+            break;
+        }
+        case uInt32:
+        {
+            qDebug() << "format = uInt32";
+            if(reg->isDoubleArray())
+            {
+                uint32_t vector[reg->getDimension1()][reg->getDimension2()];
+                uint32_t val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    for(unsigned long j=0; j<reg->getDimension2(); j++)
+                    {
+                        qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
+                        if(!from_string<uint32_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                            throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt32");
+                        else
+                            vector[i][j] = val;
+                    }
+                }
+                reg->setValUInt32Array2D((const uint32_t*)vector,reg->getDimension1(),reg->getDimension2());
+                qDebug() << "uInt32 2D array set";
+            }
+            else
+            {
+                uint32_t vector[reg->getDimension1()];
+                uint32_t val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    qDebug() << QString((*dataVector)[i]);
+                    if(!from_string<uint32_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt32");
+                    else
+                        vector[i] = val;
+                }
+                reg->setValUInt32Array(vector,reg->getDimension1());
+                qDebug() << "uInt32 array set";
+            }
+            break;
+        }
+        case Int32:
+        {
+            qDebug() << "format = Int32";
+            if(reg->isDoubleArray())
+            {
+                int32_t vector[reg->getDimension1()][reg->getDimension2()];
+                int32_t val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    for(unsigned long j=0; j<reg->getDimension2(); j++)
+                    {
+                        qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
+                        if(!from_string<int32_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                            throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int32");
+                        else
+                            vector[i][j] = val;
+                    }
+                }
+                reg->setValInt32Array2D((const int32_t*)vector,reg->getDimension1(),reg->getDimension2());
+                qDebug() << "Int32 2D array set";
+            }
+            else
+            {
+                int32_t vector[reg->getDimension1()];
+                int32_t val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    qDebug() << QString((*dataVector)[i]);
+                    if(!from_string<int32_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int32");
+                    else
+                        vector[i] = val;
+                }
+                reg->setValInt32Array(vector,reg->getDimension1());
+                qDebug() << "Int32 array set";
+            }
+            break;
+        }
+        case uInt64:
+        {
+            qDebug() << "format = uInt64";
+            if(reg->isDoubleArray())
+            {
+                uint64_t vector[reg->getDimension1()][reg->getDimension2()];
+                uint64_t val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    for(unsigned long j=0; j<reg->getDimension2(); j++)
+                    {
+                        qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
+                        if(!from_string<uint64_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                            throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt64");
+                        else
+                            vector[i][j] = val;
+                    }
+                }
+                reg->setValUInt64Array2D((const uint64_t*)vector,reg->getDimension1(),reg->getDimension2());
+                qDebug() << "uInt64 2D array set";
+            }
+            else
+            {
+                uint64_t vector[reg->getDimension1()];
+                uint64_t val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    qDebug() << QString((*dataVector)[i]);
+                    if(!from_string<uint64_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a uInt64");
+                    else
+                        vector[i] = val;
+                }
+                reg->setValUInt64Array(vector,reg->getDimension1());
+                qDebug() << "uInt64 array set";
+            }
+            break;
+        }
+        case Int64:
+        {
+            qDebug() << "format = Int64";
+            if(reg->isDoubleArray())
+            {
+                int64_t vector[reg->getDimension1()][reg->getDimension2()];
+                int64_t val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    for(unsigned long j=0; j<reg->getDimension2(); j++)
+                    {
+                        qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
+                        if(!from_string<int64_t>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                            throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int64");
+                        else
+                            vector[i][j] = val;
+                    }
+                }
+                reg->setValInt64Array2D((const int64_t*)vector,reg->getDimension1(),reg->getDimension2());
+                qDebug() << "Int64 2D array set";
+            }
+            else
+            {
+                int64_t vector[reg->getDimension1()];
+                int64_t val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    qDebug() << QString((*dataVector)[i]);
+                    if(!from_string<int64_t>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Int64");
+                    else
+                        vector[i] = val;
+                }
+                reg->setValInt64Array(vector,reg->getDimension1());
+                qDebug() << "Int64 array set";
+            }
+            break;
+        }
+        case Float32:
+        {
+            qDebug() << "format = Float32";
+            if(reg->isDoubleArray())
+            {
+                float vector[reg->getDimension1()][reg->getDimension2()];
+                float val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    for(unsigned long j=0; j<reg->getDimension2(); j++)
+                    {
+                        qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
+                        if(!from_string<float>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                            throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Float32");
+                        else
+                            vector[i][j] = val;
+                    }
+                }
+                reg->setValFloat32Array2D((const float*)vector,reg->getDimension1(),reg->getDimension2());
+                qDebug() << "Float32 2D array set";
+            }
+            else
+            {
+                float vector[reg->getDimension1()];
+                float val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    qDebug() << QString((*dataVector)[i]);
+                    if(!from_string<float>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Float32");
+                    else
+                        vector[i] = val;
+                }
+                reg->setValFloat32Array(vector,reg->getDimension1());
+                qDebug() << "Float32 array set";
+            }
+            break;
+        }
+        case Float64:
+        {
+            qDebug() << "format = Float64";
+            if(reg->isDoubleArray())
+            {
+                double vector[reg->getDimension1()][reg->getDimension2()];
+                double val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    for(unsigned long j=0; j<reg->getDimension2(); j++)
+                    {
+                        qDebug() << QString((*dataVector)[i*reg->getDimension2()+j]);
+                        if(!from_string<double>(val, QString((*dataVector)[i*reg->getDimension2()+j]).toStdString(), std::dec))
+                            throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Float64");
+                        else
+                            vector[i][j] = val;
+                    }
+                }
+                reg->setValFloat64Array2D((const double*)vector,reg->getDimension1(),reg->getDimension2());
+                qDebug() << "Float64 2D array set";
+            }
+            else
+            {
+                double vector[reg->getDimension1()];
+                double val;
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    qDebug() << QString((*dataVector)[i]);
+                    if(!from_string<double>(val, QString((*dataVector)[i]).toStdString(), std::dec))
+                        throw new std::string("Output buffer value of "+plcName+" / "+deviceName+" / "+registerName+ " must be a Float64");
+                    else
+                        vector[i] = val;
+                }
+                reg->setValFloat64Array(vector,reg->getDimension1());
+                qDebug() << "Float64 array set";
+            }
+            break;
+        }
+        case String:
+        {
+            qDebug() << "format = String";
+            if(reg->isDoubleArray())
+            {
+                void *vector = calloc(reg->getDimension1()*reg->getDimension2(), sizeof(void*));
+                std::string** stringVector = static_cast<std::string**>(vector);
+                for(unsigned long i=0; i<(reg->getDimension1()); i++)
+                {
+                    for(unsigned long j=0; j<reg->getDimension2(); j++)
+                    {
+                        stringVector[(i*reg->getDimension2())+j] = new std::string(((*dataVector)[(i*reg->getDimension2())+j]).toStdString());
+                    }
+                }
+                reg->setValStringArray2D((const std::string*)stringVector, reg->getDimension1(), reg->getDimension2());
+                qDebug() << "String 2D array set";
+                // cleanup
+                for (unsigned int i=0; i<(reg->getDimension1()*reg->getDimension2()); i++)
+                {
+                    delete stringVector[i];
+                }
+                free(vector);
+            }
+            else
+            {
+                std::string vector[reg->getDimension1()];
+                for(unsigned long i=0;i<reg->getDimension1();i++)
+                {
+                    vector[i] = ((*dataVector)[i]).toStdString();
+                }
+                reg->setValStringArray(vector, reg->getDimension1());
+                qDebug() << "String array set";
+            }
+            break;
+        }
+        default:
+        	Utils::logError(messageConsole_,"Error: no converter available for that format");
+    }
+}
+
+
+HeaderInformations* silecsModule::getHeaderInformations(std::string plcName, string parameterFile)
+{
+    HeaderInformations* headerInfos = new HeaderInformations();
+
+    std::cout << "getHeaderInformations " << __LINE__ << std::endl;
+    Silecs::Cluster *headerCluster  = silecsService->getCluster(HEADER_NAME,HEADER_VERSION);
+    std::cout << "getHeaderInformations " << __LINE__ << std::endl;
+    Silecs::PLC *plc         = headerCluster->getPLC(plcName, parameterFile);
+    std::cout << "getHeaderInformations " << __LINE__ << std::endl;
+    Silecs::Device *device   = plc->getDevice(HEADER_DEVICE);
+    std::cout << "getHeaderInformations " << __LINE__ << std::endl;
+    plc->connect(Silecs::MASTER_SYNCHRO,true); //connection will cause automatic Header registers uploading
+    std::cout << "getHeaderInformations " << __LINE__ << std::endl;
+    Silecs::Register *reg;
+    std::cout << "getHeaderInformations " << __LINE__ << std::endl;
+    // get/set release
+    reg    = device->getRegister(HEADER_RELEASE_REG);
+    std::cout << "getHeaderInformations " << __LINE__ << std::endl;
+    headerInfos->setheaderRelease(reg->getValString());
+    std::cout << "getHeaderInformations " << __LINE__ << std::endl;
+    // get/set release
+    reg    = device->getRegister(HEADER_OWNER_REG);
+    std::cout << "getHeaderInformations " << __LINE__ << std::endl;
+    headerInfos->setheaderOwner(reg->getValString());
+    std::cout << "getHeaderInformations " << __LINE__ << std::endl;
+    // get/set release
+    reg    = device->getRegister(HEADER_DATE_REG);
+    std::cout << "getHeaderInformations " << __LINE__ << std::endl;
+    headerInfos->setheaderDate(reg->getInputValAsString());
+    std::cout << "getHeaderInformations " << __LINE__ << std::endl;
+    // get/set release
+    // TODO: Fix checksum stuff for GSI
+    //reg    = device->getRegister(HEADER_CHECKSUM_REG);
+    //headerInfos->setHeaderChecksum(reg->getInputValAsString());
+    std::cout << "getHeaderInformations " << __LINE__ << std::endl;
+    // disconnect plc
+    if(plc->isConnected())
+        plc->disconnect();
+    std::cout << "getHeaderInformations " << __LINE__ << std::endl;
+    return headerInfos;
+}
+
+
+void silecsModule::updateClusterItem(Item *Cluster,bool updateInputBufferOnly)
+{
+    int numberOfPLC = Cluster->childCount();
+    for(int PLCIndex=0; PLCIndex < numberOfPLC;PLCIndex++)
+    {
+        this->updatePLCItem(dynamic_cast<Item*>(Cluster->child(PLCIndex)),updateInputBufferOnly);
+    }
+}
+
+
+void silecsModule::updatePLCItem(Item *PLCItem,bool updateInputBufferOnly)
+{
+    int numberOfdevice = PLCItem->childCount();
+    for(int deviceIndex=0; deviceIndex<numberOfdevice;deviceIndex++)
+    {
+        this->updateDeviceItem(dynamic_cast<Item*>(PLCItem->child(deviceIndex)),updateInputBufferOnly);
+    }
+}
+
+
+void silecsModule::updateDeviceItem(Item *deviceItem,bool updateInputBufferOnly)
+{
+    Silecs::Device *device = (Silecs::Device*)deviceItem->getLinkedObject();
+
+    int numberOfRegisters = deviceItem->childCount();
+    for(int regIndex=0;regIndex<numberOfRegisters;regIndex++)
+    {
+        // Get the register Item in the tree view
+        Item *regItem = dynamic_cast<Item*>(deviceItem->child(regIndex));
+        Silecs::Register *reg = device->getRegister(regItem->text(0).toStdString());
+
+        // PLC values
+        try
+        {
+            if(reg->hasInputAccess()) // is READ or READ+WRITE for silecs
+            {
+                if(reg->isScalar())
+                {
+                    // Display the value for scalar
+                    regItem->setText(2 , QString::fromStdString(reg->getInputValAsString()));
+                }
+                else
+                {
+                    // Display [...] for arrays
+                    regItem->setText(2 , "[...]");
+                }
+            }
+            else // is WRITE only for silecs
+            {
+                regItem->setText(2 , "WRITE-ONLY block");
+            }
+        }
+        catch (std::exception& ex)
+        {
+            regItem->setText(2 , "?");
+            std::ostringstream message;
+            message << "Impossible to read the input buffer value of - '" << regItem->text(0).toStdString() << "'";
+            Utils::logError(messageConsole_,QString::fromStdString(message.str()));
+        }
+
+        if(!updateInputBufferOnly)
+        {
+            // local values
+            try{
+                if(reg->hasOutputAccess()) // = is WRITE or READ+WRITE for silecs
+                {
+                    if(reg->isScalar())
+                    {
+                        // Display the value for scalar
+                        regItem->setText(3 , QString::fromStdString(reg->getOutputValAsString()));
+                    }
+                    else
+                    {
+                        // Display [...] for arrays
+                        regItem->setText(3 , "[...]");
+                    }
+                    // Output for type date not supported
+                    if(reg->getFormat()==Date)
+                    {
+                        regItem->setText(3 , "Date format not supported.");
+                    }
+                }
+                else // = is READ only for silecs
+                {
+                    regItem->setText(3 , "READ-ONLY block");
+                }
+
+            }
+            catch (std::exception& ex)
+            {
+                regItem->setText(3 , "?");
+                std::ostringstream message;
+                message << "Impossible to read the output buffer value of - '" << regItem->text(0).toStdString() << "'";
+                Utils::logError(messageConsole_,QString::fromStdString(message.str()));
+            }
+        }
+    }
+}
+
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.h b/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.h
new file mode 100755
index 0000000000000000000000000000000000000000..d89b473c7bbdbad72d4db472980e2f283c368553
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/silecsmodule.h
@@ -0,0 +1,131 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef SILECSMODULE_H
+#define SILECSMODULE_H
+
+#ifndef _Pow_PLC_SilecsModule_H_ // header encapsulation
+#define _Pow_PLC_SilecsModule_H_
+
+#include <QtGui>
+#include <QtCore>
+
+#include <silecs-communication/interface/core/SilecsService.h>
+
+#include <silecs-diagnostic/constants.h>
+#include <silecs-diagnostic/diagnostictoolmainview.h>
+#include <silecs-diagnostic/headerinformations.h>
+#include <silecs-diagnostic/item.h>
+#include <silecs-diagnostic/utils.h>
+
+#include <string>
+#include <cstdlib>
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+
+using namespace Silecs;
+
+enum LogTopic{ERROR, DEBUG, SETUP, ALLOC, LOCK, COMM, SEND, RECV, DATA, DIAG };
+
+class silecsModule
+{
+private:
+    Silecs::Service* silecsService;
+    Silecs::Cluster* silecsCluster;
+
+    /**
+      * Add an element to the tree
+      */
+    QTreeWidgetItem* addTreeItem(QTreeWidgetItem *parent,QString name ,QString description);
+
+public:
+
+    /**
+      * Constructor. Get the SILECS service from the library
+      */
+    silecsModule(std::string logParam, QTextBrowser *messageConsole);
+
+    /**
+      * setLogTopics from the service
+      */
+    void setLogTopics(std::string logParam);
+
+    bool isDebugLogEnabled();
+    void enableDebugLog();
+
+    /**
+      * Denstructor. Remove the SILECS service from the library
+      */
+    ~silecsModule();
+
+    /**
+      *Generate the empty entire tree
+      */
+    Item *generateTree(string className, string deployFile);
+
+    /**
+      * Set the device with the proper scalar data converting
+      * from the string present in the GUI
+      * in case of error returns a string exception with the message
+      */
+    void setScalarDataInDeviceFromItem(Item *currentItem, std::string blockName) throw (std::string*);
+
+    /**
+      * Set the register with the proper data converting
+      * from the string present in the GUI
+      * in case of error returns a string exception with the message
+      */
+    void setArrayRegValue(Item *currentItem,std::vector<QString> *dataVector);
+
+    /**
+     * Updates the input and output values of all the register
+     * for the given device Item without any other impact on the GUI
+     */
+    void updateDeviceItem(Item *deviceItem,bool updateInputBufferOnly);
+
+    /**
+     * Updates the input and output values of all the register
+     * for the given PLC Item without any other impact on the GUI
+     */
+    void updatePLCItem(Item *PLCItem,bool updateInputBufferOnly);
+
+    /**
+     * Updates the input and output values of all the register
+     * for the given cluster Item without any other impact on the GUI
+     */
+    void updateClusterItem(Item *Cluster,bool updateInputBufferOnly);
+
+    /**
+      * Get Header for the given plc name
+      * return a heade info with all the data set
+      */
+    HeaderInformations* getHeaderInformations(std::string plcName, string parameterFile);
+
+    /**
+      * Count the number of PLC connected
+      */
+    int counterConnectedPLC;
+
+    QTextBrowser *messageConsole_;
+
+private:
+
+    bool debugLoggingEnabled_;
+
+};
+
+#endif // end of header encapsulation _Pow_PLC_SilecsModule_H_
+#endif // SILECSMODULE_H
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/stderrredirect.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/stderrredirect.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..96999045d8cad2921a16e11a449c77f1e2062178
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/stderrredirect.cpp
@@ -0,0 +1,84 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-diagnostic/stderrredirect.h>
+
+#include <QtCore>
+#include <QtGui>
+#include <QMessageBox>
+
+
+StdErrRedirect::StdErrRedirect(QTextEdit *errorLog,QObject *parent): QObject(parent)
+{
+    // Store the pointer to the error log window
+    m_errorLog = errorLog;
+
+    // Create a temporary filename: first find the path:
+    tmpFileNameQtFormat = QDir::tempPath();
+
+    // Make sure the closing slash is present:
+    if (!tmpFileNameQtFormat.endsWith(QChar('/')))
+        tmpFileNameQtFormat.append(QChar('/'));
+
+    // Add the file name itself:
+    tmpFileNameQtFormat.append("QtDiagDump_"+QString::number(QCoreApplication::applicationPid()));
+
+    qDebug()<< "file ->" << tmpFileNameQtFormat;
+
+    // Obtain a version of the filename in the operating system's native format:
+    tmpFileNameNativeFormat = QDir::toNativeSeparators(tmpFileNameQtFormat);
+
+    // if file exists because previous section crashed i rename the file ***.old
+    QFile fileToRename(tmpFileNameQtFormat);
+    if(fileToRename.exists())
+        fileToRename.rename(tmpFileNameQtFormat+".old");
+
+    // Set up redirection to this file:
+    FILE* fdesc = freopen(tmpFileNameNativeFormat.toAscii().constData(), "a+", stderr);
+    fdesc = NULL; //just defined to avoid L866 warning
+
+    // Initialise the QFileSystemWatcher:
+    connect(&watcher, SIGNAL(fileChanged(const QString &)),
+            this,     SLOT(fileChanged(const QString &)));
+    watcher.addPath(tmpFileNameQtFormat);
+
+    tmp.setFileName(tmpFileNameQtFormat);
+}
+
+StdErrRedirect::~StdErrRedirect()
+{
+    // Ensure the temporary file is properly deleted:
+    fclose(stderr);
+    tmp.close();
+    tmp.open(QIODevice::ReadWrite);
+    tmp.remove();
+}
+
+void StdErrRedirect::fileChanged(const QString &filename)
+{
+    (void)filename;
+    tmp.open(QIODevice::ReadOnly);
+    QTextStream stream(&tmp);
+    QString content = stream.readAll();
+    tmp.close();
+
+    // Identify what's new, and just send this to the window:
+    int newchars = content.size() - oldContent.size();
+    if (newchars)
+    {
+        m_errorLog -> append(content.right(newchars));
+        oldContent = content;
+    }
+}
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/stderrredirect.h b/silecs-diagnostic-cpp/src/silecs-diagnostic/stderrredirect.h
new file mode 100644
index 0000000000000000000000000000000000000000..59fc0ab47c35f2541d02f12d261a805a760d69bd
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/stderrredirect.h
@@ -0,0 +1,49 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef STDERRREDIRECT_H
+#define STDERRREDIRECT_H
+
+#include <QObject>
+#include <QTextEdit>
+#include <QtCore>
+
+
+class StdErrRedirect : public QObject
+{
+    Q_OBJECT
+
+public:
+    // Constructor
+    StdErrRedirect();
+    StdErrRedirect(QTextEdit *errorLog, QObject   *parent = NULL);
+
+    // Destructor
+    ~StdErrRedirect();
+
+private slots:
+    void fileChanged(const QString &filename);
+
+private:
+    QFile              tmp;
+    QFileSystemWatcher watcher;
+    QString            tmpFileNameQtFormat;
+    QString            tmpFileNameNativeFormat;
+
+    QTextEdit *m_errorLog;
+    QString   oldContent;
+};
+
+#endif // STDERRREDIRECT_H
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/utils.cpp b/silecs-diagnostic-cpp/src/silecs-diagnostic/utils.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..2e736481216641175a4f3b2e79cde44488e0c895
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/utils.cpp
@@ -0,0 +1,336 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#include <silecs-diagnostic/utils.h>
+#include <silecs-diagnostic/silecsmodule.h>
+
+extern silecsModule *mysilecs;
+
+void Utils::logError(QTextBrowser* errorConsole, QString message)
+{
+	errorConsole->insertHtml("<font color='red'>DIAG-TOOL [ERROR] " + message + "</font><br>");
+	errorConsole->verticalScrollBar()->setValue(errorConsole->verticalScrollBar()->maximum());
+}
+
+void Utils::logInfo(QTextBrowser* errorConsole, QString message)
+{
+	errorConsole->insertHtml("<font color='black'>DIAG-TOOL [INFO] " + message + "</font><br>");
+	errorConsole->verticalScrollBar()->setValue(errorConsole->verticalScrollBar()->maximum());
+}
+
+void Utils::logDebugIf(QTextBrowser* errorConsole, QString message)
+{
+	if( mysilecs->isDebugLogEnabled())
+	{
+		errorConsole->insertHtml("<font color='black'>DIAG-TOOL [DEBUG] " + message + "</font><br>");
+		errorConsole->verticalScrollBar()->setValue(errorConsole->verticalScrollBar()->maximum());
+	}
+}
+
+//convert integer to string
+std::string Utils::convertInt(int number)
+{
+    char tmp[32];
+    sprintf(tmp, "%d", number);
+    return tmp;
+}
+
+//convert long to string
+std::string Utils::convertLong(long number)
+{
+    char tmp[32];
+    sprintf(tmp, "%ld", number);
+    return tmp;
+}
+
+Item* Utils::addTreeItem(Item *parent,QString name ,QString description, QString type, void* linkedObject,QString icon)
+{
+    Item *itm = new Item(linkedObject);
+    itm->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled );
+    itm->setText(0,name);
+    itm->setText(2,description);
+    itm->setWhatsThis(0,type);
+
+    if(icon.compare("")!=0)
+        itm->setIcon(0,QIcon(QPixmap(icon)));
+
+    parent->addChild(itm);
+    return itm;
+}
+
+char* Utils::chop(char *string)
+{
+    size_t i, len;
+    len = strlen(string);
+    char *newstring;
+    newstring = (char *)malloc(len);
+    for(i = 0; i < strlen(string)-1; i++)
+    {
+        newstring[i] = string[i];
+    }
+    newstring[len] = '\0';
+
+    return newstring;
+}
+
+template <class T>bool from_string(T& t,const std::string& s, std::ios_base& (*f)(std::ios_base&))
+{
+    std::istringstream iss(s);
+    return !(iss >> f >> t).fail();
+}
+
+void Utils::displayClusterInformation(Silecs::Cluster *cluster,QTextEdit *console)
+{
+    std::string text = "";
+
+    text.append("<h3>Cluster general information</h3>");
+    text.append("<ul>");
+    text.append("<li>Class name:    "+cluster->getClassName()+"</li>");
+    text.append("<li>Class version: "+cluster->getClassVersion()+"</li>");
+    text.append("<li>Host name:     "+cluster->getHostName()+"</li>");
+    text.append("</ul>");
+
+    console->setText(QString::fromStdString(text));
+
+}
+
+void Utils::displayPLCInformation(Silecs::PLC *plc,QTextEdit *console)
+{
+    std::string text = "";
+
+    //TODO: GSI Add Header Info
+    if(plc->isConnected())
+    {
+//        text.append("<h3><font color ='green'>This PLC is currently connected</font></h3><hr/>");
+//
+//        HeaderInformations *headerInfo = mysilecs->getHeaderInformations(plc->getName(),plc->getParamsFileName());
+//        text.append("<h3><font color ='green'>PLC Runtime information</font></h3>");
+//        text.append("<ul>");
+//        text.append("<li>PLC HEADER DATA uploaded from: "+plc->getName()+"</li>");
+//        text.append("<li>Software Release: "+headerInfo->getheaderRelease()+"</li>");
+//        text.append("<li>Mapping Owner:    "+headerInfo->getheaderOwner()+"</li>");
+//        text.append("<li>Mapping Checksum: "+headerInfo->getHeaderChecksum()+"</li>");
+//        text.append("<li>Generation Date:  "+headerInfo->getheaderDate()+"</li>");
+//        text.append("</ul><hr/>");
+//
+//        delete headerInfo;
+    }
+    else
+        text.append("<h3>This PLC is currently disconnected</h3><hr/>");
+
+    text.append("<h3>PLC general information</h3>");
+    text.append("<ul>");
+    text.append("<li>Name:    "+plc->getName()+"</li>");
+    text.append("<li>Address: "+plc->getIPAddress()+"</li>");
+    text.append("<li>Brand:   "+plc->getBrand()+"</li>");
+    text.append("<li>Model:   "+plc->getModel()+"</li>");
+    text.append("<li>Owner:   "+plc->getLocalOwner()+"</li>");
+    text.append("</ul><hr/>");
+
+    text.append("<h3>PLC configuration information</h3>");
+    text.append("<ul>");
+    text.append("<li>Protocol type: "+plc->getProtocolType()+"</li>");
+    text.append("<li>Protocol mode: "+plc->getProtocolMode()+"</li>");
+    text.append("<li>Base address:  "+convertLong(plc->getBaseAddress())+"</li>");
+    text.append("</ul><hr/>");
+
+    text.append("<h3>PLC generation information</h3>");
+    text.append("<ul>");
+    text.append("<li>Release:  "+plc->getLocalRelease()+"</li>");
+    text.append("<li>Date:     "+plc->getLocalDate()+"</li>");
+    text.append("<li>Checksum: "+convertLong(plc->getLocalChecksum())+"</li>");
+    text.append("</ul><hr/>");
+
+    console->setText(QString::fromStdString(text));
+}
+
+void Utils::displayDeviceInformation(Silecs::Device *device,QTextEdit *console)
+{
+    std::string text = "";
+
+    text.append("<h3>Device general information</h3>");
+    text.append("<ul>");
+    text.append("<li>Name:    "+device->getLabel()+"</li>");
+    text.append("</ul>");
+
+    console->setText(QString::fromStdString(text));
+}
+
+void Utils::displayRegisterInformation(Silecs::Register *reg,QTextEdit *console)
+{
+    std::string text = "";
+
+    text.append("<h3>Register general information</h3>");
+    text.append("<ul>");
+    text.append("<li>Name:        "+reg->getName()+"</li>");
+    text.append("<li>Format:      "+reg->getFormatAsString()+"</li>");
+    if(reg->getFormat() == String)
+        text.append("<li>String length: "+convertLong(reg->getLength())+"</li>");
+    text.append("<li>Dimension1:   "+convertLong(reg->getDimension1())+"</li>");
+    text.append("<li>Dimension2:  "+convertLong(reg->getDimension2())+"</li>");
+    text.append("<li>Block name:  "+reg->getBlockName()+"</li>");
+    text.append("<li>Last update: "+reg->getTimeStampAsString()+"</li>");
+
+    // Access method
+    if(reg->hasInputAccess() && reg->hasOutputAccess())
+        text.append("<li>Access method: Read / Write </li>");
+    else
+    {
+        if(reg->hasInputAccess()) text.append("<li>Access method: Read only </li>");
+        else text.append("<li>Access method: Write only </li>");
+    }
+
+    text.append("<li>Synchronization method:  "+reg->getSynchroTypeAsString()+"</li>");
+
+    // Retentive volatile
+    if(reg->isRetentive())
+        text.append("<li>Storage method: Retentive</li>");
+    else
+        text.append("<li>Storage method: Volatile</li>");
+
+    text.append("</ul>");
+
+    console->setText(QString::fromStdString(text));
+
+}
+
+void Utils::displayRegisterValue(Silecs::Register *reg,
+                                 QLabel *binValueLabel,
+                                 QLabel *hexValueLabel,
+                                 QLabel *decValueLabel,
+                                 QLabel *asciiValueLabel
+                                 )
+{
+
+    if(!reg->hasInputAccess()){
+        binValueLabel->setText("--Write only register--");
+        hexValueLabel->setText("--Write only register--");
+        decValueLabel->setText("--Write only register--");
+        asciiValueLabel->setText("--Write only register--");
+    }
+    else
+    {
+        // The register has input access
+        if(reg->getDimension1()>1 || reg->getDimension2()>1)
+        {
+            binValueLabel->setText("--Vector--");
+            hexValueLabel->setText("--Vector--");
+            decValueLabel->setText("--Vector--");
+            asciiValueLabel->setText("--Vector--");
+        }
+        else{
+            //Scalar with input access
+            switch(reg->getFormat())
+            {
+                case uInt8:
+                {
+
+                    binValueLabel->setText(QObject::tr("%1").arg(reg->getValUInt8(), 0, 2));
+                    hexValueLabel->setText(QObject::tr("%1").arg(reg->getValUInt8(), 0, 16));
+                    decValueLabel->setText(QObject::tr("%1").arg(reg->getValUInt8(), 0, 10));
+                    //QString temp;
+                    //asciiValueLabel->setText(temp.sprintf("%c",reg->getValUInt8()));
+                    QChar c = reg->getValUInt8();
+                    //if(!c.isPrint())
+                    //    c='?';
+                    //asciiValueLabel->setText(QObject::tr("%1").arg(c));
+                    asciiValueLabel->setText(c.isPrint() ? QObject::tr("%1").arg(c):"--Not printable--");
+
+                    break;
+                }
+                case Int8:
+                {
+                    binValueLabel->setText(QObject::tr("%1").arg(reg->getValInt8(), 0, 2));
+                    hexValueLabel->setText(QObject::tr("%1").arg(reg->getValInt8(), 0, 16));
+                    decValueLabel->setText(QObject::tr("%1").arg(reg->getValInt8(), 0, 10));
+                    QChar c = reg->getValInt8();
+                    asciiValueLabel->setText(c.isPrint() ? QObject::tr("%1").arg(c):"--Not printable--");
+                    break;
+                }
+                case uInt16:
+                {
+                    binValueLabel->setText(QObject::tr("%1").arg(reg->getValUInt16(), 0, 2));
+                    hexValueLabel->setText(QObject::tr("%1").arg(reg->getValUInt16(), 0, 16));
+                    decValueLabel->setText(QObject::tr("%1").arg(reg->getValUInt16(), 0, 10));
+                    asciiValueLabel->setText("--Not relevant--");
+                    break;
+                }
+
+                case Int16:
+                {
+                    binValueLabel->setText(QObject::tr("%1").arg(reg->getValInt16(), 0, 2));
+                    hexValueLabel->setText(QObject::tr("%1").arg(reg->getValInt16(), 0, 16));
+                    decValueLabel->setText(QObject::tr("%1").arg(reg->getValInt16(), 0, 10));
+                    asciiValueLabel->setText("--Not relevant--");
+                    break;
+                }
+
+                case uInt32:
+                {
+                    binValueLabel->setText(QObject::tr("%1").arg(reg->getValUInt32(), 0, 2));
+                    hexValueLabel->setText(QObject::tr("%1").arg(reg->getValUInt32(), 0, 16));
+                    decValueLabel->setText(QObject::tr("%1").arg(reg->getValUInt32(), 0, 10));
+                    asciiValueLabel->setText("--Not relevant--");
+                    break;
+                }
+
+                case Int32:
+                {
+                    binValueLabel->setText(QObject::tr("%1").arg(reg->getValInt32(), 0, 2));
+                    hexValueLabel->setText(QObject::tr("%1").arg(reg->getValInt32(), 0, 16));
+                    decValueLabel->setText(QObject::tr("%1").arg(reg->getValInt32(), 0, 10));
+                    asciiValueLabel->setText("--Not relevant--");
+                    break;
+                }
+
+                case uInt64:
+                {
+                    binValueLabel->setText(QObject::tr("%1").arg(reg->getValUInt64(), 0, 2));
+                    hexValueLabel->setText(QObject::tr("%1").arg(reg->getValUInt64(), 0, 16));
+                    decValueLabel->setText(QObject::tr("%1").arg(reg->getValUInt64(), 0, 10));
+                    asciiValueLabel->setText("--Not relevant--");
+                    break;
+                }
+
+                case Int64:
+                {
+                    binValueLabel->setText(QObject::tr("%1").arg(reg->getValInt64(), 0, 2));
+                    hexValueLabel->setText(QObject::tr("%1").arg(reg->getValInt64(), 0, 16));
+                    decValueLabel->setText(QObject::tr("%1").arg(reg->getValInt64(), 0, 10));
+                    asciiValueLabel->setText("--Not relevant--");
+                    break;
+                }
+
+                case String:
+                {
+                    binValueLabel->setText("--Not relevant--");
+                    hexValueLabel->setText("--Not relevant--");
+                    decValueLabel->setText("--Not relevant--");
+                    asciiValueLabel->setText("--Not relevant--");
+                    break;
+                }
+
+                default:// Float32,Float64,Date
+                {
+                    binValueLabel->setText("--Not relevant--");
+                    hexValueLabel->setText("--Not relevant--");
+                    decValueLabel->setText("--Not relevant--");
+                    asciiValueLabel->setText("--Not relevant--");
+                    break;
+                }
+            }
+        }
+    }
+}
diff --git a/silecs-diagnostic-cpp/src/silecs-diagnostic/utils.h b/silecs-diagnostic-cpp/src/silecs-diagnostic/utils.h
new file mode 100755
index 0000000000000000000000000000000000000000..45eee94005cac006ce36d23773e6a3241e3615b5
--- /dev/null
+++ b/silecs-diagnostic-cpp/src/silecs-diagnostic/utils.h
@@ -0,0 +1,110 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <string>
+#include <map>
+#include <vector>
+#include <sstream>
+#include <iostream>
+
+#include <QtCore>
+#include <QtGui>
+#include <QObject>
+#include <QTextEdit>
+
+#include <silecs-diagnostic/item.h>
+
+namespace Silecs
+{
+	class Cluster;
+	class Register;
+	class Device;
+	class PLC;
+}
+
+namespace Utils {
+
+	void logError(QTextBrowser* errorConsole, QString message);
+
+	void logInfo(QTextBrowser* errorConsole, QString message);
+
+	void logDebugIf(QTextBrowser* errorConsole, QString message);
+
+    /**
+     * Convert a integer number in the equivalent string
+     */
+    std::string convertInt(int number);
+
+    /**
+     * Convert a long number in the equivalent string
+     */
+    std::string convertLong(long number);
+
+    /**
+     * Add an element to the tree
+     */
+    Item* addTreeItem(Item *parent,QString name ,QString description, QString type, void* linkedObject,QString icon);
+
+    /**
+     * Remove the last element from a string
+     */
+    char* chop(char *string);
+
+    /**
+     * Convert from string to a generic numeric type
+     */
+    template <class T>bool from_string(T& t,const std::string& s, std::ios_base& (*f)(std::ios_base&));
+
+    /**
+     * Display information about the cluster in the given console
+     */
+    void displayClusterInformation(Silecs::Cluster *cluster,QTextEdit *console);
+
+    /**
+     * Display information about the plc in the given console
+     */
+    void displayPLCInformation(Silecs::PLC *plc,QTextEdit *console);
+
+    /**
+     * Display information about the device in the given console
+     */
+    void displayDeviceInformation(Silecs::Device *device,QTextEdit *console);
+
+    /**
+     * Display information about the register in the given console
+     */
+    void displayRegisterInformation(Silecs::Register *reg,QTextEdit *console);
+
+    /**
+     * Display register value in multiple formats
+     */
+    void displayRegisterValue(Silecs::Register *reg,
+                              QLabel *binValueLabel,
+                              QLabel *hexValueLabel,
+                              QLabel *decValueLabel,
+                              QLabel *asciiValueLabel
+                              );
+
+    /**
+     * Return a map of the list of cluster the user can access
+     * < ClassName, ClassVersionList >
+     */
+    std::map<std::string, std::vector<std::string>* >getUserAccessibleCluster(std::string userName);
+
+}
+#endif // UTILS_H
diff --git a/silecs-eclipse-plugin-feature/.project b/silecs-eclipse-plugin-feature/.project
new file mode 100644
index 0000000000000000000000000000000000000000..a49d71b111859da650459f0e33c93f24b6a607b8
--- /dev/null
+++ b/silecs-eclipse-plugin-feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>silecs-eclipse-plugin-feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/silecs-eclipse-plugin-feature/build.properties b/silecs-eclipse-plugin-feature/build.properties
new file mode 100644
index 0000000000000000000000000000000000000000..64f93a9f0b7328eb563aa5ad6cec7f828020e124
--- /dev/null
+++ b/silecs-eclipse-plugin-feature/build.properties
@@ -0,0 +1 @@
+bin.includes = feature.xml
diff --git a/silecs-eclipse-plugin-feature/feature.xml b/silecs-eclipse-plugin-feature/feature.xml
new file mode 100644
index 0000000000000000000000000000000000000000..14d3b07c2d3ead3e1661234907f73e524dfe7640
--- /dev/null
+++ b/silecs-eclipse-plugin-feature/feature.xml
@@ -0,0 +1,746 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="silecsEclipsePluginFeature"
+      label="Silecs-eclipse-plugin-feature"
+      version="1.0.0.qualifier">
+
+   <description url="http://www.example.com/description">
+      SILECS Eclipse Plugin
+   </description>
+
+   <copyright url="http://www.example.com/copyright">
+      Copyright 2016 CERN and GSI
+
+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 &lt;http://www.gnu.org/licenses/&gt;.
+   </copyright>
+
+   <license url="http://www.gnu.org/licenses">
+      GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
+ 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&apos; and authors&apos; protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users&apos; and
+authors&apos; 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&apos; 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.
+
+  &quot;This License&quot; refers to version 3 of the GNU General Public License.
+
+  &quot;Copyright&quot; also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  &quot;The Program&quot; refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as &quot;you&quot;.  &quot;Licensees&quot; and
+&quot;recipients&quot; may be individuals or organizations.
+
+  To &quot;modify&quot; 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 &quot;modified version&quot; of the
+earlier work or a work &quot;based on&quot; the earlier work.
+
+  A &quot;covered work&quot; means either the unmodified Program or a work based
+on the Program.
+
+  To &quot;propagate&quot; 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 &quot;convey&quot; 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 &quot;Appropriate Legal Notices&quot;
+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 &quot;source code&quot; for a work means the preferred form of the work
+for making modifications to it.  &quot;Object code&quot; means any non-source
+form of a work.
+
+  A &quot;Standard Interface&quot; 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 &quot;System Libraries&quot; 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
+&quot;Major Component&quot;, 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 &quot;Corresponding Source&quot; 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&apos;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&apos; 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&apos;s
+users, your or third parties&apos; legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program&apos;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
+    &quot;keep intact all notices&quot;.
+
+    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
+&quot;aggregate&quot; if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation&apos;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 &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, 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, &quot;normally used&quot; 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.
+
+  &quot;Installation Information&quot; 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.
+
+  &quot;Additional permissions&quot; 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 &quot;further
+restrictions&quot; 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 &quot;entity transaction&quot; 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&apos;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 &quot;contributor&quot; 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&apos;s &quot;contributor version&quot;.
+
+  A contributor&apos;s &quot;essential patent claims&quot; 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, &quot;control&quot; 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&apos;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 &quot;patent license&quot; 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 &quot;grant&quot; 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.  &quot;Knowingly relying&quot; means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient&apos;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 &quot;discriminatory&quot; 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&apos; 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 &quot;or any later version&quot; 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&apos;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 &quot;AS IS&quot; 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 &quot;copyright&quot; line and a pointer to where the full notice is found.
+
+    &lt;one line to give the program&apos;s name and a brief idea of what it does.&gt;
+    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
+
+    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 &lt;http://www.gnu.org/licenses/&gt;.
+
+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:
+
+    &lt;program&gt;  Copyright (C) &lt;year&gt;  &lt;name of author&gt;
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w&apos;.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c&apos; for details.
+
+The hypothetical commands `show w&apos; and `show c&apos; should show the appropriate
+parts of the General Public License.  Of course, your program&apos;s commands
+might be different; for a GUI interface, you would use an &quot;about box&quot;.
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a &quot;copyright disclaimer&quot; for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+&lt;http://www.gnu.org/licenses/&gt;.
+
+  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
+&lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.
+   </license>
+
+   <requires>
+      <import plugin="org.eclipse.ui"/>
+      <import plugin="org.eclipse.core.runtime"/>
+      <import plugin="org.eclipse.ui.workbench"/>
+      <import plugin="org.eclipse.core.resources"/>
+      <import plugin="org.eclipse.ui.ide"/>
+      <import plugin="org.eclipse.ui.editors"/>
+      <import plugin="org.eclipse.wst.xml.core"/>
+      <import plugin="org.eclipse.wst.xml.ui"/>
+      <import plugin="org.eclipse.ui.navigator.resources"/>
+      <import plugin="org.eclipse.core.filesystem"/>
+      <import plugin="org.eclipse.ui.console"/>
+      <import plugin="org.eclipse.ui.views"/>
+      <import plugin="org.eclipse.wst.validation"/>
+      <import plugin="org.eclipse.wst.validation.infopop"/>
+      <import plugin="org.eclipse.wst.validation.ui"/>
+      <import plugin="org.eclipse.jface.text"/>
+      <import plugin="org.eclipse.wst.sse.ui"/>
+      <import plugin="org.eclipse.ui.workbench.texteditor"/>
+      <import plugin="org.eclipse.text"/>
+      <import plugin="org.eclipse.wst.sse.core"/>
+      <import plugin="org.eclipse.ui.navigator"/>
+      <import plugin="org.eclipse.xsd"/>
+      <import plugin="org.eclipse.wst.xsd.core"/>
+      <import plugin="org.eclipse.core.expressions"/>
+      <import plugin="org.eclipse.cdt"/>
+      <import plugin="org.eclipse.cdt.core"/>
+      <import plugin="org.eclipse.cdt.ui"/>
+      <import plugin="org.eclipse.cdt.managedbuilder.ui"/>
+      <import plugin="org.eclipse.ltk.core.refactoring"/>
+      <import plugin="org.eclipse.ltk.ui.refactoring"/>
+      <import plugin="org.eclipse.equinox.launcher"/>
+   </requires>
+
+   <plugin
+         id="silecs.eclipse.plugin"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/silecs-eclipse-plugin-update-site/.project b/silecs-eclipse-plugin-update-site/.project
new file mode 100644
index 0000000000000000000000000000000000000000..e9558b3fd21bb03479a7f7815581694fac94a1eb
--- /dev/null
+++ b/silecs-eclipse-plugin-update-site/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>silecs-eclipse-plugin-update-site</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.UpdateSiteBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.UpdateSiteNature</nature>
+	</natures>
+</projectDescription>
diff --git a/silecs-eclipse-plugin-update-site/artifacts.jar b/silecs-eclipse-plugin-update-site/artifacts.jar
new file mode 100644
index 0000000000000000000000000000000000000000..a4dc065cb54624162ab31ba014ff081382308c53
Binary files /dev/null and b/silecs-eclipse-plugin-update-site/artifacts.jar differ
diff --git a/silecs-eclipse-plugin-update-site/content.jar b/silecs-eclipse-plugin-update-site/content.jar
new file mode 100644
index 0000000000000000000000000000000000000000..8ea08081a8759cb54e8da3d4954de65a0d2c5541
Binary files /dev/null and b/silecs-eclipse-plugin-update-site/content.jar differ
diff --git a/silecs-eclipse-plugin-update-site/deliverToWebDav.sh b/silecs-eclipse-plugin-update-site/deliverToWebDav.sh
new file mode 100755
index 0000000000000000000000000000000000000000..c5ff0fe1e226fab7ac1578d3787e1e0b5194c23d
--- /dev/null
+++ b/silecs-eclipse-plugin-update-site/deliverToWebDav.sh
@@ -0,0 +1,29 @@
+#! /bin/bash
+
+kinit
+
+function copyFileToWebDav
+{
+
+cadaver -t <<EOF
+open https://www.acc.gsi.de/dav/eclipse-luna/silecs
+mput $1
+quit
+EOF
+
+}
+
+for file in features/*
+do
+    copyFileToWebDav $file
+done
+
+for file in plugins/*
+do
+    copyFileToWebDav $file
+done
+
+copyFileToWebDav artifacts.jar
+copyFileToWebDav content.jar
+copyFileToWebDav index.html
+copyFileToWebDav site.xml
\ No newline at end of file
diff --git a/silecs-eclipse-plugin-update-site/index.html b/silecs-eclipse-plugin-update-site/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..c6627db314105eedc477f199d603166222e9ec59
--- /dev/null
+++ b/silecs-eclipse-plugin-update-site/index.html
@@ -0,0 +1,60 @@
+<html>
+<head>
+<title>silecs-eclipse-plugin-update-site</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<style>@import url("web/site.css");</style>
+<script type="text/javascript">
+	var returnval = 0;
+	var stylesheet, xmlFile, cache, doc;
+	function init(){
+		// NSCP 7.1+ / Mozilla 1.4.1+ / Safari
+		// Use the standard DOM Level 2 technique, if it is supported
+		if (document.implementation && document.implementation.createDocument) {
+			xmlFile = document.implementation.createDocument("", "", null);
+			stylesheet = document.implementation.createDocument("", "", null);
+			if (xmlFile.load){
+				xmlFile.load("site.xml");
+				stylesheet.load("web/site.xsl");
+			} else {
+				alert("Document could not be loaded by browser.");
+			}
+			xmlFile.addEventListener("load", transform, false);
+			stylesheet.addEventListener("load", transform, false);
+		}
+		//IE 6.0+ solution
+		else if (window.ActiveXObject) {
+			xmlFile = new ActiveXObject("msxml2.DOMDocument.3.0");
+			xmlFile.async = false;
+			xmlFile.load("site.xml");
+			stylesheet = new ActiveXObject("msxml2.FreeThreadedDOMDocument.3.0");
+			stylesheet.async = false;
+			stylesheet.load("web/site.xsl");
+			cache = new ActiveXObject("msxml2.XSLTemplate.3.0");
+			cache.stylesheet = stylesheet;
+			transformData();
+		}
+	}
+	// separate transformation function for IE 6.0+
+	function transformData(){
+		var processor = cache.createProcessor();
+		processor.input = xmlFile;
+		processor.transform();
+		data.innerHTML = processor.output;
+	}
+	// separate transformation function for NSCP 7.1+ and Mozilla 1.4.1+ 
+	function transform(){
+		returnval+=1;
+		if (returnval==2){
+			var processor = new XSLTProcessor();
+			processor.importStylesheet(stylesheet); 
+			doc = processor.transformToDocument(xmlFile);
+			document.getElementById("data").innerHTML = doc.documentElement.innerHTML;
+		}
+	}
+</script>
+</head>
+<body onload="init();">
+<!--[insert static HTML here]-->
+<div id="data"><!-- this is where the transformed data goes --></div>
+</body>
+</html>
diff --git a/silecs-eclipse-plugin-update-site/install.sh b/silecs-eclipse-plugin-update-site/install.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b4af9786fe949b4f71e43ea6770602e3084452e6
--- /dev/null
+++ b/silecs-eclipse-plugin-update-site/install.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+set -e
+
+INSTALL_DIR=$1
+
+SCRIPT=$(readlink -f "$0")
+SCRIPTPATH=$(dirname "$SCRIPT")     # path where this script is located in
+
+mkdir -p ${INSTALL_DIR}
+cp -r ${SCRIPTPATH}/* ${INSTALL_DIR}
\ No newline at end of file
diff --git a/silecs-eclipse-plugin-update-site/site.xml b/silecs-eclipse-plugin-update-site/site.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9800b60a7bf9172c2832120614b96637bba287d0
--- /dev/null
+++ b/silecs-eclipse-plugin-update-site/site.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+   <feature url="features/silecsEclipsePluginFeature_1.0.0.201602241715.jar" id="silecsEclipsePluginFeature" version="1.0.0.201602241715">
+      <category name="0.9.0"/>
+   </feature>
+   <feature url="features/silecsEclipsePluginFeature_1.0.0.201604071714.jar" id="silecsEclipsePluginFeature" version="1.0.0.201604071714">
+      <category name="0.10.0"/>
+   </feature>
+   <feature url="features/silecsEclipsePluginFeature_1.0.0.201607261627.jar" id="silecsEclipsePluginFeature" version="1.0.0.201607261627">
+      <category name="1.0.0"/>
+   </feature>
+   <category-def name="0.9.0" label="0.9.0"/>
+   <category-def name="0.10.0" label="0.10.0"/>
+   <category-def name="1.0.0" label="1.0.0"/>
+</site>
diff --git a/silecs-eclipse-plugin-update-site/test.txt b/silecs-eclipse-plugin-update-site/test.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5e40c0877058c504203932e5136051cf3cd3519b
--- /dev/null
+++ b/silecs-eclipse-plugin-update-site/test.txt
@@ -0,0 +1 @@
+asdf
\ No newline at end of file
diff --git a/silecs-eclipse-plugin-update-site/web/site.css b/silecs-eclipse-plugin-update-site/web/site.css
new file mode 100644
index 0000000000000000000000000000000000000000..62c6f9ffa4472e7893b59ccfdb9665254a6a07b2
--- /dev/null
+++ b/silecs-eclipse-plugin-update-site/web/site.css
@@ -0,0 +1,12 @@
+<STYLE type="text/css">
+td.spacer {padding-bottom: 10px; padding-top: 10px;}
+.title { font-family: sans-serif; color: #99AACC;}
+.bodyText { font-family: sans-serif; font-size: 9pt; color:#000000;  }
+.sub-header { font-family: sans-serif; font-style: normal; font-weight: bold; font-size: 9pt; color: white;}
+.log-text {font-family: sans-serif; font-style: normal; font-weight: lighter; font-size: 8pt; color:black;}
+.big-header { font-family: sans-serif; font-style: normal; font-weight: bold; font-size: 9pt; color: white; border-top:10px solid white;}
+.light-row {background:#FFFFFF}
+.dark-row {background:#EEEEFF}
+.header {background:#99AADD}
+#indent {word-wrap : break-word;width :300px;text-indent:10px;}
+</STYLE>
diff --git a/silecs-eclipse-plugin-update-site/web/site.xsl b/silecs-eclipse-plugin-update-site/web/site.xsl
new file mode 100644
index 0000000000000000000000000000000000000000..ccb882e7a9bd9ff08af8311a66d48d20cc34676c
--- /dev/null
+++ b/silecs-eclipse-plugin-update-site/web/site.xsl
@@ -0,0 +1,214 @@
+<xsl:stylesheet version = '1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl="urn:schemas-microsoft-com:xslt">
+<xsl:output method="html" encoding="UTF-8"/>
+<xsl:key name="cat" match="category" use="@name"/>
+<xsl:template match="/">
+<xsl:for-each select="site">
+	<html>
+	<head>
+	<title>silecs-eclipse-plugin-update-site</title>
+	<style>@import url("web/site.css");</style>
+	</head>
+	<body>
+	<h1 class="title">silecs-eclipse-plugin-update-site</h1>
+	<p class="bodyText"><xsl:value-of select="description"/></p>
+	<table width="100%" border="0" cellspacing="1" cellpadding="2">
+	<xsl:for-each select="category-def">
+		<xsl:sort select="@label" order="ascending" case-order="upper-first"/>
+		<xsl:sort select="@name" order="ascending" case-order="upper-first"/>
+	<xsl:if test="count(key('cat',@name)) != 0">
+			<tr class="header">
+				<td class="sub-header" width="30%">
+					<xsl:value-of select="@name"/>
+				</td>
+				<td class="sub-header" width="70%">
+					<xsl:value-of select="@label"/>
+				</td>
+			</tr>
+			<xsl:for-each select="key('cat',@name)">
+			<xsl:sort select="ancestor::feature//@version" order="ascending"/>
+			<xsl:sort select="ancestor::feature//@id" order="ascending" case-order="upper-first"/>
+			<tr>
+				<xsl:choose>
+				<xsl:when test="(position() mod 2 = 1)">
+					<xsl:attribute name="class">dark-row</xsl:attribute>
+				</xsl:when>
+				<xsl:otherwise>
+					<xsl:attribute name="class">light-row</xsl:attribute>
+				</xsl:otherwise>
+				</xsl:choose>
+				<td class="log-text" id="indent">
+						<xsl:choose>
+						<xsl:when test="ancestor::feature//@label">
+							<a href="{ancestor::feature//@url}"><xsl:value-of select="ancestor::feature//@label"/></a>
+							<br/>
+							<div id="indent">
+							(<xsl:value-of select="ancestor::feature//@id"/> - <xsl:value-of select="ancestor::feature//@version"/>)
+							</div>
+						</xsl:when>
+						<xsl:otherwise>
+						<a href="{ancestor::feature//@url}"><xsl:value-of select="ancestor::feature//@id"/> - <xsl:value-of select="ancestor::feature//@version"/></a>
+						</xsl:otherwise>
+						</xsl:choose>
+						<br />
+				</td>
+				<td>
+					<table>
+						<xsl:if test="ancestor::feature//@os">
+							<tr><td class="log-text" id="indent">Operating Systems:</td>
+							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@os"/></td>
+							</tr>
+						</xsl:if>
+						<xsl:if test="ancestor::feature//@ws">
+							<tr><td class="log-text" id="indent">Windows Systems:</td>
+							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@ws"/></td>
+							</tr>
+						</xsl:if>
+						<xsl:if test="ancestor::feature//@nl">
+							<tr><td class="log-text" id="indent">Languages:</td>
+							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@nl"/></td>
+							</tr>
+						</xsl:if>
+						<xsl:if test="ancestor::feature//@arch">
+							<tr><td class="log-text" id="indent">Architecture:</td>
+							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@arch"/></td>
+							</tr>
+						</xsl:if>
+					</table>
+				</td>
+			</tr>
+			</xsl:for-each>
+			<tr><td class="spacer"><br/></td><td class="spacer"><br/></td></tr>
+		</xsl:if>
+	</xsl:for-each>
+	<xsl:if test="count(feature)  &gt; count(feature/category)">
+	<tr class="header">
+		<td class="sub-header" colspan="2">
+		Uncategorized
+		</td>
+	</tr>
+	</xsl:if>
+	<xsl:choose>
+	<xsl:when test="function-available('msxsl:node-set')">
+	   <xsl:variable name="rtf-nodes">
+		<xsl:for-each select="feature[not(category)]">
+			<xsl:sort select="@id" order="ascending" case-order="upper-first"/>
+			<xsl:sort select="@version" order="ascending" />
+			<xsl:value-of select="."/>
+			<xsl:copy-of select="." />
+		</xsl:for-each>
+	   </xsl:variable>
+	   <xsl:variable name="myNodeSet" select="msxsl:node-set($rtf-nodes)/*"/>
+	<xsl:for-each select="$myNodeSet">
+	<tr>
+		<xsl:choose>
+		<xsl:when test="position() mod 2 = 1">
+		<xsl:attribute name="class">dark-row</xsl:attribute>
+		</xsl:when>
+		<xsl:otherwise>
+		<xsl:attribute name="class">light-row</xsl:attribute>
+		</xsl:otherwise>
+		</xsl:choose>
+		<td class="log-text" id="indent">
+			<xsl:choose>
+			<xsl:when test="@label">
+				<a href="{@url}"><xsl:value-of select="@label"/></a>
+				<br />
+				<div id="indent">
+				(<xsl:value-of select="@id"/> - <xsl:value-of select="@version"/>)
+				</div>
+			</xsl:when>
+			<xsl:otherwise>
+				<a href="{@url}"><xsl:value-of select="@id"/> - <xsl:value-of select="@version"/></a>
+			</xsl:otherwise>
+			</xsl:choose>
+			<br /><br />
+		</td>
+		<td>
+			<table>
+				<xsl:if test="@os">
+					<tr><td class="log-text" id="indent">Operating Systems:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@os"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@ws">
+					<tr><td class="log-text" id="indent">Windows Systems:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@ws"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@nl">
+					<tr><td class="log-text" id="indent">Languages:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@nl"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@arch">
+					<tr><td class="log-text" id="indent">Architecture:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@arch"/></td>
+					</tr>
+				</xsl:if>
+			</table>
+		</td>
+	</tr>
+	</xsl:for-each>
+	</xsl:when>
+	<xsl:otherwise>
+	<xsl:for-each select="feature[not(category)]">
+	<xsl:sort select="@id" order="ascending" case-order="upper-first"/>
+	<xsl:sort select="@version" order="ascending" />
+	<tr>
+		<xsl:choose>
+		<xsl:when test="count(preceding-sibling::feature[not(category)]) mod 2 = 1">
+		<xsl:attribute name="class">dark-row</xsl:attribute>
+		</xsl:when>
+		<xsl:otherwise>
+		<xsl:attribute name="class">light-row</xsl:attribute>
+		</xsl:otherwise>
+		</xsl:choose>
+		<td class="log-text" id="indent">
+			<xsl:choose>
+			<xsl:when test="@label">
+				<a href="{@url}"><xsl:value-of select="@label"/></a>
+				<br />
+				<div id="indent">
+				(<xsl:value-of select="@id"/> - <xsl:value-of select="@version"/>)
+				</div>
+			</xsl:when>
+			<xsl:otherwise>
+				<a href="{@url}"><xsl:value-of select="@id"/> - <xsl:value-of select="@version"/></a>
+			</xsl:otherwise>
+			</xsl:choose>
+			<br /><br />
+		</td>
+		<td>
+			<table>
+				<xsl:if test="@os">
+					<tr><td class="log-text" id="indent">Operating Systems:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@os"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@ws">
+					<tr><td class="log-text" id="indent">Windows Systems:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@ws"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@nl">
+					<tr><td class="log-text" id="indent">Languages:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@nl"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@arch">
+					<tr><td class="log-text" id="indent">Architecture:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@arch"/></td>
+					</tr>
+				</xsl:if>
+			</table>
+		</td>
+	</tr>
+	</xsl:for-each>
+	</xsl:otherwise>
+	</xsl:choose>
+	</table>
+	</body>
+	</html>
+</xsl:for-each>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/silecs-eclipse-plugin/.classpath b/silecs-eclipse-plugin/.classpath
new file mode 100644
index 0000000000000000000000000000000000000000..8cd7889e282c6a7d040ddb26e4b7e2c607237ae1
--- /dev/null
+++ b/silecs-eclipse-plugin/.classpath
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry exported="true" kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src/java"/>
+	<classpathentry exported="true" kind="lib" path="target/lib/xalan-2.7.2.jar"/>
+	<classpathentry exported="true" kind="lib" path="target/lib/jaxen-1.1.6.jar"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/silecs-eclipse-plugin/.project b/silecs-eclipse-plugin/.project
new file mode 100644
index 0000000000000000000000000000000000000000..24f2a5dc0c11f188739c4cc20e83f5425f2472a6
--- /dev/null
+++ b/silecs-eclipse-plugin/.project
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>silecs-eclipse-plugin</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.python.pydev.PyDevBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.springsource.ide.eclipse.gradle.core.nature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.python.pydev.pythonNature</nature>
+	</natures>
+</projectDescription>
diff --git a/silecs-eclipse-plugin/.pydevproject b/silecs-eclipse-plugin/.pydevproject
new file mode 100644
index 0000000000000000000000000000000000000000..3328e176e60c319bf15e7d7b046e023a9121f736
--- /dev/null
+++ b/silecs-eclipse-plugin/.pydevproject
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?eclipse-pydev version="1.0"?><pydev_project>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">jython 2.7</pydev_property>
+<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
+<path>/${PROJECT_DIR_NAME}/src/scripts</path>
+</pydev_pathproperty>
+</pydev_project>
diff --git a/silecs-eclipse-plugin/.settings/org.eclipse.core.resources.prefs b/silecs-eclipse-plugin/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..8dd9b1df3d66f1efc3bc1c9e516c16a1b034e689
--- /dev/null
+++ b/silecs-eclipse-plugin/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+encoding//src/test/java=UTF-8
+encoding/<project>=UTF-8
diff --git a/silecs-eclipse-plugin/.settings/org.eclipse.jdt.core.prefs b/silecs-eclipse-plugin/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..672496e107ed4e070613aad776b4df5146306bd4
--- /dev/null
+++ b/silecs-eclipse-plugin/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/silecs-eclipse-plugin/.settings/org.eclipse.ltk.core.refactoring.prefs b/silecs-eclipse-plugin/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/silecs-eclipse-plugin/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/silecs-eclipse-plugin/.settings/org.eclipse.m2e.core.prefs b/silecs-eclipse-plugin/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..f897a7f1cb2389f85fe6381425d29f0a9866fb65
--- /dev/null
+++ b/silecs-eclipse-plugin/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/silecs-eclipse-plugin/JNLP-INF/APPLICATION_TEMPLATE.JNLP b/silecs-eclipse-plugin/JNLP-INF/APPLICATION_TEMPLATE.JNLP
new file mode 100644
index 0000000000000000000000000000000000000000..cf8e499a329c2ada3ee7ad325a94439cb87fb69b
--- /dev/null
+++ b/silecs-eclipse-plugin/JNLP-INF/APPLICATION_TEMPLATE.JNLP
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jnlp spec="1.0+" codebase="*" href="silecs_launcher.jnlp"> <!-- URL to the site containing the jnlp application. It should match the 
+		value used on export. Href, the name of this file -->
+	<information>
+		<!-- user readable name of the application -->
+		<title> Silecs-Eclipse-Plugin</title>
+		<!-- vendor name -->
+		<vendor>CERN</vendor>
+		<!-- vendor homepage -->
+		<homepage href="https://wikis/display/SIL/SILECs+Home"/>
+		<!-- product description -->
+		<description>Silecs Configuration tool</description>
+	</information>
+
+	<!--request all permissions from the application. This does not change -->
+	<security>
+		<all-permissions />
+	</security>
+	<update check="always" policy="always"></update>
+
+	<!-- The name of the main class to execute. This does not change -->
+	<application-desc main-class="cern.silecs.activator.WebStartLauncher">
+		<argument>-nosplash</argument>
+		<argument>-consoleLog</argument>
+		<argument>-data</argument>
+		<argument>@noDefault</argument>
+	</application-desc>
+
+	<resources>
+		<!-- Reference to the launcher jar.-->
+		<jar href="*" />
+
+		<property name="app.name" value="Silecs-Eclipse-Plugin"></property>
+    	<property name="app.version" value="1.m.p"></property>
+					
+		<!-- The id of the product to run, like found in the overview page of the 
+			product editor -->
+		<property name="eclipse.application" value="silecs.eclipse.plugin.application" />
+		<property name="osgi.parentClassloader" value="current" />
+		<property name="osgi.framework" value="org.eclipse.osgi" />
+		<property name="osgi.bundles"
+			value="org.eclipse.core.runtime@start,org.eclipse.equinox.common@2:start,org.eclipse.equinox.ds@1:start,org.eclipse.equinox.simpleconfigurator@1:start,org.eclipse.osgi@-1:start,org.eclipse.equinox.event@3:start" />
+	</resources>
+
+	<resources os="Windows">
+		<j2se version="1.8+"
+			java-vm-args="-Xms128m -Xmx1024m -Dpython.cachedir.skip=true -Dpython.cachedir=/tmp  -Dpython.home=. -Dpython.console.encoding=UTF-8" />
+
+        	<property name="osgi.instance.area" value="@user.home/Silecs-Eclipse-Plugin/1.m.p/"/>
+       	 	<property name="osgi.configuration.area" value="@user.home/Silecs-Eclipse-Plugin/1.m.p/"/>
+
+		<extension name="Wrapper feature"
+			href="*" />    		
+	</resources>
+
+	<resources os="Linux">
+		<j2se version="1.8+" 
+			java-vm-args="-Xms128m -Xmx1024m -Dpython.cachedir.skip=true -Dpython.cachedir=/tmp  -Dpython.home=. -Dpython.console.encoding=UTF-8" />
+
+		<property name="jnlp.osgi.instance.area" value="@user.home/Silecs-Eclipse-Plugin/1.m.p/" />
+		<property name="jnlp.osgi.configuration.area" value="@user.home/Silecs-Eclipse-Plugin/1.m.p/" />
+		<property name="jnlp.Dosgi.user.area" value="@user.home"/>
+        	<property name="osgi.ws" value="gtk"/>
+
+		<extension name="Wrapper feature"
+			href="*" />
+
+  	</resources>
+</jnlp>
\ No newline at end of file
diff --git a/silecs-eclipse-plugin/LICENSE b/silecs-eclipse-plugin/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..20d40b6bceca3a6c0237d7455ebf1820aeff3680
--- /dev/null
+++ b/silecs-eclipse-plugin/LICENSE
@@ -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>.
\ No newline at end of file
diff --git a/silecs-eclipse-plugin/META-INF/MANIFEST.MF b/silecs-eclipse-plugin/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..cd8d7fa9228b21f09d8b47587b0864adf229776a
--- /dev/null
+++ b/silecs-eclipse-plugin/META-INF/MANIFEST.MF
@@ -0,0 +1,134 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: silecs.eclipse.plugin;singleton:=true
+Bundle-Version: 1.1.1.qualifier
+Bundle-Activator: cern.silecs.activator.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.ui.workbench,
+ org.eclipse.core.resources,
+ org.eclipse.ui.ide,
+ org.eclipse.ui.editors,
+ org.eclipse.wst.xml.core,
+ org.eclipse.wst.xml.ui,
+ org.eclipse.ui.navigator.resources,
+ org.eclipse.core.filesystem,
+ org.eclipse.ui.console,
+ org.eclipse.ui.views,
+ org.eclipse.wst.validation,
+ org.eclipse.wst.validation.infopop,
+ org.eclipse.wst.validation.ui,
+ org.eclipse.jface.text,
+ org.eclipse.wst.sse.ui,
+ org.eclipse.ui.workbench.texteditor,
+ org.eclipse.text,
+ org.eclipse.wst.sse.core,
+ org.eclipse.ui.navigator,
+ org.eclipse.xsd,
+ org.eclipse.wst.xsd.core,
+ org.eclipse.core.expressions,
+ org.eclipse.cdt,
+ org.eclipse.cdt.core,
+ org.eclipse.cdt.ui,
+ org.eclipse.cdt.managedbuilder.ui,
+ org.eclipse.ltk.core.refactoring,
+ org.eclipse.ltk.ui.refactoring,
+ org.eclipse.equinox.launcher,
+ org.eclipse.cdt.make.core;bundle-version="7.3.0",
+ org.eclipse.cdt.make.ui;bundle-version="7.2.0",
+ org.eclipse.cdt.managedbuilder.core;bundle-version="8.3.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-ActivationPolicy: lazy
+Bundle-ClassPath: .,
+ target/lib/xalan-2.7.2.jar,
+ target/lib/jaxen-1.1.6.jar
+Permissions: all-permissions
+Codebase: http://abwww.cern.ch/ap/dist/silecs/1.m.p/configuration/
+Application-Name: Silecs-Eclipse-Plugin
+Export-Package: cern.silecs.activator,
+ cern.silecs.control.core,
+ cern.silecs.control.handlers,
+ cern.silecs.control.validation,
+ cern.silecs.control.validation.internal;x-internal:=true,
+ cern.silecs.model.document,
+ cern.silecs.model.exception,
+ cern.silecs.utils,
+ cern.silecs.view,
+ cern.silecs.view.console,
+ cern.silecs.view.dialogs,
+ cern.silecs.view.editor,
+ cern.silecs.view.editor.internal;x-internal:=true,
+ cern.silecs.view.explorer,
+ cern.silecs.view.job,
+ cern.silecs.view.marker,
+ cern.silecs.view.preferences,
+ cern.silecs.view.wizards,
+ cern.silecs.view.wizards.page,
+ java_cup.runtime,
+ org.apache.bcel,
+ org.apache.bcel.classfile,
+ org.apache.bcel.generic,
+ org.apache.bcel.util,
+ org.apache.bcel.verifier,
+ org.apache.bcel.verifier.exc,
+ org.apache.bcel.verifier.statics,
+ org.apache.bcel.verifier.structurals,
+ org.apache.regexp,
+ org.apache.xalan,
+ org.apache.xalan.client,
+ org.apache.xalan.extensions,
+ org.apache.xalan.lib,
+ org.apache.xalan.lib.sql,
+ org.apache.xalan.processor,
+ org.apache.xalan.res,
+ org.apache.xalan.serialize,
+ org.apache.xalan.templates,
+ org.apache.xalan.trace,
+ org.apache.xalan.transformer,
+ org.apache.xalan.xslt,
+ org.apache.xalan.xsltc,
+ org.apache.xalan.xsltc.cmdline,
+ org.apache.xalan.xsltc.cmdline.getopt,
+ org.apache.xalan.xsltc.compiler,
+ org.apache.xalan.xsltc.compiler.util,
+ org.apache.xalan.xsltc.dom,
+ org.apache.xalan.xsltc.runtime,
+ org.apache.xalan.xsltc.runtime.output,
+ org.apache.xalan.xsltc.trax,
+ org.apache.xalan.xsltc.util,
+ org.apache.xml.dtm,
+ org.apache.xml.dtm.ref,
+ org.apache.xml.dtm.ref.dom2dtm,
+ org.apache.xml.dtm.ref.sax2dtm,
+ org.apache.xml.res,
+ org.apache.xml.utils,
+ org.apache.xml.utils.res,
+ org.apache.xpath,
+ org.apache.xpath.axes,
+ org.apache.xpath.compiler,
+ org.apache.xpath.domapi,
+ org.apache.xpath.functions,
+ org.apache.xpath.jaxp,
+ org.apache.xpath.objects,
+ org.apache.xpath.operations,
+ org.apache.xpath.patterns,
+ org.apache.xpath.res,
+ org.jaxen,
+ org.jaxen.dom,
+ org.jaxen.dom4j,
+ org.jaxen.expr,
+ org.jaxen.expr.iter,
+ org.jaxen.function,
+ org.jaxen.function.ext,
+ org.jaxen.function.xslt,
+ org.jaxen.javabean,
+ org.jaxen.jdom,
+ org.jaxen.pattern,
+ org.jaxen.saxpath,
+ org.jaxen.saxpath.base,
+ org.jaxen.saxpath.helpers,
+ org.jaxen.util,
+ org.jaxen.xom,
+ org.w3c.dom,
+ trax
diff --git a/silecs-eclipse-plugin/OSGI-INF/l10n/bundle.properties b/silecs-eclipse-plugin/OSGI-INF/l10n/bundle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..3ed82f28bd9c7df0d77ed69094db2129eb83eb05
--- /dev/null
+++ b/silecs-eclipse-plugin/OSGI-INF/l10n/bundle.properties
@@ -0,0 +1,2 @@
+#Properties file for silecs.eclipse.plugin
+Bundle-Name = Silecs-config
\ No newline at end of file
diff --git a/silecs-eclipse-plugin/README.md b/silecs-eclipse-plugin/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..04caae13e4db9c1f95ff0f5113dc810a650af7ce
--- /dev/null
+++ b/silecs-eclipse-plugin/README.md
@@ -0,0 +1,40 @@
+# silecs-codegen
+
+This component of the SILECS PLC-framework is used in order to generate and manage silecs-project.
+
+## Getting Started
+
+Please check the lab-specific SILECS-Wikis for more information:
+
+[CERN SILECS Wiki Page][CERN_Wiki]
+
+[GSI SILECS Wiki Page][GSI_Wiki]
+
+## License
+
+Licensed under the GNU GENERAL PUBLIC LICENSE Version 3. See the [LICENSE file][license] for details.
+
+[license]: LICENSE
+[CERN_Wiki]: https://wikis.cern.ch/display/SIL/SILECs+Home
+[GSI_Wiki]: https://www-acc.gsi.de/wiki/Frontend/SILECS
+
+## Dependencies
+
+### Eclipse Plugins
+Install Eclipse plug-in development environment – repo: Official Eclipse repo 
+install eclipse-core-tool – http://eclipse.org/eclipse/platform-core/updates
+
+### Maven
+Configure the Eclipe-Maven:
+https://www-acc.gsi.de/wiki/bin/viewauth/IN/Maven
+
+Goto project-folder in console and run:
+“mvn install”
+Right click on project in eclipse configure → Convert to Maven Project
+Goto eclipse and run project-->Build
+
+## Execution
+
+Goto eclipse-perspective
+double-click plugin.xml
+Launch an Eclipse Application
\ No newline at end of file
diff --git a/silecs-eclipse-plugin/build.properties b/silecs-eclipse-plugin/build.properties
new file mode 100644
index 0000000000000000000000000000000000000000..a172b18b4337c36e019b021540bceaebd5445712
--- /dev/null
+++ b/silecs-eclipse-plugin/build.properties
@@ -0,0 +1,16 @@
+source.. = src/java/
+output.. = bin/java/,\
+           bin/
+bin.includes = plugin.xml,\
+               META-INF/,\
+               .,\
+               icons/,\
+               src/scripts/,\
+               JNLP-INF/,\
+               src/java/,\
+               target/lib/jaxen-1.1.6.jar,\
+               target/lib/xalan-2.7.2.jar,\
+               OSGI-INF/
+src.includes = src/
+jars.compile.order = .
+qualifier = context
diff --git a/silecs-eclipse-plugin/icons/class-document.png b/silecs-eclipse-plugin/icons/class-document.png
new file mode 100644
index 0000000000000000000000000000000000000000..80984b14d8f98dba890f8e9e56b08f7c642ba50c
Binary files /dev/null and b/silecs-eclipse-plugin/icons/class-document.png differ
diff --git a/silecs-eclipse-plugin/icons/deploy-document.png b/silecs-eclipse-plugin/icons/deploy-document.png
new file mode 100644
index 0000000000000000000000000000000000000000..894abc409c39559e46105f195802d42f64241321
Binary files /dev/null and b/silecs-eclipse-plugin/icons/deploy-document.png differ
diff --git a/silecs-eclipse-plugin/icons/diag-tool.gif b/silecs-eclipse-plugin/icons/diag-tool.gif
new file mode 100644
index 0000000000000000000000000000000000000000..3748db1fddb2fe61380bac4dc029d6a617236453
Binary files /dev/null and b/silecs-eclipse-plugin/icons/diag-tool.gif differ
diff --git a/silecs-eclipse-plugin/icons/generated-code.gif b/silecs-eclipse-plugin/icons/generated-code.gif
new file mode 100644
index 0000000000000000000000000000000000000000..18ffabe77f499a954f2ef0d2077da4ff4365e391
Binary files /dev/null and b/silecs-eclipse-plugin/icons/generated-code.gif differ
diff --git a/silecs-eclipse-plugin/icons/silecs-logo.ico b/silecs-eclipse-plugin/icons/silecs-logo.ico
new file mode 100644
index 0000000000000000000000000000000000000000..2b22b71097787713417cae9933d9604b169ea962
Binary files /dev/null and b/silecs-eclipse-plugin/icons/silecs-logo.ico differ
diff --git a/silecs-eclipse-plugin/icons/validate-document.gif b/silecs-eclipse-plugin/icons/validate-document.gif
new file mode 100644
index 0000000000000000000000000000000000000000..23c97f09e677bb8812b26d4415fd97997e5c95a4
Binary files /dev/null and b/silecs-eclipse-plugin/icons/validate-document.gif differ
diff --git a/silecs-eclipse-plugin/plugin.xml b/silecs-eclipse-plugin/plugin.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8784193cb84f6f0c476d61505d47b513715ec6df
--- /dev/null
+++ b/silecs-eclipse-plugin/plugin.xml
@@ -0,0 +1,874 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="4.5"?>
+<plugin>
+   <extension
+           id="application"
+         point="org.eclipse.core.runtime.applications">
+      <application>
+         <run
+               class="cern.silecs.view.Application">
+         </run>
+      </application>
+   </extension>
+  <extension
+	point="org.eclipse.core.resources.natures"
+	      id="cern.fesa.plugin.core.fesaClassProjectNature"
+	      name="cern.fesa.plugin.core.fesaClassProjectNature">
+   </extension>
+   
+   <extension
+         point="org.eclipse.ui.perspectives">
+      <perspective
+            class="cern.silecs.view.Perspective"
+            fixed="false"
+            id="silecs.eclipse.plugin.perspective"
+            name="Silecs">
+      </perspective>
+   </extension>
+   <extension
+         point="org.eclipse.ui.perspectiveExtensions">
+      <perspectiveExtension
+            targetID="silecs.eclipse.plugin.perspective">
+         <view
+               closeable="false"
+               id="cern.silecs.view.explorer"
+               minimized="false"
+               moveable="false"
+               ratio="0.25"
+               relationship="left"
+               relative="org.eclipse.ui.editorss"
+               visible="true">
+         </view>
+         <view
+               closeable="false"
+               id="org.eclipse.ui.views.ProblemView"
+               minimized="false"
+               ratio="0.8f"
+               relationship="bottom"
+               relative="org.eclipse.ui.editorss"
+               visible="true">
+         </view>
+         <view
+               closeable="false"
+               id="org.eclipse.ui.console.ConsoleView"
+               minimized="false"
+               relationship="stack"
+               relative="org.eclipse.ui.views.ProblemView">
+         </view>
+         <view
+               closeable="false"
+               id="org.eclipse.wst.xml.ui.views.annotations.XMLAnnotationsView"
+               minimized="false"
+               relationship="stack"
+               relative="org.eclipse.ui.views.ProblemView"
+               visible="true">
+         </view>
+      </perspectiveExtension>
+   </extension>
+   <extension
+         point="org.eclipse.ui.ide.projectNatureImages">
+      <image
+            icon="icons/deploy-document.png"
+            id="cern.silecs.control.core.DeployProjectNature.img"
+            natureId="cern.silecs.control.core.deployprojectnature">
+      </image>
+      <image
+            icon="icons/class-document.png"
+            id="cern.silecs.control.core.DesignProjectNature.img"
+            natureId="cern.silecs.control.core.designprojectnature">
+      </image>
+   </extension>
+   <extension
+         id="deployprojectnature"
+         point="org.eclipse.core.resources.natures">
+      <runtime>
+         <run
+               class="cern.silecs.control.core.DeployProjectNature">
+         </run>
+      </runtime>
+   </extension>
+   <extension
+         point="org.eclipse.ui.commands">
+      <category
+            id="cern.silecs.view.category"
+            name="Cat">
+      </category>
+      <command
+            categoryId="cern.silecs.view.category"
+            defaultHandler="cern.silecs.control.handlers.ValidateHandler"
+            id="cern.silecs.control.handlers.validate"
+            name="SILECS Validate">
+         <commandParameter
+               id="silecs-eclipse-plugin.commandParameter"
+               name="silecs-eclipse-plugin.commandParameter"
+               optional="false">
+         </commandParameter>
+      </command>
+      <command
+            categoryId="cern.silecs.view.category"
+            defaultHandler="cern.silecs.control.handlers.GenerateCodeHandler"
+            id="cern.silecs.control.handlers.generatecodehandler"
+            name="SILECS Generate Code">
+         <commandParameter
+               id="silecs-eclipse-plugin.commandParameter"
+               name="silecs-eclipse-plugin.commandParameter"
+               optional="false">
+         </commandParameter>
+      </command>
+      <command
+            categoryId="cern.silecs.view.category"
+            defaultHandler="cern.silecs.control.handlers.AboutSilecsHandler"
+            id="cern.silecs.control.handlers.aboutsilecs"
+            name="About Silecs">
+      </command>
+      <command
+            categoryId="cern.silecs.view.category"
+            defaultHandler="cern.silecs.control.handlers.SilecsWikis"
+            id="cern.silecs.control.handlers.silecswikis"
+            name="Silecs Wikis">
+      </command>
+      <command
+            categoryId="cern.silecs.view.category"
+            defaultHandler="cern.silecs.control.handlers.ExpandAllHandler"
+            id="cern.silecs.control.handlers.expandallhandler"
+            name="Expand All">
+      </command>
+      <command
+            categoryId="cern.silecs.view.category"
+            defaultHandler="cern.silecs.control.handlers.DiagnosticToolHandler"
+            id="cern.silecs.control.handlers.launchdiagnostitoolhandler"
+            name="SILECS Diagnostic Tool">
+         <commandParameter
+               id="silecs-eclipse-plugin.commandParameter"
+               name="silecs-eclipse-plugin.commandParameter"
+               optional="false">
+         </commandParameter>
+      </command>
+      <command
+            categoryId="cern.silecs.view.category"
+            defaultHandler="cern.silecs.control.handlers.UpdateSilecsProjectHandler"
+            id="cern.silecs.control.handlers.updatesilecsprojecthandler"
+            name="SILECS Update Project">
+         <commandParameter
+               id="silecs-eclipse-plugin.commandParameter"
+               name="silecs-eclipse-plugin.commandParameter"
+               optional="false">
+         </commandParameter>
+      </command>
+   </extension>
+   <extension
+         point="org.eclipse.ui.menus">
+      <menuContribution
+            locationURI="menu:org.eclipse.ui.main.menu">
+         <menu
+               label="Silecs">
+            <command
+                  commandId="cern.silecs.control.handlers.silecswikis"
+                  label="Silecs wikis"
+                  style="push">
+            </command>
+            <command
+                  commandId="cern.silecs.control.handlers.aboutsilecs"
+                  label="About Silecs"
+                  style="push">
+            </command>
+
+            <visibleWhen
+                  checkEnabled="false">
+               <reference
+                     definitionId="cern.silecs.view.perspectivedefinition">
+               </reference>
+            </visibleWhen>
+         </menu>
+         
+      </menuContribution>
+      <menuContribution
+            locationURI="toolbar:org.eclipse.ui.main.toolbar">
+         <toolbar
+               id="cern.silecs.view.toolbars.projectFunctions"
+               label="SILECS Toolbar">
+            <command
+                  commandId="cern.silecs.control.handlers.validate"
+                  icon="icons/validate-document.gif"
+                  label="SILECS Validate"
+                  style="push">
+               <visibleWhen
+                     checkEnabled="false">
+                  <or>
+	                  <reference
+	                        definitionId="cern.silecs.view.editors.design.activeEditor">
+	                  </reference>
+	                  <reference
+	                        definitionId="cern.silecs.view.editors.deploy.activeEditor">
+	                  </reference>
+                  </or>
+               </visibleWhen>
+               <parameter
+                     name="silecs-eclipse-plugin.commandParameter"
+                     value="toolbar">
+               </parameter>
+            </command>
+            <command
+                  commandId="cern.silecs.control.handlers.generatecodehandler"
+                  icon="icons/generated-code.gif"
+                  label="SILECS Generate Code"
+                  style="push">
+              <visibleWhen
+                 checkEnabled="false">
+              <or>
+	                  <reference
+	                        definitionId="cern.silecs.view.editors.design.activeEditor">
+	                  </reference>
+	                  <reference
+	                        definitionId="cern.silecs.view.editors.deploy.activeEditor">
+	                  </reference>
+              </or>
+           </visibleWhen>
+              <parameter
+                    name="silecs-eclipse-plugin.commandParameter"
+                    value="toolbar">
+              </parameter>
+            </command>
+            <command
+                  commandId="cern.silecs.control.handlers.launchdiagnostitoolhandler"
+                  icon="icons/diag-tool.gif"
+                  label="SILECS Diagnostic Tool"
+                  style="push">
+              <visibleWhen
+                 checkEnabled="false">
+	                  <reference
+	                        definitionId="cern.silecs.view.editors.deploy.activeEditor">
+	                  </reference>
+           		</visibleWhen>
+              <parameter
+                    name="silecs-eclipse-plugin.commandParameter"
+                    value="toolbar">
+              </parameter>
+            </command>
+         </toolbar>
+      </menuContribution>
+      <menuContribution
+            allPopups="false"
+            locationURI="popup:org.eclipse.ui.navigator.ProjectExplorer#PopupMenu?after=additions">
+        <menu
+               id="silecs_submenu"
+               label="SILECS">
+        <command
+              commandId="cern.silecs.control.handlers.validate"
+              label="SILECS Validate"
+              style="push">
+           <visibleWhen
+                 checkEnabled="false">
+              <or>
+                  <reference
+                        definitionId="cern.silecs.control.core.designprojectdefinition">
+                  </reference>
+                  <reference
+                        definitionId="cern.silecs.control.core.deployprojectdefinition">
+                  </reference>
+                  <reference
+                        definitionId="cern.silecs.menu.designFile">
+                  </reference>
+                  <reference
+                        definitionId="cern.silecs.menu.deployFile">
+                  </reference>
+              </or>
+           </visibleWhen>
+           <parameter
+                 name="silecs-eclipse-plugin.commandParameter"
+                 value="menubar">
+           </parameter>
+        </command>
+                 <command
+               commandId="cern.silecs.control.handlers.generatecodehandler"
+               label="SILECS Generate Code"
+               style="push">
+           <visibleWhen
+                 checkEnabled="false">
+              <or>
+                  <reference
+                        definitionId="cern.silecs.control.core.designprojectdefinition">
+                  </reference>
+                  <reference
+                        definitionId="cern.silecs.control.core.deployprojectdefinition">
+                  </reference>
+                  <reference
+                        definitionId="cern.silecs.menu.designFile">
+                  </reference>
+                  <reference
+                        definitionId="cern.silecs.menu.deployFile">
+                  </reference>
+              </or>
+           </visibleWhen>
+           <parameter
+                 name="silecs-eclipse-plugin.commandParameter"
+                 value="menubar">
+           </parameter>
+         </command>
+         <command
+                  commandId="cern.silecs.control.handlers.launchdiagnostitoolhandler"
+                  label="SILECS Diagnostic Tool"
+                  style="push">
+              <visibleWhen
+                 checkEnabled="false">
+                   <or>
+                      <reference
+                            definitionId="cern.silecs.control.core.deployprojectdefinition">
+                      </reference>
+                      <reference
+                            definitionId="cern.silecs.menu.deployFile">
+                      </reference>
+                   </or>
+                </visibleWhen>
+              <parameter
+                    name="silecs-eclipse-plugin.commandParameter"
+                    value="menubar">
+              </parameter>
+            </command>
+            <command
+                  commandId="cern.silecs.control.handlers.updatesilecsprojecthandler"
+                  label="Update SILECS version"
+                  style="push">
+              <visibleWhen
+                 checkEnabled="false">
+                  <or>
+                      <reference
+                            definitionId="cern.silecs.control.core.designprojectdefinition">
+                      </reference>
+                      <reference
+                            definitionId="cern.silecs.control.core.deployprojectdefinition">
+                      </reference>
+                      <reference
+                        definitionId="cern.silecs.menu.designFile">
+                      </reference>
+                      <reference
+                        definitionId="cern.silecs.menu.deployFile">
+                      </reference>
+                  </or>
+                </visibleWhen>
+              <parameter
+                    name="silecs-eclipse-plugin.commandParameter"
+                    value="menubar">
+              </parameter>
+            </command>
+            </menu>
+      </menuContribution>
+      <menuContribution
+            allPopups="false"
+            locationURI="popup:cern.silecs.view.explorer#PopupMenu?after=additions">
+            <menu
+               id="silecs_submenu"
+               label="SILECS">
+            </menu>
+      </menuContribution>
+   </extension>
+   <extension
+         point="org.eclipse.ui.editors">
+      <editor
+            class="cern.silecs.view.editor.DesignMultiPageEditor"
+            contributorClass="org.eclipse.wst.xml.ui.internal.tabletree.XMLMultiPageEditorActionBarContributor"
+            default="true"
+            icon="icons/class-document.png"
+            extensions="xml"
+            filenames="silecsdesign"
+            id="cern.silecs.view.editors.design"
+            name="XML Editor">
+         <contentTypeBinding
+               contentTypeId="cern.silecs.model.contenttype.design">
+         </contentTypeBinding>
+      </editor>
+      <editor
+            class="cern.silecs.view.editor.DeployMultiPageEditor"
+            contributorClass="org.eclipse.wst.xml.ui.internal.tabletree.XMLMultiPageEditorActionBarContributor"
+            default="true"
+            icon="icons/deploy-document.png"
+            extensions="xml"
+            filenames="silecsdeploy"
+            id="cern.silecs.view.editors.deploy"
+            name="XML Editor">
+         <contentTypeBinding
+               contentTypeId="cern.silecs.model.contenttype.deploy">
+         </contentTypeBinding>
+      </editor>
+   </extension>
+   <extension
+         id="designprojectnature"
+         point="org.eclipse.core.resources.natures">
+      <runtime>
+         <run
+               class="cern.silecs.control.core.DesignProjectNature">
+         </run>
+      </runtime>
+   </extension>
+   <extension
+         id="cern.silecs.view.marker"
+         name="%silecs.marker.problem"
+         point="org.eclipse.core.resources.markers">
+      <super
+            type="org.eclipse.core.resources.problemmarker">
+      </super>
+      <persistent
+            value="false">
+      </persistent>
+      <attribute
+            name="xPath">
+      </attribute>
+   </extension>
+   <extension
+         point="org.eclipse.ui.editors.markerUpdaters">
+      <updater
+            class="cern.silecs.view.marker.SilecsMarkerUpdater"
+            id="cern.silecs.view.marker.updater"
+            markerType="cern.silecs.view.marker">
+      </updater>
+   </extension>
+   <extension
+         point="org.eclipse.ui.newWizards">
+      <category
+            id="cern.silecs.view.category.wizards"
+            name="Silecs">
+      </category>
+      <wizard
+            category="cern.silecs.view.category.wizards"
+            class="cern.silecs.view.wizards.NewSilecsDesignWizard"
+            finalPerspective="silecs.eclipse.plugin.perspective"
+            icon="icons/class-document.png"
+            id="cern.silecs.view.wizards.newdesignclass"
+            name="Design"
+            project="true">
+      </wizard>
+      <wizard
+            category="cern.silecs.view.category.wizards"
+            class="cern.silecs.view.wizards.NewSilecsDeployWizard"
+            finalPerspective="silecs.eclipse.plugin.perspective"
+            icon="icons/deploy-document.png"
+            id="cern.silecs.view.wizards.newdeployclass"
+            name="Deploy"
+            project="true">
+      </wizard>
+   </extension>
+   <extension
+         id="product"
+         point="org.eclipse.core.runtime.products">
+      <product
+            application="silecs.eclipse.plugin.application"
+            name="Silecs-Eclipse-Plugin 1.1.1">
+         <property
+               name="appName"
+               value="Silecs-Eclipse-Plugin 1.1.1">
+         </property>
+      </product>
+   </extension>
+   <extension
+         point="org.eclipse.ui.importWizards">
+      <category
+            id="cern.silecs.view.category.wizards"
+            name="Silecs">
+      </category>
+      <wizard
+            category="cern.silecs.view.category.wizards"
+            class="cern.silecs.view.wizards.ImportDeployFileWizard"
+            icon="icons/deploy-document.png"
+            id="cern.silecs.view.wizards.importdeploywizard"
+            name="Import Silecs-1 Deploy-Unit File">
+      </wizard>
+      <wizard
+            category="cern.silecs.view.category.wizards"
+            class="cern.silecs.view.wizards.ImportDesignFileWizard"
+            icon="icons/class-document.png"
+            id="cern.silecs.view.wizards.importdesignfilewizard"
+            name="Import Silecs-1 Design File">
+      </wizard>
+   </extension>
+   <extension
+         point="org.eclipse.team.core.fileTypes">
+      <fileTypes
+            extension="*.silecsdesign"
+            type="text">
+      </fileTypes>
+      <fileTypes
+            extension="*.silecsdeploy"
+            type="text">
+      </fileTypes>
+   </extension>
+   <extension
+         point="org.eclipse.core.contenttype.contentTypes">
+      <content-type
+            base-type="org.eclipse.core.runtime.xml"
+            file-extensions="silecsdesign"
+            id="cern.silecs.model.contenttype.design"
+            name="Design">
+      </content-type>
+      <content-type
+            base-type="org.eclipse.core.runtime.xml"
+            file-extensions="silecsdeploy"
+            id="cern.silecs.model.contenttype.deploy"
+            name="Deploy">
+      </content-type>
+   </extension>
+   <extension
+         point="org.eclipse.core.expressions.definitions">
+       <definition id="cern.silecs.designFile">
+         <iterate ifEmpty="false">
+            <adapt
+                  type="org.eclipse.core.resources.IFile">
+               <test
+                     property="org.eclipse.core.resources.extension"
+                     value="silecsdesign">
+               </test>
+            </adapt>
+         </iterate>
+      </definition>
+      
+      <definition id="cern.silecs.deployFile">
+         <iterate ifEmpty="false">
+            <adapt
+                  type="org.eclipse.core.resources.IFile">
+               <test
+                     property="org.eclipse.core.resources.extension"
+                     value="silecsdeploy">
+               </test>
+            </adapt>
+         </iterate>
+      </definition>
+      
+       <definition
+            id="cern.silecs.menu.designFile">
+         <with
+               variable="activeMenuSelection">
+            <reference
+                  definitionId="cern.silecs.designFile">
+            </reference>
+         </with>
+      </definition>
+      
+      <definition
+            id="cern.silecs.menu.deployFile">
+         <with
+               variable="activeMenuSelection">
+            <reference
+                  definitionId="cern.silecs.deployFile">
+            </reference>
+         </with>
+      </definition>
+      
+      <definition
+            id="cern.silecs.control.core.deployprojectdefinition">
+         <iterate
+               ifEmpty="false">
+            <adapt
+                  type="org.eclipse.core.resources.IProject">
+               <test
+                     property="org.eclipse.core.resources.projectNature"
+                     value="cern.silecs.control.core.deployprojectnature">
+               </test>
+            </adapt>
+         </iterate>
+      </definition>
+      <definition
+            id="cern.silecs.control.core.designprojectdefinition">
+         <iterate
+               ifEmpty="false">
+            <adapt
+                  type="org.eclipse.core.resources.IProject">
+               <test
+                     property="org.eclipse.core.resources.projectNature"
+                     value="cern.silecs.control.core.designprojectnature">
+               </test>
+            </adapt>
+         </iterate>
+      </definition>
+      <definition
+            id="cern.silecs.view.editors.design.activeEditor">
+         <with variable="activeEditorId">
+            <equals
+                  value="cern.silecs.view.editors.design">
+            </equals>
+         </with>
+      </definition>
+            <definition
+            id="cern.silecs.view.editors.deploy.activeEditor">
+         <with variable="activeEditorId">
+            <equals
+                  value="cern.silecs.view.editors.deploy">
+            </equals>
+         </with>
+      </definition>
+      <definition
+            id="cern.silecs.view.perspectivedefinition">
+         <with
+               variable="activeWorkbenchWindow.activePerspective">
+            <equals
+                  value="silecs.eclipse.plugin.perspective">
+            </equals>
+         </with>
+      </definition>
+   </extension>
+   <extension
+         point="org.eclipse.ui.decorators">
+      <decorator
+            adaptable="true"
+            class="org.eclipse.cdt.internal.ui.navigator.CNavigatorProblemsLabelDecorator"
+            id="cern.silecs.view.decorators.ErrorDecorator"
+            label="Project error decorator"
+            lightweight="true"
+            location="BOTTOM_LEFT"
+            objectClass="org.eclipse.core.resources.IResource"
+            state="true">
+         <enablement>
+            <and>
+               <objectClass
+                     name="org.eclipse.core.resources.IResource">
+               </objectClass>
+               <or>
+                  <objectClass
+                        name="org.eclipse.core.resources.IFolder">
+                  </objectClass>
+                  <objectClass
+                        name="org.eclipse.core.resources.IFile">
+                  </objectClass>
+               </or>
+            </and>
+         </enablement>
+      </decorator>
+   </extension>
+   <extension
+         point="org.eclipse.ui.bindings">
+      <scheme
+            id="cern.silecs.control.bindingscheme"
+            name="Binding scheme">
+      </scheme>
+      <key
+            commandId="cern.silecs.control.handlers.expandallhandler"
+            contextId="org.eclipse.ui.contexts.window"
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+            sequence="M1+M2+A">
+      </key>
+   </extension>
+   <extension
+         point="org.eclipse.ui.views">
+      <category
+            id="cern.silecs.view.ui"
+            name="Silecs">
+      </category>
+      <view
+            category="cern.silecs.view.ui"
+            class="cern.silecs.view.explorer.SilecsProjectExplorer"
+            icon="icons/silecs-logo.ico"
+            id="cern.silecs.view.explorer"
+            name="Silecs Explorer"
+            restorable="true">
+      </view>
+   </extension>
+   <extension
+         point="org.eclipse.ui.navigator.navigatorContent">
+      <commonFilter
+            activeByDefault="true"
+            id="cern.silecs.view.explorer.filter.hiddenfiles"
+            name=".* resources"
+            visibleInUI="true">
+         <filterExpression>
+            <and>
+               <adapt
+                     type="org.eclipse.core.resources.IResource">
+                  <test
+                        property="org.eclipse.core.resources.name"
+                        value=".*">
+                  </test>
+               </adapt>
+            </and>
+         </filterExpression>
+      </commonFilter>
+      <navigatorContent
+            activeByDefault="true"
+            contentProvider="cern.silecs.view.explorer.ProjectContent"
+            id="cern.silecs.view.explorer.content"
+            labelProvider="org.eclipse.ui.model.WorkbenchLabelProvider"
+            name="Silecs Project Content"
+            priority="normal">
+         <triggerPoints>
+            <or>
+               <adapt
+                     type="org.eclipse.core.resources.IWorkspaceRoot">
+               </adapt>
+               <adapt
+                     type="org.eclipse.core.resources.IFolder">
+               </adapt>
+               <adapt
+                     type="org.eclipse.core.resources.IProject">
+                  <or>
+                     <test
+                           property="org.eclipse.core.resources.projectNature"
+                           value="cern.silecs.control.core.DesignProjectNature">
+                     </test>
+                     <test
+                           property="org.eclipse.core.resources.projectNature"
+                           value="cern.silecs.control.core.DeployProjectNature">
+                     </test>
+                  </or>
+               </adapt>
+            </or>
+         </triggerPoints>
+         <possibleChildren>
+            <or>
+               <adapt
+                     type="org.eclipse.core.resources.IProject">
+               </adapt>
+               <adapt
+                     type="org.eclipse.core.resources.IFolder">
+               </adapt>
+               <adapt
+                     type="org.eclipse.core.resources.IFile">
+               </adapt>
+            </or>
+         </possibleChildren>
+         <commonSorter
+               class="cern.silecs.view.explorer.ContentSorter"
+               id="cern.silecs.view.explorer.sorter.ContentSorter">
+         </commonSorter>
+         <dropAssistant
+               class="org.eclipse.cdt.internal.ui.navigator.CNavigatorDropAdapterAssistant"
+               id="cern.silecs.view.explorer.resourceDropAdapter">
+            <possibleDropTargets>
+               <or>
+                  <adapt
+                        type="org.eclipse.core.resources.IProject">
+                  </adapt>
+                  <adapt
+                        type="org.eclipse.core.resources.IFolder">
+                  </adapt>
+                  <adapt
+                        type="org.eclipse.core.resources.IFile">
+                  </adapt>
+               </or></possibleDropTargets>
+         </dropAssistant>
+         <actionProvider
+               class="org.eclipse.cdt.internal.ui.navigator.CNavigatorEditActionProvider"
+               id="cern.silecs.view.explorer.actions.EditActions">
+         </actionProvider>
+         <actionProvider
+               class="org.eclipse.cdt.internal.ui.navigator.CNavigatorRefactorActionProvider"
+               id="cern.silecs.view.explorer.actions.RefactorActions">
+         </actionProvider>
+      </navigatorContent>
+   </extension>
+   <extension
+         point="org.eclipse.ui.navigator.viewer">
+      <viewer
+            viewerId="cern.silecs.view.explorer">
+         <popupMenu
+               allowsPlatformContributions="true"
+               id="cern.silecs.view.explorer#PopupMenu">
+     <insertionPoint
+                  name="group.new"
+                  separator="true">
+            </insertionPoint>
+            <insertionPoint
+                  name="group.goto">
+            </insertionPoint>
+            <insertionPoint
+                  name="group.open"
+                  separator="true">
+            </insertionPoint>
+            <insertionPoint
+                  name="group.openwith">
+            </insertionPoint>
+            <insertionPoint
+                  name="silecs"
+                  separator="true">
+            </insertionPoint>
+            <insertionPoint
+                  name="group.edit"
+                  separator="true">
+            </insertionPoint>
+            <insertionPoint
+                  name="group.reorganize"
+                  separator="true">
+            </insertionPoint>
+            <insertionPoint
+                  name="group.port"
+                  separator="true">
+            </insertionPoint>
+            <insertionPoint
+                  name="group.generate"
+                  separator="true">
+            </insertionPoint>
+            <insertionPoint
+                  name="group.search"
+                  separator="true">
+            </insertionPoint>
+            <insertionPoint
+                  name="group.build"
+                  separator="true">
+            </insertionPoint>
+            <insertionPoint
+                  name="additions"
+                  separator="true">
+            </insertionPoint>
+            <insertionPoint
+                  name="group.properties"
+                  separator="true">
+            </insertionPoint>
+         </popupMenu>
+      </viewer>
+      <viewerContentBinding
+            viewerId="cern.silecs.view.explorer">
+         <includes>
+            <contentExtension
+                  isRoot="true"
+                  pattern="cern.silecs.view.explorer.content">
+            </contentExtension>
+            <contentExtension
+                  pattern="cern.silecs.view.explorer.filter.*">
+            </contentExtension>
+            <contentExtension
+                  pattern="org.eclipse.ui.navigator.resources.linkHelper">
+            </contentExtension>
+            <contentExtension
+                  pattern="org.eclipse.ui.navigator.resources.filters.workingSet">
+            </contentExtension>
+         </includes>
+      </viewerContentBinding>
+      <viewerActionBinding
+            viewerId="cern.silecs.view.explorer">
+         <includes>
+            <actionExtension
+                  pattern="org.eclipse.ui.navigator.resources.*">
+            </actionExtension>
+            <actionExtension
+                  pattern="cern.silecs.view.explorer.*">
+            </actionExtension>
+         </includes>
+      </viewerActionBinding>
+      <dragAssistant
+            class="org.eclipse.cdt.internal.ui.navigator.CNavigatorDragAdapterAssistant"
+            viewerId="cern.silecs.view.explorer">
+      </dragAssistant>
+   </extension>
+   <extension
+         point="org.eclipse.core.runtime.preferences">
+      <initializer
+            class="cern.silecs.view.preferences.PreferenceInitializer">
+      </initializer>
+   </extension>
+      <extension
+         point="org.eclipse.ui.preferencePages">
+      <page
+            class="cern.silecs.view.preferences.MainPreferencePage"
+            id="Silecs"
+            name="Silecs">
+      </page>
+      <page
+            category="Silecs"
+            class="cern.silecs.view.preferences.EditorPreferencePage"
+            id="cern.silecs.plugin.preferences.editor"
+            name="XML-Editor">
+      </page>
+      <page
+            category="Silecs"
+            class="cern.silecs.view.preferences.LoggingPreferencePage"
+            id="cern.silecs.plugin.preferences.logging"
+            name="Logging">
+      </page>
+   </extension>
+</plugin>
diff --git a/silecs-eclipse-plugin/pom.xml b/silecs-eclipse-plugin/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..85bf5fa75c0e7b254f914e79d0f0d07caa8ffb78
--- /dev/null
+++ b/silecs-eclipse-plugin/pom.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+        <parent>
+            <groupId>de.gsi.cs.co</groupId>
+            <artifactId>csco-parent</artifactId>
+            <version>1.0.7</version>
+        </parent>
+
+	<groupId>silecs-eclipse-plugin</groupId>
+	<artifactId>silecs-eclipse-plugin</artifactId>
+	<version>0.10.0</version>
+	<name>silecs-eclipse-plugin</name>
+	<packaging>jar</packaging>
+	<description>adfsfasfa.</description>
+	<url>sdasdasdasdasd</url>
+
+	<developers>
+		<developer>
+			<id></id>
+			<name></name>
+			<email></email>
+			<url></url>
+		</developer>
+	</developers>
+
+	<dependencies>
+		<dependency>
+		  <groupId>org.slf4j</groupId>
+		  <artifactId>slf4j-log4j12</artifactId>
+		  <version>1.7.12</version>
+		</dependency>
+		<dependency>
+		  <groupId>org.slf4j</groupId>
+		  <artifactId>slf4j-api</artifactId>
+		  <version>1.7.12</version>
+		</dependency>
+		<dependency>
+		  <groupId>log4j</groupId>
+		  <artifactId>log4j</artifactId>
+		  <version>1.2.17</version>
+		</dependency>
+		<dependency>
+		  <groupId>xalan</groupId>
+		  <artifactId>xalan</artifactId>
+		  <version>2.7.2</version>
+		</dependency>
+		  <dependency>
+		  <groupId>jaxen</groupId>
+		  <artifactId>jaxen</artifactId>
+		  <version>1.1.6</version>
+		</dependency>
+	</dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>copy</id>
+            <phase>package</phase>
+            <goals>
+              <goal>copy</goal>
+            </goals>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+				  <groupId>org.slf4j</groupId>
+				  <artifactId>slf4j-log4j12</artifactId>
+                </artifactItem>
+		        <artifactItem>
+				  <groupId>org.slf4j</groupId>
+				  <artifactId>slf4j-api</artifactId>
+		        </artifactItem>
+		        <artifactItem>
+				  <groupId>log4j</groupId>
+				  <artifactId>log4j</artifactId>
+		        </artifactItem>
+                <artifactItem>
+	               	<groupId>xalan</groupId>
+		  			<artifactId>xalan</artifactId>
+		   		</artifactItem>
+ 				<artifactItem>
+					<groupId>jaxen</groupId>
+					<artifactId>jaxen</artifactId>
+				</artifactItem>
+              </artifactItems>
+              <outputDirectory>${project.build.directory}/lib</outputDirectory>
+              <overWriteReleases>false</overWriteReleases>
+              <overWriteSnapshots>true</overWriteSnapshots>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/silecs-eclipse-plugin/project.properties b/silecs-eclipse-plugin/project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..2dbdd52b87fef7611b3bef21047ff3062168df25
--- /dev/null
+++ b/silecs-eclipse-plugin/project.properties
@@ -0,0 +1,3 @@
+eclipseLocalOverride=true
+javadoc.enabled=false
+junit.enabled=false
\ No newline at end of file
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/activator/Activator.java b/silecs-eclipse-plugin/src/java/cern/silecs/activator/Activator.java
new file mode 100644
index 0000000000000000000000000000000000000000..3eea8ab4e369787cf2fee72a3ab48e016fb60d42
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/activator/Activator.java
@@ -0,0 +1,70 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.activator;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "silecs.eclipse.plugin"; //$NON-NLS-1$
+	
+	// The shared instance
+	private static Activator plugin;
+	
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	@Override
+    public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	@Override
+    public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+	/**
+	 * Returns an image descriptor for the image file at the given
+	 * plug-in relative path
+	 *
+	 * @param path the path
+	 * @return the image descriptor
+	 */
+	public static ImageDescriptor getImageDescriptor(String path) {
+		return imageDescriptorFromPlugin(PLUGIN_ID, path);
+	}
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/activator/WebStartLauncher.java b/silecs-eclipse-plugin/src/java/cern/silecs/activator/WebStartLauncher.java
new file mode 100644
index 0000000000000000000000000000000000000000..e3ee96efdd0e8c262947eb1a51fde70ee44380c5
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/activator/WebStartLauncher.java
@@ -0,0 +1,52 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.activator;
+
+import java.util.Properties;
+import java.util.Set;
+
+import org.eclipse.equinox.launcher.WebStartMain;
+
+/**
+ * This class is only used by jnlp launcher. 
+ * It is not used locally.
+ */
+@SuppressWarnings("restriction")
+public class WebStartLauncher {
+
+    public static void main(String[] args) {
+        Properties properties = System.getProperties();
+        // copy properties to avoid ConcurrentModificationException
+        Properties copiedProperties = new Properties();
+        copiedProperties.putAll(properties);
+        Set<Object> keys = copiedProperties.keySet();
+        for (Object key : keys) {
+            if (key instanceof String) {
+                String keyString = (String) key;
+                if (keyString.startsWith("jnlp.")) {
+                    // re set all properties starting with the jnlp-prefix
+                    // and set them without the prefix
+                    String property = System.getProperty(keyString);
+                    String replacedKeyString = keyString.replaceFirst("jnlp.", "");
+
+                    System.setProperty(replacedKeyString, property);
+                }
+            }
+        }
+
+        WebStartMain.main(args);
+    }
+}
\ No newline at end of file
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/control/core/DeployProjectNature.java b/silecs-eclipse-plugin/src/java/cern/silecs/control/core/DeployProjectNature.java
new file mode 100644
index 0000000000000000000000000000000000000000..8442589c9338b48c8237f7b1cf18c7a01c2d9db9
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/control/core/DeployProjectNature.java
@@ -0,0 +1,103 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.control.core;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+
+public class DeployProjectNature extends SilecsProjectNature implements IProjectNature {
+    
+    private static final String CERN_FESA_PLUGIN_CORE_FESA_DEPLOY_PROJECT_NATURE = "cern.fesa.plugin.core.fesaDeployProjectNature";
+	public static final String NATURE_ID = "cern.silecs.control.core.deployprojectnature";
+    
+    public static void addDeployNature(IProject project, IProgressMonitor mon) throws CoreException {
+        IProgressMonitor monitor = mon;
+        if (monitor == null) {
+            monitor = new NullProgressMonitor();
+        }
+
+        try {
+            monitor.beginTask("Add silecs deploy nature", 2);
+            addNature(project, NATURE_ID, new SubProgressMonitor(monitor, 1));
+            addCppNature(project, new SubProgressMonitor(monitor, 1));
+        } finally {
+            monitor.done();
+        }
+    }
+
+    public static void removeDeployNature(IProject project, IProgressMonitor mon) throws CoreException {
+        IProgressMonitor monitor = mon;
+        if (monitor == null) {
+            monitor = new NullProgressMonitor();
+        }
+        
+        try {
+            monitor.beginTask("Remove silecs deploy nature", 2);
+            removeNature(project, NATURE_ID, new SubProgressMonitor(monitor, 1));
+            removeCppNature(project, new SubProgressMonitor(monitor, 1));
+        } finally {
+            monitor.done();
+        }
+    }
+    
+    public static void convertToDeployNature(IProject project, IProgressMonitor mon) throws CoreException {
+        IProgressMonitor monitor = mon;
+        if (monitor == null) {
+            monitor = new NullProgressMonitor();
+        }
+        
+        try {
+            monitor.beginTask("Converting project to silecs deploy nature", 2);
+            removeAllNatures(project, new SubProgressMonitor(monitor, 1));
+            addDeployNature(project, new SubProgressMonitor(monitor, 1));
+        } finally {
+            monitor.done();
+        }
+    }
+    
+    public static void addFESADeployUnitNature(IProject project, IProgressMonitor mon) throws CoreException {
+        IProgressMonitor monitor = mon;
+        if (mon == null) {
+            monitor = new NullProgressMonitor();
+        }
+        monitor.beginTask("Adding FESA Class Nature to project", 2);
+        try {
+            addNature(project, CERN_FESA_PLUGIN_CORE_FESA_DEPLOY_PROJECT_NATURE, new SubProgressMonitor(monitor, 1));
+            addManageBuilderNature(project,mon);
+        } finally {
+            monitor.done();
+        }
+    }
+    
+    public static void removeFESADeployUnitNature(IProject project, IProgressMonitor mon) throws CoreException {
+        IProgressMonitor monitor = mon;
+        if (mon == null) {
+            monitor = new NullProgressMonitor();
+        }
+        monitor.beginTask("Removing FESA Nature from project", 2);
+        try {
+            removeNature(project, CERN_FESA_PLUGIN_CORE_FESA_DEPLOY_PROJECT_NATURE, new SubProgressMonitor(monitor, 1));
+            removeManageBuilderNature(project,mon);
+        } finally {
+            monitor.done();
+        }
+    }
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/control/core/DesignProjectNature.java b/silecs-eclipse-plugin/src/java/cern/silecs/control/core/DesignProjectNature.java
new file mode 100644
index 0000000000000000000000000000000000000000..be974ee2d0cbbe390ba7a8adfaaa39f70c812b99
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/control/core/DesignProjectNature.java
@@ -0,0 +1,110 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.control.core;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+
+import cern.silecs.view.console.ConsoleHandler;
+
+public class DesignProjectNature extends SilecsProjectNature implements IProjectNature {
+
+    public static final String NATURE_ID = "cern.silecs.control.core.designprojectnature";
+    
+	private static final String CERN_FESA_PLUGIN_CORE_FESA_CLASS_PROJECT_NATURE = "cern.fesa.plugin.core.fesaClassProjectNature";
+	
+    public static void addClassNature(IProject project, IProgressMonitor mon) throws CoreException {
+    	ConsoleHandler.printMessage("Debug0", true);
+        IProgressMonitor monitor = mon;
+        if (monitor == null) {
+            monitor = new NullProgressMonitor();
+        }
+
+        try {
+            monitor.beginTask("Add silecs class nature", 2);
+            ConsoleHandler.printMessage("Debug1", true);
+            addNature(project, NATURE_ID, new SubProgressMonitor(monitor, 1));
+            ConsoleHandler.printMessage("Debug2", true);
+            addCppNature(project, new SubProgressMonitor(monitor, 1));
+            ConsoleHandler.printMessage("Debug3", true);
+		} finally {
+            monitor.done();
+        }
+    }
+
+    public static void removeClassNature(IProject project, IProgressMonitor mon) throws CoreException {
+        IProgressMonitor monitor = mon;
+        if (monitor == null) {
+            monitor = new NullProgressMonitor();
+        }
+        
+        try {
+            monitor.beginTask("Remove silecs class nature", 2);
+            removeNature(project, NATURE_ID, new SubProgressMonitor(monitor, 1));
+            removeCppNature(project, new SubProgressMonitor(monitor, 1));
+        } finally {
+            monitor.done();
+        }
+    }
+    
+    public static void convertToClassNature(IProject project, IProgressMonitor mon) throws CoreException {
+        IProgressMonitor monitor = mon;
+        if (monitor == null) {
+            monitor = new NullProgressMonitor();
+        }
+        
+        try {
+            monitor.beginTask("Converting project to silecs class nature", 2);
+            removeAllNatures(project, new SubProgressMonitor(monitor, 1));
+            addClassNature(project, new SubProgressMonitor(monitor, 1));
+        } finally {
+            monitor.done();
+        }
+    }
+    
+    public static void addFESAClassNature(IProject project, IProgressMonitor mon) throws CoreException {
+        IProgressMonitor monitor = mon;
+        if (mon == null) {
+            monitor = new NullProgressMonitor();
+        }
+        monitor.beginTask("Adding FESA Class Nature to project", 2);
+        try {
+            addNature(project, CERN_FESA_PLUGIN_CORE_FESA_CLASS_PROJECT_NATURE, new SubProgressMonitor(monitor, 1));
+            addManageBuilderNature(project,mon);
+        } finally {
+            monitor.done();
+        }
+    }
+    
+    public static void removeFESAClassNature(IProject project, IProgressMonitor mon) throws CoreException {
+        IProgressMonitor monitor = mon;
+        if (mon == null) {
+            monitor = new NullProgressMonitor();
+        }
+        monitor.beginTask("Removing FESA Nature from project", 2);
+        try {
+            removeNature(project, CERN_FESA_PLUGIN_CORE_FESA_CLASS_PROJECT_NATURE, new SubProgressMonitor(monitor, 1));
+            removeManageBuilderNature(project,mon);
+        } finally {
+            monitor.done();
+        }
+    }
+    
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/control/core/SilecsProjectNature.java b/silecs-eclipse-plugin/src/java/cern/silecs/control/core/SilecsProjectNature.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7ea191aaf544cff030f57b991561a6870db0806
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/control/core/SilecsProjectNature.java
@@ -0,0 +1,162 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.control.core;
+
+
+import org.eclipse.cdt.core.CCProjectNature;
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+
+import org.eclipse.core.runtime.SubProgressMonitor;
+
+import cern.silecs.model.exception.SilecsException;
+import cern.silecs.utils.SilecsConstants;
+import cern.silecs.view.console.ConsoleHandler;
+
+
+public abstract class SilecsProjectNature extends CCProjectNature {
+
+    public static final String PROJECT_FILE = ".project";
+    public static final String CDT_PROJECT_FILE = ".cproject";
+
+    private static final String ORG_ECLIPSE_CDT_MANAGEDBUILDER_CORE_SCANNER_CONFIG_NATURE = "org.eclipse.cdt.managedbuilder.core.ScannerConfigNature";
+	private static final String ORG_ECLIPSE_CDT_MANAGEDBUILDER_CORE_MANAGED_BUILD_NATURE = "org.eclipse.cdt.managedbuilder.core.managedBuildNature";
+	
+	private static final String FESA_BUILD_COMMAND_1 = "org.eclipse.cdt.managedbuilder.core.genmakebuilder";
+	private static final String FESA_BUILD_COMMAND_2 = "org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder";
+	
+    protected static void removeAllNatures(IProject project, IProgressMonitor mon) throws CoreException {
+        IProgressMonitor monitor = mon;
+        if (mon == null) {
+            monitor = new NullProgressMonitor();
+        }
+        try {
+            IProjectDescription desc = project.getDescription();
+            desc.setNatureIds(new String[0]);
+            project.setDescription(desc, null);
+        } finally {
+            monitor.done();
+        }
+    }
+    
+    protected static void addCppNature(IProject project, IProgressMonitor mon) throws CoreException {
+        IProgressMonitor monitor = mon;
+        if (mon == null) {
+            monitor = new NullProgressMonitor();
+        }
+        monitor.beginTask("Adding C++ Nature to project", 2);
+        
+        try {
+            addNature(project, C_NATURE_ID, new SubProgressMonitor(monitor, 1));
+            addNature(project, CC_NATURE_ID, new SubProgressMonitor(monitor, 1));
+        } finally {
+            monitor.done();
+        }
+    }
+    
+    protected static void removeCppNature(IProject project, IProgressMonitor mon) throws CoreException {
+        IProgressMonitor monitor = mon;
+        if (mon == null) {
+            monitor = new NullProgressMonitor();
+        }
+        
+        monitor.beginTask("Removing C++ Nature from project", 2);
+        
+        try {
+            removeNature(project, C_NATURE_ID, new SubProgressMonitor(monitor, 1));
+            removeNature(project, CC_NATURE_ID, new SubProgressMonitor(monitor, 1));
+        } finally {
+            monitor.done();
+        }
+    }
+
+    @Override
+    public void configure() throws CoreException {
+        // Do nothing. this allow to put fesa nature first
+    }
+    
+    public static SilecsConstants.ProjectType getProjectType(IProject project) throws CoreException, SilecsException {
+        if (project.hasNature(DesignProjectNature.NATURE_ID)) {
+            return SilecsConstants.ProjectType.DESIGN_PROJECT;
+        } else if (project.hasNature(DeployProjectNature.NATURE_ID)) {
+            return SilecsConstants.ProjectType.DEPLOY_PROJECT;
+        } else {
+            throw new SilecsException("Project " + project.getName() + " has no fesa nature");
+        }
+    }
+    
+    protected static void addManageBuilderNature(IProject project, IProgressMonitor mon) throws CoreException {
+        IProgressMonitor monitor = mon;
+        if (mon == null) {
+            monitor = new NullProgressMonitor();
+        }
+        monitor.beginTask("Adding Managebuilder Nature to project", 2);
+        
+        try {
+        	addCppNature(project,mon);
+            addNature(project, ORG_ECLIPSE_CDT_MANAGEDBUILDER_CORE_MANAGED_BUILD_NATURE, new SubProgressMonitor(monitor, 1));
+            addNature(project, ORG_ECLIPSE_CDT_MANAGEDBUILDER_CORE_SCANNER_CONFIG_NATURE, new SubProgressMonitor(monitor, 1));
+        } finally {
+            monitor.done();
+        }
+    }
+    
+    protected static void removeManageBuilderNature(IProject project, IProgressMonitor mon) throws CoreException {
+        IProgressMonitor monitor = mon;
+        if (mon == null) {
+            monitor = new NullProgressMonitor();
+        }
+        
+        monitor.beginTask("Removing Managebuilder Nature from project", 2);
+        
+        try {
+        	removeCppNature(project,mon);
+            removeNature(project, ORG_ECLIPSE_CDT_MANAGEDBUILDER_CORE_MANAGED_BUILD_NATURE, new SubProgressMonitor(monitor, 1));
+            removeNature(project, ORG_ECLIPSE_CDT_MANAGEDBUILDER_CORE_SCANNER_CONFIG_NATURE, new SubProgressMonitor(monitor, 1));
+        } finally {
+            monitor.done();
+        }
+    }
+    
+    public static void addBuildSpecs(IProject project)
+    {
+        try {
+        	IProjectDescription desc = project.getDescription();
+        	ICommand[] commands = new ICommand[2];
+            final ICommand command0 = desc.newCommand();
+            final ICommand command1 = desc.newCommand();
+            command0.setBuilderName(FESA_BUILD_COMMAND_1);
+            command1.setBuilderName(FESA_BUILD_COMMAND_2);
+            commands[0] = command0;
+            commands[1] = command1;
+            
+            //remove auto-build options
+            commands[0].setBuilding(IncrementalProjectBuilder.AUTO_BUILD, false);
+            commands[1].setBuilding(IncrementalProjectBuilder.AUTO_BUILD, false);
+            commands[1].setBuilding(IncrementalProjectBuilder.CLEAN_BUILD, false);
+        	desc.setBuildSpec(commands);
+            project.setDescription(desc, null);
+        } catch (CoreException e) {
+            e.printStackTrace();
+            ConsoleHandler.printStackTrace(e);
+        }
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/AboutSilecsHandler.java b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/AboutSilecsHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..f639039ecd0fc41201df6c276d1f879c64f36b5a
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/AboutSilecsHandler.java
@@ -0,0 +1,68 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.control.handlers;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+
+import cern.silecs.utils.SilecsConstants;
+import cern.silecs.view.dialogs.SilecsMessageDialog;
+
+/**
+ * This handler displays basic information about the Silecs tool.
+ */
+public class AboutSilecsHandler extends AbstractHandler implements IHandler {
+
+    @Override
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+        Shell shell = PlatformUI.getWorkbench().getDisplay().getActiveShell();
+
+      //GSI-Hack .. use GSI-Support
+        String dialogMessage = "About SILECS\n\n"
+                + "A 'Design project' defines the data to be exchanged with the controller (blocks and the registers) in a hardware independent manners while a 'Deploy project' binds several design instances on a physical controller. \n"
+                + "Purpose of this tool is to provide an easy-to-use graphical interface to guide the user in the definition of his design/deploy projects and to generate the client and controller resources necessary for the communication via the Silecs communication library.\n\n"
+
+                + "If you are using this tool you may also be interests in: \n"
+                + "\u2022   Silecs communication library \n"
+                + "\u2022   Silecs diagnostic tool \n\n"
+                + "Support contact: silecs-support@gsi.de \n"
+                + "Silecs wiki:     "+ SilecsConstants.SILECS_WIKIS_PATH + "\n\n\n"
+                
+                + "Copyright 2016 CERN and GSI\n"
+                + "This program is free software: you can redistribute it and/or modify\n"
+                + "it under the terms of the GNU General Public License as published by\n"
+                + "the Free Software Foundation, either version 3 of the License, or\n"
+                + "(at your option) any later version.\n\n"
+
+                + "This program is distributed in the hope that it will be useful,\n"
+                + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+                + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+                + "GNU General Public License for more details.\n\n"
+                + "You should have received a copy of the GNU General Public License\n"
+                + "along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n";
+
+
+        MessageDialog dialog = new SilecsMessageDialog(shell, "About Silecs", null, dialogMessage,
+                MessageDialog.INFORMATION, new String[] { "OK" }, 0);
+        dialog.open();
+        return null;
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/BaseHandler.java b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/BaseHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..5167a21e23ffc0fd4d9510d5261c27e301037baa
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/BaseHandler.java
@@ -0,0 +1,175 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.control.handlers;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.ui.ide.IDE;
+
+import cern.silecs.control.core.DeployProjectNature;
+import cern.silecs.control.core.DesignProjectNature;
+import cern.silecs.utils.SilecsUtils;
+
+public abstract class BaseHandler extends AbstractHandler {
+    
+    
+    
+    /**
+     * Gives the list of selected documents
+     * Asks the user to save the file if dirty in an editor
+     * 
+     * @param event
+     * @return
+     */
+    protected List<IFile> retrieveIeplcFiles(ExecutionEvent event) {
+        List<IFile> files = retrieveIeplcFilesNonCheck(event);
+        return ensureFileSaved(files);
+    }
+    
+    /**
+     * Gives the Ieplc file form file selection or project selection
+     * @param event
+     * @return
+     */
+    private List<IFile> retrieveIeplcFilesNonCheck(ExecutionEvent event) {
+        List<IFile> files = new ArrayList<IFile>();
+
+        // get from where the command was fired
+        Object trigger = event.getTrigger();
+        if (trigger instanceof Event) {
+            Event ev = (Event) trigger;
+
+            if (ev.widget instanceof MenuItem) {
+                // if fired by a popup
+                IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getActiveMenuSelection(event);
+
+                for (Object o : selection.toList()) {
+                    if (o instanceof IFile) {
+                        files.add((IFile) o);
+                    } else if (o instanceof IProject) {
+                        // if project selected return the design or du file
+                        IProject project = (IProject) o;
+                        try {
+                            files.add(retriveIeplcFileFromProject(project));
+                        } catch (CoreException e) {
+                            // if project nature can't be retrieve, log but do nothing
+                            //LOGGER.error("Could not retrieve project nature for {}", project.getName());
+                        } catch (Exception e) {
+                            //LOGGER.error("Project nature not supported for {}", project.getName());
+                        }
+
+                    }
+                }
+
+            } else {
+                // the command was fired by a shortcut or a toolbar button
+                IEditorPart editor = HandlerUtil.getActiveEditor(event);
+                IFileEditorInput input = (IFileEditorInput) editor.getEditorInput();
+                files.add(input.getFile());
+            }
+        }
+        
+        return files;
+    }
+
+    /**
+     * Gives the list of selected project
+     * 
+     * @param event
+     * @return
+     */
+    protected List<IProject> retrieveProjects(ExecutionEvent event) {
+        List<IProject> projects = new ArrayList<IProject>();
+
+        // get from where the command was fired
+        Object trigger = event.getTrigger();
+        if (trigger instanceof Event) {
+            Event ev = (Event) trigger;
+
+            if (ev.widget instanceof MenuItem) {
+                IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getActiveMenuSelection(event);
+                List<?> resources = IDE.computeSelectedResources(selection);
+                for (Object o : resources) {
+                    if (o instanceof IProject) {
+                        projects.add((IProject) o);
+                    } else if (o instanceof IFile) {
+                        IProject project = ((IFile) o).getProject();
+
+                        if (project != null) {
+                            projects.add(project);
+                        }
+                    }
+                }
+            } else {
+                IEditorPart editor = HandlerUtil.getActiveEditor(event);
+                if (editor == null) return projects;
+                IFileEditorInput input = (IFileEditorInput) editor.getEditorInput();
+                projects.add(input.getFile().getProject());
+            }
+        }
+
+        if (projects.isEmpty()) {
+            //LOGGER.info("No projects could be retrieved");
+        }
+
+        return projects;
+    }
+
+    /**
+     * Finds the Ieplc file from the project root
+     * @param project
+     * @return
+     * @throws Exception 
+     * @throws Exception
+     */
+    private IFile retriveIeplcFileFromProject(IProject project) throws Exception {
+        if (project.hasNature(DeployProjectNature.NATURE_ID)) {
+            return SilecsUtils.getSilecsDeployFile(project);
+        } else if (project.hasNature(DesignProjectNature.NATURE_ID)) {
+            return SilecsUtils.getSilecsDesignFile(project);
+        } else {
+            throw new Exception();
+        }
+    }
+    
+    /**
+     * Ensure the documents are not dirty in an open editor
+     * @param files
+     * @return
+     */
+    private List<IFile> ensureFileSaved(List<IFile> files) {
+        if (IDE.saveAllEditors(files.toArray(new IResource[files.size()]), true)) {
+            return files;
+        } else {
+            return Collections.<IFile> emptyList();
+        }
+    }
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/DiagnosticToolHandler.java b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/DiagnosticToolHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..362d5d1168c35266f49b41f16611fec465799087
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/DiagnosticToolHandler.java
@@ -0,0 +1,76 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.control.handlers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+
+import cern.silecs.control.core.DeployProjectNature;
+import cern.silecs.utils.OSExecute;
+import cern.silecs.utils.SilecsUtils;
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.preferences.MainPreferencePage;
+
+public class DiagnosticToolHandler extends AbstractHandler implements IHandler {
+
+    @Override
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+
+            try
+            {
+            	ConsoleHandler.clear();
+
+                IProject project = SilecsUtils.extractSilecsFileFromEvent(event).getProject();
+
+                if( project.hasNature(DeployProjectNature.NATURE_ID) == false )
+                	throw new Exception("The project: " + project.getName() + " is not a silecs-deploy-project");
+                
+                SilecsUtils.checkSilecsVersion(project);
+                IFile deployFile = SilecsUtils.getSilecsDeployFile(project);
+               
+            	String binary = MainPreferencePage.getDiagToolBasePath(SilecsUtils.getSilecsVersion(project)) + "/bin/x86_64/silecs-diagnostic";
+            	String snap7lib = MainPreferencePage.getSNAP7LibraryBasePath(SilecsUtils.getSilecsVersion(project)) + "/bin/x86_64-linux";
+            	
+            	ConsoleHandler.printMessage("Starting  Silecs Diagnostic Tool from:" + binary, true);
+
+            	String[] command = new String[3];
+            	command[0] = binary;
+            	command[1] = "-d";
+            	command[2] = deployFile.getRawLocation().makeAbsolute().toOSString();
+            	String envVarName = "LD_LIBRARY_PATH";
+            	Map<String, String> env = new HashMap<String, String>();
+            	env.put(envVarName, snap7lib);
+            	ConsoleHandler.printMessage("Setting environment variable: '" + envVarName + "' to '" + snap7lib + "'", true);
+            	ConsoleHandler.printMessage("Executing command: " + command[0] + " " + command[1] + " " + command[2], true);
+            	OSExecute.executeCommand(env, command);
+            }
+            catch (Exception e)
+            {
+                ConsoleHandler.printError("Could not launch Silecs Diagnostic Tool", true);
+                e.printStackTrace();
+            }
+
+        return null;
+    }
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/ExpandAllHandler.java b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/ExpandAllHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..e9e4559a389dafc760d9ad9e50e5baccc3c203a0
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/ExpandAllHandler.java
@@ -0,0 +1,60 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.control.handlers;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.ISelectionService;
+import org.eclipse.ui.PlatformUI;
+import cern.silecs.view.explorer.SilecsProjectExplorer;
+
+/**
+ * This handler is responsible for expanding selected projects in the silecs explorer.<br>
+ * It calls SilecsProjectExplorer's expandHelper to expand projects to src-file level. 
+ */
+public class ExpandAllHandler extends AbstractHandler implements IHandler {
+
+    @Override
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+        ArrayList<IProject> projects = new ArrayList<>();
+        
+        ISelectionService selectionService = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService();
+
+        IStructuredSelection selections = (IStructuredSelection) selectionService
+                .getSelection(SilecsProjectExplorer.VIEW_ID);
+           
+        for(Object selection : selections.toArray()) {
+            if(selection instanceof IProject)
+                projects.add((IProject)selection);
+        }
+        
+        SilecsProjectExplorer explorer = (SilecsProjectExplorer) PlatformUI.getWorkbench().getActiveWorkbenchWindow()
+                .getActivePage().findView(SilecsProjectExplorer.VIEW_ID);
+
+        explorer.expandHelper(root, projects);
+
+        return null;
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/GenerateCodeHandler.java b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/GenerateCodeHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..94b33bc8334030a2f9c6e566f7d16c5220fbf6f5
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/GenerateCodeHandler.java
@@ -0,0 +1,154 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.control.handlers;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.wizard.IWizard;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+
+import cern.silecs.control.core.DeployProjectNature;
+import cern.silecs.control.core.DesignProjectNature;
+import cern.silecs.model.exception.SilecsException;
+import cern.silecs.utils.SilecsUtils;
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.job.BaseProjectJob;
+import cern.silecs.view.job.GenerateClassJob;
+import cern.silecs.view.job.GenerateDeployJob;
+import cern.silecs.view.preferences.MainPreferencePage;
+import cern.silecs.view.wizards.GenerateCodeWizard;
+
+public class GenerateCodeHandler extends BaseHandler implements IHandler {
+	
+	@Override
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+
+		ConsoleHandler.clear();
+		
+        BaseProjectJob job = null;
+        try {
+            IFile silecsFile = SilecsUtils.extractSilecsFileFromEvent(event);
+            IProject project = silecsFile.getProject();
+            SilecsUtils.checkSilecsVersion(project);
+            
+        	IFolder src = project.getFolder("src");
+			if(project.hasNature(DesignProjectNature.NATURE_ID) )
+			{
+	    		IFile fesaDesignDoc = src.getFile(project.getName() + ".design");
+	    		boolean designDocExists = fesaDesignDoc.exists();
+	    		if(designDocExists)
+	    		{
+	    			IFile backup = src.getFile(fesaDesignDoc.getName() + ".backup");
+	    			ConsoleHandler.printMessage("Existing FESA Design document detected - new data will be inserted", true);
+	    			ConsoleHandler.printWarning("Please note that old, obsolete xml-elements are not deleted automatically! Sometimes this can lead to an invalid FESA Design document!", true);
+	    			ConsoleHandler.printWarning("If this is the case, please remove the obsolete elements by hand.", true);
+	    			ConsoleHandler.printMessage("A backup of your old document will be saved at: " + backup.getRawLocation().makeAbsolute(), true);
+	    			if(backup.exists())
+	    				backup.delete(true, null);
+	    			fesaDesignDoc.copy(backup.getFullPath(), true, null);
+	    		}
+	    		else
+	    		{
+	        		File[] templates = MainPreferencePage.getFESADesignTemplates();
+	        		File template = pickTemplate(event,templates);
+	        		if( template == null) // cancel pressed
+	        			return null;
+	        		ConsoleHandler.printMessage("The following template will be used:" + template.getAbsolutePath(), true);
+	    		    InputStream source = new FileInputStream(template);
+	    		    fesaDesignDoc.create(source, IResource.NONE, null);
+	    		}
+				job = new GenerateClassJob(project, fesaDesignDoc);
+			}
+			else if(project.hasNature(DeployProjectNature.NATURE_ID) )
+			{
+	    		IFile fesaDeployDoc = src.getFile(project.getName() + ".deploy");
+	    		boolean deployDocExists = fesaDeployDoc.exists();
+	    		if(deployDocExists)
+	    		{
+	    			IFile backup = src.getFile(fesaDeployDoc.getName() + ".backup");
+	    			ConsoleHandler.printMessage("Existing FESA Deploy-Unit document detected - new data will be inserted", true);
+	    			ConsoleHandler.printWarning("Please note that old, obsolete xml-elements are not deleted automatically! Sometimes this can lead to an invalid FESA Deploy-Unit document !", true);
+	    			ConsoleHandler.printWarning("If this is the case, please remove the obsolete elements by hand.", true);
+	    			ConsoleHandler.printMessage("A backup of your old document will be saved at: " + backup.getRawLocation().makeAbsolute(), true);
+	    			if(backup.exists())
+	    				backup.delete(true, null);
+	    			fesaDeployDoc.copy(backup.getFullPath(), true, null);
+	    		}
+	    		else
+	    		{
+	        		File[] templates = MainPreferencePage.getFESADeployUnitTemplates();
+	        		File template = pickTemplate(event,templates);
+	        		if( template == null) // cancel pressed
+	        			return null;
+	        		ConsoleHandler.printMessage("The following template will be used:" + template.getAbsolutePath(), true);
+	    		    InputStream source = new FileInputStream(template);
+	    		    fesaDeployDoc.create(source, IResource.NONE, null);
+	    		}
+	    		
+				job = new GenerateDeployJob(project, fesaDeployDoc,!deployDocExists);
+			}
+			else
+			{
+				ConsoleHandler.printError("Failed to find SILECS Project Nature", true);
+				return null;
+			}
+		} catch (Exception e)
+        {
+			ConsoleHandler.printError("Failed to generate code: ", true);
+			ConsoleHandler.printStackTrace(e);
+	        return null;
+		}
+            	
+        job.setUser(true);
+        job.schedule();
+        
+        return null;
+    }
+
+	private File pickTemplate(ExecutionEvent event, File[] templates) throws SilecsException
+	{
+		if(templates.length < 1)
+		{
+			String error = "Failed to generate FESA Class. No templates found. please fix your FESA-PATH in the preferences!";
+			ConsoleHandler.printError(error, true);
+			throw new SilecsException(error);
+		}
+		if( templates.length == 1 )
+		{
+			return templates[0];
+		}
+		//TODO: Would be nice to add the possibility to pick a foreign template from the file system
+		Shell activeShell = HandlerUtil.getActiveShell(event);
+		IWizard wizard = new GenerateCodeWizard(templates);
+		WizardDialog dialog = new WizardDialog(activeShell, wizard);
+		dialog.open();
+		return ((GenerateCodeWizard)wizard).getChoice();
+	}
+    
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/SilecsWikis.java b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/SilecsWikis.java
new file mode 100644
index 0000000000000000000000000000000000000000..0973f9857731e9f63a3ab9809feccb1ac182d93a
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/SilecsWikis.java
@@ -0,0 +1,54 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.control.handlers;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+
+import cern.silecs.utils.SilecsUtils;
+import cern.silecs.utils.SilecsConstants;
+
+import java.awt.Desktop;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+ * This handler opens silecs-wiki in the browser.
+ */
+public class SilecsWikis extends AbstractHandler implements IHandler {
+
+    @Override
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+        
+        // Open windows default browser (or firefox under linux) and load Silecs Wikis pages
+        try {
+            if (SilecsUtils.isWindows) {
+                Desktop.getDesktop().browse(new URI(SilecsConstants.SILECS_WIKIS_PATH));
+            } else {
+                Runtime runtime = Runtime.getRuntime();
+                runtime.exec("/usr/bin/firefox -new-window " + SilecsConstants.SILECS_WIKIS_PATH);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (URISyntaxException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/UpdateSilecsProjectHandler.java b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/UpdateSilecsProjectHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..6966b771dc8669d9c8107b720fd6b7aaa802155d
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/UpdateSilecsProjectHandler.java
@@ -0,0 +1,77 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.control.handlers;
+
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.wizard.IWizard;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+import cern.silecs.model.exception.SilecsException;
+import cern.silecs.utils.SilecsUtils;
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.job.BaseProjectJob;
+
+import cern.silecs.view.job.UpdateVersionJob;
+import cern.silecs.view.wizards.UpdateSilecsProjectWizard;
+
+
+public class UpdateSilecsProjectHandler extends AbstractHandler implements IHandler {
+
+	@Override
+    public Object execute(ExecutionEvent event) throws ExecutionException
+	{
+
+		ConsoleHandler.clear();
+		
+        BaseProjectJob job = null;
+        
+        try
+        {
+        	String newVersion = pickVersion(event);
+            IFile silecsFile = SilecsUtils.extractSilecsFileFromEvent(event);
+            IProject project = silecsFile.getProject();
+			job = new UpdateVersionJob(project, newVersion);
+
+		} catch (Exception e)
+        {
+			ConsoleHandler.printError("Failed to update SILECS version: " , true);
+			ConsoleHandler.printStackTrace(e);
+	        return null;
+		}
+            	
+        job.setUser(true);
+        job.schedule();
+        
+        return null;
+	}
+	
+	private String pickVersion(ExecutionEvent event) throws SilecsException
+	{
+		Shell activeShell = HandlerUtil.getActiveShell(event);
+		IWizard wizard = new UpdateSilecsProjectWizard();
+		WizardDialog dialog = new WizardDialog(activeShell, wizard);
+		dialog.open();
+		return ((UpdateSilecsProjectWizard)wizard).getSelectedVersion();
+	}
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/ValidateHandler.java b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/ValidateHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..37e7e05a24b1b20b91d87d07d371b425ddb3eba7
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/control/handlers/ValidateHandler.java
@@ -0,0 +1,52 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.control.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.resources.IFile;
+
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.job.ValidationJob;
+import cern.silecs.utils.SilecsUtils;
+
+
+public class ValidateHandler extends BaseHandler implements IHandler {
+	
+    @Override
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+
+    	ConsoleHandler.clear();
+        ConsoleHandler.printMessage("Validating XML  ...", true);
+        ValidationJob job;
+		try
+		{
+			IFile file = SilecsUtils.extractSilecsFileFromEvent(event);
+			SilecsUtils.checkSilecsVersion(file.getProject());
+			job = new ValidationJob(file);
+		}
+		catch (Exception e)
+		{
+			 ConsoleHandler.printError("Failed to validate file:", true);
+			 ConsoleHandler.printStackTrace(e);
+			 return null;
+		}
+
+        job.schedule();
+        return null;
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/control/validation/Validator.java b/silecs-eclipse-plugin/src/java/cern/silecs/control/validation/Validator.java
new file mode 100644
index 0000000000000000000000000000000000000000..e9e019754aaa974ba24106ec24f8dcd9182ad05f
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/control/validation/Validator.java
@@ -0,0 +1,103 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.control.validation;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.List;
+
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.xni.parser.XMLInputSource;
+import org.eclipse.core.resources.IFile;
+
+import cern.silecs.control.validation.internal.Handler;
+import cern.silecs.model.document.SilecsDocumentError;
+import cern.silecs.view.console.ConsoleHandler;
+
+/**
+ * Class used for validating single xmlFile
+ */
+public class Validator
+{
+    /**
+     * This method takes as an argument xml file.<br>
+     * If the document is not xml file or is somehow broken list with "Document is not parsed correctly" error is returned."<br>
+     * 
+     * External python validation is called in this method!
+     * 
+     * @param xmlFile
+     * @return list of errors
+     */
+    public static List<SilecsDocumentError> validate(File xmlFile)
+    {
+        List<SilecsDocumentError> errors = null;
+        try {
+            // create DOM parser which validates, use a grammar pool,
+            // support xincludes and allow the access to the nodes
+            // during the parsing
+            DOMParser parser = new DOMParser();
+            
+            parser.setFeature("http://xml.org/sax/features/validation", true);
+            parser.setFeature("http://apache.org/xml/features/validation/schema", true);
+            parser.setFeature("http://apache.org/xml/features/honour-all-schemaLocations", true);
+            parser.setFeature("http://apache.org/xml/features/xinclude", true);
+            parser.setFeature("http://apache.org/xml/features/xinclude/fixup-base-uris", false);
+            parser.setFeature("http://apache.org/xml/features/xinclude/fixup-language", false);
+            parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
+
+            // Set the error handler
+            Handler handler = new Handler(xmlFile, parser);
+            parser.setErrorHandler(handler);
+
+            // create the input
+            String uri = xmlFile.toURI().toString().replace("%20", " ");
+            
+            InputStream inputStream = new FileInputStream(xmlFile);
+            XMLInputSource inputSource = new XMLInputSource("", uri, uri, inputStream, "UTF-8");
+            parser.parse(inputSource);
+
+            // get the errors and the model
+            errors = handler.getErrors();
+            errors.addAll(internalRules.validate(xmlFile));
+
+        }
+        catch (Exception e)
+        {
+            ConsoleHandler.printError("Document " + xmlFile.getName() + " has not been parsed correctly: " + e.getMessage(), true);
+            ConsoleHandler.printStackTrace(e);
+        }
+        
+        return errors;
+    }
+    
+    public static boolean isDocumentValid(IFile silecsDocument)
+    {
+        try
+        {
+            File xmlFile = new File(silecsDocument.getLocationURI());
+            if (validate(xmlFile).isEmpty())
+            	return true;
+            return false;
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            ConsoleHandler.printStackTrace(e);
+            return false;
+        }
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/control/validation/internal/Handler.java b/silecs-eclipse-plugin/src/java/cern/silecs/control/validation/internal/Handler.java
new file mode 100644
index 0000000000000000000000000000000000000000..56f49f716173eca614b42b3282197cff55f6dbad
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/control/validation/internal/Handler.java
@@ -0,0 +1,91 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.control.validation.internal;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.xerces.parsers.DOMParser;
+import org.w3c.dom.Element;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.SAXParseException;
+
+import cern.silecs.model.document.SilecsDocumentError;
+import cern.silecs.model.document.SilecsDocumentError.ErrorLevel;
+import cern.silecs.view.console.ConsoleHandler;
+
+public class Handler implements ErrorHandler
+{
+    private static final String CURRENT_NODE = "http://apache.org/xml/properties/dom/current-element-node";
+
+    private final DOMParser parser;
+    private final String fileName;
+    private List<SilecsDocumentError> errors;
+
+    public Handler(File xmlFile, DOMParser parser) {
+        this.parser = parser;
+        this.fileName = xmlFile.getName();
+        this.errors = new ArrayList<SilecsDocumentError>();
+    }
+
+    @Override
+    public void warning(SAXParseException e) throws SAXException {
+        addError(ErrorLevel.WARNING, e);
+    }
+
+    @Override
+    public void error(SAXParseException e) throws SAXException {
+        addError(ErrorLevel.ERROR, e);
+    }
+
+    @Override
+    public void fatalError(SAXParseException e) throws SAXException {
+        addError(ErrorLevel.FATAL, e);
+    }
+
+    public final List<SilecsDocumentError> getErrors() {
+        return errors;
+    }
+
+    private void addError(ErrorLevel level, SAXParseException e) {
+        Element element = null;
+        try
+        {
+            element = (Element) parser.getProperty(CURRENT_NODE);
+        }
+        catch (SAXNotRecognizedException | SAXNotSupportedException e1)
+        {
+        	ConsoleHandler.printStackTrace(e1);
+        	return;
+        }
+        SilecsDocumentError error = null;
+        String file = e.getSystemId();
+        if (!file.endsWith(fileName)) {
+            // if the error is in the included xml or in the schema, we want to report the problem
+            // on the validated file but with a specific message
+            error = new SilecsDocumentError(level, "Error in included file: " + file + " at " + e.getLineNumber() + ":"
+                    + e.getColumnNumber() + " => " + e.getMessage(), -1, -1, null);
+        } else {
+            error = new SilecsDocumentError(level, e, element);
+        }
+
+        errors.add(error);
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/control/validation/internalRules.java b/silecs-eclipse-plugin/src/java/cern/silecs/control/validation/internalRules.java
new file mode 100644
index 0000000000000000000000000000000000000000..0b2524b4df1acb7b70fc6ec8b6a218a1f9c008b9
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/control/validation/internalRules.java
@@ -0,0 +1,201 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.control.validation;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import cern.silecs.model.document.SilecsDocumentError;
+import cern.silecs.utils.SilecsUtils;
+
+public class internalRules {
+
+    public static List<SilecsDocumentError> validate(File file) throws ParserConfigurationException, SAXException, IOException
+    {
+    	// Some of the XSD-checks are version-specific. This is painful and will vanish some day when using XSD1.1 for all checks
+    	//String silecs_version =  
+    			
+    	List<SilecsDocumentError> errors = new ArrayList<SilecsDocumentError>();
+
+    	DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+    	DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+    	Document doc = dBuilder.parse(file);
+    	
+    	if( SilecsUtils.isSilecsDesign(file.getAbsolutePath()) )
+    	{
+    		errors.addAll(classRule_RegisterDim2(doc));
+    		errors.addAll(classRule_RO_Slave(doc));
+    		errors.addAll(classRule_WO_Master(doc));
+    		errors.addAll(classRule_StringLength(doc));
+    	}
+    	if( SilecsUtils.isSilecsDeploy(file.getAbsolutePath()) )
+    	{
+    		errors.addAll(deployRule_addressing_SchneiderM340(doc));
+    		errors.addAll(deployRule_addressing_BeckhoffCX90xx(doc));
+    	}
+        return errors;
+    }
+    
+    private static String getXPath(Node node)
+    {
+        Node parent = node.getParentNode();
+        if (parent == null)
+        {
+            return "/";
+        }
+        
+        if(!((Element)node).getAttribute("name").isEmpty())
+        	return getXPath(parent) + "/" + node.getNodeName() + "[@name='"+ ((Element)node).getAttribute("name") + "']";
+        
+        return getXPath(parent) + "/" + node.getNodeName();
+    }
+    
+    private static List<SilecsDocumentError> classRule_RegisterDim2(Document doc)
+    {
+    	List<SilecsDocumentError> errors = new ArrayList<SilecsDocumentError>();
+    	NodeList regNodes = doc.getElementsByTagName("Register");
+    	for( int i = 0; i< regNodes.getLength() ; i++)
+    	{
+    		Element register = (Element)regNodes.item(i);
+    		if( register.hasAttribute("array-dim2") && !register.hasAttribute("array-dim1") )
+    		{
+                SilecsDocumentError newError = new SilecsDocumentError( SilecsDocumentError.ErrorLevel.ERROR, "array-dim1 is required if array-dim2 is defined", -1, -1,getXPath(register));
+                errors.add(newError);
+    		}
+    	}
+    	return errors;
+    }
+    
+    private static List<SilecsDocumentError> classRule_RO_Slave(Document doc)
+    {
+    	List<SilecsDocumentError> errors = new ArrayList<SilecsDocumentError>();
+    	NodeList blockNodes = doc.getElementsByTagName("Block");
+    	for( int i = 0; i< blockNodes.getLength() ; i++)
+    	{
+    		Element block = (Element)blockNodes.item(i);
+    		if( block.getAttribute("mode").equals("READ-ONLY") )
+    		{
+    			NodeList registerNodes = block.getElementsByTagName("Register");
+    			for( int j = 0; j< registerNodes.getLength() ; j++)
+    			{
+    				Element register = (Element)registerNodes.item(j);
+    	    		if( register.getAttribute("synchro").equals("SLAVE") )
+    	    		{
+    	                SilecsDocumentError newError = new SilecsDocumentError( SilecsDocumentError.ErrorLevel.ERROR, "Register cannot have SLAVE synchro attribute within READ-ONLY block", -1, -1,getXPath(register));
+    	                errors.add(newError);
+    	    		}
+    			}
+    		}
+    	}
+    	return errors;
+    }
+    
+    private static List<SilecsDocumentError> classRule_WO_Master(Document doc)
+    {
+    	List<SilecsDocumentError> errors = new ArrayList<SilecsDocumentError>();
+    	NodeList blockNodes = doc.getElementsByTagName("Block");
+    	for( int i = 0; i< blockNodes.getLength() ; i++)
+    	{
+    		Element block = (Element)blockNodes.item(i);
+    		if( block.getAttribute("mode").equals("WRITE-ONLY"))
+    		{
+    			NodeList registerNodes = block.getElementsByTagName("Register");
+    			for( int j = 0; j< registerNodes.getLength() ; j++)
+    			{
+    				Element register = (Element)registerNodes.item(j);
+    	    		if( register.getAttribute("synchro").equals("MASTER") )
+    	    		{
+    	                SilecsDocumentError newError = new SilecsDocumentError( SilecsDocumentError.ErrorLevel.ERROR, "Register cannot have MASTER synchro attribute within WRITE-ONLY block", -1, -1,getXPath(register));
+    	                errors.add(newError);
+    	    		}
+    			}
+    		}
+    	}
+    	return errors;
+    }
+    	
+    private static List<SilecsDocumentError> classRule_StringLength(Document doc)
+    {
+    	List<SilecsDocumentError> errors = new ArrayList<SilecsDocumentError>();
+		NodeList registerNodes = doc.getElementsByTagName("Register");
+		for( int j = 0; j< registerNodes.getLength() ; j++)
+		{
+			Element register = (Element)registerNodes.item(j);
+    		if( register.getAttribute("format").equals("string") == false )
+    		{
+    			if( register.hasAttribute("string-len"))
+    			{
+	                SilecsDocumentError newError = new SilecsDocumentError( SilecsDocumentError.ErrorLevel.ERROR, "string-len attribute only allowed for @format='string'.", -1, -1,getXPath(register));
+	                errors.add(newError);
+    			}
+    		}
+		}
+    	return errors;
+    }
+
+    private static List<SilecsDocumentError> deployRule_addressing_SchneiderM340(Document doc)
+    {
+    	List<SilecsDocumentError> errors = new ArrayList<SilecsDocumentError>();
+		NodeList schneiderPLCNode = doc.getElementsByTagName("Schneider-PLC");
+		for( int i = 0; i< schneiderPLCNode.getLength() ; i++)
+		{
+			Element plc = (Element)schneiderPLCNode.item(i);
+    		if( plc.getAttribute("model").equals("M340"))
+    		{
+    			int basAddress = Integer.parseInt( plc.getAttribute("base-address"));
+    			if( basAddress%2 != 0 )
+    			{
+	                SilecsDocumentError newError = new SilecsDocumentError( SilecsDocumentError.ErrorLevel.ERROR, "Only even addressing is allowed for UNITY_M340. Please change the base address value to an even number.", -1, -1,getXPath(plc));
+	                errors.add(newError);
+    			}
+    		}
+		}
+    	return errors;
+    }
+    
+    private static List<SilecsDocumentError> deployRule_addressing_BeckhoffCX90xx(Document doc)
+    {
+    	List<SilecsDocumentError> errors = new ArrayList<SilecsDocumentError>();
+		NodeList schneiderPLCNode = doc.getElementsByTagName("Beckhoff-PLC");
+		for( int i = 0; i< schneiderPLCNode.getLength() ; i++)
+		{
+			Element plc = (Element)schneiderPLCNode.item(i);
+    		if( plc.getAttribute("model").equals("CX9020"))
+    		{
+    			int basAddress = Integer.parseInt( plc.getAttribute("base-address"));
+    			if( basAddress%2 != 0 )
+    			{
+	                SilecsDocumentError newError = new SilecsDocumentError( SilecsDocumentError.ErrorLevel.ERROR, "Only even addressing is allowed for TWINCAT_CX9020. Please change the base address value to an even number.", -1, -1,getXPath(plc));
+	                errors.add(newError);
+    			}
+    		}
+		}
+    	return errors;
+    }
+    
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/model/document/SilecsDocumentError.java b/silecs-eclipse-plugin/src/java/cern/silecs/model/document/SilecsDocumentError.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e0f25d495e4582a6d5b167d525f5fab6c207015
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/model/document/SilecsDocumentError.java
@@ -0,0 +1,106 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.model.document;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.w3c.dom.Node;
+import org.xml.sax.SAXParseException;
+
+import cern.silecs.utils.XmlUtils;
+
+
+public class SilecsDocumentError {
+
+    public enum ErrorLevel {
+        INFO,
+        WARNING,
+        ERROR,
+        FATAL
+    }
+
+    /**
+     * error level
+     */
+    public final ErrorLevel level;
+
+    /**
+     * text with the description of the error
+     */
+    public final String message;
+
+    /**
+     * line of the error
+     */
+    public final int lineNumber;
+
+    /**
+     * column of the error
+     */
+    public final int columnNumber;
+
+    /**
+     * Element which cause the error
+     */
+    public final String xPath;
+    
+    /**
+     * If an identity constraint has been violated, this contains the name of the violated key
+     */
+    public final String violatedKey;
+    
+    /**
+     * If an identity constraint has been violated, this contains the incorrect value which is the cause of the error
+     */
+    public final String incorrectValue;
+    
+    private static final String CONSTRAINT_MESSAGE_PATTERN = "cvc-identity-constraint.4.3: Key '(.*)' with value '(.*)' not found for identity constraint of element '(.*)'\\.";
+
+    public SilecsDocumentError(ErrorLevel level, String message, int lineNumber, int columnNumber, String xPath) {
+        this.level = level;
+        this.message = message;
+        this.lineNumber = lineNumber;
+        this.columnNumber = columnNumber;
+        this.xPath = xPath;
+        
+        String key = "";
+        String value = "";
+        Pattern constraintPattern = Pattern.compile(CONSTRAINT_MESSAGE_PATTERN);
+        Matcher m = constraintPattern.matcher(message);
+        if (m.find()) {
+            key = m.group(1);
+            value =  m.group(2);
+        }
+        
+        this.violatedKey = key;
+        this.incorrectValue = value;
+    }
+
+    public SilecsDocumentError(ErrorLevel level, SAXParseException e, Node node) {
+        this(level, e.getMessage(), e.getLineNumber(), e.getColumnNumber(), XmlUtils.xPathFromNode(node));
+    }
+    
+    public boolean isIdentityConstraintError() {
+        return !violatedKey.isEmpty();
+    }
+
+    @Override
+    public String toString() {
+        return lineNumber + ":" + columnNumber + " => " + message;
+    }
+}
+
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/model/document/XmlBasedDocument.java b/silecs-eclipse-plugin/src/java/cern/silecs/model/document/XmlBasedDocument.java
new file mode 100644
index 0000000000000000000000000000000000000000..e48c06af87bf6d8692b6843fcd8739776f872c2c
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/model/document/XmlBasedDocument.java
@@ -0,0 +1,234 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.model.document;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+
+import org.apache.xpath.XPathAPI;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import cern.silecs.model.exception.SilecsException;
+import cern.silecs.utils.XmlUtils;
+import cern.silecs.view.console.ConsoleHandler;
+
+public class XmlBasedDocument {
+
+    public static final String XML_EXTENSION = ".xml";
+    public static final String XSD_EXTENSION = ".xsd";
+
+    protected Document xmlDocument;
+
+    /**
+     * Abstract class for data access object based on xml DOM
+     */
+    public XmlBasedDocument(Document xmlDocument) {
+        this.xmlDocument = xmlDocument;
+    }
+
+    /**
+     * Give the DOM
+     * 
+     * @return
+     */
+    public Document getXmlDocument() {
+        return xmlDocument;
+    }
+
+    /**
+     * Helper that gives the list of element from an xPath query
+     * 
+     * @param xPathQuery
+     * @return
+     * @throws SilecsException
+     */
+    public List<Element> getElements(String xPathQuery) throws SilecsException {
+        return getElements(xmlDocument, xPathQuery);
+    }
+
+    /**
+     * Helper that gives the list of element from an xPath query
+     * 
+     * @param node node from where the query is executed
+     * @param xPathQuery
+     * @return
+     * @throws SilecsException
+     */
+    public List<Element> getElements(Node node, String xPathQuery) throws SilecsException {
+        List<Node> nodes = getNodes(node, xPathQuery);
+        List<Element> elements = new ArrayList<Element>(nodes.size());
+
+        for (Node n : nodes) {
+            if (n instanceof Element) {
+                elements.add((Element) n);
+            }
+        }
+
+        return elements;
+    }
+
+    /**
+     * Helper that gives the first element from an xPath query
+     * 
+     * @param xPathQuery
+     * @return
+     * @throws SilecsException
+     */
+    public Element getSingleElement(String xPathQuery) throws SilecsException {
+        Node foundNode = getSingleNode(xPathQuery);
+        if (foundNode instanceof Element) {
+            return (Element) foundNode;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Helper that gives the first element from an xPath query
+     * 
+     * @param node node from where the query is executed
+     * @param xPathQuery
+     * @return
+     * @throws SilecsException
+     */
+    public Element getSingleElement(Node node, String xPathQuery) throws SilecsException {
+        Node foundNode = getSingleNode(node, xPathQuery);
+        if (foundNode instanceof Element) {
+            return (Element) foundNode;
+        } else {
+            return null;
+        }
+    }
+
+    public List<Node> getNodes(String xPathQuery) throws SilecsException {
+        return getNodes(xmlDocument, xPathQuery);
+    }
+
+    public List<Node> getNodes(Node node, String xPathQuery) throws SilecsException {
+        if (xPathQuery == null || xPathQuery.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        // check the node is from the document
+        if (node != xmlDocument && node.getOwnerDocument() != xmlDocument) {
+            throw new SilecsException("The given node is not part of the document being queried");
+        }
+
+        try {
+            NodeList foundNodes = XPathAPI.selectNodeList(node, xPathQuery);
+            List<Node> nodes = new ArrayList<Node>(foundNodes.getLength());
+
+            for (int i = 0; i < foundNodes.getLength(); i++) {
+                nodes.add(foundNodes.item(i));
+            }
+
+            return nodes;
+        } catch (TransformerException e) {
+            throw new SilecsException("Could not get entity's node using xpath " + xPathQuery, e);
+        }
+    }
+
+    /**
+     * Helper that gives the first node from an xPath query
+     * 
+     * @param xPathQuery
+     * @return
+     * @throws SilecsException
+     */
+    public Node getSingleNode(String xPathQuery) throws SilecsException {
+        if (xPathQuery == null || xPathQuery.isEmpty()) {
+            return null;
+        }
+
+        try {
+            return XPathAPI.selectSingleNode(xmlDocument, xPathQuery);
+        } catch (TransformerException e) {
+            throw new SilecsException("Could not get entity's node using xpath " + xPathQuery, e);
+        }
+    }
+
+    /**
+     * Helper that gives the first node from an xPath query
+     * 
+     * @param node node from where the query is executed
+     * @param xPathQuery
+     * @return
+     * @throws SilecsException
+     */
+    public Node getSingleNode(Node node, String xPathQuery) throws SilecsException {
+        if (xPathQuery == null || xPathQuery.isEmpty()) {
+            return null;
+        }
+
+        // check the node is from the document
+        if (node.getOwnerDocument() != xmlDocument) {
+            throw new SilecsException("The given node is not part of the document being queried");
+        }
+
+        try {
+            return XPathAPI.selectSingleNode(node, xPathQuery);
+        } catch (TransformerException e) {
+            throw new SilecsException("Could not get entity's node using xpath " + xPathQuery, e);
+        }
+    }
+
+    /**
+     * Helper that gives the tag name of the elements matched by the xpath
+     * 
+     * @param xPathQuery
+     * @return
+     * @throws SilecsException
+     */
+    public List<String> getTagNames(String xPathQuery) throws SilecsException {
+        List<Element> elements = getElements(xPathQuery);
+        List<String> nodeNames = new ArrayList<String>(elements.size());
+
+        for (Element e : elements) {
+            nodeNames.add(e.getTagName());
+        }
+
+        return nodeNames;
+    }
+
+    /**
+     * Give the string representation of the DOM
+     */
+    @Override
+    public String toString()
+    {
+        try
+        {
+            return XmlUtils.nodeToString(xmlDocument);
+        }
+        catch( TransformerException e)
+        {
+        	ConsoleHandler.printStackTrace(e);
+            return super.toString();
+        }
+        catch(TransformerFactoryConfigurationError e)
+        {
+        	ConsoleHandler.printStackTrace(e.getException());
+            return super.toString();
+        }
+    }
+}
\ No newline at end of file
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/model/exception/SilecsException.java b/silecs-eclipse-plugin/src/java/cern/silecs/model/exception/SilecsException.java
new file mode 100644
index 0000000000000000000000000000000000000000..0e8ff657122b1112613458f7a58064a88ecd9c11
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/model/exception/SilecsException.java
@@ -0,0 +1,95 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.model.exception;
+
+
+public class SilecsException extends Exception {
+
+    private static final long serialVersionUID = 5282474727123991544L;
+
+    /**
+     * The error code which can be used to localize the error messages
+     */
+    private final int errorCode;
+
+    /** Empty constructor **/
+    public SilecsException() {
+        this.errorCode = -1;
+    }
+
+    /**
+     * Constructor with the Silecs error code
+     * 
+     * @param errorCode
+     */
+    public SilecsException(int errorCode) {
+        this.errorCode = errorCode;
+    }
+
+    /**
+     * Constructor
+     * 
+     * @param message
+     */
+    public SilecsException(String message) {
+        super(message);
+        this.errorCode = -1;
+    }
+
+    /**
+     * Constructor with the Silecs error code
+     * 
+     * @param errorCode
+     * @param message
+     */
+    public SilecsException(int errorCode, String message) {
+        super(message);
+        this.errorCode = errorCode;
+    }
+
+    /**
+     * Constructor
+     * 
+     * @param message
+     * @param cause previous cause of the error (exception chaining)
+     */
+    public SilecsException(String message, Throwable cause) {
+        super(message, cause);
+        this.errorCode = -1;
+    }
+
+    /**
+     * Constructor
+     * 
+     * @param errorCode
+     * @param message
+     * @param cause
+     */
+    public SilecsException(int errorCode, String message, Throwable cause) {
+        super(message, cause);
+        this.errorCode = errorCode;
+    }
+
+    /**
+     * Returns the Silecs error code
+     * -1 is the default value if no error code is set
+     * @return
+     */
+    public int getErrorCode() {
+        return errorCode;
+    }
+}
+
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/utils/OSExecute.java b/silecs-eclipse-plugin/src/java/cern/silecs/utils/OSExecute.java
new file mode 100644
index 0000000000000000000000000000000000000000..929f7d2043198f0f53e8d9381c1ed62b6e57dceb
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/utils/OSExecute.java
@@ -0,0 +1,142 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.utils;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import cern.silecs.model.exception.SilecsException;
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.preferences.MainPreferencePage;
+
+public class OSExecute
+{
+    
+    public static String getlatestSilecsFesaCodegen(String codegenBaseDirectory, String silecsVersion) throws SilecsException
+	{
+    	String fesaBaseDirectory = codegenBaseDirectory + "/fesa";
+    	if(!new File(fesaBaseDirectory).exists())
+    	{
+    		throw new SilecsException("The directory: '" + fesaBaseDirectory + "' does not exist. Please check your Eclipse-Silecs preferences!");
+    	}
+    	List<String> availableFesaVersions = MainPreferencePage.getAllFesaVersions();
+    	String selectedFesaVersion =  MainPreferencePage.getFESAVersion();
+    	String tempFesaVersion = selectedFesaVersion;
+    	int fesaVersionIndex = availableFesaVersions.lastIndexOf(selectedFesaVersion);
+    	String fesaDirectory = "";
+    	while(true)
+    	{
+	    	String fesaVersionUnderscored = tempFesaVersion.replaceAll("\\.", "_");
+	    	fesaDirectory = fesaBaseDirectory + "/fesa_" + fesaVersionUnderscored;
+	    	if(new File(fesaDirectory).exists())
+	    	{
+	    		return fesaDirectory;
+	    	}
+        	fesaVersionIndex ++ ;
+        	if( fesaVersionIndex >= availableFesaVersions.size() )
+        	{
+        		throw new SilecsException("No matching silecs code-generation found for FESA-version '" + selectedFesaVersion + "'. Please select a more recent FESA-version in the Eclipse-Silecs preferences!");
+        	}
+        	ConsoleHandler.printError("No silecs code-generation for the FESA-version '" + tempFesaVersion + "' found. Attempt to use silecs-codegen for the older FESA-version: '" + availableFesaVersions.get(fesaVersionIndex) + "'", true);
+        	tempFesaVersion = availableFesaVersions.get(fesaVersionIndex);
+    	}
+	}
+    
+    
+    public static void executePython(String file, String method, String silecsVersion, String[] parameters) throws IOException, InterruptedException, SilecsException
+    {   
+    	String[] command = new String[3];  
+    	command[0] = "python";
+    	command[1] = "-c";
+    	
+    	String codegenBaseDirectory = MainPreferencePage.getCodeGenBasePath(silecsVersion);
+    	String fesaDirectory = getlatestSilecsFesaCodegen(codegenBaseDirectory, silecsVersion);
+        
+    	// Add required root directories
+    	command[2] = "import sys; ";
+    	command[2] += "sys.path.append('" + codegenBaseDirectory + "'); ";
+    	command[2] += "sys.path.append('" + codegenBaseDirectory + "/migration'); "; 
+    	command[2] += "sys.path.append('" + fesaDirectory + "'); ";
+    	
+    	// import file
+    	command[2] += "import " + file + "; ";
+    	
+    	// execute method
+    	command[2] += file +"." + method + "(";
+    	
+    	for(int i=0;i<parameters.length;i++)
+	    {
+    		command[2] += "'" + parameters[i] + "'";
+    		if( i < parameters.length - 1)
+    		{
+    			command[2] += ",";
+    		}
+	    }
+    	command[2] += ")";
+    	int exitCode = executeCommand(command);
+        if (exitCode != 0)
+        {
+            throw new SilecsException("Executing python-command '" + command[2] + "' failed. Error code: " + exitCode);
+        }
+    }
+    
+    class Environment
+    {
+    	String environmentVariableName;
+    	
+    	
+    };
+    
+    public static int executeCommand(String... command) throws IOException, InterruptedException, SilecsException
+    {
+    	Map<String, String> env = new HashMap<String, String>();
+    	return executeCommand(env, command);
+    }
+    
+    public static int executeCommand(Map<String, String> environmentVariables, String... command) throws IOException, InterruptedException, SilecsException
+    {
+		ProcessBuilder pb = new ProcessBuilder(command);
+		Map<String, String> env = pb.environment();
+		env.putAll(environmentVariables);
+		
+		Process process = pb.start();
+        process.waitFor();
+        int exitCode = process.exitValue();
+
+        BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
+        String line;
+		while ((line = input.readLine()) != null)
+        {
+			ConsoleHandler.printMessage(line, true);
+        }
+        input.close();
+		
+        BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream()));
+
+		while ((line = error.readLine()) != null)
+        {
+			ConsoleHandler.printError(line, true);
+        }
+		error.close();
+		
+		return exitCode;
+    }
+}
\ No newline at end of file
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/utils/SilecsConstants.java b/silecs-eclipse-plugin/src/java/cern/silecs/utils/SilecsConstants.java
new file mode 100644
index 0000000000000000000000000000000000000000..da2ea02d172d6c0a8f56538760239234cdec62ba
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/utils/SilecsConstants.java
@@ -0,0 +1,103 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.utils;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class SilecsConstants {
+
+	public enum ProjectType {
+	    DESIGN_PROJECT,
+	    DEPLOY_PROJECT
+	}
+	
+    public static final String SILECS_NAME = "Silecs-Eclipse-Plugin";
+    
+    //consistency check
+    public static final String DESIGN_CLASS_NODE = "SILECS-Class";
+    
+    public static final String DEPLOY_UNIT_NODE = "Deploy-Unit";
+    
+    public static final String NAME = "name";
+    
+    public static final String HOST_NAME = "host-name";
+    
+    // schema files
+    public static final String DESIGN_SCHEMA_XSD = "DesignSchema.xsd";
+    
+    public static final String DEPLOY_SCHEMA_XSD = "DeploySchema.xsd";
+    
+    //file extensions
+    public static final String IEDESIGN_FILE = "silecsdesign";
+    
+    public static final String IEDEPLOY_FILE = "silecsdeploy";
+    
+    //name patterns
+    public static final String DESIGN_PATTERN = "[A-Z][A-Za-z0-9_]*";
+    
+    public static final String DEPLOY_PATTERN = "[A-Z][A-Za-z0-9_]*";
+    
+    public static final int MAX_DESIGN_LENGTH = 12;
+    
+    public static final int MAX_DEPLOY_LENGTH = 20;
+   
+    public static final String CLASS_VERSION_PATTERN = "[0-9]*\\.[0-9]*\\.[0-9]*";
+    
+    public static final String IEPLC_3_VERSION_PATTERN = "[0-9]*";
+    
+    public static final String FULL_DESIGN_PATTERN = "[A-Z][A-Za-z0-9_]*[_][0-9]\\.[0-9]\\.[0-9]";
+    
+    // SILECS versions which are supported by this plugin
+    public static final String[] SUPPORTED_SILECS_MAJOR_VERSIONS = { "1","DEV"};
+    public static final List<String> ADDITIONAL_SILECS_TARGET_MIGRATION_VERSIONS = Arrays.asList("0.10.0"); //e.g. in order to allow migration from 0.9.0 to 0.10.0
+    public static final int DEFAULT_SILECS_VERSION_INDEX = 0;
+    
+    // SILECS Versions which are NOT supported by this plugin
+    // All other versions foudn in the silecs-search path are supported
+    public static final String[] SILECS_VERSION_BLACKLIST = { "0.9.0" };
+    
+    //Wizards
+        //New Design Wizard
+    public static final String NEW_DESIGN_WIZARD_TITLE = "New Design Wizard";
+    public static final String NEW_DESIGN_PAGE_TITLE = "New Design Project";
+    
+        //New Deploy Wizard
+    public static final String NEW_DEPLOY_WIZARD_TITLE = "New Deploy Wizard";
+    public static final String NEW_DEPLOY_PAGE_TITLE = "New Deploy Project";
+    
+        //New Class Wizard Page
+    
+    public static final String INVAILD_PROJECT_NAME= "Invaild project name. Project name must follow pattern:";
+    
+    public static final String INITIAL_PROJECT_VERSION = "1.0.0";
+    
+        //Generate Fesa Class Wizard
+    public static final String GENERATE_FESA_CLASS_WIZARD_TITLE = "Generate Fesa Class Wizard";
+    public static final String GENERATE_FESA_CLASS_PAGE_TITLE = "Generate Fesa Class";
+    
+        //Generate Client Resources Wizard
+    public static final String GENERATE_CLIENT_RESOURCES_WIZARD_TITLE = "Generate Client Resources Wizard";
+    public static final String GENERATE_CLIENT_RESOURCES_PAGE_TITLE = "Generate Client Resources";
+    
+        //Deliver Client Resources Wizard
+    public static final String DELIVER_CLIENT_RESOURCES_WIZARD_TITLE = "Deliver Client Resources Wizard";
+    public static final String DELIVER_CLIENT_RESOURCES_PAGE_TITLE = "Deliver Client Resources";
+    
+    //GSI-Hack Use GSI SILECS Wiki
+    //public static final String SILECS_WIKIS_PATH = "https://wikis.cern.ch/display/SIL";
+    public static final String SILECS_WIKIS_PATH = "https://www-acc.gsi.de/wiki/Frontend/SILECS";
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/utils/SilecsUtils.java b/silecs-eclipse-plugin/src/java/cern/silecs/utils/SilecsUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..12d0376087f6a35693765e5b0da6fff8d8f78e79
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/utils/SilecsUtils.java
@@ -0,0 +1,311 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.utils;
+
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ITreeSelection;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.ui.part.FileEditorInput;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import cern.silecs.activator.Activator;
+import cern.silecs.control.core.DeployProjectNature;
+import cern.silecs.control.core.DesignProjectNature;
+import cern.silecs.model.exception.SilecsException;
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.preferences.MainPreferencePage;
+
+public class SilecsUtils {
+    
+    public static final String CLASS_VERSION_MATCHER = "version";
+    
+    static public String userName;
+    static public boolean isWindows = false;
+    static {
+        String system = System.getProperty("os.name");
+        isWindows = system.toLowerCase().contains("win");
+        userName = System.getProperty("user.name");
+    }
+
+    public static String findInBundle(String resourceToLocate) {
+        try {
+            URL fileURL = FileLocator.find(Platform.getBundle(Activator.PLUGIN_ID), new Path(resourceToLocate), null);
+            fileURL = FileLocator.toFileURL(fileURL);
+            if(isWindows)
+                return fileURL.getPath().toString().substring(1);
+            
+            return fileURL.getPath().toString();
+        } catch (Exception e1) {
+            e1.printStackTrace();
+        }
+        return null;
+    }
+
+    public static String getSilecsDesignFilePath(String workspacePath, String projectName) {
+    	return workspacePath + "/" + projectName + "/" + getSilecsDesignFilePathRelative(projectName);
+    }
+    
+    public static String getSilecsDeployFilePath(String workspacePath, String projectName) {
+    	return workspacePath + "/" + projectName + "/" + getSilecsDeployFilePathRelative(projectName);
+    }
+    
+    public static String getSilecsDesignFilePathRelative(String projectName) {
+    	return "/src/" + projectName + "." + SilecsConstants.IEDESIGN_FILE;
+    }
+    
+    public static String getSilecsDeployFilePathRelative(String projectName){
+    	return "/src/" + projectName + "." + SilecsConstants.IEDEPLOY_FILE;
+    }
+    
+    public static Boolean isSilecsDesign(String filePath)
+    {
+		String extension = "";
+		int i = filePath.lastIndexOf('.');
+		if (i > 0)
+		    extension = filePath.substring(i+1);
+		if(extension.equals(SilecsConstants.IEDESIGN_FILE) )
+			return true;
+		return false;
+    }
+    
+    public static Boolean isSilecsDeploy(String filePath)
+    {
+		String extension = "";
+		int i = filePath.lastIndexOf('.');
+		if (i > 0)
+		    extension = filePath.substring(i+1);
+		if(extension.equals(SilecsConstants.IEDEPLOY_FILE) )
+			return true;
+		return false;
+    }
+
+    public static IFile getSilecsDesignFile(IProject project) {
+        return project.getFile(getSilecsDesignFilePathRelative(project.getName()));
+    }
+    
+    public static IFile getSilecsDeployFile(IProject project) {
+        return project.getFile(getSilecsDeployFilePathRelative(project.getName()));
+    }
+
+    public static IFile getSilecsDocument(IProject project) throws Exception
+    {
+		if ( project.hasNature(DesignProjectNature.NATURE_ID) )
+		{
+			return SilecsUtils.getSilecsDesignFile(project);
+		}
+		else if( project.hasNature(DeployProjectNature.NATURE_ID) )
+		{
+			return SilecsUtils.getSilecsDeployFile(project);
+		}
+		else
+        	 throw new Exception("The project: " + project.getName() + " is not a silecs-project");
+    }
+    
+    public static String getSilecsVersion(IProject project) throws SilecsException {
+    	String filePath = "";
+    	try 
+    	{
+    		if( project.hasNature(DeployProjectNature.NATURE_ID) )
+    		{
+    			filePath = getSilecsDeployFile(project).getRawLocation().makeAbsolute().toOSString();
+    		}
+    		else if( project.hasNature(DesignProjectNature.NATURE_ID) )
+    		{
+    			filePath = getSilecsDesignFile(project).getRawLocation().makeAbsolute().toOSString();
+    		}
+    		else
+    		{
+    			throw new SilecsException("Faild to extract project nature from: " + project.getName());
+    		}
+
+	    	DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+	    	DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+	    	Document doc = dBuilder.parse(filePath);
+	    	Node root;
+	    	if( project.hasNature(DesignProjectNature.NATURE_ID) )
+	    		root = doc.getElementsByTagName("SILECS-Design").item(0);
+	    	else
+	    		root = doc.getElementsByTagName("SILECS-Deploy").item(0);
+	    	return root.getAttributes().getNamedItem("silecs-version").getTextContent();
+    	}
+    	catch(Exception ex)
+    	{
+    		ConsoleHandler.printError("Faild to extract silecs-version from: " + filePath, true);
+    		
+    		throw new SilecsException("Faild to extract silecs-version from: " + filePath, ex);
+    	}
+    }
+    
+    public static String getSilecsDesignVersion(String filePath) throws SilecsException {
+    	try 
+    	{
+	    	DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+	    	DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+	    	Document doc = dBuilder.parse(filePath);
+	    	Node classNode = doc.getElementsByTagName("SILECS-Class").item(0);
+	    	return classNode.getAttributes().getNamedItem(CLASS_VERSION_MATCHER).getNodeValue();
+    	}
+    	catch(Exception ex)
+    	{
+    		ConsoleHandler.printError("Faild to extract class-version from: " + filePath, true);
+    		throw new SilecsException("Faild to extract class-version from: " + filePath, ex);
+    	}
+    }
+    
+    public static String getDeployVersion(String filePath) throws SilecsException {
+    	try 
+    	{
+	    	DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+	    	DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+	    	Document doc = dBuilder.parse(filePath);
+	    	Node deployNode = doc.getElementsByTagName("Deploy-Unit").item(0);
+	    	return deployNode.getAttributes().getNamedItem(CLASS_VERSION_MATCHER).getNodeValue();
+		}
+		catch(Exception ex)
+		{
+			ConsoleHandler.printError("Faild to extract deploy-version from: " + filePath, true);
+			throw new SilecsException("Faild to extract deploy-version from: " + filePath, ex);
+		}
+    }
+    
+    public static void openInEditor(IFile file)
+    {
+    	Display.getDefault().asyncExec(new Runnable() {
+    	    @Override
+    	    public void run() {
+    	    	IEditorDescriptor desc = PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor(file.getName());
+    	    	IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+    	    	try {
+					page.openEditor(new FileEditorInput(file), desc.getId());
+				} catch (Exception e) {
+			    	 ConsoleHandler.printError("Failed to open file:" + file, true);
+			    	 e.printStackTrace();
+				}
+    	    }
+    	});
+    }
+
+    	
+    public static void checkSilecsVersion(IProject project) throws SilecsException
+    {
+    	String version = getSilecsVersion(project);
+    	if( isSilecsVersionSupported(version) == false )
+    	{
+    		throw new SilecsException("The old silecs version: '" + version + "' is not supported by this silecs-plugin. Please update your SILECS project to a more recent version (right-click --> SILECS Update Project)");
+    	}
+    }
+    
+    
+    public static Boolean isSilecsVersionSupported(String version)
+    {
+    	for(String supportedVersion: SilecsConstants.SUPPORTED_SILECS_MAJOR_VERSIONS)
+    	{
+    		if(version.startsWith(supportedVersion))
+    			return true;
+    	}
+    	return false;
+    }
+    
+    public static List<String> readOutAvailableSilecsVersions()
+	{
+    	List<String> silecsVersions = new ArrayList<String>();
+    	if (MainPreferencePage.isLocalDirectoryUsed())
+    	{
+    		silecsVersions.add("DEV");
+    		return silecsVersions;
+    	}
+    	
+    	// We just pick any sub-project
+		File silecsBaseFolder = new File(MainPreferencePage.getGlobalSilecsDirectory() + "/silecs-model");
+	    for (final File fileEntry : silecsBaseFolder.listFiles())
+	    {
+	    	silecsVersions.add(fileEntry.getName());
+	    }
+	    Collections.sort(silecsVersions);
+	    Collections.reverse(silecsVersions);
+	    return silecsVersions;
+	}
+    
+    public static IFile extractSilecsFileFromEvent(ExecutionEvent event) throws Exception
+	{
+    	String parameter = event.getParameter("silecs-eclipse-plugin.commandParameter");
+    	if ( parameter.equals("menubar"))
+    	{
+			IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
+			IWorkbenchPage activePage = window.getActivePage();
+	
+	        // Get the Selection from the active WorkbenchPage page
+	        ISelection selection = activePage.getSelection();
+	        if(selection instanceof ITreeSelection) // Event was triggered by right-click on project
+	        {
+	            TreeSelection treeSelection = (TreeSelection) selection;
+	            TreePath[] treePaths = treeSelection.getPaths();
+	            TreePath treePath = treePaths[0];
+	
+	            // The first segment should be a IProject
+	            Object firstSegmentObj = treePath.getFirstSegment();
+	            IProject theProject = (IProject) ((IAdaptable)firstSegmentObj).getAdapter(IProject.class);
+	            if( theProject == null )
+	            {
+	            	ConsoleHandler.printError("Failed to find the right project", true);
+	            	throw new ExecutionException("Failed to find the right project");
+	            }
+	            return getSilecsDocument(theProject);
+	        }
+    	}
+    	if (parameter.equals("toolbar"))
+    	{
+	        // The default: the toolbar button was pressed
+	    	IEditorPart editor = HandlerUtil.getActiveEditor(event);
+	        if (editor == null)
+	        {
+	        	ConsoleHandler.printError("Failed to find active SILECS editor", true);
+	        	throw new Exception("Failed to find active SILECS editor");
+	        } 
+	    	return ((IFileEditorInput) editor.getEditorInput()).getFile();
+    	}
+    	String message = new String("Failed to find correct silecs-project/file - command: '" + event.getCommand().getName() + "' send with parameter: '" + parameter + "'.");
+    	ConsoleHandler.printError(message, true);
+    	throw new Exception(message);
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/utils/XmlUtils.java b/silecs-eclipse-plugin/src/java/cern/silecs/utils/XmlUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..218810bb45642afd65e41e01083ebe9463c6293b
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/utils/XmlUtils.java
@@ -0,0 +1,188 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.utils;
+
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
+import org.eclipse.wst.xml.core.internal.contentmodel.modelqueryimpl.CMDocumentLoader;
+import org.eclipse.wst.xml.core.internal.contentmodel.modelqueryimpl.InferredGrammarBuildingCMDocumentLoader;
+import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+@SuppressWarnings("restriction")
+public class XmlUtils {
+
+    private static TransformerFactory TRANSFORMER_FACTORY;
+
+    public static String nodeToString(Node node) throws TransformerFactoryConfigurationError, TransformerException {
+        Transformer transformer = createPrettyTransformer();
+
+        // if given node is not a complete document, we do not
+        // put the xml declaration. we also omit if the document already has
+        // a type
+        if (!(node instanceof Document) || ((Document) node).getDoctype() != null) {
+            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+        }
+
+        // write node to string
+        DOMSource source = new DOMSource(node);
+        StringWriter writer = new StringWriter();
+        StreamResult result = new StreamResult(writer);
+        transformer.transform(source, result);
+
+        return writer.toString();
+    }
+
+
+    private static Transformer createPrettyTransformer() throws TransformerConfigurationException,
+            TransformerFactoryConfigurationError {
+        if (TRANSFORMER_FACTORY == null) {
+            TRANSFORMER_FACTORY = TransformerFactory.newInstance();
+        }
+        Transformer t = TRANSFORMER_FACTORY.newTransformer();
+        t.setOutputProperty(OutputKeys.INDENT, "yes");
+        t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
+
+        return t;
+    }
+
+    public static String xPathFromNode(Node node) {
+        if (node == null) {
+            return "";
+        }
+
+        switch (node.getNodeType()) {
+        case Node.DOCUMENT_NODE:
+            return "";
+
+        case Node.ATTRIBUTE_NODE:
+            Attr attr = (Attr) node;
+            return xPathFromNode(attr.getOwnerElement()) + "/@" + attr.getName();
+
+        case Node.ELEMENT_NODE:
+            Element elem = (Element) node;
+            Node parent = elem.getParentNode();
+            String name = elem.getTagName();
+            NodeList childs = parent.getChildNodes();
+
+            int index = 1;
+            for (int i = 0; i < childs.getLength(); i++) {
+                Node n = childs.item(i);
+                if (n.equals(elem)) {
+                    // first element in xPath is 1, not 0
+                    return xPathFromNode(parent) + "/" + node.getNodeName() + "[" + index + "]";
+                } else if (n instanceof Element && n.getNodeName().equals(name)) {
+                    // there is another element with the same name before in the list
+                    index++;
+                }
+            }
+
+        default:
+            throw new IllegalStateException("Unexpected Node type: " + node.getNodeType());
+        }
+    }
+
+    /**
+     * Return the string contained in the string builder. Remove the ending if equals to the parameter (use for joining
+     * strings in loops)
+     * 
+     * @param stringBuilder
+     * @param endingToRemove
+     * @return
+     */
+    public static String finalize(StringBuilder stringBuilder, String endingToRemove) {
+        if (stringBuilder == null) {
+            throw new IllegalArgumentException("stringBuilder cannot be null");
+        } else if (endingToRemove == null) {
+            throw new IllegalArgumentException("endingToRemove cannot be null");
+        }
+
+        int length = stringBuilder.length();
+        int endingLength = endingToRemove.length();
+        if (length > endingLength && stringBuilder.substring(length - endingLength).equals(endingToRemove)) {
+            return stringBuilder.substring(0, length - endingLength);
+        } else {
+            return stringBuilder.toString();
+        }
+    }
+    
+    public static void reloadDependencies() {
+        List<IEditorReference> editors = new ArrayList<>();
+        for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows()) {
+            for (IWorkbenchPage page : window.getPages()) {
+                editors.addAll(Arrays.asList(page.getEditorReferences()));
+            }
+        }
+
+        for (IEditorReference er : editors) {
+            IEditorPart editor = er.getEditor(false);
+            ITextEditor textEditor = null;
+            if (editor instanceof ITextEditor)
+                textEditor = (ITextEditor) editor;
+            else if (editor != null) {
+                Object o = editor.getAdapter(ITextEditor.class);
+                if (o != null)
+                    textEditor = (ITextEditor) o;
+            }
+            if (textEditor != null) {
+                IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
+                IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForRead(document);
+                if (model != null) {
+                    ModelQuery modelQuery = null;
+                    try {
+                        modelQuery = ModelQueryUtil.getModelQuery(model);
+                    } finally {
+                        model.releaseFromRead();
+                    }
+                    Document domDocument = ((IDOMModel) model).getDocument();
+                    if ((modelQuery != null) && (modelQuery.getCMDocumentManager() != null)) {
+                        modelQuery.getCMDocumentManager().getCMDocumentCache().clear();
+                        CMDocumentLoader loader = new InferredGrammarBuildingCMDocumentLoader(domDocument, modelQuery);
+                        loader.loadCMDocuments();
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/Application.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/Application.java
new file mode 100644
index 0000000000000000000000000000000000000000..b74bc99f94b48dbfbf47bcfbc1aa523a04439c48
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/Application.java
@@ -0,0 +1,68 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view;
+
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * This class controls all aspects of the application's execution
+ */
+public class Application implements IApplication {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
+	 */
+	@Override
+    public Object start(IApplicationContext context) throws Exception {
+		Display display = PlatformUI.createDisplay();
+		
+		// Displaying ChooseWorkspace Dialog and then assigning new workspace to the application
+		//      Add "-data @noDefault" to PROGRAM ARGUMENTS          to make workspace choosing working
+		
+		try {
+			int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());
+			if (returnCode == PlatformUI.RETURN_RESTART)
+				return IApplication.EXIT_RESTART;
+			else
+				return IApplication.EXIT_OK;
+		} finally {
+			display.dispose();
+		}
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.equinox.app.IApplication#stop()
+	 */
+	@Override
+    public void stop() {
+		if (!PlatformUI.isWorkbenchRunning())
+			return;
+		final IWorkbench workbench = PlatformUI.getWorkbench();
+		final Display display = workbench.getDisplay();
+		display.syncExec(new Runnable() {
+			@Override
+            public void run() {
+				if (!display.isDisposed())
+					workbench.close();
+			}
+		});
+	}
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/ApplicationActionBarAdvisor.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/ApplicationActionBarAdvisor.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ff8da6b0065c64f6c68e8989fc6296d5702b5cb
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/ApplicationActionBarAdvisor.java
@@ -0,0 +1,27 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view;
+
+
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.IActionBarConfigurer;
+
+public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
+
+    public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) {
+        super(configurer);
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/ApplicationWorkbenchAdvisor.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/ApplicationWorkbenchAdvisor.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed4ba23ada3e7af71c08daa080374668f9553d1a
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/ApplicationWorkbenchAdvisor.java
@@ -0,0 +1,120 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.ui.IWorkbenchPreferenceConstants;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.application.IWorkbenchConfigurer;
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchAdvisor;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+import org.eclipse.ui.ide.IDE;
+
+import cern.silecs.utils.OSExecute;
+import cern.silecs.utils.SilecsConstants;
+import cern.silecs.utils.XmlUtils;
+import cern.silecs.view.console.ConsoleHandler;
+
+/**
+ * In this class a lot of initialization takes place because this is the point when workbench is already created.
+ */
+public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
+
+    private static final String PERSPECTIVE_ID = "silecs.eclipse.plugin.perspective"; //$NON-NLS-1$
+
+    @Override
+    public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
+        return new ApplicationWorkbenchWindowAdvisor(configurer);
+    }
+
+    @Override
+    public String getInitialWindowPerspectiveId() {
+        return PERSPECTIVE_ID;
+    }
+
+    @Override
+    public void initialize(IWorkbenchConfigurer configurer) {
+        super.initialize(configurer);
+        
+        configurer.setSaveAndRestore(true);
+        PlatformUI.getPreferenceStore().setValue(IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS, false);
+
+        IDE.registerAdapters();
+
+        addGenerateClassEnumListener();
+    }
+
+    @Override
+    public IAdaptable getDefaultPageInput() {
+        return ResourcesPlugin.getWorkspace().getRoot();
+    }
+
+    public void printClassPath() {
+        ClassLoader cl = ClassLoader.getSystemClassLoader();
+
+        URL[] urls = ((URLClassLoader)cl).getURLs();
+
+        for(URL url: urls){
+        	System.out.println(url.getFile());
+        }
+     }
+    
+    /**
+     * This methods adds a listener that should regenerate class enum whenever design project is deleted
+     */
+    private void addGenerateClassEnumListener() {
+
+        ResourcesPlugin.getWorkspace().addResourceChangeListener(new IResourceChangeListener() {
+            @Override
+            public void resourceChanged(IResourceChangeEvent event) {
+                IResourceDelta rootDelta = event.getDelta();
+                try {
+                    rootDelta.accept(delta -> {
+                        IResource resource = delta.getResource();
+
+                        // make sure that the project has been removed and it was a design project
+                            if (resource instanceof IProject
+                                    && (delta.getKind() == IResourceDelta.REMOVED || delta.getKind() == IResourceDelta.ADDED)
+                                    && resource.getName().matches(SilecsConstants.FULL_DESIGN_PATTERN)) {
+                                try {
+                                    XmlUtils.reloadDependencies();
+                                } catch (Exception e) {
+                                    e.printStackTrace();
+                                }
+
+                                return false;
+
+                            }
+                            return true;
+                        });
+                } catch (CoreException e) {
+                    e.printStackTrace();
+                }
+            }
+        }, IResourceChangeEvent.POST_CHANGE);
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/ApplicationWorkbenchWindowAdvisor.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/ApplicationWorkbenchWindowAdvisor.java
new file mode 100644
index 0000000000000000000000000000000000000000..c41468e2f6cb8f102a4d3a4132b4ac2ed232ff3e
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/ApplicationWorkbenchWindowAdvisor.java
@@ -0,0 +1,179 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.IActionBarConfigurer;
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+import org.eclipse.ui.internal.dialogs.WorkbenchWizardElement;
+import org.eclipse.ui.internal.wizards.AbstractExtensionWizardRegistry;
+import org.eclipse.ui.wizards.IWizardCategory;
+import org.eclipse.ui.wizards.IWizardDescriptor;
+
+import cern.silecs.utils.SilecsConstants;
+
+@SuppressWarnings("restriction")
+public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
+
+    public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
+        super(configurer);
+    }
+
+    @Override
+    public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) {
+        return new ApplicationActionBarAdvisor(configurer);
+    }
+
+    @Override
+    public void preWindowOpen() {
+        IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
+        configurer.setInitialSize(new Point(700, 500));
+        configurer.setShowCoolBar(true);
+        configurer.setShowStatusLine(true);
+        configurer.setTitle(SilecsConstants.SILECS_NAME); //$NON-NLS-1$
+        configurer.setShowProgressIndicator(true);
+    }
+
+    @Override
+    public void postWindowOpen() {
+        super.postWindowOpen();
+
+        addChangedEditorListener();
+        
+        // removing unnecessary wizards from new and import menu.
+        AbstractExtensionWizardRegistry wizardRegistry = (AbstractExtensionWizardRegistry) PlatformUI.getWorkbench()
+                .getNewWizardRegistry();
+        IWizardCategory[] categories = PlatformUI.getWorkbench().getNewWizardRegistry().getRootCategory()
+                .getCategories();
+
+        for (IWizardDescriptor wizard : getAllWizards(categories)) {
+            if (wizard.getCategory().getId().matches("org.eclipse.ui.Basic")) {
+                WorkbenchWizardElement wizardElement = (WorkbenchWizardElement) wizard;
+                wizardRegistry.removeExtension(wizardElement.getConfigurationElement().getDeclaringExtension(),
+                        new Object[] { wizardElement });
+            } else if (wizard.getCategory().getId().matches("org.eclipse.wst.xml.examples")) {
+                WorkbenchWizardElement wizardElement = (WorkbenchWizardElement) wizard;
+                wizardRegistry.removeExtension(wizardElement.getConfigurationElement().getDeclaringExtension(),
+                        new Object[] { wizardElement });
+            } else if (wizard.getCategory().getId().matches("org.eclipse.wst.XMLCategory")) {
+                WorkbenchWizardElement wizardElement = (WorkbenchWizardElement) wizard;
+                wizardRegistry.removeExtension(wizardElement.getConfigurationElement().getDeclaringExtension(),
+                        new Object[] { wizardElement });
+            } else if (wizard.getCategory().getId().matches("org.eclipse.cdt.ui.newCWizards")) {
+                WorkbenchWizardElement wizardElement = (WorkbenchWizardElement) wizard;
+                wizardRegistry.removeExtension(wizardElement.getConfigurationElement().getDeclaringExtension(),
+                        new Object[] { wizardElement });
+            }
+
+        }
+
+        wizardRegistry = (AbstractExtensionWizardRegistry) PlatformUI.getWorkbench().getImportWizardRegistry();
+
+        categories = PlatformUI.getWorkbench().getImportWizardRegistry().getRootCategory().getCategories();
+
+        for (IWizardDescriptor wizard : getAllWizards(categories)) {
+            if (wizard.getCategory().getId().matches("org.eclipse.cdt.ui.importWizardCategory")) {
+                WorkbenchWizardElement wizardElement = (WorkbenchWizardElement) wizard;
+                wizardRegistry.removeExtension(wizardElement.getConfigurationElement().getDeclaringExtension(),
+                        new Object[] { wizardElement });
+            } else if (wizard.getCategory().getId().matches("org.eclipse.debug.ui")) {
+                WorkbenchWizardElement wizardElement = (WorkbenchWizardElement) wizard;
+                wizardRegistry.removeExtension(wizardElement.getConfigurationElement().getDeclaringExtension(),
+                        new Object[] { wizardElement });
+            } else if (wizard.getCategory().getId().matches("org.eclipse.wst.XMLCategory")) {
+                WorkbenchWizardElement wizardElement = (WorkbenchWizardElement) wizard;
+                wizardRegistry.removeExtension(wizardElement.getConfigurationElement().getDeclaringExtension(),
+                        new Object[] { wizardElement });
+            } else if (wizard.getCategory().getId().matches("org.eclipse.team.ui.importWizards")) {
+                WorkbenchWizardElement wizardElement = (WorkbenchWizardElement) wizard;
+                wizardRegistry.removeExtension(wizardElement.getConfigurationElement().getDeclaringExtension(),
+                        new Object[] { wizardElement });
+            }
+        }
+    }
+
+    private IWizardDescriptor[] getAllWizards(IWizardCategory[] categories) {
+        List<IWizardDescriptor> results = new ArrayList<IWizardDescriptor>();
+        for (IWizardCategory wizardCategory : categories) {
+            results.addAll(Arrays.asList(wizardCategory.getWizards()));
+            results.addAll(Arrays.asList(getAllWizards(wizardCategory.getCategories())));
+        }
+        return results.toArray(new IWizardDescriptor[0]);
+    }
+
+    private void addChangedEditorListener() {
+        IWorkbench workbench = PlatformUI.getWorkbench();
+        IWorkbenchPage page = workbench.getActiveWorkbenchWindow().getActivePage();
+        page.addPartListener(new IPartListener() {
+
+            @Override
+            public void partOpened(IWorkbenchPart part) {
+                setApplicationTitle(); 
+            }
+
+            @Override
+            public void partDeactivated(IWorkbenchPart part) {
+                setApplicationTitle(); 
+            }
+
+            @Override
+            public void partClosed(IWorkbenchPart part) {
+                setApplicationTitle(); 
+            }
+
+            @Override
+            public void partBroughtToTop(IWorkbenchPart part) {
+                setApplicationTitle(); 
+            }
+
+            @Override
+            public void partActivated(IWorkbenchPart part) {
+                setApplicationTitle(); 
+            }
+            
+            private void setApplicationTitle() {
+                IEditorPart editorPart = page.getActiveEditor();
+                IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
+                
+                if (editorPart != null) {
+                    IFileEditorInput editorInput = (IFileEditorInput) editorPart.getEditorInput();
+                    IFile file = editorInput.getFile();
+
+                    configurer.setTitle(file.getFullPath() + " - " + SilecsConstants.SILECS_NAME + " - "
+                            + ResourcesPlugin.getWorkspace());
+                } else {
+                    configurer.setTitle(SilecsConstants.SILECS_NAME + " - " + ResourcesPlugin.getWorkspace() );
+                }
+            }
+        });
+
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/Perspective.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/Perspective.java
new file mode 100644
index 0000000000000000000000000000000000000000..2404834644e28a901eaf779fd06e1fadf56045e9
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/Perspective.java
@@ -0,0 +1,28 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view;
+
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+public class Perspective implements IPerspectiveFactory {
+
+    @Override
+    public void createInitialLayout(IPageLayout layout) {
+        // TODO Auto-generated method stub
+        
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/console/ConsoleHandler.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/console/ConsoleHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..454b9d51eb499bed8b5bba565f69c9ede511f368
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/console/ConsoleHandler.java
@@ -0,0 +1,109 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.console;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.MessageConsole;
+import org.eclipse.ui.console.MessageConsoleStream;
+
+public class ConsoleHandler {
+
+    private static MessageConsole console;
+    private static MessageConsoleStream messageStream;
+    private static MessageConsoleStream errorStream;
+    private static MessageConsoleStream warningStream;
+    
+    static {
+        console = new MessageConsole("Console", null);
+        ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { console });
+
+        messageStream = console.newMessageStream();
+        errorStream = console.newMessageStream();
+        warningStream = console.newMessageStream();
+
+        final Display display = Display.getDefault();
+        Display.getDefault().asyncExec(new Runnable()
+        {
+          public void run()
+	        { 
+		         errorStream.setColor(display.getSystemColor(SWT.COLOR_RED));
+		         warningStream.setColor(display.getSystemColor(SWT.COLOR_DARK_YELLOW)); 
+	        }
+      });
+    }
+
+    public static void clear() {
+    	console.clearConsole();
+    }
+    
+    /**
+     * Prints message in the silecs console.
+     * 
+     * @param message Message to appear in the console
+     * @param activateOnWrite determines whether to activate the console
+     */
+    public static void printMessage(String message, boolean activateOnWrite) {
+        messageStream.setActivateOnWrite(activateOnWrite);
+        messageStream.println(message);
+    }
+    
+    /**
+     * Prints error message in the silecs console.
+     * 
+     * @param Error message to appear in the console
+     * @param activateOnWrite determines whether to activate the console
+     */
+    public static void printError(String message, boolean activateOnWrite) {
+        errorStream.setActivateOnWrite(activateOnWrite);
+        errorStream.println(message);
+    }
+    
+
+    private static void printTrace(Throwable ex) {
+    	if( ex == null)
+    		return;
+    	StackTraceElement[] stacktrace = ex.getStackTrace();
+
+    	     for(int i=1; i<stacktrace.length; i++){
+    	    			 errorStream.println(stacktrace[i].toString());
+            }
+    }
+    
+    public static void printStackTrace(Exception ex) {
+    	errorStream.println(ex.getLocalizedMessage());
+    	errorStream.println("Stacktrace: ");
+    	printTrace(ex);
+    	errorStream.println("Caused by: ");
+    	printTrace(ex.getCause());
+        errorStream.setActivateOnWrite(true);
+    }
+    
+    
+    /**
+     * Prints error message in the silecs console.
+     * 
+     * @param Warning message to appear in the console
+     * @param activateOnWrite determines whether to activate the console
+     */
+    public static void printWarning(String message, boolean activateOnWrite) {
+        warningStream.setActivateOnWrite(activateOnWrite);
+        warningStream.println(message);
+    }
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/dialogs/SilecsMessageDialog.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/dialogs/SilecsMessageDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..d9ea6851c4660c1ae28051ad0ab6f2bc27672988
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/dialogs/SilecsMessageDialog.java
@@ -0,0 +1,48 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.dialogs;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+
+import cern.silecs.utils.SilecsUtils;
+
+/**
+ * This class adds Silecs logo to jface Message Dialog.
+ * @see MessageDialog 
+ */
+public class SilecsMessageDialog extends MessageDialog{
+
+    private Image image = null;
+
+    /**
+     * @see MessageDialog#MessageDialog(Shell, String, Image, String, int, String[], int)
+     */
+    public SilecsMessageDialog(Shell parentShell, String dialogTitle, Image dialogTitleImage, String dialogMessage,
+            int dialogImageType, String[] dialogButtonLabels, int defaultIndex) {
+        super(parentShell, dialogTitle, dialogTitleImage, dialogMessage, dialogImageType, dialogButtonLabels, defaultIndex);
+        
+        String imagePath = SilecsUtils.findInBundle("icons/silecs-logo.ico");
+        image = new Image(PlatformUI.getWorkbench().getDisplay(), imagePath);     
+    }
+    
+    @Override
+    public Image getImage() {
+        return image;
+    }
+}
\ No newline at end of file
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/DeployMultiPageEditor.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/DeployMultiPageEditor.java
new file mode 100644
index 0000000000000000000000000000000000000000..e1d4967fa4d1aff77d3c8f3a4474b7b4a4c12ffc
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/DeployMultiPageEditor.java
@@ -0,0 +1,25 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.editor;
+
+public class DeployMultiPageEditor extends XMLMultiPageEditor {
+
+	public static String ID = "cern.silecs.view.editors.deploy";
+    public DeployMultiPageEditor() {
+        super();
+    }
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/DesignMultiPageEditor.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/DesignMultiPageEditor.java
new file mode 100644
index 0000000000000000000000000000000000000000..f8f5711c18b3ff0c2c6045265fcf323bcd107f80
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/DesignMultiPageEditor.java
@@ -0,0 +1,25 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.editor;
+
+public class DesignMultiPageEditor extends XMLMultiPageEditor {
+
+	public static String ID = "cern.silecs.view.editors.design";
+    public DesignMultiPageEditor() {
+        super();
+    }
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/XMLMultiPageEditor.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/XMLMultiPageEditor.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ca464a886bf93d38cab85deb6b371cb3e46a9b6
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/XMLMultiPageEditor.java
@@ -0,0 +1,169 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.editor;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.ResourcesPlugin;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.wst.sse.ui.StructuredTextEditor;
+import org.eclipse.wst.sse.ui.internal.contentassist.ContentAssistUtils;
+import org.eclipse.wst.xml.core.internal.document.NodeImpl;
+import org.eclipse.wst.xml.ui.internal.XMLUIPlugin;
+import org.eclipse.wst.xml.ui.internal.tabletree.IDesignViewer;
+import org.eclipse.wst.xml.ui.internal.tabletree.XMLMultiPageEditorPart;
+import org.eclipse.wst.xml.ui.internal.tabletree.XMLTableTreeHelpContextIds;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.editor.internal.SilecsXMLTableTreeViewer;
+import cern.silecs.view.job.ValidationJob;
+
+@SuppressWarnings("restriction")
+public class XMLMultiPageEditor extends XMLMultiPageEditorPart {
+
+    SilecsXMLTableTreeViewer xmlTableTreeViewer;
+
+    public XMLMultiPageEditor() {
+        super();
+    }
+
+    @Override
+    public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+        super.init(site, input);
+
+        // useless to instantiate toolbar since not used
+        noToolbar();
+    }
+
+    @Override
+    public void dispose() {
+        ResourcesPlugin.getWorkspace().removeResourceChangeListener(xmlTableTreeViewer);
+        super.dispose();
+    }
+
+    @Override
+    protected void createPages() {
+        super.createPages();
+
+        // add itself as resource change listener
+        ResourcesPlugin.getWorkspace().addResourceChangeListener(xmlTableTreeViewer, IResourceChangeEvent.POST_CHANGE);
+    }
+
+    @Override
+    protected IDesignViewer createDesignPage() {
+        xmlTableTreeViewer = new SilecsXMLTableTreeViewer(getContainer(), this);
+        xmlTableTreeViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        // Set the default info-pop for XML design viewer.
+        XMLUIPlugin.getInstance().getWorkbench().getHelpSystem()
+                .setHelp(xmlTableTreeViewer.getControl(), XMLTableTreeHelpContextIds.XML_DESIGN_VIEW_HELPID);
+
+        return xmlTableTreeViewer;
+    }
+
+    public IDocument getDocument() {
+        IDocument document = null;
+        StructuredTextEditor textEditor = (StructuredTextEditor) getAdapter(StructuredTextEditor.class);
+        if (textEditor != null) {
+            document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
+        }
+
+        return document;
+    }
+
+    public static XMLMultiPageEditor getOpenedEditor(IFile file) {
+
+        // get all the opened editors
+        List<IEditorReference> editors = new ArrayList<>();
+        for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows()) {
+            for (IWorkbenchPage page : window.getPages()) {
+                editors.addAll(Arrays.asList(page.getEditorReferences()));
+            }
+        }
+
+        for (IEditorReference er : editors) {
+            IEditorPart editor = er.getEditor(false);
+            try {
+                IEditorInput editorInput = er.getEditorInput();
+                if (editor instanceof XMLMultiPageEditor && editorInput instanceof IFileEditorInput) {
+                    IFileEditorInput input = (IFileEditorInput) editorInput;
+
+                    if (input.getFile().equals(file)) {
+                        return (XMLMultiPageEditor) editor;
+                    }
+                }
+            } catch (PartInitException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+
+    public NodeImpl getNodeAtPosition(int line, int column) {
+        try {
+            // line 1 is considered as line 0 by eclipse
+            // same for columns
+            if (line > 0) {
+                IRegion region = getDocument().getLineInformation(line - 1);
+                ITextViewer viewer = ((StructuredTextEditor) getAdapter(StructuredTextEditor.class)).getTextViewer();
+                return (NodeImpl) ContentAssistUtils.getNodeAt(viewer, region.getOffset() + column - 2);
+            }
+        } catch (BadLocationException e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+    
+    @Override
+    public void doSave(IProgressMonitor monitor)
+    {
+        IEditorInput editorInput = getEditorInput();
+        if (editorInput instanceof IFileEditorInput)
+        {
+            IFile fesaFile = ((IFileEditorInput) editorInput).getFile();
+
+            super.doSave(monitor);
+            
+            ConsoleHandler.printMessage("Validating XML  ...", true);
+            ValidationJob job;
+    		job = new ValidationJob(fesaFile);
+            job.schedule();
+        }
+    }
+    
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/internal/SchemaHelper.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/internal/SchemaHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..0754660b4aab4defc7008bc0e6ea851301fe851e
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/internal/SchemaHelper.java
@@ -0,0 +1,58 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.editor.internal;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
+import org.eclipse.wst.xml.core.internal.document.CMNodeUtil;
+import org.eclipse.wst.xsd.contentmodel.internal.XSDImpl.XSDElementDeclarationAdapter;
+import org.eclipse.xsd.XSDElementDeclaration;
+import org.eclipse.xsd.XSDIdentityConstraintDefinition;
+import org.w3c.dom.Element;
+
+@SuppressWarnings("restriction")
+public abstract class SchemaHelper {
+
+    public static List<XSDIdentityConstraintDefinition> findIdentityConstraints(Element element) {
+        CMElementDeclaration elemDecl = CMNodeUtil.getElementDeclaration(element);
+        if (elemDecl instanceof XSDElementDeclarationAdapter) {
+            XSDElementDeclarationAdapter xsdElemAdapt = (XSDElementDeclarationAdapter) elemDecl;
+            XSDElementDeclaration xsdElementDecl = (XSDElementDeclaration) xsdElemAdapt.getKey();
+
+            // get all the key constraints definitions
+            List<XSDIdentityConstraintDefinition> constraints = xsdElementDecl.getResolvedElementDeclaration()
+                    .getIdentityConstraintDefinitions();
+            constraints.addAll(xsdElementDecl.getResolvedElementDeclaration().getIdentityConstraintDefinitions());
+
+            return constraints;
+        } else {
+            return Collections.emptyList();
+        }
+    }
+
+    public static XSDIdentityConstraintDefinition findIdentityConstraint(Element element, String constraintName) {
+        List<XSDIdentityConstraintDefinition> constraints = findIdentityConstraints(element);
+        for (XSDIdentityConstraintDefinition c : constraints) {
+            if (c.getName().equals(constraintName)) {
+                return c;
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/internal/SilecsTableColumnViewerLabelProvider.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/internal/SilecsTableColumnViewerLabelProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..75fd12b9903bfb462cc76dd9996ffe4f5e13962c
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/internal/SilecsTableColumnViewerLabelProvider.java
@@ -0,0 +1,181 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.editor.internal;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.CellLabelProvider;
+import org.eclipse.jface.viewers.LabelProviderChangedEvent;
+import org.eclipse.jface.viewers.ViewerCell;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.wst.xml.ui.internal.tabletree.XMLTableTreeContentProvider;
+import org.w3c.dom.Node;
+
+import cern.silecs.utils.XmlUtils;
+
+
+/**
+ * Label provider for the design view of the FesaEditor
+ */
+@SuppressWarnings("restriction")
+public class SilecsTableColumnViewerLabelProvider extends CellLabelProvider {
+
+    private static final int TOOLTIP_DELAY_MS = 500;
+
+    // since we could not have multiple inheritance in java,
+    // we inject the base label provider in this CellLabelProvider
+    // which adds support for tool-tips in the registered treeViewer
+    private final XMLTableTreeContentProvider baseLabelProvider;
+
+    // These 2 maps behave like a bidirectional map
+    // marker -> node
+    // node -> Set<marker>
+    private final Map<IMarker, Node> markerToNode = new HashMap<>();
+    private final Map<Node, Set<IMarker>> nodeToMarkers = new HashMap<>();
+
+    public SilecsTableColumnViewerLabelProvider(XMLTableTreeContentProvider baseLabelProvider) {
+        this.baseLabelProvider = baseLabelProvider;
+    }
+
+    /**
+     * Register an error/warning with its associated node
+     * Fire a label provider changed event
+     * 
+     * @param marker
+     * @param node
+     */
+    public void addFault(IMarker marker, Node node) {
+        markerToNode.put(marker, node);
+        if (nodeToMarkers.containsKey(node)) {
+            nodeToMarkers.get(node).add(marker);
+        } else {
+            Set<IMarker> markers = new HashSet<>();
+            markers.add(marker);
+            nodeToMarkers.put(node, markers);
+        }
+        
+        fireLabelProviderChanged(new LabelProviderChangedEvent(this, node));
+    }
+
+    /**
+     * Remove the marker and its associated node from the faulty list
+     * Fire a label provider changed event
+     * 
+     * @param marker
+     */
+    public void removeFault(IMarker marker) {
+        Node node = markerToNode.remove(marker);
+        if (node != null) {
+            Set<IMarker> markers = nodeToMarkers.get(node);
+            markers.remove(marker);
+            if (markers.isEmpty()) {
+                nodeToMarkers.remove(node);
+            }
+            fireLabelProviderChanged(new LabelProviderChangedEvent(this, node));
+        }
+    }
+
+    /**
+     * Clears all the registered marker/nodes
+     */
+    public void clearFaults() {
+        markerToNode.clear();
+        nodeToMarkers.clear();
+    }
+
+    /**
+     * Provide a tool-tip for the faulty node with the error message of the associated markers
+     */
+    @Override
+    public String getToolTipText(Object element) {
+        if (nodeToMarkers.containsKey(element)) {
+            Set<IMarker> markers = nodeToMarkers.get(element);
+            StringBuilder sb = new StringBuilder();
+            for (IMarker marker : markers) {
+                try {
+                    sb.append(marker.getAttribute(IMarker.MESSAGE) + "\n");
+                } catch (CoreException e) {
+                    // don't do anything
+                }
+            }
+            
+            return XmlUtils.finalize(sb, "\n"); 
+        }
+
+        return null;
+    }
+
+    @Override
+    public Point getToolTipShift(Object object) {
+        return new Point(5, 5);
+    }
+
+    @Override
+    public int getToolTipDisplayDelayTime(Object object) {
+        return TOOLTIP_DELAY_MS;
+    }
+
+    @Override
+    public int getToolTipTimeDisplayed(Object object) {
+        return -1;
+    }
+
+    /**
+     * Use the base label provider for the content If the element is fault, compute the background color
+     */
+    @Override
+    public void update(ViewerCell cell) {
+        Object element = cell.getElement();
+        int index = cell.getColumnIndex();
+
+        cell.setText(baseLabelProvider.getColumnText(element, index));
+        cell.setImage(baseLabelProvider.getColumnImage(element, index));
+
+        cell.setForeground(baseLabelProvider.getForeground(element, index));
+        if (nodeToMarkers.containsKey(element)) {
+            // background of the faulty cell
+            cell.setBackground(computeCellBackground((Node) element));
+        } else {
+            cell.setBackground(baseLabelProvider.getBackground(element, index));
+        }
+    }
+
+    /**
+     * Helper to compute the background color of a faulty cell
+     * 
+     * @param node
+     * @return
+     */
+    private Color computeCellBackground(Node node) {
+        Set<IMarker> markers = nodeToMarkers.get(node);
+        int color = SWT.COLOR_YELLOW;
+        for (IMarker marker : markers) {
+            if (marker.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR) == IMarker.SEVERITY_ERROR) {
+                color = SWT.COLOR_RED;
+                break;
+            }
+        }
+        return Display.getCurrent().getSystemColor(color);
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/internal/SilecsXMLTableTreeContentProvider.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/internal/SilecsXMLTableTreeContentProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..1fce623e91e8395c392e162adf62e5606a6cfe1b
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/internal/SilecsXMLTableTreeContentProvider.java
@@ -0,0 +1,111 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.editor.internal;
+
+import org.eclipse.osgi.util.TextProcessor;
+import org.eclipse.wst.xml.ui.internal.tabletree.XMLTableTreeContentProvider;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import cern.silecs.utils.SilecsConstants;
+
+@SuppressWarnings("restriction")
+public class SilecsXMLTableTreeContentProvider extends XMLTableTreeContentProvider{
+
+    @Override
+    public String getColumnText(Object object, int column) {
+        String result = super.getColumnText(object, column);
+
+        if ((result.isEmpty() || result.startsWith("(")) && object instanceof Element && column == 1) {
+            result = getElementValueHelper((Element) object);
+        }
+
+        result = TextProcessor.process(result);
+        return result != null ? result : "";
+    }
+
+    private String getElementValueHelper(Element element) {
+
+        StringBuilder sb = new StringBuilder();
+        if (element.hasAttributes()) {
+            NamedNodeMap map = element.getAttributes();
+
+            sb.append("(");
+            // put name first
+            Attr name = (Attr) map.getNamedItem(SilecsConstants.NAME);
+            if (name != null) {
+                sb.append(name.getValue() + ": ");
+            }
+
+            // put other attributes
+            for (int i = 0; i < map.getLength(); i++) {
+                Attr a = (Attr) map.item(i);
+                String attrName = a.getName();
+
+                // name has already been added
+                // do not propagate id
+                if (!(attrName.equals(SilecsConstants.NAME))) {
+                    sb.append(attrName + "=" + a.getValue() + ", ");
+                }
+            }
+
+        }
+
+        if (sb.length() < 2) {
+            // if we didn't find smth interesting
+            // the node behaves like a container
+            return getContainerElementValueHelper(element);
+        } else if (sb.charAt(0) == '(') {
+            // remove the last comma/colon and close the parenthesis
+            sb.setLength(sb.length() - 2);
+            sb.append(")");
+        }
+
+        return sb.toString();
+    }
+
+    private String getContainerElementValueHelper(Element element) {
+        if (element.hasAttribute(SilecsConstants.NAME)) {
+            return element.getAttribute(SilecsConstants.NAME);
+        } else if (element.hasChildNodes()) {
+            NodeList nodeList = element.getChildNodes();
+
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < nodeList.getLength(); i++) {
+                Node n = nodeList.item(i);
+                if (n instanceof Element) {
+                    String val = getContainerElementValueHelper((Element) n);
+                    if (!val.isEmpty()) {
+                        if (sb.length() != 0) {
+                            sb.append(", ");
+                        }
+
+                        sb.append(val);
+                    }
+
+                }
+            }
+
+            return sb.toString();
+        } else {
+            return "";
+        }
+    }
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/internal/SilecsXMLTableTreePropertyDescriptionFactory.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/internal/SilecsXMLTableTreePropertyDescriptionFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..e0a32b4484ccc455c693190e9764b054f5b2248f
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/internal/SilecsXMLTableTreePropertyDescriptionFactory.java
@@ -0,0 +1,194 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.editor.internal;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.ui.views.properties.IPropertyDescriptor;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
+import org.eclipse.wst.xml.ui.internal.properties.EnumeratedStringPropertyDescriptor;
+import org.eclipse.wst.xml.ui.internal.tabletree.XMLTableTreePropertyDescriptorFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import cern.silecs.model.exception.SilecsException;
+import cern.silecs.utils.SilecsConstants;
+import cern.silecs.view.console.ConsoleHandler;
+
+@SuppressWarnings("restriction")
+class SilecsXMLTableTreePropertyDescriptorFactory extends XMLTableTreePropertyDescriptorFactory {
+
+    public static final String DESIGN_NAME_MATCHER = "silecs-design-name";
+    public static final String DESIGN_VERSION_MATCHER = "silecs-design-version";
+
+    
+    @Override
+    protected IPropertyDescriptor createPropertyDescriptorHelper(String name, Element element, CMNode cmNode)
+    {
+        Collection<String> values = null;
+        try
+        {
+            if (isSilecsDesignName(element,name))
+            {
+            	
+                values = getPossibleClassNames();
+            }
+            if (isSilecsDesignVersion(element,name) )
+            {
+            	if( !element.getAttribute(DESIGN_NAME_MATCHER).isEmpty() )
+            	{
+            		values = getPossibleClassVersions(element.getAttribute(DESIGN_NAME_MATCHER));
+            	}
+            }
+        }
+        catch (SilecsException e)
+        {
+        	ConsoleHandler.printStackTrace(e);
+        }
+
+        if (values != null && !values.isEmpty())
+        {
+            return new EnumeratedStringPropertyDescriptor(name, name, values.toArray(new String[values.size()]));
+        }
+        else
+        {
+            return super.createPropertyDescriptorHelper(name, element, cmNode);
+        }
+    }
+    
+    private static boolean isSilecsDesignName(Element element, String attribute)
+    {
+    	if (element.getTagName().matches("SilecsDesign") && attribute.matches(DESIGN_NAME_MATCHER))
+			return true;
+		return false;
+    }
+    
+    private static boolean isSilecsDesignVersion(Element element, String attribute)
+    {
+    	if (element.getTagName().matches("SilecsDesign") && attribute.matches(DESIGN_VERSION_MATCHER))
+			return true;
+		return false;
+    }
+    
+    private static List<String> getPossibleClassNames() throws SilecsException
+    {
+    	Set<File> classes = getClassFiles();
+    	String searchTerm = "." + SilecsConstants.IEDESIGN_FILE;
+    	List<String> classNames = new ArrayList<>();
+    	
+        for (File classFile : classes)
+        {
+        	String className = classFile.getName().replace(searchTerm,"");
+        	classNames.add(className);
+        }
+        return classNames;
+    }
+    
+    private static List<String> getPossibleClassVersions(String className) throws SilecsException
+    {
+    	Set<File> classes = getClassFiles();
+    	List<String> classVersions = new ArrayList<>();
+    	String searchTerm = "." + SilecsConstants.IEDESIGN_FILE;
+    	
+        for (File classFile : classes)
+        {
+        	String classNameFile = classFile.getName().replace(searchTerm,"");
+        	//ConsoleHandler.printMessage("getPossibleClassVersions - classNameFile: " + classNameFile, true);
+        	//ConsoleHandler.printMessage("getPossibleClassVersions - className: " + className, true);
+            if (classNameFile.equals(className) )
+            {
+            	try
+            	{
+	            	DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+	            	DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+	            	Document doc = dBuilder.parse(classFile);
+	            	Node classNode = doc.getElementsByTagName("SILECS-Class").item(0);
+	            	if( classNode != null )
+	            	{
+	            		classVersions.add( classNode.getAttributes().getNamedItem("version").getNodeValue() );
+	            	}
+	            }
+            	catch(Exception e)
+            	{
+            		e.printStackTrace();
+                	ConsoleHandler.printError("No version found in class: " + classNameFile, true);
+            	}
+            }
+        }
+        return classVersions;
+    }
+    
+    private static Set<File> getClassFiles() throws SilecsException
+    {
+        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+        Set<File> projects = listDirectories(workspaceRoot.getLocation().toFile());
+        Set<File> classes = new HashSet<File>();
+
+        String searchTerm = "." + SilecsConstants.IEDESIGN_FILE;
+        for (File p : projects)
+        {
+        	File designFolder = new File(p.getAbsolutePath()+"/src");
+        	if( !designFolder.exists() )
+        		continue;
+        	
+        	File[] listOfFiles = designFolder.listFiles();
+            for (int i = 0; i < listOfFiles.length; i++)
+            {
+                if (listOfFiles[i].getName().endsWith(searchTerm))
+                {
+                	classes.add(listOfFiles[i]);
+                }
+            }
+        }
+        return classes;
+    }
+    
+    private static Set<File> listDirectories(File directory)
+    {
+        File[] directories = directory.listFiles(new FileFilter()
+        {
+            @Override
+            public boolean accept(File pathname)
+            {
+                return pathname.isDirectory();
+            }
+        });
+
+        if (directories != null)
+        {
+            return new TreeSet<File>(Arrays.asList(directories));
+        }
+        else
+        {
+            return Collections.emptySet();
+        }
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/internal/SilecsXMLTableTreeViewer.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/internal/SilecsXMLTableTreeViewer.java
new file mode 100644
index 0000000000000000000000000000000000000000..e70cdcc88f98be7ffb4b0257266cb5d57d57b9bb
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/editor/internal/SilecsXMLTableTreeViewer.java
@@ -0,0 +1,176 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.editor.internal;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.wst.xml.core.internal.document.NodeImpl;
+import org.eclipse.wst.xml.ui.internal.tabletree.XMLTableTreeContentProvider;
+import org.eclipse.wst.xml.ui.internal.tabletree.XMLTableTreeViewer;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import cern.silecs.view.marker.SilecsMarker;
+
+@SuppressWarnings("restriction")
+public class SilecsXMLTableTreeViewer extends XMLTableTreeViewer implements IResourceChangeListener{
+    
+    
+    
+    private final IEditorPart parentEditor;
+    private final SilecsTableColumnViewerLabelProvider labelProvider;
+
+
+    /**
+     * @param parent
+     */
+    public SilecsXMLTableTreeViewer(Composite parent, IEditorPart parentEditor) {
+        super(parent);
+        this.parentEditor = parentEditor;
+        
+        this.propertyDescriptorFactory = new SilecsXMLTableTreePropertyDescriptorFactory();
+        XMLTableTreeContentProvider provider = new SilecsXMLTableTreeContentProvider();
+        setContentProvider(provider);
+        this.labelProvider = new SilecsTableColumnViewerLabelProvider(provider);
+        setLabelProvider(labelProvider);
+        ColumnViewerToolTipSupport.enableFor(this);
+    }
+
+    @Override
+    protected void inputChanged(Object input, Object oldInput) {
+        super.inputChanged(input, oldInput);
+
+        labelProvider.clearFaults();
+        IEditorInput editorInput = parentEditor.getEditorInput();
+        if (editorInput instanceof IFileEditorInput) {
+            try {
+                IFile inputFile = ((IFileEditorInput) editorInput).getFile();
+                IMarker[] markers = inputFile.findMarkers(SilecsMarker.TYPE, false, IResource.DEPTH_ZERO);
+
+                for (IMarker m : markers) {
+                    displayMarker(m);
+                }
+            } catch (CoreException e) {
+//                LOGGER.error(e.getMessage());
+            }
+        }
+        refresh();
+    }
+    
+    
+    @Override
+    public void refresh(Object element, boolean updateLabels) {
+        super.refresh(element, updateLabels);
+
+        // we also want to refresh label of parents elements
+        if (element instanceof Element) {
+            Node parent = ((Element) element).getParentNode();
+            while (parent != null) {
+                super.refresh(parent, updateLabels);
+                parent = parent.getParentNode();
+            }
+        }
+    }
+    
+
+    @Override
+    public void resourceChanged(IResourceChangeEvent event) {
+        IEditorInput editorInput = parentEditor.getEditorInput();
+        if (editorInput instanceof IFileEditorInput) {
+            // only apply changes if input is a file
+            final IFile inputFile = ((IFileEditorInput) editorInput).getFile();
+
+            // sort the markers so that we handle first the deletion and the the creation
+            final IMarkerDelta makerDelta[] = event.findMarkerDeltas(SilecsMarker.TYPE, false);
+            Arrays.sort(makerDelta, new Comparator<IMarkerDelta>() {
+                @Override
+                public int compare(IMarkerDelta md1, IMarkerDelta md2) {
+                    if (md1.getKind() == IResourceDelta.ADDED) {
+                        return md2.getKind() == IResourceDelta.ADDED ? 0 : 1;
+                    } else if (md1.getKind() == IResourceDelta.REMOVED) {
+                        return md2.getKind() == IResourceDelta.REMOVED ? 0 : -1;
+                    } else if (md2.getKind() == IResourceDelta.ADDED) {
+                        return -1;
+                    } else if (md2.getKind() == IResourceDelta.REMOVED) {
+                        return 1;
+                    } else {
+                        return 0;
+                    }
+                }
+            });
+
+            getControl().getDisplay().syncExec(new Runnable() {
+                @Override
+                public void run() {
+                    // this is a hack to avoid automatic scrolling to
+                    // one of the faulty nodes
+                    TreeItem item = getTree().getTopItem();
+                    for (IMarkerDelta md : makerDelta) {
+                        if (md.getResource().equals(inputFile)) {
+                            if (md.getKind() == IResourceDelta.ADDED) {
+                                displayMarker(md.getMarker());
+                            } else if (md.getKind() == IResourceDelta.REMOVED) {
+                                removeMarker(md.getMarker());
+                            }
+                        }
+                    }
+                    
+                    if (item != null) {
+                        getTree().setTopItem(item);
+                    }
+                }
+            });
+        }
+    }
+
+    public void displayMarker(final IMarker marker) {
+        NodeImpl node = null;
+        try {
+            node = (NodeImpl) marker.getAttribute(SilecsMarker.NODE_ATTR);
+            if (node != null) {
+                labelProvider.addFault(marker, node);
+                reveal(node);
+            }
+        } catch (CoreException e) {
+            //LOGGER.error("Could not highlight node: {}", e.getMessage());
+        }
+    }
+
+    public void removeMarker(final IMarker marker) {
+        labelProvider.removeFault(marker);
+    }
+    
+    @Override
+    public String getTitle() {
+        return "Tree View";
+    }
+    
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/explorer/ContentSorter.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/explorer/ContentSorter.java
new file mode 100644
index 0000000000000000000000000000000000000000..091b1a61ee7cecf3bc542cb062899c08df2317f8
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/explorer/ContentSorter.java
@@ -0,0 +1,64 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.explorer;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.ui.views.navigator.ResourceComparator;
+
+import cern.silecs.control.core.DesignProjectNature;
+
+public class ContentSorter extends ViewerSorter {
+
+    private ResourceComparator resourceComparator;
+
+    public ContentSorter() {
+        resourceComparator = new ResourceComparator(ResourceComparator.NAME);
+    }
+
+    @Override
+    public int compare(Viewer viewer, Object e1, Object e2) {
+        if (e1 instanceof IProject && e2 instanceof IProject) {
+
+            IProject f1 = (IProject) e1;
+            IProject f2 = (IProject) e2;
+            
+            if (!f1.isOpen() || !f2.isOpen())
+                return resourceComparator.compare(viewer, e1, e2);
+            
+            boolean f1b = false;
+            boolean f2b = false;
+            try {
+                f1b = f1.hasNature(DesignProjectNature.NATURE_ID);
+                f2b = f2.hasNature(DesignProjectNature.NATURE_ID);
+            } catch (CoreException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+            if (f1b ^ f2b)
+                if (f1b == true) {
+                    return -1;
+                } else {
+                    return 1;
+                }
+        }
+
+        // else let the resource comparator do the ordering
+        return resourceComparator.compare(viewer, e1, e2);
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/explorer/ProjectContent.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/explorer/ProjectContent.java
new file mode 100644
index 0000000000000000000000000000000000000000..77bf8566ff72ec30a6358e15e84c046fa669f5ce
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/explorer/ProjectContent.java
@@ -0,0 +1,137 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.explorer;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Display;
+
+public class ProjectContent implements ITreeContentProvider, IResourceChangeListener {
+
+    private Viewer attachedViewer;
+
+    private static final Object[] NO_OBJECTS = new Object[0];
+
+    public ProjectContent() {
+        ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
+    }
+
+    @Override
+    public void dispose() {
+        ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
+    }
+
+    @Override
+    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+        attachedViewer = viewer;
+    }
+
+    @Override
+    public Object[] getElements(Object inputElement) {
+        if (inputElement instanceof IWorkspaceRoot) {
+            // if root return the projects
+            return ((IWorkspaceRoot) inputElement).getProjects();
+        } else if (inputElement instanceof IProject || inputElement instanceof IFolder) {
+            // if folder or project, return the content
+            return getChildren(inputElement);
+        } else {
+            return NO_OBJECTS;
+        }
+    }
+
+    @Override
+    public Object[] getChildren(Object parentElement) {
+        if (parentElement instanceof IProject) {
+            IProject p = (IProject) parentElement;
+            try {
+                return p.members();
+            } catch (CoreException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+
+        } else if (parentElement instanceof IFolder) {
+            try {
+                return ((IFolder) parentElement).members();
+            } catch (CoreException e) {
+                // The resource is not found
+                return NO_OBJECTS;
+            }
+        }
+        return NO_OBJECTS;
+    }
+
+    @Override
+    public Object getParent(Object element) {
+        if (element instanceof IProject) {
+            return ((IProject) element).getWorkspace().getRoot();
+        } else if (element instanceof IFolder) {
+            IFolder folder = (IFolder) element;
+            if (folder.getParent() instanceof IProject) {
+                // parent of folder is the project
+                return folder.getProject();
+            } else {
+                return folder.getParent();
+            }
+        } else if (element instanceof IFile) {
+            IFile file = (IFile) element;
+            return file.getParent();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean hasChildren(Object element) {
+        IResource[] members = null;
+
+        try {
+            if (element instanceof IFolder) {
+                members = ((IFolder) element).members();
+            }
+        } catch (CoreException e) {
+            // error while accessing members
+        }
+
+        // has children if element is project or not empty folder
+        return element instanceof IProject || (members != null && members.length > 0);
+    }
+
+    @Override
+    public void resourceChanged(IResourceChangeEvent event) {
+        if (attachedViewer != null && !attachedViewer.getControl().isDisposed()) {
+
+            // make the UI thread update the viewer
+            Display.getDefault().asyncExec(new Runnable() {
+
+                @Override
+                public void run() {
+                    attachedViewer.refresh();
+                }
+            });
+        }
+    }
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/explorer/SilecsProjectExplorer.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/explorer/SilecsProjectExplorer.java
new file mode 100644
index 0000000000000000000000000000000000000000..b5811da90219f9418681c270e57923faae1d115e
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/explorer/SilecsProjectExplorer.java
@@ -0,0 +1,198 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.explorer;
+
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.navigator.CommonNavigator;
+import org.eclipse.ui.navigator.CommonViewer;
+import org.eclipse.ui.navigator.ICommonActionConstants;
+
+import cern.silecs.control.core.DeployProjectNature;
+import cern.silecs.control.core.DesignProjectNature;
+import cern.silecs.utils.SilecsUtils;
+
+/**
+ * This class is a subclass of CommonNavigator that provide changes concerning expanding tree.
+ * 
+ * @see CommonNavigator
+ */
+public class SilecsProjectExplorer extends CommonNavigator {
+
+    public static final String VIEW_ID = "cern.silecs.view.explorer";
+
+    @Override
+    public void createPartControl(Composite aParent) {
+        super.createPartControl(aParent);
+        CommonViewer viewer = getCommonViewer();
+
+        IActionBars bars = getViewSite().getActionBars();
+        IStatusLineManager lineManager = bars.getStatusLineManager();
+
+        ILabelProvider labelProvider = (ILabelProvider) viewer.getLabelProvider();
+
+        viewer.addPostSelectionChangedListener(new ISelectionChangedListener() {
+
+            @Override
+            public void selectionChanged(SelectionChangedEvent event) {
+
+                ISelection aSelection = event.getSelection();
+                if (aSelection != null && !aSelection.isEmpty() && aSelection instanceof IStructuredSelection) {
+                    IStructuredSelection selection = (IStructuredSelection) aSelection;
+                    IResource file = null;
+
+                    if (selection.size() == 1 && selection.getFirstElement() instanceof IProject) {                               
+                        IProject project = (IProject) selection.getFirstElement();
+                        try {
+                            if (project.hasNature(DesignProjectNature.NATURE_ID)) {
+                                file = SilecsUtils.getSilecsDesignFile(project);
+                            } else if (project.hasNature(DeployProjectNature.NATURE_ID)) {
+                                file = SilecsUtils.getSilecsDeployFile(project);
+                            }
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+
+                    } else if(selection.size() == 1 && selection.getFirstElement() instanceof IFile) {
+                        file = (IFile) selection.getFirstElement();
+                    }
+                    
+                    if(file != null) {
+                        Image img = null;
+                        img = labelProvider.getImage(((IStructuredSelection) aSelection).getFirstElement());
+                        long modificationTime = file.getLocalTimeStamp() / 1000;
+                        
+                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-YYYY   HH:mm:ss");
+                        LocalDateTime dateAndTime = LocalDateTime.ofEpochSecond(modificationTime, 0, ZoneOffset.ofHours(2));
+                        
+                        lineManager.setMessage(img,"Last modfication: " + formatter.format(dateAndTime) + " : " + file.getFullPath());
+                    }
+                }
+
+            }
+        });
+
+    }
+
+    /**
+     * This method is responsible for expanding the project tree from the root to the silecs file(*.silecsdesign or
+     * *.silecsdeploy)
+     */
+    @Override
+    protected void handleDoubleClick(DoubleClickEvent anEvent) {
+
+        IStructuredSelection selection = (IStructuredSelection) anEvent.getSelection();
+        Object element = selection.getFirstElement();
+        if (element instanceof IProject && !((IProject) element).isOpen()) {
+            try {
+                ((IProject) element).open(new NullProgressMonitor());
+            } catch (CoreException e) {
+                e.printStackTrace();
+            }
+            return;
+
+        } else if (element instanceof IProject && ((IProject) element).isOpen()) {
+            List<IProject> projectList = new ArrayList<IProject>();
+            projectList.add((IProject) element);
+
+            IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+
+            expandHelper(root, projectList);
+            return;
+        }
+        super.handleDoubleClick(anEvent);
+    }
+
+    /**
+     * This method expands elements in the tree. Since the tool does not have knowledge about project structure it must
+     * be done recursively.
+     * 
+     * @param root {@link WorkspaceRoot}
+     * @param projects List of projects that need to be expanded
+     */
+    public void expandHelper(IWorkspaceRoot root, List<IProject> projects) {
+        for (IProject project : projects) {
+            if (project.isOpen()) {
+                try {
+                    IFile file = null;
+                    if (project.hasNature(DeployProjectNature.NATURE_ID)) {
+                        file = SilecsUtils.getSilecsDeployFile(project);
+                    } else if (project.hasNature(DesignProjectNature.NATURE_ID)) {
+                        file = SilecsUtils.getSilecsDesignFile(project);
+                    }
+                    if (file == null)
+                        continue;
+
+                    IContainer parent = file.getParent();
+                    List<Object> toExpand = new ArrayList<>();
+
+                    do {
+                        toExpand.add(0, parent);
+                    } while ((parent = parent.getParent()) != root);
+                    boolean expand = !getCommonViewer().getExpandedState(project);
+                    toExpand.forEach(o -> expand(o, expand));
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /**
+     * Expands single element in the viewer
+     * 
+     * @param element
+     * @return true if expanded
+     */
+    private boolean expand(Object element, boolean expand) {
+        IAction openHandler = getViewSite().getActionBars().getGlobalActionHandler(ICommonActionConstants.OPEN);
+
+        if (openHandler == null) {
+
+            TreeViewer viewer = getCommonViewer();
+            if (viewer.isExpandable(element)) {
+                viewer.setExpandedState(element, expand);
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/job/BaseFileJob.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/job/BaseFileJob.java
new file mode 100644
index 0000000000000000000000000000000000000000..563bb7bb18ec813cc30f2ef0c1a2c5f27f952062
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/job/BaseFileJob.java
@@ -0,0 +1,79 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.job;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+
+import cern.silecs.activator.Activator;
+
+public abstract class BaseFileJob extends WorkspaceJob {
+    
+    protected final IFile file;
+    protected final Map<IResource, Exception> failures;
+    
+    
+    /**
+     * @param name
+     */
+    public BaseFileJob(String name, IFile file) {
+        super(name);
+        this.file = file;
+        this.failures = new HashMap<IResource, Exception>();
+        
+        // set the job rule
+        setRule(createJobRule());
+    }
+
+    public Map<IResource, Exception> getFailures(){
+        return failures;
+    }
+    
+    protected IStatus computeReturnStatus() {
+        if (failures.isEmpty()) {
+            return Status.OK_STATUS;
+        } else {
+            // return INFO status so that eclipse does not open the default error pop up
+            // we handle manually the error reporting
+            return new Status(IStatus.INFO, Activator.PLUGIN_ID, "");
+        }
+    }
+
+    
+    /**
+     * Create the job rule to avoid concurrency on the used resources
+     * 
+     * @return rule used for the job
+     */
+    protected ISchedulingRule createJobRule() {
+        return null;
+    }
+
+    protected final ISchedulingRule workspaceRule() {
+        return ResourcesPlugin.getWorkspace().getRoot();
+    }
+    
+    
+    
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/job/BaseProjectJob.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/job/BaseProjectJob.java
new file mode 100644
index 0000000000000000000000000000000000000000..ba409025f0c037380eb1d09ae0b12601171501a4
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/job/BaseProjectJob.java
@@ -0,0 +1,76 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.job;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+
+import cern.silecs.activator.Activator;
+
+public abstract class BaseProjectJob extends WorkspaceJob {
+
+    protected final IProject project;
+    protected final Map<IResource, Exception> failures;
+
+    /**
+     * @param name
+     */
+    public BaseProjectJob(String name, IProject project) {
+        super(name);
+        this.failures = new HashMap<IResource, Exception>();
+        this.project = project;
+
+        // set the job rule
+        setRule(createJobRule());
+    }
+
+    public Map<IResource, Exception> getFailures() {
+        return failures;
+    }
+
+    protected IStatus computeReturnStatus() {
+        if (failures.isEmpty()) {
+            return Status.OK_STATUS;
+        } else {
+            // return INFO status so that eclipse does not open the default error pop up
+            // we handle manually the error reporting
+            return new Status(IStatus.INFO, Activator.PLUGIN_ID, "");
+        }
+    }
+
+    /**
+     * Create the job rule to avoid concurrency on the used resources
+     * 
+     * @return rule used for the job
+     */
+    protected ISchedulingRule createJobRule() {
+        return null;
+    }
+
+    protected final ISchedulingRule workspaceRule() {
+        return ResourcesPlugin.getWorkspace().getRoot();
+    }
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/job/GenerateClassJob.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/job/GenerateClassJob.java
new file mode 100644
index 0000000000000000000000000000000000000000..263b22d9c155c7df409a9c9ed9a0cb87f3f6f913
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/job/GenerateClassJob.java
@@ -0,0 +1,99 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.job;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.SubProgressMonitor;
+
+import cern.silecs.control.core.DesignProjectNature;
+import cern.silecs.control.validation.Validator;
+import cern.silecs.utils.OSExecute;
+import cern.silecs.utils.SilecsUtils;
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.preferences.MainPreferencePage;
+
+public class GenerateClassJob extends BaseProjectJob {
+	
+    private static final String JOB_NAME = "Generate SILECS Class Job";
+
+    IFile fesaDesignXML;
+    
+    public GenerateClassJob(IProject project, IFile fesaDesignDoc) {
+        super(JOB_NAME, project);
+        fesaDesignXML = fesaDesignDoc;
+    }
+
+    @Override
+    public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
+        
+        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+        String workspacePath = workspaceRoot.getLocation().toFile().getPath();
+
+        monitor.beginTask("Generate Fesa Classes", 1);
+        
+        generateFesaClass(workspacePath, new SubProgressMonitor(monitor, 1));
+        DesignProjectNature.addFESAClassNature(project,monitor);
+        DesignProjectNature.addBuildSpecs(project);
+        monitor.done();
+        
+        return computeReturnStatus();
+    }
+
+    boolean generateFesaClass(String workspacePath, IProgressMonitor monitor)
+    {
+    	String projectName = project.getName();
+    	String projectPath = workspacePath + "/" + projectName;
+        try {
+        	String silecsDesignFilePath = SilecsUtils.getSilecsDesignFilePath(workspacePath, projectName);
+	        String silecsVersion = SilecsUtils.getSilecsVersion(project);
+	        String silecsLibraryBasePath = MainPreferencePage.getSilecsLibraryBasePath(silecsVersion);
+	
+	        ConsoleHandler.printMessage("Generating FESA class: " + projectName, false);
+	        
+	        if (!Validator.isDocumentValid(SilecsUtils.getSilecsDesignFile(project)))
+	        {
+	        	ConsoleHandler.printError( "Failed to generated FESA class: '" +  projectName + "'. Please fix all design errors first!", true);
+	            return false;
+	        }
+	        
+            monitor.beginTask("Generating " + projectName, 2);
+            OSExecute.executePython("generateFesaDesign","fillDesignFile",silecsVersion,new String[]{MainPreferencePage.getFESAVersion(),projectName,workspacePath,MainPreferencePage.getFESADesignSchemaPath()});
+            OSExecute.executePython("generateSourceCode","genCppFiles",silecsVersion,new String[]{projectName, workspacePath,silecsDesignFilePath}); // attention - Cpp Codegen has to happen AFTER design file codegen
+            OSExecute.executePython("generateBuildEnvironment","genMakefileClass",silecsVersion,new String[]{projectPath,silecsLibraryBasePath});
+            OSExecute.executePython("generateBuildEnvironment","genCProjectFile",silecsVersion,new String[]{projectPath.toString()});
+            project.refreshLocal(IResource.DEPTH_INFINITE, null);
+            SilecsUtils.openInEditor(fesaDesignXML);
+            monitor.worked(1);
+        } catch (Exception e) {
+            e.printStackTrace();
+            ConsoleHandler.printError("Failed to generate FESA class: " + projectName, true);
+            ConsoleHandler.printStackTrace(e);
+            return false;
+        }
+        
+        monitor.done();
+        ConsoleHandler.printMessage( "Successfully generated FESA class: " + projectName, true);
+        return true;
+
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/job/GenerateDeployJob.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/job/GenerateDeployJob.java
new file mode 100644
index 0000000000000000000000000000000000000000..2fb5f6c4bda37a7d067d044d153505fba24ebb96
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/job/GenerateDeployJob.java
@@ -0,0 +1,107 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.job;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.SubProgressMonitor;
+
+import cern.silecs.control.core.DeployProjectNature;
+import cern.silecs.control.validation.Validator;
+import cern.silecs.utils.OSExecute;
+import cern.silecs.utils.SilecsUtils;
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.preferences.MainPreferencePage;
+
+public class GenerateDeployJob extends BaseProjectJob {
+
+    private static final String JOB_NAME = "Generate SILECS Deploy Job";
+
+    IFile fesaDeployDoc_;
+    boolean createdNewDeployDoc_;
+    
+    public GenerateDeployJob(IProject project, IFile fesaDeployDoc, boolean createdNewDeployDoc) {
+        super(JOB_NAME, project);
+        fesaDeployDoc_ = fesaDeployDoc;
+        createdNewDeployDoc_ = createdNewDeployDoc;
+    }
+
+    @Override
+    public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
+
+        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+        String workspacePath = workspaceRoot.getLocation().toFile().getPath();
+
+        monitor.beginTask("Generating Code", 1);
+        generateDeploy(workspacePath, new SubProgressMonitor(monitor, 1));
+        monitor.done();
+
+        return computeReturnStatus();
+    }
+
+    private void generateDeploy(String workspacePath, IProgressMonitor monitor )
+    {
+        String projectName = project.getName();
+        
+        try {
+        	String deployPath = SilecsUtils.getSilecsDeployFilePath(workspacePath,projectName);
+	        String deployVersion = SilecsUtils.getDeployVersion(deployPath);
+	        String silecsVersion = SilecsUtils.getSilecsVersion(project);
+	        
+	        monitor.beginTask("Generating: " + projectName, 2);
+	        
+	        ConsoleHandler.printMessage("Generating Code for: " + projectName, false);
+	        if (!Validator.isDocumentValid(SilecsUtils.getSilecsDeployFile(project)))
+	        {
+	        	ConsoleHandler.printError( "Failed to generated code for: '" +  projectName + "'. Please fix all xml errors first!", true);
+	        	return;
+	        }
+
+	        OSExecute.executePython("genparam","genParam",silecsVersion,new String[]{workspacePath, projectName, deployVersion,silecsVersion});
+	        OSExecute.executePython("genplcsrc","genPlcSrc",silecsVersion,new String[]{workspacePath, projectName,silecsVersion});
+	        OSExecute.executePython("genduwrapper","genDuWrapper",silecsVersion,new String[]{workspacePath, projectName, deployVersion});
+	        OSExecute.executePython("generateBuildEnvironment","genCProjectFile",silecsVersion,new String[]{project.getLocation().toString()});
+
+            String silecsLibraryBasePath = MainPreferencePage.getSilecsLibraryBasePath(SilecsUtils.getSilecsVersion(project));
+            String snap7LibraryBasePath = MainPreferencePage.getSNAP7LibraryBasePath(SilecsUtils.getSilecsVersion(project));
+            OSExecute.executePython("generateBuildEnvironment","genMakefileDU",silecsVersion,new String[]{ workspacePath + "/" + projectName, silecsLibraryBasePath,snap7LibraryBasePath});
+            OSExecute.executePython("fillFESADeployUnit","fillDeployUnit",silecsVersion,new String[]{ workspacePath, projectName, MainPreferencePage.getFESADeployUnitSchemaPath(), MainPreferencePage.getFESAVersion() });
+            
+            DeployProjectNature.addFESADeployUnitNature(project,monitor);
+            DeployProjectNature.addBuildSpecs(project);
+            
+            project.refreshLocal(IResource.DEPTH_INFINITE, null);
+            
+            ConsoleHandler.printMessage("Succeeded in generated code for " + projectName, true);
+            
+            if(createdNewDeployDoc_)
+            	SilecsUtils.openInEditor(fesaDeployDoc_);
+            
+            monitor.worked(1);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            ConsoleHandler.printError("Failed to generate code for " + projectName, true);
+            ConsoleHandler.printStackTrace(e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/job/UpdateVersionJob.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/job/UpdateVersionJob.java
new file mode 100644
index 0000000000000000000000000000000000000000..d12e3f61b0b76743765cdf934e05dc62e3fb9f39
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/job/UpdateVersionJob.java
@@ -0,0 +1,115 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.job;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+
+import cern.silecs.control.core.DeployProjectNature;
+import cern.silecs.control.core.DesignProjectNature;
+import cern.silecs.model.exception.SilecsException;
+import cern.silecs.utils.OSExecute;
+import cern.silecs.utils.SilecsUtils;
+import cern.silecs.utils.SilecsConstants;
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.preferences.MainPreferencePage;
+
+public class UpdateVersionJob extends BaseProjectJob {
+	
+    private static final String JOB_NAME = "Update SILECS Version Job";
+
+    String newVersion_;
+    String oldVersion_;
+    
+    public UpdateVersionJob(IProject project, String newVersion ) {
+        super(JOB_NAME, project);
+        newVersion_ = newVersion;
+    }
+
+    @Override
+    public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException
+    {
+        monitor.beginTask("Updating Silecs Version", 1);
+        updateVersion(monitor);
+        monitor.done();
+        return computeReturnStatus();
+    }
+
+    boolean updateVersion(IProgressMonitor monitor)
+    {
+        try {
+            oldVersion_ = SilecsUtils.getSilecsVersion(project);
+
+            int result = oldVersion_.compareTo(newVersion_);
+            if( result >= 0)
+            {
+            	throw new SilecsException("Migration from "+ oldVersion_ +" to "+ newVersion_ +" not possible. The target-version always needto newer than the current version");
+            }
+            
+            String codeGenBasePath = MainPreferencePage.getCodeGenBasePath(newVersion_);
+            String silecsDocumentPath = SilecsUtils.getSilecsDocument(project).getRawLocation().makeAbsolute().toOSString();
+            String oldVersionUnderscored  = oldVersion_.replace(".", "_");
+            String newVersionUnderscored  = newVersion_.replace(".", "_");
+            String migrationScript = codeGenBasePath + "/migration/" + oldVersionUnderscored + "to" + newVersionUnderscored + ".py";
+
+            if(! new File(migrationScript).exists())
+            { 
+            	ConsoleHandler.printWarning("There is no Migration Script for an update from: '" + oldVersion_ + "' to '" + newVersion_ + "'. Using generic migration-script. Only basic xml-version strings will be changed.", true);
+            	migrationScript = codeGenBasePath + "/migration/migrationBase.py";
+                if(! new File(migrationScript).exists())
+                { 
+                	throw new SilecsException("The Migration Script: '" + migrationScript + "' does not exist. Please check your Eclipse-Silecs preferences!");
+                }
+            }
+
+            String newXMLSchema = MainPreferencePage.getModelBasePath(newVersion_) + "/";
+    		if ( project.hasNature(DesignProjectNature.NATURE_ID) )
+    		{
+    			newXMLSchema += SilecsConstants.DESIGN_SCHEMA_XSD;
+    		}
+    		else if( project.hasNature(DeployProjectNature.NATURE_ID) )
+    		{
+    			newXMLSchema += SilecsConstants.DEPLOY_SCHEMA_XSD;
+    		}
+    		else
+            	 throw new Exception("The project: " + project.getName() + " is not a silecs-project");
+
+            OSExecute.executeCommand("python", migrationScript, silecsDocumentPath, newXMLSchema, oldVersion_, newVersion_);
+	        ConsoleHandler.printMessage("Updating Silecs Version from '" + oldVersion_ + "'to '" + newVersion_ + "'", false);
+	        
+            monitor.beginTask("Updating Silecs Version " + project.getName(), 2);
+
+            project.refreshLocal(IResource.DEPTH_INFINITE, null);
+            
+            monitor.worked(1);
+        } catch (Exception e) {
+            e.printStackTrace();
+            ConsoleHandler.printError("Failed to update SILECS version of: " + project.getName(), true);
+            ConsoleHandler.printStackTrace(e);
+            return false;
+        }
+        
+        monitor.done();
+        ConsoleHandler.printMessage( "Successfully updated SILECS version of: " + project.getName(), true);
+        return true;
+
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/job/ValidationJob.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/job/ValidationJob.java
new file mode 100644
index 0000000000000000000000000000000000000000..35af12fa1dbcc98a0a6f6829afaeb9a6ee6ef7a8
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/job/ValidationJob.java
@@ -0,0 +1,223 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.job;
+
+import java.io.File;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.xml.core.internal.document.AttrImpl;
+import org.eclipse.wst.xml.core.internal.document.ElementImpl;
+import org.eclipse.wst.xml.core.internal.document.NodeImpl;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.xsd.XSDIdentityConstraintDefinition;
+import org.eclipse.xsd.XSDXPathDefinition;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import cern.silecs.control.validation.Validator;
+import cern.silecs.model.document.SilecsDocumentError;
+import cern.silecs.model.document.XmlBasedDocument;
+import cern.silecs.model.exception.SilecsException;
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.editor.XMLMultiPageEditor;
+import cern.silecs.view.editor.internal.SchemaHelper;
+import cern.silecs.view.marker.SilecsMarker;
+
+@SuppressWarnings("restriction")
+public class ValidationJob extends BaseFileJob
+{
+    private static final String JOB_NAME = "silecs validation job";
+
+    public ValidationJob(IFile file) {
+        this(JOB_NAME, file);
+
+    }
+
+    public ValidationJob(String name, IFile file) {
+        super(name, file);
+    }
+
+    @Override
+    public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
+        boolean hasErros = false;
+        try
+        {
+            // monitor.beginTask(Messages.get(Message.VALIDATION_PROCESS) + " ...", silecsFiles.size() * 2);
+            monitor.beginTask("Validation Job", 1);
+            try
+            {
+            	hasErros = !isValid(file, new SubProgressMonitor(monitor, 1));
+                file.refreshLocal(IResource.DEPTH_ZERO, null);
+            }
+            catch (Exception e)
+            {
+                failures.put(file, e);
+            }
+
+            return computeReturnStatus();
+        }
+        finally
+        {
+            // Open problem view if there are some errors
+            if (hasErros) {
+                Display.getDefault().syncExec(new Runnable() {
+
+                    @Override
+                    public void run() {
+                        IWorkbenchPage activepage = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
+                                .getActivePage();
+                        IViewPart pbv = activepage.findView("org.eclipse.ui.views.ProblemView");
+                        if (pbv != null) {
+                            activepage.bringToTop(pbv);
+                        }
+                    }
+                });
+            }
+
+            monitor.done();
+        }
+    }
+
+    protected boolean isValid(IFile silecsFile, IProgressMonitor monitor) {
+        IProgressMonitor mon = monitor;
+        if (mon == null) {
+            mon = new NullProgressMonitor();
+        }
+
+        try {
+            mon.beginTask("Validation", 1);
+
+            List<SilecsDocumentError> errors = null;
+
+            File file = new File(silecsFile.getLocationURI());
+
+            errors = Validator.validate(file);
+            
+            final XMLMultiPageEditor editor = XMLMultiPageEditor.getOpenedEditor(silecsFile);
+
+            updateMarkers(silecsFile, errors, editor);
+
+            // return true if document is valid
+            if (errors.isEmpty()) {
+                ConsoleHandler.printMessage("Document " + silecsFile.getName() + " is valid", true);
+                return true;
+            }
+            ConsoleHandler.printError("Document " + silecsFile.getName() + " is not valid", true);
+            return false;
+        } finally {
+            mon.done();
+        }
+    }
+
+    private void updateMarkers(IFile silecsFile, List<SilecsDocumentError> errors, XMLMultiPageEditor editor) {
+        // remove old markers
+        try
+        {
+            silecsFile.deleteMarkers(SilecsMarker.TYPE, false, IResource.DEPTH_ZERO);
+        }
+        catch (CoreException e)
+        {
+        	ConsoleHandler.printStackTrace(e);
+        }
+
+        for (SilecsDocumentError error : errors)
+        {
+            try
+            {
+                createMarker(silecsFile, error, editor);
+            }
+            catch (Exception e)
+            {
+            	ConsoleHandler.printMessage("Could not create marker for " + error, true);
+            }
+        }
+
+    }
+
+    private IMarker createMarker(IFile file, SilecsDocumentError error, XMLMultiPageEditor editor) throws CoreException, SilecsException {
+        IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForRead(file);
+        if (model instanceof IDOMModel)
+        {
+            try {
+                NodeImpl hintNode = null;
+                XmlBasedDocument xmlDocument = new XmlBasedDocument(((IDOMModel) model).getDocument());
+
+                if (error.xPath != null)
+                {
+                    hintNode = (NodeImpl) xmlDocument.getSingleNode(error.xPath);
+                }
+
+                // first try to get accurate not thanks to the schema
+                if (error.isIdentityConstraintError() && hintNode instanceof Element) {
+                    XSDIdentityConstraintDefinition def = SchemaHelper.findIdentityConstraint((Element) hintNode,
+                            error.violatedKey);
+
+                    // def = null can happen when eclipse has not finished to build the schema
+                    if (def != null) {
+                        List<Node> candidates = xmlDocument.getNodes(hintNode, def.getSelector().getValue());
+                        for (Node candidate : candidates) {
+                            for (XSDXPathDefinition field : def.getFields()) {
+                                List<Node> values = xmlDocument.getNodes(candidate, field.getValue());
+                                for (Node v : values) {
+                                    if ((v instanceof AttrImpl && ((AttrImpl) v).getValue()
+                                            .equals(error.incorrectValue))
+                                            || (v instanceof Element)
+                                            && ((ElementImpl) v).getTextContent().equals(error.incorrectValue)) {
+                                        return SilecsMarker.create(file, error, (NodeImpl) v);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                // try to get the node thanks to the document position
+                if (editor != null) {
+                    NodeImpl node = editor.getNodeAtPosition(error.lineNumber, error.columnNumber);
+                    if (node != null) {
+                        hintNode = node;
+                    }
+                }
+
+                // if fail, use the hint node found with the xpath provided by the validator
+                if (hintNode != null) {
+                    return SilecsMarker.create(file, error, hintNode);
+                }
+            }
+            catch (SilecsException e)
+            {
+            	ConsoleHandler.printMessage("Could not get precise location for marker: " + e.getMessage(), true);
+                throw e;
+            }
+        }
+        return SilecsMarker.create(file, error);
+    }
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/marker/SilecsMarker.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/marker/SilecsMarker.java
new file mode 100644
index 0000000000000000000000000000000000000000..ea12b390d142db5516ba5ba05f85ffcc8084180b
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/marker/SilecsMarker.java
@@ -0,0 +1,64 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.marker;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.wst.xml.core.internal.document.NodeImpl;
+
+import cern.silecs.model.document.SilecsDocumentError;
+
+@SuppressWarnings("restriction")
+public abstract class SilecsMarker {
+
+//    private static final Logger LOGGER = LoggerFactory.getLogger(SilecsMarker.class);
+
+    public static final String TYPE = "cern.silecs.view.marker";
+
+    public static final String NODE_ATTR = "node";
+
+    public static IMarker create(IFile file, SilecsDocumentError error, NodeImpl node) throws CoreException {
+        IMarker marker = create(file, error);
+        if (node != null) {
+            marker.setAttribute(IMarker.CHAR_START, node.getStartOffset());
+            marker.setAttribute(IMarker.CHAR_END, node.getEndOffset());
+            marker.setAttribute(NODE_ATTR, node);
+        }
+
+        return marker;
+    }
+
+    public static IMarker create(IFile file, SilecsDocumentError error) throws CoreException {
+        IMarker marker = file.createMarker(SilecsMarker.TYPE);
+
+        marker.setAttribute(IMarker.MESSAGE, error.message);
+        marker.setAttribute(IMarker.LINE_NUMBER, error.lineNumber);
+        switch (error.level) {
+        case INFO:
+            marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO);
+            break;
+        case WARNING:
+            marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING);
+            break;
+        default:
+            marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
+            break;
+        }
+
+        return marker;
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/marker/SilecsMarkerUpdater.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/marker/SilecsMarkerUpdater.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed8193fa31bb408db06e082ad16d73f22121a690
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/marker/SilecsMarkerUpdater.java
@@ -0,0 +1,48 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.marker;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.ui.texteditor.IMarkerUpdater;
+
+public class SilecsMarkerUpdater implements IMarkerUpdater {
+
+    @Override
+    public String getMarkerType() {
+        return SilecsMarker.TYPE;
+    }
+
+    @Override
+    public String[] getAttribute() {
+        return null;
+    }
+
+    @Override
+    public boolean updateMarker(IMarker marker, IDocument document, Position position) {
+        try {
+            int start = position.getOffset();
+            int end = position.getOffset() + position.getLength();
+            marker.setAttribute(IMarker.CHAR_START, start);
+            marker.setAttribute(IMarker.CHAR_END, end);
+            return true;
+        } catch (CoreException e) {
+            return false;
+        }
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/preferences/EditorPreferencePage.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/preferences/EditorPreferencePage.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ed40f1a98f0c2e29c1c01e7a895fd7dea9326cc
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/preferences/EditorPreferencePage.java
@@ -0,0 +1,232 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.preferences;
+
+import org.eclipse.jface.preference.ColorSelector;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+import cern.silecs.activator.Activator;
+
+public class EditorPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+
+//    // validate on save
+//    public static final String VALIDATE_ON_SAVE = "VALIDATE_ON_SAVE";
+//    
+//    // colors
+//    public static final String EDITABLE_COLOR_R = "XML_EDITOR_COLOR_EDITABLE_R";
+//    public static final String EDITABLE_COLOR_G = "XML_EDITOR_COLOR_EDITABLE_G";
+//    public static final String EDITABLE_COLOR_B = "XML_EDITOR_COLOR_EDITABLE_B";
+//
+//    public static final String CONTENT_COLOR_R = "XML_EDITOR_COLOR_CONTENT_R";
+//    public static final String CONTENT_COLOR_G = "XML_EDITOR_COLOR_CONTENT_G";
+//    public static final String CONTENT_COLOR_B = "XML_EDITOR_COLOR_CONTENT_B";
+//    
+//    // link documentation to the editor
+//    public static final String LINK_DOCUMENTATION = "DISPLAY_DOCUMENTATION";
+//    public static final String BRING_DOCUMENTATION_TO_FRONT = "DOCUMENTATION_TO_FRONT";
+//    
+//    public static final String SHOW_GENERATED = "SHOW_GENERATED"; 
+//
+//    // default theme
+//    public static final RGB DEFAULT_EDITABLE = new RGB(0, 0, 0);
+//    public static final RGB DEFAULT_CONTENT = new RGB(130, 170, 150);
+//
+//    // ocean theme
+//    public static final RGB OCEAN_EDITABLE = new RGB(0, 0, 128);
+//    public static final RGB OCEAN_CONTENT = new RGB(0, 206, 209);
+//
+//    // fire theme
+//    public static final RGB FIRE_EDITABLE = new RGB(205, 79, 57);
+//    public static final RGB FIRE_CONTENT = new RGB(205, 205, 0);
+//
+//    private Button validationOnSave;
+//    
+//    private ColorSelector editableColorSelector;
+//    private ColorSelector contentColorSelector;
+//    
+//    private Button linkDocumentation;
+//    private Button bringDocumentationToFront;
+//    private Button showGeneratedContent;
+
+    @Override
+    public void init(IWorkbench workbench) {
+        setPreferenceStore(Activator.getDefault().getPreferenceStore());
+        setDescription("Not yet available");
+    }
+
+    @Override
+    protected Control createContents(Composite parent) {
+        Composite container = new Composite(parent, SWT.NONE);
+//
+//        IPreferenceStore prefs = getPreferenceStore();
+//
+        GridLayout layout = new GridLayout(1, false);
+        container.setLayout(layout);
+//        
+//        // validation options
+//        Group validationGroup = new Group(container, SWT.NONE);
+//        validationGroup.setText("Validation");
+//        validationGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+//        layout = new GridLayout(1, false);
+//        validationGroup.setLayout(layout);
+//        validationOnSave = new Button(validationGroup, SWT.CHECK);
+//        validationOnSave.setText("Validate after Safe");
+//        validationOnSave.setSelection(prefs.getBoolean(VALIDATE_ON_SAVE));
+//
+//        // color options
+//        Group colorGroup = new Group(container, SWT.NONE);
+//        colorGroup.setText("Colors");
+//        colorGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+//        layout = new GridLayout(2, false);
+//        colorGroup.setLayout(layout);
+//        
+//        Label editableColorLabel = new Label(colorGroup, SWT.NONE);
+//        editableColorLabel.setText("Editable Text color");
+//        
+//        contentColorSelector = new ColorSelector(colorGroup);
+//        RGB contentColor = new RGB(prefs.getInt(CONTENT_COLOR_R), prefs.getInt(CONTENT_COLOR_G),
+//                prefs.getInt(CONTENT_COLOR_B));
+//        contentColorSelector.setColorValue(contentColor);
+//
+//        Label contentColorLabel = new Label(colorGroup, SWT.NONE);
+//        contentColorLabel.setText("Content Text Color");
+//        
+//        editableColorSelector = new ColorSelector(colorGroup);
+//        RGB editableColor = new RGB(prefs.getInt(EDITABLE_COLOR_R), prefs.getInt(EDITABLE_COLOR_G),
+//                prefs.getInt(EDITABLE_COLOR_B));
+//        editableColorSelector.setColorValue(editableColor);
+//
+//        Group buttonGroup = new Group(colorGroup, SWT.NONE);
+//        buttonGroup.setText("Color Scheme");
+//        RowLayout buttonLayout = new RowLayout(SWT.HORIZONTAL);
+//        buttonLayout.marginLeft = 5;
+//        buttonLayout.marginRight = 5;
+//        buttonLayout.marginTop = 5;
+//        buttonLayout.marginBottom = 5;
+//        buttonLayout.spacing = 5;
+//        buttonLayout.pack = false;
+//        buttonLayout.justify = true;
+//        buttonGroup.setLayout(buttonLayout);
+//        GridData buttonGridData = new GridData(SWT.FILL, SWT.FILL, true, false);
+//        buttonGridData.horizontalSpan = 2;
+//        buttonGroup.setLayoutData(buttonGridData);
+//        
+//        
+//        Button defaultScheme = new Button(buttonGroup, SWT.PUSH);
+//        defaultScheme.setText("default");
+//        
+//        Button oceanScheme = new Button(buttonGroup, SWT.PUSH);
+//        oceanScheme.setText("ocean");
+//        
+//        Button fireScheme = new Button(buttonGroup, SWT.PUSH);
+//        fireScheme.setText("fire");
+//
+//        defaultScheme.addListener(SWT.Selection, new Listener() {
+//            
+//            @Override
+//            public void handleEvent(Event event) {
+//                contentColorSelector.setColorValue(DEFAULT_CONTENT);
+//                editableColorSelector.setColorValue(DEFAULT_EDITABLE);
+//            }
+//        });
+//        
+//        oceanScheme.addListener(SWT.Selection, new Listener() {
+//            
+//            @Override
+//            public void handleEvent(Event event) {
+//                contentColorSelector.setColorValue(OCEAN_CONTENT);
+//                editableColorSelector.setColorValue(OCEAN_EDITABLE);
+//            }
+//        });
+//        
+//        fireScheme.addListener(SWT.Selection, new Listener() {
+//            
+//            @Override
+//            public void handleEvent(Event event) {
+//                contentColorSelector.setColorValue(FIRE_CONTENT);
+//                editableColorSelector.setColorValue(FIRE_EDITABLE);
+//            }
+//        });
+//        
+//        Group others = new Group(container, SWT.NONE);
+//        others.setText("Others");
+//        others.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+//        layout = new GridLayout(1, false);
+//        others.setLayout(layout);
+//        linkDocumentation = new Button(others, SWT.CHECK);
+//        linkDocumentation.setText("Link Documentation");
+//        linkDocumentation.setSelection(prefs.getBoolean(LINK_DOCUMENTATION));
+//        bringDocumentationToFront = new Button(others, SWT.CHECK);
+//        bringDocumentationToFront.setText("Bring Documentation to Front");
+//        bringDocumentationToFront.setSelection(prefs.getBoolean(BRING_DOCUMENTATION_TO_FRONT));
+//        
+//        showGeneratedContent = new Button(others, SWT.CHECK);
+//        showGeneratedContent.setText("Show generated content");
+//        showGeneratedContent.setSelection(prefs.getBoolean(SHOW_GENERATED));
+//        
+        return container;
+    }
+//    
+    @Override
+    public boolean performOk() {
+//        IPreferenceStore prefs = getPreferenceStore();
+//        
+//        RGB content = contentColorSelector.getColorValue();
+//        RGB editable = editableColorSelector.getColorValue();
+//        
+//        prefs.setValue(VALIDATE_ON_SAVE, validationOnSave.getSelection());
+//        
+//        prefs.setValue(CONTENT_COLOR_R, content.red);
+//        prefs.setValue(CONTENT_COLOR_G, content.green);
+//        prefs.setValue(CONTENT_COLOR_B, content.blue);
+//        prefs.setValue(EDITABLE_COLOR_R, editable.red);
+//        prefs.setValue(EDITABLE_COLOR_G, editable.green);
+//        prefs.setValue(EDITABLE_COLOR_B, editable.blue);
+//        
+//        prefs.setValue(LINK_DOCUMENTATION, linkDocumentation.getSelection());
+//        prefs.setValue(BRING_DOCUMENTATION_TO_FRONT, bringDocumentationToFront.getSelection());
+//        prefs.setValue(SHOW_GENERATED, showGeneratedContent.getSelection());
+//        
+        return true;
+    }
+    
+    @Override
+    protected void performDefaults() {
+//        validationOnSave.setSelection(true);
+//        
+//        contentColorSelector.setColorValue(DEFAULT_CONTENT);
+//        editableColorSelector.setColorValue(DEFAULT_EDITABLE);
+//        
+//        linkDocumentation.setSelection(true);
+//        bringDocumentationToFront.setSelection(false);
+//        showGeneratedContent.setSelection(false);
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/preferences/LoggingPreferencePage.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/preferences/LoggingPreferencePage.java
new file mode 100644
index 0000000000000000000000000000000000000000..b10a026077dc3f1bb90d57f31969b21c3b30b1d6
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/preferences/LoggingPreferencePage.java
@@ -0,0 +1,121 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.preferences;
+
+import java.io.File;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+import cern.silecs.activator.Activator;
+
+public class LoggingPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+
+
+    public static final String[] LOG_LEVELS = { "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "OFF" };
+    public static final int DEFAULT_LOG_LEVEL_INDEX = 3;
+    public static final String DEFAULT_LOG_DIRECTORY = System.getProperty("user.home") + "/.logs/fesa-plugin";
+
+    public static final String LOG_LEVEL = "fesaLog.level";
+    public static final String LOG_DIRECTORY = "fesaLog.directory";
+    public static final String BRING_CONSOLE_TO_FRONT = "CONSOLE_TO_FRONT";
+    
+    private Combo logLevel;
+    private Text logDirectory;
+
+    @Override
+    public void init(IWorkbench workbench) {
+        setPreferenceStore(Activator.getDefault().getPreferenceStore());
+        setDescription("SILECS Logging");
+    }
+
+    @Override
+    protected Control createContents(Composite parent) {
+        IPreferenceStore prefs = getPreferenceStore();
+
+        Composite container = new Composite(parent, SWT.NONE);
+        GridLayout layout = new GridLayout(3, false);
+        container.setLayout(layout);
+
+        Label level = new Label(container, SWT.NONE);
+        level.setText("Log Level");
+        logLevel = new Combo(container, SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY);
+        logLevel.setItems(LOG_LEVELS);
+        logLevel.select(prefs.getInt(LOG_LEVEL));
+        GridData dataLayout = new GridData();
+        dataLayout.horizontalSpan = 2;
+        logLevel.setLayoutData(dataLayout);
+
+        Label directory = new Label(container, SWT.NONE);
+        directory.setText("Log Directory");
+        logDirectory = new Text(container, SWT.BORDER);
+        logDirectory.setText(prefs.getString(LOG_DIRECTORY));
+        dataLayout = new GridData(SWT.FILL, SWT.TOP, true, false);
+        logDirectory.setLayoutData(dataLayout);
+
+        Button browse = new Button(container, SWT.PUSH);
+        browse.setText("browse");
+        browse.addListener(SWT.Selection, new Listener() {
+
+            @Override
+            public void handleEvent(Event event) {
+                DirectoryDialog dirDialog = new DirectoryDialog(getShell());
+                logDirectory.setText(dirDialog.open());
+            }
+        });
+
+        return container;
+    }
+
+    @Override
+    public boolean performOk() {
+        IPreferenceStore prefs = getPreferenceStore();
+
+        int levelIndex = logLevel.getSelectionIndex();
+        File logDir = new File(logDirectory.getText());
+        
+        if (!logDir.isDirectory()) {
+            setErrorMessage("Invalid Path !" + logDir.getAbsolutePath());
+            return false;
+        }
+        
+        prefs.setValue(LOG_LEVEL, levelIndex);
+        prefs.setValue(LOG_DIRECTORY, logDir.getAbsolutePath());
+
+
+        return true;
+    }
+
+    @Override
+    protected void performDefaults() {
+        logLevel.select(DEFAULT_LOG_LEVEL_INDEX);
+        logDirectory.setText(DEFAULT_LOG_DIRECTORY);
+    }
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/preferences/MainPreferencePage.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/preferences/MainPreferencePage.java
new file mode 100644
index 0000000000000000000000000000000000000000..20a9e8c95c539398c6a91c7d984a36ee26c717ab
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/preferences/MainPreferencePage.java
@@ -0,0 +1,344 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.preferences;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+import cern.silecs.activator.Activator;
+import cern.silecs.model.exception.SilecsException;
+import cern.silecs.view.console.ConsoleHandler;
+
+public class MainPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
+    
+	public static final String SILECS_DIRECTORY_TAG = "SILECS_DIRECTORY";
+	public static final String FESA_DIRECTORY_TAG = "FESA_DIRECTORY";
+	public static final String LOCAL_DIRECTORY_TAG = "LOCAL_DIRECTORY";
+	public static final String USE_LOCAL_DIRECTORY_TAG = "USE_LOCAL_DIRECTORY";
+	public static final String FESSA_VERSION_TAG = "FESA_VERSION";
+	
+	public static final String SILECS_DIRECTORY_DEFAULT = "/common/usr/cscofe/silecs";
+	public static final String FESA_DIRECTORY_DEFAULT = "/opt/fesa";
+	public static final Boolean USE_LOCAL_DIRECTORY_DEFAULT = false;
+	
+	private static List<String> fesaVersions_ = readOutAvailableFesaVersions();
+    
+	private static Text silecsDirectory;
+	private static Text fesaDirectory;
+	private static Button useLocalWorkspace;
+	private static Text localWorkspaceDirectory;
+	private static Combo fesaVersion;
+	
+	public static boolean isLocalDirectoryUsed()
+	{
+		IPreferenceStore prefs = Activator.getDefault().getPreferenceStore();
+		return prefs.getBoolean(USE_LOCAL_DIRECTORY_TAG);
+	}
+	
+	public static String getGlobalSilecsDirectory()
+	{
+		IPreferenceStore prefs = Activator.getDefault().getPreferenceStore();
+		return prefs.getString(SILECS_DIRECTORY_TAG);
+	}
+	
+	public static String getModelBasePath(String modelVersion)
+	{
+		IPreferenceStore prefs = Activator.getDefault().getPreferenceStore();
+		if(prefs.getBoolean(USE_LOCAL_DIRECTORY_TAG))
+			return prefs.getString(LOCAL_DIRECTORY_TAG) + "/silecs-model/src/xml";
+		else
+			return prefs.getString(SILECS_DIRECTORY_TAG) + "/silecs-model/" + modelVersion + "/" + "xml";
+	}
+	
+	public static String getCodeGenBasePath(String codegenVersion)
+	{
+		IPreferenceStore prefs = Activator.getDefault().getPreferenceStore();
+		if(prefs.getBoolean(USE_LOCAL_DIRECTORY_TAG))
+			return prefs.getString(LOCAL_DIRECTORY_TAG) + "/silecs-codegen/src/xml";
+		else
+			return prefs.getString(SILECS_DIRECTORY_TAG) + "/silecs-codegen/" + codegenVersion + "/" + "xml";
+	}
+	
+	public static String getDiagToolBasePath(String diagToolVersion)
+	{
+		IPreferenceStore prefs = Activator.getDefault().getPreferenceStore();
+		if(prefs.getBoolean(USE_LOCAL_DIRECTORY_TAG))
+			return prefs.getString(LOCAL_DIRECTORY_TAG) + "/silecs-diagnostic-cpp/build";
+		else
+			return prefs.getString(SILECS_DIRECTORY_TAG) + "/silecs-diagnostic-cpp/" + diagToolVersion;
+	}
+	
+	public static String getSilecsLibraryBasePath(String silecsLibraryVersion)
+	{
+		IPreferenceStore prefs = Activator.getDefault().getPreferenceStore();
+		if(prefs.getBoolean(USE_LOCAL_DIRECTORY_TAG))
+			return prefs.getString(LOCAL_DIRECTORY_TAG) + "/silecs-communication-cpp/build";
+		else
+			return prefs.getString(SILECS_DIRECTORY_TAG) + "/silecs-communication-cpp/" + silecsLibraryVersion;
+	}
+	
+	public static String getSNAP7LibraryBasePath(String silecsLibraryVersion)
+	{
+		IPreferenceStore prefs = Activator.getDefault().getPreferenceStore();
+		if(prefs.getBoolean(USE_LOCAL_DIRECTORY_TAG))
+			return prefs.getString(LOCAL_DIRECTORY_TAG) + "/snap7/snap7-full/build";
+		else
+			return prefs.getString(SILECS_DIRECTORY_TAG) + "/snap7/" + silecsLibraryVersion;
+	}
+	
+	public static String getFESAVersion() throws SilecsException
+	{
+		int index = Activator.getDefault().getPreferenceStore().getInt(FESSA_VERSION_TAG);
+		return fesaVersions_.get(index);
+	}
+	
+	public static File[] getFESADesignTemplates() throws SilecsException
+	{
+		return getFESATemplates("design");
+	}
+
+	public static File[] getFESADeployUnitTemplates() throws SilecsException
+	{
+		return getFESATemplates("deployment");
+	}
+	
+	public static String getFESADeployUnitSchemaPath() throws SilecsException
+	{
+		String fesaBaseDirectory = Activator.getDefault().getPreferenceStore().getString(FESA_DIRECTORY_TAG);
+		return new String(fesaBaseDirectory + "/fesa-model-gsi/" + getFESAVersion() + "/xml/deployment/deployment-gsi.xsd");
+	}
+	
+	public static String getFESADesignSchemaPath() throws SilecsException
+	{
+		String fesaBaseDirectory = Activator.getDefault().getPreferenceStore().getString(FESA_DIRECTORY_TAG);
+		return new String(fesaBaseDirectory + "/fesa-model-gsi/" + getFESAVersion() + "/xml/design/design-gsi.xsd");
+	}
+	
+	protected static File[] getFESATemplates(String type) throws SilecsException
+	{
+		String fesaBaseDirectory = Activator.getDefault().getPreferenceStore().getString(FESA_DIRECTORY_TAG);
+		File folderModel = new File(fesaBaseDirectory + "/fesa-model/" + getFESAVersion() + "/xml/" + type + "/templates");
+		File folderModelGSI = new File(fesaBaseDirectory + "/fesa-model-gsi/" + getFESAVersion() + "/xml/" + type + "/templates");
+		
+		File[] templatesModel = folderModel.listFiles();
+		if( templatesModel == null)
+			templatesModel = new File[0];
+		
+		File[] templatesModelGSI = folderModelGSI.listFiles();
+		if( templatesModelGSI == null)
+			templatesModelGSI = new File[0];
+		
+		if ( (templatesModel.length + templatesModelGSI.length) == 0 )
+		{
+			ConsoleHandler.printMessage("Template search folder 1: " + folderModel.getPath(), true);
+			ConsoleHandler.printMessage("Template search folder 2: " + folderModelGSI.getPath(), true);
+			throw new SilecsException("No templates found there! Please fix the 'FESA Base Path' in the Preferences!");
+		}
+		File[] templates= new File[templatesModel.length+templatesModelGSI.length];
+		System.arraycopy(templatesModel, 0, templates, 0, templatesModel.length);
+		System.arraycopy(templatesModelGSI, 0, templates, templatesModel.length, templatesModelGSI.length);
+		return templates;
+	}
+    
+	public static String getLocalDirectoryDefault()
+	{
+		return System.getProperty("user.home") + "/workspace";
+	}
+	
+    @Override
+    protected void createFieldEditors()
+    {
+        // TODO Auto-generated method stub        
+    }
+
+    @Override
+    public void init(IWorkbench workbench)
+    {
+        setDescription("SILECS Preferences");
+        setPreferenceStore(Activator.getDefault().getPreferenceStore());
+    }
+    
+    protected void switchEnableLocalWorkspace(Boolean localEnabled)
+    {
+		fesaDirectory.setEnabled(true);//to stay backward -compartible
+		silecsDirectory.setEnabled(!localEnabled);
+		localWorkspaceDirectory.setEnabled(localEnabled);
+    }
+
+    public static List<String> getAllFesaVersions()
+	{
+    	return fesaVersions_;
+	}
+    
+    protected static List<String> readOutAvailableFesaVersions()
+	{
+		String fesaModelDirectory = Activator.getDefault().getPreferenceStore().getString(FESA_DIRECTORY_TAG) + "/fesa-model-gsi";
+		File fesaBaseFolder = new File(fesaModelDirectory);
+		
+		List<String> fesaVersions = new ArrayList<String>();
+	    for (final File fileEntry : fesaBaseFolder.listFiles())
+	    {
+	    	fesaVersions.add(fileEntry.getName());
+	    }
+	    Collections.sort(fesaVersions);
+	    Collections.reverse(fesaVersions);
+	    return fesaVersions;
+	}
+
+    @Override
+    protected Control createContents(Composite parent)
+    {
+        IPreferenceStore prefs = getPreferenceStore();
+
+        Composite container = new Composite(parent, SWT.NONE);
+        GridLayout layout = new GridLayout(3, false);
+        container.setLayout(layout);
+
+        GridData dataLayout = new GridData();
+        dataLayout.horizontalSpan = 2;
+
+        { // fesa base
+	        Label directory = new Label(container, SWT.NONE);
+	        directory.setText("FESA Base Path");
+	        fesaDirectory = new Text(container, SWT.BORDER);
+	        fesaDirectory.setText(prefs.getString(FESA_DIRECTORY_TAG));
+	        dataLayout = new GridData(SWT.FILL, SWT.TOP, true, false);
+	        fesaDirectory.setLayoutData(dataLayout);
+	
+	        Button browse = new Button(container, SWT.PUSH);
+	        browse.setText("browse");
+	        browse.addListener(SWT.Selection, new Listener() {
+	
+	            @Override
+	            public void handleEvent(Event event) {
+	                DirectoryDialog dirDialog = new DirectoryDialog(getShell());
+	                fesaDirectory.setText(dirDialog.open());
+	            }
+	        });
+        }
+        
+        {	// FESA version
+	        Label level = new Label(container, SWT.NONE);
+	        level.setText("FESA Version to use");
+	        fesaVersion = new Combo(container, SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY);
+	        fesaVersion.setItems(fesaVersions_.toArray(new String[fesaVersions_.size()]));
+	        fesaVersion.select(prefs.getInt(FESSA_VERSION_TAG));
+	        dataLayout = new GridData();
+	        dataLayout.horizontalSpan = 2;
+	        fesaVersion.setLayoutData(dataLayout);
+        }
+        
+        { // silecs base
+	        Label directory = new Label(container, SWT.NONE);
+	        directory.setText("SILECS Base Path");
+	        silecsDirectory = new Text(container, SWT.BORDER);
+	        silecsDirectory.setText(prefs.getString(SILECS_DIRECTORY_TAG));
+	        dataLayout = new GridData(SWT.FILL, SWT.TOP, true, false);
+	        silecsDirectory.setLayoutData(dataLayout);
+	
+	        Button browse = new Button(container, SWT.PUSH);
+	        browse.setText("browse");
+	        browse.addListener(SWT.Selection, new Listener() {
+	
+	            @Override
+	            public void handleEvent(Event event) {
+	                DirectoryDialog dirDialog = new DirectoryDialog(getShell());
+	                silecsDirectory.setText(dirDialog.open());
+	            }
+	        });
+        }
+        
+	      useLocalWorkspace = new Button(container, SWT.CHECK);
+	      useLocalWorkspace.setText("Use local workspace");
+	      dataLayout = new GridData(SWT.FILL, SWT.TOP, true, false);
+	      dataLayout.horizontalSpan = 3;
+	      useLocalWorkspace.setLayoutData(dataLayout);
+	      useLocalWorkspace.setSelection(prefs.getBoolean(USE_LOCAL_DIRECTORY_TAG));
+	      useLocalWorkspace.addListener(SWT.Selection, new Listener() {
+	          @Override
+	          public void handleEvent(Event event) {
+	          		switchEnableLocalWorkspace(useLocalWorkspace.getSelection());
+	          }
+	      });
+        
+        { // Local SILECS Workspace
+	        Label directory = new Label(container, SWT.NONE);
+	        directory.setText("Local SILECS Workspace");
+	        localWorkspaceDirectory = new Text(container, SWT.BORDER);
+	        localWorkspaceDirectory.setText(prefs.getString(LOCAL_DIRECTORY_TAG));
+	        dataLayout = new GridData(SWT.FILL, SWT.TOP, true, false);
+	        localWorkspaceDirectory.setLayoutData(dataLayout);
+	
+	        Button browse = new Button(container, SWT.PUSH);
+	        browse.setText("browse");
+	        browse.addListener(SWT.Selection, new Listener() {
+	
+	            @Override
+	            public void handleEvent(Event event) {
+	                DirectoryDialog dirDialog = new DirectoryDialog(getShell());
+	                localWorkspaceDirectory.setText(dirDialog.open());
+	            }
+	        });
+        }
+
+        switchEnableLocalWorkspace(useLocalWorkspace.getSelection());
+        return container;
+    }
+    
+    @Override
+    public boolean performOk()
+    {
+        IPreferenceStore prefs = getPreferenceStore();
+        prefs.setValue(SILECS_DIRECTORY_TAG, silecsDirectory.getText());
+        prefs.setValue(FESA_DIRECTORY_TAG, fesaDirectory.getText());
+        prefs.setValue(USE_LOCAL_DIRECTORY_TAG, useLocalWorkspace.getSelection());
+        prefs.setValue(LOCAL_DIRECTORY_TAG, localWorkspaceDirectory.getText());
+        prefs.setValue(FESSA_VERSION_TAG, fesaVersion.getSelectionIndex());
+        return true;
+    }
+
+    @Override
+    protected void performDefaults()
+    {
+    	silecsDirectory.setText(SILECS_DIRECTORY_DEFAULT);
+    	fesaDirectory.setText(FESA_DIRECTORY_DEFAULT);
+    	useLocalWorkspace.setSelection(USE_LOCAL_DIRECTORY_DEFAULT);
+    	localWorkspaceDirectory.setText(MainPreferencePage.getLocalDirectoryDefault());
+    	localWorkspaceDirectory.setEnabled(false);
+    	fesaVersion.select(0);
+        switchEnableLocalWorkspace(useLocalWorkspace.getSelection());
+    }
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/preferences/PreferenceInitializer.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/preferences/PreferenceInitializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..f82a6d2f08afb9403752163df1641ff970c96002
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/preferences/PreferenceInitializer.java
@@ -0,0 +1,59 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.preferences;
+
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.graphics.RGB;
+
+import cern.silecs.activator.Activator;
+
+
+public class PreferenceInitializer extends AbstractPreferenceInitializer {
+    
+    @Override
+    public void initializeDefaultPreferences() {
+        IPreferenceStore prefs = Activator.getDefault().getPreferenceStore();
+        
+        prefs.setDefault(MainPreferencePage.SILECS_DIRECTORY_TAG, MainPreferencePage.SILECS_DIRECTORY_DEFAULT);
+        prefs.setDefault(MainPreferencePage.FESA_DIRECTORY_TAG, MainPreferencePage.FESA_DIRECTORY_DEFAULT);
+        prefs.setDefault(MainPreferencePage.LOCAL_DIRECTORY_TAG, MainPreferencePage.getLocalDirectoryDefault());
+        prefs.setDefault(MainPreferencePage.USE_LOCAL_DIRECTORY_TAG, MainPreferencePage.USE_LOCAL_DIRECTORY_DEFAULT);
+        
+        // init the xml editor preferences
+//        prefs.setDefault(EditorPreferencePage.VALIDATE_ON_SAVE, true);
+//        
+//        RGB dflt = EditorPreferencePage.DEFAULT_EDITABLE;
+//        prefs.setDefault(EditorPreferencePage.EDITABLE_COLOR_R, dflt.red);
+//        prefs.setDefault(EditorPreferencePage.EDITABLE_COLOR_G, dflt.green);
+//        prefs.setDefault(EditorPreferencePage.EDITABLE_COLOR_B, dflt.blue);
+//        
+//        dflt = EditorPreferencePage.DEFAULT_CONTENT;
+//        prefs.setDefault(EditorPreferencePage.CONTENT_COLOR_R, dflt.red);
+//        prefs.setDefault(EditorPreferencePage.CONTENT_COLOR_G, dflt.green);
+//        prefs.setDefault(EditorPreferencePage.CONTENT_COLOR_B, dflt.blue);
+//        
+//        prefs.setDefault(EditorPreferencePage.LINK_DOCUMENTATION, true);
+//        prefs.setDefault(EditorPreferencePage.BRING_DOCUMENTATION_TO_FRONT, false);
+//        prefs.setDefault(EditorPreferencePage.SHOW_GENERATED, false);
+        
+        // logging preferences
+        prefs.setDefault(LoggingPreferencePage.LOG_LEVEL, LoggingPreferencePage.DEFAULT_LOG_LEVEL_INDEX);
+        prefs.setDefault(LoggingPreferencePage.LOG_DIRECTORY, LoggingPreferencePage.DEFAULT_LOG_DIRECTORY);
+        prefs.setDefault(LoggingPreferencePage.BRING_CONSOLE_TO_FRONT, true);
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/GenerateCodeWizard.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/GenerateCodeWizard.java
new file mode 100644
index 0000000000000000000000000000000000000000..05ab3ed3cbd275fb0ff7e0bed0c834cea0ec819f
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/GenerateCodeWizard.java
@@ -0,0 +1,70 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.wizards;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.wizard.Wizard;
+
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.wizards.page.PickTemplatePage;
+
+public class GenerateCodeWizard extends Wizard
+{
+	private File[] templates;
+	File choice = null;
+	PickTemplatePage page;
+
+    public GenerateCodeWizard(File[] templateFiles) {
+        super();
+        setWindowTitle("Pick a template");
+        templates = templateFiles;
+    }
+
+    @Override
+    public void addPages() {
+        super.addPages();
+
+        List<String> templateNames = new ArrayList<String>();
+        for( File file : templates)
+        {
+            templateNames.add(file.getName());
+        }
+        String[] simpleArray = new String[ templateNames.size() ];
+        page = new PickTemplatePage("Pick a template",templateNames.toArray(simpleArray));
+        addPage(page);
+    }
+    
+    public File getChoice()
+    {
+    	return choice;
+    }
+    
+    @Override
+    public boolean performFinish() {
+    	String template = page.getTemplate();
+    	//ConsoleHandler.printMessage("template selected: " + template , true);
+        for( File file : templates)
+        {
+        	//ConsoleHandler.printMessage("file available: " + file.getName() , true);
+        	if( file.getName().equals(template))
+        		choice = file;
+        }
+        //ConsoleHandler.printMessage("choice full path: " + choice.getAbsolutePath() , true);
+        return true;
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/ImportDeployFileWizard.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/ImportDeployFileWizard.java
new file mode 100644
index 0000000000000000000000000000000000000000..496d5b7eafb87898d5a35a69c44e6a725174bf6f
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/ImportDeployFileWizard.java
@@ -0,0 +1,79 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.wizards;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.wizard.Wizard;
+
+import cern.silecs.control.core.DeployProjectNature;
+import cern.silecs.utils.SilecsConstants;
+import cern.silecs.utils.SilecsUtils;
+import cern.silecs.utils.XmlUtils;
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.wizards.page.ChooseFilePage;
+import cern.silecs.view.wizards.page.SilecsProjectPage;
+
+public class ImportDeployFileWizard extends Wizard {
+
+    private ChooseFilePage firstPage;
+    private SilecsProjectPage secondPage;
+    
+    public ImportDeployFileWizard() {
+        setWindowTitle("Import Deploy-Unit File Wizard");
+    }
+
+    @Override
+    public void addPages() {
+        super.addPages();
+     
+        firstPage = new ChooseFilePage("Import Deploy-Unit file to workspace", SilecsConstants.ProjectType.DEPLOY_PROJECT);
+        secondPage = new SilecsProjectPage("Import Deploy-Unit file to workspace",
+        		SilecsConstants.ProjectType.DEPLOY_PROJECT,
+                "Enter new deploy-unit name",
+                "Enter new deploy-unit version");
+        
+        addPage(firstPage);
+        addPage(secondPage);
+    }
+
+    @Override
+    public boolean performFinish() {
+        try {
+        	ConsoleHandler.clear();
+        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); 
+        
+            String newDeployName = secondPage.getprojectNameText();
+            IProject project = workspaceRoot.getProject(newDeployName);       
+
+            XmlUtils.reloadDependencies();
+
+            IProgressMonitor monitor = new NullProgressMonitor();
+            DeployProjectNature.addDeployNature(project, monitor);
+
+            SilecsUtils.openInEditor(SilecsUtils.getSilecsDeployFile(project));
+        } catch (Exception e) {
+            e.printStackTrace();
+            ConsoleHandler.printStackTrace(e);
+        }
+        
+        return true;
+    }
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/ImportDesignFileWizard.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/ImportDesignFileWizard.java
new file mode 100644
index 0000000000000000000000000000000000000000..76afc4082962c114ccfcbaf8bb4b417667b535dd
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/ImportDesignFileWizard.java
@@ -0,0 +1,76 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.wizards;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.wizard.Wizard;
+
+import cern.silecs.control.core.DesignProjectNature;
+import cern.silecs.utils.SilecsConstants;
+import cern.silecs.utils.SilecsUtils;
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.wizards.page.ChooseFilePage;
+import cern.silecs.view.wizards.page.SilecsProjectPage;
+
+public class ImportDesignFileWizard extends Wizard {
+
+    private ChooseFilePage firstPage;
+    private SilecsProjectPage secondPage;
+    
+    public ImportDesignFileWizard() {
+        setWindowTitle("Import Design File Wizard");
+    }
+
+    @Override
+    public void addPages() {
+        super.addPages();
+        
+        firstPage = new ChooseFilePage("Import Design file to workspace", SilecsConstants.ProjectType.DESIGN_PROJECT);
+        secondPage =  new SilecsProjectPage("Set Design properties",
+        		SilecsConstants.ProjectType.DESIGN_PROJECT,
+                "Enter new deploy-unit name",
+                "Enter new deploy-unit version");
+        
+        addPage(firstPage);
+        addPage(secondPage);
+    }
+
+    @Override
+    public boolean performFinish() {
+        try {
+        	ConsoleHandler.clear();
+        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+
+            String designName = secondPage.getprojectNameText();
+            IProject project = workspaceRoot.getProject(designName);
+           
+            IProgressMonitor monitor = new NullProgressMonitor();
+            DesignProjectNature.addClassNature(project, monitor);
+            
+            SilecsUtils.openInEditor(SilecsUtils.getSilecsDesignFile(project));
+            
+        } catch (Exception e) {
+            e.printStackTrace();
+            ConsoleHandler.printStackTrace(e);
+        }
+        return true;
+    }
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/NewSilecsDeployWizard.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/NewSilecsDeployWizard.java
new file mode 100644
index 0000000000000000000000000000000000000000..4cde66a16cc379ede5a955acaad0bb26ca40b11c
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/NewSilecsDeployWizard.java
@@ -0,0 +1,113 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.wizards;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+
+import cern.silecs.control.core.DeployProjectNature;
+import cern.silecs.model.exception.SilecsException;
+import cern.silecs.utils.SilecsConstants;
+import cern.silecs.utils.OSExecute;
+import cern.silecs.utils.SilecsUtils;
+import cern.silecs.utils.XmlUtils;
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.preferences.MainPreferencePage;
+import cern.silecs.view.wizards.page.SilecsProjectPage;
+
+public class NewSilecsDeployWizard extends Wizard implements INewWizard
+{
+    
+    SilecsProjectPage page;
+
+    public NewSilecsDeployWizard() {
+        super();
+        setWindowTitle(SilecsConstants.NEW_DEPLOY_WIZARD_TITLE);
+    }
+    
+    @Override
+    public void addPages() {
+        super.addPages();
+        page = new SilecsProjectPage(SilecsConstants.NEW_DEPLOY_PAGE_TITLE,
+        		SilecsConstants.ProjectType.DEPLOY_PROJECT,
+                "Enter deploy-unit name",
+                "Enter silecs version");
+        addPage(page);
+    }
+    
+    @Override
+    public boolean performFinish()
+    {
+        try
+        {
+	        ConsoleHandler.clear();
+	        String deployName = page.getprojectNameText();
+	        String silecsVersion = page.getsilecsVersionText();
+	        String deploySchema =  MainPreferencePage.getModelBasePath(silecsVersion) + "/" + SilecsConstants.DEPLOY_SCHEMA_XSD;
+	        if(! new File(deploySchema).exists())
+	        { 
+	        	throw new SilecsException("The Deploy Schema: '" + deploySchema + "' does not exist. Please check your Eclipse-Silecs preferences!");
+	        }
+	        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+	        String workspacePath = workspaceRoot.getLocation().toFile().getPath();    
+	        
+	        IProject project = workspaceRoot.getProject(deployName);
+	        OSExecute.executePython("iefiles","newDeployProject",silecsVersion,new String[]{workspacePath, deployName,deploySchema,silecsVersion});
+	        XmlUtils.reloadDependencies();
+	        
+	        IFile deployFile = SilecsUtils.getSilecsDeployFile(project);
+	        
+	        IProgressMonitor monitor = new NullProgressMonitor();
+	        //project.create(monitor); 
+	        //DeployProjectNature.addDeployNature(project, monitor); TODO: No idea why this does not work
+	        
+	        IProjectDescription description = project.getWorkspace().newProjectDescription(project.getName());
+	        String[] newNatures = new String[1];
+	        newNatures[0] = DeployProjectNature.NATURE_ID;
+	        description.setNatureIds(newNatures);
+	        
+	        project.create(description, null);
+	        
+	        project.open(IResource.FORCE, monitor);
+	       
+	        SilecsUtils.openInEditor(deployFile);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            ConsoleHandler.printStackTrace(e);
+        }
+        return true;
+    }
+
+	@Override
+	public void init(IWorkbench arg0, IStructuredSelection arg1) {
+		// TODO Auto-generated method stub
+		
+	}
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/NewSilecsDesignWizard.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/NewSilecsDesignWizard.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d915f52faa27725d734b9aecd67ad845d7a8c2f
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/NewSilecsDesignWizard.java
@@ -0,0 +1,115 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.wizards;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+
+import cern.silecs.control.core.DesignProjectNature;
+import cern.silecs.model.exception.SilecsException;
+import cern.silecs.utils.OSExecute;
+import cern.silecs.utils.SilecsUtils;
+import cern.silecs.utils.SilecsConstants;
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.preferences.MainPreferencePage;
+import cern.silecs.view.wizards.page.SilecsProjectPage;
+
+public class NewSilecsDesignWizard extends Wizard implements INewWizard{
+    
+    SilecsProjectPage page;
+
+    public NewSilecsDesignWizard() {
+        super();
+        setWindowTitle(SilecsConstants.NEW_DESIGN_WIZARD_TITLE);
+    }
+
+    @Override
+    public void addPages() {
+        super.addPages();
+
+        page = new SilecsProjectPage(SilecsConstants.NEW_DESIGN_PAGE_TITLE,
+        		SilecsConstants.ProjectType.DESIGN_PROJECT,
+                "Enter design name",
+                "Enter silecs version");
+
+        addPage(page);
+    }
+
+    @Override
+    public boolean performFinish()
+    {
+        try
+        {
+	        ConsoleHandler.clear();
+	        String designName = page.getprojectNameText();
+	        String silecsVersion = page.getsilecsVersionText();
+	        String designSchema = MainPreferencePage.getModelBasePath(silecsVersion) + "/" +SilecsConstants.DESIGN_SCHEMA_XSD;
+	
+	        if(! new File(designSchema).exists())
+	        { 
+	        	throw new SilecsException("The Design Schema: '" + designSchema + "' does not exist. Please check your Eclipse-Silecs preferences!");
+	        }
+	        
+	        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+	        String workspacePath = workspaceRoot.getLocation().toFile().getPath();
+	
+	        IProject project = workspaceRoot.getProject(designName);
+	        OSExecute.executePython("iefiles","newDesignProject",silecsVersion, new String[]{workspacePath, designName, designSchema, silecsVersion});
+	
+	        IFile designFile = SilecsUtils.getSilecsDesignFile(project);
+	
+	        
+	        IProgressMonitor monitor = new NullProgressMonitor();
+	        //project.create(monitor);
+	       
+	        IProjectDescription description = project.getWorkspace().newProjectDescription(project.getName());
+	        String[] newNatures = new String[1];
+	        newNatures[0] = DesignProjectNature.NATURE_ID;
+	        description.setNatureIds(newNatures);
+	        
+	        project.create(description, null);
+	        
+	        project.open(IResource.FORCE, monitor);
+	        //DesignProjectNature.addClassNature(project, monitor); TODO: No idea why this does not work
+	        SilecsUtils.openInEditor(designFile);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            ConsoleHandler.printStackTrace(e);
+        }
+        return true;
+    }
+
+	@Override
+	public void init(IWorkbench arg0, IStructuredSelection arg1) {
+		// TODO Auto-generated method stub
+		
+	}
+
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/UpdateSilecsProjectWizard.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/UpdateSilecsProjectWizard.java
new file mode 100644
index 0000000000000000000000000000000000000000..2de9a3eff1ea63d1faac6e747630f70b7a895755
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/UpdateSilecsProjectWizard.java
@@ -0,0 +1,52 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.wizards;
+
+import org.eclipse.jface.wizard.Wizard;
+
+import cern.silecs.view.console.ConsoleHandler;
+import cern.silecs.view.wizards.page.PickVersionPage;
+
+public class UpdateSilecsProjectWizard extends Wizard
+{
+	String selectedVersion;
+	PickVersionPage page;
+
+    public UpdateSilecsProjectWizard() {
+        super();
+        setWindowTitle("Pick a version");
+    }
+
+    @Override
+    public void addPages() {
+        super.addPages();
+        page = new PickVersionPage("Select the new SILECS version");
+        addPage(page);
+    }
+    
+    public String getSelectedVersion()
+    {
+    	return selectedVersion;
+    }
+    
+    @Override
+    public boolean performFinish() {
+    	ConsoleHandler.clear();
+    	selectedVersion = page.getsilecsVersionText();
+    	ConsoleHandler.printMessage("selected version: " + selectedVersion , true);
+        return true;
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/page/ChooseFilePage.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/page/ChooseFilePage.java
new file mode 100644
index 0000000000000000000000000000000000000000..0f26be830db2ecf8640ed8e906abc0380f3c78f4
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/page/ChooseFilePage.java
@@ -0,0 +1,136 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.wizards.page;
+
+
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+
+import cern.silecs.utils.SilecsConstants;
+
+public class ChooseFilePage extends WizardPage{
+
+    private Composite container;
+    
+    private Text filePathText;
+    
+    private SilecsConstants.ProjectType projectType;
+    
+    /**
+     * @param pageName
+     */
+    public ChooseFilePage(String pageName, SilecsConstants.ProjectType type) {
+        super(pageName);
+        setTitle(pageName);
+
+        projectType = type; 
+    }
+
+    @Override
+    public void createControl(Composite parent) {
+        container = new Composite(parent, SWT.NONE);
+        GridLayout layout = new GridLayout();
+        container.setLayout(layout);
+        layout.numColumns = 3;
+
+        Label classNameLabel = new Label(container, SWT.NONE);
+        classNameLabel.setText("Enter file path");
+
+        filePathText = new Text(container, SWT.BORDER | SWT.SINGLE);
+        filePathText.setText("");
+        filePathText.addModifyListener(new ModifyListener() {
+
+            @Override
+            public void modifyText(ModifyEvent e) {
+                setErrorMessage(null);
+                setMessage(null, IMessageProvider.WARNING);
+                setPageComplete(true);
+
+                saveProjectData();
+            }
+        });
+        
+        Button locateFileButton = new Button(container, SWT.NONE);
+        locateFileButton.setText("Select file");
+        locateFileButton.addSelectionListener(new SelectionListener() {
+            
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+
+                FileDialog dialog = new FileDialog(shell, SWT.OPEN);
+                dialog.setFilterPath(ResourcesPlugin.getWorkspace().getRoot().getLocationURI().getPath());
+                filePathText.setText(dialog.open());
+            }
+            
+            @Override
+            public void widgetDefaultSelected(SelectionEvent e) {
+                // do nothing
+            }
+        });
+        
+        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+        filePathText.setLayoutData(gd);
+        
+        setControl(container);
+        setPageComplete(false);
+    }
+    
+    public String getFilePath() {
+        return filePathText.getText();
+    }
+    
+    protected void saveProjectData() { 
+        try {
+            String originalFilePath = filePathText.getText();
+            
+            switch(projectType) {
+            case DESIGN_PROJECT:               
+                int dotAfterDesignName = originalFilePath.lastIndexOf('.');
+                String designName = originalFilePath.substring(0, dotAfterDesignName);
+                int dotBeforeDesignName = designName.lastIndexOf('.');
+                designName = designName.substring(dotBeforeDesignName);
+                ((SilecsProjectPage) getNextPage()).setprojectNameText(designName);
+                break;
+                
+            case DEPLOY_PROJECT:
+                int dotAfterDUName = originalFilePath.lastIndexOf('.');
+                String deployName = originalFilePath.substring(0, dotAfterDUName);
+                int dotBeforeDUName = deployName.lastIndexOf('.');
+                deployName = deployName.substring(dotBeforeDUName);
+                ((SilecsProjectPage) getNextPage()).setprojectNameText(deployName);
+                break;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/page/PickTemplatePage.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/page/PickTemplatePage.java
new file mode 100644
index 0000000000000000000000000000000000000000..aa99505c3f8bc5465de61f9f652e822017a949a2
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/page/PickTemplatePage.java
@@ -0,0 +1,58 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.wizards.page;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+
+public class PickTemplatePage extends WizardPage{
+	
+	private String[] templates;
+    private Composite container;
+    private Combo templatePicker;
+    
+    /**
+     * @param pageName
+     */
+    public PickTemplatePage(String pageName, String[] templateNames) {
+        super(pageName);
+        setTitle(pageName);
+        templates = templateNames;
+    }
+
+    @Override
+    public void createControl(Composite parent) {
+        container = new Composite(parent, SWT.NONE);
+        GridLayout layout = new GridLayout();
+        container.setLayout(layout);
+        layout.numColumns = 1;
+
+        templatePicker = new Combo(container, SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY);
+        templatePicker.setItems(templates);
+        templatePicker.select(0);
+        GridData dataLayout = new GridData();
+        dataLayout.horizontalSpan = 1;
+        templatePicker.setLayoutData(dataLayout);
+        setControl(container);
+    }
+    
+    public String getTemplate() {
+        return templatePicker.getText();
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/page/PickVersionPage.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/page/PickVersionPage.java
new file mode 100644
index 0000000000000000000000000000000000000000..0326bee9c616178e900bbd7153a9516b0b1d5b51
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/page/PickVersionPage.java
@@ -0,0 +1,72 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.wizards.page;
+
+import java.util.List;
+
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+import cern.silecs.utils.SilecsConstants;
+import cern.silecs.utils.SilecsUtils;
+
+public class PickVersionPage extends WizardPage {
+
+    private Combo silecsVersionText;
+    private String silecsVersionDescription;
+
+    public PickVersionPage(String pageName)
+    {
+        super(pageName);
+        setTitle(pageName);
+        silecsVersionDescription = "New silecs version";
+    }
+
+    @Override
+    public void createControl(Composite parent)
+    {
+        Composite container = new Composite(parent, SWT.NONE);
+        GridLayout layout = new GridLayout();
+        container.setLayout(layout);
+        layout.numColumns = 2;
+
+        Label classVersionLabel = new Label(container, SWT.NONE);
+        classVersionLabel.setText(silecsVersionDescription);
+
+        silecsVersionText = new Combo(container, SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY);
+        List<String> availableSilecsVersions = SilecsUtils.readOutAvailableSilecsVersions();
+        availableSilecsVersions.addAll(SilecsConstants.ADDITIONAL_SILECS_TARGET_MIGRATION_VERSIONS);
+        silecsVersionText.setItems(availableSilecsVersions.toArray(new String[availableSilecsVersions.size()]));
+        silecsVersionText.select(SilecsConstants.DEFAULT_SILECS_VERSION_INDEX);
+        GridData dataLayout = new GridData();
+        dataLayout.horizontalSpan = 2;
+        silecsVersionText.setLayoutData(dataLayout);
+
+        // required to avoid an error in the system
+        setControl(container);
+        setPageComplete(true);
+    }
+
+    public String getsilecsVersionText() {
+        return silecsVersionText.getText();
+    }
+}
diff --git a/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/page/SilecsProjectPage.java b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/page/SilecsProjectPage.java
new file mode 100644
index 0000000000000000000000000000000000000000..61a31e3b8b6599a738315d45b0a108d182793091
--- /dev/null
+++ b/silecs-eclipse-plugin/src/java/cern/silecs/view/wizards/page/SilecsProjectPage.java
@@ -0,0 +1,152 @@
+// Copyright 2016 CERN and GSI
+//
+// 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/>.
+
+package cern.silecs.view.wizards.page;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+import cern.silecs.utils.SilecsConstants;
+import cern.silecs.utils.SilecsUtils;
+import cern.silecs.view.preferences.MainPreferencePage;
+
+public class SilecsProjectPage extends WizardPage {
+    
+    private Text projectNameText;
+    private String projectNameDescription;
+
+    private Combo silecsVersionText;
+    private String silecsVersionDescription;
+    
+    private String projectNamePattern;
+    private int maxNameLength;
+    
+
+    private class PatternMatcherListener implements ModifyListener{
+        
+        @Override
+        public void modifyText(ModifyEvent e) {
+            String name = projectNameText.getText();
+            setErrorMessage(null);
+            setMessage(null, IMessageProvider.WARNING);
+            setPageComplete(true);
+            
+            if (!name.matches(projectNamePattern)) {
+                setErrorMessage(SilecsConstants.INVAILD_PROJECT_NAME + "\n" + projectNamePattern);
+                setPageComplete(false);
+            }   else if(name.length() > maxNameLength) {
+                setErrorMessage("Name cannot be longer than " + maxNameLength + " characters");
+                setPageComplete(false);
+            }   else if (workspaceContainsProject(projectNameText.getText())) {
+                setErrorMessage("Project with this name already exists in the workspace");
+                setPageComplete(false);
+            }
+        }
+        
+    }
+    
+    /**
+     * @param pageName
+     * @param projectNameLabelDescryption For example "Enter project name:"
+     * @param projectVersionLabelDescryption
+     * @param type
+     */
+    public SilecsProjectPage(String pageName, SilecsConstants.ProjectType type, String projectNameLabelDescryption,
+            String silecsVersionLabelDescryption) {
+        super("New Silecs Project Page");
+        setTitle(pageName);
+
+        projectNameDescription = projectNameLabelDescryption;
+        silecsVersionDescription = silecsVersionLabelDescryption;
+        
+        if (type == SilecsConstants.ProjectType.DEPLOY_PROJECT) {
+            projectNamePattern = SilecsConstants.DEPLOY_PATTERN;
+            maxNameLength = SilecsConstants.MAX_DEPLOY_LENGTH;
+        }
+        else if (type == SilecsConstants.ProjectType.DESIGN_PROJECT) {
+            projectNamePattern = SilecsConstants.DESIGN_PATTERN;
+            maxNameLength = SilecsConstants.MAX_DESIGN_LENGTH;
+        }
+    }
+    
+
+    @Override
+    public void createControl(Composite parent) {
+        Composite container = new Composite(parent, SWT.NONE);
+        GridLayout layout = new GridLayout();
+        container.setLayout(layout);
+        layout.numColumns = 2;
+
+        Label classNameLabel = new Label(container, SWT.NONE);
+        classNameLabel.setText(projectNameDescription);
+
+        projectNameText = new Text(container, SWT.BORDER | SWT.SINGLE);
+        projectNameText.setText("");
+        projectNameText.addModifyListener(new PatternMatcherListener());
+        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+        projectNameText.setLayoutData(gd);
+
+        Label classVersionLabel = new Label(container, SWT.NONE);
+        classVersionLabel.setText(silecsVersionDescription);
+
+        silecsVersionText = new Combo(container, SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY);
+        List<String> availableSilecsVersions = SilecsUtils.readOutAvailableSilecsVersions();
+        silecsVersionText.setItems(availableSilecsVersions.toArray(new String[availableSilecsVersions.size()]));
+        silecsVersionText.select(SilecsConstants.DEFAULT_SILECS_VERSION_INDEX);
+        GridData dataLayout = new GridData();
+        dataLayout.horizontalSpan = 2;
+        silecsVersionText.setLayoutData(dataLayout);
+
+        // required to avoid an error in the system
+        setControl(container);
+        setPageComplete(false);
+    }
+
+    public String getprojectNameText() {
+        return projectNameText.getText();
+    }
+
+    public String getsilecsVersionText() {
+        return silecsVersionText.getText();
+    }
+
+    public void setprojectNameText(String text) {
+        projectNameText.setText(text);
+    }
+
+    public void setsilecsVersionText(String text) {
+        silecsVersionText.setText(text);
+    }
+
+    private boolean workspaceContainsProject(String name) {
+        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+        IProject project = workspaceRoot.getProject(name);
+        return project.exists();
+    }
+}
diff --git a/silecs-model/.project b/silecs-model/.project
new file mode 100644
index 0000000000000000000000000000000000000000..f2e3f959d74c28d9c810be36b10e325224b091c5
--- /dev/null
+++ b/silecs-model/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>silecs-model</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
diff --git a/silecs-model/.settings/org.eclipse.core.resources.prefs b/silecs-model/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..0c1820173279914d15734c8c125975d48eb48b70
--- /dev/null
+++ b/silecs-model/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding//src/xml/DeploySchema.xsd=UTF8
diff --git a/silecs-model/LICENSE b/silecs-model/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..20d40b6bceca3a6c0237d7455ebf1820aeff3680
--- /dev/null
+++ b/silecs-model/LICENSE
@@ -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>.
\ No newline at end of file
diff --git a/silecs-model/README.md b/silecs-model/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..e81edfe326686658eae8d919ec2a9e016af67668
--- /dev/null
+++ b/silecs-model/README.md
@@ -0,0 +1,19 @@
+# silecs-codegen
+
+This component of the SILECS PLC-framework is used in order to validate silecs-project-specific XML files.
+
+## Getting Started
+
+Please check the lab-specific SILECS-Wikis for more information:
+
+[CERN SILECS Wiki Page][CERN_Wiki]
+
+[GSI SILECS Wiki Page][GSI_Wiki]
+
+## License
+
+Licensed under the GNU GENERAL PUBLIC LICENSE Version 3. See the [LICENSE file][license] for details.
+
+[license]: LICENSE
+[CERN_Wiki]: https://wikis.cern.ch/display/SIL/SILECs+Home
+[GSI_Wiki]: https://www-acc.gsi.de/wiki/Frontend/SILECS
\ No newline at end of file
diff --git a/silecs-model/install.sh b/silecs-model/install.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e8e33e9f6cfb3f50b7dc6357fdb42e4d7803ef7a
--- /dev/null
+++ b/silecs-model/install.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+set -e
+
+INSTALL_DIR=$1
+
+SCRIPT=$(readlink -f "$0")
+SCRIPTPATH=$(dirname "$SCRIPT")     # path where this script is located in
+
+mkdir -p ${INSTALL_DIR}
+cp -r ${SCRIPTPATH}/src/xml ${INSTALL_DIR}
\ No newline at end of file
diff --git a/silecs-model/src/xml/DeploySchema.xsd b/silecs-model/src/xml/DeploySchema.xsd
new file mode 100644
index 0000000000000000000000000000000000000000..ffc6ec6ff652ca0cc584adc7885351a975b2a197
--- /dev/null
+++ b/silecs-model/src/xml/DeploySchema.xsd
@@ -0,0 +1,518 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright 2016 CERN and GSI
+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/.-->
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
+	<xs:include schemaLocation="shared.xsd" />
+	
+	<xs:element name="SILECS-Deploy">
+		<xs:annotation>
+			<xs:documentation>A SILECS configuration contains the class designs, the memory mapping and the hardware distribution for a given set of PLCs.</xs:documentation>
+			<xs:appinfo>
+				<doc>
+				The SILECS configuration defines the data structure and the communication parameters required for the interconnection of the PLCs and the Front-End clients. It consists of 3 parts:
+				&lt;ol&gt;
+				&lt;li&gt; Design: to define the structure of the exchanged data
+				&lt;li&gt; Mapping: to define the PLC memory mapping and the protocol parameters
+				&lt;li&gt; Generation: to define the hardware on which we will deployed the different Mapping
+				&lt;/ol&gt;
+				Generally under the responsability of a unique expert entity, an SILECS configuration is done for a set of classes and PLCs in the scope of a particular project or set of equipment.
+				</doc>
+			</xs:appinfo>
+		</xs:annotation>
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="Information">
+					<xs:complexType>
+						<xs:sequence>
+							<xs:element name="Owner">
+								<xs:complexType>
+									<xs:attribute name="user-login" type="xs:string" use="required"/>
+								</xs:complexType>
+							</xs:element>
+							<xs:element name="Editor" maxOccurs="unbounded">
+								<xs:complexType>
+									<xs:attribute name="user-login" type="xs:string" use="required"/>
+								</xs:complexType>
+							</xs:element>
+						</xs:sequence>
+					</xs:complexType>
+				</xs:element>
+				<xs:element name="Deploy-Unit">
+					<xs:complexType>
+						<xs:attribute name="name" type="DeployNameType" use="required"/>
+						<xs:attribute name="version" type="VersionType" use="required"/>
+					</xs:complexType>
+				</xs:element>
+				<xs:element name="Controller" type="ControllerType" maxOccurs="unbounded" minOccurs="1">
+			        <xs:unique name="Device-name-unique-per-controller">
+			            <xs:selector xpath="SilecsDesign/Device"/>
+			            <xs:field xpath="@device-name"/>
+			        </xs:unique>
+			        <xs:unique name="Class-name-unique-per-controller">
+                        <xs:selector xpath="SilecsDesign"/>
+                        <xs:field xpath="@silecs-design-name"/>
+                    </xs:unique>
+				</xs:element>
+			</xs:sequence>
+			<xs:attribute name="silecs-version" type="xs:string" use="required">
+				<xs:annotation>
+					<xs:appinfo>
+						<doc>Silecs framework version</doc>
+					</xs:appinfo>
+				</xs:annotation>
+			</xs:attribute>
+			<xs:attribute name="created" type="xs:string" use="required">
+				<xs:annotation>
+					<xs:appinfo>
+						<doc>Creation date</doc>
+					</xs:appinfo>
+				</xs:annotation>
+			</xs:attribute>
+			<xs:attribute name="updated" type="xs:string" use="required">
+				<xs:annotation>
+					<xs:appinfo>
+						<doc>Last update Date</doc>
+					</xs:appinfo>
+				</xs:annotation>
+			</xs:attribute>
+		</xs:complexType>
+	    <xs:unique name="Host-name-unique-per-silecsdeploy">
+	      <xs:selector xpath="Controller"/>
+	      <xs:field xpath="@host-name"/>
+	    </xs:unique>
+	</xs:element>
+                    
+	<xs:complexType name="ControllerType">
+		<xs:sequence>
+		    <xs:choice>
+		        <xs:element name="Siemens-PLC" type="SiemensPLCType">
+		            <xs:annotation>
+		                <xs:documentation>A Siemens-Mapping defines a particular Mapping of classes intended to SIMATIC PLCs</xs:documentation>
+		            </xs:annotation>
+		        </xs:element>
+		        <xs:element name="Schneider-PLC" type="SchneiderPLCType">
+		            <xs:annotation>
+		                <xs:documentation>A Schneider-Mapping defines a particular Mapping of classes intended to PL7/UNITY PLCs</xs:documentation>
+		            </xs:annotation>
+		        </xs:element>
+		        <xs:element name="Beckhoff-PLC" type="BeckhoffPLCType">
+		            <xs:annotation>
+		                <xs:documentation>A Beckhoff-Mapping defines a particular Mapping of classes intended to TwinCat PLCs</xs:documentation>
+		            </xs:annotation>
+		        </xs:element>
+		        <!--  No support for this type in CERN codegen so far<xs:element name="Beckhoff-RIO" type="BeckhoffRIOType">
+				    <xs:annotation>
+				        <xs:documentation>A Beckhoff-RIO deployment defines the physical Mapping of TwinCAT Remote IO modules.</xs:documentation>
+				    </xs:annotation>
+                </xs:element>-->
+		        <xs:element name="Rabbit-uC" type="RabbituCType">
+		            <xs:annotation>
+		                <xs:documentation>A Rabbit-Mapping defines a particular Mapping of classes intended for Rabbit microcontrollers</xs:documentation>
+		            </xs:annotation>
+		        </xs:element>
+		        <xs:element name="Virtual-Controller" type="VirtualControllerType">
+				    <xs:annotation>
+				        <xs:documentation>Defines a particular C++ code mapping of classes intended for Software controller</xs:documentation>
+				    </xs:annotation>
+                </xs:element>
+		        <xs:element name="NI-Controller" type="NIControllerType">
+		            <xs:annotation>
+		                <xs:documentation>A NI-Mapping defines a particular Mapping of classes intended to National Instrument Controllers</xs:documentation>
+		            </xs:annotation>
+		        </xs:element>
+		   </xs:choice>
+		   <xs:element name="SilecsDesign" type="SilecsDesignType" maxOccurs="unbounded"/>
+		</xs:sequence>
+		<xs:attribute name="host-name" type="HostNameType" use="required"/>
+	</xs:complexType>
+	
+	<xs:complexType name="SilecsDesignType">
+        <xs:sequence>
+            <xs:element name="Device" type="DeviceType" maxOccurs="unbounded"/>
+        </xs:sequence>              
+        <xs:attribute name="silecs-design-name" type="SilecsClassNameType" use="required"/>
+        <xs:attribute name="silecs-design-version" type="VersionType" use="required"/>
+    </xs:complexType>
+    
+    <xs:complexType name="DeviceType">
+        <xs:sequence>
+	        <xs:annotation>
+	            <xs:documentation>The device is an instance of the related silecs-design.</xs:documentation>
+	            <xs:appinfo>
+	                <doc>
+	                    The device is an instance of the related SILECS design class. 
+	                    The label is dedicated to the PLC process and the SILECS client software to identify the device in the scope of that class in that particular Mapping.
+	                    It does not identify a unique device instance of the control system at the supervision level.    
+	                    The device sequence will occupy contiguous segment of PLC memory respecting their exact ordering.     
+	                    The SILECS tool assists the expert in ordering devices as required.
+	                </doc>
+	            </xs:appinfo>
+	        </xs:annotation>
+        </xs:sequence>
+        <xs:attribute name="device-name" type="DeviceNameType" use="required"/>
+    </xs:complexType>
+
+	<xs:simpleType name="HostNameType">
+		<xs:restriction base="xs:string">
+		    <xs:minLength value="1"/>
+			<xs:pattern value="[_A-Za-z0-9]*"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="DeployNameType">
+		<xs:restriction base="xs:string">
+			<xs:minLength value="1"/>
+			<xs:maxLength value="20"/>
+			<xs:pattern value="[_A-Za-z]+[_A-Za-z0-9]*"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:simpleType name="DeviceNameType">
+		<xs:restriction base="xs:string">
+			<xs:minLength value="1"/>
+			<xs:maxLength value="30"/>
+			<!--  In FESA the deviceName is restricted to max. 30 characters -->
+			<xs:pattern value="[_A-Za-z][_A-Za-z0-9]*"/>
+		</xs:restriction>
+	</xs:simpleType>
+	
+	<xs:simpleType name="SiemensSystemType">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="STEP-7"/>
+			<xs:enumeration value="TIA-PORTAL"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="SchneiderSystemType">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="UNITY Pro"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="BeckhoffSystemType">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="TWINCat"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="RabbitSystemType">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="Standard-C"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="NISystemType">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="Labview"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="BothProtocolType">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="DEVICE_MODE"/>
+			<xs:enumeration value="BLOCK_MODE"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="DeviceProtocolType">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="DEVICE_MODE"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="BlockProtocolType">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="BLOCK_MODE"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="PCSystemType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="SNAP7 linux32"/>
+            <xs:enumeration value="SNAP7 linux64"/>
+        </xs:restriction>
+    </xs:simpleType>
+    
+	<xs:complexType name="SiemensPLCType">
+		<xs:attribute name="system" type="SiemensSystemType" use="required">
+			<xs:annotation>
+				<xs:documentation>System infrastructure used to develop and/or configure the controller software.</xs:documentation>
+				<xs:appinfo>
+					<doc>
+						System infrastructure used to develop and/or configure the controller software.
+					</doc>
+				</xs:appinfo>
+			</xs:annotation>
+		</xs:attribute>
+		<xs:attribute name="model" use="required">
+			<xs:simpleType>
+				<xs:restriction base="xs:string">
+					<xs:enumeration value="SIMATIC_S7-300"/>
+					<xs:enumeration value="SIMATIC_S7-400"/>
+					<xs:enumeration value="SIMATIC_S7-1200"/>
+					<xs:enumeration value="SIMATIC_S7-1500"/>
+					<xs:enumeration value="SIMATIC_ET-200S"/>
+				</xs:restriction>
+			</xs:simpleType>
+		</xs:attribute>
+		<xs:attribute name="protocol" type="BothProtocolType" use="required">
+			<xs:annotation>
+				<xs:documentation>Data access mode is defined at PLC level for all the classes</xs:documentation>
+				<xs:appinfo>
+					<doc>
+				DEVICE_MODE: One S7-DB per class/device ([class-name]_[device-label|id]), &lt;br&gt;containing the corresponding ordered list of Blocks
+				&lt;br&gt;BLOCK_MODE: One S7-DB per class/block ([class-name]_[block-name]), &lt;br&gt;containing array of corresponding Block, one element per device
+			</doc>
+				</xs:appinfo>
+			</xs:annotation>
+		</xs:attribute>
+		<xs:attribute name="base-DB-number" type="xs:unsignedInt" use="required">
+			<xs:annotation>
+				<xs:documentation>Number of the diagnostic DB that is the first one of the global configuration (corresponds to the common SilecsHeader data-block).</xs:documentation>
+				<xs:appinfo>
+					<doc>
+						Number of the diagnostic DB that is the first one of the global configuration ( &gt;=1)
+					</doc>
+				</xs:appinfo>
+			</xs:annotation>
+		</xs:attribute>
+	</xs:complexType>
+	<xs:complexType name="SchneiderPLCType">
+			<xs:attribute name="system" type="SchneiderSystemType" use="required">
+				<xs:annotation>
+					<xs:documentation>System infrastructure used to develop and/or configure the controller software.</xs:documentation>
+					<xs:appinfo>
+						<doc>
+							System infrastructure used to develop and/or configure the controller software.
+						</doc>
+					</xs:appinfo>
+				</xs:annotation>
+			</xs:attribute>
+			<xs:attribute name="model" use="required">
+				<xs:simpleType>
+					<xs:restriction base="xs:string">
+						<xs:enumeration value="Premium"/>
+						<xs:enumeration value="Quantum"/>
+						<xs:enumeration value="M340"/>
+					</xs:restriction>
+				</xs:simpleType>
+			</xs:attribute>
+			<xs:attribute name="protocol" type="BlockProtocolType" use="required">
+				<xs:annotation>
+					<xs:documentation>Data access mode is defined at PLC level for all the classes</xs:documentation>
+					<xs:appinfo>
+						<doc>
+					BLOCK_MODE: One data-segment per class/block ([class-name]_[block-name]), &lt;br&gt;containing array of corresponding Block, one element per device
+				</doc>
+					</xs:appinfo>
+				</xs:annotation>
+			</xs:attribute>
+			<xs:attribute name="base-address" type="xs:unsignedInt" use="required">
+				<xs:annotation>
+					<xs:documentation>Start address of the SILECS configuration (corresponds to the common SilecsHeader block address).  Attention: 16bit address value is expected independently from the HW model (16 or 32 bit).</xs:documentation>
+					<xs:appinfo>
+						<doc>
+							Start address of the SILECS configuration (corresponds to the common SilecsHeader block address).
+							&lt;br&gt;Attention: 16bit address value is expected independently from the HW model (16 or 32 bit)
+						</doc>
+					</xs:appinfo>
+				</xs:annotation>
+			</xs:attribute>
+</xs:complexType>
+
+<xs:complexType name="BeckhoffPLCType">
+	<xs:attribute name="system" type="BeckhoffSystemType" use="required">
+		<xs:annotation>
+			<xs:documentation>System infrastructure used to develop and/or configure the controller software.</xs:documentation>
+			<xs:appinfo>
+				<doc>
+					System infrastructure used to develop and/or configure the Controller software.
+				</doc>
+			</xs:appinfo>
+		</xs:annotation>
+	</xs:attribute>
+	<xs:attribute name="model" use="required">
+		<xs:simpleType>
+			<xs:restriction base="xs:string">
+				<xs:enumeration value="BC9020"/>
+				<xs:enumeration value="CX9020"/>
+			</xs:restriction>
+		</xs:simpleType>
+	</xs:attribute>
+	<xs:attribute name="protocol" type="BlockProtocolType" use="required">
+		<xs:annotation>
+			<xs:documentation>Data access mode is defined at PLC level for all the classes</xs:documentation>
+			<xs:appinfo>
+				<doc>
+			BLOCK_MODE: One data-segment per class/block ([class-name]_[block-name]), &lt;br&gt;containing array of corresponding Block, one element per device
+		</doc>
+			</xs:appinfo>
+		</xs:annotation>
+	</xs:attribute>
+	<xs:attribute name="base-address" type="xs:unsignedInt" use="required">
+		<xs:annotation>
+			<xs:documentation>Start address of the SILECS configuration (corresponds to the common SilecsHeader block address).  Attention: 16bit address value is expected independently from the HW model (16 or 32 bit).</xs:documentation>
+			<xs:appinfo>
+				<doc>
+					Start address of the SILECS configuration (corresponds to the common SilecsHeader block address).
+					&lt;br&gt;Attention: 16bit address value is expected independently from the HW model (16 or 32 bit)
+				</doc>
+			</xs:appinfo>
+		</xs:annotation>
+	</xs:attribute>
+</xs:complexType>
+
+<!--  No support for this type in CERN codegen so far <xs:complexType name="BeckhoffRIOType">
+    <xs:attribute name="system" type="BeckhoffSystemType" use="required">
+        <xs:annotation>
+            <xs:documentation>System infrastructure used to develop and/or configure the controller software.</xs:documentation>
+            <xs:appinfo>
+                <doc>
+                    System infrastructure used to develop and/or configure the Controller software.
+                </doc>
+            </xs:appinfo>
+        </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="model" use="required">
+        <xs:simpleType>
+            <xs:restriction base="xs:string">
+                <xs:enumeration value="BK9000"/>
+                <xs:enumeration value="BK9050"/>
+                <xs:enumeration value="BK9100"/>
+            </xs:restriction>
+        </xs:simpleType>
+    </xs:attribute>
+    <xs:attribute name="io-base-address" type="xs:unsignedInt" use="required">
+        <xs:annotation>
+            <xs:documentation>Start address of the Remote IO modules (can be 0 if not required). Attention: 16bit address value is expected independently from the HW model (16 or 32 bit).</xs:documentation>
+            <xs:appinfo>
+                <doc>
+                    Start address of the Remote IO modules (can be 0 if not required).
+                    &lt;br&gt;Attention: 16bit address value is expected independently from the HW model (16 or 32 bit).
+                </doc>
+            </xs:appinfo>
+        </xs:annotation>
+    </xs:attribute>
+</xs:complexType>-->
+                            
+<xs:complexType name="RabbituCType">
+	<xs:attribute name="system" type="RabbitSystemType" use="required">
+		<xs:annotation>
+			<xs:documentation>System infrastructure used to develop and/or configure the controller software.</xs:documentation>
+			<xs:appinfo>
+				<doc>
+					System infrastructure used to develop and/or configure the Controller software.
+				</doc>
+			</xs:appinfo>
+		</xs:annotation>
+	</xs:attribute>
+	<xs:attribute name="model" use="required">
+		<xs:simpleType>
+			<xs:restriction base="xs:string">
+	            <xs:enumeration value="Rabbit_RCM_4010"/>
+	            <xs:enumeration value="Rabbit_RCM_2000"/>
+			</xs:restriction>
+		</xs:simpleType>
+	</xs:attribute>
+	<xs:attribute name="protocol" type="BothProtocolType" use="required">
+		<xs:annotation>
+			<xs:documentation>Data access mode is defined at PLC level for all the classes</xs:documentation>
+			<xs:appinfo>
+				<doc>
+			DEVICE_MODE: One C struct field per class/device ([class-name]_[device-label|id]), &lt;br&gt;containing the corresponding ordered list of Blocks
+			&lt;br&gt;BLOCK_MODE: One C struct field per class/block ([class-name]_[block-name]), &lt;br&gt;containing array of corresponding Block, one element per device
+		</doc>
+			</xs:appinfo>
+		</xs:annotation>
+	</xs:attribute>
+	<xs:attribute name="base-address" type="xs:unsignedInt" use="required">
+		<xs:annotation>
+			<xs:documentation>Start address of the entire SILECS configuration interpreted as 16bit address.</xs:documentation>
+			<xs:appinfo>
+				<doc>
+					Start address of the entire SILECS configuration interpreted as 16bit address.
+				</doc>
+			</xs:appinfo>
+		</xs:annotation>
+	</xs:attribute>
+</xs:complexType>
+
+<xs:complexType name="VirtualControllerType">
+    <xs:attribute name="system" type="PCSystemType" use="required">
+        <xs:annotation>
+            <xs:documentation>System infrastructure used to develop and/or configure the controller software.</xs:documentation>
+            <xs:appinfo>
+                <doc>
+                    System infrastructure used to develop and/or configure the Controller software.
+                </doc>
+            </xs:appinfo>
+        </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="model" use="required">
+        <xs:simpleType>
+            <xs:restriction base="xs:string">
+                <xs:enumeration value="SIMATIC_S7-VIRTUAL"/>
+            </xs:restriction>
+        </xs:simpleType>
+    </xs:attribute>
+    <xs:attribute name="protocol" type="BothProtocolType" use="required">
+        <xs:annotation>
+            <xs:documentation>Data access mode is defined at PLC level for all the classes</xs:documentation>
+            <xs:appinfo>
+                <doc>
+            DEVICE_MODE: One C struct field per class/device ([class-name]_[device-label|id]), &lt;br&gt;containing the corresponding ordered list of Blocks
+            &lt;br&gt;BLOCK_MODE: One C struct field per class/block ([class-name]_[block-name]), &lt;br&gt;containing array of corresponding Block, one element per device
+        </doc>
+            </xs:appinfo>
+        </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="base-DB-number" type="xs:unsignedInt" use="required">
+        <xs:annotation>
+            <xs:documentation>Number of the diagnostic DB that is the first one of the global configuration (corresponds to the common SilecsHeader data-block).</xs:documentation>
+            <xs:appinfo>
+                <doc>
+                    Number of the diagnostic DB that is the first one of the global configuration ( &gt;=1)
+                </doc>
+            </xs:appinfo>
+        </xs:annotation>
+    </xs:attribute>
+</xs:complexType>
+                            
+<xs:complexType name="NIControllerType">
+	<xs:attribute name="model" use="required">
+		<xs:simpleType>
+			<xs:restriction base="xs:string">
+				<xs:enumeration value="Compact_RIO"/>
+				<xs:enumeration value="PXI_RT"/>
+				<xs:enumeration value="PXI_Windows"/>
+				<xs:enumeration value="PC_Windows"/>
+				<xs:enumeration value="Other_Support_CNV"/>
+			</xs:restriction>
+		</xs:simpleType>
+	</xs:attribute>
+	<xs:attribute name="system" type="NISystemType" use="required">
+		<xs:annotation>
+			<xs:documentation>System infrastructure used to develop and/or configure the controller software.</xs:documentation>
+			<xs:appinfo>
+				<doc>
+					System infrastructure used to develop and/or configure the Controller software.
+				</doc>
+			</xs:appinfo>
+		</xs:annotation>
+	</xs:attribute>
+	<xs:attribute name="protocol" type="DeviceProtocolType" use="required">
+		<xs:annotation>
+			<xs:documentation>Data access mode is defined at PLC level for all the classes</xs:documentation>
+			<xs:appinfo>
+				<doc>
+					DEVICE_MODE: One shared variable per class/device (//class-name//controllerName//device-label), &lt;br&gt;containing the corresponding ordered list of Blocks.
+				</doc>
+			</xs:appinfo>
+		</xs:annotation>
+	</xs:attribute>
+</xs:complexType>
+
+</xs:schema>
diff --git a/silecs-model/src/xml/DesignSchema.xsd b/silecs-model/src/xml/DesignSchema.xsd
new file mode 100644
index 0000000000000000000000000000000000000000..aa754bc0e23c798a6e1f9e1de5b091d5c294c6d0
--- /dev/null
+++ b/silecs-model/src/xml/DesignSchema.xsd
@@ -0,0 +1,355 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright 2016 CERN and GSI
+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/.-->
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
+    <xs:include schemaLocation="shared.xsd" />
+    
+	<xs:element name="SILECS-Design">
+		<xs:annotation>
+			<xs:documentation>A SILECS configuration contains the class designs, the memory mapping and the hardware distribution for a given set of PLCs.</xs:documentation>
+			<xs:appinfo>
+				<doc>
+				The SILECS configuration defines the data structure and the communication parameters required for the interconnection of the PLCs and the Front-End clients. It consists of 3 parts:
+				&lt;ol&gt;
+				&lt;li&gt; Design: to define the structure of the exchanged data
+				&lt;li&gt; Mapping: to define the PLC memory mapping and the protocol parameters
+				&lt;li&gt; Generation: to define a the hardware on which we will deployed the different Mapping
+				&lt;/ol&gt;
+				Generally under the responsability of a unique expert entity, an SILECS configuration is done for a set of classes and PLCs in the scope of a particular project or set of equipments.
+				</doc>
+			</xs:appinfo>
+		</xs:annotation>
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="Information">
+					<xs:complexType>
+						<xs:sequence>
+							<xs:element name="Owner">
+								<xs:annotation>
+									<xs:documentation>Owner is the one who created the class. He has write-access on the Design document and can deploy the corresponding class course. Owner can add Editors and Users on his class.</xs:documentation>
+									<xs:appinfo>
+										<doc>Owner is the one who created the class. He has write-access on the Design document and can deploy the corresponding class course. Owner can add Editors and Users on his class.</doc>
+									</xs:appinfo>
+								</xs:annotation>
+								<xs:complexType>
+									<xs:attribute name="user-login" type="xs:string" use="required"/>
+								</xs:complexType>
+							</xs:element>
+							<xs:choice maxOccurs="unbounded">
+								<xs:element name="Editor" minOccurs="0" maxOccurs="unbounded">
+									<xs:annotation>
+										<xs:documentation>Editor has write-access on the Design document and can deploy the corresponding class. He cannot add Editors or Users on the class.</xs:documentation>
+										<xs:appinfo>
+											<doc>Editor has write-access on the Design document and can deploy the corresponding class. He cannot add Editors or Users on the class.</doc>
+										</xs:appinfo>
+									</xs:annotation>
+									<xs:complexType>
+										<xs:attribute name="user-login" type="xs:string" use="required"/>
+									</xs:complexType>
+								</xs:element>
+								<xs:element name="User" minOccurs="0" maxOccurs="unbounded">
+									<xs:annotation>
+										<xs:documentation>User has read-only access on the Design document but can deploy the corresponding class. He cannot add Editors or Users on the class.</xs:documentation>
+										<xs:appinfo>
+											<doc>User has read-only access on the Design document but can deploy the corresponding class. He cannot add Editors or Users on the class.</doc>
+										</xs:appinfo>
+									</xs:annotation>
+									<xs:complexType>
+										<xs:attribute name="user-login" type="xs:string" use="required"/>
+									</xs:complexType>
+								</xs:element>
+							</xs:choice>
+						</xs:sequence>
+					</xs:complexType>
+				</xs:element>
+				<xs:element name="SILECS-Class">
+					<xs:annotation>
+						<xs:documentation>The Class node contains the definition of a particular class</xs:documentation>
+						<xs:appinfo>
+							<doc>
+										The Class node contains the definition of a particular class. Designing a class means: 
+										&lt;ol&gt;
+										&lt;li&gt; Defining a unique class name in the scope of the all configuration
+										&lt;li&gt; Providing list of variables which will be exchanged with the target PLC   
+										&lt;li&gt; Identifying coherent groups of variables according to their nature and access mode
+										&lt;/ol&gt;
+										The SILECS tool assists the expert in specifying the data blocks from this abstract point of view.
+										</doc>
+						</xs:appinfo>
+					</xs:annotation>
+					<xs:complexType>
+						<xs:sequence>
+							<xs:element name="Description" type="xs:string" minOccurs="0"/>
+							<xs:element name="Block" maxOccurs="unbounded">
+								<xs:complexType>
+									<xs:sequence>
+										<xs:element name="Description" type="xs:string" minOccurs="0"/>
+										<xs:element name="Register" type="RegisterType" maxOccurs="unbounded">
+									        <xs:annotation>
+									            <xs:appinfo>
+									                <doc>
+									                    The Register is the elementary component of the SILECS data model.
+									                    &lt;br&gt;Each variable has a unique name in the scope of the class (including all blocks).
+									                </doc>
+									            </xs:appinfo>
+									        </xs:annotation>
+                                        </xs:element>
+									</xs:sequence>
+									<xs:attribute name="name" type="BlockNameType" use="required">
+										<xs:annotation>
+											<xs:appinfo>
+												Defines the name of the block that must be unique in all the class.
+ 												Must not exceed 12 characters.
+ 											</xs:appinfo>
+										</xs:annotation>
+									</xs:attribute>
+									<xs:attribute name="mode" use="required">
+										<xs:annotation>
+											<xs:documentation>Defines the access-mode of the block and finally of its related variables.</xs:documentation>
+										</xs:annotation>
+										<xs:simpleType>
+											<xs:restriction base="xs:string">
+												<xs:enumeration value="READ-ONLY"/>
+												<xs:enumeration value="WRITE-ONLY"/>
+												<xs:enumeration value="READ-WRITE"/>
+											</xs:restriction>
+										</xs:simpleType>
+									</xs:attribute>
+									<xs:attribute name="generateFesaProperty" type="xs:boolean" use="required">
+                                        <xs:annotation>
+                                            <xs:appinfo>
+                                                Defines if the code-generation will generate a FESA-Property and the related Actions/Events/etc for this block
+                                            </xs:appinfo>
+                                        </xs:annotation>
+                                    </xs:attribute>
+								</xs:complexType>
+							</xs:element>
+						</xs:sequence>
+						<xs:attribute name="name" type="SilecsClassNameType" use="required"/>
+						<xs:attribute name="version" type="VersionType" use="required"/>
+						<xs:attribute name="domain" use="required">
+							<xs:annotation>
+								<xs:documentation>Defines the domain of use of the class: Operation or Test</xs:documentation>
+							</xs:annotation>
+							<xs:simpleType>
+								<xs:restriction base="xs:string">
+									<xs:enumeration value="TEST"/>
+									<xs:enumeration value="OPERATIONAL"/>
+								</xs:restriction>
+							</xs:simpleType>
+						</xs:attribute>
+					</xs:complexType>
+					<xs:unique name="Register-name-per-class">
+						<xs:selector xpath="Block/Register"/>
+						<xs:field xpath="@name"/>
+					</xs:unique>
+					<xs:unique name="Block-name-per-class">
+						<xs:selector xpath="Block"/>
+						<xs:field xpath="@name"/>
+					</xs:unique>
+				</xs:element>
+			</xs:sequence>
+			<xs:attribute name="silecs-version" type="VersionType" use="required"/>
+			<xs:attribute name="created" type="xs:string" use="required"/>
+			<xs:attribute name="updated" type="xs:string" use="required"/>
+		</xs:complexType>
+	</xs:element>
+
+<xs:complexType name="RegisterType">
+    <xs:sequence>
+        <xs:element name="Description" type="xs:string" minOccurs="0"/>
+    </xs:sequence>
+    <xs:attribute name="name" type="RegisterNameType" use="required">
+        <xs:annotation>
+            <xs:appinfo>
+                <doc>Name must be unique and must respect the following standard:  [_A-Za-z]+[_A-Za-z0-9]*</doc>
+            </xs:appinfo>
+        </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="format" type="FormatType" use="required">
+        <xs:annotation>
+            <xs:appinfo>
+                <doc>
+                    &lt;table border = "1"&gt;
+                        &lt;tr&gt;
+                            &lt;th align="center"&gt; Hardware types &lt;/th&gt;
+                            &lt;th align="center"&gt; Client process types &lt;/th&gt;
+                        &lt;/tr&gt;
+                        &lt;tr&gt;
+                            &lt;td align="center"&gt; uint8 / byte &lt;/td&gt;
+                            &lt;td align="center"&gt; uint8_t &lt;/td&gt;
+                        &lt;/tr&gt;
+                        &lt;tr&gt;
+                            &lt;td align="center"&gt; int8 / char &lt;/td&gt;
+                            &lt;td align="center"&gt; int8_t &lt;/td&gt;
+                        &lt;/tr&gt;
+                        &lt;tr&gt;
+                            &lt;td align="center"&gt; uint16 / word &lt;/td&gt;
+                            &lt;td align="center"&gt; uint16_t &lt;/td&gt;
+                        &lt;/tr&gt;
+                        &lt;tr&gt;
+                            &lt;td align="center"&gt; int16 / int &lt;/td&gt;
+                            &lt;td align="center"&gt; int16_t &lt;/td&gt;
+                        &lt;/tr&gt;
+                        &lt;tr&gt;
+                            &lt;td align="center"&gt; uint32 / dword &lt;/td&gt;
+                            &lt;td align="center"&gt; uint32_t &lt;/td&gt;
+                        &lt;/tr&gt;
+                        &lt;tr&gt;
+                            &lt;td align="center"&gt; int32 / dint &lt;/td&gt;
+                            &lt;td align="center"&gt; int32_t &lt;/td&gt;
+                        &lt;/tr&gt;
+                        &lt;tr&gt;
+                            &lt;td align="center"&gt; uint64 &lt;/td&gt;
+                            &lt;td align="center"&gt; uint64_t &lt;/td&gt;
+                        &lt;/tr&gt;
+                        &lt;tr&gt;
+                            &lt;td align="center"&gt; int64 &lt;/td&gt;
+                            &lt;td align="center"&gt; int64_t &lt;/td&gt;
+                        &lt;/tr&gt;
+                        &lt;tr&gt;
+                            &lt;td align="center"&gt; float32 / real &lt;/td&gt;
+                            &lt;td align="center"&gt; float &lt;/td&gt;
+                        &lt;/tr&gt;
+                        &lt;tr&gt;
+                            &lt;td align="center"&gt; float64 &lt;/td&gt;
+                            &lt;td align="center"&gt; double &lt;/td&gt;
+                        &lt;/tr&gt;
+                        &lt;tr&gt;
+                            &lt;td align="center"&gt; date / dt &lt;/td&gt;
+                            &lt;td align="center"&gt; double &lt;/td&gt;
+                        &lt;/tr&gt;
+                        &lt;tr&gt;
+                            &lt;td align="center"&gt; string / char[] &lt;/td&gt;
+                            &lt;td align="center"&gt; string &lt;/td&gt;
+                        &lt;/tr&gt;
+                    &lt;/table&gt;
+                </doc>
+            </xs:appinfo>
+        </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="synchro" use="required">
+        <xs:annotation>
+            <xs:appinfo>
+                <doc>
+                    initial value or processing value of persistent data must be up-to-date each time a connection is established. 
+                    &lt;br/&gt;SILECS library supports automatic synchronization.
+                    &lt;ul&gt;
+                        &lt;li&gt;MASTER:  PLC overwrites FEC register values. &lt;/li&gt;
+                        &lt;li&gt;SLAVE: FEC overwrites PLC register values. &lt;/li&gt;
+                        &lt;li&gt;NONE: no automatic synchronization performed. (volatile data) &lt;/li&gt;
+                    &lt;/ul&gt;
+                </doc>
+            </xs:appinfo>
+        </xs:annotation>
+        <xs:simpleType>
+            <xs:restriction base="xs:string">
+                <xs:enumeration value="MASTER"/>
+                <xs:enumeration value="SLAVE"/>
+                <xs:enumeration value="NONE"/>
+            </xs:restriction>
+        </xs:simpleType>
+    </xs:attribute>
+    <xs:attribute name="array-dim1" type="DimensionType" use="optional" default="1">
+        <xs:annotation>
+            <xs:appinfo>
+                <doc>
+                    specify register dimension.
+                    &lt;br/&gt; if array-dim1 = 1 the register is a scalar. If array-dim1 > 1 the register is an array.
+                </doc>
+            </xs:appinfo>
+        </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="array-dim2" type="DimensionType" use="optional" default="1">
+        <xs:annotation>
+            <xs:appinfo>
+                <doc>
+                    specify second register dimension.
+                    &lt;br/&gt; if array-dim2 = 1 the register is monodimensional. If array-dim2 > 1 the register is bidimensional.
+                </doc>
+            </xs:appinfo>
+        </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="string-len" type="LengthType" use="optional">
+        <xs:annotation>
+            <xs:appinfo>
+                <doc>specify length of string. If not specified, default value is 64.</doc>
+            </xs:appinfo>
+        </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="generateFesaValueItem" type="xs:boolean" use="required">
+        <xs:annotation>
+            <xs:appinfo>
+                Defines if the code-generation will generate a FESA-Value-Item for this Register
+            </xs:appinfo>
+        </xs:annotation>
+    </xs:attribute>
+</xs:complexType>
+
+                                    
+	<xs:simpleType name="BlockNameType"> 
+		<xs:restriction base="xs:string">
+			<xs:minLength value="1"/>
+			<xs:maxLength value="30"/>
+			<!-- Siemens Support bezüglich der maximalen Zeichenlänge für PLC- Tags : S7-300/1200/1500er bei 128 Zeichen -->
+			<!-- FESA PropertyNames have max. 30 characters. Since For each Block a prop is generated, we have to use this limit -->
+			<xs:pattern value="[_A-Za-z]+[_A-Za-z0-9]*"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="RegisterNameType">
+		<xs:restriction base="xs:string">
+			<xs:minLength value="1"/>
+			<xs:maxLength value="60"/>
+			<!-- FESA Fields have max. 60 characters. Since For each Register a field is generated, we have to use this limit -->
+			<xs:pattern value="[_A-Za-z]+[_A-Za-z0-9]*"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="FormatType">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="uint8"/>
+			<xs:enumeration value="int8"/>
+			<xs:enumeration value="uint16"/>
+			<xs:enumeration value="int16"/>
+			<xs:enumeration value="uint32"/>
+			<xs:enumeration value="int32"/>
+			<xs:enumeration value="uint64"/>
+			<xs:enumeration value="int64"/>
+			<xs:enumeration value="float32"/>
+			<xs:enumeration value="float64"/>
+			<xs:enumeration value="string"/>
+			<xs:enumeration value="date"/>
+			<xs:enumeration value="char"/>
+			<xs:enumeration value="byte"/>
+			<xs:enumeration value="word"/>
+			<xs:enumeration value="dword"/>
+			<xs:enumeration value="int"/>
+			<xs:enumeration value="dint"/>
+			<xs:enumeration value="real"/>
+			<xs:enumeration value="dt"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:simpleType name="DimensionType">
+		<xs:restriction base="xs:unsignedInt">
+			<xs:minInclusive value="1"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="LengthType">
+		<xs:restriction base="xs:unsignedInt">
+			<xs:minInclusive value="2"/>
+			<xs:maxInclusive value="254"/>
+		</xs:restriction>
+	</xs:simpleType>
+</xs:schema>
diff --git a/silecs-model/src/xml/shared.xsd b/silecs-model/src/xml/shared.xsd
new file mode 100644
index 0000000000000000000000000000000000000000..ee68b9c1b9fa4ebc989920052d1770c6c4e1a7f0
--- /dev/null
+++ b/silecs-model/src/xml/shared.xsd
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright 2016 CERN and GSI
+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/.-->
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
+    
+    <xs:simpleType name="SilecsClassNameType"> <!-- Same restrictions as for FESA class name -->
+        <xs:restriction base="xs:string">
+            <xs:minLength value="1"/>
+            <xs:maxLength value="20"/>
+            <xs:pattern value="[_A-Za-z]+[_A-Za-z0-9]*"/>
+        </xs:restriction>
+    </xs:simpleType>
+    
+    <xs:simpleType name="VersionType">
+        <xs:restriction base="xs:string">
+            <xs:minLength value="1"/>
+            <xs:maxLength value="20"/>
+        </xs:restriction>
+    </xs:simpleType>
+    
+    </xs:schema>
diff --git a/snap7/.project b/snap7/.project
new file mode 100644
index 0000000000000000000000000000000000000000..4171e78dd711bc76ca2cf36b8dea9feca1624a7d
--- /dev/null
+++ b/snap7/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>snap7</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
diff --git a/snap7/build.sh b/snap7/build.sh
new file mode 100755
index 0000000000000000000000000000000000000000..fe8ea20e0c24e1023b68271004fb78f6a503c7e9
--- /dev/null
+++ b/snap7/build.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+set -e
+
+SNAP7_VERSION=1.4.0
+SNAP7_FOLDER=snap7-full-${SNAP7_VERSION}
+
+rm -rf snap7-full*
+wget http://downloads.sourceforge.net/project/snap7/${SNAP7_VERSION}/${SNAP7_FOLDER}.tar.gz
+tar -vxzf ${SNAP7_FOLDER}.tar.gz
+mv ${SNAP7_FOLDER} snap7-full
+cd snap7-full/build/unix
+make -f x86_64_linux.mk
diff --git a/snap7/install.sh b/snap7/install.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b4c97cb302ebbf527c669c3d9d55fab9e8ecf459
--- /dev/null
+++ b/snap7/install.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+set -e
+
+INSTALL_DIR=$1
+
+SCRIPT=$(readlink -f "$0")
+SCRIPTPATH=$(dirname "$SCRIPT")     # path where this script is located in
+
+mkdir -p ${INSTALL_DIR}
+cp -r ${SCRIPTPATH}/snap7-full/build/bin ${INSTALL_DIR}
\ No newline at end of file