diff --git a/silecs-codegen/src/xml/Mapping.py b/silecs-codegen/src/xml/Mapping.py
new file mode 100644
index 0000000000000000000000000000000000000000..29a6ee4df7f8533a65be35e5c024689092d94be0
--- /dev/null
+++ b/silecs-codegen/src/xml/Mapping.py
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+# Copyright 2016 CERN and GSI
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+global MEM_TYPE
+global DI_TYPE
+global DO_TYPE
+global AI_TYPE
+global AO_TYPE
+global mappin2String
+
+MEM_TYPE = 0
+DI_TYPE = 1
+DO_TYPE = 2
+AI_TYPE = 3
+AO_TYPE = 4
+    
+mappingType2String =  { MEM_TYPE: "MEM", DI_TYPE: "DI", DO_TYPE: "DO", AI_TYPE: "AI", AO_TYPE: "AO" }
+
+class Mapping(object):
+    def __init__(self,controllerAddress, type):
+        self.classBaseAddress    = controllerAddress  # 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.usedData             = ""  # data size summary per class and per area type#
+        self.instanceAddress     = -1  # start-address of the device data
+        self.isDefined = False  # True if the object related base-address has been defined
+        self.type = type               # mapping-type (MEM, DI, DO,AI,AO )
+        self.blockDataSize   = 0
+        self.blockAddress    = 0
+        
+        if controllerAddress != -1:
+            self.instanceAddress     = 0
+            self.isDefined = True
+            
+    def clearInstanceAddressIfDefined(self):
+        if self.isDefined:
+            self.instanceAddress     = 0
\ No newline at end of file
diff --git a/silecs-codegen/src/xml/genparam.py b/silecs-codegen/src/xml/genparam.py
index d4e2c49e48739fc6b56506105bdb8a15492dc49a..236fc5f8a190901ff4017f10eee8da033f55487b 100644
--- a/silecs-codegen/src/xml/genparam.py
+++ b/silecs-codegen/src/xml/genparam.py
@@ -27,6 +27,7 @@ import xmltemplate
 import iefiles
 
 from iecommon import *
+from Mapping import *
 from model.Class.Register import *
 from model.Class.Block import *
 from model.Class.Class import *
@@ -35,28 +36,6 @@ 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
-blockDataSize              = 0 # my $blockMemSize = 0; in the former PERL script
-blockAddress                 = 0 # my $blockAddress = 0; in the former PERL script
-plcSize                 = 0
-plcLast                 = 0
-instAddr                = 0 
-
-blockCounter            = 0 # used for NI block address generation
-regCounter              = 0 # used for NI register address generation
-
-
 #-------------------------------------------------------------------------
 # Trimming: remove new-line, tabulation and spaces of the string
 # Used to compute CRC32 on significant data only
@@ -68,395 +47,10 @@ def trim (str):
     str = str.replace('\n', '')
     return str
 
-#-------------------------------------------------------------------------
-# Return the highest bit-alignment of the given address
-def whichDataAlignment(value):
-    if (value % 2 != 0): return 8
-    if (value % 4 != 0): return 16
-    if (value % 8 != 0): return 32
-    return 64
-
-
-#-------------------------------------------------------------------------
-# DATA ALIGNMENT depends on different conditions: PLC brand, model and also
-# depends on type of data structure (scalar or array)
-# These methods are used to compute the correct address of each register respecting
-# this conditions.
-# Attention!! $addr is the relative address of the register within the block including
-# this alignment while $msize is still the useful memory of the data which does not include
-# memory spaces because of alignment shifts of the following variables if any.
-# This remark is not true for the block mem-size which naturally includes the alignment spaces.
-#
-
-# Adjust the register address relying on the SCHNEIDER Premium/Quantum alignment constraints
-# Unity Premium/Quantum is 16bits processor and base-address is interpreted as 16bit address
-# Byte elements of array (including STRING) use 8bit alignment.
-def alignPremiumRegAddress(addr, format, size, dim, dim2, strLen):
-    global msize
-
-    # internal string/unicode to integer cast
-    size = int(size)
-    addr = int(addr)
-    dim = int(dim)
-    dim2 = int(dim2)
-    strLen = int(strLen)
-    
-    algnt  = 16
-    while(whichDataAlignment(addr) < algnt):
-        addr+=1
-    msize = dim * dim2 * strLen * size    #compute memory data size
-    if (format in ['int8', 'char']):   #8bit signed type use word alignment (16bit)
-        msize = msize * 2            # while string and uint8-array use 8bit alignment
-    return addr
-    
-# Adjust the register address relying on the SCHNEIDER M340 alignment constraints
-# Unity M340 is 32bits processor but base-address is interpreted as 16bit address (required even address in the mapping)
-# 32bits alignment except for 8/16bits (16bits alignment)
-# Byte elements of array (including STRING) use 8bit alignment.
-def alignM340RegAddress(addr, format, size, dim, dim2, strLen):
-    global msize
-    
-    # internal string/unicode to integer cast
-    size = int(size)
-    addr = int(addr)
-    dim = int(dim)
-    dim2 = int(dim2)
-    strLen = int(strLen)
-    
-    algnt  = 16
-    if (size > 2):
-        algnt = 32
-    while(whichDataAlignment(addr) < algnt):
-        addr+=1
-    msize = dim * dim2 * strLen * size    #compute memory data size
-    if (format in ['int8', 'char']):   #8bit signed type use word alignment (16bit)
-        msize = msize * 2            # while string and uint8-array use 8bit alignment
-    return addr
-    
-# Adjust the register address relying on the DIGI-Rabbit RCMx alignment constraints
-# Use  16bits processor and base-address is interpreted as 16bit address
-def alignDIGIRegAddress(addr, format, size, dim, dim2, strLen):
-    global msize
-
-    # internal string/unicode to integer cast
-    size = int(size)
-    addr = int(addr)
-    dim = int(dim)
-    dim2 = int(dim2)
-    strLen = int(strLen)
-    
-    algnt  = 16
-    while(whichDataAlignment(addr) < algnt):
-        addr+=1
-    msize = dim * dim2 * strLen * size    #compute memory data size
-    if (format != 'string'):                       
-        if (size == 1):                   #but it's a 8bit type
-            msize = msize * 2        #so, it's a word alignment (only string use byte alignment)
-    return addr
-
-def alignCNVRegAddress(addr, format, size, dim, dim2, strLen):
-    global regCounter
-    return regCounter
-
-# Adjust the register relying on the SIEMENS Simatic alignment constraints
-# 8bits alignment except for array and >8bits data (16bits alignment)
-# In case of string, its length has to be +2 to hold info on string
-def alignSimaticRegAddress(addr, format, size, dim, dim2, strLen):
-    global msize
-    
-    # internal string/unicode to integer cast
-    size = int(size)
-    addr = int(addr)
-    dim = int(dim)
-    dim2 = int(dim2)
-    strLen = int(strLen)
-        
-    algnt  = 8
-    if ((size > 1) | (dim > 1) | (dim2 > 1) | (strLen > 1)):
-        algnt = 16
-    while(whichDataAlignment(addr) < algnt):
-        addr+=1
-    if strLen > 1:                          # register is a string, 
-        if ((strLen % 2) != 0): strLen+=1   #adjusts the global size for byte type (word alignment)
-        strLen+=2   #add increment to strLen first two bytes for info on string (len, maxlen)
-          
-    msize = dim * dim2 * strLen * size      #compute memory data size
-    return addr
-
-# Adjust the register address relying on the BECKHOFF Twincat BC9020 alignment constraints.
-# TwinCAT BCxx PLCs are 16bits processor and base-address is interpreted as 16bit address
-# 8bits alignment between elements of 8bit-data array (including strings).
-# In case of string, its length has to be +1 to hold end-terminator.
-def alignBCxxRegAddress(addr, format, size, dim, dim2, strLen):
-    global msize
-
-    # internal string/unicode to integer cast
-    size = int(size)
-    addr = int(addr)
-    dim = int(dim)
-    dim2 = int(dim2)
-    strLen = int(strLen)
-    
-    algnt  = 16
-    while(whichDataAlignment(addr) < algnt):
-        addr+=1
-        
-    if strLen > 1:          # register is a string, 
-        strLen += 1       #TwinCAT  requires  '\0' string terminator.                             
-    
-    msize = dim * dim2 * strLen * size    #compute memory data size
-    return addr
-
-# Adjust the register address relying on the BECKHOFF Twincat CX9020 alignment constraints.
-# TwinCAT CXxx PLCs are 32bits processor but base-address is interpreted as 16bit address (required even address in the mapping)
-# 32bits alignment except for 8/16bits (16bits alignment).
-# 8bits alignment between elements of 8bit-data array (including strings).
-# In case of string, its length has to be +1 to hold end-terminator.
-def alignCXxxRegAddress(addr, format, size, dim, dim2, strLen):
-    global msize
-    
-    # internal string/unicode to integer cast
-    size = int(size)
-    addr = int(addr)
-    dim = int(dim)
-    dim2 = int(dim2)
-    strLen = int(strLen)
-    
-    algnt  = 16
-    if (size > 2):
-        algnt = 32
-    while(whichDataAlignment(addr) < algnt):
-        addr+=1
-        
-    if strLen > 1:          # register is a string, 
-        strLen += 1       #TwinCAT  requires  '\0' string terminator.
-                                     
-    msize = dim * dim2 * strLen * size    #compute memory data size
-    return addr
-    
-#block-address = block DB-Number
-def computeSiemensBlockBlkAddress(regAddr, classAddr, nbDev):
-    #Compute block mem-size at first: each block has a dedicated DB-number which contains an array of devices
-    #each element of the array is a structure which must be 16bits aligned!
-    global blockDataSize
-    global plcModel
-    global blockAddress
-    
-    # internal string/unicode to integer cast
-    regAddr = int(regAddr)
-    classAddr = int(classAddr)
-    nbDev = int(nbDev)
-    
-    nextBlockAddr = regAddr
-    algnt = whichBaseAlignment[plcModel]    #get the base struct-alignment of that PLC (16bit here)
-    # then adjust the next block-address by respecting this base-alignment.
-    while(int(whichDataAlignment(nextBlockAddr)) < int(algnt)):
-        nextBlockAddr+=1
-    blockDataSize = nextBlockAddr
-    # then compute the next block DB-number and return the current one
-    tmpblockAddress = blockAddress    
-    blockAddress = blockAddress + 1
-
-    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 blockDataSize
-    global plcModel
-    global blockAddress
-    
-    # internal string/unicode to integer cast
-    regAddr = int(regAddr)
-    classAddr = int(classAddr)
-    nbDev = int(nbDev)
-
-    nextBlockAddr = regAddr
-    algnt  = whichBaseAlignment[plcModel]   #get the base struct-alignment of that PLC (16bit here)
-    #then adjust the next block-address by respecting this base-alignment.                          
-    while(int(whichDataAlignment(nextBlockAddr)) < int(algnt)):
-        nextBlockAddr+=1
-    blockDataSize = nextBlockAddr
-    #then compute the next block DB-number and return the current one
-    tmpblockAddress = blockAddress
-    blockAddress = blockAddress + blockDataSize
-    return tmpblockAddress
-    
-    
-# Block-address = absolute address in the PLC memory
-def computeSchneiderBlockBlkAddress(regAddr, classAddr, nbDev):
-    global blockDataSize
-    global plcModel
-    global blockAddress
-
-    # Internal string/unicode to integer cast
-    regAddr = int(regAddr)
-    classAddr = int(classAddr)
-    nbDev = int(nbDev)
-
-    # Compute block mem-size at first:
-    # It corresponds to the next potential address that is 16bits or 32bits with SCHNEIDER.
-    nextBlockAddr = regAddr
-    
-    # Each data-block for each class and device will be aligned on the worst-case alignment
-    # of the given PLC. This logic allows having a unique address computing whatever the mode (DEVICE/BLOCK)
-    # and the PLC model (16bits or 32bits).
-    algnt  = whichBaseAlignment[plcModel] # get the "worst-case" base-alignment of that PLC
-    #then adjust the next block-address by respecting this base-alignment.                          
-    while(whichDataAlignment(nextBlockAddr) < int(algnt)):
-        nextBlockAddr+=1
-    blockDataSize = nextBlockAddr  
-    # then compute the next block DB-number and return the current one
-    tmpblockAddress = blockAddress   
-    # next absolute address: relies on the global class-address
-    blockAddress = blockAddress + (nbDev * blockDataSize)
-    return classAddr + tmpblockAddress
-    
-    
-# Block-address = offset in the device memory
-def computeSchneiderDeviceBlkAddress(regAddr, classAddr, nbDev):
-    global blockDataSize
-    global plcModel
-    global blockAddress
-        
-    # internal string/unicode to integer cast
-    regAddr = int(regAddr)
-    classAddr = int(classAddr)
-    nbDev = int(nbDev)
-    
-    #Compute block mem-size at first:
-    #it corresponds to the next potential address that is 16bits or 32bits with SCHNEIDER.
-    nextBlockAddr = regAddr
-    #Each data-block for each class and device will be aligned on the worst-case alignment
-    #of the given PLC. This logic allows having a unique adress computing whatever the mode (DEVICE/BLOCK)
-    #and the PLC model (16bits or 32bits).
-    algnt  = whichBaseAlignment[plcModel] #get the "worst-case" base-alignment of that PLC
-    #then adjust the next block-address by respecting this base-alignment.          
-    while(whichDataAlignment(nextBlockAddr) < int(algnt)):
-        nextBlockAddr+=1
-    blockDataSize = nextBlockAddr
-    #then compute the next block DB-number and return the current one
-    tmpblockAddress = blockAddress   
-    #next relative address: independent from the global class-address
-    blockAddress = blockAddress + blockDataSize
-    return tmpblockAddress
-    
-def computeNiDeviceBlkAddress(regAddr, classAddr, nbDev):
-    global blockCounter
-    blockCounter = blockCounter + 1
-    return blockCounter
-
-#-------------------------------------------------------------------------
-# Compute the next register address relying on the data start-address and size.
-def computeAnyNextRegAddress(brand, addr, dim, dim2=1):
-    global msize
-    
-    # internal string/unicode to integer cast
-    addr = int(addr)
-    dim = int (dim)
-    dim2 = int(dim2)
-    
-    addr = addr + msize;    #compute the next address for any case
-    if (brand == 'SIEMENS'):
-        # SIEMENS requires specific treatment in case of array.
-        if ((dim > 1) | (dim2 > 1)):
-            #SIEMENS array is always followed by 16bits adressing
-            algnt = 16
-            while(whichDataAlignment(addr) < algnt):
-                addr+=1
-    elif (brand == 'NI'):
-        msize = 0
-    return addr
-
-
-#-------------------------------------------------------------------------
-def computeAnyBlockInstAddress(classAddr, devSize):
-    global instAddr
-    tmpInstAddr = instAddr
-    instAddr = instAddr + 1     #device-index
-    return tmpInstAddr
-
-def computeSiemensDeviceInstAddress(classAddr, devSize):
-    global instAddr 
-    tmpInstAddr = instAddr
-    instAddr = instAddr + 1     #device DB-number
-    return tmpInstAddr + classAddr
-
-def computeSchneiderDeviceInstAddress(classAddr, devSize):
-    global instAddr
-    tmpInstAddr = instAddr
-    instAddr = instAddr + devSize #absolute address
-    return tmpInstAddr + classAddr
-
-def computeNiDeviceInstAddress(classAddr, devSize):
-    return 0
-#-------------------------------------------------------------------------
-# Compute the base DB-number of the next class in the SIEMENS PLC memory
-# BLOCK mode requires 1 DB per class block
-def computeSiemensBlockNextBaseAddress(mapping, nbDev):
-    global plcLast
-    global plcSize
-
-    # internal string/unicode to integer cast
-    classAddr   = int(mapping.classBaseAddress)
-    nbBlk       = int(mapping.nbBlock)
-    devSize     = int(mapping.deviceDataSize)
-    nbDev       = int(nbDev)
-    
-    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
-    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(mapping, nbDev):
-    global plcLast
-    global plcSize
-    
-    # internal string/unicode to integer cast
-    classAddr   = int(mapping.classBaseAddress)
-    nbBlk       = int(mapping.nbBlock)
-    devSize     = int(mapping.deviceDataSize)
-    nbDev       = int(nbDev)
-    
-    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
-    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(mapping, nbDev):
-    global plcLast
-    global plcSize
-    
-    # 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
-    mapping.usedMem = "MW%d..MW%d / %d words"%(startAddr,plcLast,wordSize);
-    return (classAddr + (wordSize * 2))     #next word address expressed in bytes
-
-def computeNiAnyNextBaseAddress(mapping, nbDev):
-    return 0
-
 def computeChecksumController( workspacePath, deploy, controller, silecsVersion, funcGetSilecsDesignFilePath,  logTopics={'errorlog': True}):
     majorSilecsVersion = iecommon.getMajorSilecsVersion(silecsVersion)
     CRC32 = zlib.crc32(trim(str(majorSilecsVersion)),0)& 0xffffffff
