diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/PLCRecvAction.cpp b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCRecvAction.cpp
index 77e2ca2fb8f26cfa39df90ac14525d77d053ad9c..9dae94d9cef4ce43d65d500c8841ae66a144f901 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/core/PLCRecvAction.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCRecvAction.cpp
@@ -69,9 +69,10 @@ int PLCRecvBlockMode::execute(Context* pContext)
             Device* pDev = pContext->getDevice();
 
             //Base attributes of the device within the complete data block containing all devices.
+            AccessArea area = theBlock_->getAccessArea();
             unsigned long usedAddress = theBlock_->getAddress();
             unsigned long usedSize = theBlock_->getMemSize();
-            unsigned long usedDeviceOffset = pDev->getAddress() * usedSize;
+            unsigned long usedDeviceOffset = pDev->getInputAddress(area) * usedSize;
             unsigned char* pBuffer = ((unsigned char*)theBlock_->getBuffer()) + usedDeviceOffset;
 
             // Overwrite device-block address, offset & size in case user wants to resize the block dynamically
@@ -147,7 +148,8 @@ int PLCRecvBlockMode::execute(Context* pContext)
 
             //begin critical section
             Lock lock(bufferMux_);
-            switch (theBlock_->getAccessArea())
+            AccessArea area = theBlock_->getAccessArea();
+            switch (area)
             {
                 case Digital:
                 case Analog:
@@ -179,7 +181,7 @@ int PLCRecvBlockMode::execute(Context* pContext)
                 for (pDeviceIter = deviceCol.begin(); pDeviceIter != deviceCol.end(); ++pDeviceIter)
                 {
                     Device* pDev = pDeviceIter->second;
-                    unsigned long deviceOffset = pDev->getAddress() * theBlock_->getMemSize();
+                    unsigned long deviceOffset = pDev->getInputAddress(area) * theBlock_->getMemSize();
                     unsigned char* pBuffer = ((unsigned char*)theBlock_->getBuffer()) + deviceOffset;
                     pDev->importRegisters(theBlock_, pBuffer, tod, pContext);
                 }
@@ -212,7 +214,8 @@ int PLCRecvDeviceMode::execute(Context* pContext)
             Device* pDev = pContext->getDevice();
 
             //Set base attributes of the device blocks
-            unsigned long usedDeviceAddress = pDev->getAddress();
+            AccessArea area = theBlock_->getAccessArea();
+            unsigned long usedDeviceAddress = pDev->getInputAddress(area);
             unsigned long usedBlockAddress = theBlock_->getAddress();
             unsigned long usedSize = theBlock_->getMemSize();
 
@@ -294,12 +297,13 @@ int PLCRecvDeviceMode::execute(Context* pContext)
                 }
                 //begin critical section
                 Lock lock(bufferMux_);
