diff --git a/silecs-codegen/src/xml/genparam.py b/silecs-codegen/src/xml/genparam.py
index 1af7fbafc0e22f46832de5e10b5142c1ba077ae9..d4e2c49e48739fc6b56506105bdb8a15492dc49a 100644
--- a/silecs-codegen/src/xml/genparam.py
+++ b/silecs-codegen/src/xml/genparam.py
@@ -19,7 +19,6 @@ import sys
 import time
 import zlib
 import glob
-import datetime
 import shutil
 import libxml2
 
@@ -34,18 +33,24 @@ from model.Class.Class import *
 from model.Deploy.Deploy import *
 from model.Deploy.Controller import *
 import model.Deploy.Device
+from model.Param.Param import *
+
+class Mapping(object):
+    def __init__(self,classBaseAddress):
+        self.classBaseAddress    = classBaseAddress  # start-address of the data per area type (MEM, DI,DO, AI,AO) for the given class
+        self.nbBlock             = 0  # number of block per area type (MEM, DI,DO, AI,AO)
+        self.deviceDataSize      = 0  # global size of one class instance (sum of block size per area type)
+        self.usedMem            = ""  # data size summary per class and per area type 
+    
 
 #-------------------------------------------------------------------------
 # 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
+blockDataSize              = 0 # my $blockMemSize = 0; in the former PERL script
+blockAddress                 = 0 # my $blockAddress = 0; in the former PERL script
 plcSize                 = 0
 plcLast                 = 0
-classMem                = ""
 instAddr                = 0 
 
 blockCounter            = 0 # used for NI block address generation
@@ -233,9 +238,9 @@ def alignCXxxRegAddress(addr, format, size, dim, dim2, strLen):
 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 blockDataSize
     global plcModel
-    global blkAddr
+    global blockAddress
     
     # internal string/unicode to integer cast
     regAddr = int(regAddr)
@@ -247,20 +252,20 @@ def computeSiemensBlockBlkAddress(regAddr, classAddr, nbDev):
     # then adjust the next block-address by respecting this base-alignment.
     while(int(whichDataAlignment(nextBlockAddr)) < int(algnt)):
         nextBlockAddr+=1
-    blkMemSize = nextBlockAddr
+    blockDataSize = nextBlockAddr
     # then compute the next block DB-number and return the current one
-    tmpblkAddr = blkAddr    
-    blkAddr = blkAddr + 1
+    tmpblockAddress = blockAddress    
+    blockAddress = blockAddress + 1
 
-    return tmpblkAddr + classAddr
+    return tmpblockAddress + 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 blockDataSize
     global plcModel
-    global blkAddr
+    global blockAddress
     
     # internal string/unicode to integer cast
     regAddr = int(regAddr)
@@ -272,18 +277,18 @@ def computeSiemensDeviceBlkAddress(regAddr, classAddr, nbDev):
     #then adjust the next block-address by respecting this base-alignment.                          
     while(int(whichDataAlignment(nextBlockAddr)) < int(algnt)):
         nextBlockAddr+=1
-    blkMemSize = nextBlockAddr
+    blockDataSize = nextBlockAddr
     #then compute the next block DB-number and return the current one
-    tmpblkAddr = blkAddr
-    blkAddr = blkAddr + blkMemSize
-    return tmpblkAddr
+    tmpblockAddress = blockAddress
+    blockAddress = blockAddress + blockDataSize
+    return tmpblockAddress
     
     
 # Block-address = absolute address in the PLC memory
 def computeSchneiderBlockBlkAddress(regAddr, classAddr, nbDev):
-    global blkMemSize
+    global blockDataSize
     global plcModel
-    global blkAddr
+    global blockAddress
 
     # Internal string/unicode to integer cast
     regAddr = int(regAddr)
@@ -301,19 +306,19 @@ def computeSchneiderBlockBlkAddress(regAddr, classAddr, nbDev):
     #then adjust the next block-address by respecting this base-alignment.                          
     while(whichDataAlignment(nextBlockAddr) < int(algnt)):
         nextBlockAddr+=1
-    blkMemSize = nextBlockAddr  
+    blockDataSize = nextBlockAddr  
     # then compute the next block DB-number and return the current one
-    tmpblkAddr = blkAddr   
+    tmpblockAddress = blockAddress   
     # next absolute address: relies on the global class-address
-    blkAddr = blkAddr + (nbDev * blkMemSize)
-    return classAddr + tmpblkAddr
+    blockAddress = blockAddress + (nbDev * blockDataSize)
+    return classAddr + tmpblockAddress
     
     
 # Block-address = offset in the device memory
 def computeSchneiderDeviceBlkAddress(regAddr, classAddr, nbDev):
-    global blkMemSize
+    global blockDataSize
     global plcModel
-    global blkAddr
+    global blockAddress
         
     # internal string/unicode to integer cast
     regAddr = int(regAddr)
@@ -330,12 +335,12 @@ def computeSchneiderDeviceBlkAddress(regAddr, classAddr, nbDev):
     #then adjust the next block-address by respecting this base-alignment.          
     while(whichDataAlignment(nextBlockAddr) < int(algnt)):
         nextBlockAddr+=1
-    blkMemSize = nextBlockAddr
+    blockDataSize = nextBlockAddr
     #then compute the next block DB-number and return the current one
-    tmpblkAddr = blkAddr   
+    tmpblockAddress = blockAddress   
     #next relative address: independent from the global class-address
-    blkAddr = blkAddr + blkMemSize
-    return tmpblkAddr
+    blockAddress = blockAddress + blockDataSize
+    return tmpblockAddress
     
 def computeNiDeviceBlkAddress(regAddr, classAddr, nbDev):
     global blockCounter
@@ -389,62 +394,63 @@ def computeNiDeviceInstAddress(classAddr, devSize):
 #-------------------------------------------------------------------------
 # 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
+def computeSiemensBlockNextBaseAddress(mapping, nbDev):
     global plcLast
     global plcSize
 
     # internal string/unicode to integer cast
-    classAddr   = int(classAddr)
-    nbBlk       = int(nbBlk)
+    classAddr   = int(mapping.classBaseAddress)
+    nbBlk       = int(mapping.nbBlock)
+    devSize     = int(mapping.deviceDataSize)
     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)
+    mapping.usedMem = "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
+def computeSiemensDeviceNextBaseAddress(mapping, nbDev):
     global plcLast
     global plcSize
-    classAddr   = int(classAddr)
-    nbBlk       = int(nbBlk)
+    
+    # internal string/unicode to integer cast
+    classAddr   = int(mapping.classBaseAddress)
+    nbBlk       = int(mapping.nbBlock)
+    devSize     = int(mapping.deviceDataSize)
     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
+    mapping.usedMem = "DB%d..DB%d / %d bytes"%(startDB,plcLast,byteSize)
+    return plcLast + 1                      #next DB number                  #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
+def computeSchneiderAnyNextBaseAddress(mapping, nbDev):
     global plcLast
     global plcSize
-    classAddr   = int(classAddr)
-    nbBlk       = int(nbBlk)
-    nbDev       = int(nbDev)
-    devSize     = int(devSize)
+    
+    # internal string/unicode to integer cast
+    classAddr   = int(mapping.classBaseAddress)
+    nbBlk       = int(mapping.nbBlock)
+    devSize     = int(mapping.deviceDataSize)
+    nbDev       = int(nbDev)    
     
     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);
+    mapping.usedMem = "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):
+def computeNiAnyNextBaseAddress(mapping, nbDev):
     return 0
 
 def computeChecksumController( workspacePath, deploy, controller, silecsVersion, funcGetSilecsDesignFilePath,  logTopics={'errorlog': True}):
@@ -473,6 +479,13 @@ def computeChecksumClass(designDOM, CRC32, logTopics={'errorlog': True}):
             CRC32     = zlib.crc32(trim(str(register.dim1)),CRC32)& 0xffffffff
             CRC32     = zlib.crc32(trim(str(register.dim2)),CRC32)& 0xffffffff
             CRC32     = zlib.crc32(trim(str(register.stringLength)),CRC32)& 0xffffffff
+        for register in block.getDesignIORegisters():
+            CRC32     = zlib.crc32(trim(register.name),CRC32)& 0xffffffff
+            CRC32     = zlib.crc32(trim(register.format),CRC32)& 0xffffffff
+            CRC32     = zlib.crc32(trim(str(register.dim1)),CRC32)& 0xffffffff
+            CRC32     = zlib.crc32(trim(str(register.dim2)),CRC32)& 0xffffffff
+            CRC32     = zlib.crc32(trim(str(register.stringLength)),CRC32)& 0xffffffff
+            CRC32     = zlib.crc32(trim(register.type),CRC32)& 0xffffffff
     return CRC32
     
 