-    CRC32 = zlib.crc32(trim(str(controller.baseAddress)),CRC32)& 0xffffffff
+    CRC32 = zlib.crc32(trim(str(controller.address[MEM_TYPE])),CRC32)& 0xffffffff
     for silecsDesign in deploy.silecsDesigns:
         devices = controller.getDevicesOfDesign(silecsDesign.name)
         if len(devices) > 0:
@@ -479,129 +73,10 @@ 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
     
-
-# The following constant are used to align the address of a device block {set of registers}.
-# With SCHNEIDER PLC, block is aligned depending on his 'worst-case' alignement {16bits or 32bits}.
-# This logic allows having a unique adress computing whatever the mode {DEVICE/BLOCK} and the PLC model.
-# Concerning SIEMENS PLC, block alignment should respect the 16bits alignement constraint for Struct&Array.
-whichBaseAlignment = {
-    'SIMATIC_S7-300'    : '16',
-    'SIMATIC_S7-400'    : '16',
-    'SIMATIC_S7-1200'   : '16',
-    'SIMATIC_S7-1500'   : '16',
-    'SIMATIC_ET-200S'   : '16',
-    'SIMATIC_S7-VIRTUAL': '16',
-    'Premium'           : '16',
-    'Quantum'           : '16',
-    'M340'              : '32',     # any data-block of M340 model will start on 32bits address
-                                  # even if the first register of the block is a 16bit data.
-    'Rabbit_RCM_4010' : '16',
-    'Rabbit_RCM_2000' : '16',
-    'BC9020'          : '16',
-    'CX9020'          : '32',
-    'BK9000'          : '16',
-    'BK9050'          : '16',
-    'BK9100'          : '16'
-}
-
-whichDataSize = {
-    'uint8'       : '1',
-    'int8'        : '1',
-    'uint16'      : '2',
-    'int16'       : '2',
-    'uint32'      : '4',
-    'int32'       : '4',
-    'float32'     : '4',
-    'uint64'      : '8',
-    'int64'       : '8',
-    'float64'     : '8',
-    'string'      : '1',
-    'date'        : '8',
-    # deprecated formats
-    'char'        : '1',
-    'byte'        : '1',
-    'word'        : '2',
-    'dword'       : '4',
-    'int'         : '2',
-    'dint'        : '4',
-    'real'        : '4',
-    'dt'          : '8'
-}
-
-whichRegAddressFunction = {
-    'SIMATIC_S7-300'          : alignSimaticRegAddress,
-    'SIMATIC_S7-400'          : alignSimaticRegAddress,
-    'SIMATIC_S7-1200'         : alignSimaticRegAddress,
-    'SIMATIC_S7-1500'         : alignSimaticRegAddress,
-    'SIMATIC_ET-200S'         : alignSimaticRegAddress,
-    'SIMATIC_S7-VIRTUAL'      : alignSimaticRegAddress,
-    'Premium'                 : alignPremiumRegAddress,
-    'Quantum'                 : alignPremiumRegAddress,
-    'M340'                    : alignM340RegAddress,
-    'Compact_RIO'             : alignCNVRegAddress,
-    'PXI_RT'                  : alignCNVRegAddress,
-    'PXI_Windows'             : alignCNVRegAddress,
-    'PC_Windows'              : alignCNVRegAddress,
-    'Other_Support_CNV'       : alignCNVRegAddress,
-    'Rabbit_RCM_4010'         : alignDIGIRegAddress,
-    'Rabbit_RCM_2000'         : alignDIGIRegAddress,
-    'BC9020'                  : alignBCxxRegAddress,
-    'CX9020'                  : alignCXxxRegAddress,
-    'BK9000'                  : alignPremiumRegAddress,
-    'BK9050'                  : alignPremiumRegAddress,
-    'BK9100'                  : alignPremiumRegAddress
-}
-
-whichBlkAddressFunction = {
-    'SIEMENS'+'BLOCK_MODE'        : computeSiemensBlockBlkAddress,
-    'SIEMENS'+'DEVICE_MODE'       : computeSiemensDeviceBlkAddress,
-    'SCHNEIDER'+'BLOCK_MODE'    : computeSchneiderBlockBlkAddress,
-    'SCHNEIDER'+'DEVICE_MODE'   : computeSchneiderDeviceBlkAddress,
-    'NI'+'DEVICE_MODE'                  : computeNiDeviceBlkAddress,
-    'DIGI'+'BLOCK_MODE'           : computeSchneiderBlockBlkAddress,
-    'DIGI'+'DEVICE_MODE'          : computeSchneiderDeviceBlkAddress,
-    'BECKHOFF'+'BLOCK_MODE'      : computeSchneiderBlockBlkAddress
-}
-
-whichInstAddressFunction = {
-    'SIEMENS'+'BLOCK_MODE'         : computeAnyBlockInstAddress,
-    'SIEMENS'+'DEVICE_MODE'        : computeSiemensDeviceInstAddress,
-    'SCHNEIDER'+'BLOCK_MODE'    : computeAnyBlockInstAddress,
-    'SCHNEIDER'+'DEVICE_MODE'   : computeSchneiderDeviceInstAddress,
-    'NI'+'DEVICE_MODE'                  : computeNiDeviceInstAddress,
-    'DIGI'+'BLOCK_MODE'           : computeAnyBlockInstAddress,
-    'DIGI'+'DEVICE_MODE'          : computeSchneiderDeviceInstAddress,
-    'BECKHOFF'+'BLOCK_MODE'      : computeAnyBlockInstAddress
-}
-
-whichBaseAddressFunction = {
-    'SIEMENS'+'BLOCK_MODE'         : computeSiemensBlockNextBaseAddress,
-    'SIEMENS'+'DEVICE_MODE'        : computeSiemensDeviceNextBaseAddress,
-    'SCHNEIDER'+'BLOCK_MODE'     : computeSchneiderAnyNextBaseAddress,
-    'SCHNEIDER'+'DEVICE_MODE'    : computeSchneiderAnyNextBaseAddress,
-    'NI'+'DEVICE_MODE'                   : computeNiAnyNextBaseAddress,
-    'DIGI'+'BLOCK_MODE'            : computeSchneiderAnyNextBaseAddress,
-    'DIGI'+'DEVICE_MODE'           : computeSchneiderAnyNextBaseAddress,
-    'BECKHOFF'+'BLOCK_MODE'       : computeSchneiderAnyNextBaseAddress
-}
-
 # Needed to encapsulate "genParam" in order to allow unit-testing (fake all file interactions)
 def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSilecsDeployFilePath,  funcGetParameterFileDirectory, workspacePath, deployName, deployVersion, silecsVersion, logTopics={'debuglog': True}):
-    # Global variable links
-    global plcModel, plcSize, plcLast
-    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)):
@@ -618,8 +93,10 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile
         iecommon.logDebug("create directory %s" %paramPath,logTopics)
     
     for controller in deploy.controllers:
-        mapping = Mapping(controller.baseAddress)
-        plcModel = controller.model
+        mappings = { MEM_TYPE: None, DI_TYPE: None, DO_TYPE: None, AI_TYPE: None, AO_TYPE: None }
+        for mappingType, mapping in  mappings.iteritems():
+            mappings[mappingType] = Mapping(controller.address[mappingType], mappingType)
+        
         # Messagges for debugging purpose
         iecommon.logDebug("------ XML extracted informations ------",logTopics)
         iecommon.logDebug("owner = " + deploy.owner,logTopics)
@@ -627,7 +104,8 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile
         iecommon.logDebug("plcModel = " + controller.model,logTopics)
         iecommon.logDebug("plcBrand = " + controller.brand,logTopics)
         iecommon.logDebug("plcProtocol = " + controller.protocol,logTopics)
-        iecommon.logDebug("PLCbaseAddress = %d" %controller.baseAddress,logTopics)
+        for mappingType, mapping in  mappings.iteritems():
+            iecommon.logDebug("address" + mappingType2String[mappingType] + " = " + str(controller.address[mappingType]),logTopics)
 
         paramFile = funcGetParameterFile(workspacePath, deployName, controller.hostName )
         iecommon.logInfo("Generate xml for parameters file: " + paramFile,logTopics)
@@ -651,17 +129,13 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile
             paramClass = ParamClass()
             paramClass.initWithDesignClass(designClass)
             param.controller.addParamClass(paramClass)
-            
-            #-------------------------------------------------------------------------
-            # Generate section <Block></Block>
-            #-------------------------------------------------------------------------
-            blockCounter = 0
-            
-            blockAddress = 0                 # memory address of the block (using byte addressing)
-            mapping.nbBlock = 0             # number of block of the class
+            controller.blockCounter = 0
+            for mappingType, mapping in mappings.iteritems():
+                mapping.blockAddress = 0
+                mapping.nbBlock = 0
+                mapping.deviceDataSize = 0
+                mapping.clearInstanceAddressIfDefined()
 
-            computeBlkAddress = whichBlkAddressFunction[controller.brand + controller.protocol]
-            
             # INNER LOOP TO ACCESS AT BLOCK LEVEL
             for designBlock in designClass.getDesignBlocks():
                 paramBlock = ParamBlock()
@@ -672,18 +146,12 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile
                 regAddress = 0      # memory address of the register (using byte addressing)
                 blockSize = 0           # block size (sum of the register size)
                 blockMemSize = 0    # block size (sum of the regist)
-                instAddr = 0                # initial class address BUG FIXED
-                regCounter = 0      # used for NI register address generation
-                alignRegAddress     = whichRegAddressFunction [controller.model]
-        
-                #-------------------------------------------------------------------------
-                # Generate section <Register></Register>
-                #-------------------------------------------------------------------------
+                controller.regCounter = 0      # used for NI register address generation
                 # INNER LOOP TO ACCESS AT REGISTER LEVEL
                 for designRegister in designBlock.getDesignRegisters():
                     iecommon.logDebug("------ Processing Register " + designRegister.name + " ------",logTopics)
                     # Set length attribute only for string registers
-                    if designRegister.format == 'string':
+                    if designRegister.format == 'string': # TODO: Port this constraint to java
                         if controller.brand == 'DIGI':
                             # RABBIT has 8bit memory alignment but uses 16bit word communication protocol (MODBUS).
                             # String buffer (8bit elements) must have even number of bytes.
@@ -691,59 +159,56 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile
                                 iecommon.logError("String length of %s designRegister must be an even value." %designRegister.name, False,logTopics)
                                 sys.exit(2)
                     
-                    # Set register size
-                    regSize = whichDataSize[designRegister.format]
-                    # Set register address
-                    regAddress = alignRegAddress(regAddress, designRegister.format, regSize, designRegister.dim1, designRegister.dim2, designRegister.stringLength)
-                    regCounter = regCounter + 1 # used for NI register address generation
+                    regAddress = controller.alignRegAddress(designBlock, designRegister, regAddress)
+                    controller.regCounter += 1 # used for NI register address generation
                     # Set register mem-size
                     paramRegister = ParamRegister()
-                    paramRegister.initWithDesignRegister(designRegister,regSize,regAddress,msize)
+                    paramRegister.initWithDesignRegister(designRegister,regAddress,controller.msize)
                     # Compute address for the next register
-                    regAddress = computeAnyNextRegAddress(controller.brand, regAddress, designRegister.dim1, designRegister.dim2)
+                    regAddress = controller.computeNextRegAddress(designBlock, designRegister, regAddress)
                     paramBlock.xmlNode.addChild(paramRegister.xmlNode)
                     #paramRegister.xmlNode.shellPrintNode()
                     #iterativelly compute the block size (accumulator initialized outside the loop)
-                    blockSize = blockSize + (int(regSize) * designRegister.dim1 * designRegister.dim2)
+                    blockSize = blockSize + (paramRegister.size * paramRegister.dim1 * paramRegister.dim2)
                 # END OF INNER LOOP TO ACCESS AT REGISTER LEVEL
 
                 paramBlock.setSize(blockSize)
-                paramBlock.setAddress(computeBlkAddress(regAddress, int(mapping.classBaseAddress),nbDevice))
-                paramBlock.setMemSize(blockDataSize)
-                # Append block
+                
+                blockSpecificMapping = mappings[paramBlock.type]    
+                paramBlock.setAddress(controller.computeBlkAddress(paramBlock,blockSpecificMapping, regAddress,nbDevice))
+                paramBlock.setMemSize(blockSpecificMapping.blockDataSize)
                 paramClass.xmlNode.addChild(paramBlock.xmlNode)
-                # Count the number of devices
-                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(mapping.classBaseAddress)
+            for mappingType, mapping in mappings.iteritems():
+                paramClass.setAddress(mapping.classBaseAddress,mappingType)
             
-            computeInstAddress = whichInstAddressFunction[ controller.brand + controller.protocol ]
             for device in devices:
                 instance = libxml2.newNode("Instance")
                 instance.setProp("label", device.silecsDeviceLabel)