-                switch (theBlock_->getAccessArea())
+                AccessArea area = theBlock_->getAccessArea();
+                switch (area)
                 {
                     case Digital:
                     case Analog:
                     {
-                        errorCode = pConn->readIO(theBlock_->getPLC(), pDev->getAddress(), //Base address (or DBn) of the device
+                        errorCode = pConn->readIO(theBlock_->getPLC(), pDev->getInputAddress(area), //Base address (or DBn) of the device
                         theBlock_->getAddress(), //Block data address within the device
                         theBlock_->getMemSize(), //Get one device-block only
                         (unsigned char*)theBlock_->getBuffer() //Buffer to store the data
@@ -309,7 +313,7 @@ int PLCRecvDeviceMode::execute(Context* pContext)
                     case Memory:
                     default:
                     {
-                        errorCode = pConn->readMemory(theBlock_->getPLC(), pDev->getAddress(), //Base address (or DBn) of the device
+                        errorCode = pConn->readMemory(theBlock_->getPLC(), pDev->getInputAddress(area), //Base address (or DBn) of the device
                         theBlock_->getAddress(), //Block data address within the device
                         theBlock_->getMemSize(), //Get one device-block only
                         (unsigned char*)theBlock_->getBuffer() //Buffer to store the data
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/PLCSendAction.cpp b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCSendAction.cpp
index 5e96b925904edf6b31190f52f75087a726d0d001..b34efdd86d3a9a7762ff34db8a7191a3cbfedbf2 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/core/PLCSendAction.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/core/PLCSendAction.cpp
@@ -70,7 +70,8 @@ int PLCSendBlockMode::execute(Context* pContext)
             //Base attributes of the device within the complete data block containing all devices.
             unsigned long usedAddress = theBlock_->getAddress();
             unsigned long usedSize = theBlock_->getMemSize();
-            unsigned long usedDeviceOffset = pDev->getAddress() * usedSize;
+            AccessArea area = theBlock_->getAccessArea();
+            unsigned long usedDeviceOffset = pDev->getOutputAddress(area) * usedSize;
             unsigned char* pBuffer = ((unsigned char*)theBlock_->getBuffer()) + usedDeviceOffset;
 
             // Overwrite device-block address, offset & size in case user wants to resize the block dynamically
@@ -91,7 +92,7 @@ int PLCSendBlockMode::execute(Context* pContext)
                     pDev->exportRegisters(theBlock_, pBuffer, pContext);
                 }
 
-                switch (theBlock_->getAccessArea())
+                switch (area)
                 {
                     case Digital:
                     case Analog:
@@ -142,7 +143,8 @@ int PLCSendBlockMode::execute(Context* pContext)
                     for (pDeviceIter = deviceCol.begin(); pDeviceIter != deviceCol.end(); ++pDeviceIter)
                     {
                         Device* pDev = pDeviceIter->second;
-                        unsigned long deviceOffset = pDev->getAddress() * theBlock_->getMemSize();
+                        AccessArea area = theBlock_->getAccessArea();
+                        unsigned long deviceOffset = pDev->getOutputAddress(area) * theBlock_->getMemSize();
                         unsigned char* pBuffer = ((unsigned char*)theBlock_->getBuffer()) + deviceOffset;
                         pDev->exportRegisters(theBlock_, pBuffer, pContext);
                     }
@@ -202,7 +204,8 @@ int PLCSendDeviceMode::execute(Context* pContext)
             Device* pDev = pContext->getDevice();
 
             //Set base attributes of the device blocks
-            unsigned long usedDeviceAddress = pDev->getAddress();
+            AccessArea area = theBlock_->getAccessArea();
+            unsigned long usedDeviceAddress = pDev->getOutputAddress(area);
             unsigned long usedBlockAddress = theBlock_->getAddress();
             unsigned long usedSize = theBlock_->getMemSize();
 
@@ -224,7 +227,7 @@ int PLCSendDeviceMode::execute(Context* pContext)
                     pDev->exportRegisters(theBlock_, (unsigned char*)theBlock_->getBuffer(), pContext);
                 }
 
-                switch (theBlock_->getAccessArea())
+                switch (area)
                 {
                     case Digital:
                     case Analog:
@@ -278,12 +281,13 @@ int PLCSendDeviceMode::execute(Context* pContext)
                         pDev->exportRegisters(theBlock_, (unsigned char*)theBlock_->getBuffer(), pContext);
                     }
 
-                    switch (theBlock_->getAccessArea())
+                    AccessArea area = theBlock_->getAccessArea();
+                    switch (area)
                     {
                         case Digital:
                         case Analog:
                         {
-                            errorCode = pConn->writeIO(theBlock_->getPLC(), pDev->getAddress(), //Base address (or DBn) of the device
+                            errorCode = pConn->writeIO(theBlock_->getPLC(), pDev->getOutputAddress(area), //Base address (or DBn) of the device
                             theBlock_->getAddress(), //Block data address within the device
                             theBlock_->getMemSize(), //Set one device-block only
                             (unsigned char*)theBlock_->getBuffer() //Buffer which contain the data
@@ -292,7 +296,7 @@ int PLCSendDeviceMode::execute(Context* pContext)
                         }
                         case Memory:
                         default:
-                            errorCode = pConn->writeMemory(theBlock_->getPLC(), pDev->getAddress(), //Base address (or DBn) of the device
+                            errorCode = pConn->writeMemory(theBlock_->getPLC(), pDev->getOutputAddress(area), //Base address (or DBn) of the device
                             theBlock_->getAddress(), //Block data address within the device
                             theBlock_->getMemSize(), //Set one device-block only
                             (unsigned char*)theBlock_->getBuffer() //Buffer which contain the data
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.cpp
index 1840df02ec2d6de0738d80b551d0d261e800b503..eb2c96bed8dc8450a5db1cc17a352d6e78c69b67 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.cpp
@@ -33,13 +33,17 @@
 
 namespace Silecs
 {
-	Device::Device(PLC* thePLC, std::string deviceName, std::string deviceAddress, boost::ptr_vector<ElementXML>& blockNodes) : thePLC_ (thePLC)
+	Device::Device(PLC* thePLC, const ElementXML& deviceNode, boost::ptr_vector<ElementXML>& blockNodes) : thePLC_ (thePLC)
 	{
 		// Update Device ElementXML attributes
-        label_ = deviceName;
-		StringUtilities::fromString(address_,deviceAddress );
-
-        LOG(ALLOC) << "Creating SilecsDevice: " << label_;
+        label_ = deviceNode.getAttribute("label");
+		StringUtilities::fromString(address_,deviceNode.getAttribute("address") );
+		StringUtilities::fromString(ai_address_,deviceNode.getAttribute("AI-address") );
+		StringUtilities::fromString(ao_address_,deviceNode.getAttribute("AO-address") );
+		StringUtilities::fromString(di_address_,deviceNode.getAttribute("DI-address") );
+		StringUtilities::fromString(do_address_,deviceNode.getAttribute("DO-address") );
+
+		LOG(ALLOC) << "Creating SilecsDevice: " << label_;
 
         boost::ptr_vector<ElementXML>::const_iterator blockIter;
         for(blockIter = blockNodes.begin(); blockIter != blockNodes.end(); blockIter++)
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.h
index 7bd8f978f4cccbca5510662f644dc49b6799c291..048b7b2ac57bb99bbdbb992a10f93fda8162db69 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.h
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsDevice.h
@@ -124,10 +124,54 @@ namespace Silecs
         friend class CNVSendBlockMode;
         friend class CNVSendDeviceMode;
 
-		Device(PLC* thePLC, std::string deviceName, std::string deviceAddress, boost::ptr_vector<ElementXML>& blockNodes);
+		Device(PLC* thePLC, const ElementXML& deviceNode, boost::ptr_vector<ElementXML>& blockNodes);
 		virtual ~Device();
 
-		inline unsigned long& getAddress() { return address_; }
+	    inline unsigned long& getInputAddress(AccessArea area)
+	    {
+	        switch (area)
+	        {
+	            case Digital:
+	            {
+	                return di_address_;
+	                break;
+	            }
+	            case Analog:
+	            {
+	                return ai_address_;
+	                break;
+	            }
+	            case Memory:
+	            {
+	                return address_;
+	                break;
+	            }
+	        }
+	        return address_;
+	    }
+
+	    inline unsigned long& getOutputAddress(AccessArea area)
+	    {
+	        switch (area)
+	        {
+	            case Digital:
+	            {
+	                return do_address_;
+	                break;
+	            }
+	            case Analog:
+	            {
+	                return ao_address_;
+	                break;
+	            }
+	            case Memory:
+	            {
+	                return address_;
+	                break;
+	            }
+	        }
+	        return address_;
+	    }
 
 		Register* instantiateRegister(const boost::shared_ptr<ElementXML>& registerNode);
 
@@ -161,9 +205,13 @@ namespace Silecs
 		/// Parent PLC reference of that device
 		PLC* thePLC_;
 
-		/// Device attributes
-		std::string label_;
-		unsigned long address_;
+	    /// Device attributes
+	    std::string label_;
+	    unsigned long address_;
+	    unsigned long ai_address_;
+	    unsigned long ao_address_;
+	    unsigned long di_address_;
+	    unsigned long do_address_;
 
 		/// Register collection of that device
 		registerVectorType registerCol_;
diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp
index 9770f08a6b95d0d2dea97e29c722ab05a0461df7..4996585b30e9f2ce40b31ec91bdde1a25a6bbf8d 100644
--- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp
+++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp
@@ -436,11 +436,9 @@ namespace Silecs
 				boost::ptr_vector<ElementXML>::const_iterator instanceIter;
 				for(instanceIter = instanceNodes.begin(); instanceIter != instanceNodes.end(); instanceIter++)
 				{
-					std::string deviceName = (*instanceIter).getAttribute("label");
-					std::string deviceAddress = (*instanceIter).getAttribute("address");
-					Device* pDevice = new Device(this, deviceName, deviceAddress, blockNodes);
-					deviceCol_.push_back(std::make_pair(deviceName, pDevice));
-					if(deviceName == "SilecsHeader")
+					Device* pDevice = new Device(this, *instanceIter, blockNodes);
+					deviceCol_.push_back(std::make_pair(pDevice->getLabel(), pDevice));
+					if(pDevice->getLabel() == "SilecsHeader")
 						theHeader_ = pDevice;
 				}