@@ -494,31 +507,34 @@ whichBaseAlignment = {
     'Rabbit_RCM_4010' : '16',
     'Rabbit_RCM_2000' : '16',
     'BC9020'          : '16',
-    'CX9020'          : '32'                          
+    'CX9020'          : '32',
+    'BK9000'          : '16',
+    'BK9050'          : '16',
+    'BK9100'          : '16'
 }
 
 whichDataSize = {
-    'uint8'        : '1',
-    'int8'          : '1',
+    'uint8'       : '1',
+    'int8'        : '1',
     'uint16'      : '2',
-    'int16'        : '2',
+    'int16'       : '2',
     'uint32'      : '4',
-    'int32'        : '4',
+    'int32'       : '4',
     'float32'     : '4',
     'uint64'      : '8',
-    'int64'        : '8',
+    'int64'       : '8',
     'float64'     : '8',
-    'string'       : '1',
-    'date'         : '8',
+    'string'      : '1',
+    'date'        : '8',
     # deprecated formats
-    'char'         : '1',
-    'byte'         : '1',
+    'char'        : '1',
+    'byte'        : '1',
     'word'        : '2',
-    'dword'      : '4',
-    'int'            : '2',
-    'dint'          : '4',
-    'real'          : '4',
-    'dt'             : '8'
+    'dword'       : '4',
+    'int'         : '2',
+    'dint'        : '4',
+    'real'        : '4',
+    'dt'          : '8'
 }
 
 whichRegAddressFunction = {
@@ -539,7 +555,10 @@ whichRegAddressFunction = {
     'Rabbit_RCM_4010'         : alignDIGIRegAddress,
     'Rabbit_RCM_2000'         : alignDIGIRegAddress,
     'BC9020'                  : alignBCxxRegAddress,
-    'CX9020'                  : alignCXxxRegAddress
+    'CX9020'                  : alignCXxxRegAddress,
+    'BK9000'                  : alignPremiumRegAddress,
+    'BK9050'                  : alignPremiumRegAddress,
+    'BK9100'                  : alignPremiumRegAddress
 }
 
 whichBlkAddressFunction = {
@@ -579,18 +598,14 @@ whichBaseAddressFunction = {
 def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSilecsDeployFilePath,  funcGetParameterFileDirectory, workspacePath, deployName, deployVersion, silecsVersion, logTopics={'debuglog': True}):
     # Global variable links
     global plcModel, plcSize, plcLast
-    global PLCbaseAddress, checksumRef, owner, deviceMemSize, blkAddr, nbBlock, msize
-    global blkMemSize
-    global instAddr, classAddr
-    global classMem
-    
+    global blockAddress, msize, blockDataSize, instAddr
     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)
+        iecommon.logError(deployName + "deployment file cannot be found in provided workspace",True,logTopics)
     
     deploy = Deploy.getDeployFromFile(deployPath)
 
@@ -603,7 +618,7 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile
         iecommon.logDebug("create directory %s" %paramPath,logTopics)
     
     for controller in deploy.controllers:
-        classBaseAddress = controller.baseAddress
+        mapping = Mapping(controller.baseAddress)
         plcModel = controller.model
         # Messagges for debugging purpose
         iecommon.logDebug("------ XML extracted informations ------",logTopics)
@@ -616,43 +631,9 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile
 
         paramFile = funcGetParameterFile(workspacePath, deployName, controller.hostName )
         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)