-                instance.setProp("address", str(computeInstAddress(mapping.classBaseAddress, mapping.deviceDataSize)))
+                instance.setProp("address", str(controller.computeInstAddress(mappings[MEM_TYPE])))
+                instance.setProp("DI-address", str(controller.computeInstAddress(mappings[DI_TYPE])))
+                instance.setProp("DO-address", str(controller.computeInstAddress(mappings[DO_TYPE])))
+                instance.setProp("AI-address", str(controller.computeInstAddress(mappings[AI_TYPE])))
+                instance.setProp("AO-address", str(controller.computeInstAddress(mappings[AO_TYPE])))
                 paramClass.xmlNode.addChild(instance)
 
             # Compute the memory address for the next class
-            computeBaseAddress = whichBaseAddressFunction [controller.brand + controller.protocol]
-            mapping.classBaseAddress = computeBaseAddress(mapping, nbDevice);
+            for mappingType, mapping in mappings.iteritems():
+                controller.computeNextBaseAddress(mapping, nbDevice);
             
-            # Set class used-memory
-            paramClass.setUsedMemory(mapping.usedMem)
-            iecommon.logInfo("Used-memory for Class " + deployDesign.name + ": " + mapping.usedMem ,logTopics)
+            for mappingType, mapping in mappings.iteritems():
+                paramClass.setUsedData(mapping.usedData,mappingType)
+                iecommon.logInfo("Used-"+ mappingType2String[mappingType] +" for Class " + deployDesign.name + ": " + mapping.usedData ,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"
+            plcUsedMem = "DB"+str(controller.address[MEM_TYPE])+"..DB"+str(controller.memLast)+" / "+str(controller.memSize)+" 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"
+            startAddr   = controller.address[MEM_TYPE] /2         #Memory info uses word-addressing
+            plcUsedMem  = "MW"+str(startAddr)+"..MW"+str(controller.memLast)+" / "+str(controller.memSize)+" words"
         
         # print plc used memory
         iecommon.logInfo("Used-memory for PLC " + deploy.name + ": "+str(plcUsedMem),logTopics)
diff --git a/silecs-codegen/src/xml/genplcsrc.py b/silecs-codegen/src/xml/genplcsrc.py
index ae8424d25800199d01284e19a7d7a3cdaa8f5cf2..479fb589ad127e2ff22bd4a52673905d3e2036b1 100644
--- a/silecs-codegen/src/xml/genplcsrc.py
+++ b/silecs-codegen/src/xml/genplcsrc.py
@@ -135,8 +135,8 @@ def generateSiemensSources(param, sourceFolderPath ,logTopics):
     symString = ''  # for .sdf Symbol file
 
     # Prepare the Simatic Symbols (<.sdf> file)
-    DBnumber    = param.controller.address       #first data-block (SilecsHeader) starts from the base-address
-    UDTnumber   = param.controller.address       #use base data-block address for UDT number as well (to be reserved by the developer)
+    DBnumber    = param.controller.address[MEM_TYPE]       #first data-block (SilecsHeader) starts from the base-address
+    UDTnumber   = param.controller.address[MEM_TYPE]       #use base data-block address for UDT number as well (to be reserved by the developer)
 
     # Generate sources for each class that is deployed in the PLC
     for paramClass in param.controller.paramClasses:
@@ -278,7 +278,7 @@ def generateSchneiderSources(param,sourceFolderPath,logTopics):
 # ----------------------------------------------------
 def generateDIGISources(param,sourceFolderPath,logTopics):
     deviceLabel = ''
-    cCodeString =  DIGITemplate.cHeader(param.silecsVersion, param.controller.address)
+    cCodeString =  DIGITemplate.cHeader(param.silecsVersion, param.controller.address[MEM_TYPE])
     cTypeDefinitions = ''
     cDataAllocation  = DIGITemplate.cAllocationComment(param.controller.protocol)
     
@@ -359,7 +359,7 @@ def generateVirtualS7Sources(param,sourceFolderPath,logTopics):
     protocolMode = 'BlockMode'; 
     if param.controller.protocol == 'DEVICE_MODE':
         protocolMode = 'DeviceMode'; 
-    duConstructor = virtualS7Template.vs7DuConstructor(param.deployName, param.deployVersion, protocolMode, param.controller.address)
+    duConstructor = virtualS7Template.vs7DuConstructor(param.deployName, param.deployVersion, protocolMode, param.controller.address[MEM_TYPE])
     
     for paramClass in param.controller.paramClasses:
         blocksCodeString = ''
@@ -466,9 +466,9 @@ def generateBeckhoffRegisters(param, paramClass, deviceDOM, block, deviceIndex,
         # Compute the register address relying on the Class Parameters file data
         # Attention! Beckhoff uses WORD addressing while Parameters data are expressed in bytes to be PLC independent
         if param.controller.model == 'BC9020':
-            totalAddress = (block.address - long(param.controller.address) + (deviceIndex * block.memSize) + register.address)/2
+            totalAddress = (block.address - long(param.controller.address[MEM_TYPE]) + (deviceIndex * block.memSize) + register.address)/2
         elif param.controller.model == 'CX9020':
-            totalAddress = (block.address - long(param.controller.address) + (deviceIndex * block.memSize) + register.address)
+            totalAddress = (block.address - long(param.controller.address[MEM_TYPE]) + (deviceIndex * block.memSize) + register.address)
         else:
             raise "PLC model not supported: " + param.controller.model
 
diff --git a/silecs-codegen/src/xml/model/Class/Block.py b/silecs-codegen/src/xml/model/Class/Block.py
index f5acb56c88d9759908fa98a058add7289e2353c6..df93b6f8d96e9fb78d8451ce48d892c7a472017f 100644
--- a/silecs-codegen/src/xml/model/Class/Block.py
+++ b/silecs-codegen/src/xml/model/Class/Block.py
@@ -16,16 +16,22 @@
 
 from iecommon import *
 from model.Class.Register import *
+from Mapping import *
 import libxml2
 
 
+class IOType(object):
+    ANALOG = "ANALOG-IO"
+    DIGITAL = "DIGITAL-IO"
+    MEMORY  = "MEMORY"
+    
 class Block(object):
 
-    ___settingBlockType = "Setting-Block"
-    ___acquisitionBlockType = "Acquisition-Block"
-    ___commandBlockType = "Command-Block"
-    ___settingIOBlockType = "Setting-IO-Block"
-    ___acquisitionIOBlockType = "Acquisition-IO-Block"
+    ___settingBlockName = "Setting-Block"
+    ___acquisitionBlockName = "Acquisition-Block"
+    ___commandBlockName = "Command-Block"
+    ___settingIOBlockName = "Setting-IO-Block"
+    ___acquisitionIOBlockName = "Acquisition-IO-Block"
     
     def __init__(self, xmlNode):
         self.xmlNode = xmlNode
@@ -33,36 +39,64 @@ class Block(object):
         self.name = xmlNode.prop("name")
         if xmlNode.hasProp("ioType"):
             self.ioType = xmlNode.prop("ioType") #only available on io-blocks
-        self.___type = xmlNode.get_name()
+        else:
+            self.ioType = IOType.MEMORY
+        self.___name = xmlNode.get_name()
+        self.type = None
+        if self.___name == self.___settingBlockName or self.___name == self.___acquisitionBlockName or self.___name == self.___commandBlockName:
+            self.type = MEM_TYPE
+        elif self.___name == self.___acquisitionIOBlockName and self.ioType == IOType.DIGITAL:
+            self.type = DI_TYPE
+        elif self.___name == self.___settingIOBlockName and self.ioType == IOType.DIGITAL:
+            self.type = DO_TYPE
+        elif self.___name == self.___acquisitionIOBlockName and self.ioType == IOType.ANALOG:
+            self.type = AI_TYPE
+        elif self.___name == self.___settingIOBlockName and self.ioType == IOType.ANALOG:
+            self.type = AO_TYPE
+        else:
+            raise Exception( "Cannot identify block-type of block:" + self.name )
                 #xmlNode.shellPrintNode()
 
     def getNameCapitalized(self):
         return  iecommon.capitalizeString(self.name)
     
     def isReadable(self):
-        return self.___type == self.___settingBlockType or self.___type == self.___acquisitionBlockType
+        return self.___name == self.___settingBlockName or self.___name == self.___acquisitionBlockName
     
     def isWritable(self):
-        return self.___type == self.___settingBlockType or self.___type == self.___commandBlockType
+        return self.___name == self.___settingBlockName or self.___name == self.___commandBlockName
 
     def isIOBlock(self):
-        return self.___type == self.___settingIOBlockType or self.___type == self.___acquisitionIOBlockType
+        return not self.isMEMBlock()
+    
+    def isMEMBlock(self):
+        return self.type == MEM_TYPE
+    
+    
+    def isAnanlogIO(self):
+        return self.ioType == IOType.ANALOG
+    
+    def isDigitalIO(self):
+        return self.ioType == IOType.DIGITAL
     
     def isAcquisition(self):
-        return self.___type == self.___acquisitionBlockType
+        return self.___name == self.___acquisitionBlockName or self.___name == self.___acquisitionIOBlockName
     
     def isSetting(self):
-        return self.___type == self.___settingBlockType
+        return self.___name == self.___settingBlockName or self.___name == self.___settingIOBlockName
     
     def isCommand(self):
-        return self.___type == self.___commandBlockType
+        return self.___name == self.___commandBlockName
     
-    def getRegisterNodes(self):
+    def getMEMRegisterNodes(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']")
     
+    def getRegisterNodes(self):
+        return self.getMEMRegisterNodes() + self.getIORegisterNodes()
+    
 #has some additionalValues
 class ParamBlock(Block):
     def __init__(self):
@@ -144,14 +178,17 @@ class DesignBlock(Block):
     def getFesaName(self):
         return self.fesaPropertyName
     
-    def getDesignRegisters(self):
+    def getDesignMEMRegisters(self):
         designRegisters = []
-        for registerNode in self.getRegisterNodes():
+        for registerNode in self.getMEMRegisterNodes():
             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
+            designIORegisters.append(DesignRegister(registerNode))
+        return designIORegisters
+    
+    def getDesignRegisters(self):
+        return self.getDesignMEMRegisters() + self.getDesignIORegisters()
diff --git a/silecs-codegen/src/xml/model/Class/Class.py b/silecs-codegen/src/xml/model/Class/Class.py
index 7af201c8f6e760a08cd7d6cdeb0fde32bb8df2ba..dbd12db3d3fc08ed64877e6656d8f468a0f55282 100644
--- a/silecs-codegen/src/xml/model/Class/Class.py
+++ b/silecs-codegen/src/xml/model/Class/Class.py
@@ -16,6 +16,7 @@
 
 from iecommon import *
 from model.Class.Block import *
+from Mapping import *
 import libxml2
 
 class Class(object):
@@ -33,31 +34,37 @@ class Class(object):
         return self.xmlNode.xpathEval("*[name()='Acquisition-Block' or name()='Setting-Block' or name()='Command-Block']")
     
 class ParamClass(Class):
-    def __init__(self):
-        self.address = 0
-        self.usedMemory = ""
+    ___addressAttribute = { MEM_TYPE: "address", DI_TYPE: "DI-address", DO_TYPE: "DO-address", AI_TYPE: "AI-address", AO_TYPE: "AO-address" }
+    ___usedDataAttribute = { MEM_TYPE: "used-mem", DI_TYPE: "used-DI", DO_TYPE: "used-DO", AI_TYPE: "used-AI", AO_TYPE: "used-AO" }
 
+    def __init__(self):
+        self.address = { MEM_TYPE: long(-1), DI_TYPE: long(-1), DO_TYPE: long(-1), AI_TYPE: long(-1), AO_TYPE: long(-1) }
+        self.usedData = { MEM_TYPE: "", DI_TYPE: "", DO_TYPE: "", AI_TYPE: "", AO_TYPE: "" }
             
     def initWithParamClassNode(self, xmlNode):
         super(ParamClass, self).__init__(xmlNode)
-        self.address = long(self.xmlNode.prop("address"))
-        self.usedMemory = self.xmlNode.prop("usedMemory")
+        for index, address in enumerate(self.address):
+            self.address[index] = long(self.xmlNode.prop(self.___addressAttribute[index]))
+        for index, usedData in enumerate(self.usedData):
+            self.usedData[index] = self.xmlNode.prop(self.___usedDataAttribute[index])
         
     def initWithDesignClass(self, designClass):
         newNode = libxml2.newNode(designClass.xmlNode.get_name())
         newNode.newProp("name", designClass.name)
         newNode.newProp("version", designClass.version)
         super(ParamClass, self).__init__(newNode)
-        newNode.newProp("address", str(self.address))
-        newNode.newProp("usedMemory", self.usedMemory)
-        
-    def setAddress(self,address):
-        self.xmlNode.setProp("address", str(address))
-        self.address = address
-        
-    def setUsedMemory(self,usedMemory):
-        self.xmlNode.setProp("usedMemory", usedMemory)
-        self.usedMemory = usedMemory
+        for index, address in enumerate(self.address):
+            newNode.newProp(self.___addressAttribute[index], str(self.address[index]))
+        for index, usedData in enumerate(self.usedData):
+            newNode.newProp(self.___usedDataAttribute[index], str(self.usedData[index]))
+
+    def setAddress(self,address,type):
+        self.xmlNode.setProp(self.___addressAttribute[type], str(address))
+        self.address[type] = address
+
+    def setUsedData(self,usedData,type):
+        self.xmlNode.setProp(self.___usedDataAttribute[type], usedData)
+        self.usedData[type] = usedData
         
     def getParamBlocks(self):
         paramBlocks = []
diff --git a/silecs-codegen/src/xml/model/Class/Register.py b/silecs-codegen/src/xml/model/Class/Register.py
index e61d27097ed74b449f7deca2307087922056fcc1..2239601143a63256f2ec56d63a2ed364e61e90e2 100644
--- a/silecs-codegen/src/xml/model/Class/Register.py
+++ b/silecs-codegen/src/xml/model/Class/Register.py
@@ -21,6 +21,8 @@ class Register(object):
     ___settingRegisterType = "Setting-Register"
     ___acquisitionRegisterType = "Acquisition-Register"
     ___volatileRegisterType = "Volatile-Register"
+    ___settingIORegisterType = "Setting-IO-Register"
+    ___acquisitionIORegisterType = "Acquisition-IO-Register"
     
     
     def __init__(self, xmlNode):
@@ -93,10 +95,10 @@ class Register(object):
         return self.isArray() or self.isArray2D()
     
     def isAcquisition(self):
-        return self.___type == self.___acquisitionRegisterType
+        return self.___type == self.___acquisitionRegisterType or self.___type == self.___acquisitionIORegisterType
     
     def isSetting(self):
-        return self.___type == self.___settingRegisterType
+        return self.___type == self.___settingRegisterType or self.___type == self.___settingIORegisterType
     
     def isVolatile(self):
         return self.___type == self.___volatileRegisterType
@@ -172,6 +174,31 @@ class Register(object):
             typeUpperCase = silecsType[:1].upper() + silecsType[1:]  # only first character if not unsigned
         return typeUpperCase
 
+    def getDataSize(self):
+        return {
+            'uint8'       : 1,
+            'int8'        : 1,
+            'uint16'      : 2,
+            'int16'       : 2,
+            'uint32'      : 4,
+            'int32'       : 4,
+            'float32'     : 4,
+            'uint64'      : 8,
+            'int64'       : 8,
+            'float64'     : 8,
+            'string'      : 1,
+            'date'        : 8,
+            # deprecated formats
+            'char'        : 1,
+            'byte'        : 1,
+            'word'        : 2,
+            'dword'       : 4,
+            'int'         : 2,
+            'dint'        : 4,
+            'real'        : 4,
+            'dt'          : 8
+        }[self.format]
+        
 #has some additionalValues
 class ParamRegister(Register):
 
@@ -187,14 +214,14 @@ class ParamRegister(Register):
         self.address = long(self.xmlNode.prop("address"))
         self.memSize = long(self.xmlNode.prop("mem-size"))
         
-    def initWithDesignRegister(self, designRegister,size,address,memSize):
+    def initWithDesignRegister(self, designRegister,address,memSize):
         newNodeTree = designRegister.xmlNode.copyNode(1) # 1 is for recursive copy
         if ( newNodeTree == None ):
             iecommon.logError('ERROR: Failed to copy register node: '+ designRegister.name +'.', True, {'errorlog': True})
         super(ParamRegister, self).__init__(designRegister.xmlNode)
         self.xmlNode = newNodeTree
-        newNodeTree.newProp("size", size)
-        self.size = long(size)
+        self.size = self.getDataSize()
+        newNodeTree.newProp("size", str(self.size))
         newNodeTree.newProp("address", str(address))
         self.address = address
         newNodeTree.newProp("mem-size", str(memSize))
@@ -213,7 +240,7 @@ class ParamRegister(Register):
         self.xmlNode.setProp("mem-size", str(memSize))
         self.memSize = memSize
         
-                
+        
 class DesignRegister(Register):
     
     def __init__(self, xmlNode):
@@ -284,25 +311,3 @@ class DesignRegister(Register):
                  'dt'       :'double',
                  '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 e3df9efd36b20026d8be4d66a00d0caa1ce2b267..2dedd2a71184cdc19d8bcbc76a30fb092411b996 100644
--- a/silecs-codegen/src/xml/model/Deploy/Controller.py
+++ b/silecs-codegen/src/xml/model/Deploy/Controller.py
@@ -16,10 +16,24 @@
 
 from model.Deploy.Device import *
 from model.Deploy.SilecsDesign import *
+from model.Class.Block import *
+from Mapping import *
 import libxml2
 
+#-------------------------------------------------------------------------
+# Return the highest bit-alignment of the given address
+def whichDataAlignment(value):
+    if (value % 2 != 0): return 8
+    if (value % 4 != 0): return 16
+    if (value % 8 != 0): return 32
+    if (value % 16 != 0): return 64
+    return 128
+    
 class Controller(object):
 
+    BLOCK_MODE = "BLOCK_MODE"
+    DEVICE_MODE = "DEVICE_MODE"
+    
     def __init__(self, xmlNode):
         self.hostName = ""
         self.domain = ""
@@ -27,12 +41,28 @@ class Controller(object):
         self.model = ""
         self.protocol = ""
         self.brand = ""
-        self.baseAddress = long(0)
-        self.xmlNode = None
+        self._baseAddress =  { MEM_TYPE: None, DI_TYPE: None, DO_TYPE: None, AI_TYPE: None, AO_TYPE: None }
+        self.address = { MEM_TYPE: long(-1), DI_TYPE: long(-1), DO_TYPE: long(-1), AI_TYPE: long(-1), AO_TYPE: long(-1) }
+        self.offset = { MEM_TYPE: long(0), DI_TYPE: long(0), DO_TYPE: long(0), AI_TYPE: long(0), AO_TYPE: long(0) }
+        self.addressFactor = 1
+        
+        # some variable used to calculate class/block/register-memory
+        self.memSize = 0
+        self.memLast = 0
+        self.msize = 0
+        self.regCounter = 0
+        self.blockCounter = 0
+        
+        # The following constant are used to align the address of a device block {set of registers}.
+        # With SCHNEIDER PLC, block is aligned depending on his 'worst-case' alignement {16bits or 32bits}.
+        # This logic allows having a unique adress computing whatever the mode {DEVICE/BLOCK} and the PLC model.
+        # Concerning SIEMENS PLC, block alignment should respect the 16bits alignement constraint for Struct&Array.
+        self.baseAlignment = long(16) # the default
+        self.alligment = { IOType.MEMORY: long(16), IOType.DIGITAL: long(8), IOType.ANALOG: long(16) } # the default
+        self.xmlNode = xmlNode
         self.plcNode = None
         self.devices = []
     
-        self.xmlNode = xmlNode
         self.hostName = xmlNode.prop("host-name")
         if xmlNode.hasProp("domain"):
             self.domain = xmlNode.prop("domain")
@@ -41,6 +71,19 @@ class Controller(object):
         self.model = self.plcNode.prop('model')
         self.protocol = self.plcNode.prop('protocol')
         
+        if self.plcNode.hasProp("base-address"):
+            self._baseAddress[MEM_TYPE] = long(self.plcNode.prop('base-address'))
+        if self.plcNode.hasProp("base-DB-number"):
+            self._baseAddress[MEM_TYPE] = long(self.plcNode.prop('base-DB-number'))
+        if self.plcNode.hasProp("DI-base-address"):
+            self._baseAddress[DI_TYPE] = long(self.plcNode.prop("DI-base-address"))
+        if self.plcNode.hasProp("DO-base-address"):
+            self._baseAddress[DO_TYPE] = long(self.plcNode.prop("DO-base-address"))
+        if self.plcNode.hasProp("AI-base-address"):
+            self._baseAddress[AI_TYPE] = long(self.plcNode.prop("AI-base-address"))
+        if self.plcNode.hasProp("AO-base-address"):
+            self._baseAddress[AO_TYPE] = long(self.plcNode.prop("AO-base-address"))
+        
         silecsHeader = Device()
         silecsHeader.silecsDeviceLabel = "SilecsHeader"
         silecsHeader.silecsDesignRef = "SilecsHeader"
@@ -51,6 +94,11 @@ class Controller(object):
             device.initFromXMLNode(deviceNode)
             self.devices.append(device)
     
+    def computeAddresses(self):
+        for index, baseAddress in enumerate(self._baseAddress):
+            if self._baseAddress[index] != None:
+                self.address[index] = ( self._baseAddress[index] + self.offset[index] ) * self.addressFactor
+
     def connectDesignObjects(self,silecsDesigns):
         for device in self.devices:
             for design in silecsDesigns:
@@ -96,65 +144,466 @@ class Controller(object):
         elif type == "NI-Controller":
             return NIController(controllerNode)
         elif type == "Virtual-Controller":
-            return VirtualS7Controller(controllerNode)
+            return SiemensController(controllerNode)#currently there is only S7-virtual
         else:
             raise Exception( "Controller-Type " + type + " not supported" )
+        
+    def hasMappingFor(self,type):
+        return self._baseAddress[type] != None
     
+    def computeInstAddress(self, mapping):
+        if self.protocol == self.BLOCK_MODE:
+            return self.computeBlockInstAddress(mapping)
+        elif self.protocol == self.DEVICE_MODE:
+            return self.computeDeviceInstAddress(mapping)
+        else:
+            raise Exception("The protocol '" + self.protocol + "' of controller '" + self.hostName + "is not known.")
+    
+    def computeBlockInstAddress(self, mapping):
+        raise NotImplementedError()
+        
+    def computeDeviceInstAddress(self, mapping):
+        raise NotImplementedError()
+        
+    def computeBlockInstAddressDefault(self, mapping):
+        if not mapping.isDefined:
+            return mapping.instanceAddress
+        tmpInstAddr = mapping.instanceAddress
+        mapping.instanceAddress += 1     #device-index
+        return tmpInstAddr
+    
+    def computeDeviceInstAddressDefault(self, mapping):
+        if not mapping.isDefined:
+            return mapping.instanceAddress
+        tmpInstAddr = mapping.instanceAddress
+        mapping.instanceAddress = mapping.instanceAddress + mapping.deviceDataSize #absolute address
+        return tmpInstAddr + mapping.classBaseAddress
+
+    def computeNextBaseAddress(self, mapping, nbDev):
+        raise NotImplementedError()
+    
+    # Compute the base-address of the next class
+    # 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 computeNextBaseAddressDefault(self, mapping, nbDev):
+        mapping.usedData = "0 word"
+        if not mapping.isDefined or ( mapping.nbBlock == 0 ) or not self.hasMappingFor(mapping.type):
+            return mapping.classBaseAddress
+        wordSize = (nbDev * mapping.deviceDataSize) / self.addressFactor
+        self.memSize += wordSize  # global size of the plc configuration
+        startAddr = (mapping.classBaseAddress - self.offset[mapping.type] * self.addressFactor) / self.addressFactor  # first word address used for this class
+        self.memLast = startAddr + wordSize - 1  # last word address used for this class
+        mapping.usedData = "MW%d..MW%d/%d words" % (startAddr, self.memLast, wordSize);
+        mapping.classBaseAddress  = (mapping.classBaseAddress + (wordSize * self.addressFactor))  # next word address expressed in bytes
+
+    def alignRegAddress(self, block, register, regAddress):
+        raise NotImplementedError()
+
+    # Adjust the register address relying on the SCHNEIDER Premium/Quantum and/or Beckhoff alignment constraints
+    # Unity Premium/Quantum is 16bits processor and base-address is interpreted as 16bit address
+    # Byte elements of array (including STRING) use 8bit alignment.
+    def alignRegAddressDefault(self, block, register, regAddress):
+        algnt = 16
+        while(whichDataAlignment(regAddress) < algnt):
+            regAddress += 1
+        self.msize = register.dim1 * register.dim2 * register.stringLength * register.getDataSize()  # compute memory data size
+        if register.format == 'int8' or register.format == 'char':# 8bit signed type use word alignment (16bit)
+            self.msize = self.msize * 2  # while string and uint8-array use 8bit alignment
+        return regAddress
+
+    def computeNextRegAddress(self, block, register, regAddress ):
+        raise NotImplementedError()
+    #-------------------------------------------------------------------------
+    # Compute the next register address relying on the data start-address and size.
+    def computeNextRegAddressDefault(self, block, register, regAddress ):
+        regAddress = regAddress + self.msize;
+        return regAddress
+
+    def computeBlkAddress(self, block, mapping, regAddr, nbDev):
+        if self.protocol == self.BLOCK_MODE:
+            return self.computeBlockBlkAddress(block, mapping, regAddr, nbDev)
+        elif self.protocol == self.DEVICE_MODE:
+            return self.computeDeviceBlkAddress(block, mapping, regAddr, nbDev)
+        else:
+            raise Exception("The protocol '" + self.protocol + "' of controller '" + self.hostName + "is not known.")
+        
+    def computeBlockBlkAddress(self, block, mapping, regAddr, nbDev):
+        raise NotImplementedError()
+    
+    def computeDeviceBlkAddress(self, block, mapping, regAddr, nbDev):
+        raise NotImplementedError()
+    
+    # Block-address = absolute address in the PLC memory
+    def computeBlockBlkAddressDefault(self, block, mapping, regAddr, nbDev):
+        # Compute block mem-size at first:
+        # It corresponds to the next potential address that is 16bits or 32bits.
+        nextBlockAddr = regAddr
+        # Adjust the next block-address by respecting the  alignment depending on the area 
+        while int(whichDataAlignment(nextBlockAddr)) < self.alligment[block.ioType]:
+            nextBlockAddr += 1
+            
+        mapping.blockDataSize = nextBlockAddr  
+        # then compute the next block DB-number and return the current one
+        tmpblockAddress = mapping.blockAddress   
+        # next absolute address: relies on the global class-address
+        mapping.blockAddress += (nbDev * mapping.blockDataSize)
+        # Count the number of block per area type,
+        # accumulate the block data size to compute the total device data size
+        mapping.nbBlock += 1
+        mapping.deviceDataSize += mapping.blockDataSize
+        return mapping.classBaseAddress + tmpblockAddress
+    
+    # Block-address = offset in the device memory
+    def computeDeviceBlkAddressDefault(self, block, mapping, regAddr, nbDev):
+        # Compute block mem-size at first:
+        # it corresponds to the next potential address that is 16bits or 32bits
+        nextBlockAddr = regAddr
+        # Adjust the next block-address by respecting the  alignment depending on the area 
+        while int(whichDataAlignment(nextBlockAddr)) < self.alligment[block.ioType]:
+            nextBlockAddr += 1
+            
+        mapping.blockDataSize = nextBlockAddr
+        # then compute the next block DB-number and return the current one
+        tmpblockAddress = mapping.blockAddress   
+        # next relative address: independent from the global class-address
+        mapping.blockAddress +=  mapping.blockDataSize
+        # Count the number of block per area type,
+        # accumulate the block data size to compute the total device data size
+        mapping.nbBlock += 1
+        mapping.deviceDataSize += mapping.blockDataSize
+        return tmpblockAddress
+
 class SiemensController(Controller):
     def __init__(self, xmlNode):
         super(SiemensController, self).__init__(xmlNode)
         self.brand = "SIEMENS"
-        self.baseAddress = long(self.plcNode.prop('base-DB-number'))
+        self.computeAddresses()
+        
+    def computeDeviceInstAddress(self, mapping):
+        if not mapping.isDefined:
+            return mapping.instanceAddress
+        
+        tmpInstAddr = mapping.instanceAddress
+        mapping.instanceAddress += 1     #device DB-number
+        return tmpInstAddr + mapping.classBaseAddress
+
+    def computeBlockInstAddress(self, mapping):
+        return self.computeBlockInstAddressDefault(mapping)
+    
+    def computeNextBaseAddress(self, mapping, nbDev):
+        mapping.usedData = "0 byte"
+        if not mapping.isDefined or ( mapping.nbBlock == 0 ) or not self.hasMappingFor(mapping.type):
+            return mapping.classBaseAddress
+        if mapping.type != MEM_TYPE:
+            return self.computeIONextBaseAddress(mapping, nbDev)
+        if self.protocol == self.BLOCK_MODE:
+            return self.computeBlockNextBaseAddress(mapping, nbDev)
+        elif self.protocol == self.DEVICE_MODE:
+            return self.computeDeviceNextBaseAddress(mapping, nbDev)
+        else:
+            raise Exception("The protocol '" + self.protocol + "' of controller '" + self.hostName + "is not known.")
         
+    # Compute the base DB-number of the next instance in the SIEMENS PLC memory
+    # BLOCK mode requires 1 DB per class block
+    def computeBlockNextBaseAddress(self, mapping, nbDev):
+        byteSize = nbDev * mapping.deviceDataSize
+        self.memSize = self.memSize + byteSize  # global size of the plc configuration
+        startDB = mapping.classBaseAddress  # first DB used for this class
+        self.memLast = mapping.classBaseAddress + mapping.nbBlock - 1  # last DB used
+        mapping.usedData = "DB%d..DB%d/%d bytes" % (startDB, self.memLast, byteSize)
+        mapping.classBaseAddress =  self.memLast + 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 computeDeviceNextBaseAddress(self, mapping, nbDev):
+        byteSize = nbDev * mapping.deviceDataSize
+        self.memSize = self.memSize + byteSize  # global size of the plc configuration
+        startDB = mapping.classBaseAddress  # first DB used for this class
+        self.memLast = mapping.classBaseAddress + nbDev - 1  # last DB used
+        mapping.usedData = "DB%d..DB%d/%d bytes" % (startDB, self.memLast, byteSize)
+        mapping.classBaseAddress =  self.memLast + 1  # next DB number
+
+    # Compute the base-address of the next class in the SIEMENS PLC IO area
+    # DEVICE or BLOCK mode use the same data size: next base address should be the same
+    # 'used-IO' info is expressed in bytes
+    def computeIONextBaseAddress(mapping, nbDev):
+        byteSize = nbDev * mapping.deviceDataSize
+        self.memSize += byteSize  # global size of the plc configuration
+        startAddr = mapping.classBaseAddress              # first byte address used for this class
+        self.memLast = startAddr + byteSize - 1  # last byte address used for this class
+        if mapping.type == DI_TYPE or mapping.type == AI_TYPE:
+            mapping.usedData = "IB%d..IB%d/%d bytes" % (startAddr, self.memLast, byteSize);
+        else:             #in ['DO-', 'AO-']
+            mapping.usedData = "QB%d..QB%d/%d bytes" % (startAddr, self.memLast, byteSize);
+        mapping.classBaseAddress =  (mapping.classBaseAddress + byteSize)  # next byte address expressed in bytes
+
+    # Adjust the register relying on the SIEMENS Simatic alignment constraints
+    # MEMORY area: uses 8bits alignment except for array and >8bits data (16bits alignment)
+    # DIGITAL area: uses 8bit alignment without any exception.
+    # ANALOG area: uses 16bit alignment.
+    # In case of string, its length has to be +2 to hold info on string
+    def alignRegAddress(self, block, register, regAddress):
+        algnt = 8
+        if ( block.isAnanlogIO() or ( block.isMEMBlock() and ((register.getDataSize() > 1) or (register.dim1 > 1) or (register.dim2 > 1) or (register.stringLength > 1))) ):
+                algnt = self.alligment[block.ioType]
+        while(whichDataAlignment(regAddress) < algnt):
+            regAddress += 1
+        if register.stringLength > 1:  # register is a string, 
+            if ((register.stringLength % 2) != 0): register.stringLength += 1  # adjusts the global size for byte type (word alignment)
+            register.stringLength += 2  # add increment to register.stringLength first two bytes for info on string (len, maxlen)
+        self.msize = register.dim1 * register.dim2 * register.stringLength * register.getDataSize()  # compute memory data size
+        return regAddress
+
+    def computeNextRegAddress(self, block, register, regAddress ):
+        regAddress = regAddress + self.msize;    #compute the next address for any case
+            # SIEMENS requires specific treatment in case of array.
+        if register.isArrayType():
+            #SIEMENS array is always followed by 16bits adressing
+            algnt = 16
+            while(whichDataAlignment(regAddress) < algnt):
+                regAddress+=1
+                
+        # SIEMENS ANALOG-IO area uses 16bit addressing
+        # SIEMENS MEMORY array is always followed by 16bits address
+        if block.isAnanlogIO() or ( block.isMEMBlock() and register.isArrayType() ):
+            while(whichDataAlignment(regAddress) < 16):
+                regAddress += 1
+        return regAddress
+    
+    def computeBlockBlkAddress(self, block, mapping, regAddr, nbDev):
+        if mapping.type == MEM_TYPE:
+            return self.computeBlockBlkAddressMemory(block, mapping, regAddr, nbDev)
+        else:
+            return self.computeBlockBlkAddressDefault(block, mapping, regAddr, nbDev)
+    
+    def computeDeviceBlkAddress(self, block, mapping, regAddr, nbDev):
+        return self.computeDeviceBlkAddressDefault(block, mapping, regAddr, nbDev)
+    
+    # block-address = block DB-Number
+    def computeBlockBlkAddressMemory(self, block, mapping, regAddr, 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!
+        nextBlockAddr = regAddr
+        # Adjust the next block-address by respecting the  alignment depending on the area 
+        while int(whichDataAlignment(nextBlockAddr)) < self.alligment[block.ioType]:
+            nextBlockAddr += 1
+        mapping.blockDataSize = nextBlockAddr
+        # then compute the next block DB-number and return the current one
+        tmpblockAddress = mapping.blockAddress    
+        mapping.blockAddress += 1
+        # Count the number of block per area type,
+        # accumulate the block data size to compute the total device data size
+        mapping.nbBlock += 1
+        mapping.deviceDataSize += mapping.blockDataSize
+        return mapping.classBaseAddress + tmpblockAddress
+    
 class BeckhoffController(Controller):
     addressFactor_default = 2 # Beckhoff default is 16 bit addressing
-    addressFactor_CX9020 = 1
-    offset_default = 0  # No offset by default (Bus coupler for instance)
-    offset_BC9020 = 32768 # some controllers use a memory-offset
-    offset_CX9020 = 24576
+    addressFactor_CX9020_Twincat2 = 1
+    addressFactor_CX9020_Twincat3 = 2
+    offset_mem_BC9020_base = 0x8000 # some controllers use a memory-offset
+    offset_mem_CX9020_base = 0x6000
+    offset_output_base = 0x1000 # offset for analog and digital output registers
+    memoryAlignment_CX9020 = 32 
     def __init__(self, xmlNode):
         super(BeckhoffController, self).__init__(xmlNode)
         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
+        self.addressFactor = self.addressFactor_default
+        if 'CX90' in self.model:
+            if self.system == 'TWINCat-2':
+                self.addressFactor = self.addressFactor_CX9020_Twincat2
+            elif self.system == 'TWINCat-3':
+                self.addressFactor = self.addressFactor_CX9020_Twincat3
+            else:
+                raise Exception("system '" + self.system + "' of controller '" + self.hostName + "'not supported")
+            self.offset[MEM_TYPE] = self.offset_mem_CX9020_base / self.addressFactor
+            self.alligment[IOType.MEMORY] = self.memoryAlignment_CX9020
         if self.model == 'BC9020':
-            self.offset = self.offset_BC9020
-        self.baseAddress = ( self.baseAddress * self.addressFactor) + self.offset
+            self.offset[MEM_TYPE] = self.offset_mem_BC9020_base / self.addressFactor
+        self.offset[AO_TYPE] = self.offset_output_base / self.addressFactor
+        self.offset[DO_TYPE] = self.offset_output_base / self.addressFactor
+        self.computeAddresses()
+            
+    def computeDeviceInstAddress(self, mapping):
+        return self.computeDeviceInstAddressDefault(mapping)
+    
+    def computeBlockInstAddress(self, mapping):
+        return self.computeBlockInstAddressDefault(mapping)
+    
+    def computeNextBaseAddress(self, mapping, nbDev):
+        return self.computeNextBaseAddressDefault(mapping, nbDev)
 
-        
+    def alignRegAddress(self, block, register, regAddress):
+        if self.model == 'BC9020':
+            return self.alignBCxxRegAddress(block, register, regAddress);
+        elif self.model == 'CX9020':
+            return self.alignCXxxRegAddress(block, register, regAddress);
+        elif self.model == 'BK9000' or self.model == 'BK9050' or self.model == 'BK9100':
+            return self.alignRegAddressDefault(block, register, regAddress);
+        else:
+            raise Exception("The plc-model '" + self.model + "' is not yet supported.")
+    
+    # Adjust the register address relying on the BECKHOFF Twincat BC9020 alignment constraints.
+    # TwinCAT BCxx PLCs are 16bits processor and base-address is interpreted as 16bit address
+    # 8bits alignment between elements of 8bit-data array (including strings).
+    # In case of string, its length has to be +1 to hold end-terminator.
+    def alignBCxxRegAddress(self, block, register, regAddress):
+        algnt = 16
+        while(whichDataAlignment(regAddress) < algnt):
+            regAddress += 1
+        if register.stringLength > 1:  # register is a string, 
+            register.stringLength += 1  # TwinCAT  requires  '\0' string terminator.                             
+        self.msize = register.dim1 * register.dim2 * register.stringLength * register.getDataSize()  # compute memory data size
+        return regAddress
+    
+    # Adjust the register address relying on the BECKHOFF Twincat CX9020 alignment constraints.
+    # TwinCAT CXxx PLCs are 32bits processor but base-address is interpreted as 16bit address (required even address in the mapping)
+    # TWINCAT-2: 32bits alignment except for 8/16bits (16bits alignment).
+    # TWINCAT-3: 16bits alignment
+    # BOTH: 8bits alignment between elements of 8bit-data array (including strings).
+    # In case of string, its length has to be +1 to hold end-terminator.
+    def alignCXxxRegAddress(self, block, register, regAddress):
+        algnt = 16
+        if (register.getDataSize() > 2):
+            algnt = self.alligment[block.ioType]  #depends on TwinCAT platform
+        while(whichDataAlignment(regAddress) < algnt):
+            regAddress += 1
+        if register.stringLength > 1:  # register is a string, 
+            register.stringLength += 1  # TwinCAT  requires  '\0' string terminator.
+        self.msize = register.dim1 * register.dim2 * register.stringLength * register.getDataSize()  # compute memory data size
+        return regAddress
+    
+    def computeNextRegAddress(self, block, register, regAddress):
+        return self.computeNextRegAddressDefault(block, register, regAddress)
+    
+    def computeBlockBlkAddress(self, block, mapping, regAddr, nbDev):
+        return self.computeBlockBlkAddressDefault(block, mapping, regAddr, nbDev)
+    
+    def computeDeviceBlkAddress(self, block, mapping, regAddr, nbDev):
+        return self.computeDeviceBlkAddressDefault(block, mapping, regAddr, nbDev)
+    
 class SchneiderController(Controller):
-    addressFactor = 2
     # Premium/Quantum uses 16bit adressing for 32bit values
     # Unity M340 is interpreted as 32bit address
+    addressFactor_Schneider_default = 2
+    memoryAlignment_M340 = 32 
     def __init__(self, xmlNode):
         super(SchneiderController, self).__init__(xmlNode)
         self.brand = "SCHNEIDER"
-        self.baseAddress = long(self.plcNode.prop('base-address'))
-        self.baseAddress = self.baseAddress * self.addressFactor
+        self.addressFactor = self.addressFactor_Schneider_default
+        if self.model == 'M340':
+            self.alligment[IOType.MEMORY] = self.memoryAlignment_M340
+        self.computeAddresses()
+
+    def computeDeviceInstAddress(self, mapping):
+        return self.computeDeviceInstAddressDefault(mapping)
+    
+    def computeBlockInstAddress(self, mapping):
+        return self.computeBlockInstAddressDefault(mapping)
+
+    def computeNextBaseAddress(self, mapping, nbDev):
+        return self.computeNextBaseAddressDefault(mapping, nbDev)
+
+    def alignRegAddress(self, block, register, regAddress):
+        if self.model == 'M340':
+            return self.alignM340RegAddress(block, register, regAddress);
+        elif self.model == 'Premium' or self.model == 'Quantum':
+            return self.alignRegAddressDefault(block, register, regAddress);
+        else:
+            raise Exception("The plc-model '" + self.model + "' is not yet supported.")
         
+    # Adjust the register address relying on the SCHNEIDER M340 alignment constraints
+    # Unity M340 is 32bits processor but base-address is interpreted as 16bit address (required even address in the mapping)
+    # 32bits alignment except for 8/16bits (16bits alignment)
+    # Byte elements of array (including STRING) use 8bit alignment.
+    
+    def alignM340RegAddress(self, block, register, regAddress):
+        algnt = 16
+        if (register.getDataSize() > 2):
+            algnt = self.alligment[block.ioType]
+        while(whichDataAlignment(regAddress) < algnt):
+            regAddress += 1
+        self.msize = register.dim1 * register.dim2 * register.stringLength * register.getDataSize()  # compute memory data size
+        if register.format == 'int8' or register.format == 'char':# 8bit signed type use word alignment (16bit)
+            self.msize = self.msize * 2  # while string and uint8-array use 8bit alignment
+        return regAddress
+    
+    def computeNextRegAddress(self, block, register, regAddress):
+        return self.computeNextRegAddressDefault(block, register, regAddress)
+    
+    def computeBlockBlkAddress(self, block, mapping, regAddr, nbDev):
+        return self.computeBlockBlkAddressDefault(block, mapping, regAddr, nbDev)
+    
+    def computeDeviceBlkAddress(self, block, mapping, regAddr, nbDev):
+        return self.computeDeviceBlkAddressDefault(block, mapping, regAddr, nbDev)
+    
 class RabbitController(Controller):
-    addressFactor = 2
+    addressFactor_DIGI_default = 2
     def __init__(self, xmlNode):
         super(RabbitController, self).__init__(xmlNode)
         self.brand = "DIGI"
-        self.baseAddress = long(self.plcNode.prop('base-address'))
-        self.baseAddress = self.baseAddress * self.addressFactor
+        self.addressFactor = self.addressFactor_DIGI_default
+        self.computeAddresses()
+            
+    def computeDeviceInstAddress(self, mapping):
+        return self.computeDeviceInstAddressDefault(mapping)
+    
+    def computeBlockInstAddress(self, mapping):
+        return self.computeBlockInstAddressDefault(mapping)
+
+    def computeNextBaseAddress(self, mapping, nbDev):
+        return self.computeNextBaseAddressDefault(mapping, nbDev)
+    
+    # Adjust the register address relying on the DIGI-Rabbit RCMx alignment constraints
+    # Use  16bits processor and base-address is interpreted as 16bit address
+    def alignRegAddress(self, block, register, regAddress):
+        algnt = 16
+        while(whichDataAlignment(regAddress) < algnt):
+            regAddress += 1
+        self.msize = register.dim1 * register.dim2 * register.stringLength * register.getDataSize()  # compute memory data size
+        if not register.isStringType():
+            if (register.getDataSize() == 1):  # but it's a 8bit type
+                self.msize = self.msize * 2  # so, it's a word alignment (only string use byte alignment)
+        return regAddress
+    
+    def computeNextRegAddress(self, block, register, regAddress):
+        return self.computeNextRegAddressDefault(block, register, regAddress)
+    
+    def computeBlockBlkAddress(self, block, mapping, regAddr, nbDev):
+        return self.computeBlockBlkAddressDefault(block, mapping, regAddr, nbDev)
+    
+    def computeDeviceBlkAddress(self, block, mapping, regAddr, nbDev):
+        return self.computeDeviceBlkAddressDefault(block, mapping, regAddr, nbDev)
 
-class VirtualS7Controller(Controller):
-    def __init__(self, xmlNode):
-        super(VirtualS7Controller, self).__init__(xmlNode)
-        self.brand = "SIEMENS"
-        self.baseAddress = long(self.plcNode.prop('base-address'))
-        
 class NIController(Controller):
     def __init__(self, xmlNode):
         super(NIController, self).__init__(xmlNode)
         self.brand = "NI"
-        self.baseAddress = 0
+        self.computeAddresses()
         
+    def computeDeviceInstAddress(self, mapping):
+        return 0
+        
+    def computeNextBaseAddress(self, mapping, nbDev):
+        mapping.usedData = "0 byte"
+        mapping.classBaseAddress = 0
+        
+    def alignRegAddress(self, block, register, regAddress):
+        return self.regCounter
+    
+    def computeNextRegAddress(self, block, register, regAddress):
+        regAddress = regAddress + self.msize;    #compute the next address for any case
+        self.msize = 0
+        return regAddress
+    
+    def computeBlockBlkAddress(self, block, mapping, regAddr, nbDev):
+        raise Exception("Block-mode not possible for NI-Controllers")
     
+    def computeDeviceBlkAddress(self, block, mapping, regAddr, nbDev):
+        self.blockCounter += 1
+        # Count the number of block per area type,
+        # accumulate the block data size to compute the total device data size
+        mapping.nbBlock += 1
+        mapping.deviceDataSize += mapping.blockDataSize
+        return self.blockCounter
     #xmlNode.shellPrintNode()
diff --git a/silecs-codegen/src/xml/model/Param/Controller.py b/silecs-codegen/src/xml/model/Param/Controller.py
index f56606e6ecb5c1a2a79c8205087d15d7e63be0df..5cd2e33c8a6c0f9284689de9da81f03fa2cc133b 100644
--- a/silecs-codegen/src/xml/model/Param/Controller.py
+++ b/silecs-codegen/src/xml/model/Param/Controller.py
@@ -16,6 +16,7 @@
 
 from model.Class.Class import ParamClass
 from model.Deploy.Controller import Controller
+from Mapping import *
 import libxml2
 
 class ParamController(object):
@@ -27,7 +28,7 @@ class ParamController(object):
         self.model = ""
         self.protocol = ""
         self.brand = ""
-        self.address = long(0)
+        self.address = { MEM_TYPE: long(-1), DI_TYPE: long(-1), DO_TYPE: long(-1), AI_TYPE: long(-1), AO_TYPE: long(-1) }
         self.usedMem = ""
         self.xmlNode = None
         self.paramClasses = []
@@ -40,7 +41,11 @@ class ParamController(object):
         self.model = self.xmlNode.prop('plc-model')
         self.protocol = self.xmlNode.prop('protocol')
         self.brand = self.xmlNode.prop("plc-brand")
-        self.address = long(self.xmlNode.prop("address"))
+        self.address[MEM_TYPE] = long(self.xmlNode.prop("address"))
+        self.address[DI_TYPE] = long(self.xmlNode.prop("DI-address"))
+        self.address[DO_TYPE] = long(self.xmlNode.prop("DO-address"))
+        self.address[AI_TYPE] = long(self.xmlNode.prop("AI-address"))
+        self.address[AO_TYPE] = long(self.xmlNode.prop("AO-address"))
         self.usedMem = self.xmlNode.prop("used-mem")
             
     def initFromXMLNode(self, xmlNode):
@@ -57,7 +62,12 @@ class ParamController(object):
         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("address", str(controller.address[MEM_TYPE]))
+        newNode.newProp("DI-address", str(controller.address[DI_TYPE]))
+        newNode.newProp("DO-address", str(controller.address[DO_TYPE]))
+        newNode.newProp("AI-address", str(controller.address[AI_TYPE]))
+        newNode.newProp("AO-address", str(controller.address[AO_TYPE]))
+
         newNode.newProp("domain", controller.domain)
         newNode.newProp("used-mem", "TODO")
         self.initAttributes(newNode)
diff --git a/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy b/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy
index 0c5dbffbf80c077a1484af4416efda8412ad3606..ae92f5a229a1eef3b1e37d9022ef65c21cf78c65 100644
--- a/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy
+++ b/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy
@@ -37,32 +37,37 @@
     </Controller>
 
     <Controller host-name="Virtual_SiemensDevice">
-    <Virtual-Controller model="SIMATIC_S7-VIRTUAL" system="S7 virtual controller" protocol="DEVICE_MODE" base-address="0">
+    <Virtual-Controller model="SIMATIC_S7-VIRTUAL" system="SNAP7 linux32" protocol="DEVICE_MODE" base-address="0">
                 <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" />
             <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" />
     </Virtual-Controller>
 
     </Controller>
     <Controller host-name="Virtual_SiemensBlock">
-    <Virtual-Controller model="SIMATIC_S7-VIRTUAL" system="S7 virtual controller" protocol="BLOCK_MODE" base-address="0">
+    <Virtual-Controller model="SIMATIC_S7-VIRTUAL" system="SNAP7 linux32" protocol="BLOCK_MODE" base-address="0">
                 <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" />
             <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" />
     </Virtual-Controller>
     </Controller>
     <Controller host-name="Beckhoff_BC9020">
-        <Beckhoff-PLC model="BC9020" system="TWINCat" protocol="BLOCK_MODE" base-address="0">
+        <Beckhoff-PLC model="BC9020" system="TWINCat-2" protocol="BLOCK_MODE" base-address="0">
             <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" />
             <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" />
         </Beckhoff-PLC>
 
     </Controller>
-    <Controller host-name="Beckhoff_CX9020">
-        <Beckhoff-PLC model="CX9020" system="TWINCat" protocol="BLOCK_MODE" base-address="0">
+    <Controller host-name="Beckhoff_CX9020_TC2">
+        <Beckhoff-PLC model="CX9020" system="TWINCat-2" protocol="BLOCK_MODE" base-address="0">
             <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" />
             <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" />
         </Beckhoff-PLC>
-
     </Controller>
+                <Controller host-name="Beckhoff_CX9020_TC3">
+        <Beckhoff-PLC model="CX9020" system="TWINCat-3" protocol="BLOCK_MODE" base-address="0">
+            <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" />
+            <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" />
+        </Beckhoff-PLC>
+        </Controller>
     <Controller host-name="Schneider_PremiumQuantum">
         <Schneider-PLC model="Premium" system="UNITY Pro" protocol="BLOCK_MODE" base-address="0">
             <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" />
diff --git a/silecs-codegen/src/xml/test/general/genParamTest.py b/silecs-codegen/src/xml/test/general/genParamTest.py
index 64f955bf9cd14b44d6f7d72e9187b55801cfeb5a..0cc31d1ef533593d047b7228f976c5d5ac0f8e3f 100644
--- a/silecs-codegen/src/xml/test/general/genParamTest.py
+++ b/silecs-codegen/src/xml/test/general/genParamTest.py
@@ -59,7 +59,8 @@ def SiemensVirtualSourcesTest():
 
 def BeckhoffSourcesTest():
     CompareGeneratedFiles("Beckhoff_BC9020",".silecsparam")
-    CompareGeneratedFiles("Beckhoff_CX9020",".silecsparam")
+    CompareGeneratedFiles("Beckhoff_CX9020_TC2",".silecsparam")
+    CompareGeneratedFiles("Beckhoff_CX9020_TC3",".silecsparam")
 
 def SchneiderSourcesTest():
     CompareGeneratedFiles("Schneider_M340",".silecsparam")
diff --git a/silecs-codegen/src/xml/test/general/genplcsrcTest.py b/silecs-codegen/src/xml/test/general/genplcsrcTest.py
index ad97feae26ac5f224e401d1f3119cf17944c1802..7262d6a2d106f74ccc23e4adb97f0c58e020fce4 100644
--- a/silecs-codegen/src/xml/test/general/genplcsrcTest.py
+++ b/silecs-codegen/src/xml/test/general/genplcsrcTest.py
@@ -77,7 +77,8 @@ def SiemensVirtualSourcesTest():
 
 def BeckhoffSourcesTest():
     CompareGeneratedFiles("Beckhoff_BC9020",".exp")
-    CompareGeneratedFiles("Beckhoff_CX9020",".exp")
+    CompareGeneratedFiles("Beckhoff_CX9020_TC2",".exp")
+    CompareGeneratedFiles("Beckhoff_CX9020_TC3",".exp")
 
 def SchneiderSourcesTest():
     CompareGeneratedFiles("Schneider_M340",".xsy")
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 2b7c148e2f8ca1b910021ad2bfe855c3a30ead0c..11250f892fda94f20b88d15e682c0e7eb4e7ca9c 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,11 +2,11 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-25 11:00:26.492677"/>
+    <Generation date="2017-07-27 16:14:06.421145"/>
     <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">
-    <SILECS-Class name="SilecsHeader" version="1.0.0" address="32768" usedMemory="MW16384..MW16407 / 24 words">
+  <SILECS-Mapping plc-name="Beckhoff_BC9020" plc-brand="BECKHOFF" plc-system="TWINCat-2" plc-model="BC9020" protocol="BLOCK_MODE" address="32768" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="32768" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW0..MW23/24 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word">
       <Acquisition-Block name="hdrBlk" size="14" address="32768" mem-size="48">
         <Acquisition-Register name="_version" size="1" address="0" mem-size="17">
           <string string-length="16" format="string"/>
@@ -21,9 +21,9 @@
           <scalar format="dt"/>
       </Acquisition-Register>
       </Acquisition-Block>
-      <Instance label="SilecsHeader" address="0"/>
+      <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="32816" usedMemory="MW16408..MW18215 / 1808 words">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="32816" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW24..MW1783/1760 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word">
       <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"/>
@@ -183,8 +183,8 @@
 				<array dim="10" format="dt"/>
 			</Setting-Register>
       </Command-Block>
-      <Instance label="testDevice1" address="0"/>
-      <Instance label="testDevice2" address="1"/>
+      <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
+      <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
   </SILECS-Mapping>
 </SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020_TC2.silecsparam
similarity index 92%
rename from silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020.silecsparam
rename to silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020_TC2.silecsparam
index 20aae0aa31382d8a444f44c6c3ed814e9747412d..b1393097bbd7f2a35ad1856383fca7b84ca5cd34 100644
--- a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020.silecsparam
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020_TC2.silecsparam
@@ -2,11 +2,11 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-25 11:00:26.530253"/>
+    <Generation date="2017-07-28 12:11:45.390885"/>
     <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">
-    <SILECS-Class name="SilecsHeader" version="1.0.0" address="24576" usedMemory="MW12288..MW12313 / 26 words">
+  <SILECS-Mapping plc-name="Beckhoff_CX9020_TC2" plc-brand="BECKHOFF" plc-system="TWINCat-2" plc-model="CX9020" protocol="BLOCK_MODE" address="24576" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="24576" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW0..MW51/52 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word">
       <Acquisition-Block name="hdrBlk" size="14" address="24576" mem-size="52">
         <Acquisition-Register name="_version" size="1" address="0" mem-size="17">
           <string string-length="16" format="string"/>
@@ -21,9 +21,9 @@
           <scalar format="dt"/>
       </Acquisition-Register>
       </Acquisition-Block>
-      <Instance label="SilecsHeader" address="0"/>
+      <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="24628" usedMemory="MW12314..MW14133 / 1820 words">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="24628" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW52..MW3587/3536 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word">
       <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"/>
@@ -183,8 +183,8 @@
 				<array dim="10" format="dt"/>
 			</Setting-Register>
       </Command-Block>
-      <Instance label="testDevice1" address="0"/>
-      <Instance label="testDevice2" address="1"/>
+      <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
+      <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
   </SILECS-Mapping>
 </SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020_TC3.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020_TC3.silecsparam
new file mode 100644
index 0000000000000000000000000000000000000000..069dc75fc1f2c7ae305944aacd40f23d60757d87
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020_TC3.silecsparam
@@ -0,0 +1,190 @@
+<?xml version="1.0"?>
+<SILECS-Param silecs-version="DEV">
+  <Mapping-Info>
+    <Owner user-login="schwinn"/>
+    <Generation date="2017-07-28 12:11:45.427012"/>
+    <Deployment checksum="2754857673"/>
+  </Mapping-Info>
+  <SILECS-Mapping plc-name="Beckhoff_CX9020_TC3" plc-brand="BECKHOFF" plc-system="TWINCat-3" plc-model="CX9020" protocol="BLOCK_MODE" address="24576" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="24576" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW0..MW25/26 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word">
+      <Acquisition-Block name="hdrBlk" size="14" address="24576" mem-size="52">
+        <Acquisition-Register name="_version" size="1" address="0" mem-size="17">
+          <string string-length="16" format="string"/>
+      </Acquisition-Register>
+        <Acquisition-Register name="_checksum" size="4" address="20" mem-size="4">
+          <scalar format="uint32"/>
+      </Acquisition-Register>
+        <Acquisition-Register name="_user" size="1" address="24" mem-size="17">
+          <string string-length="16" format="string"/>
+      </Acquisition-Register>
+        <Acquisition-Register name="_date" size="8" address="44" mem-size="8">
+          <scalar format="dt"/>
+      </Acquisition-Register>
+      </Acquisition-Block>
+      <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
+    </SILECS-Class>
+    <SILECS-Class name="AllTypes" version="0.1.0" address="24628" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW26..MW1793/1768 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word">
+      <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"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_uint8" generateFesaValueItem="true" fesaFieldName="RO_uint8_fesa" size="1" address="2" mem-size="1">
+				<scalar format="uint8"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_int16" generateFesaValueItem="true" fesaFieldName="RO_int16_fesa" size="2" address="4" mem-size="2">
+				<scalar format="int16"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_uint16" generateFesaValueItem="true" fesaFieldName="RO_uint16_fesa" size="2" address="6" mem-size="2">
+				<scalar format="uint16"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_int32" generateFesaValueItem="true" fesaFieldName="RO_int32_fesa" size="4" address="8" mem-size="4">
+				<scalar format="int32"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_uint32" generateFesaValueItem="true" fesaFieldName="RO_uint32_fesa" size="4" address="12" mem-size="4">
+				<scalar format="uint32"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_float32" generateFesaValueItem="true" fesaFieldName="RO_float32_fesa" size="4" address="16" mem-size="4">
+				<scalar format="float32"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_string" generateFesaValueItem="true" fesaFieldName="RO_string_fesa" size="1" address="20" mem-size="65">
+				<string string-length="64" format="string"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_date" generateFesaValueItem="true" fesaFieldName="RO_date_fesa" size="8" address="88" mem-size="8">
+				<scalar format="date"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_char" generateFesaValueItem="true" fesaFieldName="RO_char_fesa" size="1" address="96" mem-size="1">
+				<scalar format="char"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_byte" generateFesaValueItem="true" fesaFieldName="RO_byte_fesa" size="1" address="98" mem-size="1">
+				<scalar format="byte"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_word" generateFesaValueItem="true" fesaFieldName="RO_word_fesa" size="2" address="100" mem-size="2">
+				<scalar format="word"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_dword" generateFesaValueItem="true" fesaFieldName="RO_dword_fesa" size="4" address="104" mem-size="4">
+				<scalar format="dword"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_int" generateFesaValueItem="true" fesaFieldName="RO_int_fesa" size="2" address="108" mem-size="2">
+				<scalar format="int"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_dint" generateFesaValueItem="true" fesaFieldName="RO_dint_fesa" size="4" address="112" mem-size="4">
+				<scalar format="dint"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_real" generateFesaValueItem="true" fesaFieldName="RO_real_fesa" size="4" address="116" mem-size="4">
+				<scalar format="real"/>
+			</Acquisition-Register>
+        <Acquisition-Register name="RO_dt" generateFesaValueItem="true" fesaFieldName="RO_dt_fesa" size="8" address="120" mem-size="8">
+				<scalar format="dt"/>
+			</Acquisition-Register>
+      </Acquisition-Block>
+      <Setting-Block name="MyRWBlock" size="212" address="24884" mem-size="468">
+        <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="260">
+				<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="332" 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="364" 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="368" 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="372" 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="380" 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="396" 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="404" 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="420" 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="436" mem-size="32">
+				<array2D dim1="2" dim2="2" format="dt"/>
+			</Volatile-Register>
+      </Setting-Block>
+      <Command-Block name="MyWOBlock" size="530" address="25820" mem-size="1172">
+        <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="650">
+				<stringArray dim="10" string-length="64" format="string"/>
+			</Setting-Register>
+        <Setting-Register name="WO_date" generateFesaValueItem="true" fesaFieldName="WO_date_fesa" size="8" address="832" mem-size="80">
+				<array dim="10" format="date"/>
+			</Setting-Register>
+        <Setting-Register name="WO_char" generateFesaValueItem="true" fesaFieldName="WO_char_fesa" size="1" address="912" mem-size="10">
+				<array dim="10" format="char"/>
+			</Setting-Register>
+        <Setting-Register name="WO_byte" generateFesaValueItem="true" fesaFieldName="WO_byte_fesa" size="1" address="922" mem-size="10">
+				<array dim="10" format="byte"/>
+			</Setting-Register>
+        <Setting-Register name="WO_word" generateFesaValueItem="true" fesaFieldName="WO_word_fesa" size="2" address="932" mem-size="20">
+				<array dim="10" format="word"/>
+			</Setting-Register>
+        <Setting-Register name="WO_dword" generateFesaValueItem="true" fesaFieldName="WO_dword_fesa" size="4" address="952" mem-size="40">
+				<array dim="10" format="dword"/>
+			</Setting-Register>
+        <Setting-Register name="WO_int" generateFesaValueItem="true" fesaFieldName="WO_int_fesa" size="2" address="992" mem-size="20">
+				<array dim="10" format="int"/>
+			</Setting-Register>
+        <Setting-Register name="WO_dint" generateFesaValueItem="true" fesaFieldName="WO_dint_fesa" size="4" address="1012" mem-size="40">
+				<array dim="10" format="dint"/>
+			</Setting-Register>
+        <Setting-Register name="WO_real" generateFesaValueItem="true" fesaFieldName="WO_real_fesa" size="4" address="1052" mem-size="40">
+				<array dim="10" format="real"/>
+			</Setting-Register>
+        <Setting-Register name="WO_dt" generateFesaValueItem="true" fesaFieldName="WO_dt_fesa" size="8" address="1092" mem-size="80">
+				<array dim="10" format="dt"/>
+			</Setting-Register>
+      </Command-Block>
+      <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
+      <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
+    </SILECS-Class>
+  </SILECS-Mapping>
+</SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam
index 5e445be2729b9b49c9e7a49037d0b3859c68614b..547f7eff5ee62111d0793ecfa54214bde2bd7205 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,11 +2,11 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-25 11:00:26.682209"/>
+    <Generation date="2017-07-27 16:14:06.611199"/>
     <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">
-    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="MW0..MW21 / 22 words">
+  <SILECS-Mapping plc-name="Rabbit_BlockMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="BLOCK_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW0..MW21/22 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word">
       <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44">
         <Acquisition-Register name="_version" size="1" address="0" mem-size="16">
           <string string-length="16" format="string"/>
@@ -21,9 +21,9 @@
           <scalar format="dt"/>
       </Acquisition-Register>
       </Acquisition-Block>
-      <Instance label="SilecsHeader" address="0"/>
+      <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1865 / 1844 words">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW22..MW1821/1800 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word">
       <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"/>
@@ -183,8 +183,8 @@
 				<array dim="10" format="dt"/>
 			</Setting-Register>
       </Command-Block>
-      <Instance label="testDevice1" address="0"/>
-      <Instance label="testDevice2" address="1"/>
+      <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
+      <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
   </SILECS-Mapping>
 </SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam
index d9946854f1f85aaa04950cc45ced9af8b7e72c58..8405a9d5208473a1a478ac8d5f48464348b03cd4 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,11 +2,11 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-25 11:00:26.645862"/>
+    <Generation date="2017-07-27 16:14:06.572989"/>
     <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">
-    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="MW0..MW21 / 22 words">
+  <SILECS-Mapping plc-name="Rabbit_DeviceMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="DEVICE_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW0..MW21/22 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word">
       <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44">
         <Acquisition-Register name="_version" size="1" address="0" mem-size="16">
           <string string-length="16" format="string"/>
@@ -21,9 +21,9 @@
           <scalar format="dt"/>
       </Acquisition-Register>
       </Acquisition-Block>
-      <Instance label="SilecsHeader" address="0"/>
+      <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1865 / 1844 words">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW22..MW1821/1800 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word">
       <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"/>
@@ -183,8 +183,8 @@
 				<array dim="10" format="dt"/>
 			</Setting-Register>
       </Command-Block>
-      <Instance label="testDevice1" address="44"/>
-      <Instance label="testDevice2" address="1888"/>
+      <Instance label="testDevice1" address="44" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
+      <Instance label="testDevice2" address="1844" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </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 2287afacfda1278ad945b0525987f6f6d9c0cf82..9f487f777f7fcddc30fa5a63c5975872ecec5f23 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,11 +2,11 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-25 11:00:26.607123"/>
+    <Generation date="2017-07-27 16:14:06.534996"/>
     <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">
-    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="MW0..MW21 / 22 words">
+  <SILECS-Mapping plc-name="Schneider_M340" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="M340" protocol="BLOCK_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW0..MW21/22 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word">
       <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44">
         <Acquisition-Register name="_version" size="1" address="0" mem-size="16">
           <string string-length="16" format="string"/>
@@ -21,9 +21,9 @@
           <scalar format="dt"/>
       </Acquisition-Register>
       </Acquisition-Block>
-      <Instance label="SilecsHeader" address="0"/>
+      <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1845 / 1824 words">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW22..MW1801/1780 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word">
       <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"/>
@@ -183,8 +183,8 @@
 				<array dim="10" format="dt"/>
 			</Setting-Register>
       </Command-Block>
-      <Instance label="testDevice1" address="0"/>
-      <Instance label="testDevice2" address="1"/>
+      <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
+      <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
   </SILECS-Mapping>
 </SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Schneider_PremiumQuantum.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Schneider_PremiumQuantum.silecsparam
index 986aa092bcffc51ef28d375fddf91181a39ea505..a8fc93ad660871337aac9b155c074dc1b8272bf1 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,11 +2,11 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-25 11:00:26.568077"/>
+    <Generation date="2017-07-27 16:14:06.499570"/>
     <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">
-    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="MW0..MW21 / 22 words">
+  <SILECS-Mapping plc-name="Schneider_PremiumQuantum" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="Premium" protocol="BLOCK_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW0..MW21/22 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word">
       <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44">
         <Acquisition-Register name="_version" size="1" address="0" mem-size="16">
           <string string-length="16" format="string"/>
@@ -21,9 +21,9 @@
           <scalar format="dt"/>
       </Acquisition-Register>
       </Acquisition-Block>
-      <Instance label="SilecsHeader" address="0"/>
+      <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1837 / 1816 words">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="44" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW22..MW1793/1772 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word">
       <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"/>
@@ -183,8 +183,8 @@
 				<array dim="10" format="dt"/>
 			</Setting-Register>
       </Command-Block>
-      <Instance label="testDevice1" address="0"/>
-      <Instance label="testDevice2" address="1"/>
+      <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
+      <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
   </SILECS-Mapping>
 </SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Block.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Block.silecsparam
index f6ad542a588ece820a32b2b955f07b428341ea49..9537336121eecb9417336884bf9d9625186156ad 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,11 +2,11 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-25 11:00:26.340140"/>
+    <Generation date="2017-07-27 16:14:06.268832"/>
     <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">
-    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes">
+  <SILECS-Mapping plc-name="Siemens_Step7Block" plc-brand="SIEMENS" plc-system="STEP-7" plc-model="SIMATIC_S7-300" protocol="DEVICE_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB0..DB0/48 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte">
       <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"/>
@@ -21,9 +21,9 @@
           <scalar format="dt"/>
       </Acquisition-Register>
       </Acquisition-Block>
-      <Instance label="SilecsHeader" address="0"/>
+      <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB2 / 3636 bytes">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB1..DB2/3540 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte">
       <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"/>
@@ -183,8 +183,8 @@
 				<array dim="10" format="dt"/>
 			</Setting-Register>
       </Command-Block>
-      <Instance label="testDevice1" address="1"/>
-      <Instance label="testDevice2" address="2"/>
+      <Instance label="testDevice1" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
+      <Instance label="testDevice2" address="2" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
   </SILECS-Mapping>
 </SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Device.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Device.silecsparam
index 11ab3a4d92ab05eca142cfd2c5a93c88d1383ae4..9202eb91813b47c501ab822144d6703e0093cd93 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,11 +2,11 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-25 11:00:26.378125"/>
+    <Generation date="2017-07-27 16:14:06.306171"/>
     <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">
-    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes">
+  <SILECS-Mapping plc-name="Siemens_Step7Device" plc-brand="SIEMENS" plc-system="STEP-7" plc-model="SIMATIC_S7-300" protocol="BLOCK_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB0..DB0/48 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte">
       <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"/>
@@ -21,9 +21,9 @@
           <scalar format="dt"/>
       </Acquisition-Register>
       </Acquisition-Block>
-      <Instance label="SilecsHeader" address="0"/>
+      <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB3 / 3636 bytes">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB1..DB3/3540 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte">
       <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"/>
@@ -183,8 +183,8 @@
 				<array dim="10" format="dt"/>
 			</Setting-Register>
       </Command-Block>
-      <Instance label="testDevice1" address="0"/>
-      <Instance label="testDevice2" address="1"/>
+      <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
+      <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
   </SILECS-Mapping>
 </SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaBlock.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaBlock.silecsparam
index aedddec1cda9f200133797bbf8bcca84edcacd54..b861f907cae5a433a52e63377a61a5eeb3504906 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,11 +2,11 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-25 11:00:26.302895"/>
+    <Generation date="2017-07-27 16:14:06.229930"/>
     <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">
-    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes">
+  <SILECS-Mapping plc-name="Siemens_TiaBlock" plc-brand="SIEMENS" plc-system="TIA-PORTAL" plc-model="SIMATIC_S7-300" protocol="BLOCK_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB0..DB0/48 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte">
       <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"/>
@@ -21,9 +21,9 @@
           <scalar format="dt"/>
       </Acquisition-Register>
       </Acquisition-Block>
-      <Instance label="SilecsHeader" address="0"/>
+      <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB3 / 3636 bytes">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB1..DB3/3540 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte">
       <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"/>
@@ -183,8 +183,8 @@
 				<array dim="10" format="dt"/>
 			</Setting-Register>
       </Command-Block>
-      <Instance label="testDevice1" address="0"/>
-      <Instance label="testDevice2" address="1"/>
+      <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
+      <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
   </SILECS-Mapping>
 </SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaDevice.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaDevice.silecsparam
index a9a789de36fc615490246577d62d81dfd19d3b4e..61c75903977e855dc18dda006c3e1f2677b70bc3 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,11 +2,11 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-25 11:00:26.263419"/>
+    <Generation date="2017-07-27 16:14:06.192160"/>
     <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">
-    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes">
+  <SILECS-Mapping plc-name="Siemens_TiaDevice" plc-brand="SIEMENS" plc-system="TIA-PORTAL" plc-model="SIMATIC_S7-300" protocol="DEVICE_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB0..DB0/48 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte">
       <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"/>
@@ -21,9 +21,9 @@
           <scalar format="dt"/>
       </Acquisition-Register>
       </Acquisition-Block>
-      <Instance label="SilecsHeader" address="0"/>
+      <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB2 / 3636 bytes">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB1..DB2/3540 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte">
       <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"/>
@@ -183,8 +183,8 @@
 				<array dim="10" format="dt"/>
 			</Setting-Register>
       </Command-Block>
-      <Instance label="testDevice1" address="1"/>
-      <Instance label="testDevice2" address="2"/>
+      <Instance label="testDevice1" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
+      <Instance label="testDevice2" address="2" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
   </SILECS-Mapping>
 </SILECS-Param>
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
index ef0b905083157b6e3d405f57a01df635ca8a136e..abb3a74ecfcb34fd9d3c8d52e5fb9f476002e8c8 100644
--- a/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensBlock.silecsparam
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensBlock.silecsparam
@@ -2,11 +2,11 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-25 11:00:26.453248"/>
+    <Generation date="2017-07-28 12:09:58.078995"/>
     <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">
+  <SILECS-Mapping plc-name="Virtual_SiemensBlock" plc-brand="SIEMENS" plc-system="SNAP7 linux32" plc-model="SIMATIC_S7-VIRTUAL" protocol="BLOCK_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB0..DB0/48 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte">
       <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"/>
@@ -21,9 +21,9 @@
           <scalar format="dt"/>
       </Acquisition-Register>
       </Acquisition-Block>
-      <Instance label="SilecsHeader" address="0"/>
+      <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB3 / 3636 bytes">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB1..DB3/3540 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte">
       <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"/>
@@ -183,8 +183,8 @@
 				<array dim="10" format="dt"/>
 			</Setting-Register>
       </Command-Block>
-      <Instance label="testDevice1" address="0"/>
-      <Instance label="testDevice2" address="1"/>
+      <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
+      <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-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
index 61c9023b07a337a325d273732268fe0784d999c8..de610430ebacc1a6630146f104dafaeab1c258c0 100644
--- a/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensDevice.silecsparam
+++ b/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensDevice.silecsparam
@@ -2,11 +2,11 @@
 <SILECS-Param silecs-version="DEV">
   <Mapping-Info>
     <Owner user-login="schwinn"/>
-    <Generation date="2017-07-25 11:00:26.415203"/>
+    <Generation date="2017-07-28 12:09:58.040528"/>
     <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">
+  <SILECS-Mapping plc-name="Virtual_SiemensDevice" plc-brand="SIEMENS" plc-system="SNAP7 linux32" plc-model="SIMATIC_S7-VIRTUAL" protocol="DEVICE_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO">
+    <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB0..DB0/48 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte">
       <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"/>
@@ -21,9 +21,9 @@
           <scalar format="dt"/>
       </Acquisition-Register>
       </Acquisition-Block>
-      <Instance label="SilecsHeader" address="0"/>
+      <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
-    <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB2 / 3636 bytes">
+    <SILECS-Class name="AllTypes" version="0.1.0" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB1..DB2/3540 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte">
       <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"/>
@@ -183,8 +183,8 @@
 				<array dim="10" format="dt"/>
 			</Setting-Register>
       </Command-Block>
-      <Instance label="testDevice1" address="1"/>
-      <Instance label="testDevice2" address="2"/>
+      <Instance label="testDevice1" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
+      <Instance label="testDevice2" address="2" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/>
     </SILECS-Class>
   </SILECS-Mapping>
 </SILECS-Param>
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020.exp b/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020_TC2.exp
similarity index 96%
rename from silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020.exp
rename to silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020_TC2.exp
index d6fca4ca68637ac60952990e7de60bbdeb1bfe47..7b1e2a3ef9e1df24cb96bbf1fbd3b9dcdcacb328 100644
--- a/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020.exp
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020_TC2.exp
@@ -17,7 +17,7 @@ VAR_GLOBAL
     _user_a781_SilecsHeader AT %MW24: STRING(16):= 'schwinn';
 
     (*SilecsHeader/SilecsHeader/hdrBlk *)
-    _date_a781_SilecsHeader AT %MW44: DT:= DT#2017-6-8-16:38:3;
+    _date_a781_SilecsHeader AT %MW44: DT:= DT#2017-7-28-12:15:6;
 
     (*AllTypes/testDevice1/MyROBlock *)
     RO_int8_a583_testDevice1 AT %MW52: SINT;
diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020_TC3.exp b/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020_TC3.exp
new file mode 100644
index 0000000000000000000000000000000000000000..7b1e2a3ef9e1df24cb96bbf1fbd3b9dcdcacb328
--- /dev/null
+++ b/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020_TC3.exp
@@ -0,0 +1,328 @@
+(* +-------------------------------------------------------------------
+* | C.E.R.N Geneva, Switzerland
+* | SILECS - BE/CO-FE
+* | April 2015
+* +-------------------------------------------------------------------
+*
+* Release : SILECS_DEV
+*)
+VAR_GLOBAL
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _version_a781_SilecsHeader AT %MW0: STRING(16):= DEV;
+
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _checksum_a781_SilecsHeader AT %MW20: DWORD:= 2754857673;
+
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _user_a781_SilecsHeader AT %MW24: STRING(16):= 'schwinn';
+
+    (*SilecsHeader/SilecsHeader/hdrBlk *)
+    _date_a781_SilecsHeader AT %MW44: DT:= DT#2017-7-28-12:15:6;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int8_a583_testDevice1 AT %MW52: SINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_uint8_a583_testDevice1 AT %MW54: BYTE;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int16_a583_testDevice1 AT %MW56: INT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_uint16_a583_testDevice1 AT %MW58: WORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int32_a583_testDevice1 AT %MW60: DINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_uint32_a583_testDevice1 AT %MW64: DWORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_float32_a583_testDevice1 AT %MW68: REAL;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_string_a583_testDevice1 AT %MW72: STRING(64);
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_date_a583_testDevice1 AT %MW140: DT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_char_a583_testDevice1 AT %MW148: SINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_byte_a583_testDevice1 AT %MW150: BYTE;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_word_a583_testDevice1 AT %MW152: WORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_dword_a583_testDevice1 AT %MW156: DWORD;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_int_a583_testDevice1 AT %MW160: INT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_dint_a583_testDevice1 AT %MW164: DINT;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_real_a583_testDevice1 AT %MW168: REAL;
+
+    (*AllTypes/testDevice1/MyROBlock *)
+    RO_dt_a583_testDevice1 AT %MW172: DT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int8_a583_testDevice2 AT %MW180: SINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_uint8_a583_testDevice2 AT %MW182: BYTE;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int16_a583_testDevice2 AT %MW184: INT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_uint16_a583_testDevice2 AT %MW186: WORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int32_a583_testDevice2 AT %MW188: DINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_uint32_a583_testDevice2 AT %MW192: DWORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_float32_a583_testDevice2 AT %MW196: REAL;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_string_a583_testDevice2 AT %MW200: STRING(64);
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_date_a583_testDevice2 AT %MW268: DT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_char_a583_testDevice2 AT %MW276: SINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_byte_a583_testDevice2 AT %MW278: BYTE;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_word_a583_testDevice2 AT %MW280: WORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_dword_a583_testDevice2 AT %MW284: DWORD;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_int_a583_testDevice2 AT %MW288: INT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_dint_a583_testDevice2 AT %MW292: DINT;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_real_a583_testDevice2 AT %MW296: REAL;
+
+    (*AllTypes/testDevice2/MyROBlock *)
+    RO_dt_a583_testDevice2 AT %MW300: DT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int8_a583_testDevice1 AT %MW308: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_uint8_a583_testDevice1 AT %MW312: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int16_a583_testDevice1 AT %MW316: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_uint16_a583_testDevice1 AT %MW324: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int32_a583_testDevice1 AT %MW332: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_uint32_a583_testDevice1 AT %MW348: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_float32_a583_testDevice1 AT %MW364: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_string_a583_testDevice1 AT %MW380: ARRAY [0..1, 0..1] OF STRING(64);
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_date_a583_testDevice1 AT %MW640: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_char_a583_testDevice1 AT %MW672: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_byte_a583_testDevice1 AT %MW676: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_word_a583_testDevice1 AT %MW680: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_dword_a583_testDevice1 AT %MW688: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_int_a583_testDevice1 AT %MW704: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_dint_a583_testDevice1 AT %MW712: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_real_a583_testDevice1 AT %MW728: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice1/MyRWBlock *)
+    RW_dt_a583_testDevice1 AT %MW744: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int8_a583_testDevice2 AT %MW776: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_uint8_a583_testDevice2 AT %MW780: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int16_a583_testDevice2 AT %MW784: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_uint16_a583_testDevice2 AT %MW792: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int32_a583_testDevice2 AT %MW800: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_uint32_a583_testDevice2 AT %MW816: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_float32_a583_testDevice2 AT %MW832: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_string_a583_testDevice2 AT %MW848: ARRAY [0..1, 0..1] OF STRING(64);
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_date_a583_testDevice2 AT %MW1108: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_char_a583_testDevice2 AT %MW1140: ARRAY [0..1, 0..1] OF SINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_byte_a583_testDevice2 AT %MW1144: ARRAY [0..1, 0..1] OF BYTE;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_word_a583_testDevice2 AT %MW1148: ARRAY [0..1, 0..1] OF WORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_dword_a583_testDevice2 AT %MW1156: ARRAY [0..1, 0..1] OF DWORD;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_int_a583_testDevice2 AT %MW1172: ARRAY [0..1, 0..1] OF INT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_dint_a583_testDevice2 AT %MW1180: ARRAY [0..1, 0..1] OF DINT;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_real_a583_testDevice2 AT %MW1196: ARRAY [0..1, 0..1] OF REAL;
+
+    (*AllTypes/testDevice2/MyRWBlock *)
+    RW_dt_a583_testDevice2 AT %MW1212: ARRAY [0..1, 0..1] OF DT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int8_a583_testDevice1 AT %MW1244: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_uint8_a583_testDevice1 AT %MW1254: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int16_a583_testDevice1 AT %MW1264: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_uint16_a583_testDevice1 AT %MW1284: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int32_a583_testDevice1 AT %MW1304: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_uint32_a583_testDevice1 AT %MW1344: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_float32_a583_testDevice1 AT %MW1384: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_string_a583_testDevice1 AT %MW1424: ARRAY [0..9] OF STRING(64);
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_date_a583_testDevice1 AT %MW2076: ARRAY [0..9] OF DT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_char_a583_testDevice1 AT %MW2156: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_byte_a583_testDevice1 AT %MW2166: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_word_a583_testDevice1 AT %MW2176: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_dword_a583_testDevice1 AT %MW2196: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_int_a583_testDevice1 AT %MW2236: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_dint_a583_testDevice1 AT %MW2256: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_real_a583_testDevice1 AT %MW2296: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice1/MyWOBlock *)
+    WO_dt_a583_testDevice1 AT %MW2336: ARRAY [0..9] OF DT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int8_a583_testDevice2 AT %MW2416: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_uint8_a583_testDevice2 AT %MW2426: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int16_a583_testDevice2 AT %MW2436: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_uint16_a583_testDevice2 AT %MW2456: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int32_a583_testDevice2 AT %MW2476: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_uint32_a583_testDevice2 AT %MW2516: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_float32_a583_testDevice2 AT %MW2556: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_string_a583_testDevice2 AT %MW2596: ARRAY [0..9] OF STRING(64);
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_date_a583_testDevice2 AT %MW3248: ARRAY [0..9] OF DT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_char_a583_testDevice2 AT %MW3328: ARRAY [0..9] OF SINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_byte_a583_testDevice2 AT %MW3338: ARRAY [0..9] OF BYTE;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_word_a583_testDevice2 AT %MW3348: ARRAY [0..9] OF WORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_dword_a583_testDevice2 AT %MW3368: ARRAY [0..9] OF DWORD;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_int_a583_testDevice2 AT %MW3408: ARRAY [0..9] OF INT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_dint_a583_testDevice2 AT %MW3428: ARRAY [0..9] OF DINT;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_real_a583_testDevice2 AT %MW3468: ARRAY [0..9] OF REAL;
+
+    (*AllTypes/testDevice2/MyWOBlock *)
+    WO_dt_a583_testDevice2 AT %MW3508: ARRAY [0..9] OF DT;
+
+END_VAR
\ No newline at end of file
diff --git a/silecs-model/src/xml/DeploySchema.xsd b/silecs-model/src/xml/DeploySchema.xsd
index cf53afb27cfcd7ae448f4fb2b0dddeb021f31ee5..073dadd560ee9f11733bab472b4ff5a8626062b7 100644
--- a/silecs-model/src/xml/DeploySchema.xsd
+++ b/silecs-model/src/xml/DeploySchema.xsd
@@ -278,7 +278,7 @@
                         </xs:appinfo>
                     </xs:annotation>
                 </xs:attribute>
-                <xs:attribute name="model" use="required" type="SiemensModelType"/>
+                <xs:attribute name="model" use="required" type="SiemensModelType" />
                 <xs:attribute name="protocol" type="BothProtocolType" use="required">
                     <xs:annotation>
                         <xs:documentation>Data access mode is defined at PLC level for all
@@ -336,7 +336,7 @@
                         </xs:appinfo>
                     </xs:annotation>
                 </xs:attribute>
-                <xs:attribute name="model" use="required" type="SchneiderModelType"/>
+                <xs:attribute name="model" use="required" type="SchneiderModelType" />
                 <xs:attribute name="protocol" type="BlockProtocolType" use="required">
                     <xs:annotation>
                         <xs:documentation>Data access mode is defined at PLC level for all
@@ -394,7 +394,7 @@
                         </xs:appinfo>
                     </xs:annotation>
                 </xs:attribute>
-                <xs:attribute name="model" use="required" type="BeckhoffModelType"/>
+                <xs:attribute name="model" use="required" type="BeckhoffModelType" />
                 <xs:attribute name="protocol" type="BlockProtocolType" use="required">
                     <xs:annotation>
                         <xs:documentation>Data access mode is defined at PLC level for all
@@ -452,7 +452,7 @@
                         </xs:appinfo>
                     </xs:annotation>
                 </xs:attribute>
-                <xs:attribute name="model" use="required" type="RabbitModelType"/>
+                <xs:attribute name="model" use="required" type="RabbitModelType" />
                 <xs:attribute name="protocol" type="BothProtocolType" use="required">
                     <xs:annotation>
                         <xs:documentation>Data access mode is defined at PLC level for all
@@ -502,7 +502,7 @@
                         </xs:appinfo>
                     </xs:annotation>
                 </xs:attribute>
-                <xs:attribute name="model" use="required" type="VirtualModelType"/>
+                <xs:attribute name="model" use="required" type="VirtualModelType" />
                 <xs:attribute name="protocol" type="BothProtocolType" use="required">
                     <xs:annotation>
                         <xs:documentation>Data access mode is defined at PLC level for all the classes</xs:documentation>
@@ -531,7 +531,7 @@
     <xs:complexType name="NIControllerType">
         <xs:complexContent>
             <xs:extension base="SimpleControllerType">
-                <xs:attribute name="model" use="required" type="NIModelType"/>
+                <xs:attribute name="model" use="required" type="NIModelType" />
                 <xs:attribute name="system" type="NISystemType" use="required">
                     <xs:annotation>
                         <xs:documentation>System infrastructure used to develop and/or
@@ -563,8 +563,8 @@
             </xs:extension>
         </xs:complexContent>
     </xs:complexType>
-    
-        <xs:simpleType name="HostNameType">
+
+    <xs:simpleType name="HostNameType">
         <xs:restriction base="xs:string">
             <xs:minLength value="1" />
             <xs:pattern value="[_A-Za-z0-9]*" />
@@ -586,38 +586,6 @@
             <xs:pattern value="[_A-Za-z][_A-Za-z0-9]*" />
         </xs:restriction>
     </xs:simpleType>
-
-    <xs:simpleType name="SiemensSystemType">
-        <xs:restriction base="xs:string">
-            <xs:enumeration value="STEP-7" />
-            <xs:enumeration value="TIA-PORTAL" />
-        </xs:restriction>
-    </xs:simpleType>
-    <xs:simpleType name="SchneiderSystemType">
-        <xs:restriction base="xs:string">
-            <xs:enumeration value="UNITY Pro" />
-        </xs:restriction>
-    </xs:simpleType>
-    <xs:simpleType name="BeckhoffSystemType">
-        <xs:restriction base="xs:string">
-            <xs:enumeration value="TWINCat" />
-        </xs:restriction>
-    </xs:simpleType>
-    <xs:simpleType name="RabbitSystemType">
-        <xs:restriction base="xs:string">
-            <xs:enumeration value="Standard-C" />
-        </xs:restriction>
-    </xs:simpleType>
-    <xs:simpleType name="PCSystemType">
-        <xs:restriction base="xs:string">
-            <xs:enumeration value="S7 virtual controller" />
-        </xs:restriction>
-    </xs:simpleType>
-    <xs:simpleType name="NISystemType">
-        <xs:restriction base="xs:string">
-            <xs:enumeration value="Labview" />
-        </xs:restriction>
-    </xs:simpleType>
     <xs:simpleType name="BothProtocolType">
         <xs:restriction base="xs:string">
             <xs:enumeration value="DEVICE_MODE" />
@@ -652,6 +620,39 @@
             <xs:enumeration value="TST" />
         </xs:restriction>
     </xs:simpleType>
+    <xs:simpleType name="SiemensSystemType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="STEP-7" />
+            <xs:enumeration value="TIA-PORTAL" />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="SchneiderSystemType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="UNITY Pro" />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="BeckhoffSystemType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="TWINCat-2" />
+            <xs:enumeration value="TWINCat-3" />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="RabbitSystemType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="Standard-C" />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="PCSystemType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="SNAP7 linux32" />
+            <xs:enumeration value="SNAP7 linux64" />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="NISystemType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="Labview"/>
+        </xs:restriction>
+    </xs:simpleType>
     <xs:simpleType name="SiemensModelType">
         <xs:restriction base="xs:string">
             <xs:enumeration value="SIMATIC_S7-300" />