-
-        paramMappingInfoNode = libxml2.newNode("Mapping-Info")
-        outputRoot.addChild(paramMappingInfoNode)
-
-        paramOwnerNode = libxml2.newNode('Owner')
-        paramOwnerNode.setProp("user-login", deploy.owner)
-        paramMappingInfoNode.addChild(paramOwnerNode)
-        
-        element2 = libxml2.newNode('Generation')
-        currentDate = str(datetime.datetime.now())
-        element2.setProp("date",currentDate)
-        paramMappingInfoNode.addChild(element2)
-        
-        element2 = libxml2.newNode('Deployment')
-        CRC32 = computeChecksumController(workspacePath, deploy, controller, silecsVersion, 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", controller.hostName)
-        paramSilecsMappingNode.setProp("plc-brand", controller.brand)
-        paramSilecsMappingNode.setProp("plc-system", controller.system)
-        paramSilecsMappingNode.setProp("plc-model", controller.model)
-        paramSilecsMappingNode.setProp("protocol", controller.protocol)
-        paramSilecsMappingNode.setProp("address", str(controller.baseAddress))
-        paramSilecsMappingNode.setProp("domain", controller.domain)
-        paramSilecsMappingNode.setProp("used-mem", "TODO")
-        outputRoot.addChild(paramSilecsMappingNode)
+        checksum = computeChecksumController(workspacePath, deploy, controller, silecsVersion, funcGetSilecsDesignFilePath, logTopics)
+        param = Param.createParam(silecsVersion, deploy.owner, checksum)
+        param.addController(controller)
 
         for deployDesign in deploy.silecsDesigns:
             devices = controller.getDevicesOfDesign(deployDesign.name)
@@ -669,16 +650,15 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile
             designClass = DesignClass.getDesignClassFromRootNode(designDOM)
             paramClass = ParamClass()
             paramClass.initWithDesignClass(designClass)
-            paramSilecsMappingNode.addChild(paramClass.xmlNode)
+            param.controller.addParamClass(paramClass)
             
             #-------------------------------------------------------------------------
             # 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
+            blockAddress = 0                 # memory address of the block (using byte addressing)
+            mapping.nbBlock = 0             # number of block of the class
 
             computeBlkAddress = whichBlkAddressFunction[controller.brand + controller.protocol]
             
@@ -728,38 +708,49 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile
                 # END OF INNER LOOP TO ACCESS AT REGISTER LEVEL
 
                 paramBlock.setSize(blockSize)
-                paramBlock.setAddress(computeBlkAddress(regAddress, int(classBaseAddress),nbDevice))
-                paramBlock.setMemSize(blkMemSize)
+                paramBlock.setAddress(computeBlkAddress(regAddress, int(mapping.classBaseAddress),nbDevice))
+                paramBlock.setMemSize(blockDataSize)
                 # Append block
                 paramClass.xmlNode.addChild(paramBlock.xmlNode)
                 # Count the number of devices
-                nbBlock = nbBlock+1
-                # Accumulate blkMemSize to compute the total deviceMemSize
-                deviceMemSize = deviceMemSize + blkMemSize
+                mapping.nbBlock = mapping.nbBlock+1
+                # Accumulate blockDataSize to compute the total mapping.deviceDataSize
+                mapping.deviceDataSize = mapping.deviceDataSize + blockDataSize
 
             # END OF INNER LOOP TO ACCESS AT BLOCK LEVEL (LOOP-2)
             # Set block Address
-            paramClass.setAddress(classBaseAddress)
+            paramClass.setAddress(mapping.classBaseAddress)
             
             computeInstAddress = whichInstAddressFunction[ controller.brand + controller.protocol ]
             for device in devices:
                 instance = libxml2.newNode("Instance")
                 instance.setProp("label", device.silecsDeviceLabel)
-                instance.setProp("address", str(computeInstAddress(classBaseAddress, deviceMemSize)))
+                instance.setProp("address", str(computeInstAddress(mapping.classBaseAddress, mapping.deviceDataSize)))
                 paramClass.xmlNode.addChild(instance)
 
             # Compute the memory address for the next class
             computeBaseAddress = whichBaseAddressFunction [controller.brand + controller.protocol]
-            classBaseAddress = computeBaseAddress(classBaseAddress, nbBlock, nbDevice, deviceMemSize);
+            mapping.classBaseAddress = computeBaseAddress(mapping, nbDevice);
             
             # Set class used-memory
-            paramClass.setUsedMemory(classMem)
-            iecommon.logInfo("Used-memory for Class " + deployDesign.name + ": "+str(classMem),logTopics)
-
+            paramClass.setUsedMemory(mapping.usedMem)
+            iecommon.logInfo("Used-memory for Class " + deployDesign.name + ": " + mapping.usedMem ,logTopics)
+
+        #Display details about the PLC memory using for the global configuration
+        if (controller.brand == 'SIEMENS'):
+            # SIEMENS works with data-block addressing
+            plcUsedMem = "DB"+str(controller.baseAddress)+"..DB"+str(plcLast)+" / "+str(plcSize)+" bytes"
+        else:
+            # SCHNEIDER works with absolute addressing
+            startAddr   = controller.baseAddress /2         #Memory info uses word-addressing
+            plcUsedMem  = "MW"+str(startAddr)+"..MW"+str(plcLast)+" / "+str(plcSize)+" words"
+        
+        # print plc used memory
+        iecommon.logInfo("Used-memory for PLC " + deploy.name + ": "+str(plcUsedMem),logTopics)
         #------------------------------------------------------
         # Generate output XML
         #------------------------------------------------------
-        iefiles.saveXMLToFile(paramFile,paramDOM)
+        iefiles.saveXMLToFile(paramFile,param.xmlNode.get_doc())
         
         iecommon.logDebug("---------------------------------------------------------",logTopics)
         iecommon.logDebug("------GENERATED FILE: %s "%paramFile,logTopics)
diff --git a/silecs-codegen/src/xml/genplcsrc.py b/silecs-codegen/src/xml/genplcsrc.py
index 30bc66eb921fd24d267406dde65f7cd76a609900..ae8424d25800199d01284e19a7d7a3cdaa8f5cf2 100644
--- a/silecs-codegen/src/xml/genplcsrc.py
+++ b/silecs-codegen/src/xml/genplcsrc.py
@@ -582,7 +582,8 @@ def genPlcSrc(workspacePath, deployName,silecsVersion,logTopics={'errorlog': Tru
     for controller in silecsDeploy.controllers:
         paramsFile = iefiles.getParameterFile(workspacePath, deployName,controller.hostName)
         paramDOM = libxml2.parseFile(paramsFile)
-        param = Param(paramDOM)
+        param = Param()
+        param.initFromXMLNode(paramDOM)
         param.deployName = silecsDeploy.name
         param.deployVersion = silecsDeploy.version
         generateControllerCode(controller,param,sourceFolderPath,logTopics)
diff --git a/silecs-codegen/src/xml/model/Class/Block.py b/silecs-codegen/src/xml/model/Class/Block.py
index 0ae09cbe49be2509381bf59cd39c24769ff29905..f5acb56c88d9759908fa98a058add7289e2353c6 100644
--- a/silecs-codegen/src/xml/model/Class/Block.py
+++ b/silecs-codegen/src/xml/model/Class/Block.py
@@ -24,10 +24,15 @@ class Block(object):
     ___settingBlockType = "Setting-Block"
     ___acquisitionBlockType = "Acquisition-Block"
     ___commandBlockType = "Command-Block"
+    ___settingIOBlockType = "Setting-IO-Block"
+    ___acquisitionIOBlockType = "Acquisition-IO-Block"
     
     def __init__(self, xmlNode):
         self.xmlNode = xmlNode
+        self.ioType = ""
         self.name = xmlNode.prop("name")
+        if xmlNode.hasProp("ioType"):
+            self.ioType = xmlNode.prop("ioType") #only available on io-blocks
         self.___type = xmlNode.get_name()
                 #xmlNode.shellPrintNode()
 
@@ -40,6 +45,9 @@ class Block(object):
     def isWritable(self):
         return self.___type == self.___settingBlockType or self.___type == self.___commandBlockType
 
+    def isIOBlock(self):
+        return self.___type == self.___settingIOBlockType or self.___type == self.___acquisitionIOBlockType
+    
     def isAcquisition(self):
         return self.___type == self.___acquisitionBlockType
     
@@ -52,6 +60,9 @@ class Block(object):
     def getRegisterNodes(self):
         return self.xmlNode.xpathEval("*[name()='Acquisition-Register' or name()='Setting-Register' or name()='Volatile-Register']")
     
+    def getIORegisterNodes(self):
+        return self.xmlNode.xpathEval("*[name()='Acquisition-IO-Register' or name()='Setting-IO-Register']")
+    
 #has some additionalValues
 class ParamBlock(Block):
     def __init__(self):
@@ -94,6 +105,14 @@ class ParamBlock(Block):
             paramRegisters.append(paramRegister)
         return paramRegisters
     
+    def getParamIORegisters(self):
+        paramIORegisters = []
+        for registerNode in self.getIORegisterNodes():
+            paramRegister = ParamIORegister()
+            paramRegister.initWithParamIORegisterNode(registerNode)
+            paramIORegisters.append(paramRegister)
+        return paramIORegisters
+    
                 
 class DesignBlock(Block):
             
@@ -130,3 +149,9 @@ class DesignBlock(Block):
         for registerNode in self.getRegisterNodes():
             designRegisters.append(DesignRegister(registerNode))
         return designRegisters
+        
+    def getDesignIORegisters(self):
+        designIORegisters = []
+        for registerNode in self.getIORegisterNodes():
+            designIORegisters.append(DesignIORegister(registerNode))
+        return designIORegisters
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/model/Class/Register.py b/silecs-codegen/src/xml/model/Class/Register.py
index 079dcdec4a3594b6b0540260d36fa5d78ca59af1..e61d27097ed74b449f7deca2307087922056fcc1 100644
--- a/silecs-codegen/src/xml/model/Class/Register.py
+++ b/silecs-codegen/src/xml/model/Class/Register.py
@@ -285,3 +285,24 @@ class DesignRegister(Register):
                  'string'   :'char'
         }[silecsDataType]
     
+    
+class DesignIORegister(DesignRegister):
+    def __init__(self, xmlNode):
+        super(DesignIORegister, self).__init__(xmlNode)
+        self.type = self.xmlNode.prop("type")
+        
+class ParamIORegister(ParamRegister):
+    def __init__(self):
+        super(ParamIORegister, self).__init__()
+        self.type = ""
+        
+    def initWithParamIORegisterNode(self, xmlNode):
+        super(ParamIORegister, self).__init__()
+        self.type = self.xmlNode.prop("type")
+        self.initWithParamRegisterNode(xmlNode)
+        
+    def initWithDesignIORegister(self, designIORegister,size,address,memSize):
+        super(ParamIORegister, self).__init__()
+        self.type = self.xmlNode.prop("type")
+        self.initWithDesignRegister(designIORegister,size,address,memSize)
+        #self.xmlNode.shellPrintNode()
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/model/Deploy/Controller.py b/silecs-codegen/src/xml/model/Deploy/Controller.py
index 0d4a40cdc42505d440c672bb0af6fcba68242a50..e3df9efd36b20026d8be4d66a00d0caa1ce2b267 100644
--- a/silecs-codegen/src/xml/model/Deploy/Controller.py
+++ b/silecs-codegen/src/xml/model/Deploy/Controller.py
@@ -107,20 +107,24 @@ class SiemensController(Controller):
         self.baseAddress = long(self.plcNode.prop('base-DB-number'))
         
 class BeckhoffController(Controller):
-    addressFactor_BC9020 = 2 # BC90xx use 16 bit addressing
+    addressFactor_default = 2 # Beckhoff default is 16 bit addressing
     addressFactor_CX9020 = 1
-    offset_BC9020 = 32768
+    offset_default = 0  # No offset by default (Bus coupler for instance)
+    offset_BC9020 = 32768 # some controllers use a memory-offset
     offset_CX9020 = 24576
     def __init__(self, xmlNode):
         super(BeckhoffController, self).__init__(xmlNode)
-        self.brand = "BECKHOFF"
-        self.baseAddress = long(self.plcNode.prop('base-address'))
+        self.brand =            "BECKHOFF"
+        self.baseAddress =      long(self.plcNode.prop('base-address'))
+        self.addressFactor =    self.addressFactor_default
+        self.offset =           self.offset_default
+        if self.model == 'CX9020':
+            self.addressFactor = self.addressFactor_CX9020
+            self.offset = self.offset_CX9020
         if self.model == 'BC9020':
-            self.baseAddress = ( self.baseAddress * self.addressFactor_BC9020 ) + self.offset_BC9020
-        elif self.model == 'CX9020':
-            self.baseAddress = ( self.baseAddress * self.addressFactor_CX9020 ) + self.offset_CX9020
-        else:
-            raise Exception( "Unknown beckhoff plc-model:" + self.model )
+            self.offset = self.offset_BC9020
+        self.baseAddress = ( self.baseAddress * self.addressFactor) + self.offset
+
         
 class SchneiderController(Controller):
     addressFactor = 2
diff --git a/silecs-codegen/src/xml/model/Param/Controller.py b/silecs-codegen/src/xml/model/Param/Controller.py
index 21ec8a3f7d1ef72c5fd20f9471ba5aaf62e6de87..f56606e6ecb5c1a2a79c8205087d15d7e63be0df 100644
--- a/silecs-codegen/src/xml/model/Param/Controller.py
+++ b/silecs-codegen/src/xml/model/Param/Controller.py
@@ -15,11 +15,12 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from model.Class.Class import ParamClass
+from model.Deploy.Controller import Controller
 import libxml2
 
-class Controller(object):
+class ParamController(object):
 
-    def __init__(self, xmlNode):
+    def __init__(self):
         self.hostName = ""
         self.domain = ""
         self.system = ""
@@ -27,10 +28,11 @@ class Controller(object):
         self.protocol = ""
         self.brand = ""
         self.address = long(0)
-        self.usedMem = long(0)
+        self.usedMem = ""
         self.xmlNode = None
         self.paramClasses = []
-    
+
+    def initAttributes(self, xmlNode):
         self.xmlNode = xmlNode
         self.hostName = xmlNode.prop("plc-name")
         self.domain = xmlNode.prop("domain")
@@ -40,8 +42,27 @@ class Controller(object):
         self.brand = self.xmlNode.prop("plc-brand")
         self.address = long(self.xmlNode.prop("address"))
         self.usedMem = self.xmlNode.prop("used-mem")
-        
+            
+    def initFromXMLNode(self, xmlNode):
+        self.initAttributes(xmlNode)
         for classNode in self.xmlNode.xpathEval('SILECS-Class'):
             paramClass = ParamClass()
             paramClass.initWithParamClassNode(classNode)
-            self.paramClasses.append(paramClass)
\ No newline at end of file
+            self.paramClasses.append(paramClass)
+            
+    def initFromDeployController(self, controller):
+        newNode = libxml2.newNode("SILECS-Mapping")
+        newNode.newProp("plc-name", controller.hostName)
+        newNode.newProp("plc-brand", controller.brand)
+        newNode.newProp("plc-system", str(controller.system))
+        newNode.newProp("plc-model", controller.model)
+        newNode.newProp("protocol", controller.protocol)
+        newNode.newProp("address", str(controller.baseAddress))
+        newNode.newProp("domain", controller.domain)
+        newNode.newProp("used-mem", "TODO")
+        self.initAttributes(newNode)
+    
+    def addParamClass(self,paramClass):
+        self.xmlNode.addChild(paramClass.xmlNode)
+        self.paramClasses.append(paramClass)
+        
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/model/Param/Param.py b/silecs-codegen/src/xml/model/Param/Param.py
index ce952f934f94e946f07cf40edc555578cdf24ee5..841f91c789543aaf3452cd7ec2059fb2ac2d1142 100644
--- a/silecs-codegen/src/xml/model/Param/Param.py
+++ b/silecs-codegen/src/xml/model/Param/Param.py
@@ -15,12 +15,15 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import libxml2
+import datetime
 
-from model.Param.Controller import Controller
+from model.Param.Controller import ParamController
 
 class Param(object):
 
-    def __init__(self, xmlNode):
+    def __init__(self):
+        self.xmlNode = None
+        self.mappingNode = None
         self.silecsVersion = ""
         self.owner = ""
         self.genDate = ""
@@ -28,26 +31,70 @@ class Param(object):
         self.controller = None
         self.deployName ="" #need to be explicitly set by codegen
         self.deployVersion ="" #need to be explicitly set by codegen
-        self.xmlNode = xmlNode
-        paramNodes = self.xmlNode.xpathEval('/SILECS-Param')
+
+    def initBaseAttributes(self, paramDOM):
+        paramNodes = paramDOM.xpathEval('/SILECS-Param')
         if len(paramNodes) != 1:
             raise Exception( "Error: param-document is corrupt" )
-        paramNode = paramNodes[0]
-        ownderNodes = paramNode.xpathEval('Mapping-Info/Owner')
+        self.xmlNode = paramNodes[0]
+        ownderNodes = self.xmlNode.xpathEval('Mapping-Info/Owner')
         if len(ownderNodes) != 1:
             raise Exception( "Error: param-document is corrupt" )
-        generationNodes = paramNode.xpathEval('Mapping-Info/Generation')
+        generationNodes = self.xmlNode.xpathEval('Mapping-Info/Generation')
         if len(generationNodes) != 1:
             raise Exception( "Error: param-document is corrupt" )
-        deploymentNodes = paramNode.xpathEval('Mapping-Info/Deployment')
+        deploymentNodes = self.xmlNode.xpathEval('Mapping-Info/Deployment')
         if len(deploymentNodes) != 1:
             raise Exception( "Error: param-document is corrupt" )
-        mappingNodes = paramNode.xpathEval('SILECS-Mapping')
-        if len(mappingNodes) != 1:
-            raise Exception( "Error: param-document is corrupt" )
-
-        self.silecsVersion = paramNode.prop("silecs-version")
+        self.silecsVersion = self.xmlNode.prop("silecs-version")
         self.owner = ownderNodes[0].prop("user-login")
         self.genDate = generationNodes[0].prop("date")
         self.checksum = long(deploymentNodes[0].prop('checksum'))
-        self.controller = Controller(mappingNodes[0])
\ No newline at end of file
+        
+    def initFromXMLNode(self,paramDOM):
+        self.initBaseAttributes(paramDOM)
+        mappingNodes = self.xmlNode.xpathEval('SILECS-Mapping')
+        if len(mappingNodes) != 1:
+            raise Exception( "Error: param-document is corrupt" )
+        self.mappingNode = mappingNodes[0]
+        self.controller = ParamController()
+        self.controller.initFromXMLNode(self.mappingNode)
+        
+    def addController(self,deployController):
+        if self.controller != None:
+            raise Exception("Cannot add controller '" + deployController.hostName + "'. A controller named '" + self.controller.hostName  + "' is already registered")
+        paramController = ParamController()
+        paramController.initFromDeployController(deployController)
+        self.xmlNode.addChild(paramController.xmlNode)
+        self.controller = paramController
+
+                
+    @staticmethod
+    def createParam(silecsVersion, owner, checksum):
+        paramDOM  = libxml2.newDoc(version='1.0')
+        rootNode  = libxml2.newNode('SILECS-Param')
+        rootNode.setProp("silecs-version", silecsVersion)
+        paramDOM.addChild(rootNode)
+
+        paramMappingInfoNode = libxml2.newNode("Mapping-Info")
+        rootNode.addChild(paramMappingInfoNode)
+
+        paramOwnerNode = libxml2.newNode('Owner')
+        paramOwnerNode.setProp("user-login", owner)
+        paramMappingInfoNode.addChild(paramOwnerNode)
+        
+        gen = libxml2.newNode('Generation')
+        currentDate = str(datetime.datetime.now())
+        gen.setProp("date",currentDate)
+        paramMappingInfoNode.addChild(gen)
+        
+        deploy = libxml2.newNode('Deployment')
+        deploy.setProp("checksum", str(checksum))
+        paramMappingInfoNode.addChild(deploy)
+        
+        param = Param()
+        param.initBaseAttributes(rootNode)
+        #param.mappingNode = libxml2.newNode('SILECS-Mapping')
+        #rootNode.addChild(param.mappingNode)
+        return param
+    
diff --git a/silecs-codegen/src/xml/test/general/genParamTest.py b/silecs-codegen/src/xml/test/general/genParamTest.py
index 0d59b80e66005313b0a8100189384ee9fc57205d..64f955bf9cd14b44d6f7d72e9187b55801cfeb5a 100644
--- a/silecs-codegen/src/xml/test/general/genParamTest.py
+++ b/silecs-codegen/src/xml/test/general/genParamTest.py
@@ -52,6 +52,10 @@ def SiemensSourcesTest():
     CompareGeneratedFiles("Siemens_TiaBlock",".silecsparam")
     CompareGeneratedFiles("Siemens_Step7Device",".silecsparam")
     CompareGeneratedFiles("Siemens_Step7Block",".silecsparam")
+    
+def SiemensVirtualSourcesTest():
+    CompareGeneratedFiles("Virtual_SiemensBlock",".silecsparam")
+    CompareGeneratedFiles("Virtual_SiemensDevice",".silecsparam")
 
 def BeckhoffSourcesTest():
     CompareGeneratedFiles("Beckhoff_BC9020",".silecsparam")
@@ -64,11 +68,13 @@ def SchneiderSourcesTest():
 def RabbitSourcesTest():
     CompareGeneratedFiles("Rabbit_BlockMode",".silecsparam")
     CompareGeneratedFiles("Rabbit_DeviceMode",".silecsparam")
+    
 
 def runTests():
 
     genParamBase( fakeGetSilecsDesignFilePath, fakeGetParameterFile, fakeGetSilecsDeployFilePath, fakeGetParameterFileDirectory, "fake", "AllTypesDU", "fake", "DEV")
     SiemensSourcesTest()
+    SiemensVirtualSourcesTest()
     BeckhoffSourcesTest()
     SchneiderSourcesTest()
     RabbitSourcesTest()
diff --git a/silecs-codegen/src/xml/test/general/genplcsrcTest.py b/silecs-codegen/src/xml/test/general/genplcsrcTest.py
index 7190864762b9747f99d6236f18d148a8de75acc9..ad97feae26ac5f224e401d1f3119cf17944c1802 100644
--- a/silecs-codegen/src/xml/test/general/genplcsrcTest.py
+++ b/silecs-codegen/src/xml/test/general/genplcsrcTest.py
@@ -39,7 +39,8 @@ def generatePLCSources():
     for controller in silecsDeploy.controllers:
         paramsFile = generationFolder + "/client/" + controller.hostName + ".silecsparam"
         paramDOM = libxml2.parseFile(paramsFile)
-        param = Param(paramDOM)
+        param = Param()
+        param.initFromXMLNode(paramDOM)
         param.deployName = silecsDeploy.name
         param.deployVersion = silecsDeploy.version
         genplcsrc.generateControllerCode(controller, param, generationFoldeController ,{'errorlog': True})
@@ -60,6 +61,19 @@ def SiemensSourcesTest():
     CompareGeneratedFiles("Siemens_Step7Device",".sdf")
     CompareGeneratedFiles("Siemens_Step7Block",".scl")
     CompareGeneratedFiles("Siemens_Step7Block",".sdf")
+    
+def SiemensVirtualSourcesTest():
+    CompareGeneratedFiles("SilecsHeader_1.0.0",".h")
+    CompareGeneratedFiles("Virtual_SiemensBlock_0.1.0",".cpp")
+    CompareGeneratedFiles("Virtual_SiemensBlock.AllTypes",".h")
+    CompareGeneratedFiles("Virtual_SiemensBlock",".cpp")
+    CompareGeneratedFiles("Virtual_SiemensBlock",".h")
+    CompareGeneratedFiles("Virtual_SiemensBlock.SilecsHeader",".h")
+    CompareGeneratedFiles("Virtual_SiemensDevice_0.1.0",".cpp")
+    CompareGeneratedFiles("Virtual_SiemensDevice.AllTypes",".h")
+    CompareGeneratedFiles("Virtual_SiemensDevice",".cpp")
+    CompareGeneratedFiles("Virtual_SiemensDevice",".h")
+    CompareGeneratedFiles("Virtual_SiemensDevice.SilecsHeader",".h")
 
 def BeckhoffSourcesTest():
     CompareGeneratedFiles("Beckhoff_BC9020",".exp")
@@ -78,6 +92,7 @@ def runTests():
     generatePLCSources()
 
     SiemensSourcesTest()
+    SiemensVirtualSourcesTest()
     BeckhoffSourcesTest()
     SchneiderSourcesTest()
     RabbitSourcesTest()
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
index 163cd5fbf98453fb4848c18fc497c2538a40245c..2b7c148e2f8ca1b910021ad2bfe855c3a30ead0c 100644
--- a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_BC9020.silecsparam
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_BC9020.silecsparam
@@ -2,7 +2,7 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-20 10:34:35.153287"/>
+    <Generation date="2017-07-25 11:00:26.492677"/>
     <Deployment checksum="1037751963"/>
   </Mapping-Info>
   <SILECS-Mapping plc-name="Beckhoff_BC9020" plc-brand="BECKHOFF" plc-system="TWINCat" plc-model="BC9020" protocol="BLOCK_MODE" address="32768" domain="" used-mem="TODO">
@@ -23,7 +23,7 @@
       </Acquisition-Block>
       <Instance label="SilecsHeader" address="0"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="32816" usedMemory="MW16408..MW18167 / 1760 words">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="32816" usedMemory="MW16408..MW18215 / 1808 words">
       <Acquisition-Block name="MyROBlock" size="53" address="32816" mem-size="122">
         <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1">
 				<scalar format="int8"/>
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
index b711383b67eaa73c41a7880f61b0bba6f818142b..20aae0aa31382d8a444f44c6c3ed814e9747412d 100644
--- a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020.silecsparam
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020.silecsparam
@@ -2,7 +2,7 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-20 10:34:35.186172"/>
+    <Generation date="2017-07-25 11:00:26.530253"/>
     <Deployment checksum="2754857673"/>
   </Mapping-Info>
   <SILECS-Mapping plc-name="Beckhoff_CX9020" plc-brand="BECKHOFF" plc-system="TWINCat" plc-model="CX9020" protocol="BLOCK_MODE" address="24576" domain="" used-mem="TODO">
@@ -23,7 +23,7 @@
       </Acquisition-Block>
       <Instance label="SilecsHeader" address="0"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="24628" usedMemory="MW12314..MW14081 / 1768 words">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="24628" usedMemory="MW12314..MW14133 / 1820 words">
       <Acquisition-Block name="MyROBlock" size="53" address="24628" mem-size="128">
         <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1">
 				<scalar format="int8"/>
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
index 161f848188630bcd335b864d2b27d2390a242756..5e445be2729b9b49c9e7a49037d0b3859c68614b 100644
--- a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam
@@ -2,7 +2,7 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-20 10:34:35.299118"/>
+    <Generation date="2017-07-25 11:00:26.682209"/>
     <Deployment checksum="308863231"/>
   </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="" used-mem="TODO">
@@ -23,7 +23,7 @@
       </Acquisition-Block>
       <Instance label="SilecsHeader" address="0"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1821 / 1800 words">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1865 / 1844 words">
       <Acquisition-Block name="MyROBlock" size="53" address="44" mem-size="120">
         <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="2">
 				<scalar format="int8"/>
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
index c762cf3a2d749f31bfcab68027c0c19dc4e600ac..d9946854f1f85aaa04950cc45ced9af8b7e72c58 100644
--- a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam
@@ -2,7 +2,7 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-20 10:34:35.271989"/>
+    <Generation date="2017-07-25 11:00:26.645862"/>
     <Deployment checksum="308863231"/>
   </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="" used-mem="TODO">
@@ -23,7 +23,7 @@
       </Acquisition-Block>
       <Instance label="SilecsHeader" address="0"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1821 / 1800 words">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1865 / 1844 words">
       <Acquisition-Block name="MyROBlock" size="53" address="0" mem-size="120">
         <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="2">
 				<scalar format="int8"/>
@@ -184,7 +184,7 @@
 			</Setting-Register>
       </Command-Block>
       <Instance label="testDevice1" address="44"/>
-      <Instance label="testDevice2" address="1844"/>
+      <Instance label="testDevice2" address="1888"/>
     </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
index 6a7ba61e5c13d4ee8da466625c97a1fec68d3a49..2287afacfda1278ad945b0525987f6f6d9c0cf82 100644
--- a/silecs-codegen/src/xml/test/generated_correct/client/Schneider_M340.silecsparam
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Schneider_M340.silecsparam
@@ -2,7 +2,7 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-20 10:34:35.244711"/>
+    <Generation date="2017-07-25 11:00:26.607123"/>
     <Deployment checksum="308863231"/>
   </Mapping-Info>
   <SILECS-Mapping plc-name="Schneider_M340" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="M340" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO">
@@ -23,7 +23,7 @@
       </Acquisition-Block>
       <Instance label="SilecsHeader" address="0"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1801 / 1780 words">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1845 / 1824 words">
       <Acquisition-Block name="MyROBlock" size="53" address="44" mem-size="124">
         <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="2">
 				<scalar format="int8"/>
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
index 0daaea48bea92782101fef029778cea8d087b8b9..986aa092bcffc51ef28d375fddf91181a39ea505 100644
--- a/silecs-codegen/src/xml/test/generated_correct/client/Schneider_PremiumQuantum.silecsparam
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Schneider_PremiumQuantum.silecsparam
@@ -2,7 +2,7 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-20 10:34:35.214606"/>
+    <Generation date="2017-07-25 11:00:26.568077"/>
     <Deployment checksum="308863231"/>
   </Mapping-Info>
   <SILECS-Mapping plc-name="Schneider_PremiumQuantum" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="Premium" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO">
@@ -23,7 +23,7 @@
       </Acquisition-Block>
       <Instance label="SilecsHeader" address="0"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1793 / 1772 words">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1837 / 1816 words">
       <Acquisition-Block name="MyROBlock" size="53" address="44" mem-size="120">
         <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="2">
 				<scalar format="int8"/>
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
index 1bbf34fa26974c9e6ab801345c69c99138c53900..f6ad542a588ece820a32b2b955f07b428341ea49 100644
--- a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Block.silecsparam
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Block.silecsparam
@@ -2,7 +2,7 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-20 10:34:35.015979"/>
+    <Generation date="2017-07-25 11:00:26.340140"/>
     <Deployment checksum="308863231"/>
   </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="" used-mem="TODO">
@@ -23,7 +23,7 @@
       </Acquisition-Block>
       <Instance label="SilecsHeader" address="0"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB2 / 3540 bytes">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB2 / 3636 bytes">
       <Acquisition-Block name="MyROBlock" size="53" address="0" mem-size="118">
         <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1">
 				<scalar format="int8"/>
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
index fadc78156f67b270cda3804c5f2e2487e5b2ddda..11ab3a4d92ab05eca142cfd2c5a93c88d1383ae4 100644
--- a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Device.silecsparam
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Device.silecsparam
@@ -2,7 +2,7 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-20 10:34:35.051991"/>
+    <Generation date="2017-07-25 11:00:26.378125"/>
     <Deployment checksum="308863231"/>
   </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="" used-mem="TODO">
@@ -23,7 +23,7 @@
       </Acquisition-Block>
       <Instance label="SilecsHeader" address="0"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB3 / 3540 bytes">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB3 / 3636 bytes">
       <Acquisition-Block name="MyROBlock" size="53" address="1" mem-size="118">
         <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1">
 				<scalar format="int8"/>
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
index 783f88664f8add012a348475e71aa7e8253a9340..aedddec1cda9f200133797bbf8bcca84edcacd54 100644
--- a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaBlock.silecsparam
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaBlock.silecsparam
@@ -2,7 +2,7 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-20 10:34:34.977960"/>
+    <Generation date="2017-07-25 11:00:26.302895"/>
     <Deployment checksum="308863231"/>
   </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="" used-mem="TODO">
@@ -23,7 +23,7 @@
       </Acquisition-Block>
       <Instance label="SilecsHeader" address="0"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB3 / 3540 bytes">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB3 / 3636 bytes">
       <Acquisition-Block name="MyROBlock" size="53" address="1" mem-size="118">
         <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1">
 				<scalar format="int8"/>
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
index e4721eff7c71194b76012352904c16394afb6027..a9a789de36fc615490246577d62d81dfd19d3b4e 100644
--- a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaDevice.silecsparam
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaDevice.silecsparam
@@ -2,7 +2,7 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-20 10:34:34.943897"/>
+    <Generation date="2017-07-25 11:00:26.263419"/>
     <Deployment checksum="308863231"/>
   </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="" used-mem="TODO">
@@ -23,7 +23,7 @@
       </Acquisition-Block>
       <Instance label="SilecsHeader" address="0"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB2 / 3540 bytes">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB2 / 3636 bytes">
       <Acquisition-Block name="MyROBlock" size="53" address="0" mem-size="118">
         <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1">
 				<scalar format="int8"/>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensBlock.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensBlock.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..ef0b905083157b6e3d405f57a01df635ca8a136e
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensBlock.silecsparam
@@ -0,0 +1,190 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2017-07-25 11:00:26.453248"/>
+    <Deployment checksum="308863231"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Virtual_SiemensBlock" plc-brand="SIEMENS" plc-system="S7 virtual controller" plc-model="SIMATIC_S7-VIRTUAL" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes">
+      <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="48">
+        <Acquisition-Register name="_version" size="1" address="0" mem-size="18">
+          <string string-length="16" format="string"/>
+      </Acquisition-Register>
+        <Acquisition-Register name="_checksum" size="4" address="18" mem-size="4">
+          <scalar format="uint32"/>
+      </Acquisition-Register>
+        <Acquisition-Register name="_user" size="1" address="22" mem-size="18">
+          <string string-length="16" format="string"/>
+      </Acquisition-Register>
+        <Acquisition-Register name="_date" size="8" address="40" mem-size="8">
+          <scalar format="dt"/>
+      </Acquisition-Register>
+      </Acquisition-Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB3 / 3636 bytes">
+      <Acquisition-Block name="MyROBlock" size="53" address="1" mem-size="118">
+        <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1">
+				<scalar format="int8"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_uint8" generateFesaValueItem="true" fesaFieldName="RO_uint8_fesa" size="1" address="1" mem-size="1">
+				<scalar format="uint8"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_int16" generateFesaValueItem="true" fesaFieldName="RO_int16_fesa" size="2" address="2" mem-size="2">
+				<scalar format="int16"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_uint16" generateFesaValueItem="true" fesaFieldName="RO_uint16_fesa" size="2" address="4" mem-size="2">
+				<scalar format="uint16"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_int32" generateFesaValueItem="true" fesaFieldName="RO_int32_fesa" size="4" address="6" mem-size="4">
+				<scalar format="int32"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_uint32" generateFesaValueItem="true" fesaFieldName="RO_uint32_fesa" size="4" address="10" mem-size="4">
+				<scalar format="uint32"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_float32" generateFesaValueItem="true" fesaFieldName="RO_float32_fesa" size="4" address="14" mem-size="4">
+				<scalar format="float32"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_string" generateFesaValueItem="true" fesaFieldName="RO_string_fesa" size="1" address="18" mem-size="66">
+				<string string-length="64" format="string"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_date" generateFesaValueItem="true" fesaFieldName="RO_date_fesa" size="8" address="84" mem-size="8">
+				<scalar format="date"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_char" generateFesaValueItem="true" fesaFieldName="RO_char_fesa" size="1" address="92" mem-size="1">
+				<scalar format="char"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_byte" generateFesaValueItem="true" fesaFieldName="RO_byte_fesa" size="1" address="93" mem-size="1">
+				<scalar format="byte"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_word" generateFesaValueItem="true" fesaFieldName="RO_word_fesa" size="2" address="94" mem-size="2">
+				<scalar format="word"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_dword" generateFesaValueItem="true" fesaFieldName="RO_dword_fesa" size="4" address="96" mem-size="4">
+				<scalar format="dword"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_int" generateFesaValueItem="true" fesaFieldName="RO_int_fesa" size="2" address="100" mem-size="2">
+				<scalar format="int"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_dint" generateFesaValueItem="true" fesaFieldName="RO_dint_fesa" size="4" address="102" mem-size="4">
+				<scalar format="dint"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_real" generateFesaValueItem="true" fesaFieldName="RO_real_fesa" size="4" address="106" mem-size="4">
+				<scalar format="real"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_dt" generateFesaValueItem="true" fesaFieldName="RO_dt_fesa" size="8" address="110" mem-size="8">
+				<scalar format="dt"/>
+			</Acquisition-Register>
+      </Acquisition-Block>
+      <Setting-Block name="MyRWBlock" size="212" address="2" mem-size="472">
+        <Volatile-Register name="RW_int8" generateFesaValueItem="true" size="1" address="0" mem-size="4">
+				<array2D dim1="2" dim2="2" format="int8"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_uint8" generateFesaValueItem="true" fesaFieldName="RW_uint8_fesa" size="1" address="4" mem-size="4">
+				<array2D dim1="2" dim2="2" format="uint8"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_int16" generateFesaValueItem="true" fesaFieldName="RW_int16_fesa" size="2" address="8" mem-size="8">
+				<array2D dim1="2" dim2="2" format="int16"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_uint16" generateFesaValueItem="true" fesaFieldName="RW_uint16_fesa" size="2" address="16" mem-size="8">
+				<array2D dim1="2" dim2="2" format="uint16"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_int32" generateFesaValueItem="true" fesaFieldName="RW_int32_fesa" size="4" address="24" mem-size="16">
+				<array2D dim1="2" dim2="2" format="int32"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_uint32" generateFesaValueItem="true" fesaFieldName="RW_uint32_fesa" size="4" address="40" mem-size="16">
+				<array2D dim1="2" dim2="2" format="uint32"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_float32" generateFesaValueItem="true" fesaFieldName="RW_float32_fesa" size="4" address="56" mem-size="16">
+				<array2D dim1="2" dim2="2" format="float32"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_string" generateFesaValueItem="true" fesaFieldName="RW_string_fesa" size="1" address="72" mem-size="264">
+				<stringArray2D dim1="2" dim2="2" string-length="64" format="string"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_date" generateFesaValueItem="true" fesaFieldName="RW_date_fesa" size="8" address="336" mem-size="32">
+				<array2D dim1="2" dim2="2" format="date"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_char" generateFesaValueItem="true" fesaFieldName="RW_char_fesa" size="1" address="368" mem-size="4">
+				<array2D dim1="2" dim2="2" format="char"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_byte" generateFesaValueItem="true" fesaFieldName="RW_byte_fesa" size="1" address="372" mem-size="4">
+				<array2D dim1="2" dim2="2" format="byte"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_word" generateFesaValueItem="true" fesaFieldName="RW_word_fesa" size="2" address="376" mem-size="8">
+				<array2D dim1="2" dim2="2" format="word"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_dword" generateFesaValueItem="true" fesaFieldName="RW_dword_fesa" size="4" address="384" mem-size="16">
+				<array2D dim1="2" dim2="2" format="dword"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_int" generateFesaValueItem="true" fesaFieldName="RW_int_fesa" size="2" address="400" mem-size="8">
+				<array2D dim1="2" dim2="2" format="int"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_dint" generateFesaValueItem="true" fesaFieldName="RW_dint_fesa" size="4" address="408" mem-size="16">
+				<array2D dim1="2" dim2="2" format="dint"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_real" generateFesaValueItem="true" fesaFieldName="RW_real_fesa" size="4" address="424" mem-size="16">
+				<array2D dim1="2" dim2="2" format="real"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_dt" generateFesaValueItem="true" fesaFieldName="RW_dt_fesa" size="8" address="440" mem-size="32">
+				<array2D dim1="2" dim2="2" format="dt"/>
+			</Volatile-Register>
+      </Setting-Block>
+      <Command-Block name="MyWOBlock" size="530" address="3" mem-size="1180">
+        <Setting-Register name="WO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="10">
+				<array dim="10" format="int8"/>
+			</Setting-Register>
+        <Setting-Register name="WO_uint8" generateFesaValueItem="true" fesaFieldName="WO_uint8_fesa" size="1" address="10" mem-size="10">
+				<array dim="10" format="uint8"/>
+			</Setting-Register>
+        <Setting-Register name="WO_int16" generateFesaValueItem="true" fesaFieldName="WO_int16_fesa" size="2" address="20" mem-size="20">
+				<array dim="10" format="int16"/>
+			</Setting-Register>
+        <Setting-Register name="WO_uint16" generateFesaValueItem="true" fesaFieldName="WO_uint16_fesa" size="2" address="40" mem-size="20">
+				<array dim="10" format="uint16"/>
+			</Setting-Register>
+        <Setting-Register name="WO_int32" generateFesaValueItem="true" fesaFieldName="WO_int32_fesa" size="4" address="60" mem-size="40">
+				<array dim="10" format="int32"/>
+			</Setting-Register>
+        <Setting-Register name="WO_uint32" generateFesaValueItem="true" fesaFieldName="WO_uint32_fesa" size="4" address="100" mem-size="40">
+				<array dim="10" format="uint32"/>
+			</Setting-Register>
+        <Setting-Register name="WO_float32" generateFesaValueItem="true" fesaFieldName="WO_float32_fesa" size="4" address="140" mem-size="40">
+				<array dim="10" format="float32"/>
+			</Setting-Register>
+        <Setting-Register name="WO_string" generateFesaValueItem="true" fesaFieldName="WO_string_fesa" size="1" address="180" mem-size="660">
+				<stringArray dim="10" string-length="64" format="string"/>
+			</Setting-Register>
+        <Setting-Register name="WO_date" generateFesaValueItem="true" fesaFieldName="WO_date_fesa" size="8" address="840" mem-size="80">
+				<array dim="10" format="date"/>
+			</Setting-Register>
+        <Setting-Register name="WO_char" generateFesaValueItem="true" fesaFieldName="WO_char_fesa" size="1" address="920" mem-size="10">
+				<array dim="10" format="char"/>
+			</Setting-Register>
+        <Setting-Register name="WO_byte" generateFesaValueItem="true" fesaFieldName="WO_byte_fesa" size="1" address="930" mem-size="10">
+				<array dim="10" format="byte"/>
+			</Setting-Register>
+        <Setting-Register name="WO_word" generateFesaValueItem="true" fesaFieldName="WO_word_fesa" size="2" address="940" mem-size="20">
+				<array dim="10" format="word"/>
+			</Setting-Register>
+        <Setting-Register name="WO_dword" generateFesaValueItem="true" fesaFieldName="WO_dword_fesa" size="4" address="960" mem-size="40">
+				<array dim="10" format="dword"/>
+			</Setting-Register>
+        <Setting-Register name="WO_int" generateFesaValueItem="true" fesaFieldName="WO_int_fesa" size="2" address="1000" mem-size="20">
+				<array dim="10" format="int"/>
+			</Setting-Register>
+        <Setting-Register name="WO_dint" generateFesaValueItem="true" fesaFieldName="WO_dint_fesa" size="4" address="1020" mem-size="40">
+				<array dim="10" format="dint"/>
+			</Setting-Register>
+        <Setting-Register name="WO_real" generateFesaValueItem="true" fesaFieldName="WO_real_fesa" size="4" address="1060" mem-size="40">
+				<array dim="10" format="real"/>
+			</Setting-Register>
+        <Setting-Register name="WO_dt" generateFesaValueItem="true" fesaFieldName="WO_dt_fesa" size="8" address="1100" mem-size="80">
+				<array dim="10" format="dt"/>
+			</Setting-Register>
+      </Command-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/Virtual_SiemensDevice.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensDevice.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..61c9023b07a337a325d273732268fe0784d999c8
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensDevice.silecsparam
@@ -0,0 +1,190 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2017-07-25 11:00:26.415203"/>
+    <Deployment checksum="308863231"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Virtual_SiemensDevice" plc-brand="SIEMENS" plc-system="S7 virtual controller" plc-model="SIMATIC_S7-VIRTUAL" protocol="DEVICE_MODE" address="0" domain="" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes">
+      <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="48">
+        <Acquisition-Register name="_version" size="1" address="0" mem-size="18">
+          <string string-length="16" format="string"/>
+      </Acquisition-Register>
+        <Acquisition-Register name="_checksum" size="4" address="18" mem-size="4">
+          <scalar format="uint32"/>
+      </Acquisition-Register>
+        <Acquisition-Register name="_user" size="1" address="22" mem-size="18">
+          <string string-length="16" format="string"/>
+      </Acquisition-Register>
+        <Acquisition-Register name="_date" size="8" address="40" mem-size="8">
+          <scalar format="dt"/>
+      </Acquisition-Register>
+      </Acquisition-Block>
+      <Instance label="SilecsHeader" address="0"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB2 / 3636 bytes">
+      <Acquisition-Block name="MyROBlock" size="53" address="0" mem-size="118">
+        <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1">
+				<scalar format="int8"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_uint8" generateFesaValueItem="true" fesaFieldName="RO_uint8_fesa" size="1" address="1" mem-size="1">
+				<scalar format="uint8"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_int16" generateFesaValueItem="true" fesaFieldName="RO_int16_fesa" size="2" address="2" mem-size="2">
+				<scalar format="int16"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_uint16" generateFesaValueItem="true" fesaFieldName="RO_uint16_fesa" size="2" address="4" mem-size="2">
+				<scalar format="uint16"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_int32" generateFesaValueItem="true" fesaFieldName="RO_int32_fesa" size="4" address="6" mem-size="4">
+				<scalar format="int32"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_uint32" generateFesaValueItem="true" fesaFieldName="RO_uint32_fesa" size="4" address="10" mem-size="4">
+				<scalar format="uint32"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_float32" generateFesaValueItem="true" fesaFieldName="RO_float32_fesa" size="4" address="14" mem-size="4">
+				<scalar format="float32"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_string" generateFesaValueItem="true" fesaFieldName="RO_string_fesa" size="1" address="18" mem-size="66">
+				<string string-length="64" format="string"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_date" generateFesaValueItem="true" fesaFieldName="RO_date_fesa" size="8" address="84" mem-size="8">
+				<scalar format="date"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_char" generateFesaValueItem="true" fesaFieldName="RO_char_fesa" size="1" address="92" mem-size="1">
+				<scalar format="char"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_byte" generateFesaValueItem="true" fesaFieldName="RO_byte_fesa" size="1" address="93" mem-size="1">
+				<scalar format="byte"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_word" generateFesaValueItem="true" fesaFieldName="RO_word_fesa" size="2" address="94" mem-size="2">
+				<scalar format="word"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_dword" generateFesaValueItem="true" fesaFieldName="RO_dword_fesa" size="4" address="96" mem-size="4">
+				<scalar format="dword"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_int" generateFesaValueItem="true" fesaFieldName="RO_int_fesa" size="2" address="100" mem-size="2">
+				<scalar format="int"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_dint" generateFesaValueItem="true" fesaFieldName="RO_dint_fesa" size="4" address="102" mem-size="4">
+				<scalar format="dint"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_real" generateFesaValueItem="true" fesaFieldName="RO_real_fesa" size="4" address="106" mem-size="4">
+				<scalar format="real"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_dt" generateFesaValueItem="true" fesaFieldName="RO_dt_fesa" size="8" address="110" mem-size="8">
+				<scalar format="dt"/>
+			</Acquisition-Register>
+      </Acquisition-Block>
+      <Setting-Block name="MyRWBlock" size="212" address="118" mem-size="472">
+        <Volatile-Register name="RW_int8" generateFesaValueItem="true" size="1" address="0" mem-size="4">
+				<array2D dim1="2" dim2="2" format="int8"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_uint8" generateFesaValueItem="true" fesaFieldName="RW_uint8_fesa" size="1" address="4" mem-size="4">
+				<array2D dim1="2" dim2="2" format="uint8"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_int16" generateFesaValueItem="true" fesaFieldName="RW_int16_fesa" size="2" address="8" mem-size="8">
+				<array2D dim1="2" dim2="2" format="int16"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_uint16" generateFesaValueItem="true" fesaFieldName="RW_uint16_fesa" size="2" address="16" mem-size="8">
+				<array2D dim1="2" dim2="2" format="uint16"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_int32" generateFesaValueItem="true" fesaFieldName="RW_int32_fesa" size="4" address="24" mem-size="16">
+				<array2D dim1="2" dim2="2" format="int32"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_uint32" generateFesaValueItem="true" fesaFieldName="RW_uint32_fesa" size="4" address="40" mem-size="16">
+				<array2D dim1="2" dim2="2" format="uint32"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_float32" generateFesaValueItem="true" fesaFieldName="RW_float32_fesa" size="4" address="56" mem-size="16">
+				<array2D dim1="2" dim2="2" format="float32"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_string" generateFesaValueItem="true" fesaFieldName="RW_string_fesa" size="1" address="72" mem-size="264">
+				<stringArray2D dim1="2" dim2="2" string-length="64" format="string"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_date" generateFesaValueItem="true" fesaFieldName="RW_date_fesa" size="8" address="336" mem-size="32">
+				<array2D dim1="2" dim2="2" format="date"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_char" generateFesaValueItem="true" fesaFieldName="RW_char_fesa" size="1" address="368" mem-size="4">
+				<array2D dim1="2" dim2="2" format="char"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_byte" generateFesaValueItem="true" fesaFieldName="RW_byte_fesa" size="1" address="372" mem-size="4">
+				<array2D dim1="2" dim2="2" format="byte"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_word" generateFesaValueItem="true" fesaFieldName="RW_word_fesa" size="2" address="376" mem-size="8">
+				<array2D dim1="2" dim2="2" format="word"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_dword" generateFesaValueItem="true" fesaFieldName="RW_dword_fesa" size="4" address="384" mem-size="16">
+				<array2D dim1="2" dim2="2" format="dword"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_int" generateFesaValueItem="true" fesaFieldName="RW_int_fesa" size="2" address="400" mem-size="8">
+				<array2D dim1="2" dim2="2" format="int"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_dint" generateFesaValueItem="true" fesaFieldName="RW_dint_fesa" size="4" address="408" mem-size="16">
+				<array2D dim1="2" dim2="2" format="dint"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_real" generateFesaValueItem="true" fesaFieldName="RW_real_fesa" size="4" address="424" mem-size="16">
+				<array2D dim1="2" dim2="2" format="real"/>
+			</Volatile-Register>
+        <Volatile-Register name="RW_dt" generateFesaValueItem="true" fesaFieldName="RW_dt_fesa" size="8" address="440" mem-size="32">
+				<array2D dim1="2" dim2="2" format="dt"/>
+			</Volatile-Register>
+      </Setting-Block>
+      <Command-Block name="MyWOBlock" size="530" address="590" mem-size="1180">
+        <Setting-Register name="WO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="10">
+				<array dim="10" format="int8"/>
+			</Setting-Register>
+        <Setting-Register name="WO_uint8" generateFesaValueItem="true" fesaFieldName="WO_uint8_fesa" size="1" address="10" mem-size="10">
+				<array dim="10" format="uint8"/>
+			</Setting-Register>
+        <Setting-Register name="WO_int16" generateFesaValueItem="true" fesaFieldName="WO_int16_fesa" size="2" address="20" mem-size="20">
+				<array dim="10" format="int16"/>
+			</Setting-Register>
+        <Setting-Register name="WO_uint16" generateFesaValueItem="true" fesaFieldName="WO_uint16_fesa" size="2" address="40" mem-size="20">
+				<array dim="10" format="uint16"/>
+			</Setting-Register>
+        <Setting-Register name="WO_int32" generateFesaValueItem="true" fesaFieldName="WO_int32_fesa" size="4" address="60" mem-size="40">
+				<array dim="10" format="int32"/>
+			</Setting-Register>
+        <Setting-Register name="WO_uint32" generateFesaValueItem="true" fesaFieldName="WO_uint32_fesa" size="4" address="100" mem-size="40">
+				<array dim="10" format="uint32"/>
+			</Setting-Register>
+        <Setting-Register name="WO_float32" generateFesaValueItem="true" fesaFieldName="WO_float32_fesa" size="4" address="140" mem-size="40">
+				<array dim="10" format="float32"/>
+			</Setting-Register>
+        <Setting-Register name="WO_string" generateFesaValueItem="true" fesaFieldName="WO_string_fesa" size="1" address="180" mem-size="660">
+				<stringArray dim="10" string-length="64" format="string"/>
+			</Setting-Register>
+        <Setting-Register name="WO_date" generateFesaValueItem="true" fesaFieldName="WO_date_fesa" size="8" address="840" mem-size="80">
+				<array dim="10" format="date"/>
+			</Setting-Register>
+        <Setting-Register name="WO_char" generateFesaValueItem="true" fesaFieldName="WO_char_fesa" size="1" address="920" mem-size="10">
+				<array dim="10" format="char"/>
+			</Setting-Register>
+        <Setting-Register name="WO_byte" generateFesaValueItem="true" fesaFieldName="WO_byte_fesa" size="1" address="930" mem-size="10">
+				<array dim="10" format="byte"/>
+			</Setting-Register>
+        <Setting-Register name="WO_word" generateFesaValueItem="true" fesaFieldName="WO_word_fesa" size="2" address="940" mem-size="20">
+				<array dim="10" format="word"/>
+			</Setting-Register>
+        <Setting-Register name="WO_dword" generateFesaValueItem="true" fesaFieldName="WO_dword_fesa" size="4" address="960" mem-size="40">
+				<array dim="10" format="dword"/>
+			</Setting-Register>
+        <Setting-Register name="WO_int" generateFesaValueItem="true" fesaFieldName="WO_int_fesa" size="2" address="1000" mem-size="20">
+				<array dim="10" format="int"/>
+			</Setting-Register>
+        <Setting-Register name="WO_dint" generateFesaValueItem="true" fesaFieldName="WO_dint_fesa" size="4" address="1020" mem-size="40">
+				<array dim="10" format="dint"/>
+			</Setting-Register>
+        <Setting-Register name="WO_real" generateFesaValueItem="true" fesaFieldName="WO_real_fesa" size="4" address="1060" mem-size="40">
+				<array dim="10" format="real"/>
+			</Setting-Register>
+        <Setting-Register name="WO_dt" generateFesaValueItem="true" fesaFieldName="WO_dt_fesa" size="8" address="1100" mem-size="80">
+				<array dim="10" format="dt"/>
+			</Setting-Register>
+      </Command-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/SilecsHeader_1.0.0.h b/silecs-codegen/src/xml/test/generated_correct/controller/SilecsHeader_1.0.0.h
new file mode 100644
index 0000000000000000000000000000000000000000..3449b46362d02fe17c48fc5c06133252c6ea2daf
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/SilecsHeader_1.0.0.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(0XFFE06812);
+        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_correct/controller/Virtual_SiemensBlock.AllTypes.h b/silecs-codegen/src/xml/test/generated_correct/controller/Virtual_SiemensBlock.AllTypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..20575358570ca5090c7998c15c3e0c4673cab700
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/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 48; }
+
+	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 284; }
+
+	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 1228; }
+
+	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_correct/controller/Virtual_SiemensBlock.SilecsHeader.h b/silecs-codegen/src/xml/test/generated_correct/controller/Virtual_SiemensBlock.SilecsHeader.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6929715548326dafede84de2ed0143fba5f4dae
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/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(0XFFE06812);
+		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_correct/controller/Virtual_SiemensBlock.cpp b/silecs-codegen/src/xml/test/generated_correct/controller/Virtual_SiemensBlock.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d7e2a30372df7923ad5c8667bbdf45c9d043942e
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/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_correct/controller/Virtual_SiemensBlock.h b/silecs-codegen/src/xml/test/generated_correct/controller/Virtual_SiemensBlock.h
new file mode 100644
index 0000000000000000000000000000000000000000..819405bef1b250069e55be5edebff102efa37f28
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/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_correct/controller/Virtual_SiemensBlock_0.1.0.cpp b/silecs-codegen/src/xml/test/generated_correct/controller/Virtual_SiemensBlock_0.1.0.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8bd839e19b919295b634cfc9b42b2b9968b746f4
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Virtual_SiemensBlock_0.1.0.cpp
@@ -0,0 +1,33 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cstring>
+#include <iostream>
+
+#include <silecs-virtual-controller/core/SilecsSnap7Server.h>
+#include "AllTypesDU_0.1.0.h"
+
+class UserSnap7Server : public SilecsServer::SilecsSnap7Server
+{
+public:
+    UserSnap7Server(AllTypesDU_0_1_0::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[])
+{
+    AllTypesDU_0_1_0::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_correct/controller/Virtual_SiemensDevice.AllTypes.h b/silecs-codegen/src/xml/test/generated_correct/controller/Virtual_SiemensDevice.AllTypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..3883554cce81e731ece7cea9a4b17f7aacad908f
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/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_correct/controller/Virtual_SiemensDevice.SilecsHeader.h b/silecs-codegen/src/xml/test/generated_correct/controller/Virtual_SiemensDevice.SilecsHeader.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6929715548326dafede84de2ed0143fba5f4dae
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/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(0XFFE06812);
+		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_correct/controller/Virtual_SiemensDevice.cpp b/silecs-codegen/src/xml/test/generated_correct/controller/Virtual_SiemensDevice.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..43c22864b768a82ba2ad177475d15288ad6e606a
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/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_correct/controller/Virtual_SiemensDevice.h b/silecs-codegen/src/xml/test/generated_correct/controller/Virtual_SiemensDevice.h
new file mode 100644
index 0000000000000000000000000000000000000000..1827c94a58cd3d50d26a1f866c1c11978e3ccfb0
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/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_correct/controller/Virtual_SiemensDevice_0.1.0.cpp b/silecs-codegen/src/xml/test/generated_correct/controller/Virtual_SiemensDevice_0.1.0.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8bd839e19b919295b634cfc9b42b2b9968b746f4
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Virtual_SiemensDevice_0.1.0.cpp
@@ -0,0 +1,33 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cstring>
+#include <iostream>
+
+#include <silecs-virtual-controller/core/SilecsSnap7Server.h>
+#include "AllTypesDU_0.1.0.h"
+
+class UserSnap7Server : public SilecsServer::SilecsSnap7Server
+{
+public:
+    UserSnap7Server(AllTypesDU_0_1_0::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[])
+{
+    AllTypesDU_0_1_0::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;
+}